Consolidated all post-fork updates including dependency bumps and workflow changes

This commit is contained in:
dependabot[bot] 2023-10-04 12:17:38 +02:00 committed by Nick Fedor
parent 2abaa47fd3
commit 6b62d53797
No known key found for this signature in database
GPG key ID: A167CBEDE64D29CB
100 changed files with 1503 additions and 1264 deletions

View file

@ -1,7 +1,7 @@
package metrics
import (
"github.com/containrrr/watchtower/pkg/metrics"
"github.com/nicholas-fedor/watchtower/pkg/metrics"
"net/http"
"github.com/prometheus/client_golang/prometheus/promhttp"

View file

@ -2,18 +2,18 @@ package metrics_test
import (
"fmt"
"io/ioutil"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/containrrr/watchtower/pkg/api"
metricsAPI "github.com/containrrr/watchtower/pkg/api/metrics"
"github.com/containrrr/watchtower/pkg/metrics"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/nicholas-fedor/watchtower/pkg/api"
metricsAPI "github.com/nicholas-fedor/watchtower/pkg/api/metrics"
"github.com/nicholas-fedor/watchtower/pkg/metrics"
)
const (
@ -36,7 +36,7 @@ func getWithToken(handler http.Handler) map[string]string {
handler.ServeHTTP(respWriter, req)
res := respWriter.Result()
body, _ := ioutil.ReadAll(res.Body)
body, _ := io.ReadAll(res.Body)
for _, line := range strings.Split(string(body), "\n") {
if len(line) < 1 || line[0] == '#' {

View file

@ -5,7 +5,7 @@ import (
"os"
"regexp"
"github.com/containrrr/watchtower/pkg/types"
"github.com/nicholas-fedor/watchtower/pkg/types"
)
var dockerContainerPattern = regexp.MustCompile(`[0-9]+:.*:/docker/([a-f|0-9]{64})`)

View file

@ -3,21 +3,21 @@ package container
import (
"bytes"
"fmt"
"io/ioutil"
"io"
"strings"
"time"
"github.com/containrrr/watchtower/pkg/registry"
"github.com/containrrr/watchtower/pkg/registry/digest"
t "github.com/containrrr/watchtower/pkg/types"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/network"
sdkClient "github.com/docker/docker/client"
log "github.com/sirupsen/logrus"
"golang.org/x/net/context"
"github.com/nicholas-fedor/watchtower/pkg/registry"
"github.com/nicholas-fedor/watchtower/pkg/registry/digest"
t "github.com/nicholas-fedor/watchtower/pkg/types"
)
const defaultStopSignal = "SIGTERM"
@ -57,7 +57,6 @@ func NewClient(opts ClientOptions) Client {
// ClientOptions contains the options for how the docker client wrapper should behave
type ClientOptions struct {
PullImages bool
RemoveVolumes bool
IncludeStopped bool
ReviveStopped bool
@ -110,7 +109,7 @@ func (client dockerClient) ListContainers(fn t.Filter) ([]t.Container, error) {
filter := client.createListFilter()
containers, err := client.api.ContainerList(
bg,
types.ContainerListOptions{
container.ListOptions{
Filters: filter,
})
@ -207,7 +206,7 @@ func (client dockerClient) StopContainer(c t.Container, timeout time.Duration) e
} else {
log.Debugf("Removing container %s", shortID)
if err := client.api.ContainerRemove(bg, idStr, types.ContainerRemoveOptions{Force: true, RemoveVolumes: client.RemoveVolumes}); err != nil {
if err := client.api.ContainerRemove(bg, idStr, container.RemoveOptions{Force: true, RemoveVolumes: client.RemoveVolumes}); err != nil {
if sdkClient.IsErrNotFound(err) {
log.Debugf("Container %s not found, skipping removal.", shortID)
return nil
@ -304,7 +303,7 @@ func (client dockerClient) doStartContainer(bg context.Context, c t.Container, c
name := c.Name()
log.Debugf("Starting container %s (%s)", name, t.ContainerID(creation.ID).ShortID())
err := client.api.ContainerStart(bg, creation.ID, types.ContainerStartOptions{})
err := client.api.ContainerStart(bg, creation.ID, container.StartOptions{})
if err != nil {
return err
}
@ -399,7 +398,7 @@ func (client dockerClient) PullImage(ctx context.Context, container t.Container)
defer response.Close()
// the pull request will be aborted prematurely unless the response is read
if _, err = ioutil.ReadAll(response); err != nil {
if _, err = io.ReadAll(response); err != nil {
log.Error(err)
return err
}
@ -412,7 +411,7 @@ func (client dockerClient) RemoveImageByID(id t.ImageID) error {
items, err := client.api.ImageRemove(
context.Background(),
string(id),
types.ImageRemoveOptions{
image.RemoveOptions{
Force: true,
})
@ -445,7 +444,7 @@ func (client dockerClient) ExecuteCommand(containerID t.ContainerID, command str
clog := log.WithField("containerID", containerID)
// Create the exec
execConfig := types.ExecConfig{
execConfig := container.ExecOptions{
Tty: true,
Detach: false,
Cmd: []string{"sh", "-c", command},
@ -456,7 +455,7 @@ func (client dockerClient) ExecuteCommand(containerID t.ContainerID, command str
return false, err
}
response, attachErr := client.api.ContainerExecAttach(bg, exec.ID, types.ExecStartCheck{
response, attachErr := client.api.ContainerExecAttach(bg, exec.ID, container.ExecStartOptions{
Tty: true,
Detach: false,
})
@ -465,7 +464,7 @@ func (client dockerClient) ExecuteCommand(containerID t.ContainerID, command str
}
// Run the exec
execStartCheck := types.ExecStartCheck{Detach: false, Tty: true}
execStartCheck := container.ExecStartOptions{Detach: false, Tty: true}
err = client.api.ContainerExecStart(bg, exec.ID, execStartCheck)
if err != nil {
return false, err

View file

@ -1,13 +1,15 @@
package container
import (
"github.com/docker/docker/api/types/network"
"time"
"github.com/containrrr/watchtower/internal/util"
"github.com/containrrr/watchtower/pkg/container/mocks"
"github.com/containrrr/watchtower/pkg/filters"
t "github.com/containrrr/watchtower/pkg/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/nicholas-fedor/watchtower/internal/util"
"github.com/nicholas-fedor/watchtower/pkg/container/mocks"
"github.com/nicholas-fedor/watchtower/pkg/filters"
t "github.com/nicholas-fedor/watchtower/pkg/types"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
@ -70,7 +72,8 @@ var _ = Describe("the client", func() {
It("should gracefully fail with a useful message", func() {
c := dockerClient{}
pinnedContainer := MockContainer(WithImageName("sha256:fa5269854a5e615e51a72b17ad3fd1e01268f278a6684c8ed3c5f0cdce3f230b"))
c.PullImage(context.Background(), pinnedContainer)
err := c.PullImage(context.Background(), pinnedContainer)
Expect(err).To(MatchError(`container uses a pinned image, and cannot be updated by watchtower`))
})
})
})
@ -144,7 +147,7 @@ var _ = Describe("the client", func() {
mockServer.AppendHandlers(mocks.GetContainerHandlers(&mocks.Watchtower, &mocks.Running)...)
client := dockerClient{
api: docker,
ClientOptions: ClientOptions{PullImages: false},
ClientOptions: ClientOptions{},
}
containers, err := client.ListContainers(filters.NoFilter)
Expect(err).NotTo(HaveOccurred())
@ -158,7 +161,7 @@ var _ = Describe("the client", func() {
filter := filters.FilterByNames([]string{"lollercoaster"}, filters.NoFilter)
client := dockerClient{
api: docker,
ClientOptions: ClientOptions{PullImages: false},
ClientOptions: ClientOptions{},
}
containers, err := client.ListContainers(filter)
Expect(err).NotTo(HaveOccurred())
@ -171,11 +174,11 @@ var _ = Describe("the client", func() {
mockServer.AppendHandlers(mocks.GetContainerHandlers(&mocks.Watchtower, &mocks.Running)...)
client := dockerClient{
api: docker,
ClientOptions: ClientOptions{PullImages: false},
ClientOptions: ClientOptions{},
}
containers, err := client.ListContainers(filters.WatchtowerContainersFilter)
Expect(err).NotTo(HaveOccurred())
Expect(containers).To(ConsistOf(withContainerImageName(Equal("containrrr/watchtower:latest"))))
Expect(containers).To(ConsistOf(withContainerImageName(Equal("nickfedor/watchtower:latest"))))
})
})
When(`include stopped is enabled`, func() {
@ -184,7 +187,7 @@ var _ = Describe("the client", func() {
mockServer.AppendHandlers(mocks.GetContainerHandlers(&mocks.Stopped, &mocks.Watchtower, &mocks.Running)...)
client := dockerClient{
api: docker,
ClientOptions: ClientOptions{PullImages: false, IncludeStopped: true},
ClientOptions: ClientOptions{IncludeStopped: true},
}
containers, err := client.ListContainers(filters.NoFilter)
Expect(err).NotTo(HaveOccurred())
@ -197,7 +200,7 @@ var _ = Describe("the client", func() {
mockServer.AppendHandlers(mocks.GetContainerHandlers(&mocks.Watchtower, &mocks.Running, &mocks.Restarting)...)
client := dockerClient{
api: docker,
ClientOptions: ClientOptions{PullImages: false, IncludeRestarting: true},
ClientOptions: ClientOptions{IncludeRestarting: true},
}
containers, err := client.ListContainers(filters.NoFilter)
Expect(err).NotTo(HaveOccurred())
@ -210,7 +213,7 @@ var _ = Describe("the client", func() {
mockServer.AppendHandlers(mocks.GetContainerHandlers(&mocks.Watchtower, &mocks.Running)...)
client := dockerClient{
api: docker,
ClientOptions: ClientOptions{PullImages: false, IncludeRestarting: false},
ClientOptions: ClientOptions{IncludeRestarting: false},
}
containers, err := client.ListContainers(filters.NoFilter)
Expect(err).NotTo(HaveOccurred())
@ -224,7 +227,7 @@ var _ = Describe("the client", func() {
mockServer.AppendHandlers(mocks.GetContainerHandlers(&consumerContainerRef)...)
client := dockerClient{
api: docker,
ClientOptions: ClientOptions{PullImages: false},
ClientOptions: ClientOptions{},
}
container, err := client.GetContainer(consumerContainerRef.ContainerID())
Expect(err).NotTo(HaveOccurred())
@ -238,7 +241,7 @@ var _ = Describe("the client", func() {
mockServer.AppendHandlers(mocks.GetContainerHandlers(&consumerContainerRef)...)
client := dockerClient{
api: docker,
ClientOptions: ClientOptions{PullImages: false},
ClientOptions: ClientOptions{},
}
container, err := client.GetContainer(consumerContainerRef.ContainerID())
Expect(err).NotTo(HaveOccurred())
@ -253,7 +256,7 @@ var _ = Describe("the client", func() {
It("should include container id field", func() {
client := dockerClient{
api: docker,
ClientOptions: ClientOptions{PullImages: false},
ClientOptions: ClientOptions{},
}
// Capture logrus output in buffer
@ -269,7 +272,7 @@ var _ = Describe("the client", func() {
// API.ContainerExecCreate
ghttp.CombineHandlers(
ghttp.VerifyRequest("POST", HaveSuffix("containers/%v/exec", containerID)),
ghttp.VerifyJSONRepresenting(types.ExecConfig{
ghttp.VerifyJSONRepresenting(container.ExecOptions{
User: user,
Detach: false,
Tty: true,
@ -284,7 +287,7 @@ var _ = Describe("the client", func() {
// API.ContainerExecStart
ghttp.CombineHandlers(
ghttp.VerifyRequest("POST", HaveSuffix("exec/%v/start", execID)),
ghttp.VerifyJSONRepresenting(types.ExecStartCheck{
ghttp.VerifyJSONRepresenting(container.ExecStartOptions{
Detach: false,
Tty: true,
}),
@ -320,7 +323,7 @@ var _ = Describe("the client", func() {
It(`should omit the container ID alias`, func() {
client := dockerClient{
api: docker,
ClientOptions: ClientOptions{PullImages: false, IncludeRestarting: false},
ClientOptions: ClientOptions{IncludeRestarting: false},
}
container := MockContainer(WithImageName("docker.io/prefix/imagename:latest"))

View file

@ -7,8 +7,8 @@ import (
"strconv"
"strings"
"github.com/containrrr/watchtower/internal/util"
wt "github.com/containrrr/watchtower/pkg/types"
"github.com/nicholas-fedor/watchtower/internal/util"
wt "github.com/nicholas-fedor/watchtower/pkg/types"
"github.com/sirupsen/logrus"
"github.com/docker/docker/api/types"
@ -304,6 +304,29 @@ func (c Container) GetCreateConfig() *dockercontainer.Config {
}
}
// Clear HEALTHCHECK configuration (if default)
if config.Healthcheck != nil && imageConfig.Healthcheck != nil {
if util.SliceEqual(config.Healthcheck.Test, imageConfig.Healthcheck.Test) {
config.Healthcheck.Test = nil
}
if config.Healthcheck.Retries == imageConfig.Healthcheck.Retries {
config.Healthcheck.Retries = 0
}
if config.Healthcheck.Interval == imageConfig.Healthcheck.Interval {
config.Healthcheck.Interval = 0
}
if config.Healthcheck.Timeout == imageConfig.Healthcheck.Timeout {
config.Healthcheck.Timeout = 0
}
if config.Healthcheck.StartPeriod == imageConfig.Healthcheck.StartPeriod {
config.Healthcheck.StartPeriod = 0
}
}
config.Env = util.SliceSubtract(config.Env, imageConfig.Env)
config.Labels = util.StringMapSubtract(config.Labels, imageConfig.Labels)

View file

@ -21,7 +21,8 @@ func MockContainer(updates ...MockContainerUpdate) *Container {
},
}
image := types.ImageInspect{
ID: "image_id",
ID: "image_id",
Config: &dockerContainer.Config{},
}
for _, update := range updates {
@ -64,3 +65,15 @@ func WithContainerState(state types.ContainerState) MockContainerUpdate {
cnt.State = &state
}
}
func WithHealthcheck(healthConfig dockerContainer.HealthConfig) MockContainerUpdate {
return func(cnt *types.ContainerJSON, img *types.ImageInspect) {
cnt.Config.Healthcheck = &healthConfig
}
}
func WithImageHealthcheck(healthConfig dockerContainer.HealthConfig) MockContainerUpdate {
return func(cnt *types.ContainerJSON, img *types.ImageInspect) {
img.Config.Healthcheck = &healthConfig
}
}

View file

@ -1,7 +1,8 @@
package container
import (
"github.com/containrrr/watchtower/pkg/types"
"github.com/nicholas-fedor/watchtower/pkg/types"
dc "github.com/docker/docker/api/types/container"
"github.com/docker/go-connections/nat"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@ -67,6 +68,93 @@ var _ = Describe("the container", func() {
})
})
})
Describe("GetCreateConfig", func() {
When("container healthcheck config is equal to image config", func() {
It("should return empty healthcheck values", func() {
c := MockContainer(WithHealthcheck(dc.HealthConfig{
Test: []string{"/usr/bin/sleep", "1s"},
}), WithImageHealthcheck(dc.HealthConfig{
Test: []string{"/usr/bin/sleep", "1s"},
}))
Expect(c.GetCreateConfig().Healthcheck).To(Equal(&dc.HealthConfig{}))
c = MockContainer(WithHealthcheck(dc.HealthConfig{
Timeout: 30,
}), WithImageHealthcheck(dc.HealthConfig{
Timeout: 30,
}))
Expect(c.GetCreateConfig().Healthcheck).To(Equal(&dc.HealthConfig{}))
c = MockContainer(WithHealthcheck(dc.HealthConfig{
StartPeriod: 30,
}), WithImageHealthcheck(dc.HealthConfig{
StartPeriod: 30,
}))
Expect(c.GetCreateConfig().Healthcheck).To(Equal(&dc.HealthConfig{}))
c = MockContainer(WithHealthcheck(dc.HealthConfig{
Retries: 30,
}), WithImageHealthcheck(dc.HealthConfig{
Retries: 30,
}))
Expect(c.GetCreateConfig().Healthcheck).To(Equal(&dc.HealthConfig{}))
})
})
When("container healthcheck config is different to image config", func() {
It("should return the container healthcheck values", func() {
c := MockContainer(WithHealthcheck(dc.HealthConfig{
Test: []string{"/usr/bin/sleep", "1s"},
Interval: 30,
Timeout: 30,
StartPeriod: 10,
Retries: 2,
}), WithImageHealthcheck(dc.HealthConfig{
Test: []string{"/usr/bin/sleep", "10s"},
Interval: 10,
Timeout: 60,
StartPeriod: 30,
Retries: 10,
}))
Expect(c.GetCreateConfig().Healthcheck).To(Equal(&dc.HealthConfig{
Test: []string{"/usr/bin/sleep", "1s"},
Interval: 30,
Timeout: 30,
StartPeriod: 10,
Retries: 2,
}))
})
})
When("container healthcheck config is empty", func() {
It("should not panic", func() {
c := MockContainer(WithImageHealthcheck(dc.HealthConfig{
Test: []string{"/usr/bin/sleep", "10s"},
Interval: 10,
Timeout: 60,
StartPeriod: 30,
Retries: 10,
}))
Expect(c.GetCreateConfig().Healthcheck).To(BeNil())
})
})
When("container image healthcheck config is empty", func() {
It("should not panic", func() {
c := MockContainer(WithHealthcheck(dc.HealthConfig{
Test: []string{"/usr/bin/sleep", "1s"},
Interval: 30,
Timeout: 30,
StartPeriod: 10,
Retries: 2,
}))
Expect(c.GetCreateConfig().Healthcheck).To(Equal(&dc.HealthConfig{
Test: []string{"/usr/bin/sleep", "1s"},
Interval: 30,
Timeout: 30,
StartPeriod: 10,
Retries: 2,
}))
})
})
})
When("asked for metadata", func() {
var c *Container
BeforeEach(func() {

View file

@ -3,16 +3,18 @@ package mocks
import (
"encoding/json"
"fmt"
"github.com/onsi/ginkgo"
"net/http"
"net/url"
"os"
"path/filepath"
"strings"
t "github.com/containrrr/watchtower/pkg/types"
"github.com/onsi/ginkgo"
t "github.com/nicholas-fedor/watchtower/pkg/types"
"github.com/docker/docker/api/types"
i "github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/filters"
O "github.com/onsi/gomega"
"github.com/onsi/gomega/ghttp"
@ -262,12 +264,12 @@ func RemoveImageHandler(imagesWithParents map[string][]string) http.HandlerFunc
image := parts[len(parts)-1]
if parents, found := imagesWithParents[image]; found {
items := []types.ImageDeleteResponseItem{
items := []i.DeleteResponse{
{Untagged: image},
{Deleted: image},
}
for _, parent := range parents {
items = append(items, types.ImageDeleteResponseItem{Deleted: parent})
items = append(items, i.DeleteResponse{Deleted: parent})
}
ghttp.RespondWithJSONEncoded(http.StatusOK, items)(w, r)
} else {

View file

@ -4,7 +4,7 @@ import (
"fmt"
"os"
t "github.com/containrrr/watchtower/pkg/types"
t "github.com/nicholas-fedor/watchtower/pkg/types"
)
type imageRef struct {

View file

@ -30,9 +30,7 @@
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": [
"/var/run/docker.sock:/var/run/docker.sock"
],
"Binds": ["/var/run/docker.sock:/var/run/docker.sock"],
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
@ -67,10 +65,7 @@
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"ConsoleSize": [0, 0],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
@ -155,12 +150,10 @@
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": null,
"Image": "containrrr/watchtower:latest",
"Image": "nickfedor/watchtower:latest",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/watchtower"
],
"Entrypoint": ["/watchtower"],
"OnBuild": null,
"Labels": {
"com.centurylinklabs.watchtower": "true"

View file

@ -30,9 +30,7 @@
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": [
"/var/run/docker.sock:/var/run/docker.sock"
],
"Binds": ["/var/run/docker.sock:/var/run/docker.sock"],
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
@ -67,10 +65,7 @@
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"ConsoleSize": [0, 0],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
@ -155,12 +150,10 @@
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": null,
"Image": "containrrr/watchtower:latest",
"Image": "nickfedor/watchtower:latest",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/watchtower"
],
"Entrypoint": ["/watchtower"],
"OnBuild": null,
"Labels": {
"com.centurylinklabs.watchtower": "true"

View file

@ -30,9 +30,7 @@
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": [
"/var/run/docker.sock:/var/run/docker.sock"
],
"Binds": ["/var/run/docker.sock:/var/run/docker.sock"],
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
@ -67,10 +65,7 @@
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"ConsoleSize": [0, 0],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
@ -155,12 +150,10 @@
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": null,
"Image": "containrrr/watchtower:latest",
"Image": "nickfedor/watchtower:latest",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/watchtower"
],
"Entrypoint": ["/watchtower"],
"OnBuild": null,
"Labels": {
"com.centurylinklabs.watchtower": "true"

View file

@ -1,10 +1,8 @@
[
{
"Id": "ae8964ba86c7cd7522cf84e09781343d88e0e3543281c747d88b27e246578b65",
"Names": [
"/watchtower-stopped"
],
"Image": "containrrr/watchtower:latest",
"Names": ["/watchtower-stopped"],
"Image": "nickfedor/watchtower:latest",
"ImageID": "sha256:4dbc5f9c07028a985e14d1393e849ea07f68804c4293050d5a641b138db72daa",
"Command": "/watchtower",
"Created": 1554925882,
@ -49,10 +47,8 @@
},
{
"Id": "3d88e0e3543281c747d88b27e246578b65ae8964ba86c7cd7522cf84e0978134",
"Names": [
"/watchtower-running"
],
"Image": "containrrr/watchtower:latest",
"Names": ["/watchtower-running"],
"Image": "nickfedor/watchtower:latest",
"ImageID": "sha256:4dbc5f9c07028a985e14d1393e849ea07f68804c4293050d5a641b138db72daa",
"Command": "/watchtower",
"Created": 1554925882,
@ -97,9 +93,7 @@
},
{
"Id": "b978af0b858aa8855cce46b628817d4ed58e58f2c4f66c9b9c5449134ed4c008",
"Names": [
"/portainer"
],
"Names": ["/portainer"],
"Image": "portainer/portainer:latest",
"ImageID": "sha256:19d07168491a3f9e2798a9bed96544e34d57ddc4757a4ac5bb199dea896c87fd",
"Command": "/portainer",
@ -160,9 +154,7 @@
},
{
"Id": "ae8964ba86c7cd7522cf84e09781343d88e0e3543281c747d88b27e246578b67",
"Names": [
"/portainer"
],
"Names": ["/portainer"],
"Image": "portainer/portainer:latest",
"ImageID": "sha256:19d07168491a3f9e2798a9bed96544e34d57ddc4757a4ac5bb199dea896c87fd",
"Command": "/portainer",

View file

@ -1,8 +1,6 @@
{
"Id": "sha256:4dbc5f9c07028a985e14d1393e849ea07f68804c4293050d5a641b138db72daa",
"RepoTags": [
"containrrr/watchtower:latest"
],
"RepoTags": ["nickfedor/watchtower:latest"],
"RepoDigests": [],
"Parent": "sha256:2753b9621e0d76153e1725d0cea015baf0ae4d829782a463b4ea9532ec976447",
"Comment": "",
@ -21,18 +19,11 @@
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"ENTRYPOINT [\"/watchtower\"]"
],
"Cmd": ["/bin/sh", "-c", "#(nop) ", "ENTRYPOINT [\"/watchtower\"]"],
"Image": "sha256:2753b9621e0d76153e1725d0cea015baf0ae4d829782a463b4ea9532ec976447",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/watchtower"
],
"Entrypoint": ["/watchtower"],
"OnBuild": null,
"Labels": {
"com.centurylinklabs.watchtower": "true"
@ -57,9 +48,7 @@
"Image": "sha256:2753b9621e0d76153e1725d0cea015baf0ae4d829782a463b4ea9532ec976447",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/watchtower"
],
"Entrypoint": ["/watchtower"],
"OnBuild": null,
"Labels": {
"com.centurylinklabs.watchtower": "true"

View file

@ -1,7 +1,7 @@
package container_test
import (
wt "github.com/containrrr/watchtower/pkg/types"
wt "github.com/nicholas-fedor/watchtower/pkg/types"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

View file

@ -4,7 +4,7 @@ import (
"regexp"
"strings"
t "github.com/containrrr/watchtower/pkg/types"
t "github.com/nicholas-fedor/watchtower/pkg/types"
)
// WatchtowerContainersFilter filters only watchtower containers
@ -86,13 +86,14 @@ 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 {
containerScope, containerHasScope := c.Scope()
if !containerHasScope || containerScope == "" {
containerScope = "none"
}
if containerScope == scope {
return baseFilter(c)
}
@ -152,7 +153,13 @@ func BuildFilter(names []string, disableNames []string, enableLabel bool, scope
filter = FilterByEnableLabel(filter)
sb.WriteString("using enable label, ")
}
if scope != "" {
if scope == "none" {
// If a scope has explicitly defined as "none", containers should only be considered
// if they do not have a scope defined, or if it's explicitly set to "none".
filter = FilterByScope(scope, filter)
sb.WriteString(`without a scope, "`)
} else if scope != "" {
// If a scope has been defined, containers should only be considered
// if the scope is specifically set.
filter = FilterByScope(scope, filter)

View file

@ -3,7 +3,7 @@ package filters
import (
"testing"
"github.com/containrrr/watchtower/pkg/container/mocks"
"github.com/nicholas-fedor/watchtower/pkg/container/mocks"
"github.com/stretchr/testify/assert"
)
@ -111,6 +111,53 @@ func TestFilterByScope(t *testing.T) {
container.AssertExpectations(t)
}
func TestFilterByNoneScope(t *testing.T) {
scope := "none"
filter := FilterByScope(scope, NoFilter)
assert.NotNil(t, filter)
container := new(mocks.FilterableContainer)
container.On("Scope").Return("anyscope", true)
assert.False(t, filter(container))
container.AssertExpectations(t)
container = new(mocks.FilterableContainer)
container.On("Scope").Return("", false)
assert.True(t, filter(container))
container.AssertExpectations(t)
container = new(mocks.FilterableContainer)
container.On("Scope").Return("", true)
assert.True(t, filter(container))
container.AssertExpectations(t)
container = new(mocks.FilterableContainer)
container.On("Scope").Return("none", true)
assert.True(t, filter(container))
container.AssertExpectations(t)
}
func TestBuildFilterNoneScope(t *testing.T) {
filter, desc := BuildFilter(nil, nil, false, "none")
assert.Contains(t, desc, "without a scope")
scoped := new(mocks.FilterableContainer)
scoped.On("Enabled").Return(false, false)
scoped.On("Scope").Return("anyscope", true)
unscoped := new(mocks.FilterableContainer)
unscoped.On("Enabled").Return(false, false)
unscoped.On("Scope").Return("", false)
assert.False(t, filter(scoped))
assert.True(t, filter(unscoped))
scoped.AssertExpectations(t)
unscoped.AssertExpectations(t)
}
func TestFilterByDisabledLabel(t *testing.T) {
filter := FilterByDisabledLabel(NoFilter)
assert.NotNil(t, filter)

View file

@ -1,8 +1,8 @@
package lifecycle
import (
"github.com/containrrr/watchtower/pkg/container"
"github.com/containrrr/watchtower/pkg/types"
"github.com/nicholas-fedor/watchtower/pkg/container"
"github.com/nicholas-fedor/watchtower/pkg/types"
log "github.com/sirupsen/logrus"
)

View file

@ -1,7 +1,7 @@
package metrics
import (
"github.com/containrrr/watchtower/pkg/types"
"github.com/nicholas-fedor/watchtower/pkg/types"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)

View file

@ -6,7 +6,7 @@ import (
"github.com/spf13/cobra"
shoutrrrSmtp "github.com/containrrr/shoutrrr/pkg/services/smtp"
t "github.com/containrrr/watchtower/pkg/types"
t "github.com/nicholas-fedor/watchtower/pkg/types"
log "github.com/sirupsen/logrus"
)

View file

@ -5,7 +5,7 @@ import (
"strings"
shoutrrrGotify "github.com/containrrr/shoutrrr/pkg/services/gotify"
t "github.com/containrrr/watchtower/pkg/types"
t "github.com/nicholas-fedor/watchtower/pkg/types"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"

View file

@ -3,7 +3,7 @@ package notifications
import (
"encoding/json"
t "github.com/containrrr/watchtower/pkg/types"
t "github.com/nicholas-fedor/watchtower/pkg/types"
)
type jsonMap = map[string]interface{}

View file

@ -1,7 +1,7 @@
package notifications
import (
s "github.com/containrrr/watchtower/pkg/session"
s "github.com/nicholas-fedor/watchtower/pkg/session"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

View file

@ -1,7 +1,7 @@
package notifications
import (
t "github.com/containrrr/watchtower/pkg/types"
t "github.com/nicholas-fedor/watchtower/pkg/types"
log "github.com/sirupsen/logrus"
)

View file

@ -4,7 +4,7 @@ import (
"net/url"
shoutrrrTeams "github.com/containrrr/shoutrrr/pkg/services/teams"
t "github.com/containrrr/watchtower/pkg/types"
t "github.com/nicholas-fedor/watchtower/pkg/types"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

View file

@ -5,7 +5,7 @@ import (
"strings"
"time"
ty "github.com/containrrr/watchtower/pkg/types"
ty "github.com/nicholas-fedor/watchtower/pkg/types"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

View file

@ -5,9 +5,9 @@ import (
"net/url"
"time"
"github.com/containrrr/watchtower/cmd"
"github.com/containrrr/watchtower/internal/flags"
"github.com/containrrr/watchtower/pkg/notifications"
"github.com/nicholas-fedor/watchtower/cmd"
"github.com/nicholas-fedor/watchtower/internal/flags"
"github.com/nicholas-fedor/watchtower/pkg/notifications"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

View file

@ -7,7 +7,7 @@ import (
"strconv"
"time"
"github.com/containrrr/watchtower/pkg/types"
"github.com/nicholas-fedor/watchtower/pkg/types"
)
type previewData struct {

View file

@ -3,7 +3,7 @@ package data
import (
"sort"
"github.com/containrrr/watchtower/pkg/types"
"github.com/nicholas-fedor/watchtower/pkg/types"
)
// State is the outcome of a container in a session report

View file

@ -1,6 +1,6 @@
package data
import wt "github.com/containrrr/watchtower/pkg/types"
import wt "github.com/nicholas-fedor/watchtower/pkg/types"
type containerStatus struct {
containerID wt.ContainerID

View file

@ -5,8 +5,8 @@ import (
"strings"
"text/template"
"github.com/containrrr/watchtower/pkg/notifications/preview/data"
"github.com/containrrr/watchtower/pkg/notifications/templates"
"github.com/nicholas-fedor/watchtower/pkg/notifications/preview/data"
"github.com/nicholas-fedor/watchtower/pkg/notifications/templates"
)
func Render(input string, states []data.State, loglevels []data.LogLevel) (string, error) {
@ -15,7 +15,7 @@ func Render(input string, states []data.State, loglevels []data.LogLevel) (strin
tpl, err := template.New("").Funcs(templates.Funcs).Parse(input)
if err != nil {
return "", fmt.Errorf("failed to parse template: %e", err)
return "", fmt.Errorf("failed to parse %v", err)
}
for _, state := range states {
@ -29,7 +29,7 @@ func Render(input string, states []data.State, loglevels []data.LogLevel) (strin
var buf strings.Builder
err = tpl.Execute(&buf, data)
if err != nil {
return "", fmt.Errorf("failed to execute template: %e", err)
return "", fmt.Errorf("failed to execute template: %v", err)
}
return buf.String(), nil

View file

@ -10,8 +10,8 @@ import (
"github.com/containrrr/shoutrrr"
"github.com/containrrr/shoutrrr/pkg/types"
"github.com/containrrr/watchtower/pkg/notifications/templates"
t "github.com/containrrr/watchtower/pkg/types"
"github.com/nicholas-fedor/watchtower/pkg/notifications/templates"
t "github.com/nicholas-fedor/watchtower/pkg/types"
log "github.com/sirupsen/logrus"
)
@ -60,7 +60,7 @@ func (n *shoutrrrTypeNotifier) GetNames() []string {
return names
}
// GetNames returns a list of URLs for notification services that has been added
// GetURLs returns a list of URLs for notification services that has been added
func (n *shoutrrrTypeNotifier) GetURLs() []string {
return n.Urls
}
@ -73,7 +73,7 @@ func (n *shoutrrrTypeNotifier) AddLogHook() {
n.receiving = true
log.AddHook(n)
// Do the sending in a separate goroutine so we don't block the main process.
// Do the sending in a separate goroutine, so we don't block the main process.
go sendNotifications(n)
}

View file

@ -4,9 +4,9 @@ import (
"time"
"github.com/containrrr/shoutrrr/pkg/types"
"github.com/containrrr/watchtower/internal/actions/mocks"
"github.com/containrrr/watchtower/internal/flags"
s "github.com/containrrr/watchtower/pkg/session"
"github.com/nicholas-fedor/watchtower/internal/actions/mocks"
"github.com/nicholas-fedor/watchtower/internal/flags"
s "github.com/nicholas-fedor/watchtower/pkg/session"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"

View file

@ -5,7 +5,7 @@ import (
shoutrrrDisco "github.com/containrrr/shoutrrr/pkg/services/discord"
shoutrrrSlack "github.com/containrrr/shoutrrr/pkg/services/slack"
t "github.com/containrrr/watchtower/pkg/types"
t "github.com/nicholas-fedor/watchtower/pkg/types"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

View file

@ -9,9 +9,9 @@ import (
"net/url"
"strings"
"github.com/containrrr/watchtower/pkg/registry/helpers"
"github.com/containrrr/watchtower/pkg/types"
ref "github.com/docker/distribution/reference"
"github.com/nicholas-fedor/watchtower/pkg/registry/helpers"
"github.com/nicholas-fedor/watchtower/pkg/types"
ref "github.com/distribution/reference"
"github.com/sirupsen/logrus"
)

View file

@ -8,11 +8,11 @@ import (
"testing"
"time"
"github.com/containrrr/watchtower/internal/actions/mocks"
"github.com/containrrr/watchtower/pkg/registry/auth"
"github.com/nicholas-fedor/watchtower/internal/actions/mocks"
"github.com/nicholas-fedor/watchtower/pkg/registry/auth"
wtTypes "github.com/containrrr/watchtower/pkg/types"
ref "github.com/docker/distribution/reference"
ref "github.com/distribution/reference"
wtTypes "github.com/nicholas-fedor/watchtower/pkg/types"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
@ -45,7 +45,7 @@ var _ = Describe("the auth module", func() {
mockName := "mock-container"
mockImage := "ghcr.io/k6io/operator:latest"
mockCreated := time.Now()
mockDigest := "ghcr.io/k6io/operator@sha256:d68e1e532088964195ad3a0a71526bc2f11a78de0def85629beb75e2265f0547"
mockDigest := "ghcr.io/k6io/operator@sha256:d6d356ad6ec80e6765b99921babb8580ca0dee21c27abc3f0197c9441d83d680"
mockContainer := mocks.CreateMockContainerWithDigest(
mockId,
@ -68,13 +68,13 @@ var _ = Describe("the auth module", func() {
Describe("GetAuthURL", func() {
It("should create a valid auth url object based on the challenge header supplied", func() {
challenge := `bearer realm="https://ghcr.io/token",service="ghcr.io",scope="repository:user/image:pull"`
imageRef, err := ref.ParseNormalizedNamed("containrrr/watchtower")
imageRef, err := ref.ParseNormalizedNamed("nicholas-fedor/watchtower")
Expect(err).NotTo(HaveOccurred())
expected := &url.URL{
Host: "ghcr.io",
Scheme: "https",
Path: "/token",
RawQuery: "scope=repository%3Acontainrrr%2Fwatchtower%3Apull&service=ghcr.io",
RawQuery: "scope=repository%3Anicholas-fedor%2Fwatchtower%3Apull&service=ghcr.io",
}
URL, err := auth.GetAuthURL(challenge, imageRef)
@ -85,7 +85,7 @@ var _ = Describe("the auth module", func() {
When("given an invalid challenge header", func() {
It("should return an error", func() {
challenge := `bearer realm="https://ghcr.io/token"`
imageRef, err := ref.ParseNormalizedNamed("containrrr/watchtower")
imageRef, err := ref.ParseNormalizedNamed("nicholas-fedor/watchtower")
Expect(err).NotTo(HaveOccurred())
URL, err := auth.GetAuthURL(challenge, imageRef)
Expect(err).To(HaveOccurred())
@ -100,21 +100,17 @@ var _ = Describe("the auth module", func() {
Expect(getScopeFromImageAuthURL("index.docker.io/registry")).To(Equal("library/registry"))
})
It("should not include vanity hosts\"", func() {
Expect(getScopeFromImageAuthURL("docker.io/containrrr/watchtower")).To(Equal("containrrr/watchtower"))
Expect(getScopeFromImageAuthURL("index.docker.io/containrrr/watchtower")).To(Equal("containrrr/watchtower"))
})
It("should not destroy three segment image names\"", func() {
Expect(getScopeFromImageAuthURL("piksel/containrrr/watchtower")).To(Equal("piksel/containrrr/watchtower"))
Expect(getScopeFromImageAuthURL("ghcr.io/piksel/containrrr/watchtower")).To(Equal("piksel/containrrr/watchtower"))
})
It("should not prepend library/ to image names if they're not on dockerhub", func() {
Expect(getScopeFromImageAuthURL("ghcr.io/watchtower")).To(Equal("watchtower"))
Expect(getScopeFromImageAuthURL("ghcr.io/containrrr/watchtower")).To(Equal("containrrr/watchtower"))
Expect(getScopeFromImageAuthURL("docker.io/nickfedor/watchtower")).To(Equal("nickfedor/watchtower"))
Expect(getScopeFromImageAuthURL("index.docker.io/nickfedor/watchtower")).To(Equal("nickfedor/watchtower"))
})
// It("should not prepend library/ to image names if they're not on dockerhub", func() {
// Expect(getScopeFromImageAuthURL("ghcr.io/watchtower")).To(Equal("watchtower"))
// Expect(getScopeFromImageAuthURL("ghcr.io/nicholas-fedor/watchtower")).To(Equal("nicholas-fedor/watchtower"))
// })
})
It("should not crash when an empty field is received", func() {
input := `bearer realm="https://ghcr.io/token",service="ghcr.io",scope="repository:user/image:pull",`
imageRef, err := ref.ParseNormalizedNamed("containrrr/watchtower")
imageRef, err := ref.ParseNormalizedNamed("nicholas-fedor/watchtower")
Expect(err).NotTo(HaveOccurred())
res, err := auth.GetAuthURL(input, imageRef)
Expect(err).NotTo(HaveOccurred())
@ -122,7 +118,7 @@ var _ = Describe("the auth module", func() {
})
It("should not crash when a field without a value is received", func() {
input := `bearer realm="https://ghcr.io/token",service="ghcr.io",scope="repository:user/image:pull",valuelesskey`
imageRef, err := ref.ParseNormalizedNamed("containrrr/watchtower")
imageRef, err := ref.ParseNormalizedNamed("nicholas-fedor/watchtower")
Expect(err).NotTo(HaveOccurred())
res, err := auth.GetAuthURL(input, imageRef)
Expect(err).NotTo(HaveOccurred())
@ -133,17 +129,17 @@ var _ = Describe("the auth module", func() {
Describe("GetChallengeURL", func() {
It("should create a valid challenge url object based on the image ref supplied", func() {
expected := url.URL{Host: "ghcr.io", Scheme: "https", Path: "/v2/"}
imageRef, _ := ref.ParseNormalizedNamed("ghcr.io/containrrr/watchtower:latest")
imageRef, _ := ref.ParseNormalizedNamed("ghcr.io/nicholas-fedor/watchtower:latest")
Expect(auth.GetChallengeURL(imageRef)).To(Equal(expected))
})
It("should assume Docker Hub for image refs with no explicit registry", func() {
expected := url.URL{Host: "index.docker.io", Scheme: "https", Path: "/v2/"}
imageRef, _ := ref.ParseNormalizedNamed("containrrr/watchtower:latest")
imageRef, _ := ref.ParseNormalizedNamed("nickfedor/watchtower:latest")
Expect(auth.GetChallengeURL(imageRef)).To(Equal(expected))
})
It("should use index.docker.io if the image ref specifies docker.io", func() {
expected := url.URL{Host: "index.docker.io", Scheme: "https", Path: "/v2/"}
imageRef, _ := ref.ParseNormalizedNamed("docker.io/containrrr/watchtower:latest")
imageRef, _ := ref.ParseNormalizedNamed("docker.io/nickfedor/watchtower:latest")
Expect(auth.GetChallengeURL(imageRef)).To(Equal(expected))
})
})

View file

@ -11,10 +11,10 @@ import (
"strings"
"time"
"github.com/containrrr/watchtower/internal/meta"
"github.com/containrrr/watchtower/pkg/registry/auth"
"github.com/containrrr/watchtower/pkg/registry/manifest"
"github.com/containrrr/watchtower/pkg/types"
"github.com/nicholas-fedor/watchtower/internal/meta"
"github.com/nicholas-fedor/watchtower/pkg/registry/auth"
"github.com/nicholas-fedor/watchtower/pkg/registry/manifest"
"github.com/nicholas-fedor/watchtower/pkg/types"
"github.com/sirupsen/logrus"
)

View file

@ -2,9 +2,9 @@ package digest_test
import (
"fmt"
"github.com/containrrr/watchtower/internal/actions/mocks"
"github.com/containrrr/watchtower/pkg/registry/digest"
wtTypes "github.com/containrrr/watchtower/pkg/types"
"github.com/nicholas-fedor/watchtower/internal/actions/mocks"
"github.com/nicholas-fedor/watchtower/pkg/registry/digest"
wtTypes "github.com/nicholas-fedor/watchtower/pkg/types"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/ghttp"

View file

@ -1,7 +1,7 @@
package helpers
import (
"github.com/docker/distribution/reference"
"github.com/distribution/reference"
)
// domains for Docker Hub, the default registry

View file

@ -20,18 +20,18 @@ var _ = Describe("the helpers", func() {
})
It("should return index.docker.io for image refs with no explicit registry", func() {
Expect(GetRegistryAddress("watchtower")).To(Equal("index.docker.io"))
Expect(GetRegistryAddress("containrrr/watchtower")).To(Equal("index.docker.io"))
Expect(GetRegistryAddress("nickfedor/watchtower")).To(Equal("index.docker.io"))
})
It("should return index.docker.io for image refs with docker.io domain", func() {
Expect(GetRegistryAddress("docker.io/watchtower")).To(Equal("index.docker.io"))
Expect(GetRegistryAddress("docker.io/containrrr/watchtower")).To(Equal("index.docker.io"))
Expect(GetRegistryAddress("docker.io/nickfedor/watchtower")).To(Equal("index.docker.io"))
})
It("should return the host if passed an image name containing a local host", func() {
Expect(GetRegistryAddress("henk:80/watchtower")).To(Equal("henk:80"))
Expect(GetRegistryAddress("localhost/watchtower")).To(Equal("localhost"))
})
It("should return the server address if passed a fully qualified image name", func() {
Expect(GetRegistryAddress("github.com/containrrr/config")).To(Equal("github.com"))
Expect(GetRegistryAddress("github.com/nicholas-fedor/config")).To(Equal("github.com"))
})
})
})

View file

@ -5,9 +5,9 @@ import (
"fmt"
url2 "net/url"
"github.com/containrrr/watchtower/pkg/registry/helpers"
"github.com/containrrr/watchtower/pkg/types"
ref "github.com/docker/distribution/reference"
"github.com/nicholas-fedor/watchtower/pkg/registry/helpers"
"github.com/nicholas-fedor/watchtower/pkg/types"
ref "github.com/distribution/reference"
"github.com/sirupsen/logrus"
)

View file

@ -4,9 +4,9 @@ import (
"testing"
"time"
"github.com/containrrr/watchtower/internal/actions/mocks"
"github.com/containrrr/watchtower/pkg/registry/manifest"
apiTypes "github.com/docker/docker/api/types"
"github.com/nicholas-fedor/watchtower/internal/actions/mocks"
"github.com/nicholas-fedor/watchtower/pkg/registry/manifest"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
@ -19,24 +19,24 @@ func TestManifest(t *testing.T) {
var _ = Describe("the manifest module", func() {
Describe("BuildManifestURL", func() {
It("should return a valid url given a fully qualified image", func() {
imageRef := "ghcr.io/containrrr/watchtower:mytag"
expected := "https://ghcr.io/v2/containrrr/watchtower/manifests/mytag"
imageRef := "ghcr.io/nicholas-fedor/watchtower:mytag"
expected := "https://ghcr.io/v2/nicholas-fedor/watchtower/manifests/mytag"
URL, err := buildMockContainerManifestURL(imageRef)
Expect(err).NotTo(HaveOccurred())
Expect(URL).To(Equal(expected))
})
It("should assume Docker Hub for image refs with no explicit registry", func() {
imageRef := "containrrr/watchtower:latest"
expected := "https://index.docker.io/v2/containrrr/watchtower/manifests/latest"
imageRef := "nickfedor/watchtower:latest"
expected := "https://index.docker.io/v2/nickfedor/watchtower/manifests/latest"
URL, err := buildMockContainerManifestURL(imageRef)
Expect(err).NotTo(HaveOccurred())
Expect(URL).To(Equal(expected))
})
It("should assume latest for image refs with no explicit tag", func() {
imageRef := "containrrr/watchtower"
expected := "https://index.docker.io/v2/containrrr/watchtower/manifests/latest"
imageRef := "nickfedor/watchtower"
expected := "https://index.docker.io/v2/nickfedor/watchtower/manifests/latest"
URL, err := buildMockContainerManifestURL(imageRef)
Expect(err).NotTo(HaveOccurred())

View file

@ -1,29 +1,31 @@
package registry
import (
"github.com/containrrr/watchtower/pkg/registry/helpers"
watchtowerTypes "github.com/containrrr/watchtower/pkg/types"
ref "github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"context"
ref "github.com/distribution/reference"
"github.com/docker/docker/api/types/image"
"github.com/nicholas-fedor/watchtower/pkg/registry/helpers"
watchtowerTypes "github.com/nicholas-fedor/watchtower/pkg/types"
log "github.com/sirupsen/logrus"
)
// GetPullOptions creates a struct with all options needed for pulling images from a registry
func GetPullOptions(imageName string) (types.ImagePullOptions, error) {
func GetPullOptions(imageName string) (image.PullOptions, error) {
auth, err := EncodedAuth(imageName)
log.Debugf("Got image name: %s", imageName)
if err != nil {
return types.ImagePullOptions{}, err
return image.PullOptions{}, err
}
if auth == "" {
return types.ImagePullOptions{}, nil
return image.PullOptions{}, nil
}
// CREDENTIAL: Uncomment to log docker config auth
// log.Tracef("Got auth value: %s", auth)
return types.ImagePullOptions{
return image.PullOptions{
RegistryAuth: auth,
PrivilegeFunc: DefaultAuthHandler,
}, nil
@ -32,7 +34,7 @@ func GetPullOptions(imageName string) (types.ImagePullOptions, error) {
// 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) {
func DefaultAuthHandler(context.Context) (string, error) {
log.Debug("Authentication request was rejected. Trying again without authentication")
return "", nil
}

View file

@ -1,8 +1,8 @@
package registry_test
import (
"github.com/containrrr/watchtower/internal/actions/mocks"
unit "github.com/containrrr/watchtower/pkg/registry"
"github.com/nicholas-fedor/watchtower/internal/actions/mocks"
unit "github.com/nicholas-fedor/watchtower/pkg/registry"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@ -13,7 +13,7 @@ var _ = Describe("Registry", func() {
Describe("WarnOnAPIConsumption", func() {
When("Given a container with an image from ghcr.io", func() {
It("should want to warn", func() {
Expect(testContainerWithImage("ghcr.io/containrrr/watchtower")).To(BeTrue())
Expect(testContainerWithImage("ghcr.io/nicholas-fedor/watchtower")).To(BeTrue())
})
})
When("Given a container with an image implicitly from dockerhub", func() {

View file

@ -6,7 +6,7 @@ import (
"errors"
"os"
"github.com/containrrr/watchtower/pkg/registry/helpers"
"github.com/nicholas-fedor/watchtower/pkg/registry/helpers"
cliconfig "github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/config/credentials"

View file

@ -1,6 +1,6 @@
package session
import wt "github.com/containrrr/watchtower/pkg/types"
import wt "github.com/nicholas-fedor/watchtower/pkg/types"
// State indicates what the current state is of the container
type State int

View file

@ -1,7 +1,7 @@
package session
import (
"github.com/containrrr/watchtower/pkg/types"
"github.com/nicholas-fedor/watchtower/pkg/types"
)
// Progress contains the current session container status

View file

@ -3,7 +3,7 @@ package session
import (
"sort"
"github.com/containrrr/watchtower/pkg/types"
"github.com/nicholas-fedor/watchtower/pkg/types"
)
type report struct {

View file

@ -4,7 +4,7 @@ import (
"fmt"
"time"
"github.com/containrrr/watchtower/pkg/types"
"github.com/nicholas-fedor/watchtower/pkg/types"
)
// ByCreated allows a list of Container structs to be sorted by the container's