From 5845120deba55e25484263bd7f8e1ca9e5a72b98 Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Thu, 17 Sep 2020 06:27:39 -0600 Subject: [PATCH] Improve router-compose and ssh-auth-compose handling, fixes #1779, fixes #2476 (#2505) * Refactor router.go so that a ddev stop before start won't break things, fixes #1779 * the letsencrypt volume should not be created unless letsencrypt is being used * Allow overriding router-compose, fixes #2476 * Allow overriding ssh-auth-compose, fixes #2476 * Add tests for overriding router-compose and ssh-auth-compose --- cmd/ddev/cmd/global_dotddev_assets/.gitignore | 4 + cmd/ddev/cmd/packrd/packed-packr.go | 2 +- pkg/ddevapp/router.go | 89 ++++++++++++++----- pkg/ddevapp/router_test.go | 40 +++++++++ pkg/ddevapp/ssh_auth.go | 37 ++++++-- pkg/ddevapp/ssh_auth_test.go | 45 ++++++++++ pkg/ddevapp/templates.go | 2 + .../router-compose.override.yaml | 5 ++ .../ssh-auth-compose.override.yaml | 5 ++ 9 files changed, 199 insertions(+), 30 deletions(-) create mode 100644 pkg/ddevapp/testdata/TestRouterConfigOverride/router-compose.override.yaml create mode 100644 pkg/ddevapp/testdata/TestSshAuthConfigOverride/ssh-auth-compose.override.yaml diff --git a/cmd/ddev/cmd/global_dotddev_assets/.gitignore b/cmd/ddev/cmd/global_dotddev_assets/.gitignore index 8d6d59716df..fd0807eb4c0 100644 --- a/cmd/ddev/cmd/global_dotddev_assets/.gitignore +++ b/cmd/ddev/cmd/global_dotddev_assets/.gitignore @@ -1,4 +1,8 @@ #ddev-generated +/.router-compose.yaml +/.router-composer-full.yaml +/.ssh-auth-compose.yaml +/.ssh-auth-compose-full.yaml /.gitignore /**/*.example /**/README.* diff --git a/cmd/ddev/cmd/packrd/packed-packr.go b/cmd/ddev/cmd/packrd/packed-packr.go index d2cfc3a6ff7..0a31b7e6617 100644 --- a/cmd/ddev/cmd/packrd/packed-packr.go +++ b/cmd/ddev/cmd/packrd/packed-packr.go @@ -31,7 +31,7 @@ var _ = func() error { "70e36634c16a7624fd589b024278291e": "1f8b08000000000000ff6c8e316fc230108577ff8aabc34a0c5d2a59aa54689058aa5484764517e704ae826d7c4e21aafadf2bd3810e5d6e789fdefbaeb853ad75aa453e0851741d7d4ef7e42862a24e140554c426da90ac771a368303a6d3403d1a82b34d0730438ce41284e83fc824e830618b4cb9fbc6b8277d6be46c75c163e84983ccae1b9319d6cd760cc41a3a8c67eb72b4f69c96d6611c5717cb8935a84508bd35985f62d55c07000d951882104c09a617711a288e8ff238f2a9d74a45ef93cee7697eff50ceca5939d793afaa5abdefd675b3dd55cbdd6bbdd97eabae9542f8400ee4e4ba21618a20ff752e7e9dead9bb442eb17a4153377fa814e2270000fffff3fe1fe55f010000", "7b12f0fa2b5500e80bcf6b6c591bf919": "1f8b08000000000000ff6ccfbd4a05410c05e07e9e22cedaca05cba904b5102c44b4badc22bb739c8dec669649fc7b7b19c12dc4367c272719ce0ea3e861649b431872c6fb4581a2b1238761a01bd8d46473a99ae8f14d69e502f54ad7f777246a92413e833e30d254d55914ad079f8d0bd2ce8f2f0b173bd1915bb15307b79fbc6e0b12c5debac345cc23d5f667bcb2a843592724288f0bfe41f6b331b3736a3078ec3d0fadbe62f2a7af0db6df7319427ffb3718cfaf6208df010000ffffea8268380c010000", "7c6228a6c7ef5d0443d336cdab6123bc": "1f8b08000000000000ff7c92514fdb301485dff32baec4d3a4b6694b5b68df80666213902ccd98f6546eec9bd4c3b12ddb09e4df4f498a6063e32937cef9e2738fce09e7d48c4b5264d1130f76cc0ae31d0805fe201c706189796d5b781252424e40cfc46a4f1c7427213868e783bcf6dd4b0b0c15787c24207442b6c38ccc0bad3a8069e55128b20ef2166a2754193c7416fadf3e4ce002545de564411740aa1156ab8a948706adc05c9203b404ae36460ae2e075efc10dae03a198acb950e52608b6dbe87e7f9124691c671b28842470adf35481d40c0743454f1bab7f11f36f17fa34e0d7f12edb6f2ff7499c661bb8d10c65f7158cb6fe85e6e8314747e0c83664df803fa2cb5d94de47e987fc13e5efc8eb2c4b76ffa60a6de1e0bd719dddbfd86d7c356c9b92442f1a0283fe0085d515a031566bdf25c635ebc6d7fbee2e6ea30d5ce9aac2b123837d15400ad79bfcfc6d7bd787a2b0223750c975b2bf8fd2dd97f86e3878dd35fb99441b50a550cfe3c254234083ec40dd7c64d3f86b74951d85dcd606e5f9087c6bf4e90872648fdc6a3382276db9b1e4dc08c8b3c900a7f1f72c4afb808ef9a4baf664ff0ce79d76f781d805c1adb6f49fba55d876adc70685ec4e46e088066e1386a5f0873a9f305d85dcd63cecaa1ce652e7e172ceced6b325275accf8e27cb12ad6c56ab65ecea7f9d97cb55e2fd8f4f46cce96a1792c7b0c8d79794e4a7d72339b4e57e39bd9f4741afc0e0000ffff31f525faa5030000", - "7c9657a7540eafd259889c880f3e95a7": "1f8b08000000000000ff34cd3b0ec2301084e17eaf416729de33f04899060e80167be2585a3f143b086e8f10a1fc668affe03d9e4340c62a1d9ed886d863c86505b1316c2c5e92aafe741d8f9769b486f83cdd88839687e8dd953cc760df9294b84aee0b4a36c4c695544bc3fefc39cc9beabed9d6969824e0b445fdd6b7eaa583b8a375276e017d020000ffffa600161ea2000000", + "7c9657a7540eafd259889c880f3e95a7": "1f8b08000000000000ff6c8f31ce022110467baef17724c0197e75cb6df400668459200186c060f4f6c6a8c5ae96f3262f2fdf9f7378551e0b366074c2e84683b1294bb952477d879cbe6853cb48e9f3eb3d28181cb6ce96af241f39fa420d8591d2488d37c835bdaee3f47f98272d85d9cf27617ca20ba4b3a5b244fff62b140e48450a23d759f9abd67b88193cee464ccf91a33a601486b1b3051b503c020000ffff9466e5cb09010000", "800dae8de2a441a90553db3d618aab8b": "1f8b08000000000000ff7c93c16edb3c0cc7ef7e0a023d7d801327699236b9b58d3f74435b7b8ed761a74096685bab2c0a92ec366f3fd84ed16ddd7a1245f127927f5167426037a950a3651e45b0e7561aef406af0b57420a445eec91ee1592a050502be206f3d0a90da4981e06b0451049cb46752a39dc215e8b629d0029580ba93967483da43c7ac64854207cc22b8d618255180a7e10e37660e416aae5a2175b50d82dd2e7e3c5ca5699624f9164aa910dcd1796c4011675e92ee93f4b8b1f403b907d2c3b626e7ff1bf1db649f1f76d78734c9f22ddc1167aa3f0543d6bfd28279563087e0d076687f01bfc5d7fb387b8cb30ff9672cde91b7799eeeff4e9564a1f6deb8bedc3fd85d7233769ba1625e760886f91a4a4b0d30632c91ef2513c47bf32ddfc3d57dbc851b6a1a367168d8f09ea0a41b8afcffcbee611045b306dd48a5b7e9e131cef69f9287d1f1d66bfe3d8db7a02ba95f26a569426086f11a7bfbc466c9e7f8263f050adb1aa62e43f04743e721148c3f094b268467b2c258742e04f47c3ac259f2358fb341a0933e19b51eedefe2bc8bdd7f10ec82e09e2cfe63de1a76ec4797754caade1382431cb96d1455d2d76d31e5d444c2b622eabf4454282aa2d5825f6ce62b81b89c8be5e5725d6ecaf57cb35acc8a8bc57ab359f2d9f9c582af22f3540d1833e6759d567476379fcdd693bbf9ec7c16fc0c0000ffff750afb9f6a030000", "980540b4eafc1b28426dd9c06ca8db82": "1f8b08000000000000ff7c935f4fe33814c5dff329aec4d34ae95fda42fb06342b7605a49b6619f1546eecdbc6e0f85ab6d3d26f3f4a42c5cc30c393ff9d9f7ceeb1ef9994b4efedc890c340325a0ba76cf0a00c84527990ca9108ec8e70505a4341406f24ea401294f14a128492e0404524d80454865c1f9eb806810604db637b4e6f58594db0559a801dbcd43e80238315810a8be8b9da8374b52ffb2765bb7a8e61cbee44c78046820a2727822b8a10b4da1308ae2a34b21f455760eaaa2007bc05327be5d8546402ecd1292c34794047e06b6bb52209815b83be2b3b066584aea532bb45142d97c9e3e66ab5cad2345f74defdd107aa40b3c0a0d8349734b875fc4222009b7659b20f7f75f86dbace37cbebcd2acdf205dcb140dd9c8265174eb4c480057a024f6e4fee07f05b72bd4eb2c724fb923f50f189bccdf3d5faf75413691982f58ddd5fd8657ad3559b91c6d0246b3194b0755c015aeb9843139964d14c3fee7bb8ba4f1670d3bc42cf93c5f6338156be35f9f77fcb873694e6c17d47ad6e579bc7245bff933e741b1fb5e64fab640166a7cc5b6f6bab18d0a228a999bfb359fa6f7293bf0ba5ab2deacb18c2d1f2790c058a57e9d8c6706027ad23ef63a020fa1d9ca5ffe749d606f49e4fc67520f773389fb4eb2fc43e8aeed9d11ffe5b85c7a66f708f4a373b3178a28e5b0c063b15cabae80bae06d2d572d0f4e3a0d05c0ca66371311f4d25d16424279793d976be9d8de6d3f1b0b818cfe6f389189e5f8cc574605f772d86d69ec6fe8ecfee46c3e1ac77371a9e0fa3ef010000ffff2ce872f4e7030000", "a06cff5b1ff09738b67c168ae71914e7": "1f8b08000000000000ff1ccd314ec4301005d0dea7f8920b24a4ec0da8105bad2868a88de73b19e48c23cfb090db23b8c07b195984f765a57196a0a48c973be7199bda0a35c446d4b1efc5c4213a5963cc13468ae3764557e34213b5d553c6eb083cbfddae288e36c78e773519df7e49191fc537d00f562dbd9ff8fcf2402df610a8e320b441034dffa67f430d055ea71e71498f58823f018efed45bfa0d0000ffff5624b0f4ba000000", diff --git a/pkg/ddevapp/router.go b/pkg/ddevapp/router.go index 1a157d69cb0..fc46f2b51f0 100644 --- a/pkg/ddevapp/router.go +++ b/pkg/ddevapp/router.go @@ -9,6 +9,7 @@ import ( "html/template" "os" "path" + "path/filepath" "sort" "strings" @@ -25,20 +26,29 @@ const RouterProjectName = "ddev-router" // RouterComposeYAMLPath returns the full filepath to the routers docker-compose yaml file. func RouterComposeYAMLPath() string { globalDir := globalconfig.GetGlobalDdevDir() - dest := path.Join(globalDir, "router-compose.yaml") + dest := path.Join(globalDir, ".router-compose.yaml") + return dest +} + +// FullRenderedRouterComposeYAMLPath returns the path of the full rendered .router-compose-full.yaml +func FullRenderedRouterComposeYAMLPath() string { + globalDir := globalconfig.GetGlobalDdevDir() + dest := path.Join(globalDir, ".router-compose-full.yaml") return dest } // StopRouterIfNoContainers stops the router if there are no ddev containers running. func StopRouterIfNoContainers() error { - + dest, err := generateRouterCompose() + if err != nil { + return err + } containersRunning, err := ddevContainersRunning() if err != nil { return err } if !containersRunning { - dest := RouterComposeYAMLPath() _, _, err = dockerutil.ComposeCmd([]string{dest}, "-p", RouterProjectName, "down") return err } @@ -47,21 +57,49 @@ func StopRouterIfNoContainers() error { // StartDdevRouter ensures the router is running. func StartDdevRouter() error { - newExposedPorts := determineRouterPorts() + routerComposeFullPath, err := generateRouterCompose() + if err != nil { + return err + } + err = CheckRouterPorts() + if err != nil { + return fmt.Errorf("Unable to listen on required ports, %v,\nTroubleshooting suggestions at https://ddev.readthedocs.io/en/stable/users/troubleshooting/#unable-listen", err) + } + + // run docker-compose up -d against the ddev-router full compose file + _, _, err = dockerutil.ComposeCmd([]string{routerComposeFullPath}, "-p", RouterProjectName, "up", "-d") + if err != nil { + return fmt.Errorf("failed to start ddev-router: %v", err) + } + + // ensure we have a happy router + label := map[string]string{"com.docker.compose.service": "ddev-router"} + logOutput, err := dockerutil.ContainerWait(containerWaitTimeout, label) + if err != nil { + return fmt.Errorf("ddev-router failed to become ready; debug with 'docker logs ddev-router'; logOutput=%s, err=%v", logOutput, err) + } + + return nil +} - routerComposePath := RouterComposeYAMLPath() +// generateRouterCompose() generates the ~/.ddev/.router-compose.yaml and ~/.ddev/.router-compose-full.yaml +func generateRouterCompose() (string, error) { + exposedPorts := determineRouterPorts() + + routerComposeBasePath := RouterComposeYAMLPath() + routerComposeFullPath := FullRenderedRouterComposeYAMLPath() var doc bytes.Buffer - f, ferr := os.Create(routerComposePath) + f, ferr := os.Create(routerComposeBasePath) if ferr != nil { - return ferr + return "", ferr } defer util.CheckClose(f) templ := template.New("routerTemplate") templ, err := templ.Parse(DdevRouterTemplate) if err != nil { - return err + return "", err } dockerIP, _ := dockerutil.GetDockerIP() @@ -69,7 +107,7 @@ func StartDdevRouter() error { templateVars := map[string]interface{}{ "router_image": version.RouterImage, "router_tag": version.RouterTag, - "ports": newExposedPorts, + "ports": exposedPorts, "router_bind_all_interfaces": globalconfig.DdevGlobalConfig.RouterBindAllInterfaces, "compose_version": version.DockerComposeFileFormatVersion, "dockerIP": dockerIP, @@ -79,29 +117,34 @@ func StartDdevRouter() error { } err = templ.Execute(&doc, templateVars) - util.CheckErr(err) + if err != nil { + return "", err + } _, err = f.WriteString(doc.String()) - util.CheckErr(err) - - err = CheckRouterPorts() if err != nil { - return fmt.Errorf("Unable to listen on required ports, %v,\nTroubleshooting suggestions at https://ddev.readthedocs.io/en/stable/users/troubleshooting/#unable-listen", err) + return "", err } - // run docker-compose up -d against the ddev-router compose file - _, _, err = dockerutil.ComposeCmd([]string{routerComposePath}, "-p", RouterProjectName, "up", "-d") + fullHandle, err := os.Create(routerComposeFullPath) if err != nil { - return fmt.Errorf("failed to start ddev-router: %v", err) + return "", err } - // ensure we have a happy router - label := map[string]string{"com.docker.compose.service": "ddev-router"} - logOutput, err := dockerutil.ContainerWait(containerWaitTimeout, label) + userFiles, err := filepath.Glob(filepath.Join(globalconfig.GetGlobalDdevDir(), "router-compose.*.yaml")) if err != nil { - return fmt.Errorf("ddev-router failed to become ready; debug with 'docker logs ddev-router'; logOutput=%s, err=%v", logOutput, err) + return "", err + } + files := append([]string{RouterComposeYAMLPath()}, userFiles...) + fullContents, _, err := dockerutil.ComposeCmd(files, "config") + if err != nil { + return "", err + } + _, err = fullHandle.WriteString(fullContents) + if err != nil { + return "", err } - return nil + return routerComposeFullPath, nil } // FindDdevRouter usees FindContainerByLabels to get our router container and @@ -158,7 +201,7 @@ func GetRouterStatus() (string, string) { // determineRouterPorts returns a list of port mappings retrieved from running site // containers defining VIRTUAL_PORT env var func determineRouterPorts() []string { - var routerPorts []string + routerPorts := []string{"80"} labels := map[string]string{ "com.ddev.platform": "ddev", } diff --git a/pkg/ddevapp/router_test.go b/pkg/ddevapp/router_test.go index 4008cb5c988..7d4c7cbf422 100644 --- a/pkg/ddevapp/router_test.go +++ b/pkg/ddevapp/router_test.go @@ -7,6 +7,8 @@ import ( "github.com/drud/ddev/pkg/netutil" "github.com/drud/ddev/pkg/nodeps" "github.com/stretchr/testify/require" + "os" + "path/filepath" "strconv" "strings" "testing" @@ -147,3 +149,41 @@ func TestLetsEncrypt(t *testing.T) { _, _, err = dockerutil.Exec(container.ID, "test -f /etc/letsencrypt/options-ssl-nginx.conf") assert.NoError(err) } + +// TestRouterConfigOverride tests that the ~/.ddev/.router-compose.yaml can be overridden +// with ~/.ddev/router-compose.*.yaml +func TestRouterConfigOverride(t *testing.T) { + assert := asrt.New(t) + pwd, _ := os.Getwd() + testDir := testcommon.CreateTmpDir(t.Name()) + _ = os.Chdir(testDir) + overrideYaml := filepath.Join(globalconfig.GetGlobalDdevDir(), "router-compose.override.yaml") + + testcommon.ClearDockerEnv() + + app, err := ddevapp.NewApp(testDir, true, nodeps.ProviderDefault) + assert.NoError(err) + err = app.WriteConfig() + assert.NoError(err) + err = fileutil.CopyFile(filepath.Join(pwd, "testdata", t.Name(), "router-compose.override.yaml"), overrideYaml) + assert.NoError(err) + + answer := fileutil.RandomFilenameBase() + os.Setenv("ANSWER", answer) + assert.NoError(err) + t.Cleanup(func() { + err = app.Stop(true, false) + assert.NoError(err) + err = os.Chdir(pwd) + assert.NoError(err) + _ = os.RemoveAll(testDir) + err = os.Remove(overrideYaml) + assert.NoError(err) + }) + + err = app.Start() + assert.NoError(err) + + stdout, _, err := dockerutil.Exec("ddev-router", "bash -c 'echo $ANSWER'") + assert.Equal(answer+"\n", stdout) +} diff --git a/pkg/ddevapp/ssh_auth.go b/pkg/ddevapp/ssh_auth.go index b3fc1dc4c06..4f2d6f3337d 100644 --- a/pkg/ddevapp/ssh_auth.go +++ b/pkg/ddevapp/ssh_auth.go @@ -18,10 +18,18 @@ import ( // SSHAuthName is the "machine name" of the ddev-ssh-agent docker-compose service const SSHAuthName = "ddev-ssh-agent" -// SSHAuthComposeYAMLPath returns the full filepath to the ssh-auth docker-compose yaml file. +// SSHAuthComposeYAMLPath returns the filepath to the base .ssh-auth-compose yaml file. func SSHAuthComposeYAMLPath() string { globalDir := globalconfig.GetGlobalDdevDir() - dest := path.Join(globalDir, "ssh-auth-compose.yaml") + dest := path.Join(globalDir, ".ssh-auth-compose.yaml") + return dest +} + +// FullRenderedSSHAuthComposeYAMLPath returns the filepath to the rendered +//.ssh-auth-compose-full.yaml file. +func FullRenderedSSHAuthComposeYAMLPath() string { + globalDir := globalconfig.GetGlobalDdevDir() + dest := path.Join(globalDir, ".ssh-auth-compose-full.yaml") return dest } @@ -92,10 +100,8 @@ func RemoveSSHAgentContainer() error { // CreateSSHAuthComposeFile creates the docker-compose file for the ddev-ssh-agent func CreateSSHAuthComposeFile() (string, error) { - sshAuthComposePath := SSHAuthComposeYAMLPath() - var doc bytes.Buffer - f, ferr := os.Create(sshAuthComposePath) + f, ferr := os.Create(SSHAuthComposeYAMLPath()) if ferr != nil { return "", ferr } @@ -129,7 +135,26 @@ func CreateSSHAuthComposeFile() (string, error) { util.CheckErr(err) _, err = f.WriteString(doc.String()) util.CheckErr(err) - return sshAuthComposePath, nil + + fullHandle, err := os.Create(FullRenderedSSHAuthComposeYAMLPath()) + if err != nil { + return "", err + } + + userFiles, err := filepath.Glob(filepath.Join(globalconfig.GetGlobalDdevDir(), "ssh-auth-compose.*.yaml")) + if err != nil { + return "", err + } + files := append([]string{SSHAuthComposeYAMLPath()}, userFiles...) + fullContents, _, err := dockerutil.ComposeCmd(files, "config") + if err != nil { + return "", err + } + _, err = fullHandle.WriteString(fullContents) + if err != nil { + return "", err + } + return FullRenderedSSHAuthComposeYAMLPath(), nil } // findDdevSSHAuth usees FindContainerByLabels to get our sshAuth container and diff --git a/pkg/ddevapp/ssh_auth_test.go b/pkg/ddevapp/ssh_auth_test.go index a1d9e564e98..7b538b5ab34 100644 --- a/pkg/ddevapp/ssh_auth_test.go +++ b/pkg/ddevapp/ssh_auth_test.go @@ -5,6 +5,8 @@ import ( "github.com/drud/ddev/pkg/dockerutil" "github.com/drud/ddev/pkg/exec" "github.com/drud/ddev/pkg/fileutil" + "github.com/drud/ddev/pkg/globalconfig" + "github.com/drud/ddev/pkg/nodeps" "github.com/drud/ddev/pkg/testcommon" "github.com/drud/ddev/pkg/util" "github.com/drud/ddev/pkg/version" @@ -125,3 +127,46 @@ func TestSSHAuth(t *testing.T) { runTime() switchDir() } + +// TestSshAuthConfigOverride tests that the ~/.ddev/.ssh-auth-compose-compose.yaml can be overridden +// with ~/.ddev/ssh-auth-compose.*.yaml +func TestSshAuthConfigOverride(t *testing.T) { + assert := asrt.New(t) + pwd, _ := os.Getwd() + testDir := testcommon.CreateTmpDir(t.Name()) + _ = os.Chdir(testDir) + overrideYaml := filepath.Join(globalconfig.GetGlobalDdevDir(), "ssh-auth-compose.override.yaml") + + // Remove the ddev-ssh-agent, since the start code simply checks to see if it's + // running and doesn't restart it if it's running + _ = dockerutil.RemoveContainer("ddev-ssh-agent", 0) + + testcommon.ClearDockerEnv() + + app, err := ddevapp.NewApp(testDir, true, nodeps.ProviderDefault) + assert.NoError(err) + err = app.WriteConfig() + assert.NoError(err) + err = fileutil.CopyFile(filepath.Join(pwd, "testdata", t.Name(), "ssh-auth-compose.override.yaml"), overrideYaml) + assert.NoError(err) + + answer := fileutil.RandomFilenameBase() + os.Setenv("ANSWER", answer) + assert.NoError(err) + assert.NoError(err) + t.Cleanup(func() { + err = app.Stop(true, false) + assert.NoError(err) + err = os.Chdir(pwd) + assert.NoError(err) + _ = os.RemoveAll(testDir) + err = os.Remove(overrideYaml) + assert.NoError(err) + }) + + err = app.Start() + assert.NoError(err) + + stdout, _, err := dockerutil.Exec("ddev-ssh-agent", "bash -c 'echo $ANSWER'") + assert.Equal(answer+"\n", stdout) +} diff --git a/pkg/ddevapp/templates.go b/pkg/ddevapp/templates.go index 479d7c74a1c..457ea6b5bd0 100644 --- a/pkg/ddevapp/templates.go +++ b/pkg/ddevapp/templates.go @@ -449,8 +449,10 @@ networks: volumes: ddev-global-cache: name: ddev-global-cache +{{ if .letsencrypt }} ddev-router-letsencrypt: name: ddev-router-letsencrypt +{{ end }} ` const DdevSSHAuthTemplate = `version: '{{ .compose_version }}' diff --git a/pkg/ddevapp/testdata/TestRouterConfigOverride/router-compose.override.yaml b/pkg/ddevapp/testdata/TestRouterConfigOverride/router-compose.override.yaml new file mode 100644 index 00000000000..b44e2956791 --- /dev/null +++ b/pkg/ddevapp/testdata/TestRouterConfigOverride/router-compose.override.yaml @@ -0,0 +1,5 @@ +version: '3.6' +services: + ddev-router: + environment: + - ANSWER diff --git a/pkg/ddevapp/testdata/TestSshAuthConfigOverride/ssh-auth-compose.override.yaml b/pkg/ddevapp/testdata/TestSshAuthConfigOverride/ssh-auth-compose.override.yaml new file mode 100644 index 00000000000..e59dc4e45cd --- /dev/null +++ b/pkg/ddevapp/testdata/TestSshAuthConfigOverride/ssh-auth-compose.override.yaml @@ -0,0 +1,5 @@ +version: '3.6' +services: + ddev-ssh-agent: + environment: + - ANSWER