mirror of
https://github.com/containrrr/watchtower.git
synced 2025-12-14 06:06:38 +01:00
Adds scopeUID config to enable multiple instances of Watchtower (#511)
* Adds scopeUID config to enable multiple instances of Watchtower * Adds tests for multiple instance support with scopeuid * Adds docs on scope monitoring and multiple instance support * Adds multiple instances docs to mkdocs config file * Changes multiple instances check and refactors naming for scope feature * Applies linter suggestions * Fixes documentation on Watchtower monitoring scope
This commit is contained in:
parent
5efb249a86
commit
6a18ee911e
14 changed files with 160 additions and 24 deletions
|
|
@ -90,6 +90,17 @@ func (c Container) Enabled() (bool, bool) {
|
|||
return parsedBool, true
|
||||
}
|
||||
|
||||
// Scope returns the value of the scope UID label and if the label
|
||||
// was set.
|
||||
func (c Container) Scope() (string, bool) {
|
||||
rawString, ok := c.getLabelValue(scope)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
|
||||
return rawString, true
|
||||
}
|
||||
|
||||
// Links returns a list containing the names of all the containers to which
|
||||
// this container is linked.
|
||||
func (c Container) Links() []string {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ const (
|
|||
enableLabel = "com.centurylinklabs.watchtower.enable"
|
||||
dependsOnLabel = "com.centurylinklabs.watchtower.depends-on"
|
||||
zodiacLabel = "com.centurylinklabs.zodiac.original-image"
|
||||
scope = "com.centurylinklabs.watchtower.scope"
|
||||
preCheckLabel = "com.centurylinklabs.watchtower.lifecycle.pre-check"
|
||||
postCheckLabel = "com.centurylinklabs.watchtower.lifecycle.post-check"
|
||||
preUpdateLabel = "com.centurylinklabs.watchtower.lifecycle.pre-update"
|
||||
|
|
|
|||
|
|
@ -55,3 +55,27 @@ func (_m *FilterableContainer) Name() string {
|
|||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Scope provides a mock function with given fields:
|
||||
func (_m *FilterableContainer) Scope() (string, bool) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 string
|
||||
|
||||
if rf, ok := ret.Get(0).(func() string); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
var r1 bool
|
||||
|
||||
if rf, ok := ret.Get(1).(func() bool); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Get(1).(bool)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,8 +51,24 @@ func FilterByDisabledLabel(baseFilter t.Filter) t.Filter {
|
|||
}
|
||||
}
|
||||
|
||||
// FilterByScope returns all containers that belongs to a specific scope
|
||||
func FilterByScope(scope string, baseFilter t.Filter) t.Filter {
|
||||
if scope == "" {
|
||||
return baseFilter
|
||||
}
|
||||
|
||||
return func(c t.FilterableContainer) bool {
|
||||
containerScope, ok := c.Scope()
|
||||
if ok && containerScope == scope {
|
||||
return baseFilter(c)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// BuildFilter creates the needed filter of containers
|
||||
func BuildFilter(names []string, enableLabel bool) t.Filter {
|
||||
func BuildFilter(names []string, enableLabel bool, scope string) t.Filter {
|
||||
filter := NoFilter
|
||||
filter = FilterByNames(names, filter)
|
||||
if enableLabel {
|
||||
|
|
@ -60,6 +76,11 @@ func BuildFilter(names []string, enableLabel bool) t.Filter {
|
|||
// if the label is specifically set.
|
||||
filter = FilterByEnableLabel(filter)
|
||||
}
|
||||
if scope != "" {
|
||||
// If a scope has been defined, containers should only be considered
|
||||
// if the scope is specifically set.
|
||||
filter = FilterByScope(scope, filter)
|
||||
}
|
||||
filter = FilterByDisabledLabel(filter)
|
||||
return filter
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,29 @@ func TestFilterByEnableLabel(t *testing.T) {
|
|||
container.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestFilterByScope(t *testing.T) {
|
||||
var scope string
|
||||
scope = "testscope"
|
||||
|
||||
filter := FilterByScope(scope, NoFilter)
|
||||
assert.NotNil(t, filter)
|
||||
|
||||
container := new(mocks.FilterableContainer)
|
||||
container.On("Scope").Return("testscope", true)
|
||||
assert.True(t, filter(container))
|
||||
container.AssertExpectations(t)
|
||||
|
||||
container = new(mocks.FilterableContainer)
|
||||
container.On("Scope").Return("nottestscope", true)
|
||||
assert.False(t, filter(container))
|
||||
container.AssertExpectations(t)
|
||||
|
||||
container = new(mocks.FilterableContainer)
|
||||
container.On("Scope").Return("", false)
|
||||
assert.False(t, filter(container))
|
||||
container.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestFilterByDisabledLabel(t *testing.T) {
|
||||
filter := FilterByDisabledLabel(NoFilter)
|
||||
assert.NotNil(t, filter)
|
||||
|
|
@ -91,7 +114,7 @@ func TestBuildFilter(t *testing.T) {
|
|||
var names []string
|
||||
names = append(names, "test")
|
||||
|
||||
filter := BuildFilter(names, false)
|
||||
filter := BuildFilter(names, false, "")
|
||||
|
||||
container := new(mocks.FilterableContainer)
|
||||
container.On("Name").Return("Invalid")
|
||||
|
|
@ -127,7 +150,7 @@ func TestBuildFilterEnableLabel(t *testing.T) {
|
|||
var names []string
|
||||
names = append(names, "test")
|
||||
|
||||
filter := BuildFilter(names, true)
|
||||
filter := BuildFilter(names, true, "")
|
||||
|
||||
container := new(mocks.FilterableContainer)
|
||||
container.On("Enabled").Return(false, false)
|
||||
|
|
|
|||
|
|
@ -6,4 +6,5 @@ type FilterableContainer interface {
|
|||
Name() string
|
||||
IsWatchtower() bool
|
||||
Enabled() (bool, bool)
|
||||
Scope() (string, bool)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue