Files
dokku/plugins/network/functions.go
Jose Diaz-Gonzalez 4436bb2023 chore: standardize on ls subcommand when interacting with the docker binary
The ls command is what is referenced in the --help output for the subcommands, so we should just use that everywhere.
2023-08-05 10:58:57 -04:00

143 lines
3.3 KiB
Go

package network
import (
"bytes"
"errors"
"fmt"
"strings"
"github.com/dokku/dokku/plugins/common"
sh "github.com/codeskyblue/go-sh"
)
// attachAppToNetwork attaches a container to a network
func attachAppToNetwork(containerID string, networkName string, appName string, phase string, processType string) error {
if isContainerInNetwork(containerID, networkName) {
return nil
}
cmdParts := []string{
common.DockerBin(),
"network",
"connect",
}
if phase == "deploy" {
tld := reportComputedTld(appName)
networkAlias := fmt.Sprintf("%v.%v", appName, processType)
if tld != "" {
networkAlias = fmt.Sprintf("%v.%v", networkAlias, tld)
}
cmdParts = append(cmdParts, "--alias")
cmdParts = append(cmdParts, networkAlias)
hostname, err := common.DockerInspect(containerID, "{{ .Config.Hostname }}")
if err != nil {
common.LogWarn(err.Error())
} else {
cmdParts = append(cmdParts, "--alias")
cmdParts = append(cmdParts, fmt.Sprintf("%v.%v", hostname, networkAlias))
}
}
cmdParts = append(cmdParts, networkName)
cmdParts = append(cmdParts, containerID)
attachCmd := common.NewShellCmd(strings.Join(cmdParts, " "))
var stderr bytes.Buffer
attachCmd.ShowOutput = false
attachCmd.Command.Stderr = &stderr
_, err := attachCmd.Output()
if err != nil {
err = errors.New(strings.TrimSpace(stderr.String()))
return fmt.Errorf("Unable to attach container to network: %v", err.Error())
}
return nil
}
// isContainerInNetwork returns true if the container is already attached to the specified network
func isContainerInNetwork(containerID string, networkName string) bool {
b, err := sh.Command(
common.DockerBin(),
"container",
"inspect",
"--format",
"{{range $net, $v := .NetworkSettings.Networks}}{{println $net}}{{end}}",
containerID,
).Output()
if err != nil {
common.LogVerboseQuiet(fmt.Sprintf("Error checking container networking status:%v", err.Error()))
return false
}
for _, line := range strings.Split(strings.TrimSpace(string(b[:])), "\n") {
network := strings.TrimSpace(line)
if network == "" {
continue
}
if network == networkName {
return true
}
}
return false
}
// isConflictingPropertyValue returns true if the other attach property has a conflicting value
func isConflictingPropertyValue(appName string, property string, value string) bool {
if value == "" {
return false
}
otherValue := ""
if property == "attach-post-create" {
otherValue = reportComputedAttachPostDeploy(appName)
} else {
otherValue = reportComputedAttachPostCreate(appName)
}
return value == otherValue
}
// networkExists checks to see if a network exists
func networkExists(networkName string) (bool, error) {
if networkName == "" {
return false, errors.New("No network name specified")
}
exists := false
networks, err := listNetworks()
if err != nil {
return false, err
}
for _, n := range networks {
if networkName == n {
exists = true
break
}
}
return exists, nil
}
// listNetworks returns a list of docker networks
func listNetworks() ([]string, error) {
b, err := sh.Command(common.DockerBin(), "network", "ls", "--format", "{{ .Name }}").Output()
output := strings.TrimSpace(string(b[:]))
networks := []string{}
if err != nil {
common.LogVerboseQuiet(output)
return networks, err
}
networks = strings.Split(output, "\n")
return networks, nil
}