mirror of
https://github.com/containrrr/watchtower.git
synced 2025-12-13 21:56:38 +01:00
fix: correctly handle non-stale restarts (#1220)
This commit is contained in:
parent
d12ce7ce79
commit
e9c83af533
4 changed files with 166 additions and 93 deletions
|
|
@ -1,55 +1,76 @@
|
|||
package actions_test
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/containrrr/watchtower/internal/actions"
|
||||
"github.com/containrrr/watchtower/pkg/container"
|
||||
"github.com/containrrr/watchtower/pkg/types"
|
||||
dockerTypes "github.com/docker/docker/api/types"
|
||||
dockerContainer "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"time"
|
||||
|
||||
. "github.com/containrrr/watchtower/internal/actions/mocks"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func getCommonTestData(keepContainer string) *TestData {
|
||||
return &TestData{
|
||||
NameOfContainerToKeep: keepContainer,
|
||||
Containers: []container.Container{
|
||||
CreateMockContainer(
|
||||
"test-container-01",
|
||||
"test-container-01",
|
||||
"fake-image:latest",
|
||||
time.Now().AddDate(0, 0, -1)),
|
||||
CreateMockContainer(
|
||||
"test-container-02",
|
||||
"test-container-02",
|
||||
"fake-image:latest",
|
||||
time.Now()),
|
||||
CreateMockContainer(
|
||||
"test-container-02",
|
||||
"test-container-02",
|
||||
"fake-image:latest",
|
||||
time.Now()),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func getLinkedTestData(withImageInfo bool) *TestData {
|
||||
staleContainer := CreateMockContainer(
|
||||
"test-container-01",
|
||||
"/test-container-01",
|
||||
"fake-image1:latest",
|
||||
time.Now().AddDate(0, 0, -1))
|
||||
|
||||
var imageInfo *dockerTypes.ImageInspect
|
||||
if withImageInfo {
|
||||
imageInfo = CreateMockImageInfo("test-container-02")
|
||||
}
|
||||
linkingContainer := CreateMockContainerWithLinks(
|
||||
"test-container-02",
|
||||
"/test-container-02",
|
||||
"fake-image2:latest",
|
||||
time.Now(),
|
||||
[]string{staleContainer.Name()},
|
||||
imageInfo)
|
||||
|
||||
return &TestData{
|
||||
Staleness: map[string]bool{linkingContainer.Name(): false},
|
||||
Containers: []container.Container{
|
||||
staleContainer,
|
||||
linkingContainer,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
var _ = Describe("the update action", func() {
|
||||
var client MockClient
|
||||
|
||||
When("watchtower has been instructed to clean up", func() {
|
||||
BeforeEach(func() {
|
||||
pullImages := false
|
||||
removeVolumes := false
|
||||
//goland:noinspection GoBoolExpressions
|
||||
client = CreateMockClient(
|
||||
&TestData{
|
||||
NameOfContainerToKeep: "test-container-02",
|
||||
Containers: []container.Container{
|
||||
CreateMockContainer(
|
||||
"test-container-01",
|
||||
"test-container-01",
|
||||
"fake-image:latest",
|
||||
time.Now().AddDate(0, 0, -1)),
|
||||
CreateMockContainer(
|
||||
"test-container-02",
|
||||
"test-container-02",
|
||||
"fake-image:latest",
|
||||
time.Now()),
|
||||
CreateMockContainer(
|
||||
"test-container-02",
|
||||
"test-container-02",
|
||||
"fake-image:latest",
|
||||
time.Now()),
|
||||
},
|
||||
},
|
||||
pullImages,
|
||||
removeVolumes,
|
||||
)
|
||||
})
|
||||
|
||||
When("there are multiple containers using the same image", func() {
|
||||
It("should only try to remove the image once", func() {
|
||||
|
||||
client := CreateMockClient(getCommonTestData(""), false, false)
|
||||
_, err := actions.Update(client, types.UpdateParams{Cleanup: true})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(client.TestData.TriedToRemoveImageCount).To(Equal(1))
|
||||
|
|
@ -57,8 +78,9 @@ var _ = Describe("the update action", func() {
|
|||
})
|
||||
When("there are multiple containers using different images", func() {
|
||||
It("should try to remove each of them", func() {
|
||||
client.TestData.Containers = append(
|
||||
client.TestData.Containers,
|
||||
testData := getCommonTestData("")
|
||||
testData.Containers = append(
|
||||
testData.Containers,
|
||||
CreateMockContainer(
|
||||
"unique-test-container",
|
||||
"unique-test-container",
|
||||
|
|
@ -66,25 +88,46 @@ var _ = Describe("the update action", func() {
|
|||
time.Now(),
|
||||
),
|
||||
)
|
||||
client := CreateMockClient(testData, false, false)
|
||||
_, err := actions.Update(client, types.UpdateParams{Cleanup: true})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(client.TestData.TriedToRemoveImageCount).To(Equal(2))
|
||||
})
|
||||
})
|
||||
When("there are linked containers being updated", func() {
|
||||
It("should not try to remove their images", func() {
|
||||
client := CreateMockClient(getLinkedTestData(true), false, false)
|
||||
_, err := actions.Update(client, types.UpdateParams{Cleanup: true})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(client.TestData.TriedToRemoveImageCount).To(Equal(1))
|
||||
})
|
||||
})
|
||||
When("performing a rolling restart update", func() {
|
||||
It("should try to remove the image once", func() {
|
||||
|
||||
client := CreateMockClient(getCommonTestData(""), false, false)
|
||||
_, err := actions.Update(client, types.UpdateParams{Cleanup: true, RollingRestart: true})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(client.TestData.TriedToRemoveImageCount).To(Equal(1))
|
||||
})
|
||||
})
|
||||
When("updating a linked container with missing image info", func() {
|
||||
It("should gracefully fail", func() {
|
||||
client := CreateMockClient(getLinkedTestData(false), false, false)
|
||||
|
||||
report, err := actions.Update(client, types.UpdateParams{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
// Note: Linked containers that were skipped for recreation is not counted in Failed
|
||||
// If this happens, an error is emitted to the logs, so a notification should still be sent.
|
||||
Expect(report.Updated()).To(HaveLen(1))
|
||||
Expect(report.Fresh()).To(HaveLen(1))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
When("watchtower has been instructed to monitor only", func() {
|
||||
When("certain containers are set to monitor only", func() {
|
||||
BeforeEach(func() {
|
||||
client = CreateMockClient(
|
||||
It("should not update those containers", func() {
|
||||
client := CreateMockClient(
|
||||
&TestData{
|
||||
NameOfContainerToKeep: "test-container-02",
|
||||
Containers: []container.Container{
|
||||
|
|
@ -110,9 +153,6 @@ var _ = Describe("the update action", func() {
|
|||
false,
|
||||
false,
|
||||
)
|
||||
})
|
||||
|
||||
It("should not update those containers", func() {
|
||||
_, err := actions.Update(client, types.UpdateParams{Cleanup: true})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(client.TestData.TriedToRemoveImageCount).To(Equal(1))
|
||||
|
|
@ -120,8 +160,8 @@ var _ = Describe("the update action", func() {
|
|||
})
|
||||
|
||||
When("monitor only is set globally", func() {
|
||||
BeforeEach(func() {
|
||||
client = CreateMockClient(
|
||||
It("should not update any containers", func() {
|
||||
client := CreateMockClient(
|
||||
&TestData{
|
||||
Containers: []container.Container{
|
||||
CreateMockContainer(
|
||||
|
|
@ -139,9 +179,6 @@ var _ = Describe("the update action", func() {
|
|||
false,
|
||||
false,
|
||||
)
|
||||
})
|
||||
|
||||
It("should not update any containers", func() {
|
||||
_, err := actions.Update(client, types.UpdateParams{MonitorOnly: true})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(client.TestData.TriedToRemoveImageCount).To(Equal(0))
|
||||
|
|
@ -152,9 +189,9 @@ var _ = Describe("the update action", func() {
|
|||
|
||||
When("watchtower has been instructed to run lifecycle hooks", func() {
|
||||
|
||||
When("prupddate script returns 1", func() {
|
||||
BeforeEach(func() {
|
||||
client = CreateMockClient(
|
||||
When("pre-update script returns 1", func() {
|
||||
It("should not update those containers", func() {
|
||||
client := CreateMockClient(
|
||||
&TestData{
|
||||
//NameOfContainerToKeep: "test-container-02",
|
||||
Containers: []container.Container{
|
||||
|
|
@ -177,9 +214,7 @@ var _ = Describe("the update action", func() {
|
|||
false,
|
||||
false,
|
||||
)
|
||||
})
|
||||
|
||||
It("should not update those containers", func() {
|
||||
_, err := actions.Update(client, types.UpdateParams{Cleanup: true, LifecycleHooks: true})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(client.TestData.TriedToRemoveImageCount).To(Equal(0))
|
||||
|
|
@ -188,8 +223,8 @@ var _ = Describe("the update action", func() {
|
|||
})
|
||||
|
||||
When("prupddate script returns 75", func() {
|
||||
BeforeEach(func() {
|
||||
client = CreateMockClient(
|
||||
It("should not update those containers", func() {
|
||||
client := CreateMockClient(
|
||||
&TestData{
|
||||
//NameOfContainerToKeep: "test-container-02",
|
||||
Containers: []container.Container{
|
||||
|
|
@ -212,9 +247,6 @@ var _ = Describe("the update action", func() {
|
|||
false,
|
||||
false,
|
||||
)
|
||||
})
|
||||
|
||||
It("should not update those containers", func() {
|
||||
_, err := actions.Update(client, types.UpdateParams{Cleanup: true, LifecycleHooks: true})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(client.TestData.TriedToRemoveImageCount).To(Equal(0))
|
||||
|
|
@ -223,8 +255,8 @@ var _ = Describe("the update action", func() {
|
|||
})
|
||||
|
||||
When("prupddate script returns 0", func() {
|
||||
BeforeEach(func() {
|
||||
client = CreateMockClient(
|
||||
It("should update those containers", func() {
|
||||
client := CreateMockClient(
|
||||
&TestData{
|
||||
//NameOfContainerToKeep: "test-container-02",
|
||||
Containers: []container.Container{
|
||||
|
|
@ -247,9 +279,6 @@ var _ = Describe("the update action", func() {
|
|||
false,
|
||||
false,
|
||||
)
|
||||
})
|
||||
|
||||
It("should update those containers", func() {
|
||||
_, err := actions.Update(client, types.UpdateParams{Cleanup: true, LifecycleHooks: true})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(client.TestData.TriedToRemoveImageCount).To(Equal(1))
|
||||
|
|
@ -305,8 +334,8 @@ var _ = Describe("the update action", func() {
|
|||
})
|
||||
|
||||
When("container is not running", func() {
|
||||
BeforeEach(func() {
|
||||
client = CreateMockClient(
|
||||
It("skip running preupdate", func() {
|
||||
client := CreateMockClient(
|
||||
&TestData{
|
||||
//NameOfContainerToKeep: "test-container-02",
|
||||
Containers: []container.Container{
|
||||
|
|
@ -329,9 +358,6 @@ var _ = Describe("the update action", func() {
|
|||
false,
|
||||
false,
|
||||
)
|
||||
})
|
||||
|
||||
It("skip running preupdate", func() {
|
||||
_, err := actions.Update(client, types.UpdateParams{Cleanup: true, LifecycleHooks: true})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(client.TestData.TriedToRemoveImageCount).To(Equal(1))
|
||||
|
|
@ -340,8 +366,8 @@ var _ = Describe("the update action", func() {
|
|||
})
|
||||
|
||||
When("container is restarting", func() {
|
||||
BeforeEach(func() {
|
||||
client = CreateMockClient(
|
||||
It("skip running preupdate", func() {
|
||||
client := CreateMockClient(
|
||||
&TestData{
|
||||
//NameOfContainerToKeep: "test-container-02",
|
||||
Containers: []container.Container{
|
||||
|
|
@ -364,9 +390,6 @@ var _ = Describe("the update action", func() {
|
|||
false,
|
||||
false,
|
||||
)
|
||||
})
|
||||
|
||||
It("skip running preupdate", func() {
|
||||
_, err := actions.Update(client, types.UpdateParams{Cleanup: true, LifecycleHooks: true})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(client.TestData.TriedToRemoveImageCount).To(Equal(1))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue