From 026a04b59b2a09a9287cec57af50e77ce2f8f2c6 Mon Sep 17 00:00:00 2001 From: Fabrizio Steiner Date: Fri, 2 Mar 2018 17:22:42 +0100 Subject: [PATCH 1/5] implemented enableLabel by a Filter --- README.md | 6 ++--- actions/check.go | 4 +-- actions/update.go | 21 ++------------- container/client.go | 25 +++++------------- container/filters.go | 61 ++++++++++++++++++++++++++++++++++++++++++++ main.go | 8 ++++-- 6 files changed, 79 insertions(+), 46 deletions(-) create mode 100644 container/filters.go diff --git a/README.md b/README.md index 8b3b260..4f84340 100644 --- a/README.md +++ b/README.md @@ -129,9 +129,9 @@ docker run -d --label=com.centurylinklabs.watchtower.stop-signal=SIGHUP someimag ## Selectively Watching Containers -By default, watchtower will watch all containers. -However, sometimes only some containers should be updated. -If you need to selectively watch containers, pass the --label-enable flag on startup and set the *com.centurylinklabs.watchtower.enable* label with a value of true for the containers you want to watch. +By default, watchtower will watch all containers. However, sometimes only some containers should be updated. + +If you need to only include only some containers, pass the --label-enable flag on startup and set the *com.centurylinklabs.watchtower.enable* label with a value of true for the containers you want to watch. ```docker LABEL com.centurylinklabs.watchtower.enable="true" diff --git a/actions/check.go b/actions/check.go index 8fb5786..5354dd7 100644 --- a/actions/check.go +++ b/actions/check.go @@ -6,14 +6,12 @@ import ( "github.com/v2tec/watchtower/container" ) -func watchtowerContainersFilter(c container.Container) bool { return c.IsWatchtower() } - // CheckPrereqs will ensure that there are not multiple instances of the // watchtower running simultaneously. If multiple watchtower containers are // detected, this function will stop and remove all but the most recently // started container. func CheckPrereqs(client container.Client, cleanup bool) error { - containers, err := client.ListContainers(watchtowerContainersFilter) + containers, err := client.ListContainers(container.WatchtowerContainersFilter) if err != nil { return err } diff --git a/actions/update.go b/actions/update.go index 3866d4b..4d488a5 100644 --- a/actions/update.go +++ b/actions/update.go @@ -12,31 +12,14 @@ var ( letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") ) -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 // 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 // the new image. -func Update(client container.Client, names []string, cleanup bool, noRestart bool, timeout time.Duration) error { +func Update(client container.Client, filter container.Filter, cleanup bool, noRestart bool, timeout time.Duration) error { log.Debug("Checking containers for updated images") - containers, err := client.ListContainers(containerFilter(names)) + containers, err := client.ListContainers(filter) if err != nil { return err } diff --git a/container/client.go b/container/client.go index 340c51b..5a75163 100644 --- a/container/client.go +++ b/container/client.go @@ -5,10 +5,10 @@ import ( "io/ioutil" "time" - log "github.com/sirupsen/logrus" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/network" dockerclient "github.com/docker/docker/client" + log "github.com/sirupsen/logrus" "golang.org/x/net/context" ) @@ -16,10 +16,6 @@ const ( defaultStopSignal = "SIGTERM" ) -// A Filter is a prototype for a function that can be used to filter the -// results from a call to the ListContainers() method on the Client. -type Filter func(Container) bool - // A Client is the interface through which watchtower interacts with the // Docker API. type Client interface { @@ -37,20 +33,19 @@ type Client interface { // * DOCKER_HOST the docker-engine host to send api requests to // * DOCKER_TLS_VERIFY whether to verify tls certificates // * DOCKER_API_VERSION the minimum docker api version to work with -func NewClient(pullImages, enableLabel bool) Client { +func NewClient(pullImages bool) Client { cli, err := dockerclient.NewEnvClient() if err != nil { log.Fatalf("Error instantiating Docker client: %s", err) } - return dockerClient{api: cli, pullImages: pullImages, enableLabel: enableLabel} + return dockerClient{api: cli, pullImages: pullImages} } type dockerClient struct { - api *dockerclient.Client - pullImages bool - enableLabel bool + api *dockerclient.Client + pullImages bool } func (client dockerClient) ListContainers(fn Filter) ([]Container, error) { @@ -62,6 +57,7 @@ func (client dockerClient) ListContainers(fn Filter) ([]Container, error) { runningContainers, err := client.api.ContainerList( bg, types.ContainerListOptions{}) + if err != nil { return nil, err } @@ -79,15 +75,6 @@ func (client dockerClient) ListContainers(fn Filter) ([]Container, error) { c := Container{containerInfo: &containerInfo, imageInfo: &imageInfo} - if client.enableLabel { - // If label filtering is enabled, containers should only be enabled - // if the label is specifically set to true. - enabledLabel, ok := c.Enabled() - if !ok || !enabledLabel { - continue - } - } - if fn(c) { cs = append(cs, c) } diff --git a/container/filters.go b/container/filters.go new file mode 100644 index 0000000..894cbc3 --- /dev/null +++ b/container/filters.go @@ -0,0 +1,61 @@ +package container + +// A Filter is a prototype for a function that can be used to filter the +// results from a call to the ListContainers() method on the Client. +type Filter func(FilterableContainer) bool + +// A FilterableContainer is the interface which is used to filter +// containers. +type FilterableContainer interface { + Name() string + IsWatchtower() bool + Enabled() (bool, bool) +} + +// WatchtowerContainersFilter filters only watchtower containers +func WatchtowerContainersFilter(c FilterableContainer) bool { return c.IsWatchtower() } + +// Filter no containers and returns all +func noFilter(FilterableContainer) bool { return true } + +// Filters containers which don't have a specified name +func filterByNames(names []string, baseFilter Filter) Filter { + if len(names) == 0 { + return baseFilter + } + + return func(c FilterableContainer) bool { + for _, name := range names { + if (name == c.Name()) || (name == c.Name()[1:]) { + return baseFilter(c) + } + } + return false + } +} + +// Filters out containers that don't have the 'enableLabel' +func filterByEnableLabel(baseFilter Filter) Filter { + return func(c FilterableContainer) bool { + // If label filtering is enabled, containers should only be enabled + // if the label is specifically set to true. + enabledLabel, ok := c.Enabled() + if !ok || !enabledLabel { + return false + } + + return baseFilter(c) + } +} + +// BuildFilter creates the needed filter of containers +func BuildFilter(names []string, enableLabel bool) Filter { + filter := noFilter + filter = filterByNames(names, filter) + if enableLabel { + // If label filtering is enabled, containers should only be considered + // if the label is specifically set. + filter = filterByEnableLabel(filter) + } + return filter +} diff --git a/main.go b/main.go index c84f26c..97fe15d 100644 --- a/main.go +++ b/main.go @@ -29,6 +29,7 @@ var ( scheduleSpec string cleanup bool noRestart bool + enableLabel bool notifier *notifications.Notifier timeout time.Duration ) @@ -189,6 +190,7 @@ func before(c *cli.Context) error { if timeout < 0 { log.Fatal("Please specify a positive value for timeout value.") } + enableLabel = c.GlobalBool("label-enable") // configure environment vars for client err := envConfig(c) @@ -196,7 +198,7 @@ func before(c *cli.Context) error { return err } - client = container.NewClient(!c.GlobalBool("no-pull"), c.GlobalBool("label-enable")) + client = container.NewClient(!c.GlobalBool("no-pull")) notifier = notifications.NewNotifier(c) return nil @@ -209,6 +211,8 @@ func start(c *cli.Context) error { log.Fatal(err) } + filter := container.BuildFilter(names, enableLabel) + tryLockSem := make(chan bool, 1) tryLockSem <- true @@ -220,7 +224,7 @@ func start(c *cli.Context) error { case v := <-tryLockSem: defer func() { tryLockSem <- v }() notifier.StartNotification() - if err := actions.Update(client, names, cleanup, noRestart, timeout); err != nil { + if err := actions.Update(client, filter, cleanup, noRestart, timeout); err != nil { log.Println(err) } notifier.SendNotification() From 6c12aee9752a6f879d9d2a4c8905c8b340c81570 Mon Sep 17 00:00:00 2001 From: Fabrizio Steiner Date: Fri, 2 Mar 2018 18:08:57 +0100 Subject: [PATCH 2/5] always exclude containers that have the com.centurylinklabs.watchtower.enable set to false. Fixes #169 --- README.md | 12 ++++++++++++ container/filters.go | 20 +++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4f84340..74748f8 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,18 @@ docker run -d --label=com.centurylinklabs.watchtower.stop-signal=SIGHUP someimag By default, watchtower will watch all containers. However, sometimes only some containers should be updated. +If you need to exclude some containers, set the *com.centurylinklabs.watchtower.enable* label to `false`. + +```docker +LABEL com.centurylinklabs.watchtower.enable="false" +``` + +Or, it can be specified as part of the `docker run` command line: + +```bash +docker run -d --label=com.centurylinklabs.watchtower.enable=false someimage +``` + If you need to only include only some containers, pass the --label-enable flag on startup and set the *com.centurylinklabs.watchtower.enable* label with a value of true for the containers you want to watch. ```docker diff --git a/container/filters.go b/container/filters.go index 894cbc3..1b3fbbd 100644 --- a/container/filters.go +++ b/container/filters.go @@ -37,10 +37,23 @@ func filterByNames(names []string, baseFilter Filter) Filter { // Filters out containers that don't have the 'enableLabel' func filterByEnableLabel(baseFilter Filter) Filter { return func(c FilterableContainer) bool { - // If label filtering is enabled, containers should only be enabled - // if the label is specifically set to true. + // If label filtering is enabled, containers should only be considered + // if the label is specifically set. + _, ok := c.Enabled() + if !ok { + return false + } + + return baseFilter(c) + } +} + +// Filters out containers that have a 'enableLabel' and is set to disable. +func filterByDisabledLabel(baseFilter Filter) Filter { + return func(c FilterableContainer) bool { enabledLabel, ok := c.Enabled() - if !ok || !enabledLabel { + if ok && !enabledLabel { + // If the label has been set and it demands a disable return false } @@ -57,5 +70,6 @@ func BuildFilter(names []string, enableLabel bool) Filter { // if the label is specifically set. filter = filterByEnableLabel(filter) } + filter = filterByDisabledLabel(filter) return filter } From 6d4e7cffaf917635c14ba1d2f8725a7283f4cc7a Mon Sep 17 00:00:00 2001 From: Fabrizio Steiner Date: Fri, 2 Mar 2018 21:26:43 +0100 Subject: [PATCH 3/5] add tests for filters --- container/filters_test.go | 152 +++++++++++++++++++++++++ container/mocks/FilterableContainer.go | 58 ++++++++++ 2 files changed, 210 insertions(+) create mode 100644 container/filters_test.go create mode 100644 container/mocks/FilterableContainer.go diff --git a/container/filters_test.go b/container/filters_test.go new file mode 100644 index 0000000..1129be3 --- /dev/null +++ b/container/filters_test.go @@ -0,0 +1,152 @@ +package container + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/v2tec/watchtower/container/mocks" +) + +func TestWatchtowerContainersFilter(t *testing.T) { + container := new(mocks.FilterableContainer) + + container.On("IsWatchtower").Return(true) + + assert.True(t, WatchtowerContainersFilter(container)) + + container.AssertExpectations(t) +} + +func TestNoFilter(t *testing.T) { + container := new(mocks.FilterableContainer) + + assert.True(t, noFilter(container)) + + container.AssertExpectations(t) +} + +func TestFilterByNames(t *testing.T) { + filter := filterByNames(make([]string, 0), nil) + assert.Nil(t, filter) + + names := make([]string, 0) + names = append(names, "test") + + filter = filterByNames(names, noFilter) + assert.NotNil(t, filter) + + container := new(mocks.FilterableContainer) + container.On("Name").Return("test") + assert.True(t, filter(container)) + container.AssertExpectations(t) + + container = new(mocks.FilterableContainer) + container.On("Name").Return("NoTest") + assert.False(t, filter(container)) + container.AssertExpectations(t) +} + +func TestFilterByEnableLabel(t *testing.T) { + filter := filterByEnableLabel(noFilter) + assert.NotNil(t, filter) + + container := new(mocks.FilterableContainer) + container.On("Enabled").Return(true, true) + assert.True(t, filter(container)) + container.AssertExpectations(t) + + container = new(mocks.FilterableContainer) + container.On("Enabled").Return(false, true) + assert.True(t, filter(container)) + container.AssertExpectations(t) + + container = new(mocks.FilterableContainer) + container.On("Enabled").Return(false, false) + assert.False(t, filter(container)) + container.AssertExpectations(t) +} + +func TestFilterByDisabledLabel(t *testing.T) { + filter := filterByDisabledLabel(noFilter) + assert.NotNil(t, filter) + + container := new(mocks.FilterableContainer) + container.On("Enabled").Return(true, true) + assert.True(t, filter(container)) + container.AssertExpectations(t) + + container = new(mocks.FilterableContainer) + container.On("Enabled").Return(false, true) + assert.False(t, filter(container)) + container.AssertExpectations(t) + + container = new(mocks.FilterableContainer) + container.On("Enabled").Return(false, false) + assert.True(t, filter(container)) + container.AssertExpectations(t) +} + +func TestBuildFilter(t *testing.T) { + names := make([]string, 0) + names = append(names, "test") + + filter := BuildFilter(names, false) + + container := new(mocks.FilterableContainer) + container.On("Name").Return("Invalid") + container.On("Enabled").Return(false, false) + assert.False(t, filter(container)) + container.AssertExpectations(t) + + container = new(mocks.FilterableContainer) + container.On("Name").Return("test") + container.On("Enabled").Return(false, false) + assert.True(t, filter(container)) + container.AssertExpectations(t) + + container = new(mocks.FilterableContainer) + container.On("Name").Return("Invalid") + container.On("Enabled").Return(true, true) + assert.False(t, filter(container)) + container.AssertExpectations(t) + + container = new(mocks.FilterableContainer) + container.On("Name").Return("test") + container.On("Enabled").Return(true, true) + assert.True(t, filter(container)) + container.AssertExpectations(t) + + container = new(mocks.FilterableContainer) + container.On("Enabled").Return(false, true) + assert.False(t, filter(container)) + container.AssertExpectations(t) +} + +func TestBuildFilterEnableLabel(t *testing.T) { + names := make([]string, 0) + names = append(names, "test") + + filter := BuildFilter(names, true) + + container := new(mocks.FilterableContainer) + container.On("Enabled").Return(false, false) + assert.False(t, filter(container)) + container.AssertExpectations(t) + + container = new(mocks.FilterableContainer) + container.On("Name").Return("Invalid") + container.On("Enabled").Twice().Return(true, true) + assert.False(t, filter(container)) + container.AssertExpectations(t) + + container = new(mocks.FilterableContainer) + container.On("Name").Return("test") + container.On("Enabled").Twice().Return(true, true) + assert.True(t, filter(container)) + container.AssertExpectations(t) + + container = new(mocks.FilterableContainer) + container.On("Enabled").Return(false, true) + assert.False(t, filter(container)) + container.AssertExpectations(t) +} diff --git a/container/mocks/FilterableContainer.go b/container/mocks/FilterableContainer.go new file mode 100644 index 0000000..15f9db5 --- /dev/null +++ b/container/mocks/FilterableContainer.go @@ -0,0 +1,58 @@ +// Code generated by mockery v1.0.0 +package mocks + +import mock "github.com/stretchr/testify/mock" + +// FilterableContainer is an autogenerated mock type for the FilterableContainer type +type FilterableContainer struct { + mock.Mock +} + +// Enabled provides a mock function with given fields: +func (_m *FilterableContainer) Enabled() (bool, bool) { + ret := _m.Called() + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + var r1 bool + if rf, ok := ret.Get(1).(func() bool); ok { + r1 = rf() + } else { + r1 = ret.Get(1).(bool) + } + + return r0, r1 +} + +// IsWatchtower provides a mock function with given fields: +func (_m *FilterableContainer) IsWatchtower() bool { + ret := _m.Called() + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// Name provides a mock function with given fields: +func (_m *FilterableContainer) Name() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} From 1f10817b4bf669909f6d0ebfce10edf9c2c04491 Mon Sep 17 00:00:00 2001 From: Fabrizio Steiner Date: Fri, 2 Mar 2018 22:26:39 +0100 Subject: [PATCH 4/5] Removed unused mock code. --- container/mockclient/mock.go | 42 ------------------------------- container/mockclient/mock_test.go | 17 ------------- 2 files changed, 59 deletions(-) delete mode 100644 container/mockclient/mock.go delete mode 100644 container/mockclient/mock_test.go diff --git a/container/mockclient/mock.go b/container/mockclient/mock.go deleted file mode 100644 index 62cd321..0000000 --- a/container/mockclient/mock.go +++ /dev/null @@ -1,42 +0,0 @@ -package mockclient - -import ( - "time" - - "github.com/stretchr/testify/mock" - "github.com/v2tec/watchtower/container" -) - -type MockClient struct { - mock.Mock -} - -func (m *MockClient) ListContainers(cf container.Filter) ([]container.Container, error) { - args := m.Called(cf) - return args.Get(0).([]container.Container), args.Error(1) -} - -func (m *MockClient) StopContainer(c container.Container, timeout time.Duration) error { - args := m.Called(c, timeout) - return args.Error(0) -} - -func (m *MockClient) StartContainer(c container.Container) error { - args := m.Called(c) - return args.Error(0) -} - -func (m *MockClient) RenameContainer(c container.Container, name string) error { - args := m.Called(c, name) - return args.Error(0) -} - -func (m *MockClient) IsContainerStale(c container.Container) (bool, error) { - args := m.Called(c) - return args.Bool(0), args.Error(1) -} - -func (m *MockClient) RemoveImage(c container.Container) error { - args := m.Called(c) - return args.Error(0) -} diff --git a/container/mockclient/mock_test.go b/container/mockclient/mock_test.go deleted file mode 100644 index 234a218..0000000 --- a/container/mockclient/mock_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package mockclient - -import ( - "reflect" - "testing" - - "github.com/v2tec/watchtower/container" -) - -func TestMockInterface(t *testing.T) { - iface := reflect.TypeOf((*container.Client)(nil)).Elem() - mock := &MockClient{} - - if !reflect.TypeOf(mock).Implements(iface) { - t.Fatalf("Mock does not implement the Client interface") - } -} From d0ac9f14aba908af2da273ed2c6e34ea6521cf41 Mon Sep 17 00:00:00 2001 From: Fabrizio Steiner Date: Fri, 2 Mar 2018 22:37:50 +0100 Subject: [PATCH 5/5] some linting --- container/client.go | 3 +- container/container.go | 2 +- container/filters_test.go | 9 +++--- container/mocks/FilterableContainer.go | 1 - container/trust.go | 43 ++++++++++---------------- 5 files changed, 23 insertions(+), 35 deletions(-) diff --git a/container/client.go b/container/client.go index 5a75163..476e3ca 100644 --- a/container/client.go +++ b/container/client.go @@ -216,10 +216,9 @@ func (client dockerClient) IsContainerStale(c Container) (bool, error) { if newImageInfo.ID != oldImageInfo.ID { log.Infof("Found new %s image (%s)", imageName, newImageInfo.ID) return true, nil - } else { - log.Debugf("No new images found for %s", c.Name()) } + log.Debugf("No new images found for %s", c.Name()) return false, nil } diff --git a/container/container.go b/container/container.go index e620d92..7453507 100644 --- a/container/container.go +++ b/container/container.go @@ -155,7 +155,7 @@ func (c Container) runtimeConfig() *dockercontainer.Config { config.Volumes = structMapSubtract(config.Volumes, imageConfig.Volumes) // subtract ports exposed in image from container - for k, _ := range config.ExposedPorts { + for k := range config.ExposedPorts { if _, ok := imageConfig.ExposedPorts[k]; ok { delete(config.ExposedPorts, k) } diff --git a/container/filters_test.go b/container/filters_test.go index 1129be3..25a0118 100644 --- a/container/filters_test.go +++ b/container/filters_test.go @@ -26,10 +26,11 @@ func TestNoFilter(t *testing.T) { } func TestFilterByNames(t *testing.T) { - filter := filterByNames(make([]string, 0), nil) + var names []string + + filter := filterByNames(names, nil) assert.Nil(t, filter) - names := make([]string, 0) names = append(names, "test") filter = filterByNames(names, noFilter) @@ -87,7 +88,7 @@ func TestFilterByDisabledLabel(t *testing.T) { } func TestBuildFilter(t *testing.T) { - names := make([]string, 0) + var names []string names = append(names, "test") filter := BuildFilter(names, false) @@ -123,7 +124,7 @@ func TestBuildFilter(t *testing.T) { } func TestBuildFilterEnableLabel(t *testing.T) { - names := make([]string, 0) + var names []string names = append(names, "test") filter := BuildFilter(names, true) diff --git a/container/mocks/FilterableContainer.go b/container/mocks/FilterableContainer.go index 15f9db5..508bd7c 100644 --- a/container/mocks/FilterableContainer.go +++ b/container/mocks/FilterableContainer.go @@ -1,4 +1,3 @@ -// Code generated by mockery v1.0.0 package mocks import mock "github.com/stretchr/testify/mock" diff --git a/container/trust.go b/container/trust.go index 90ba335..e388302 100644 --- a/container/trust.go +++ b/container/trust.go @@ -5,20 +5,18 @@ import ( "os" "strings" - log "github.com/sirupsen/logrus" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/reference" "github.com/docker/docker/cli/command" "github.com/docker/docker/cliconfig" "github.com/docker/docker/cliconfig/configfile" "github.com/docker/docker/cliconfig/credentials" + log "github.com/sirupsen/logrus" ) -/** - * Return an encoded auth config for the given registry - * loaded from environment variables or docker config - * as available in that order - */ +// EncodedAuth returns an encoded auth config for the given registry +// loaded from environment variables or docker config +// as available in that order func EncodedAuth(ref string) (string, error) { auth, err := EncodedEnvAuth(ref) if err != nil { @@ -27,11 +25,9 @@ func EncodedAuth(ref string) (string, error) { return auth, err } -/* - * Return an encoded auth config for the given registry - * loaded from environment variables - * Returns an error if authentication environment variables have not been set - */ +// EncodedEnvAuth returns an encoded auth config for the given registry +// loaded from environment variables +// Returns an error if authentication environment variables have not been set func EncodedEnvAuth(ref string) (string, error) { username := os.Getenv("REPO_USER") password := os.Getenv("REPO_PASS") @@ -42,17 +38,14 @@ func EncodedEnvAuth(ref string) (string, error) { } log.Debugf("Loaded auth credentials %s for %s", auth, ref) return EncodeAuth(auth) - } else { - return "", errors.New("Registry auth environment variables (REPO_USER, REPO_PASS) not set") } + return "", errors.New("Registry auth environment variables (REPO_USER, REPO_PASS) not set") } -/* - * Return an encoded auth config for the given registry - * loaded from the docker config - * Returns an empty string if credentials cannot be found for the referenced server - * The docker config must be mounted on the container - */ +// EncodedConfigAuth returns an encoded auth config for the given registry +// loaded from the docker config +// Returns an empty string if credentials cannot be found for the referenced server +// The docker config must be mounted on the container func EncodedConfigAuth(ref string) (string, error) { server, err := ParseServerAddress(ref) configDir := os.Getenv("DOCKER_CONFIG") @@ -92,18 +85,14 @@ func CredentialsStore(configFile configfile.ConfigFile) credentials.Store { return credentials.NewFileStore(&configFile) } -/* - * Base64 encode an AuthConfig struct for transmission over HTTP - */ +// EncodeAuth Base64 encode an AuthConfig struct for transmission over HTTP func EncodeAuth(auth types.AuthConfig) (string, error) { return command.EncodeAuthToBase64(auth) } -/** - * This function will be invoked if an AuthConfig is rejected - * It could be used to return a new value for the "X-Registry-Auth" authentication header, - * but there's no point trying again with the same value as used in AuthConfig - */ +// DefaultAuthHandler will be invoked if an AuthConfig is rejected +// It could be used to return a new value for the "X-Registry-Auth" authentication header, +// but there's no point trying again with the same value as used in AuthConfig func DefaultAuthHandler() (string, error) { log.Debug("Authentication request was rejected. Trying again without authentication") return "", nil