mirror of
https://github.com/containrrr/watchtower.git
synced 2025-12-14 14:10:12 +01:00
Setup a working pipeline
* add tests to ensure function even after switching docker client api version * switch docker client api version to remove import of Sirupsen and get rid of the casing workaround * migrate from glide to dep to go modules * rewrite ci workflow * only run publish on version tags * only run build on branches * update goreleaser config * disable automated latest tag push * remove dependency to v2tec/docker-gobuilder * remove dead code and files * add golands .idea folder to gitignore * add label to released docker images * add test reporting, add some unit tests * change test output dir * fix goreleaser versions * add debug output for circleci and goreleaser * disable cgo
This commit is contained in:
parent
98f916f29a
commit
1b82da1ab7
16 changed files with 450 additions and 362 deletions
|
|
@ -187,6 +187,8 @@ func (client dockerClient) IsContainerStale(c Container) (bool, error) {
|
|||
|
||||
var opts types.ImagePullOptions // ImagePullOptions can take a RegistryAuth arg to authenticate against a private registry
|
||||
auth, err := EncodedAuth(imageName)
|
||||
log.Infof("Got auth value: %s", auth)
|
||||
log.Infof("Got image name: %s", imageName)
|
||||
if err != nil {
|
||||
log.Debugf("Error loading authentication credentials %s", err)
|
||||
return false, err
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/docker/docker/api/types"
|
||||
dockercontainer "github.com/docker/docker/api/types/container"
|
||||
)
|
||||
|
|
@ -102,8 +102,9 @@ func (c Container) Links() []string {
|
|||
// identified by the presence of the "com.centurylinklabs.watchtower" label in
|
||||
// the container metadata.
|
||||
func (c Container) IsWatchtower() bool {
|
||||
val, ok := c.containerInfo.Config.Labels[watchtowerLabel]
|
||||
return ok && val == "true"
|
||||
log.Debugf("Checking if %s is a watchtower instance.", c.Name())
|
||||
wasWatchtower := ContainsWatchtowerLabel(c.containerInfo.Config.Labels)
|
||||
return wasWatchtower
|
||||
}
|
||||
|
||||
// StopSignal returns the custom stop signal (if any) that is encoded in the
|
||||
|
|
@ -182,3 +183,10 @@ func (c Container) hostConfig() *dockercontainer.HostConfig {
|
|||
|
||||
return hostConfig
|
||||
}
|
||||
|
||||
// ContainsWatchtowerLabel takes a map of labels and values and tells
|
||||
// the consumer whether it contains a valid watchtower instance label
|
||||
func ContainsWatchtowerLabel(labels map[string]string) bool {
|
||||
val, ok := labels[watchtowerLabel]
|
||||
return ok && val == "true"
|
||||
}
|
||||
25
container/container_test.go
Normal file
25
container/container_test.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestContainsWatchtowerLabel_ShouldReturnTrueIfTheWatchtowerLabelExistsOnTheContainer(t *testing.T) {
|
||||
labelMap := map[string]string {
|
||||
"com.centurylinklabs.watchtower": "true",
|
||||
}
|
||||
assert.True(t, ContainsWatchtowerLabel(labelMap))
|
||||
}
|
||||
|
||||
func TestContainsWatchtowerLabel_ShouldReturnFalseIfTheWatchtowerLabelDoesntExistOnTheContainer(t *testing.T) {
|
||||
labelMap := map[string]string {
|
||||
"com.containrrr.watchtower": "lost",
|
||||
}
|
||||
assert.False(t, ContainsWatchtowerLabel(labelMap))
|
||||
}
|
||||
|
||||
func TestContainsWatchtowerLabel_ShouldReturnFalseIfLabelsIsEmpty(t *testing.T) {
|
||||
labelMap := map[string]string {}
|
||||
assert.False(t, ContainsWatchtowerLabel(labelMap))
|
||||
}
|
||||
|
|
@ -5,12 +5,12 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/command"
|
||||
cliconfig "github.com/docker/cli/cli/config"
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/cli/cli/config/credentials"
|
||||
"github.com/docker/distribution/reference"
|
||||
"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"
|
||||
)
|
||||
|
||||
|
|
@ -67,12 +67,15 @@ func EncodedConfigAuth(ref string) (string, error) {
|
|||
return EncodeAuth(auth)
|
||||
}
|
||||
|
||||
// ParseServerAddress extracts the server part from a container image ref
|
||||
func ParseServerAddress(ref string) (string, error) {
|
||||
repository, _, err := reference.Parse(ref)
|
||||
|
||||
parsedRef, err := reference.Parse(ref)
|
||||
if err != nil {
|
||||
return ref, err
|
||||
}
|
||||
parts := strings.Split(repository, "/")
|
||||
|
||||
parts := strings.Split(parsedRef.String(), "/")
|
||||
return parts[0], nil
|
||||
}
|
||||
|
||||
|
|
|
|||
60
container/trust_test.go
Normal file
60
container/trust_test.go
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestEncodedEnvAuth_ShouldReturnAnErrorIfRepoEnvsAreUnset(t *testing.T) {
|
||||
os.Unsetenv("REPO_USER")
|
||||
os.Unsetenv("REPO_PASS")
|
||||
_, err := EncodedEnvAuth("")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
func TestEncodedEnvAuth_ShouldReturnAuthHashIfRepoEnvsAreSet(t *testing.T) {
|
||||
expectedHash := "eyJ1c2VybmFtZSI6ImNvbnRhaW5ycnItdXNlciIsInBhc3N3b3JkIjoiY29udGFpbnJyci1wYXNzIn0="
|
||||
|
||||
os.Setenv("REPO_USER", "containrrr-user")
|
||||
os.Setenv("REPO_PASS", "containrrr-pass")
|
||||
config, _ := EncodedEnvAuth("")
|
||||
|
||||
assert.Equal(t, config, expectedHash)
|
||||
}
|
||||
|
||||
func TestEncodedConfigAuth_ShouldReturnAnErrorIfFileIsNotPresent(t *testing.T) {
|
||||
os.Setenv("DOCKER_CONFIG", "/dev/null/should-fail")
|
||||
_, err := EncodedConfigAuth("")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* This part only confirms that it still works in the same way as it did
|
||||
* with the old version of the docker api client sdk. I'd say that
|
||||
* ParseServerAddress likely needs to be elaborated a bit to default to
|
||||
* dockerhub in case no server address was provided.
|
||||
*
|
||||
* ++ @simskij, 2019-04-04
|
||||
*/
|
||||
|
||||
func TestParseServerAddress_ShouldReturnErrorIfPassedEmptyString(t *testing.T) {
|
||||
_, err := ParseServerAddress("")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestParseServerAddress_ShouldReturnTheRepoNameIfPassedAFullyQualifiedImageName(t *testing.T) {
|
||||
val, _ := ParseServerAddress("github.com/containrrrr/config")
|
||||
assert.Equal(t, val, "github.com")
|
||||
}
|
||||
|
||||
func TestParseServerAddress_ShouldReturnTheOrganizationPartIfPassedAnImageNameMissingServerName(t *testing.T) {
|
||||
val, _ := ParseServerAddress("containrrr/config")
|
||||
assert.Equal(t, val, "containrrr")
|
||||
}
|
||||
|
||||
func TestParseServerAddress_ShouldReturnTheServerNameIfPassedAFullyQualifiedImageName(t *testing.T) {
|
||||
val, _ := ParseServerAddress("github.com/containrrrr/config")
|
||||
assert.Equal(t, val, "github.com")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue