Add support for whitelist of monitored containers

pull/1/head
Brian DeHamer 9 years ago
parent d6321bf8dc
commit b0910ee20b

@ -39,6 +39,21 @@ docker run -d \
centurylink/watchtower centurylink/watchtower
``` ```
### Arguments
By default, watchtower will monitor all containers running within the Docker daemon to which it is pointed (in most cases this will be the local Docker daemon, but you can override it with the `--host` option described in the next section). However, you can restrict watchtower to monitoring a subset of the running containers by specifying the container names as arguments when launching watchtower.
```
docker run -d \
--name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \
centurylink/watchtower nginx redis
```
In the example above, watchtower will only monitor the containers named "nginx" and "redis" for updates -- all of the other running containers will be ignored.
When no arguments are specified, watchtower will monitor all running containers.
### Options ### Options
Any of the options described below can be passed to the watchtower process by setting them after the image name in the `docker run` string: Any of the options described below can be passed to the watchtower process by setting them after the image name in the `docker run` string:
@ -59,7 +74,6 @@ docker run --rm centurylink/watchtower --help
* `--debug` - Enable debug mode. When this option is specified you'll see more verbose logging in the watchtower log file. * `--debug` - Enable debug mode. When this option is specified you'll see more verbose logging in the watchtower log file.
* `--help` - Show documentation about the supported flags. * `--help` - Show documentation about the supported flags.
## Stopping Containers ## Stopping Containers
When watchtower detects that a running container needs to be updated it will stop the container by sending it a SIGTERM signal. When watchtower detects that a running container needs to be updated it will stop the container by sending it a SIGTERM signal.

@ -15,14 +15,29 @@ var (
func allContainersFilter(container.Container) bool { return true } func allContainersFilter(container.Container) bool { return true }
func containerFilter(names []string) container.Filter {
if len(names) == 0 {
return allContainersFilter
}
return func(c container.Container) bool {
for _, name := range names {
if (name == c.Name()) || (name == c.Name()[1:]) {
return true
}
}
return false
}
}
// Update looks at the running Docker containers to see if any of the images // Update looks at the running Docker containers to see if any of the images
// used to start those containers have been updated. If a change is detected in // used to start those containers have been updated. If a change is detected in
// any of the images, the associated containers are stopped and restarted with // any of the images, the associated containers are stopped and restarted with
// the new image. // the new image.
func Update(client container.Client, cleanup bool) error { func Update(client container.Client, names []string, cleanup bool) error {
log.Info("Checking containers for updated images") log.Info("Checking containers for updated images")
containers, err := client.ListContainers(allContainersFilter) containers, err := client.ListContainers(containerFilter(names))
if err != nil { if err != nil {
return err return err
} }

@ -9,6 +9,30 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestContainerFilter_StraightMatch(t *testing.T) {
c := newTestContainer("foo", []string{})
f := containerFilter([]string{"foo"})
assert.True(t, f(c))
}
func TestContainerFilter_SlashMatch(t *testing.T) {
c := newTestContainer("/foo", []string{})
f := containerFilter([]string{"foo"})
assert.True(t, f(c))
}
func TestContainerFilter_NoMatch(t *testing.T) {
c := newTestContainer("/bar", []string{})
f := containerFilter([]string{"foo"})
assert.False(t, f(c))
}
func TestContainerFilter_NoFilters(t *testing.T) {
c := newTestContainer("/bar", []string{})
f := containerFilter([]string{})
assert.True(t, f(c))
}
func TestCheckDependencies(t *testing.T) { func TestCheckDependencies(t *testing.T) {
cs := []container.Container{ cs := []container.Container{
newTestContainer("1", []string{}), newTestContainer("1", []string{}),

@ -56,15 +56,11 @@ func (client dockerClient) ListContainers(fn Filter) ([]Container, error) {
} }
for _, runningContainer := range runningContainers { for _, runningContainer := range runningContainers {
log.Debugf("Inspecting container %s (%s)", runningContainer.Names[0], runningContainer.Id)
containerInfo, err := client.api.InspectContainer(runningContainer.Id) containerInfo, err := client.api.InspectContainer(runningContainer.Id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
log.Debugf("Inspecting image %s (%s)", containerInfo.Config.Image, containerInfo.Image)
imageInfo, err := client.api.InspectImage(containerInfo.Image) imageInfo, err := client.api.InspectImage(containerInfo.Image)
if err != nil { if err != nil {
return nil, err return nil, err

@ -116,14 +116,16 @@ func before(c *cli.Context) error {
return nil return nil
} }
func start(*cli.Context) { func start(c *cli.Context) {
names := c.Args()
if err := actions.CheckPrereqs(client, cleanup); err != nil { if err := actions.CheckPrereqs(client, cleanup); err != nil {
log.Fatal(err) log.Fatal(err)
} }
for { for {
wg.Add(1) wg.Add(1)
if err := actions.Update(client, cleanup); err != nil { if err := actions.Update(client, names, cleanup); err != nil {
fmt.Println(err) fmt.Println(err)
} }
wg.Done() wg.Done()

Loading…
Cancel
Save