mirror of
https://github.com/containrrr/watchtower.git
synced 2025-09-21 21:30:48 +02:00
Feat/lifecycle hooks (#351)
* feat(update): add lifecycle hooks to the update action * fix(ci): add bash tests for lifecycle-hooks to the ci workflow * fix(ci): move integration tests to an isolated step * fix(ci): fix malformed all-contributors json * fix(ci): disable automatic bash test until we figure out a reasonable way to run it in circleci
This commit is contained in:
parent
874180a518
commit
bfae38dbf8
12 changed files with 499 additions and 73 deletions
|
@ -160,7 +160,7 @@ func (client mockClient) StopContainer(c container.Container, d time.Duration) e
|
|||
}
|
||||
return nil
|
||||
}
|
||||
func (client mockClient) StartContainer(c container.Container) error {
|
||||
func (client mockClient) StartContainer(c container.Container) (string, error) {
|
||||
panic("Not implemented")
|
||||
}
|
||||
|
||||
|
@ -173,6 +173,14 @@ func (client mockClient) RemoveImage(c container.Container) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (client mockClient) GetContainer(containerID string) (container.Container, error) {
|
||||
return container.Container{}, nil
|
||||
}
|
||||
|
||||
func (client mockClient) ExecuteCommand(containerID string, command string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client mockClient) IsContainerStale(c container.Container) (bool, error) {
|
||||
panic("Not implemented")
|
||||
}
|
||||
|
|
|
@ -61,8 +61,9 @@ func stopStaleContainer(container container.Container, client container.Client,
|
|||
return
|
||||
}
|
||||
|
||||
err := client.StopContainer(container, params.Timeout)
|
||||
if err != nil {
|
||||
executePreUpdateCommand(client, container)
|
||||
|
||||
if err := client.StopContainer(container, params.Timeout); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
|
@ -89,8 +90,10 @@ func restartStaleContainer(container container.Container, client container.Clien
|
|||
}
|
||||
|
||||
if !params.NoRestart {
|
||||
if err := client.StartContainer(container); err != nil {
|
||||
if newContainerID, err := client.StartContainer(container); err != nil {
|
||||
log.Error(err)
|
||||
} else if container.Stale && params.LifecycleHooks {
|
||||
executePostUpdateCommand(client, newContainerID)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,18 +107,49 @@ func restartStaleContainer(container container.Container, client container.Clien
|
|||
func checkDependencies(containers []container.Container) {
|
||||
|
||||
for i, parent := range containers {
|
||||
if parent.Stale {
|
||||
if parent.ToRestart() {
|
||||
continue
|
||||
}
|
||||
|
||||
LinkLoop:
|
||||
for _, linkName := range parent.Links() {
|
||||
for _, child := range containers {
|
||||
if child.Name() == linkName && child.Stale {
|
||||
containers[i].Stale = true
|
||||
if child.Name() == linkName && child.ToRestart() {
|
||||
containers[i].Linked = true
|
||||
break LinkLoop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func executePreUpdateCommand(client container.Client, container container.Container) {
|
||||
|
||||
command := container.GetLifecyclePreUpdateCommand()
|
||||
if len(command) == 0 {
|
||||
log.Debug("No pre-update command supplied. Skipping")
|
||||
}
|
||||
|
||||
log.Info("Executing pre-update command.")
|
||||
if err := client.ExecuteCommand(container.ID(), command); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func executePostUpdateCommand(client container.Client, newContainerID string) {
|
||||
newContainer, err := client.GetContainer(newContainerID)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
command := newContainer.GetLifecyclePostUpdateCommand()
|
||||
if len(command) == 0 {
|
||||
log.Debug("No post-update command supplied. Skipping")
|
||||
}
|
||||
|
||||
log.Info("Executing post-update command.")
|
||||
if err := client.ExecuteCommand(newContainerID, command); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,10 @@ import (
|
|||
|
||||
// UpdateParams contains all different options available to alter the behavior of the Update func
|
||||
type UpdateParams struct {
|
||||
Filter t.Filter
|
||||
Cleanup bool
|
||||
NoRestart bool
|
||||
Timeout time.Duration
|
||||
MonitorOnly bool
|
||||
Filter t.Filter
|
||||
Cleanup bool
|
||||
NoRestart bool
|
||||
Timeout time.Duration
|
||||
MonitorOnly bool
|
||||
LifecycleHooks bool
|
||||
}
|
||||
|
|
|
@ -88,6 +88,12 @@ func RegisterSystemFlags(rootCmd *cobra.Command) {
|
|||
"S",
|
||||
viper.GetBool("WATCHTOWER_INCLUDE_STOPPED"),
|
||||
"Will also include created and exited containers")
|
||||
|
||||
flags.BoolP(
|
||||
"enable-lifecycle-hooks",
|
||||
"",
|
||||
viper.GetBool("WATCHTOWER_LIFECYCLE_HOOKS"),
|
||||
"Enable the execution of commands triggered by pre- and post-update lifecycle hooks")
|
||||
}
|
||||
|
||||
// RegisterNotificationFlags that are used by watchtower to send notifications
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue