From 017037586c7fb9a132e6ca2f9d82357f438afb0c Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 22 Mar 2021 01:05:35 -0400 Subject: [PATCH] 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 {