Pre-update lifecycle hook (#793)

* Make watchtower skip update if pre-update lifecycle hook exits with a non-zero exit code
#649

* Make watchtower skip update if pre-update lifecycle hook exits with a non-zero exit code
#649

* Make watchtower skip update if pre-update lifecycle hook exits with a non-zero exit code
#649

* Make watchtower skip update if pre-update lifecycle hook exits with a non-zero exit code
#649

* Make watchtower skip update if pre-update lifecycle hook exits with a non-zero exit code #649

* Make watchtower skip update if pre-update lifecycle hook exits with a non-zero exit code #649

* Make watchtower skip update if pre-update lifecycle hook exits with a non-zero exit code #649

* Prevent starting new container if old one is not stopped because of lifecycle hook.

* Add null check for c.containerInfo.State in IsRunning

* Fixed that the container would not start

* Added test for preupdate

* EX_TEMPFAIL -> ExTempFail

* Added missing fuction ouput names

* Skip preupdate when container is restarting.
This commit is contained in:
yrien30 2021-06-24 00:36:33 +02:00 committed by GitHub
parent dc12a1ac7f
commit 145fe6dbcb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 281 additions and 39 deletions

View file

@ -7,6 +7,7 @@ import (
"github.com/containrrr/watchtower/pkg/types"
container2 "github.com/docker/docker/api/types/container"
cli "github.com/docker/docker/client"
"github.com/docker/go-connections/nat"
"time"
. "github.com/containrrr/watchtower/internal/actions/mocks"
@ -106,6 +107,8 @@ var _ = Describe("the update action", func() {
"test-container-02",
"test-container-02",
"fake-image2:latest",
false,
false,
time.Now(),
&container2.Config{
Labels: map[string]string{
@ -158,4 +161,187 @@ 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(
&TestData{
//NameOfContainerToKeep: "test-container-02",
Containers: []container.Container{
CreateMockContainerWithConfig(
"test-container-02",
"test-container-02",
"fake-image2:latest",
true,
false,
time.Now(),
&container2.Config{
Labels: map[string]string{
"com.centurylinklabs.watchtower.lifecycle.pre-update-timeout": "190",
"com.centurylinklabs.watchtower.lifecycle.pre-update": "/PreUpdateReturn1.sh",
},
ExposedPorts: map[nat.Port]struct{}{},
}),
},
},
dockerClient,
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))
})
})
When("prupddate script returns 75", func() {
BeforeEach(func() {
client = CreateMockClient(
&TestData{
//NameOfContainerToKeep: "test-container-02",
Containers: []container.Container{
CreateMockContainerWithConfig(
"test-container-02",
"test-container-02",
"fake-image2:latest",
true,
false,
time.Now(),
&container2.Config{
Labels: map[string]string{
"com.centurylinklabs.watchtower.lifecycle.pre-update-timeout": "190",
"com.centurylinklabs.watchtower.lifecycle.pre-update": "/PreUpdateReturn75.sh",
},
ExposedPorts: map[nat.Port]struct{}{},
}),
},
},
dockerClient,
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))
})
})
When("prupddate script returns 0", func() {
BeforeEach(func() {
client = CreateMockClient(
&TestData{
//NameOfContainerToKeep: "test-container-02",
Containers: []container.Container{
CreateMockContainerWithConfig(
"test-container-02",
"test-container-02",
"fake-image2:latest",
true,
false,
time.Now(),
&container2.Config{
Labels: map[string]string{
"com.centurylinklabs.watchtower.lifecycle.pre-update-timeout": "190",
"com.centurylinklabs.watchtower.lifecycle.pre-update": "/PreUpdateReturn0.sh",
},
ExposedPorts: map[nat.Port]struct{}{},
}),
},
},
dockerClient,
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))
})
})
When("container is not running", func() {
BeforeEach(func() {
client = CreateMockClient(
&TestData{
//NameOfContainerToKeep: "test-container-02",
Containers: []container.Container{
CreateMockContainerWithConfig(
"test-container-02",
"test-container-02",
"fake-image2:latest",
false,
false,
time.Now(),
&container2.Config{
Labels: map[string]string{
"com.centurylinklabs.watchtower.lifecycle.pre-update-timeout": "190",
"com.centurylinklabs.watchtower.lifecycle.pre-update": "/PreUpdateReturn1.sh",
},
ExposedPorts: map[nat.Port]struct{}{},
}),
},
},
dockerClient,
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))
})
})
When("container is restarting", func() {
BeforeEach(func() {
client = CreateMockClient(
&TestData{
//NameOfContainerToKeep: "test-container-02",
Containers: []container.Container{
CreateMockContainerWithConfig(
"test-container-02",
"test-container-02",
"fake-image2:latest",
false,
true,
time.Now(),
&container2.Config{
Labels: map[string]string{
"com.centurylinklabs.watchtower.lifecycle.pre-update-timeout": "190",
"com.centurylinklabs.watchtower.lifecycle.pre-update": "/PreUpdateReturn1.sh",
},
ExposedPorts: map[nat.Port]struct{}{},
}),
},
},
dockerClient,
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))
})
})
})
})