diff --git a/build.sh b/build.sh index 47d2b5c..304786d 100644 --- a/build.sh +++ b/build.sh @@ -2,4 +2,4 @@ VERSION=$(git describe --tags) echo "Building $VERSION..." -go build -o watchtower -ldflags "-X github.com/containrrr/watchtower/cmd.version=$VERSION" +go build -o watchtower -ldflags "-X github.com/containrrr/watchtower/internal/meta.Version=$VERSION" diff --git a/cmd/root.go b/cmd/root.go index e4c24b3..cf752ae 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,6 +1,7 @@ package cmd import ( + "github.com/containrrr/watchtower/internal/meta" "math" "os" "os/signal" @@ -39,7 +40,6 @@ var ( rollingRestart bool scope string // Set on build using ldflags - version = "v0.0.0-unknown" ) var rootCmd = NewRootCommand() @@ -273,7 +273,7 @@ func writeStartupMessage(c *cobra.Command, sched time.Time, filtering string) { notifs = "Using notifications: " + notifList } - log.Info("Watchtower ", version, "\n", notifs, "\n", filtering, "\n", schedMessage) + log.Info("Watchtower ", meta.Version, "\n", notifs, "\n", filtering, "\n", schedMessage) if log.IsLevelEnabled(log.TraceLevel) { log.Warn("trace level enabled: log will include sensitive information as credentials and tokens") } diff --git a/goreleaser.yml b/goreleaser.yml index 3f5e95d..1904d5e 100644 --- a/goreleaser.yml +++ b/goreleaser.yml @@ -10,7 +10,7 @@ build: - arm - arm64 ldflags: - - -s -w -X github.com/containrrr/watchtower/cmd.version={{.Version}} + - -s -w -X github.com/containrrr/watchtower/internal/meta.Version={{.Version}} archives: - name_template: "{{.ProjectName}}_{{.Os}}_{{.Arch}}" diff --git a/internal/meta/meta.go b/internal/meta/meta.go new file mode 100644 index 0000000..1571291 --- /dev/null +++ b/internal/meta/meta.go @@ -0,0 +1,13 @@ +package meta + +var ( + // Version is the compile-time set version of Watchtower + Version = "v0.0.0-unknown" + + // UserAgent is the http client identifier derived from Version + UserAgent string +) + +func init() { + UserAgent = "Watchtower/" + Version +} diff --git a/pkg/registry/digest/digest.go b/pkg/registry/digest/digest.go index 4634688..858bf33 100644 --- a/pkg/registry/digest/digest.go +++ b/pkg/registry/digest/digest.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "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" @@ -86,6 +87,7 @@ func GetDigest(url string, token string) (string, error) { client := &http.Client{Transport: tr} req, _ := http.NewRequest("HEAD", url, nil) + req.Header.Set("User-Agent", meta.UserAgent) if token != "" { logrus.WithField("token", token).Trace("Setting request token") diff --git a/pkg/registry/digest/digest_test.go b/pkg/registry/digest/digest_test.go index 0de6025..0321c1f 100644 --- a/pkg/registry/digest/digest_test.go +++ b/pkg/registry/digest/digest_test.go @@ -7,6 +7,8 @@ import ( wtTypes "github.com/containrrr/watchtower/pkg/types" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "github.com/onsi/gomega/ghttp" + "net/http" "os" "testing" "time" @@ -18,14 +20,16 @@ func TestDigest(t *testing.T) { RunSpecs(GinkgoT(), "Digest Suite") } -var DockerHubCredentials = &wtTypes.RegistryCredentials{ - Username: os.Getenv("CI_INTEGRATION_TEST_REGISTRY_DH_USERNAME"), - Password: os.Getenv("CI_INTEGRATION_TEST_REGISTRY_DH_PASSWORD"), -} -var GHCRCredentials = &wtTypes.RegistryCredentials{ - Username: os.Getenv("CI_INTEGRATION_TEST_REGISTRY_GH_USERNAME"), - Password: os.Getenv("CI_INTEGRATION_TEST_REGISTRY_GH_PASSWORD"), -} +var ( + DockerHubCredentials = &wtTypes.RegistryCredentials{ + Username: os.Getenv("CI_INTEGRATION_TEST_REGISTRY_DH_USERNAME"), + Password: os.Getenv("CI_INTEGRATION_TEST_REGISTRY_DH_PASSWORD"), + } + GHCRCredentials = &wtTypes.RegistryCredentials{ + Username: os.Getenv("CI_INTEGRATION_TEST_REGISTRY_GH_USERNAME"), + Password: os.Getenv("CI_INTEGRATION_TEST_REGISTRY_GH_PASSWORD"), + } +) func SkipIfCredentialsEmpty(credentials *wtTypes.RegistryCredentials, fn func()) func() { if credentials.Username == "" { @@ -84,4 +88,32 @@ var _ = Describe("Digests", func() { }), ) }) + When("sending a HEAD request", func() { + var server *ghttp.Server + BeforeEach(func() { + server = ghttp.NewServer() + }) + AfterEach(func() { + server.Close() + }) + It("should use a custom user-agent", func() { + server.AppendHandlers( + ghttp.CombineHandlers( + ghttp.VerifyHeader(http.Header{ + "User-Agent": []string{"Watchtower/v0.0.0-unknown"}, + }), + ghttp.RespondWith(http.StatusOK, "", http.Header{ + digest.ContentDigestHeader: []string{ + mockDigest, + }, + }), + ), + ) + dig, err := digest.GetDigest(server.URL(), "token") + println(dig) + Expect(server.ReceivedRequests()).Should(HaveLen(1)) + Expect(err).NotTo(HaveOccurred()) + Expect(dig).To(Equal(mockDigest)) + }) + }) })