From 4275d1cd3d43b7a4c01331bd049de93900be7681 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Wed, 22 Jul 2015 22:52:22 +0000 Subject: [PATCH] Add more accessors to Container struct --- container/client.go | 31 +++++++------------ container/container.go | 29 +++++++++++++++++- container/container_test.go | 60 +++++++++++++++++++++++++++++++++++-- 3 files changed, 97 insertions(+), 23 deletions(-) diff --git a/container/client.go b/container/client.go index 9e88423..7fdbf9a 100644 --- a/container/client.go +++ b/container/client.go @@ -1,8 +1,6 @@ package container import ( - "fmt" - "strings" "time" log "github.com/Sirupsen/logrus" @@ -11,7 +9,6 @@ import ( const ( defaultStopSignal = "SIGTERM" - signalLabel = "com.centurylinklabs.watchtower.stop-signal" ) type Filter func(Container) bool @@ -74,24 +71,23 @@ func (client DockerClient) ListContainers(fn Filter) ([]Container, error) { } func (client DockerClient) StopContainer(c Container, timeout time.Duration) error { - signal := defaultStopSignal - - if sig, ok := c.containerInfo.Config.Labels[signalLabel]; ok { - signal = sig + signal := c.StopSignal() + if signal == "" { + signal = defaultStopSignal } - log.Infof("Stopping %s (%s) with %s", c.Name(), c.containerInfo.Id, signal) + log.Infof("Stopping %s (%s) with %s", c.Name(), c.ID(), signal) - if err := client.api.KillContainer(c.containerInfo.Id, signal); err != nil { + if err := client.api.KillContainer(c.ID(), signal); err != nil { return err } // Wait for container to exit, but proceed anyway after the timeout elapses client.waitForStop(c, timeout) - log.Debugf("Removing container %s", c.containerInfo.Id) + log.Debugf("Removing container %s", c.ID()) - return client.api.RemoveContainer(c.containerInfo.Id, true, false) + return client.api.RemoveContainer(c.ID(), true, false) } func (client DockerClient) StartContainer(c Container) error { @@ -112,20 +108,15 @@ func (client DockerClient) StartContainer(c Container) error { } func (client DockerClient) RenameContainer(c Container, newName string) error { - log.Debugf("Renaming container %s (%s) to %s", c.Name(), c.containerInfo.Id, newName) - return client.api.RenameContainer(c.containerInfo.Id, newName) + log.Debugf("Renaming container %s (%s) to %s", c.Name(), c.ID(), newName) + return client.api.RenameContainer(c.ID(), newName) } func (client DockerClient) IsContainerStale(c Container) (bool, error) { - containerInfo := c.containerInfo oldImageInfo := c.imageInfo - imageName := containerInfo.Config.Image + imageName := c.ImageName() if client.pullImages { - if !strings.Contains(imageName, ":") { - imageName = fmt.Sprintf("%s:latest", imageName) - } - log.Debugf("Pulling %s for %s", imageName, c.Name()) if err := client.api.PullImage(imageName, nil); err != nil { return false, err @@ -153,7 +144,7 @@ func (client DockerClient) waitForStop(c Container, waitTime time.Duration) erro case <-timeout: return nil default: - if ci, err := client.api.InspectContainer(c.containerInfo.Id); err != nil { + if ci, err := client.api.InspectContainer(c.ID()); err != nil { return err } else if !ci.State.Running { return nil diff --git a/container/container.go b/container/container.go index 423bf3b..f7a506a 100644 --- a/container/container.go +++ b/container/container.go @@ -7,6 +7,11 @@ import ( "github.com/samalba/dockerclient" ) +const ( + watchtowerLabel = "com.centurylinklabs.watchtower" + signalLabel = "com.centurylinklabs.watchtower.stop-signal" +) + func NewContainer(containerInfo *dockerclient.ContainerInfo, imageInfo *dockerclient.ImageInfo) *Container { return &Container{ containerInfo: containerInfo, @@ -21,10 +26,24 @@ type Container struct { imageInfo *dockerclient.ImageInfo } +func (c Container) ID() string { + return c.containerInfo.Id +} + func (c Container) Name() string { return c.containerInfo.Name } +func (c Container) ImageName() string { + imageName := c.containerInfo.Config.Image + + if !strings.Contains(imageName, ":") { + imageName = fmt.Sprintf("%s:latest", imageName) + } + + return imageName +} + func (c Container) Links() []string { var links []string @@ -39,10 +58,18 @@ func (c Container) Links() []string { } func (c Container) IsWatchtower() bool { - val, ok := c.containerInfo.Config.Labels["com.centurylinklabs.watchtower"] + val, ok := c.containerInfo.Config.Labels[watchtowerLabel] return ok && val == "true" } +func (c Container) StopSignal() string { + if val, ok := c.containerInfo.Config.Labels[signalLabel]; ok { + return val + } + + return "" +} + // Ideally, we'd just be able to take the ContainerConfig from the old container // and use it as the starting point for creating the new container; however, // the ContainerConfig that comes back from the Inspect call merges the default diff --git a/container/container_test.go b/container/container_test.go index 4d2237f..34cec85 100644 --- a/container/container_test.go +++ b/container/container_test.go @@ -7,14 +7,44 @@ import ( "github.com/stretchr/testify/assert" ) +func TestID(t *testing.T) { + c := Container{ + containerInfo: &dockerclient.ContainerInfo{Id: "foo"}, + } + + assert.Equal(t, "foo", c.ID()) +} + func TestName(t *testing.T) { c := Container{ containerInfo: &dockerclient.ContainerInfo{Name: "foo"}, } - name := c.Name() + assert.Equal(t, "foo", c.Name()) +} - assert.Equal(t, "foo", name) +func TestImageName_Tagged(t *testing.T) { + c := Container{ + containerInfo: &dockerclient.ContainerInfo{ + Config: &dockerclient.ContainerConfig{ + Image: "foo:latest", + }, + }, + } + + assert.Equal(t, "foo:latest", c.ImageName()) +} + +func TestImageName_Untagged(t *testing.T) { + c := Container{ + containerInfo: &dockerclient.ContainerInfo{ + Config: &dockerclient.ContainerConfig{ + Image: "foo", + }, + }, + } + + assert.Equal(t, "foo:latest", c.ImageName()) } func TestLinks(t *testing.T) { @@ -66,3 +96,29 @@ func TestIsWatchtower_NoLabel(t *testing.T) { assert.False(t, c.IsWatchtower()) } + +func TestStopSignal_Present(t *testing.T) { + c := Container{ + containerInfo: &dockerclient.ContainerInfo{ + Config: &dockerclient.ContainerConfig{ + Labels: map[string]string{ + "com.centurylinklabs.watchtower.stop-signal": "SIGQUIT", + }, + }, + }, + } + + assert.Equal(t, "SIGQUIT", c.StopSignal()) +} + +func TestStopSignal_NoLabel(t *testing.T) { + c := Container{ + containerInfo: &dockerclient.ContainerInfo{ + Config: &dockerclient.ContainerConfig{ + Labels: map[string]string{}, + }, + }, + } + + assert.Equal(t, "", c.StopSignal()) +}