You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
watchtower/updater/config.go

113 lines
2.6 KiB
Go

package updater
import (
"github.com/samalba/dockerclient"
)
// Ideally, we'd just be able to take the ContainerConfig from the old container
// and use it as the starting point for creating the new container; however,
// the ContainerConfig that comes back from the Inspect call merges the default
// configuration (the stuff specified in the metadata for the image itself)
// with the overridden configuration (the stuff that you might specify as part
// of the "docker run"). In order to avoid unintentionally overriding the
// defaults in the new image we need to separate the override options from the
// default options. To do this we have to compare the ContainerConfig for the
// running container with the ContainerConfig from the image that container was
// started from. This function returns a ContainerConfig which contains just
// the override options.
func GenerateContainerConfig(oldContainerInfo *dockerclient.ContainerInfo, oldImageConfig *dockerclient.ContainerConfig) *dockerclient.ContainerConfig {
config := oldContainerInfo.Config
if config.WorkingDir == oldImageConfig.WorkingDir {
config.WorkingDir = ""
}
if config.User == oldImageConfig.User {
config.User = ""
}
if sliceEqual(config.Cmd, oldImageConfig.Cmd) {
config.Cmd = []string{}
}
if sliceEqual(config.Entrypoint, oldImageConfig.Entrypoint) {
config.Entrypoint = []string{}
}
config.Env = arraySubtract(config.Env, oldImageConfig.Env)
config.Labels = stringMapSubtract(config.Labels, oldImageConfig.Labels)
config.Volumes = structMapSubtract(config.Volumes, oldImageConfig.Volumes)
config.ExposedPorts = structMapSubtract(config.ExposedPorts, oldImageConfig.ExposedPorts)
for p, _ := range oldContainerInfo.HostConfig.PortBindings {
config.ExposedPorts[p] = struct{}{}
}
return config
}
func sliceEqual(s1, s2 []string) bool {
if len(s1) != len(s2) {
return false
}
for i := range s1 {
if s1[i] != s2[i] {
return false
}
}
return true
}
func stringMapSubtract(m1, m2 map[string]string) map[string]string {
m := map[string]string{}
for k1, v1 := range m1 {
if v2, ok := m2[k1]; ok {
if v2 != v1 {
m[k1] = v1
}
} else {
m[k1] = v1
}
}
return m
}
func structMapSubtract(m1, m2 map[string]struct{}) map[string]struct{} {
m := map[string]struct{}{}
for k1, v1 := range m1 {
if _, ok := m2[k1]; !ok {
m[k1] = v1
}
}
return m
}
func arraySubtract(a1, a2 []string) []string {
a := []string{}
for _, e1 := range a1 {
found := false
for _, e2 := range a2 {
if e1 == e2 {
found = true
break
}
}
if !found {
a = append(a, e1)
}
}
return a
}