From 02ad7f44ff7c3341af9f8b6c2a8544cd2e900370 Mon Sep 17 00:00:00 2001 From: Chris Brown Date: Sat, 30 Nov 2019 18:17:57 -0500 Subject: [PATCH] Dnsmasq allows use of a common config folder, much like nginx and php do. This PR changes Valet's default config process to empower this feature, which makes installation less intrusive, and easier to identify and remove valet-specific customizations. This will make for easier troubleshooting ... and easier customizing (such as dropping in a custom logging config, additional TLDs, alternate DNS resolvers, etc) Also removes old dnsmasq configs used by prior Valet versions --- cli/Valet/DnsMasq.php | 91 ++++++++++++++------------------ cli/stubs/etc-dnsmasq-valet.conf | 3 ++ tests/DnsMasqTest.php | 19 ++++--- 3 files changed, 54 insertions(+), 59 deletions(-) create mode 100644 cli/stubs/etc-dnsmasq-valet.conf diff --git a/cli/Valet/DnsMasq.php b/cli/Valet/DnsMasq.php index 4597510e3..0de1c4b08 100644 --- a/cli/Valet/DnsMasq.php +++ b/cli/Valet/DnsMasq.php @@ -9,9 +9,9 @@ class DnsMasq { var $brew, $cli, $files; + var $dnsmasqMasterConfigFile = '/usr/local/etc/dnsmasq.conf'; + var $dnsmasqSystemConfDir = '/usr/local/etc/dnsmasq.d'; var $resolverPath = '/etc/resolver'; - var $configPath = '/usr/local/etc/dnsmasq.conf'; - var $exampleConfigPath = '/usr/local/opt/dnsmasq/dnsmasq.conf.example'; /** * Create a new DnsMasq instance. @@ -37,10 +37,12 @@ function install($tld = 'test') { $this->brew->ensureInstalled('dnsmasq'); - // For DnsMasq, we create our own custom configuration file which will be imported - // in the main DnsMasq file. This allows Valet to make changes to our own files - // without needing to modify the "primary" DnsMasq configuration files again. - $this->createCustomConfigFile($tld); + // For DnsMasq, we enable its feature of loading *.conf from /usr/local/etc/dnsmasq.d/ + // and then we put a valet config file in there to point to the user's home .config/valet/dnsmasq.d + // This allows Valet to make changes to our own files without needing to modify the core dnsmasq configs + $this->ensureUsingDnsmasqDForConfigs(); + + $this->createDnsmasqTldConfigFile($tld); $this->createTldResolver($tld); @@ -50,65 +52,52 @@ function install($tld = 'test') } /** - * Append the custom DnsMasq configuration file to the main configuration file. + * Ensure the DnsMasq configuration primary config is set to read custom configs * - * @param string $tld * @return void */ - function createCustomConfigFile($tld) + function ensureUsingDnsmasqDForConfigs() { - $customConfigPath = $this->customConfigPath(); + info('Updating Dnsmasq configuration...'); - $this->copyExampleConfig(); + // set primary config to look for configs in /usr/local/etc/dnsmasq.d/*.conf + $contents = $this->files->get($this->dnsmasqMasterConfigFile); + // ensure the line we need to use is present, and uncomment it if needed + if (false === strpos($contents, 'conf-dir=/usr/local/etc/dnsmasq.d/,*.conf')) { + $contents .= PHP_EOL . 'conf-dir=/usr/local/etc/dnsmasq.d/,*.conf' . PHP_EOL; + } + $contents = str_replace('#conf-dir=/usr/local/etc/dnsmasq.d/,*.conf', 'conf-dir=/usr/local/etc/dnsmasq.d/,*.conf', $contents); - $this->appendCustomConfigImport($customConfigPath); + // remove entries used by older Valet versions: + $contents = preg_replace('/^conf-file.*valet.*$/m', '', $contents); - $this->files->putAsUser($customConfigPath, 'address=/.'.$tld.'/127.0.0.1'.PHP_EOL.'listen-address=127.0.0.1'.PHP_EOL); - } + // save the updated config file + $this->files->put($this->dnsmasqMasterConfigFile, $contents); - /** - * Copy the Homebrew installed example DnsMasq configuration file. - * - * @return void - */ - function copyExampleConfig() - { - if (! $this->files->exists($this->configPath)) { - $this->files->copyAsUser( - $this->exampleConfigPath, - $this->configPath - ); + // remove old ~/.config/valet/dnsmasq.conf file because things are moved to the ~/.config/valet/dnsmasq.d/ folder now + if (file_exists($file = dirname($this->dnsmasqUserConfigDir()) . '/dnsmasq.conf')) { + unlink($file); } + + // add a valet-specific config file to point to user's home directory valet config + $contents = $this->files->get(__DIR__.'/../stubs/etc-dnsmasq-valet.conf'); + $contents = str_replace('VALET_HOME_PATH', VALET_HOME_PATH, $contents); + $this->files->ensureDirExists($this->dnsmasqSystemConfDir, user()); + $this->files->putAsUser($this->dnsmasqSystemConfDir . '/dnsmasq-valet.conf', $contents); + + $this->files->ensureDirExists(VALET_HOME_PATH . '/dnsmasq.d', user()); } /** - * Append import command for our custom configuration to DnsMasq file. - * - * @param string $customConfigPath + * Create the TLD-specific dnsmasq config file + * @param string $tld * @return void */ - function appendCustomConfigImport($customConfigPath) + function createDnsmasqTldConfigFile($tld) { - $contents = preg_replace('/^conf-file=.*\/\.valet\/.*$/m', '', $this->files->get($this->configPath)); - $this->files->putAsUser($this->configPath, $contents); - - if (! $this->customConfigIsBeingImported($customConfigPath)) { - $this->files->appendAsUser( - $this->configPath, - PHP_EOL.'conf-file='.$customConfigPath.PHP_EOL - ); - } - } + $tldConfigFile = $this->dnsmasqUserConfigDir() . 'tld-' . $tld . '.conf'; - /** - * Determine if Valet's custom DnsMasq configuration is being imported. - * - * @param string $customConfigPath - * @return bool - */ - function customConfigIsBeingImported($customConfigPath) - { - return strpos($this->files->get($this->configPath), $customConfigPath) !== false; + $this->files->putAsUser($tldConfigFile, 'address=/.'.$tld.'/127.0.0.1'.PHP_EOL.'listen-address=127.0.0.1'.PHP_EOL); } /** @@ -143,8 +132,8 @@ function updateTld($oldTld, $newTld) * * @return string */ - function customConfigPath() + function dnsmasqUserConfigDir() { - return $_SERVER['HOME'].'/.config/valet/dnsmasq.conf'; + return $_SERVER['HOME'].'/.config/valet/dnsmasq.d/'; } } diff --git a/cli/stubs/etc-dnsmasq-valet.conf b/cli/stubs/etc-dnsmasq-valet.conf new file mode 100644 index 000000000..d6ac21fef --- /dev/null +++ b/cli/stubs/etc-dnsmasq-valet.conf @@ -0,0 +1,3 @@ +# Valet +# Include all *.conf files in user's valet directory +conf-dir=VALET_HOME_PATH/dnsmasq.d/,*.conf diff --git a/tests/DnsMasqTest.php b/tests/DnsMasqTest.php index 92fc6e506..b6b4279d2 100644 --- a/tests/DnsMasqTest.php +++ b/tests/DnsMasqTest.php @@ -38,18 +38,21 @@ public function test_install_installs_and_places_configuration_files_in_proper_l $dnsMasq = resolve(StubForCreatingCustomDnsMasqConfigFiles::class); - $dnsMasq->exampleConfigPath = __DIR__.'/files/dnsmasq.conf'; - $dnsMasq->configPath = __DIR__.'/output/dnsmasq.conf'; + + $dnsMasq->dnsmasqMasterConfigFile = __DIR__.'/output/dnsmasq.conf'; + $dnsMasq->dnsmasqSystemConfDir = __DIR__.'/output/dnsmasq.d'; $dnsMasq->resolverPath = __DIR__.'/output/resolver'; + file_put_contents($dnsMasq->dnsmasqMasterConfigFile, file_get_contents(__DIR__.'/files/dnsmasq.conf')); + $dnsMasq->install('test'); $this->assertSame('nameserver 127.0.0.1'.PHP_EOL, file_get_contents(__DIR__.'/output/resolver/test')); - $this->assertSame('address=/.test/127.0.0.1'.PHP_EOL.'listen-address=127.0.0.1'.PHP_EOL, file_get_contents(__DIR__.'/output/custom-dnsmasq.conf')); + $this->assertSame('address=/.test/127.0.0.1'.PHP_EOL.'listen-address=127.0.0.1'.PHP_EOL, file_get_contents(__DIR__.'/output/tld-test.conf')); $this->assertSame('test-contents - -conf-file='.__DIR__.'/output/custom-dnsmasq.conf -', file_get_contents(__DIR__.'/output/dnsmasq.conf')); +' . PHP_EOL . 'conf-dir=/usr/local/etc/dnsmasq.d/,*.conf' . PHP_EOL, + file_get_contents($dnsMasq->dnsmasqMasterConfigFile) + ); } @@ -66,8 +69,8 @@ public function test_update_tld_removes_old_resolver_and_reinstalls() class StubForCreatingCustomDnsMasqConfigFiles extends DnsMasq { - public function customConfigPath() + public function dnsmasqUserConfigDir() { - return __DIR__.'/output/custom-dnsmasq.conf'; + return __DIR__.'/output/'; } }