feat: implement container network attaching

Containers can be attached:

- after they are created, but before they are started
- after a successful deploy, but before the proxy reloads

This allows folks to have flexibility around when they would like a container to be made available to a network.
This commit is contained in:
Jose Diaz-Gonzalez
2020-02-03 04:37:31 -05:00
parent 8eb32e4371
commit 9818cc6461
13 changed files with 384 additions and 20 deletions

View File

@@ -1,11 +1,132 @@
package network
import (
"bytes"
"errors"
"fmt"
"os"
"strings"
"github.com/dokku/dokku/plugins/common"
)
// CommandCreate is an alias for "docker network create"
func CommandCreate(networkName string) error {
common.LogInfo1Quiet(fmt.Sprintf("Creating network %v", networkName))
createCmd := common.NewShellCmd(strings.Join([]string{
common.DockerBin(),
"network",
"create",
"--attachable",
"--label",
"com.dokku.network=true",
"--label",
fmt.Sprintf("com.dokku.network-name=%v", networkName),
networkName,
}, " "))
var stderr bytes.Buffer
createCmd.ShowOutput = false
createCmd.Command.Stderr = &stderr
_, err := createCmd.Output()
if err != nil {
err = errors.New(strings.TrimSpace(stderr.String()))
}
return err
}
// CommandDestroy is an alias for "docker network rm"
func CommandDestroy(networkName string, forceDestroy bool) error {
if os.Getenv("DOKKU_APPS_FORCE_DELETE") == "1" {
forceDestroy = true
}
if !forceDestroy {
common.LogWarn("WARNING: Potentially Destructive Action")
common.LogWarn(fmt.Sprintf("This command will destroy network %v.", networkName))
common.LogWarn(fmt.Sprintf("To proceed, type \"%v\"", networkName))
fmt.Print("> ")
var response string
_, err := fmt.Scanln(&response)
if err != nil {
return err
}
if response != networkName {
common.LogStderr("Confirmation did not match test. Aborted.")
os.Exit(1)
return nil
}
}
common.LogInfo1Quiet(fmt.Sprintf("Destroying network %v", networkName))
destroyCmd := common.NewShellCmd(strings.Join([]string{
common.DockerBin(),
"network",
"rm",
networkName,
}, " "))
var stderr bytes.Buffer
destroyCmd.ShowOutput = false
destroyCmd.Command.Stderr = &stderr
_, err := destroyCmd.Output()
if err != nil {
err = errors.New(strings.TrimSpace(stderr.String()))
}
return err
}
// CommandExists checks if a network exists
func CommandExists(networkName string) error {
exists := false
if networkName == "" {
return errors.New("No network name specified")
}
networks, err := ListNetworks()
if err != nil {
return err
}
for _, n := range networks {
if networkName == n {
exists = true
break
}
}
if exists {
common.LogInfo1Quiet("Network exists")
} else {
common.LogFail("Network does not exist")
}
return nil
}
// CommandInfo is an alias for "docker network inspect"
func CommandInfo() error {
return nil
}
// CommandList is an alias for "docker network ls"
func CommandList() error {
networks, err := ListNetworks()
if err != nil {
return err
}
common.LogInfo2Quiet("Networks")
for _, networkName := range networks {
fmt.Println(networkName)
}
return nil
}
// CommandRebuildall rebuilds network settings for all apps
func CommandRebuildall() {
apps, err := common.DokkuApps()
@@ -44,5 +165,18 @@ func CommandSet(appName string, property string, value string) {
value = "false"
}
attachProperites := map[string]bool{
"attach-post-create": true,
"attach-post-deploy": true,
}
invalidNetworks := map[string]bool{
"host": true,
"bridge": true,
}
if attachProperites[property] && invalidNetworks[value] {
common.LogFail("Invalid network name specified for attach")
}
common.CommandPropertySet("network", appName, property, value, DefaultProperties)
}