Add a label take precedence argument

This commit is contained in:
Jean-Edouard Babin 2023-09-07 19:43:40 +02:00
parent 36391b0ae7
commit 82f5472fd6
6 changed files with 85 additions and 30 deletions

View file

@ -28,17 +28,18 @@ import (
) )
var ( var (
client container.Client client container.Client
scheduleSpec string scheduleSpec string
cleanup bool cleanup bool
noRestart bool noRestart bool
monitorOnly bool monitorOnly bool
enableLabel bool enableLabel bool
notifier t.Notifier notifier t.Notifier
timeout time.Duration timeout time.Duration
lifecycleHooks bool lifecycleHooks bool
rollingRestart bool rollingRestart bool
scope string scope string
labelPrecedence bool
) )
var rootCmd = NewRootCommand() var rootCmd = NewRootCommand()
@ -109,6 +110,7 @@ func PreRun(cmd *cobra.Command, _ []string) {
lifecycleHooks, _ = f.GetBool("enable-lifecycle-hooks") lifecycleHooks, _ = f.GetBool("enable-lifecycle-hooks")
rollingRestart, _ = f.GetBool("rolling-restart") rollingRestart, _ = f.GetBool("rolling-restart")
scope, _ = f.GetString("scope") scope, _ = f.GetString("scope")
labelPrecedence, _ = f.GetBool("label-take-precedence")
if scope != "" { if scope != "" {
log.Debugf(`Using scope %q`, scope) log.Debugf(`Using scope %q`, scope)
@ -359,13 +361,14 @@ func runUpgradesOnSchedule(c *cobra.Command, filter t.Filter, filtering string,
func runUpdatesWithNotifications(filter t.Filter) *metrics.Metric { func runUpdatesWithNotifications(filter t.Filter) *metrics.Metric {
notifier.StartNotification() notifier.StartNotification()
updateParams := t.UpdateParams{ updateParams := t.UpdateParams{
Filter: filter, Filter: filter,
Cleanup: cleanup, Cleanup: cleanup,
NoRestart: noRestart, NoRestart: noRestart,
Timeout: timeout, Timeout: timeout,
MonitorOnly: monitorOnly, MonitorOnly: monitorOnly,
LifecycleHooks: lifecycleHooks, LifecycleHooks: lifecycleHooks,
RollingRestart: rollingRestart, RollingRestart: rollingRestart,
LabelPrecedence: labelPrecedence,
} }
result, err := actions.Update(client, updateParams) result, err := actions.Update(client, updateParams)
if err != nil { if err != nil {

View file

@ -205,7 +205,7 @@ Environment Variable: WATCHTOWER_POLL_INTERVAL
``` ```
## Filter by enable label ## Filter by enable label
Update containers that have a `com.centurylinklabs.watchtower.enable` label set to true. Monitor and update containers that have a `com.centurylinklabs.watchtower.enable` label set to true.
```text ```text
Argument: --label-enable Argument: --label-enable
@ -215,7 +215,7 @@ Environment Variable: WATCHTOWER_LABEL_ENABLE
``` ```
## Filter by disable label ## Filter by disable label
__Do not__ update containers that have `com.centurylinklabs.watchtower.enable` label set to false and __Do not__ Monitor and update containers that have `com.centurylinklabs.watchtower.enable` label set to false and
no `--label-enable` argument is passed. Note that only one or the other (targeting by enable label) can be no `--label-enable` argument is passed. Note that only one or the other (targeting by enable label) can be
used at the same time to target containers. used at the same time to target containers.
@ -238,6 +238,18 @@ Environment Variable: WATCHTOWER_MONITOR_ONLY
Note that monitor-only can also be specified on a per-container basis with the `com.centurylinklabs.watchtower.monitor-only` label set on those containers. Note that monitor-only can also be specified on a per-container basis with the `com.centurylinklabs.watchtower.monitor-only` label set on those containers.
## With label taking precedence over environment variables
By default, environement variables will take precedence over labels. This means that if you set `WATCHTOWER_MONITOR_ONLY` to true, a container with `com.centurylinklabs.watchtower.monitor-only` set to false will not be updated. If you set `WATCHTOWER_LABEL_TAKE_PRECEDENCE` to true, then the container will also be updated
```text
Argument: --label-take-precedence
Environment Variable: WATCHTOWER_LABEL_TAKE_PRECEDENCE
Type: Boolean
Default: false
```
## Without restarting containers ## Without restarting containers
Do not restart containers after updating. This option can be useful when the start of the containers Do not restart containers after updating. This option can be useful when the start of the containers
is managed by an external system such as systemd. is managed by an external system such as systemd.

View file

@ -34,7 +34,7 @@ func Update(client container.Client, params types.UpdateParams) (types.Report, e
for i, targetContainer := range containers { for i, targetContainer := range containers {
stale, newestImage, err := client.IsContainerStale(targetContainer) stale, newestImage, err := client.IsContainerStale(targetContainer)
shouldUpdate := stale && !params.NoRestart && !params.MonitorOnly && !targetContainer.IsMonitorOnly() shouldUpdate := stale && !params.NoRestart && (( !params.MonitorOnly && !targetContainer.IsMonitorOnly() ) || ( params.LabelPrecedence && !targetContainer.IsMonitorOnly() ))
if err == nil && shouldUpdate { if err == nil && shouldUpdate {
// Check to make sure we have all the necessary information for recreating the container // Check to make sure we have all the necessary information for recreating the container
err = targetContainer.VerifyConfiguration() err = targetContainer.VerifyConfiguration()
@ -72,7 +72,7 @@ func Update(client container.Client, params types.UpdateParams) (types.Report, e
UpdateImplicitRestart(containers) UpdateImplicitRestart(containers)
var containersToUpdate []types.Container var containersToUpdate []types.Container
if !params.MonitorOnly { if ( !params.MonitorOnly || params.LabelPrecedence ) {
for _, c := range containers { for _, c := range containers {
if !c.IsMonitorOnly() { if !c.IsMonitorOnly() {
containersToUpdate = append(containersToUpdate, c) containersToUpdate = append(containersToUpdate, c)

View file

@ -182,8 +182,41 @@ var _ = Describe("the update action", func() {
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(client.TestData.TriedToRemoveImageCount).To(Equal(0)) Expect(client.TestData.TriedToRemoveImageCount).To(Equal(0))
}) })
})
When("watchtower has been instructed to have label take precedence", func() {
It("it should update containers with monitor only set to false", func() {
client := CreateMockClient(
&TestData{
NameOfContainerToKeep: "test-container-02",
Containers: []types.Container{
CreateMockContainer(
"test-container-01",
"test-container-01",
"fake-image1:latest",
time.Now()),
CreateMockContainerWithConfig(
"test-container-02",
"test-container-02",
"fake-image2:latest",
false,
false,
time.Now(),
&dockerContainer.Config{
Labels: map[string]string{
"com.centurylinklabs.watchtower.monitor-only": "false",
},
}),
},
},
false,
false,
)
_, err := actions.Update(client, types.UpdateParams{MonitorOnly: true, LabelPrecedence: true})
Expect(err).To(HaveOccurred())
Expect(client.TestData.TriedToRemoveImageCount).To(Equal(1))
})
})
})
}) })
When("watchtower has been instructed to run lifecycle hooks", func() { When("watchtower has been instructed to run lifecycle hooks", func() {

View file

@ -185,6 +185,12 @@ func RegisterSystemFlags(rootCmd *cobra.Command) {
"log-level", "log-level",
viper.GetString("WATCHTOWER_LOG_LEVEL"), viper.GetString("WATCHTOWER_LOG_LEVEL"),
"The maximum log level that will be written to STDERR. Possible values: panic, fatal, error, warn, info, debug or trace") "The maximum log level that will be written to STDERR. Possible values: panic, fatal, error, warn, info, debug or trace")
flags.BoolP(
"label-take-precedence",
"",
viper.GetBool("WATCHTOWER_LABEL_TAKE_PRECEDENCE"),
"Label applied to containers take precedence over environement variable")
} }
// RegisterNotificationFlags that are used by watchtower to send notifications // RegisterNotificationFlags that are used by watchtower to send notifications

View file

@ -6,11 +6,12 @@ import (
// UpdateParams contains all different options available to alter the behavior of the Update func // UpdateParams contains all different options available to alter the behavior of the Update func
type UpdateParams struct { type UpdateParams struct {
Filter Filter Filter Filter
Cleanup bool Cleanup bool
NoRestart bool NoRestart bool
Timeout time.Duration Timeout time.Duration
MonitorOnly bool MonitorOnly bool
LifecycleHooks bool LifecycleHooks bool
RollingRestart bool RollingRestart bool
LabelPrecedence bool
} }