Skip to content

Commit bbbe041

Browse files
gilbsgilbsnedzadalibegovicpiksel
authored
feat: add no-pull label for containers (#1574)
Co-authored-by: Nedžad Alibegović <[email protected]> Co-authored-by: nils måsén <[email protected]>
1 parent 6ace7bd commit bbbe041

File tree

5 files changed

+66
-13
lines changed

5 files changed

+66
-13
lines changed

docs/arguments.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@ Environment Variable: WATCHTOWER_NO_PULL
234234
Default: false
235235
```
236236

237+
Note that no-pull can also be specified on a per-container basis with the
238+
`com.centurylinklabs.watchtower.no-pull` label set on those containers.
239+
237240
## Without sending a startup message
238241
Do not send a message after watchtower started. Otherwise there will be an info-level notification.
239242

pkg/container/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ func (client dockerClient) RenameContainer(c Container, newName string) error {
280280
func (client dockerClient) IsContainerStale(container Container) (stale bool, latestImage t.ImageID, err error) {
281281
ctx := context.Background()
282282

283-
if !client.PullImages {
283+
if !client.PullImages || container.IsNoPull() {
284284
log.Debugf("Skipping image pull.")
285285
} else if err := client.PullImage(ctx, container); err != nil {
286286
return false, container.SafeImageID(), err

pkg/container/container.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,22 @@ func (c Container) IsMonitorOnly() bool {
125125
return parsedBool
126126
}
127127

128+
// IsNoPull returns the value of the no-pull label. If the label is not set
129+
// then false is returned.
130+
func (c Container) IsNoPull() bool {
131+
rawBool, ok := c.getLabelValue(noPullLabel)
132+
if !ok {
133+
return false
134+
}
135+
136+
parsedBool, err := strconv.ParseBool(rawBool)
137+
if err != nil {
138+
return false
139+
}
140+
141+
return parsedBool
142+
}
143+
128144
// Scope returns the value of the scope UID label and if the label
129145
// was set.
130146
func (c Container) Scope() (string, bool) {

pkg/container/container_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,39 @@ var _ = Describe("the container", func() {
207207
})
208208
})
209209

210+
When("checking no-pull label", func() {
211+
When("no-pull label is true", func() {
212+
c := MockContainer(WithLabels(map[string]string{
213+
"com.centurylinklabs.watchtower.no-pull": "true",
214+
}))
215+
It("should return true", func() {
216+
Expect(c.IsNoPull()).To(Equal(true))
217+
})
218+
})
219+
When("no-pull label is false", func() {
220+
c := MockContainer(WithLabels(map[string]string{
221+
"com.centurylinklabs.watchtower.no-pull": "false",
222+
}))
223+
It("should return false", func() {
224+
Expect(c.IsNoPull()).To(Equal(false))
225+
})
226+
})
227+
When("no-pull label is set to an invalid value", func() {
228+
c := MockContainer(WithLabels(map[string]string{
229+
"com.centurylinklabs.watchtower.no-pull": "maybe",
230+
}))
231+
It("should return false", func() {
232+
Expect(c.IsNoPull()).To(Equal(false))
233+
})
234+
})
235+
When("no-pull label is unset", func() {
236+
c = MockContainer(WithLabels(map[string]string{}))
237+
It("should return false", func() {
238+
Expect(c.IsNoPull()).To(Equal(false))
239+
})
240+
})
241+
})
242+
210243
When("there is a pre or post update timeout", func() {
211244
It("should return minute values", func() {
212245
c = MockContainer(WithLabels(map[string]string{

pkg/container/metadata.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
package container
22

33
const (
4-
watchtowerLabel = "com.centurylinklabs.watchtower"
5-
signalLabel = "com.centurylinklabs.watchtower.stop-signal"
6-
enableLabel = "com.centurylinklabs.watchtower.enable"
7-
monitorOnlyLabel = "com.centurylinklabs.watchtower.monitor-only"
8-
dependsOnLabel = "com.centurylinklabs.watchtower.depends-on"
9-
zodiacLabel = "com.centurylinklabs.zodiac.original-image"
10-
scope = "com.centurylinklabs.watchtower.scope"
11-
preCheckLabel = "com.centurylinklabs.watchtower.lifecycle.pre-check"
12-
postCheckLabel = "com.centurylinklabs.watchtower.lifecycle.post-check"
13-
preUpdateLabel = "com.centurylinklabs.watchtower.lifecycle.pre-update"
14-
postUpdateLabel = "com.centurylinklabs.watchtower.lifecycle.post-update"
15-
preUpdateTimeoutLabel = "com.centurylinklabs.watchtower.lifecycle.pre-update-timeout"
4+
watchtowerLabel = "com.centurylinklabs.watchtower"
5+
signalLabel = "com.centurylinklabs.watchtower.stop-signal"
6+
enableLabel = "com.centurylinklabs.watchtower.enable"
7+
monitorOnlyLabel = "com.centurylinklabs.watchtower.monitor-only"
8+
noPullLabel = "com.centurylinklabs.watchtower.no-pull"
9+
dependsOnLabel = "com.centurylinklabs.watchtower.depends-on"
10+
zodiacLabel = "com.centurylinklabs.zodiac.original-image"
11+
scope = "com.centurylinklabs.watchtower.scope"
12+
preCheckLabel = "com.centurylinklabs.watchtower.lifecycle.pre-check"
13+
postCheckLabel = "com.centurylinklabs.watchtower.lifecycle.post-check"
14+
preUpdateLabel = "com.centurylinklabs.watchtower.lifecycle.pre-update"
15+
postUpdateLabel = "com.centurylinklabs.watchtower.lifecycle.post-update"
16+
preUpdateTimeoutLabel = "com.centurylinklabs.watchtower.lifecycle.pre-update-timeout"
1617
postUpdateTimeoutLabel = "com.centurylinklabs.watchtower.lifecycle.post-update-timeout"
1718
)
1819

0 commit comments

Comments
 (0)