mirror of
https://github.com/containrrr/watchtower.git
synced 2025-09-21 21:30:48 +02:00
fix: linked/depends-on container restarting (#1103)
This commit is contained in:
parent
aa02d8d31b
commit
084249c5fc
5 changed files with 358 additions and 21 deletions
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/containrrr/watchtower/pkg/sorter"
|
||||
"github.com/containrrr/watchtower/pkg/types"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Update looks at the running Docker containers to see if any of the images
|
||||
|
@ -68,7 +69,7 @@ func Update(client container.Client, params types.UpdateParams) (types.Report, e
|
|||
return nil, err
|
||||
}
|
||||
|
||||
checkDependencies(containers)
|
||||
UpdateImplicitRestart(containers)
|
||||
|
||||
var containersToUpdate []container.Container
|
||||
if !params.MonitorOnly {
|
||||
|
@ -216,24 +217,41 @@ func restartStaleContainer(container container.Container, client container.Clien
|
|||
return nil
|
||||
}
|
||||
|
||||
func checkDependencies(containers []container.Container) {
|
||||
// UpdateImplicitRestart iterates through the passed containers, setting the
|
||||
// `LinkedToRestarting` flag if any of it's linked containers are marked for restart
|
||||
func UpdateImplicitRestart(containers []container.Container) {
|
||||
|
||||
for _, c := range containers {
|
||||
for ci, c := range containers {
|
||||
if c.ToRestart() {
|
||||
// The container is already marked for restart, no need to check
|
||||
continue
|
||||
}
|
||||
|
||||
LinkLoop:
|
||||
for _, linkName := range c.Links() {
|
||||
for _, candidate := range containers {
|
||||
if candidate.Name() != linkName {
|
||||
continue
|
||||
}
|
||||
if candidate.ToRestart() {
|
||||
c.LinkedToRestarting = true
|
||||
break LinkLoop
|
||||
}
|
||||
if link := linkedContainerMarkedForRestart(c.Links(), containers); link != "" {
|
||||
log.WithFields(log.Fields{
|
||||
"restarting": link,
|
||||
"linked": c.Name(),
|
||||
}).Debug("container is linked to restarting")
|
||||
// NOTE: To mutate the array, the `c` variable cannot be used as it's a copy
|
||||
containers[ci].LinkedToRestarting = true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// linkedContainerMarkedForRestart returns the name of the first link that matches a
|
||||
// container marked for restart
|
||||
func linkedContainerMarkedForRestart(links []string, containers []container.Container) string {
|
||||
for _, linkName := range links {
|
||||
// Since the container names need to start with '/', let's prepend it if it's missing
|
||||
if !strings.HasPrefix(linkName, "/") {
|
||||
linkName = "/" + linkName
|
||||
}
|
||||
for _, candidate := range containers {
|
||||
if candidate.Name() == linkName && candidate.ToRestart() {
|
||||
return linkName
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ var _ = Describe("the update action", func() {
|
|||
BeforeEach(func() {
|
||||
pullImages := false
|
||||
removeVolumes := false
|
||||
//goland:noinspection GoBoolExpressions
|
||||
client = CreateMockClient(
|
||||
&TestData{
|
||||
NameOfContainerToKeep: "test-container-02",
|
||||
|
@ -255,6 +256,54 @@ var _ = Describe("the update action", func() {
|
|||
})
|
||||
})
|
||||
|
||||
When("container is linked to restarting containers", func() {
|
||||
It("should be marked for restart", func() {
|
||||
|
||||
provider := CreateMockContainerWithConfig(
|
||||
"test-container-provider",
|
||||
"/test-container-provider",
|
||||
"fake-image2:latest",
|
||||
true,
|
||||
false,
|
||||
time.Now(),
|
||||
&dockerContainer.Config{
|
||||
Labels: map[string]string{},
|
||||
ExposedPorts: map[nat.Port]struct{}{},
|
||||
})
|
||||
|
||||
provider.Stale = true
|
||||
|
||||
consumer := CreateMockContainerWithConfig(
|
||||
"test-container-consumer",
|
||||
"/test-container-consumer",
|
||||
"fake-image3:latest",
|
||||
true,
|
||||
false,
|
||||
time.Now(),
|
||||
&dockerContainer.Config{
|
||||
Labels: map[string]string{
|
||||
"com.centurylinklabs.watchtower.depends-on": "test-container-provider",
|
||||
},
|
||||
ExposedPorts: map[nat.Port]struct{}{},
|
||||
})
|
||||
|
||||
containers := []container.Container{
|
||||
provider,
|
||||
consumer,
|
||||
}
|
||||
|
||||
Expect(provider.ToRestart()).To(BeTrue())
|
||||
Expect(consumer.ToRestart()).To(BeFalse())
|
||||
|
||||
actions.UpdateImplicitRestart(containers)
|
||||
|
||||
Expect(containers[0].ToRestart()).To(BeTrue())
|
||||
Expect(containers[1].ToRestart()).To(BeTrue())
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
When("container is not running", func() {
|
||||
BeforeEach(func() {
|
||||
client = CreateMockClient(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue