From 017037586c7fb9a132e6ca2f9d82357f438afb0c Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 22 Mar 2021 01:05:35 -0400 Subject: [PATCH 01/12] feat: add ability to specify the initial container network Closes #4477 --- docs/networking/network.md | 23 +++++++++++++++++-- plugins/network/network.go | 5 ++++- plugins/network/report.go | 28 ++++++++++++++++++++---- plugins/network/src/triggers/triggers.go | 9 ++++++++ plugins/network/triggers.go | 17 ++++++++++++++ 5 files changed, 75 insertions(+), 7 deletions(-) diff --git a/docs/networking/network.md b/docs/networking/network.md index 7e87636b2..3c018be9f 100644 --- a/docs/networking/network.md +++ b/docs/networking/network.md @@ -127,7 +127,7 @@ dokku network:info test-network > New as of 0.20.0, Requires Docker 1.21+ -Apps will default to being associated with the `bridge` network, but can be attached to `attachable` networks by changing the `attach-post-create` or `attach-post-deploy` network properties when using the [docker-local scheduler](/docs/advanced-usage/schedulers/docker-local.md). A change in these values will require an app deploy or rebuild. +Apps will default to being associated with the `bridge` network, but can be attached to `attachable` networks by changing the `attach-post-create` or `attach-post-deploy` network properties when using the [docker-local scheduler](/docs/advanced-usage/schedulers/docker-local.md). Additionally, it can be attached to an initial network via the `initial-network` property. A change in these values will require an app deploy or rebuild. ```shell # associates the network after a container is created but before it is started @@ -135,6 +135,9 @@ dokku network:set node-js-app attach-post-create test-network # associates the network after the deploy is successful but before the proxy is updated dokku network:set node-js-app attach-post-deploy other-test-network + +# associates the network at container creation +dokku network:set node-js-app initial-network global-network ``` Setting the `attach` network property to an empty value will de-associate the container with the network. @@ -142,6 +145,13 @@ Setting the `attach` network property to an empty value will de-associate the co ```shell dokku network:set node-js-app attach-post-create dokku network:set node-js-app attach-post-deploy +dokku network:set node-js-app initial-network +``` + +Finally, the `initial-network` property can be set globally by using the `--global` flag in place of the app name. + +```shell +dokku network:set --global initial-network global-network ``` #### Network Aliases @@ -203,8 +213,17 @@ Whatever the reason, the semantics of the two network hooks are important and ar - Container state on attach: `running` - Use case: When another container on the network needs to access _this_ container. - Example: A background process needs to communicate with the web process exposed by this container. +- `initial-network`: + - Phase it applies to: + - `build`: Intermediate containers created during the build process. + - `deploy`: Deployed app containers. + - `run`: Containers created by the `run` command. + - Container state on attach: `created` + - Use case: When another container on the network is already running and needed by this container. + - Example: A key-value store exposing itself to all your apps may be on the `initial-network`. -> Warning: If the attachment fails at this stage, this may result in your application failing to respond to proxied requests once older containers are removed. + +> Warning: If the attachment fails during the `running` container state, this may result in your application failing to respond to proxied requests once older containers are removed. ### Rebuilding network settings diff --git a/plugins/network/network.go b/plugins/network/network.go index 954083f1e..90d60d727 100644 --- a/plugins/network/network.go +++ b/plugins/network/network.go @@ -20,11 +20,14 @@ var ( "bind-all-interfaces": "false", "attach-post-create": "", "attach-post-deploy": "", + "initial-network": "", "tld": "", } // GlobalProperties is a map of all valid global network properties - GlobalProperties = map[string]bool{} + GlobalProperties = map[string]bool{ + "initial-network": true, + } ) // BuildConfig builds network config files diff --git a/plugins/network/report.go b/plugins/network/report.go index 23b876f73..e67ef460a 100644 --- a/plugins/network/report.go +++ b/plugins/network/report.go @@ -13,10 +13,13 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { } flags := map[string]common.ReportFunc{ - "--network-bind-all-interfaces": reportBindAllInterfaces, - "--network-attach-post-create": reportAttachPostCreate, - "--network-attach-post-deploy": reportAttachPostDeploy, - "--network-web-listeners": reportWebListeners, + "--network-bind-all-interfaces": reportBindAllInterfaces, + "--network-attach-post-create": reportAttachPostCreate, + "--network-attach-post-deploy": reportAttachPostDeploy, + "--network-computed-initial-network": reportComputedInitialNetwork, + "--network-global-initial-network": reportGlobalInitialNetwork, + "--network-initial-network": reportInitialNetwork, + "--network-web-listeners": reportWebListeners, } flagKeys := []string{} @@ -42,6 +45,23 @@ func reportAttachPostDeploy(appName string) string { return common.PropertyGet("network", appName, "attach-post-deploy") } +func reportComputedInitialNetwork(appName string) string { + value := reportInitialNetwork(appName) + if value == "" { + value = reportGlobalInitialNetwork(appName) + } + + return value +} + +func reportGlobalInitialNetwork(appName string) string { + return common.PropertyGet("network", "--global", "initial-network") +} + +func reportInitialNetwork(appName string) string { + return common.PropertyGet("network", appName, "initial-network") +} + func reportWebListeners(appName string) string { return strings.Join(GetListeners(appName, "web"), " ") } diff --git a/plugins/network/src/triggers/triggers.go b/plugins/network/src/triggers/triggers.go index 0ce27d43a..625180f24 100644 --- a/plugins/network/src/triggers/triggers.go +++ b/plugins/network/src/triggers/triggers.go @@ -18,6 +18,15 @@ func main() { var err error switch trigger { + case "docker-args-process-build": + appName := flag.Arg(0) + err = network.TriggerDockerArgsProcess(appName) + case "docker-args-process-deploy": + appName := flag.Arg(0) + err = network.TriggerDockerArgsProcess(appName) + case "docker-args-process-run": + appName := flag.Arg(0) + err = network.TriggerDockerArgsProcess(appName) case "install": err = network.TriggerInstall() case "network-build-config": diff --git a/plugins/network/triggers.go b/plugins/network/triggers.go index 23b39bf02..06ba13f0a 100644 --- a/plugins/network/triggers.go +++ b/plugins/network/triggers.go @@ -2,6 +2,7 @@ package network import ( "fmt" + "io/ioutil" "os" "strings" "unicode/utf8" @@ -10,6 +11,22 @@ import ( "github.com/dokku/dokku/plugins/config" ) +// TriggerDockerArgsProcess outputs the network plugin docker options for an app +func TriggerDockerArgsProcess(appName string) error { + stdin, err := ioutil.ReadAll(os.Stdin) + if err != nil { + return err + } + + initialNetwork := reportComputedInitialNetwork(appName) + if initialNetwork != "" { + fmt.Printf(" --network=%s ", initialNetwork) + } + + fmt.Print(string(stdin)) + return nil +} + // TriggerInstall runs the install step for the network plugin func TriggerInstall() error { if err := common.PropertySetup("network"); err != nil { From 21aef2eef1cae4369b4e34e29dbd51b2f81fcdbe Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 22 Mar 2021 01:05:46 -0400 Subject: [PATCH 02/12] chore: properly format go.mod files --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 2c518168b..b4d8d412f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -15,7 +15,7 @@ insert_final_newline = true indent_style = tab indent_size = 4 -[*.go] +[*.{go,mod}] insert_final_newline = true indent_style = tab indent_size = 4 From 84907be0cdbc233704581418b976051567179ef9 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 22 Mar 2021 01:05:57 -0400 Subject: [PATCH 03/12] fix: gitignore binaries in common plugin --- plugins/common/.gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/common/.gitignore b/plugins/common/.gitignore index a39ded4ae..100934a87 100644 --- a/plugins/common/.gitignore +++ b/plugins/common/.gitignore @@ -1 +1,6 @@ /prop +/common +/core-post-deploy +/install +/post-delete +/triggers From 8d26d06f5e72b924c6db4384cd4827e8c5e5e7ed Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 22 Mar 2021 17:13:54 -0400 Subject: [PATCH 04/12] feat: allow all network properties to be globally set Global settings are cool if managed in a standard way (ugh env vars) so we'll add them back for golang plugins as necessary. --- docs/networking/network.md | 116 ++++++++++++++++++++++++++++++++--- plugins/network/functions.go | 15 ++--- plugins/network/network.go | 8 ++- plugins/network/report.go | 87 ++++++++++++++++++++++---- plugins/network/triggers.go | 25 +++++--- 5 files changed, 210 insertions(+), 41 deletions(-) diff --git a/docs/networking/network.md b/docs/networking/network.md index 3c018be9f..da5681de7 100644 --- a/docs/networking/network.md +++ b/docs/networking/network.md @@ -148,12 +148,22 @@ dokku network:set node-js-app attach-post-deploy dokku network:set node-js-app initial-network ``` -Finally, the `initial-network` property can be set globally by using the `--global` flag in place of the app name. +The network properties can also be set globally. The global default is emty string, and the global value is used when no app-specific value is set. ```shell +dokku network:set --global attach-post-create global-create-network +dokku network:set --global attach-post-deploy global-deploy-network dokku network:set --global initial-network global-network ``` +The default value may be set by passing an empty value for the option. + +```shell +dokku network:set --global attach-post-create +dokku network:set --global attach-post-deploy +dokku network:set --global initial-network +``` + #### Network Aliases When a container created for a deployment is being attached to a network - regardless of which `attach` property was used - a network alias of the pattern `APP.PROC_TYPE` will be added to all containers. This can be used to load-balance requests between containers. For an application named `node-js-app` with a process type of web, the network alias - or resolvable DNS record within the network - will be: @@ -172,7 +182,7 @@ Dockerfile-based applications may listen on other ports. For more information on #### Specifying a custom TLD -When attaching applications to networks, a custom TLD can be specified via the `network:set` command. This TLD is suffixed to the network alias for the application/process-type combination for _all_ networks to which the application is attached, and cannot be customized per network. +When attaching applications to networks, a custom TLD can be specified via the `network:set` command. This TLD is suffixed to the network alias for the application/process-type combination for _all_ networks to which the application is attached, and cannot be customized per network. The default value is an empty string. To specify a TLD of `svc.cluster.local` for your application, run the following command: @@ -189,6 +199,24 @@ node-js-app.web.svc.cluster.local Note that this has no impact on container port handling, and users must still specify the container port when making internal network requests. +The default value may be set by passing an empty value for the option: + +```shell +dokku network:set node-js-app tld +``` + +The `tld` property can also be set globally. The global default is emty string, and the global value is used when no app-specific value is set. + +```shell +dokku network:set --global tld svc.cluster.local +``` + +The default value may be set by passing an empty value for the option. + +```shell +dokku network:set --global tld +``` + #### When to attach containers to a network Containers can be attached to a network for a variety of reasons: @@ -297,6 +325,18 @@ CONTAINER ID IMAGE COMMAND CREATED d6499edb0edb dokku/node-js-app:latest "/bin/bash -c '/star About a minute ago Up About a minute 0.0.0.0:49153->5000/tcp node-js-app.web.1 ``` +The `bind-all-interfaces` property can also be set globally. The global default is `false`, and the global value is used when no app-specific value is set. + +```shell +dokku network:set --global bind-all-interfaces true +``` + +The default value may be set by passing an empty value for the option. + +```shell +dokku network:set --global bind-all-interfaces +``` + ### Displaying network reports for an app You can get a report about the app's network status using the `network:report` command: @@ -307,14 +347,56 @@ dokku network:report ``` =====> node-js-app network information - Network bind all interfaces: false - Network listeners: 172.17.0.1:5000 + Network attach post create: + Network attach post deploy: + Network bind all interfaces: false + Network computed attach post create: + Network computed attach post deploy: + Network computed bind all interfaces:false + Network computed initial network: + Network computed tld: + Network global attach post create: + Network global attach post deploy: + Network global bind all interfaces:false + Network global initial network: + Network global tld: + Network initial network: + Network tld: + Network web listeners: 172.17.0.1:5000 =====> python-sample network information - Network bind all interfaces: false - Network listeners: 172.17.0.2:5000 + Network attach post create: + Network attach post deploy: + Network bind all interfaces: false + Network computed attach post create: + Network computed attach post deploy: + Network computed bind all interfaces:false + Network computed initial network: + Network computed tld: + Network global attach post create: + Network global attach post deploy: + Network global bind all interfaces:false + Network global initial network: + Network global tld: + Network initial network: + Network tld: + Network web listeners: 172.17.0.2:5000 =====> ruby-sample network information - Network bind all interfaces: true - Network listeners: + Network attach post create: + Network attach post deploy: + Network bind all interfaces: false + Network computed attach post create: + Network computed attach post deploy: + Network computed bind all interfaces:false + Network computed initial network: + Network computed tld: + Network global attach post create: + Network global attach post deploy: + Network global bind all interfaces:false + Network global initial network: + Network global tld: + Network initial network: + Network tld: + Network web listeners: ``` You can run the command for a specific app also. @@ -325,8 +407,22 @@ dokku network:report node-js-app ``` =====> node-js-app network information - Network bind all interfaces: false - Network listeners: 172.17.0.1:5000 + Network attach post create: + Network attach post deploy: + Network bind all interfaces: false + Network computed attach post create: + Network computed attach post deploy: + Network computed bind all interfaces:false + Network computed initial network: + Network computed tld: + Network global attach post create: + Network global attach post deploy: + Network global bind all interfaces:false + Network global initial network: + Network global tld: + Network initial network: + Network tld: + Network web listeners: 172.17.0.1:5000 ``` You can pass flags which will output only the value of the specific information you want. For example: diff --git a/plugins/network/functions.go b/plugins/network/functions.go index 17d0ee8e8..28badd79c 100644 --- a/plugins/network/functions.go +++ b/plugins/network/functions.go @@ -20,9 +20,7 @@ func attachAppToNetwork(containerID string, networkName string, appName string, } if phase == "deploy" { - property := "tld" - defaultValue := GetDefaultValue(property) - tld := common.PropertyGetDefault("network", appName, property, defaultValue) + tld := reportComputedTld(appName) networkAlias := fmt.Sprintf("%v.%v", appName, processType) if tld != "" { @@ -62,14 +60,13 @@ func isConflictingPropertyValue(appName string, property string, value string) b return false } - otherProperty := "attach-post-create" - if property == otherProperty { - otherProperty = "attach-post-deploy" + otherValue := "" + if property == "attach-post-create" { + otherValue = reportComputedAttachPostDeploy(appName) + } else { + otherValue = reportComputedAttachPostCreate(appName) } - defaultValue := GetDefaultValue(otherProperty) - otherValue := common.PropertyGetDefault("network", appName, otherProperty, defaultValue) - return value == otherValue } diff --git a/plugins/network/network.go b/plugins/network/network.go index 90d60d727..65cbca829 100644 --- a/plugins/network/network.go +++ b/plugins/network/network.go @@ -17,7 +17,7 @@ import ( var ( // DefaultProperties is a map of all valid network properties with corresponding default property values DefaultProperties = map[string]string{ - "bind-all-interfaces": "false", + "bind-all-interfaces": "", "attach-post-create": "", "attach-post-deploy": "", "initial-network": "", @@ -26,7 +26,11 @@ var ( // GlobalProperties is a map of all valid global network properties GlobalProperties = map[string]bool{ - "initial-network": true, + "bind-all-interfaces": true, + "attach-post-create": true, + "attach-post-deploy": true, + "initial-network": true, + "tld": true, } ) diff --git a/plugins/network/report.go b/plugins/network/report.go index e67ef460a..f3c3ed606 100644 --- a/plugins/network/report.go +++ b/plugins/network/report.go @@ -13,13 +13,22 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { } flags := map[string]common.ReportFunc{ - "--network-bind-all-interfaces": reportBindAllInterfaces, - "--network-attach-post-create": reportAttachPostCreate, - "--network-attach-post-deploy": reportAttachPostDeploy, - "--network-computed-initial-network": reportComputedInitialNetwork, - "--network-global-initial-network": reportGlobalInitialNetwork, - "--network-initial-network": reportInitialNetwork, - "--network-web-listeners": reportWebListeners, + "--network-bind-all-interfaces": reportBindAllInterfaces, + "--network-attach-post-create": reportAttachPostCreate, + "--network-attach-post-deploy": reportAttachPostDeploy, + "--network-computed-attach-post-create": reportComputedAttachPostCreate, + "--network-computed-attach-post-deploy": reportComputedAttachPostDeploy, + "--network-computed-bind-all-interfaces": reportComputedBindAllInterfaces, + "--network-computed-initial-network": reportComputedInitialNetwork, + "--network-computed-tld": reportComputedTld, + "--network-global-attach-post-create": reportGlobalAttachPostCreate, + "--network-global-attach-post-deploy": reportGlobalAttachPostDeploy, + "--network-global-bind-all-interfaces": reportGlobalBindAllInterfaces, + "--network-global-initial-network": reportGlobalInitialNetwork, + "--network-global-tld": reportGlobalTld, + "--network-initial-network": reportInitialNetwork, + "--network-tld": reportTld, + "--network-web-listeners": reportWebListeners, } flagKeys := []string{} @@ -33,10 +42,6 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { return common.ReportSingleApp("network", appName, infoFlag, infoFlags, flagKeys, format, trimPrefix, uppercaseFirstCharacter) } -func reportBindAllInterfaces(appName string) string { - return common.PropertyGet("network", appName, "bind-all-interfaces") -} - func reportAttachPostCreate(appName string) string { return common.PropertyGet("network", appName, "attach-post-create") } @@ -45,6 +50,37 @@ func reportAttachPostDeploy(appName string) string { return common.PropertyGet("network", appName, "attach-post-deploy") } +func reportBindAllInterfaces(appName string) string { + return common.PropertyGet("network", appName, "bind-all-interfaces") +} + +func reportComputedAttachPostCreate(appName string) string { + value := reportAttachPostCreate(appName) + if value == "" { + value = reportGlobalAttachPostCreate(appName) + } + + return value +} + +func reportComputedAttachPostDeploy(appName string) string { + value := reportAttachPostDeploy(appName) + if value == "" { + value = reportGlobalAttachPostDeploy(appName) + } + + return value +} + +func reportComputedBindAllInterfaces(appName string) string { + value := reportBindAllInterfaces(appName) + if value == "" { + value = reportGlobalBindAllInterfaces(appName) + } + + return value +} + func reportComputedInitialNetwork(appName string) string { value := reportInitialNetwork(appName) if value == "" { @@ -54,14 +90,43 @@ func reportComputedInitialNetwork(appName string) string { return value } +func reportComputedTld(appName string) string { + value := reportTld(appName) + if value == "" { + value = reportGlobalTld(appName) + } + + return value +} + +func reportGlobalAttachPostCreate(appName string) string { + return common.PropertyGet("network", "--global", "attach-post-create") +} + +func reportGlobalAttachPostDeploy(appName string) string { + return common.PropertyGet("network", "--global", "attach-post-deploy") +} + +func reportGlobalBindAllInterfaces(appName string) string { + return common.PropertyGetDefault("network", "--global", "bind-all-interfaces", "false") +} + func reportGlobalInitialNetwork(appName string) string { return common.PropertyGet("network", "--global", "initial-network") } +func reportGlobalTld(appName string) string { + return common.PropertyGet("network", "--global", "tld") +} + func reportInitialNetwork(appName string) string { return common.PropertyGet("network", appName, "initial-network") } +func reportTld(appName string) string { + return common.PropertyGet("network", appName, "tld") +} + func reportWebListeners(appName string) string { return strings.Join(GetListeners(appName, "web"), " ") } diff --git a/plugins/network/triggers.go b/plugins/network/triggers.go index 06ba13f0a..95c952d23 100644 --- a/plugins/network/triggers.go +++ b/plugins/network/triggers.go @@ -123,9 +123,20 @@ func TriggerNetworkGetPort(appName string, processType string, containerID strin // TriggerNetworkGetProperty writes the network property to stdout for a given app container func TriggerNetworkGetProperty(appName string, property string) error { - defaultValue := GetDefaultValue(property) - value := common.PropertyGetDefault("network", appName, property, defaultValue) - fmt.Println(value) + computedValueMap := map[string]common.ReportFunc{ + "attach-post-create": reportComputedAttachPostCreate, + "attach-post-deploy": reportComputedAttachPostDeploy, + "bind-all-interfaces": reportComputedBindAllInterfaces, + "initial-network": reportComputedInitialNetwork, + "tld": reportComputedTld, + } + + fn, ok := computedValueMap[property] + if !ok { + return fmt.Errorf("Invalid network property specified: %v", property) + } + + fmt.Println(fn(appName)) return nil } @@ -207,9 +218,7 @@ func TriggerPostContainerCreate(containerType string, containerID string, appNam } - property := "attach-post-create" - defaultValue := GetDefaultValue(property) - networkName := common.PropertyGetDefault("network", appName, property, defaultValue) + networkName := reportComputedAttachPostCreate(appName) if networkName == "" { return nil @@ -249,9 +258,7 @@ func TriggerPostDelete(appName string) error { // TriggerCorePostDeploy associates the container with a specified network func TriggerCorePostDeploy(appName string) error { - property := "attach-post-deploy" - defaultValue := GetDefaultValue(property) - networkName := common.PropertyGetDefault("network", appName, property, defaultValue) + networkName := reportComputedAttachPostDeploy(appName) if networkName == "" { return nil } From 012040d5c7eb9e4fb97210990738873b6a369ac9 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 16 Apr 2021 23:58:11 -0400 Subject: [PATCH 05/12] chore: drop unused function --- plugins/network/network.go | 9 --------- plugins/network/network_test.go | 12 ------------ 2 files changed, 21 deletions(-) delete mode 100644 plugins/network/network_test.go diff --git a/plugins/network/network.go b/plugins/network/network.go index 65cbca829..614d0e22f 100644 --- a/plugins/network/network.go +++ b/plugins/network/network.go @@ -158,15 +158,6 @@ func GetContainerPort(appName, processType string, containerID string, isHerokui return } -// GetDefaultValue returns the default value for a given property -func GetDefaultValue(property string) (value string) { - value, ok := DefaultProperties[property] - if ok { - return - } - return -} - // GetListeners returns a string array of app listeners func GetListeners(appName string, processType string) []string { appRoot := common.AppRoot(appName) diff --git a/plugins/network/network_test.go b/plugins/network/network_test.go deleted file mode 100644 index 9aed75050..000000000 --- a/plugins/network/network_test.go +++ /dev/null @@ -1,12 +0,0 @@ -package network - -import ( - "testing" - - . "github.com/onsi/gomega" -) - -func TestNetworkGetDefaultValue(t *testing.T) { - RegisterTestingT(t) - Expect(GetDefaultValue("bind-all-interfaces")).To(Equal("false")) -} From 3ed019d7089e5908ca9b2e025ea3b517d292be29 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sat, 17 Apr 2021 00:05:48 -0400 Subject: [PATCH 06/12] tests: add test for initial network --- tests/unit/network.bats | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/unit/network.bats b/tests/unit/network.bats index 4eddaf925..c34176a62 100644 --- a/tests/unit/network.bats +++ b/tests/unit/network.bats @@ -162,6 +162,11 @@ teardown() { echo "status: $status" assert_success + run /bin/bash -c "dokku network:create initial-network" + echo "output: $output" + echo "status: $status" + assert_success + run /bin/bash -c "dokku network:set $TEST_APP attach-post-create nonexistent-network" echo "output: $output" echo "status: $status" @@ -193,6 +198,11 @@ teardown() { echo "status: $status" assert_success + run /bin/bash -c "dokku network:set $TEST_APP initial-network initial-network" + echo "output: $output" + echo "status: $status" + assert_success + run /bin/bash -c "dokku ps:rebuild $TEST_APP" echo "output: $output" echo "status: $status" @@ -204,6 +214,11 @@ teardown() { echo "status: $status" assert_failure + run /bin/bash -c "dokku --force network:destroy initial-network" + echo "output: $output" + echo "status: $status" + assert_failure + run /bin/bash -c "dokku --force apps:destroy $TEST_APP" echo "output: $output" echo "status: $status" @@ -221,4 +236,9 @@ teardown() { echo "output: $output" echo "status: $status" assert_success + + run /bin/bash -c "dokku --force network:destroy initial-network" + echo "output: $output" + echo "status: $status" + assert_success } From bd894ceaaf7c77aea87a3e2ca9938ec0956ef214 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sat, 17 Apr 2021 00:15:24 -0400 Subject: [PATCH 07/12] docs: add note to migration guide --- docs/appendices/0.25.0-migration-guide.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/appendices/0.25.0-migration-guide.md diff --git a/docs/appendices/0.25.0-migration-guide.md b/docs/appendices/0.25.0-migration-guide.md new file mode 100644 index 000000000..6361d512d --- /dev/null +++ b/docs/appendices/0.25.0-migration-guide.md @@ -0,0 +1,5 @@ +# 0.25.0 Migration Guide + +## Changes + +- The network plugin can now set an `initial-network` for all containers on creation. This is a replacement for specifying the `--network` flag via the `docker-options` plugin. Please see the [network documentation](/docs/networking/network.md#attaching-an-app-to-a-network) for more information. From a086302fc5da230a6c574bced1b1bdb4dd4633d5 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 9 Jul 2021 21:12:43 -0400 Subject: [PATCH 08/12] fix: actually create the network triggers --- plugins/network/.gitignore | 3 +++ plugins/network/Makefile | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/network/.gitignore b/plugins/network/.gitignore index dee017e8f..efa5c21c7 100644 --- a/plugins/network/.gitignore +++ b/plugins/network/.gitignore @@ -7,3 +7,6 @@ /install /post-* /report +/docker-args-process-build +/docker-args-process-deploy +/docker-args-process-run diff --git a/plugins/network/Makefile b/plugins/network/Makefile index 32a94414d..0c2eff4bb 100644 --- a/plugins/network/Makefile +++ b/plugins/network/Makefile @@ -1,5 +1,5 @@ SUBCOMMANDS = subcommands/create subcommands/destroy subcommands/exists subcommands/info subcommands/list subcommands/rebuild subcommands/rebuildall subcommands/report subcommands/set -TRIGGERS = triggers/core-post-deploy triggers/install triggers/network-build-config triggers/network-compute-ports triggers/network-config-exists triggers/network-get-ipaddr triggers/network-get-listeners triggers/network-get-port triggers/network-get-property triggers/network-write-ipaddr triggers/network-write-port triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-container-create triggers/post-create triggers/post-delete triggers/report +TRIGGERS = triggers/core-post-deploy triggers/docker-args-process-build triggers/docker-args-process-deploy triggers/docker-args-process-run triggers/install triggers/network-build-config triggers/network-compute-ports triggers/network-config-exists triggers/network-get-ipaddr triggers/network-get-listeners triggers/network-get-port triggers/network-get-property triggers/network-write-ipaddr triggers/network-write-port triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-container-create triggers/post-create triggers/post-delete triggers/report BUILD = commands subcommands triggers PLUGIN_NAME = network From 267cc3fd54d9a71049a9bf24d755b534c724de21 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 9 Jul 2021 21:13:57 -0400 Subject: [PATCH 09/12] fix: respect custom networks when computing the container ip We also change the inspect format to support network names with non alphanumeric characters. See https://github.com/moby/moby/issues/35886 for details. --- plugins/network/network.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/network/network.go b/plugins/network/network.go index 614d0e22f..341234070 100644 --- a/plugins/network/network.go +++ b/plugins/network/network.go @@ -112,7 +112,12 @@ func GetContainerIpaddress(appName, processType, containerID string) (ipAddr str } } - b, err := common.DockerInspect(containerID, "{{.NetworkSettings.Networks.bridge.IPAddress}}") + initialNetwork := reportComputedInitialNetwork(appName) + if initialNetwork == "" { + initialNetwork = "bridge" + } + + b, err := common.DockerInspect(containerID, fmt.Sprintf("{{ $network := index .NetworkSettings.Networks \"%s\" }}{{ $network.IPAddress}}", initialNetwork)) if err != nil || len(b) == 0 { // docker < 1.9 compatibility b, err = common.DockerInspect(containerID, "{{ .NetworkSettings.IPAddress }}") From 50361505dbc380e8ae5c17a10cb2f3464bd95a53 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 9 Jul 2021 21:14:06 -0400 Subject: [PATCH 10/12] chore: add deprecation notice --- plugins/network/network.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/network/network.go b/plugins/network/network.go index 341234070..b7d77e8fd 100644 --- a/plugins/network/network.go +++ b/plugins/network/network.go @@ -119,7 +119,7 @@ func GetContainerIpaddress(appName, processType, containerID string) (ipAddr str b, err := common.DockerInspect(containerID, fmt.Sprintf("{{ $network := index .NetworkSettings.Networks \"%s\" }}{{ $network.IPAddress}}", initialNetwork)) if err != nil || len(b) == 0 { - // docker < 1.9 compatibility + // Deprecated: docker < 1.9 compatibility b, err = common.DockerInspect(containerID, "{{ .NetworkSettings.IPAddress }}") } From e8a4a4c89e5e95e4eb4759ab71e059216a5aae4b Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 9 Jul 2021 21:14:18 -0400 Subject: [PATCH 11/12] tests: always delete the initial-network in tests --- tests/unit/network.bats | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit/network.bats b/tests/unit/network.bats index c34176a62..596699448 100644 --- a/tests/unit/network.bats +++ b/tests/unit/network.bats @@ -15,6 +15,7 @@ teardown() { [[ -f "$DOKKU_ROOT/HOSTNAME.bak" ]] && mv "$DOKKU_ROOT/HOSTNAME.bak" "$DOKKU_ROOT/HOSTNAME" && chown dokku:dokku "$DOKKU_ROOT/HOSTNAME" docker network rm create-network || true docker network rm deploy-network || true + docker network rm initial-network || true global_teardown } From a3d9db0e00b6959d39f8b80c6f538e1e2473536e Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 9 Jul 2021 21:17:42 -0400 Subject: [PATCH 12/12] docs: clarify bridge network --- docs/networking/network.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/networking/network.md b/docs/networking/network.md index da5681de7..01869cece 100644 --- a/docs/networking/network.md +++ b/docs/networking/network.md @@ -127,7 +127,7 @@ dokku network:info test-network > New as of 0.20.0, Requires Docker 1.21+ -Apps will default to being associated with the `bridge` network, but can be attached to `attachable` networks by changing the `attach-post-create` or `attach-post-deploy` network properties when using the [docker-local scheduler](/docs/advanced-usage/schedulers/docker-local.md). Additionally, it can be attached to an initial network via the `initial-network` property. A change in these values will require an app deploy or rebuild. +Apps will default to being associated with the default `bridge` network or a network specified by the `initial-network` network property. Additionally, an app can be attached to `attachable` networks by changing the `attach-post-create` or `attach-post-deploy` network properties when using the [docker-local scheduler](/docs/advanced-usage/schedulers/docker-local.md). A change in these values will require an app deploy or rebuild. ```shell # associates the network after a container is created but before it is started