From a94142b892b2ff759db9d41844161cda1d8e6819 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2024 07:47:29 +0000 Subject: [PATCH 1/2] Bump github.com/regclient/regclient from 0.7.2 to 0.8.0 Bumps [github.com/regclient/regclient](https://github.com/regclient/regclient) from 0.7.2 to 0.8.0. - [Release notes](https://github.com/regclient/regclient/releases) - [Changelog](https://github.com/regclient/regclient/blob/v0.8.0/release.md) - [Commits](https://github.com/regclient/regclient/compare/v0.7.2...v0.8.0) --- updated-dependencies: - dependency-name: github.com/regclient/regclient dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] # Conflicts: # go.mod --- go.mod | 2 +- go.sum | 4 +- .../regclient/regclient/.osv-scanner.toml | 2 +- .../regclient/regclient/.version-bump.lock | 44 ++-- .../github.com/regclient/regclient/Makefile | 8 +- vendor/github.com/regclient/regclient/blob.go | 56 ++--- .../regclient/regclient/config/host.go | 175 ++++++------- .../github.com/regclient/regclient/image.go | 233 +++++++++--------- .../regclient/regclient/internal/auth/auth.go | 59 ++--- .../regclient/internal/reghttp/http.go | 110 ++++----- .../regclient/internal/sloghandle/logrus.go | 126 ++++++++++ .../regclient/regclient/manifest.go | 9 +- .../regclient/regclient/referrer.go | 41 ++- .../regclient/regclient/regclient.go | 86 +++---- .../regclient/regclient/regclient_nowasm.go | 20 ++ .../github.com/regclient/regclient/release.md | 142 +++++------ .../regclient/regclient/scheme/ocidir/blob.go | 17 +- .../regclient/scheme/ocidir/close.go | 20 +- .../regclient/scheme/ocidir/manifest.go | 20 +- .../regclient/scheme/ocidir/ocidir.go | 19 +- .../regclient/scheme/ocidir/ocidir_nowasm.go | 20 ++ .../regclient/scheme/ocidir/referrer.go | 52 ++-- .../regclient/regclient/scheme/reg/blob.go | 79 +++--- .../regclient/scheme/reg/manifest.go | 18 +- .../regclient/scheme/reg/referrer.go | 88 ++----- .../regclient/regclient/scheme/reg/reg.go | 21 +- .../regclient/scheme/reg/reg_nowasm.go | 21 ++ .../regclient/regclient/scheme/reg/repo.go | 19 +- .../regclient/regclient/scheme/reg/tag.go | 46 ++-- .../regclient/regclient/scheme/scheme.go | 11 + .../regclient/regclient/types/ref/ref.go | 2 +- .../regclient/types/referrer/referrer.go | 18 +- .../regclient/regclient/types/slog.go | 8 + .../regclient/types/warning/warning.go | 31 ++- vendor/modules.txt | 3 +- 35 files changed, 873 insertions(+), 757 deletions(-) create mode 100644 vendor/github.com/regclient/regclient/internal/sloghandle/logrus.go create mode 100644 vendor/github.com/regclient/regclient/regclient_nowasm.go create mode 100644 vendor/github.com/regclient/regclient/scheme/ocidir/ocidir_nowasm.go create mode 100644 vendor/github.com/regclient/regclient/scheme/reg/reg_nowasm.go create mode 100644 vendor/github.com/regclient/regclient/types/slog.go diff --git a/go.mod b/go.mod index 6714a2658..9b39f4262 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/operator-framework/api v0.27.0 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.78.1 github.com/prometheus/client_golang v1.20.5 - github.com/regclient/regclient v0.7.2 + github.com/regclient/regclient v0.8.0 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.10.0 github.com/urfave/cli/v2 v2.27.5 diff --git a/go.sum b/go.sum index dd8b85822..10313f7bf 100644 --- a/go.sum +++ b/go.sum @@ -321,8 +321,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/regclient/regclient v0.7.2 h1:vcldDAwBMLtighYVMeb6qNt5+0hKg3AN2IkCc0JIJNM= -github.com/regclient/regclient v0.7.2/go.mod h1:QlA7W9/pvmbblOXM4d49JgfuOTwVXcUMKt3bFuOSVIQ= +github.com/regclient/regclient v0.8.0 h1:xNAMDlADcyMvFAlGXoqDOxlSUBG4mqWBFgjQqVTP8Og= +github.com/regclient/regclient v0.8.0/go.mod h1:h9+Y6dBvqBkdlrj6EIhbTOv0xUuIFl7CdI1bZvEB42g= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= diff --git a/vendor/github.com/regclient/regclient/.osv-scanner.toml b/vendor/github.com/regclient/regclient/.osv-scanner.toml index a4acf069a..b3d1f7a2d 100644 --- a/vendor/github.com/regclient/regclient/.osv-scanner.toml +++ b/vendor/github.com/regclient/regclient/.osv-scanner.toml @@ -1 +1 @@ -GoVersionOverride = "1.23.2" +GoVersionOverride = "1.23.4" diff --git a/vendor/github.com/regclient/regclient/.version-bump.lock b/vendor/github.com/regclient/regclient/.version-bump.lock index 625cd5436..d3276884f 100644 --- a/vendor/github.com/regclient/regclient/.version-bump.lock +++ b/vendor/github.com/regclient/regclient/.version-bump.lock @@ -1,52 +1,52 @@ -{"name":"docker-arg-alpine-digest","key":"docker.io/library/alpine:3.20.3","version":"sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d"} -{"name":"docker-arg-alpine-tag","key":"docker.io/library/alpine","version":"3.20.3"} -{"name":"docker-arg-ecr","key":"https://github.com/awslabs/amazon-ecr-credential-helper.git:main","version":"fb978450068958e4e5874e36a3cc2b69798132f9"} -{"name":"docker-arg-gcr","key":"https://github.com/GoogleCloudPlatform/docker-credential-gcr.git","version":"v2.1.25"} -{"name":"docker-arg-go-digest","key":"docker.io/library/golang:1.23.2-alpine","version":"sha256:9dd2625a1ff2859b8d8b01d8f7822c0f528942fe56cfe7a1e7c38d3b8d72d679"} -{"name":"docker-arg-go-tag","key":"docker.io/library/golang","version":"1.23.2"} +{"name":"docker-arg-alpine-digest","key":"docker.io/library/alpine:3.21.0","version":"sha256:21dc6063fd678b478f57c0e13f47560d0ea4eeba26dfc947b2a4f81f686b9f45"} +{"name":"docker-arg-alpine-tag","key":"docker.io/library/alpine","version":"3.21.0"} +{"name":"docker-arg-ecr","key":"https://github.com/awslabs/amazon-ecr-credential-helper.git:main","version":"b9e7404a33c30f6b0f4c3585b12aa5c33dc7f715"} +{"name":"docker-arg-gcr","key":"https://github.com/GoogleCloudPlatform/docker-credential-gcr.git","version":"v2.1.26"} +{"name":"docker-arg-go-digest","key":"docker.io/library/golang:1.23.4-alpine","version":"sha256:6c5c9590f169f77c8046e45c611d3b28fe477789acd8d3762d23d4744de69812"} +{"name":"docker-arg-go-tag","key":"docker.io/library/golang","version":"1.23.4"} {"name":"docker-arg-lunajson","key":"https://github.com/grafi-tt/lunajson.git:master","version":"3d10600874527d71519b33ecbb314eb93ccd1df6"} {"name":"docker-arg-semver","key":"https://github.com/kikito/semver.lua.git:master","version":"af495adc857d51fd1507a112be18523828a1da0d"} -{"name":"gha-alpine-digest","key":"docker.io/library/alpine:3.20.3","version":"sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d"} +{"name":"gha-alpine-digest","key":"docker.io/library/alpine:3.21.0","version":"sha256:21dc6063fd678b478f57c0e13f47560d0ea4eeba26dfc947b2a4f81f686b9f45"} {"name":"gha-alpine-tag-base","key":"docker.io/library/alpine","version":"3"} -{"name":"gha-alpine-tag-comment","key":"docker.io/library/alpine","version":"3.20.3"} +{"name":"gha-alpine-tag-comment","key":"docker.io/library/alpine","version":"3.21.0"} {"name":"gha-cosign-version","key":"https://github.com/sigstore/cosign.git","version":"v2.4.1"} {"name":"gha-golang-matrix","key":"golang-matrix","version":"[\"1.21\", \"1.22\", \"1.23\"]"} {"name":"gha-golang-release","key":"golang-latest","version":"1.23"} -{"name":"gha-syft-version","key":"docker.io/anchore/syft","version":"v1.15.0"} +{"name":"gha-syft-version","key":"docker.io/anchore/syft","version":"v1.17.0"} {"name":"gha-uses-commit","key":"https://github.com/actions/checkout.git:v4.2.2","version":"11bd71901bbe5b1630ceea73d27597364c9af683"} {"name":"gha-uses-commit","key":"https://github.com/actions/setup-go.git:v5.1.0","version":"41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed"} {"name":"gha-uses-commit","key":"https://github.com/actions/stale.git:v9.0.0","version":"28ca1036281a5e5922ead5184a1bbf96e5fc984e"} {"name":"gha-uses-commit","key":"https://github.com/actions/upload-artifact.git:v4.4.3","version":"b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882"} -{"name":"gha-uses-commit","key":"https://github.com/anchore/sbom-action.git:v0.17.6","version":"251a468eed47e5082b105c3ba6ee500c0e65a764"} -{"name":"gha-uses-commit","key":"https://github.com/docker/build-push-action.git:v6.9.0","version":"4f58ea79222b3b9dc2c8bbdd6debcef730109a75"} +{"name":"gha-uses-commit","key":"https://github.com/anchore/sbom-action.git:v0.17.8","version":"55dc4ee22412511ee8c3142cbea40418e6cec693"} +{"name":"gha-uses-commit","key":"https://github.com/docker/build-push-action.git:v6.10.0","version":"48aba3b46d1b1fec4febb7c5d0c644b249a11355"} {"name":"gha-uses-commit","key":"https://github.com/docker/login-action.git:v3.3.0","version":"9780b0c442fbb1117ed29e0efdff1e18412f7567"} {"name":"gha-uses-commit","key":"https://github.com/docker/setup-buildx-action.git:v3.7.1","version":"c47758b77c9736f4b2ef4073d4d51994fabfe349"} {"name":"gha-uses-commit","key":"https://github.com/regclient/actions.git:main","version":"ce5fd131e371ffcdd7508b478cb223b3511a9183"} {"name":"gha-uses-commit","key":"https://github.com/sigstore/cosign-installer.git:v3.7.0","version":"dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da"} -{"name":"gha-uses-commit","key":"https://github.com/softprops/action-gh-release.git:v2.0.9","version":"e7a8f85e1c67a31e6ed99a94b41bd0b71bbee6b8"} +{"name":"gha-uses-commit","key":"https://github.com/softprops/action-gh-release.git:v2.1.0","version":"01570a1f39cb168c169c802c3bceb9e93fb10974"} {"name":"gha-uses-semver","key":"https://github.com/actions/checkout.git","version":"v4.2.2"} {"name":"gha-uses-semver","key":"https://github.com/actions/setup-go.git","version":"v5.1.0"} {"name":"gha-uses-semver","key":"https://github.com/actions/stale.git","version":"v9.0.0"} {"name":"gha-uses-semver","key":"https://github.com/actions/upload-artifact.git","version":"v4.4.3"} -{"name":"gha-uses-semver","key":"https://github.com/anchore/sbom-action.git","version":"v0.17.6"} -{"name":"gha-uses-semver","key":"https://github.com/docker/build-push-action.git","version":"v6.9.0"} +{"name":"gha-uses-semver","key":"https://github.com/anchore/sbom-action.git","version":"v0.17.8"} +{"name":"gha-uses-semver","key":"https://github.com/docker/build-push-action.git","version":"v6.10.0"} {"name":"gha-uses-semver","key":"https://github.com/docker/login-action.git","version":"v3.3.0"} {"name":"gha-uses-semver","key":"https://github.com/docker/setup-buildx-action.git","version":"v3.7.1"} {"name":"gha-uses-semver","key":"https://github.com/sigstore/cosign-installer.git","version":"v3.7.0"} -{"name":"gha-uses-semver","key":"https://github.com/softprops/action-gh-release.git","version":"v2.0.9"} +{"name":"gha-uses-semver","key":"https://github.com/softprops/action-gh-release.git","version":"v2.1.0"} {"name":"go-mod-golang-release","key":"golang-oldest","version":"1.21"} {"name":"makefile-ci-distribution","key":"docker.io/library/registry","version":"2.8.3"} {"name":"makefile-ci-zot","key":"ghcr.io/project-zot/zot-linux-amd64","version":"v2.1.1"} {"name":"makefile-go-vulncheck","key":"https://go.googlesource.com/vuln.git","version":"v1.1.3"} {"name":"makefile-gomajor","key":"https://github.com/icholy/gomajor.git","version":"v0.14.0"} {"name":"makefile-gosec","key":"https://github.com/securego/gosec.git","version":"v2.21.4"} -{"name":"makefile-markdown-lint","key":"docker.io/davidanson/markdownlint-cli2","version":"v0.14.0"} +{"name":"makefile-markdown-lint","key":"docker.io/davidanson/markdownlint-cli2","version":"v0.15.0"} {"name":"makefile-osv-scanner","key":"https://github.com/google/osv-scanner.git","version":"v1.9.1"} {"name":"makefile-staticcheck","key":"https://github.com/dominikh/go-tools.git","version":"v0.5.1"} -{"name":"makefile-syft-container-digest","key":"anchore/syft:v1.15.0","version":"sha256:92b229ac1d84cd9627624a951e26a78333b26a5f34c9999629ba96e90751c971"} -{"name":"makefile-syft-container-tag","key":"anchore/syft","version":"v1.15.0"} -{"name":"makefile-syft-version","key":"docker.io/anchore/syft","version":"v1.15.0"} -{"name":"osv-golang-release","key":"docker.io/library/golang","version":"1.23.2"} -{"name":"shell-alpine-digest","key":"docker.io/library/alpine:3.20.3","version":"sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d"} +{"name":"makefile-syft-container-digest","key":"anchore/syft:v1.17.0","version":"sha256:f1099806495b4d2300adf03887bdfb69230c36a5e077061a12ee292bcd9bfd62"} +{"name":"makefile-syft-container-tag","key":"anchore/syft","version":"v1.17.0"} +{"name":"makefile-syft-version","key":"docker.io/anchore/syft","version":"v1.17.0"} +{"name":"osv-golang-release","key":"docker.io/library/golang","version":"1.23.4"} +{"name":"shell-alpine-digest","key":"docker.io/library/alpine:3.21.0","version":"sha256:21dc6063fd678b478f57c0e13f47560d0ea4eeba26dfc947b2a4f81f686b9f45"} {"name":"shell-alpine-tag-base","key":"docker.io/library/alpine","version":"3"} -{"name":"shell-alpine-tag-comment","key":"docker.io/library/alpine","version":"3.20.3"} +{"name":"shell-alpine-tag-comment","key":"docker.io/library/alpine","version":"3.21.0"} diff --git a/vendor/github.com/regclient/regclient/Makefile b/vendor/github.com/regclient/regclient/Makefile index 8d40b7394..2bb73230d 100644 --- a/vendor/github.com/regclient/regclient/Makefile +++ b/vendor/github.com/regclient/regclient/Makefile @@ -20,7 +20,7 @@ VCS_VERSION?=$(shell vcs_describe="$$(git describe --all)"; \ echo "$${vcs_version}" | sed -r 's#/+#-#g') VCS_TAG?=$(shell git describe --tags --abbrev=0 2>/dev/null || true) LD_FLAGS?=-s -w -extldflags -static -buildid= -X \"github.com/regclient/regclient/internal/version.vcsTag=$(VCS_TAG)\" -GO_BUILD_FLAGS?=-trimpath -ldflags "$(LD_FLAGS)" -tags nolegacy +GO_BUILD_FLAGS?=-trimpath -ldflags "$(LD_FLAGS)" DOCKERFILE_EXT?=$(shell if docker build --help 2>/dev/null | grep -q -- '--progress'; then echo ".buildkit"; fi) DOCKER_ARGS?=--build-arg "VCS_REF=$(VCS_REF)" --build-arg "VCS_VERSION=$(VCS_VERSION)" GOPATH?=$(shell go env GOPATH) @@ -33,15 +33,15 @@ ifeq "$(strip $(VER_BUMP))" '' -u "$(shell id -u):$(shell id -g)" \ $(VER_BUMP_CONTAINER) endif -MARKDOWN_LINT_VER?=v0.14.0 +MARKDOWN_LINT_VER?=v0.15.0 GOMAJOR_VER?=v0.14.0 GOSEC_VER?=v2.21.4 GO_VULNCHECK_VER?=v1.1.3 OSV_SCANNER_VER?=v1.9.1 SYFT?=$(shell command -v syft 2>/dev/null) SYFT_CMD_VER:=$(shell [ -x "$(SYFT)" ] && echo "v$$($(SYFT) version | awk '/^Version: / {print $$2}')" || echo "0") -SYFT_VERSION?=v1.15.0 -SYFT_CONTAINER?=anchore/syft:v1.15.0@sha256:92b229ac1d84cd9627624a951e26a78333b26a5f34c9999629ba96e90751c971 +SYFT_VERSION?=v1.17.0 +SYFT_CONTAINER?=anchore/syft:v1.17.0@sha256:f1099806495b4d2300adf03887bdfb69230c36a5e077061a12ee292bcd9bfd62 ifneq "$(SYFT_CMD_VER)" "$(SYFT_VERSION)" SYFT=docker run --rm \ -v "$(shell pwd)/:$(shell pwd)/" -w "$(shell pwd)" \ diff --git a/vendor/github.com/regclient/regclient/blob.go b/vendor/github.com/regclient/regclient/blob.go index 62f08acce..4bea46791 100644 --- a/vendor/github.com/regclient/regclient/blob.go +++ b/vendor/github.com/regclient/regclient/blob.go @@ -6,10 +6,9 @@ import ( "errors" "fmt" "io" + "log/slog" "time" - "github.com/sirupsen/logrus" - "github.com/regclient/regclient/internal/pqueue" "github.com/regclient/regclient/internal/reqmeta" "github.com/regclient/regclient/scheme" @@ -65,11 +64,10 @@ func (rc *RegClient) BlobCopy(ctx context.Context, refSrc ref.Ref, refTgt ref.Re if opt.callback != nil { opt.callback(types.CallbackBlob, d.Digest.String(), types.CallbackSkipped, 0, d.Size) } - rc.log.WithFields(logrus.Fields{ - "src": refTgt.Reference, - "tgt": refTgt.Reference, - "digest": d.Digest, - }).Debug("Blob copy skipped, same repo") + rc.slog.Debug("Blob copy skipped, same repo", + slog.String("src", refSrc.Reference), + slog.String("tgt", refTgt.Reference), + slog.String("digest", string(d.Digest))) return nil } // check if layer already exists @@ -77,10 +75,10 @@ func (rc *RegClient) BlobCopy(ctx context.Context, refSrc ref.Ref, refTgt ref.Re if opt.callback != nil { opt.callback(types.CallbackBlob, d.Digest.String(), types.CallbackSkipped, 0, d.Size) } - rc.log.WithFields(logrus.Fields{ - "tgt": refTgt.Reference, - "digest": d, - }).Debug("Blob copy skipped, already exists") + rc.slog.Debug("Blob copy skipped, already exists", + slog.String("src", refSrc.Reference), + slog.String("tgt", refTgt.Reference), + slog.String("digest", string(d.Digest))) return nil } // acquire throttle for both src and tgt to avoid deadlocks @@ -117,28 +115,25 @@ func (rc *RegClient) BlobCopy(ctx context.Context, refSrc ref.Ref, refTgt ref.Re if opt.callback != nil { opt.callback(types.CallbackBlob, d.Digest.String(), types.CallbackSkipped, 0, d.Size) } - rc.log.WithFields(logrus.Fields{ - "src": refTgt.Reference, - "tgt": refTgt.Reference, - "digest": d.Digest, - }).Debug("Blob copy performed server side with registry mount") + rc.slog.Debug("Blob copy performed server side with registry mount", + slog.String("src", refSrc.Reference), + slog.String("tgt", refTgt.Reference), + slog.String("digest", string(d.Digest))) return nil } - rc.log.WithFields(logrus.Fields{ - "err": err, - "src": refSrc.Reference, - "tgt": refTgt.Reference, - }).Warn("Failed to mount blob") + rc.slog.Warn("Failed to mount blob", + slog.String("src", refSrc.Reference), + slog.String("tgt", refTgt.Reference), + slog.String("err", err.Error())) } // fast options failed, download layer from source and push to target blobIO, err := rc.BlobGet(ctx, refSrc, d) if err != nil { if !errors.Is(err, context.Canceled) { - rc.log.WithFields(logrus.Fields{ - "err": err, - "src": refSrc.Reference, - "digest": d.Digest, - }).Warn("Failed to retrieve blob") + rc.slog.Warn("Failed to retrieve blob", + slog.String("src", refSrc.Reference), + slog.String("digest", string(d.Digest)), + slog.String("err", err.Error())) } return err } @@ -170,11 +165,10 @@ func (rc *RegClient) BlobCopy(ctx context.Context, refSrc ref.Ref, refTgt ref.Re defer blobIO.Close() if _, err := rc.BlobPut(ctx, refTgt, blobIO.GetDescriptor(), blobIO); err != nil { if !errors.Is(err, context.Canceled) { - rc.log.WithFields(logrus.Fields{ - "err": err, - "src": refSrc.Reference, - "tgt": refTgt.Reference, - }).Warn("Failed to push blob") + rc.slog.Warn("Failed to push blob", + slog.String("src", refSrc.Reference), + slog.String("tgt", refTgt.Reference), + slog.String("err", err.Error())) } return err } diff --git a/vendor/github.com/regclient/regclient/config/host.go b/vendor/github.com/regclient/regclient/config/host.go index 17d4e20e7..77ae57bf5 100644 --- a/vendor/github.com/regclient/regclient/config/host.go +++ b/vendor/github.com/regclient/regclient/config/host.go @@ -5,11 +5,10 @@ import ( "encoding/json" "fmt" "io" + "log/slog" "strings" "time" - "github.com/sirupsen/logrus" - "github.com/regclient/regclient/internal/timejson" ) @@ -267,13 +266,13 @@ func (host Host) IsZero() bool { } // Merge adds fields from a new config host entry. -func (host *Host) Merge(newHost Host, log *logrus.Logger) error { +func (host *Host) Merge(newHost Host, log *slog.Logger) error { name := newHost.Name if name == "" { name = host.Name } if log == nil { - log = &logrus.Logger{Out: io.Discard} + log = slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})) } // merge the existing and new config host @@ -296,62 +295,56 @@ func (host *Host) Merge(newHost Host, log *logrus.Logger) error { if newHost.User != "" { if host.User != "" && host.User != newHost.User { - log.WithFields(logrus.Fields{ - "orig": host.User, - "new": newHost.User, - "host": name, - }).Warn("Changing login user for registry") + log.Warn("Changing login user for registry", + slog.String("orig", host.User), + slog.String("new", newHost.User), + slog.String("host", name)) } host.User = newHost.User } if newHost.Pass != "" { if host.Pass != "" && host.Pass != newHost.Pass { - log.WithFields(logrus.Fields{ - "host": name, - }).Warn("Changing login password for registry") + log.Warn("Changing login password for registry", + slog.String("host", name)) } host.Pass = newHost.Pass } if newHost.Token != "" { if host.Token != "" && host.Token != newHost.Token { - log.WithFields(logrus.Fields{ - "host": name, - }).Warn("Changing login token for registry") + log.Warn("Changing login token for registry", + slog.String("host", name)) } host.Token = newHost.Token } if newHost.CredHelper != "" { if host.CredHelper != "" && host.CredHelper != newHost.CredHelper { - log.WithFields(logrus.Fields{ - "host": name, - "orig": host.CredHelper, - "new": newHost.CredHelper, - }).Warn("Changing credential helper for registry") + log.Warn("Changing credential helper for registry", + slog.String("host", name), + slog.String("orig", host.CredHelper), + slog.String("new", newHost.CredHelper)) } host.CredHelper = newHost.CredHelper } if newHost.CredExpire != 0 { if host.CredExpire != 0 && host.CredExpire != newHost.CredExpire { - log.WithFields(logrus.Fields{ - "host": name, - "orig": host.CredExpire, - "new": newHost.CredExpire, - }).Warn("Changing credential expire for registry") + log.Warn("Changing credential expire for registry", + slog.String("host", name), + slog.Any("orig", host.CredExpire), + slog.Any("new", newHost.CredExpire)) } host.CredExpire = newHost.CredExpire } if newHost.CredHost != "" { if host.CredHost != "" && host.CredHost != newHost.CredHost { - log.WithFields(logrus.Fields{ - "host": name, - "orig": host.CredHost, - "new": newHost.CredHost, - }).Warn("Changing credential host for registry") + log.Warn("Changing credential host for registry", + slog.String("host", name), + slog.String("orig", host.CredHost), + slog.String("new", newHost.CredHost)) } host.CredHost = newHost.CredHost } @@ -360,53 +353,48 @@ func (host *Host) Merge(newHost Host, log *logrus.Logger) error { if host.TLS != TLSUndefined && host.TLS != newHost.TLS { tlsOrig, _ := host.TLS.MarshalText() tlsNew, _ := newHost.TLS.MarshalText() - log.WithFields(logrus.Fields{ - "orig": string(tlsOrig), - "new": string(tlsNew), - "host": name, - }).Warn("Changing TLS settings for registry") + log.Warn("Changing TLS settings for registry", + slog.String("orig", string(tlsOrig)), + slog.String("new", string(tlsNew)), + slog.String("host", name)) } host.TLS = newHost.TLS } if newHost.RegCert != "" { if host.RegCert != "" && host.RegCert != newHost.RegCert { - log.WithFields(logrus.Fields{ - "orig": host.RegCert, - "new": newHost.RegCert, - "host": name, - }).Warn("Changing certificate settings for registry") + log.Warn("Changing certificate settings for registry", + slog.String("orig", host.RegCert), + slog.String("new", newHost.RegCert), + slog.String("host", name)) } host.RegCert = newHost.RegCert } if newHost.ClientCert != "" { if host.ClientCert != "" && host.ClientCert != newHost.ClientCert { - log.WithFields(logrus.Fields{ - "orig": host.ClientCert, - "new": newHost.ClientCert, - "host": name, - }).Warn("Changing client certificate settings for registry") + log.Warn("Changing client certificate settings for registry", + slog.String("orig", host.ClientCert), + slog.String("new", newHost.ClientCert), + slog.String("host", name)) } host.ClientCert = newHost.ClientCert } if newHost.ClientKey != "" { if host.ClientKey != "" && host.ClientKey != newHost.ClientKey { - log.WithFields(logrus.Fields{ - "host": name, - }).Warn("Changing client certificate key settings for registry") + log.Warn("Changing client certificate key settings for registry", + slog.String("host", name)) } host.ClientKey = newHost.ClientKey } if newHost.Hostname != "" { if host.Hostname != "" && host.Hostname != newHost.Hostname { - log.WithFields(logrus.Fields{ - "orig": host.Hostname, - "new": newHost.Hostname, - "host": name, - }).Warn("Changing hostname settings for registry") + log.Warn("Changing hostname settings for registry", + slog.String("orig", host.Hostname), + slog.String("new", newHost.Hostname), + slog.String("host", name)) } host.Hostname = newHost.Hostname } @@ -414,33 +402,30 @@ func (host *Host) Merge(newHost Host, log *logrus.Logger) error { if newHost.PathPrefix != "" { newHost.PathPrefix = strings.Trim(newHost.PathPrefix, "/") // leading and trailing / are not needed if host.PathPrefix != "" && host.PathPrefix != newHost.PathPrefix { - log.WithFields(logrus.Fields{ - "orig": host.PathPrefix, - "new": newHost.PathPrefix, - "host": name, - }).Warn("Changing path prefix settings for registry") + log.Warn("Changing path prefix settings for registry", + slog.String("orig", host.PathPrefix), + slog.String("new", newHost.PathPrefix), + slog.String("host", name)) } host.PathPrefix = newHost.PathPrefix } if len(newHost.Mirrors) > 0 { if len(host.Mirrors) > 0 && !stringSliceEq(host.Mirrors, newHost.Mirrors) { - log.WithFields(logrus.Fields{ - "orig": host.Mirrors, - "new": newHost.Mirrors, - "host": name, - }).Warn("Changing mirror settings for registry") + log.Warn("Changing mirror settings for registry", + slog.Any("orig", host.Mirrors), + slog.Any("new", newHost.Mirrors), + slog.String("host", name)) } host.Mirrors = newHost.Mirrors } if newHost.Priority != 0 { if host.Priority != 0 && host.Priority != newHost.Priority { - log.WithFields(logrus.Fields{ - "orig": host.Priority, - "new": newHost.Priority, - "host": name, - }).Warn("Changing priority settings for registry") + log.Warn("Changing priority settings for registry", + slog.Uint64("orig", uint64(host.Priority)), + slog.Uint64("new", uint64(newHost.Priority)), + slog.String("host", name)) } host.Priority = newHost.Priority } @@ -451,10 +436,9 @@ func (host *Host) Merge(newHost Host, log *logrus.Logger) error { // TODO: eventually delete if newHost.API != "" { - log.WithFields(logrus.Fields{ - "api": newHost.API, - "host": name, - }).Warn("API field has been deprecated") + log.Warn("API field has been deprecated", + slog.String("api", newHost.API), + slog.String("host", name)) } if len(newHost.APIOpts) > 0 { @@ -462,12 +446,11 @@ func (host *Host) Merge(newHost Host, log *logrus.Logger) error { merged := copyMapString(host.APIOpts) for k, v := range newHost.APIOpts { if host.APIOpts[k] != "" && host.APIOpts[k] != v { - log.WithFields(logrus.Fields{ - "orig": host.APIOpts[k], - "new": newHost.APIOpts[k], - "opt": k, - "host": name, - }).Warn("Changing APIOpts setting for registry") + log.Warn("Changing APIOpts setting for registry", + slog.String("orig", host.APIOpts[k]), + slog.String("new", newHost.APIOpts[k]), + slog.String("opt", k), + slog.String("host", name)) } merged[k] = v } @@ -479,44 +462,40 @@ func (host *Host) Merge(newHost Host, log *logrus.Logger) error { if newHost.BlobChunk > 0 { if host.BlobChunk != 0 && host.BlobChunk != newHost.BlobChunk { - log.WithFields(logrus.Fields{ - "orig": host.BlobChunk, - "new": newHost.BlobChunk, - "host": name, - }).Warn("Changing blobChunk settings for registry") + log.Warn("Changing blobChunk settings for registry", + slog.Int64("orig", host.BlobChunk), + slog.Int64("new", newHost.BlobChunk), + slog.String("host", name)) } host.BlobChunk = newHost.BlobChunk } if newHost.BlobMax != 0 { if host.BlobMax != 0 && host.BlobMax != newHost.BlobMax { - log.WithFields(logrus.Fields{ - "orig": host.BlobMax, - "new": newHost.BlobMax, - "host": name, - }).Warn("Changing blobMax settings for registry") + log.Warn("Changing blobMax settings for registry", + slog.Int64("orig", host.BlobMax), + slog.Int64("new", newHost.BlobMax), + slog.String("host", name)) } host.BlobMax = newHost.BlobMax } if newHost.ReqPerSec != 0 { if host.ReqPerSec != 0 && host.ReqPerSec != newHost.ReqPerSec { - log.WithFields(logrus.Fields{ - "orig": host.ReqPerSec, - "new": newHost.ReqPerSec, - "host": name, - }).Warn("Changing reqPerSec settings for registry") + log.Warn("Changing reqPerSec settings for registry", + slog.Float64("orig", host.ReqPerSec), + slog.Float64("new", newHost.ReqPerSec), + slog.String("host", name)) } host.ReqPerSec = newHost.ReqPerSec } if newHost.ReqConcurrent > 0 { if host.ReqConcurrent != 0 && host.ReqConcurrent != newHost.ReqConcurrent { - log.WithFields(logrus.Fields{ - "orig": host.ReqConcurrent, - "new": newHost.ReqConcurrent, - "host": name, - }).Warn("Changing reqPerSec settings for registry") + log.Warn("Changing reqPerSec settings for registry", + slog.Int64("orig", host.ReqConcurrent), + slog.Int64("new", newHost.ReqConcurrent), + slog.String("host", name)) } host.ReqConcurrent = newHost.ReqConcurrent } diff --git a/vendor/github.com/regclient/regclient/image.go b/vendor/github.com/regclient/regclient/image.go index b6698d870..9f2cf88bd 100644 --- a/vendor/github.com/regclient/regclient/image.go +++ b/vendor/github.com/regclient/regclient/image.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "io" + "log/slog" "net/url" "path/filepath" "strings" @@ -19,7 +20,6 @@ import ( _ "crypto/sha512" digest "github.com/opencontainers/go-digest" - "github.com/sirupsen/logrus" "github.com/regclient/regclient/pkg/archive" "github.com/regclient/regclient/scheme" @@ -96,6 +96,8 @@ type imageOpt struct { platform string platforms []string referrerConfs []scheme.ReferrerConfig + referrerSrc ref.Ref + referrerTgt ref.Ref tagList []string mu sync.Mutex seen map[string]*imageSeen @@ -225,6 +227,20 @@ func ImageWithReferrers(rOpts ...scheme.ReferrerOpts) ImageOpts { } } +// ImageWithReferrerSrc specifies an alternate repository to pull referrers from. +func ImageWithReferrerSrc(src ref.Ref) ImageOpts { + return func(opts *imageOpt) { + opts.referrerSrc = src + } +} + +// ImageWithReferrerTgt specifies an alternate repository to pull referrers from. +func ImageWithReferrerTgt(tgt ref.Ref) ImageOpts { + return func(opts *imageOpt) { + opts.referrerTgt = tgt + } +} + // ImageCheckBase returns nil if the base image is unchanged. // A base image mismatch returns an error that wraps errs.ErrMismatch. func (rc *RegClient) ImageCheckBase(ctx context.Context, r ref.Ref, opts ...ImageOpts) error { @@ -279,17 +295,15 @@ func (rc *RegClient) ImageCheckBase(ctx context.Context, r ref.Ref, opts ...Imag return err } if baseMH.GetDescriptor().Digest == expectDig { - rc.log.WithFields(logrus.Fields{ - "name": baseR.CommonName(), - "digest": baseMH.GetDescriptor().Digest.String(), - }).Debug("base image digest matches") + rc.slog.Debug("base image digest matches", + slog.String("name", baseR.CommonName()), + slog.String("digest", baseMH.GetDescriptor().Digest.String())) return nil } else { - rc.log.WithFields(logrus.Fields{ - "name": baseR.CommonName(), - "digest": baseMH.GetDescriptor().Digest.String(), - "expected": expectDig.String(), - }).Debug("base image digest changed") + rc.slog.Debug("base image digest changed", + slog.String("name", baseR.CommonName()), + slog.String("digest", baseMH.GetDescriptor().Digest.String()), + slog.String("expected", expectDig.String())) return fmt.Errorf("base digest changed, %s, expected %s, received %s%.0w", baseR.CommonName(), expectDig.String(), baseMH.GetDescriptor().Digest.String(), errs.ErrMismatch) } @@ -383,11 +397,10 @@ func (rc *RegClient) ImageCheckBase(ctx context.Context, r ref.Ref, opts ...Imag return fmt.Errorf("image has fewer layers than base image") } if !layers[i].Same(baseLayers[i]) { - rc.log.WithFields(logrus.Fields{ - "layer": i, - "expected": layers[i].Digest.String(), - "digest": baseLayers[i].Digest.String(), - }).Debug("image layer changed") + rc.slog.Debug("image layer changed", + slog.Int("layer", i), + slog.String("expected", layers[i].Digest.String()), + slog.String("digest", baseLayers[i].Digest.String())) return fmt.Errorf("base layer changed, %s[%d], expected %s, received %s%.0w", baseR.CommonName(), i, layers[i].Digest.String(), baseLayers[i].Digest.String(), errs.ErrMismatch) } @@ -425,19 +438,17 @@ func (rc *RegClient) ImageCheckBase(ctx context.Context, r ref.Ref, opts ...Imag !baseConfOCI.History[i].Created.Equal(*confOCI.History[i].Created) || baseConfOCI.History[i].CreatedBy != confOCI.History[i].CreatedBy || baseConfOCI.History[i].EmptyLayer != confOCI.History[i].EmptyLayer { - rc.log.WithFields(logrus.Fields{ - "index": i, - "expected": confOCI.History[i], - "history": baseConfOCI.History[i], - }).Debug("image history changed") + rc.slog.Debug("image history changed", + slog.Int("index", i), + slog.Any("expected", confOCI.History[i]), + slog.Any("history", baseConfOCI.History[i])) return fmt.Errorf("base history changed, %s[%d], expected %v, received %v%.0w", baseR.CommonName(), i, confOCI.History[i], baseConfOCI.History[i], errs.ErrMismatch) } } - rc.log.WithFields(logrus.Fields{ - "base": baseR.CommonName(), - }).Debug("base image layers and history matches") + rc.slog.Debug("base image layers and history matches", + slog.String("base", baseR.CommonName())) return nil } @@ -539,6 +550,7 @@ func (rc *RegClient) ImageCopy(ctx context.Context, refSrc ref.Ref, refTgt ref.R func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt ref.Ref, d descriptor.Descriptor, child bool, parents []digest.Digest, opt *imageOpt) (err error) { var mSrc, mTgt manifest.Manifest var sDig digest.Digest + refTgtRepo := refTgt.SetTag("").CommonName() seenCB := func(error) {} defer func() { if seenCB != nil { @@ -552,7 +564,7 @@ func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt re sDig = digest.Digest(refSrc.Digest) } if sDig != "" { - if seenCB, err = imageSeenOrWait(ctx, opt, refTgt.Tag, sDig, parents); seenCB == nil { + if seenCB, err = imageSeenOrWait(ctx, opt, refTgtRepo, refTgt.Tag, sDig, parents); seenCB == nil { return err } } @@ -570,7 +582,7 @@ func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt re return fmt.Errorf("copy failed, error getting source: %w", err) } sDig = mSrc.GetDescriptor().Digest - if seenCB, err = imageSeenOrWait(ctx, opt, refTgt.Tag, sDig, parents); seenCB == nil { + if seenCB, err = imageSeenOrWait(ctx, opt, refTgtRepo, refTgt.Tag, sDig, parents); seenCB == nil { return err } } @@ -588,7 +600,7 @@ func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt re return fmt.Errorf("copy failed, error getting source: %w", err) } sDig = mSrc.GetDescriptor().Digest - if seenCB, err = imageSeenOrWait(ctx, opt, refTgt.Tag, sDig, parents); seenCB == nil { + if seenCB, err = imageSeenOrWait(ctx, opt, refTgtRepo, refTgt.Tag, sDig, parents); seenCB == nil { return err } } @@ -600,7 +612,7 @@ func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt re } if sDig == "" { sDig = mSrc.GetDescriptor().Digest - if seenCB, err = imageSeenOrWait(ctx, opt, refTgt.Tag, sDig, parents); seenCB == nil { + if seenCB, err = imageSeenOrWait(ctx, opt, refTgtRepo, refTgt.Tag, sDig, parents); seenCB == nil { return err } } @@ -639,9 +651,8 @@ func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt re return err } if !match { - rc.log.WithFields(logrus.Fields{ - "platform": dEntry.Platform, - }).Debug("Platform excluded from copy") + rc.slog.Debug("Platform excluded from copy", + slog.Any("platform", dEntry.Platform)) continue } } @@ -649,10 +660,9 @@ func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt re waitCount++ go func() { var err error - rc.log.WithFields(logrus.Fields{ - "platform": dEntry.Platform, - "digest": dEntry.Digest.String(), - }).Debug("Copy platform") + rc.slog.Debug("Copy platform", + slog.Any("platform", dEntry.Platform), + slog.String("digest", dEntry.Digest.String())) entrySrc := refSrc.SetDigest(dEntry.Digest.String()) entryTgt := refTgt.SetDigest(dEntry.Digest.String()) switch dEntry.MediaType { @@ -687,28 +697,25 @@ func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt re if err != nil { // docker schema v1 does not have a config object, ignore if it's missing if !errors.Is(err, errs.ErrUnsupportedMediaType) { - rc.log.WithFields(logrus.Fields{ - "ref": refSrc.Reference, - "err": err, - }).Warn("Failed to get config digest from manifest") + rc.slog.Warn("Failed to get config digest from manifest", + slog.String("ref", refSrc.Reference), + slog.String("err", err.Error())) return fmt.Errorf("failed to get config digest for %s: %w", refSrc.CommonName(), err) } } else { waitCount++ go func() { - rc.log.WithFields(logrus.Fields{ - "source": refSrc.Reference, - "target": refTgt.Reference, - "digest": cd.Digest.String(), - }).Info("Copy config") + rc.slog.Info("Copy config", + slog.String("source", refSrc.Reference), + slog.String("target", refTgt.Reference), + slog.String("digest", cd.Digest.String())) err := rc.imageCopyBlob(ctx, refSrc, refTgt, cd, opt, bOpt...) if err != nil && !errors.Is(err, context.Canceled) { - rc.log.WithFields(logrus.Fields{ - "source": refSrc.Reference, - "target": refTgt.Reference, - "digest": cd.Digest.String(), - "err": err, - }).Warn("Failed to copy config") + rc.slog.Warn("Failed to copy config", + slog.String("source", refSrc.Reference), + slog.String("target", refTgt.Reference), + slog.String("digest", cd.Digest.String()), + slog.String("err", err.Error())) } waitCh <- err }() @@ -722,30 +729,27 @@ func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt re for _, layerSrc := range l { if len(layerSrc.URLs) > 0 && !opt.includeExternal { // skip blobs where the URLs are defined, these aren't hosted and won't be pulled from the source - rc.log.WithFields(logrus.Fields{ - "source": refSrc.Reference, - "target": refTgt.Reference, - "layer": layerSrc.Digest.String(), - "external-urls": layerSrc.URLs, - }).Debug("Skipping external layer") + rc.slog.Debug("Skipping external layer", + slog.String("source", refSrc.Reference), + slog.String("target", refTgt.Reference), + slog.String("layer", layerSrc.Digest.String()), + slog.Any("external-urls", layerSrc.URLs)) continue } waitCount++ layerSrc := layerSrc go func() { - rc.log.WithFields(logrus.Fields{ - "source": refSrc.Reference, - "target": refTgt.Reference, - "layer": layerSrc.Digest.String(), - }).Info("Copy layer") + rc.slog.Info("Copy layer", + slog.String("source", refSrc.Reference), + slog.String("target", refTgt.Reference), + slog.String("layer", layerSrc.Digest.String())) err := rc.imageCopyBlob(ctx, refSrc, refTgt, layerSrc, opt, bOpt...) if err != nil && !errors.Is(err, context.Canceled) { - rc.log.WithFields(logrus.Fields{ - "source": refSrc.Reference, - "target": refTgt.Reference, - "layer": layerSrc.Digest.String(), - "err": err, - }).Warn("Failed to copy layer") + rc.slog.Warn("Failed to copy layer", + slog.String("source", refSrc.Reference), + slog.String("target", refTgt.Reference), + slog.String("layer", layerSrc.Digest.String()), + slog.String("err", err.Error())) } waitCh <- err }() @@ -778,21 +782,36 @@ func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt re } } if err != nil { - rc.log.WithFields(logrus.Fields{ - "err": err, - "sDig": sDig, - }).Debug("child manifest copy failed") + rc.slog.Debug("child manifest copy failed", + slog.String("err", err.Error()), + slog.String("sDig", sDig.String())) return err } // copy referrers referrerTags := []string{} if opt.referrerConfs != nil { - rl, err := rc.ReferrerList(ctx, refSrc) + referrerOpts := []scheme.ReferrerOpts{} + rSubject := refSrc + referrerSrc := refSrc + referrerTgt := refTgt + if opt.referrerSrc.IsSet() { + referrerOpts = append(referrerOpts, scheme.WithReferrerSource(opt.referrerSrc)) + referrerSrc = opt.referrerSrc + } + if opt.referrerTgt.IsSet() { + referrerTgt = opt.referrerTgt + } + if sDig != "" { + rSubject = rSubject.SetDigest(sDig.String()) + } + rl, err := rc.ReferrerList(ctx, rSubject, referrerOpts...) if err != nil { return err } - referrerTags = append(referrerTags, rl.Tags...) + if !rl.Source.IsSet() || ref.EqualRepository(refSrc, rl.Source) { + referrerTags = append(referrerTags, rl.Tags...) + } descList := []descriptor.Descriptor{} if len(opt.referrerConfs) == 0 { descList = rl.Descriptors @@ -809,8 +828,8 @@ func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt re if seen != nil { continue // skip referrers that have been seen } - referrerSrc := refSrc.SetDigest(rDesc.Digest.String()) - referrerTgt := refTgt.SetDigest(rDesc.Digest.String()) + referrerSrc := referrerSrc.SetDigest(rDesc.Digest.String()) + referrerTgt := referrerTgt.SetDigest(rDesc.Digest.String()) rDesc := rDesc waitCount++ go func() { @@ -825,11 +844,10 @@ func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt re waitCh <- nil } else { if err != nil && !errors.Is(err, context.Canceled) { - rc.log.WithFields(logrus.Fields{ - "digest": rDesc.Digest.String(), - "src": referrerSrc.CommonName(), - "tgt": referrerTgt.CommonName(), - }).Warn("Failed to copy referrer") + rc.slog.Warn("Failed to copy referrer", + slog.String("digest", rDesc.Digest.String()), + slog.String("src", referrerSrc.CommonName()), + slog.String("tgt", referrerTgt.CommonName())) } waitCh <- err } @@ -845,19 +863,17 @@ func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt re tl, err := rc.TagList(ctx, refSrc) if err != nil { opt.mu.Unlock() - rc.log.WithFields(logrus.Fields{ - "source": refSrc.Reference, - "err": err, - }).Warn("Failed to list tags for digest-tag copy") + rc.slog.Warn("Failed to list tags for digest-tag copy", + slog.String("source", refSrc.Reference), + slog.String("err", err.Error())) return err } tags, err := tl.GetTags() if err != nil { opt.mu.Unlock() - rc.log.WithFields(logrus.Fields{ - "source": refSrc.Reference, - "err": err, - }).Warn("Failed to list tags for digest-tag copy") + rc.slog.Warn("Failed to list tags for digest-tag copy", + slog.String("source", refSrc.Reference), + slog.String("err", err.Error())) return err } if tags == nil { @@ -896,11 +912,10 @@ func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt re waitCh <- nil } else { if err != nil && !errors.Is(err, context.Canceled) { - rc.log.WithFields(logrus.Fields{ - "tag": tag, - "src": refTagSrc.CommonName(), - "tgt": refTagTgt.CommonName(), - }).Warn("Failed to copy digest-tag") + rc.slog.Warn("Failed to copy digest-tag", + slog.String("tag", tag), + slog.String("src", refTagSrc.CommonName()), + slog.String("tgt", refTagTgt.CommonName())) } waitCh <- err } @@ -936,10 +951,9 @@ func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt re err = rc.ManifestPut(ctx, refTgt, mSrc, mOpts...) if err != nil { if !errors.Is(err, context.Canceled) { - rc.log.WithFields(logrus.Fields{ - "target": refTgt.Reference, - "err": err, - }).Warn("Failed to push manifest") + rc.slog.Warn("Failed to push manifest", + slog.String("target", refTgt.Reference), + slog.String("err", err.Error())) } return err } @@ -960,7 +974,7 @@ func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt re } func (rc *RegClient) imageCopyBlob(ctx context.Context, refSrc ref.Ref, refTgt ref.Ref, d descriptor.Descriptor, opt *imageOpt, bOpt ...BlobOpts) error { - seenCB, err := imageSeenOrWait(ctx, opt, "", d.Digest, []digest.Digest{}) + seenCB, err := imageSeenOrWait(ctx, opt, refTgt.SetTag("").CommonName(), "", d.Digest, []digest.Digest{}) if seenCB == nil { return err } @@ -971,9 +985,9 @@ func (rc *RegClient) imageCopyBlob(ctx context.Context, refSrc ref.Ref, refTgt r // imageSeenOrWait returns either a callback to report the error when the digest hasn't been seen before // or it will wait for the previous copy to run and return the error from that copy -func imageSeenOrWait(ctx context.Context, opt *imageOpt, tag string, dig digest.Digest, parents []digest.Digest) (func(error), error) { +func imageSeenOrWait(ctx context.Context, opt *imageOpt, repo, tag string, dig digest.Digest, parents []digest.Digest) (func(error), error) { var seenNew *imageSeen - key := tag + ":" + dig.String() + key := repo + "/" + tag + ":" + dig.String() opt.mu.Lock() seen := opt.seen[key] if seen == nil { @@ -992,7 +1006,7 @@ func imageSeenOrWait(ctx context.Context, opt *imageOpt, tag string, dig digest. } // look for loops in parents for _, p := range parents { - if key == tag+":"+p.String() { + if key == repo+"/"+tag+":"+p.String() { return nil, errs.ErrLoopDetected } } @@ -1068,10 +1082,9 @@ func (rc *RegClient) ImageExport(ctx context.Context, r ref.Ref, outStream io.Wr // retrieve image manifest m, err := rc.ManifestGet(ctx, r) if err != nil { - rc.log.WithFields(logrus.Fields{ - "ref": r.CommonName(), - "err": err, - }).Warn("Failed to get manifest") + rc.slog.Warn("Failed to get manifest", + slog.String("ref", r.CommonName()), + slog.String("err", err.Error())) return err } @@ -1383,10 +1396,9 @@ func (rc *RegClient) imageImportDockerAddLayerHandlers(ctx context.Context, r re } } if !found { - rc.log.WithFields(logrus.Fields{ - "tags": tags, - "name": trd.name, - }).Warn("Could not find requested name") + rc.slog.Warn("Could not find requested name", + slog.Any("tags", tags), + slog.String("name", trd.name)) return } } @@ -1476,9 +1488,8 @@ func (rc *RegClient) imageImportOCIAddHandler(ctx context.Context, r ref.Ref, tr } if ociLayout.Version != ociLayoutVersion { // unknown version, ignore - rc.log.WithFields(logrus.Fields{ - "version": ociLayout.Version, - }).Warn("Unsupported oci-layout version") + rc.slog.Warn("Unsupported oci-layout version", + slog.String("version", ociLayout.Version)) return nil } foundLayout = true diff --git a/vendor/github.com/regclient/regclient/internal/auth/auth.go b/vendor/github.com/regclient/regclient/internal/auth/auth.go index 0955d2dcc..e05488f83 100644 --- a/vendor/github.com/regclient/regclient/internal/auth/auth.go +++ b/vendor/github.com/regclient/regclient/internal/auth/auth.go @@ -7,15 +7,13 @@ import ( "encoding/json" "fmt" "io" + "log/slog" "net/http" "net/url" - "os" "strings" "sync" "time" - "github.com/sirupsen/logrus" - "github.com/regclient/regclient/types/errs" ) @@ -74,7 +72,7 @@ type handler interface { } // handlerBuild is used to make a new handler for a specific authType and URL -type handlerBuild func(client *http.Client, clientID, host string, credFn CredsFn, log *logrus.Logger) handler +type handlerBuild func(client *http.Client, clientID, host string, credFn CredsFn, slog *slog.Logger) handler // Opts configures options for NewAuth type Opts func(*Auth) @@ -87,7 +85,7 @@ type Auth struct { hbs map[string]handlerBuild // handler builders based on authType hs map[string]map[string]handler // handlers based on url and authType authTypes []string - log *logrus.Logger + slog *slog.Logger mu sync.Mutex } @@ -100,12 +98,7 @@ func NewAuth(opts ...Opts) *Auth { hbs: map[string]handlerBuild{}, hs: map[string]map[string]handler{}, authTypes: []string{}, - } - a.log = &logrus.Logger{ - Out: os.Stderr, - Formatter: new(logrus.TextFormatter), - Hooks: make(logrus.LevelHooks), - Level: logrus.WarnLevel, + slog: slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})), } for _, opt := range opts { @@ -160,10 +153,10 @@ func WithDefaultHandlers() Opts { } } -// WithLog injects a logrus Logger -func WithLog(log *logrus.Logger) Opts { +// WithLog injects a Logger +func WithLog(slog *slog.Logger) Opts { return func(a *Auth) { - a.log = log + a.slog = slog } } @@ -190,10 +183,9 @@ func (a *Auth) AddScope(host, scope string) error { if !success { return ErrNoNewChallenge } - a.log.WithFields(logrus.Fields{ - "host": host, - "scope": scope, - }).Debug("Auth scope added") + a.slog.Debug("Auth scope added", + slog.String("host", host), + slog.String("scope", scope)) return nil } @@ -214,9 +206,8 @@ func (a *Auth) HandleResponse(resp *http.Response) error { if err != nil { return err } - a.log.WithFields(logrus.Fields{ - "challenge": cl, - }).Debug("Auth request parsed") + a.slog.Debug("Auth request parsed", + slog.Any("challenge", cl)) if len(cl) < 1 { return ErrEmptyChallenge } @@ -224,9 +215,8 @@ func (a *Auth) HandleResponse(resp *http.Response) error { // loop over the received challenge(s) for _, c := range cl { if _, ok := a.hbs[c.authType]; !ok { - a.log.WithFields(logrus.Fields{ - "authtype": c.authType, - }).Warn("Unsupported auth type") + a.slog.Warn("Unsupported auth type", + slog.String("authtype", c.authType)) continue } // setup a handler for the host and auth type @@ -234,7 +224,7 @@ func (a *Auth) HandleResponse(resp *http.Response) error { a.hs[host] = map[string]handler{} } if _, ok := a.hs[host][c.authType]; !ok { - h := a.hbs[c.authType](a.httpClient, a.clientID, host, a.credsFn, a.log) + h := a.hbs[c.authType](a.httpClient, a.clientID, host, a.credsFn, a.slog) if h == nil { continue } @@ -277,11 +267,10 @@ func (a *Auth) UpdateRequest(req *http.Request) error { if a.hs[host][at] != nil { ah, err = a.hs[host][at].GenerateAuth() if err != nil { - a.log.WithFields(logrus.Fields{ - "err": err, - "host": host, - "authtype": at, - }).Debug("Failed to generate auth") + a.slog.Debug("Failed to generate auth", + slog.String("err", err.Error()), + slog.String("host", host), + slog.String("authtype", at)) continue } req.Header.Set("Authorization", ah) @@ -454,7 +443,7 @@ type basicHandler struct { } // NewBasicHandler creates a new BasicHandler -func NewBasicHandler(client *http.Client, clientID, host string, credsFn CredsFn, log *logrus.Logger) handler { +func NewBasicHandler(client *http.Client, clientID, host string, credsFn CredsFn, slog *slog.Logger) handler { return &basicHandler{ realm: "", host: host, @@ -498,7 +487,7 @@ type bearerHandler struct { credsFn CredsFn scopes []string token bearerToken - log *logrus.Logger + slog *slog.Logger } // bearerToken is the json response to the Bearer request @@ -512,7 +501,7 @@ type bearerToken struct { } // NewBearerHandler creates a new BearerHandler -func NewBearerHandler(client *http.Client, clientID, host string, credsFn CredsFn, log *logrus.Logger) handler { +func NewBearerHandler(client *http.Client, clientID, host string, credsFn CredsFn, slog *slog.Logger) handler { return &bearerHandler{ client: client, clientID: clientID, @@ -521,7 +510,7 @@ func NewBearerHandler(client *http.Client, clientID, host string, credsFn CredsF realm: "", service: "", scopes: []string{}, - log: log, + slog: slog, } } @@ -770,7 +759,7 @@ type jwtHubResp struct { } // NewJWTHubHandler creates a new JWTHandler for Docker Hub. -func NewJWTHubHandler(client *http.Client, clientID, host string, credsFn CredsFn, log *logrus.Logger) handler { +func NewJWTHubHandler(client *http.Client, clientID, host string, credsFn CredsFn, slog *slog.Logger) handler { // JWT handler is only tested against Hub, and the API is Hub specific if host == "hub.docker.com" { return &jwtHubHandler{ diff --git a/vendor/github.com/regclient/regclient/internal/reghttp/http.go b/vendor/github.com/regclient/regclient/internal/reghttp/http.go index e7bd207cb..e461a9c3b 100644 --- a/vendor/github.com/regclient/regclient/internal/reghttp/http.go +++ b/vendor/github.com/regclient/regclient/internal/reghttp/http.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "io" + "log/slog" "net/http" "net/url" "os" @@ -25,12 +26,11 @@ import ( _ "crypto/sha256" _ "crypto/sha512" - "github.com/sirupsen/logrus" - "github.com/regclient/regclient/config" "github.com/regclient/regclient/internal/auth" "github.com/regclient/regclient/internal/pqueue" "github.com/regclient/regclient/internal/reqmeta" + "github.com/regclient/regclient/types" "github.com/regclient/regclient/types/errs" "github.com/regclient/regclient/types/warning" ) @@ -55,7 +55,7 @@ type Client struct { retryLimit int // number of retries before failing a request, this applies to each host, and each request delayInit time.Duration // how long to initially delay requests on a failure delayMax time.Duration // maximum time to delay a request - log *logrus.Logger // logging for tracing and failures + slog *slog.Logger // logging for tracing and failures userAgent string // user agent to specify in http request headers mu sync.Mutex // mutex to prevent data races } @@ -64,7 +64,7 @@ type clientHost struct { config *config.Host // config entry httpClient *http.Client // modified http client for registry specific settings userAgent string // user agent to specify in http request headers - log *logrus.Logger // logging for tracing and failures + slog *slog.Logger // logging for tracing and failures auth map[string]*auth.Auth // map of auth handlers by repository backoffCur int // current count of backoffs for this host backoffLast time.Time // time the last request was released, this may be in the future if there is a queue, or zero if no delay is needed @@ -120,7 +120,7 @@ func NewClient(opts ...Opts) *Client { retryLimit: DefaultRetryLimit, delayInit: defaultDelayInit, delayMax: defaultDelayMax, - log: &logrus.Logger{Out: io.Discard}, + slog: slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})), rootCAPool: [][]byte{}, rootCADirs: []string{}, } @@ -151,10 +151,9 @@ func WithCertFiles(files []string) Opts { //#nosec G304 command is run by a user accessing their own files cert, err := os.ReadFile(f) if err != nil { - c.log.WithFields(logrus.Fields{ - "err": err, - "file": f, - }).Warn("Failed to read certificate") + c.slog.Warn("Failed to read certificate", + slog.String("err", err.Error()), + slog.String("file", f)) } else { c.rootCAPool = append(c.rootCAPool, cert) } @@ -203,10 +202,10 @@ func WithRetryLimit(rl int) Opts { } } -// WithLog injects a logrus Logger configuration. -func WithLog(log *logrus.Logger) Opts { +// WithLog injects a slog Logger configuration. +func WithLog(slog *slog.Logger) Opts { return func(c *Client) { - c.log = log + c.slog = slog } } @@ -336,10 +335,9 @@ func (resp *Resp) next() error { bu := resp.backoffGet() if !bu.IsZero() && bu.After(time.Now()) { sleepTime := time.Until(bu) - c.log.WithFields(logrus.Fields{ - "Host": h.config.Name, - "Seconds": sleepTime.Seconds(), - }).Debug("Sleeping for backoff") + c.slog.Debug("Sleeping for backoff", + slog.String("Host", h.config.Name), + slog.Duration("Duration", sleepTime)) select { case <-resp.ctx.Done(): return errs.ErrCanceled @@ -426,10 +424,9 @@ func (resp *Resp) next() error { resp.resp, err = hc.Do(httpReq) if err != nil { - c.log.WithFields(logrus.Fields{ - "URL": u.String(), - "err": err, - }).Debug("Request failed") + c.slog.Debug("Request failed", + slog.String("URL", u.String()), + slog.String("err", err.Error())) backoff = true return err } @@ -446,15 +443,13 @@ func (resp *Resp) next() error { } if err != nil { if errors.Is(err, errs.ErrEmptyChallenge) || errors.Is(err, errs.ErrNoNewChallenge) || errors.Is(err, errs.ErrHTTPUnauthorized) { - c.log.WithFields(logrus.Fields{ - "URL": u.String(), - "Err": err, - }).Debug("Failed to handle auth request") + c.slog.Debug("Failed to handle auth request", + slog.String("URL", u.String()), + slog.String("Err", err.Error())) } else { - c.log.WithFields(logrus.Fields{ - "URL": u.String(), - "Err": err, - }).Warn("Failed to handle auth request") + c.slog.Warn("Failed to handle auth request", + slog.String("URL", u.String()), + slog.String("Err", err.Error())) } dropHost = true } else { @@ -489,10 +484,9 @@ func (resp *Resp) next() error { if resp.readCur == 0 && clHeader != "" { cl, parseErr := strconv.ParseInt(clHeader, 10, 64) if parseErr != nil { - c.log.WithFields(logrus.Fields{ - "err": err, - "header": clHeader, - }).Debug("failed to parse content-length header") + c.slog.Debug("failed to parse content-length header", + slog.String("err", parseErr.Error()), + slog.String("header", clHeader)) } else if resp.readMax > 0 { if resp.readMax != cl { return fmt.Errorf("unexpected content-length, expected %d, received %d", resp.readMax, cl) @@ -570,10 +564,9 @@ func (resp *Resp) Read(b []byte) (int, error) { resp.done = true } else { // short read, retry? - resp.client.log.WithFields(logrus.Fields{ - "curRead": resp.readCur, - "contentLen": resp.readMax, - }).Debug("EOF before reading all content, retrying") + resp.client.slog.Debug("EOF before reading all content, retrying", + slog.Int64("curRead", resp.readCur), + slog.Int64("contentLen", resp.readMax)) // retry respErr := resp.backoffSet() if respErr == nil { @@ -581,9 +574,8 @@ func (resp *Resp) Read(b []byte) (int, error) { } // unrecoverable EOF if respErr != nil { - resp.client.log.WithFields(logrus.Fields{ - "err": respErr, - }).Warn("Failed to recover from short read") + resp.client.slog.Warn("Failed to recover from short read", + slog.String("err", respErr.Error())) resp.done = true return i, err } @@ -740,7 +732,7 @@ func (c *Client) getHost(host string) *clientHost { h := &clientHost{ config: conf, userAgent: c.userAgent, - log: c.log, + slog: c.slog, auth: map[string]*auth.Auth{}, } if h.config.ReqPerSec > 0 { @@ -771,9 +763,8 @@ func (c *Client) getHost(host string) *clientHost { } else { rootPool, err := makeRootPool(c.rootCAPool, c.rootCADirs, h.config.Hostname, h.config.RegCert) if err != nil { - c.log.WithFields(logrus.Fields{ - "err": err, - }).Warn("failed to setup CA pool") + c.slog.Warn("failed to setup CA pool", + slog.String("err", err.Error())) } else { tlsc.RootCAs = rootPool } @@ -781,9 +772,8 @@ func (c *Client) getHost(host string) *clientHost { if h.config.ClientCert != "" && h.config.ClientKey != "" { cert, err := tls.X509KeyPair([]byte(h.config.ClientCert), []byte(h.config.ClientKey)) if err != nil { - c.log.WithFields(logrus.Fields{ - "err": err, - }).Warn("failed to configure client certs") + c.slog.Warn("failed to configure client certs", + slog.String("err", err.Error())) } else { tlsc.Certificates = []tls.Certificate{cert} } @@ -841,7 +831,7 @@ func (ch *clientHost) getAuth(repo string) *auth.Auth { } if _, ok := ch.auth[repo]; !ok { ch.auth[repo] = auth.NewAuth( - auth.WithLog(ch.log), + auth.WithLog(ch.slog), auth.WithHTTPClient(ch.httpClient), auth.WithCreds(ch.AuthCreds()), auth.WithClientID(ch.userAgent), @@ -873,27 +863,25 @@ func (wt *wrapTransport) RoundTrip(req *http.Request) (*http.Response, error) { reqHead.Set("Authorization", "[censored]") } if err != nil { - wt.c.log.WithFields(logrus.Fields{ - "req-method": req.Method, - "req-url": req.URL.String(), - "req-headers": reqHead, - "err": err, - }).Debug("reg http request") + wt.c.slog.Debug("reg http request", + slog.String("req-method", req.Method), + slog.String("req-url", req.URL.String()), + slog.Any("req-headers", reqHead), + slog.String("err", err.Error())) } else { // extract any warnings for _, wh := range resp.Header.Values("Warning") { if match := warnRegexp.FindStringSubmatch(wh); len(match) == 2 { // TODO(bmitch): pass other fields (registry hostname) with structured logging - warning.Handle(req.Context(), wt.c.log, match[1]) + warning.Handle(req.Context(), wt.c.slog, match[1]) } } - wt.c.log.WithFields(logrus.Fields{ - "req-method": req.Method, - "req-url": req.URL.String(), - "req-headers": reqHead, - "resp-status": resp.Status, - "resp-headers": resp.Header, - }).Trace("reg http request") + wt.c.slog.Log(req.Context(), types.LevelTrace, "reg http request", + slog.String("req-method", req.Method), + slog.String("req-url", req.URL.String()), + slog.Any("req-headers", reqHead), + slog.String("resp-status", resp.Status), + slog.Any("resp-headers", resp.Header)) } return resp, err } diff --git a/vendor/github.com/regclient/regclient/internal/sloghandle/logrus.go b/vendor/github.com/regclient/regclient/internal/sloghandle/logrus.go new file mode 100644 index 000000000..4f7ec4bf3 --- /dev/null +++ b/vendor/github.com/regclient/regclient/internal/sloghandle/logrus.go @@ -0,0 +1,126 @@ +//go:build !wasm +// +build !wasm + +// Package sloghandle provides a transition handler for migrating from logrus to slog. +package sloghandle + +import ( + "context" + "log/slog" + "strings" + + "github.com/sirupsen/logrus" + + "github.com/regclient/regclient/types" +) + +func Logrus(logger *logrus.Logger) *logrusHandler { + return &logrusHandler{ + logger: logger, + } +} + +type logrusHandler struct { + logger *logrus.Logger + attrs []slog.Attr + groups []string +} + +func (h *logrusHandler) Enabled(_ context.Context, level slog.Level) bool { + ll := h.logger.GetLevel() + if curLevel, ok := logrusToSlog[ll]; ok { + return level >= curLevel + } + return true +} + +func (h *logrusHandler) Handle(ctx context.Context, r slog.Record) error { + log := logrus.NewEntry(h.logger).WithContext(ctx) + if !r.Time.IsZero() { + log = log.WithTime(r.Time) + } + fields := logrus.Fields{} + for _, a := range h.attrs { + if a.Key != "" { + fields[a.Key] = a.Value + } + } + r.Attrs(func(a slog.Attr) bool { + if a.Key != "" { + fields[a.Key] = a.Value + } + return true + }) + if len(fields) > 0 { + log = log.WithFields(fields) + } + log.Log(slogToLogrus(r.Level), r.Message) + return nil +} + +func (h *logrusHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + ret := h.clone() + prefix := "" + if len(h.groups) > 0 { + prefix = strings.Join(h.groups, ":") + ":" + } + for _, a := range attrs { + if a.Key == "" { + continue + } + ret.attrs = append(ret.attrs, slog.Attr{ + Key: prefix + a.Key, + Value: a.Value, + }) + } + return ret +} + +func (h *logrusHandler) WithGroup(name string) slog.Handler { + if name == "" { + return h + } + ret := h.clone() + ret.groups = append(ret.groups, name) + return ret +} + +func (h *logrusHandler) clone() *logrusHandler { + attrs := make([]slog.Attr, len(h.attrs)) + copy(attrs, h.attrs) + groups := make([]string, len(h.groups)) + copy(groups, h.groups) + return &logrusHandler{ + logger: h.logger, + attrs: attrs, + groups: groups, + } +} + +var logrusToSlog = map[logrus.Level]slog.Level{ + logrus.TraceLevel: types.LevelTrace, + logrus.DebugLevel: slog.LevelDebug, + logrus.InfoLevel: slog.LevelInfo, + logrus.WarnLevel: slog.LevelWarn, + logrus.ErrorLevel: slog.LevelError, + logrus.FatalLevel: slog.LevelError + 4, + logrus.PanicLevel: slog.LevelError + 8, +} + +func slogToLogrus(level slog.Level) logrus.Level { + if level <= types.LevelTrace { + return logrus.TraceLevel + } else if level <= slog.LevelDebug { + return logrus.DebugLevel + } else if level <= slog.LevelInfo { + return logrus.InfoLevel + } else if level <= slog.LevelWarn { + return logrus.WarnLevel + } else if level <= slog.LevelError { + return logrus.ErrorLevel + } else if level <= slog.LevelError+4 { + return logrus.FatalLevel + } else { + return logrus.PanicLevel + } +} diff --git a/vendor/github.com/regclient/regclient/manifest.go b/vendor/github.com/regclient/regclient/manifest.go index c5cc84e90..285f72e51 100644 --- a/vendor/github.com/regclient/regclient/manifest.go +++ b/vendor/github.com/regclient/regclient/manifest.go @@ -3,6 +3,7 @@ package regclient import ( "context" "fmt" + "log/slog" "github.com/regclient/regclient/scheme" "github.com/regclient/regclient/types/descriptor" @@ -121,7 +122,9 @@ func (rc *RegClient) ManifestGet(ctx context.Context, r ref.Ref, opts ...Manifes return m, err } if opt.platform != nil && !m.IsList() { - rc.log.Debugf("ignoring platform option %s, %s is not an index", opt.platform.String(), r.CommonName()) + rc.slog.Debug("ignoring platform option, image is not an index", + slog.String("platform", opt.platform.String()), + slog.String("ref", r.CommonName())) } // this will loop to handle a nested index for opt.platform != nil && m.IsList() { @@ -160,7 +163,9 @@ func (rc *RegClient) ManifestHead(ctx context.Context, r ref.Ref, opts ...Manife return m, err } if opt.platform != nil && !m.IsList() { - rc.log.Debugf("ignoring platform option %s, %s is not an index", opt.platform.String(), r.CommonName()) + rc.slog.Debug("ignoring platform option, image is not an index", + slog.String("platform", opt.platform.String()), + slog.String("ref", r.CommonName())) } // this will loop to handle a nested index for opt.platform != nil && m.IsList() { diff --git a/vendor/github.com/regclient/regclient/referrer.go b/vendor/github.com/regclient/regclient/referrer.go index a4411bbe2..2c168124b 100644 --- a/vendor/github.com/regclient/regclient/referrer.go +++ b/vendor/github.com/regclient/regclient/referrer.go @@ -6,19 +6,52 @@ import ( "github.com/regclient/regclient/scheme" "github.com/regclient/regclient/types/errs" + "github.com/regclient/regclient/types/platform" "github.com/regclient/regclient/types/ref" "github.com/regclient/regclient/types/referrer" + "github.com/regclient/regclient/types/warning" ) // ReferrerList retrieves a list of referrers to a manifest. // The descriptor list should contain manifests that each have a subject field matching the requested ref. -func (rc *RegClient) ReferrerList(ctx context.Context, r ref.Ref, opts ...scheme.ReferrerOpts) (referrer.ReferrerList, error) { - if !r.IsSet() { - return referrer.ReferrerList{}, fmt.Errorf("ref is not set: %s%.0w", r.CommonName(), errs.ErrInvalidReference) +func (rc *RegClient) ReferrerList(ctx context.Context, rSubject ref.Ref, opts ...scheme.ReferrerOpts) (referrer.ReferrerList, error) { + if !rSubject.IsSet() { + return referrer.ReferrerList{}, fmt.Errorf("ref is not set: %s%.0w", rSubject.CommonName(), errs.ErrInvalidReference) + } + // dedup warnings + if w := warning.FromContext(ctx); w == nil { + ctx = warning.NewContext(ctx, &warning.Warning{Hook: warning.DefaultHook()}) + } + // set the digest on the subject reference + config := scheme.ReferrerConfig{} + for _, opt := range opts { + opt(&config) + } + if rSubject.Digest == "" || config.Platform != "" { + mo := []ManifestOpts{WithManifestRequireDigest()} + if config.Platform != "" { + p, err := platform.Parse(config.Platform) + if err != nil { + return referrer.ReferrerList{}, fmt.Errorf("failed to lookup referrer platform: %w", err) + } + mo = append(mo, WithManifestPlatform(p)) + } + m, err := rc.ManifestHead(ctx, rSubject, mo...) + if err != nil { + return referrer.ReferrerList{}, fmt.Errorf("failed to get digest for subject: %w", err) + } + rSubject = rSubject.SetDigest(m.GetDescriptor().Digest.String()) + } + // lookup the scheme for the appropriate ref + var r ref.Ref + if config.SrcRepo.IsSet() { + r = config.SrcRepo + } else { + r = rSubject } schemeAPI, err := rc.schemeGet(r.Scheme) if err != nil { return referrer.ReferrerList{}, err } - return schemeAPI.ReferrerList(ctx, r, opts...) + return schemeAPI.ReferrerList(ctx, rSubject, opts...) } diff --git a/vendor/github.com/regclient/regclient/regclient.go b/vendor/github.com/regclient/regclient/regclient.go index 0ac4be851..c1a342187 100644 --- a/vendor/github.com/regclient/regclient/regclient.go +++ b/vendor/github.com/regclient/regclient/regclient.go @@ -3,12 +3,11 @@ package regclient import ( "io" + "log/slog" "time" "fmt" - "github.com/sirupsen/logrus" - "github.com/regclient/regclient/config" "github.com/regclient/regclient/internal/version" "github.com/regclient/regclient/scheme" @@ -33,9 +32,9 @@ const ( type RegClient struct { hosts map[string]*config.Host hostDefault *config.Host - log *logrus.Logger regOpts []reg.Opts schemes map[string]scheme.API + slog *slog.Logger userAgent string } @@ -47,9 +46,9 @@ func New(opts ...Opt) *RegClient { var rc = RegClient{ hosts: map[string]*config.Host{}, userAgent: DefaultUserAgent, - log: &logrus.Logger{Out: io.Discard}, regOpts: []reg.Opts{}, schemes: map[string]scheme.API{}, + slog: slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})), } info := version.GetInfo() @@ -74,20 +73,19 @@ func New(opts ...Opt) *RegClient { rc.regOpts = append(rc.regOpts, reg.WithConfigHosts(hostList), reg.WithConfigHostDefault(rc.hostDefault), - reg.WithLog(rc.log), + reg.WithSlog(rc.slog), reg.WithUserAgent(rc.userAgent), ) // setup scheme's rc.schemes["reg"] = reg.New(rc.regOpts...) rc.schemes["ocidir"] = ocidir.New( - ocidir.WithLog(rc.log), + ocidir.WithSlog(rc.slog), ) - rc.log.WithFields(logrus.Fields{ - "VCSRef": info.VCSRef, - "VCSTag": info.VCSTag, - }).Debug("regclient initialized") + rc.slog.Debug("regclient initialized", + slog.String("VCSRef", info.VCSRef), + slog.String("VCSTag", info.VCSTag)) return &rc } @@ -151,9 +149,8 @@ func WithDockerCreds() Opt { return func(rc *RegClient) { configHosts, err := config.DockerLoad() if err != nil { - rc.log.WithFields(logrus.Fields{ - "err": err, - }).Warn("Failed to load docker creds") + rc.slog.Warn("Failed to load docker creds", + slog.String("err", err.Error())) return } rc.hostLoad("docker", configHosts) @@ -166,22 +163,14 @@ func WithDockerCredsFile(fname string) Opt { return func(rc *RegClient) { configHosts, err := config.DockerLoadFile(fname) if err != nil { - rc.log.WithFields(logrus.Fields{ - "err": err, - }).Warn("Failed to load docker creds") + rc.slog.Warn("Failed to load docker creds", + slog.String("err", err.Error())) return } rc.hostLoad("docker-file", configHosts) } } -// WithLog overrides default logrus Logger. -func WithLog(log *logrus.Logger) Opt { - return func(rc *RegClient) { - rc.log = log - } -} - // WithRegOpts passes through opts to the reg scheme. func WithRegOpts(opts ...reg.Opts) Opt { return func(rc *RegClient) { @@ -210,6 +199,13 @@ func WithRetryLimit(retryLimit int) Opt { } } +// WithSlog configures the slog Logger. +func WithSlog(slog *slog.Logger) Opt { + return func(rc *RegClient) { + rc.slog = slog + } +} + // WithUserAgent specifies the User-Agent http header. func WithUserAgent(ua string) Opt { return func(rc *RegClient) { @@ -220,7 +216,14 @@ func WithUserAgent(ua string) Opt { func (rc *RegClient) hostLoad(src string, hosts []config.Host) { for _, configHost := range hosts { if configHost.Name == "" { - // TODO: should this error, warn, or fall back to hostname? + if configHost.Pass != "" { + configHost.Pass = "***" + } + if configHost.Token != "" { + configHost.Token = "***" + } + rc.slog.Warn("Ignoring registry config without a name", + slog.Any("entry", configHost)) continue } if configHost.Name == DockerRegistry || configHost.Name == DockerRegistryDNS || configHost.Name == DockerRegistryAuth { @@ -230,25 +233,24 @@ func (rc *RegClient) hostLoad(src string, hosts []config.Host) { } } tls, _ := configHost.TLS.MarshalText() - rc.log.WithFields(logrus.Fields{ - "name": configHost.Name, - "user": configHost.User, - "hostname": configHost.Hostname, - "helper": configHost.CredHelper, - "repoAuth": configHost.RepoAuth, - "tls": string(tls), - "pathPrefix": configHost.PathPrefix, - "mirrors": configHost.Mirrors, - "blobMax": configHost.BlobMax, - "blobChunk": configHost.BlobChunk, - }).Debugf("Loading %s config", src) + rc.slog.Debug("Loading config", + slog.Int64("blobChunk", configHost.BlobChunk), + slog.Int64("blobMax", configHost.BlobMax), + slog.String("helper", configHost.CredHelper), + slog.String("hostname", configHost.Hostname), + slog.Any("mirrors", configHost.Mirrors), + slog.String("name", configHost.Name), + slog.String("pathPrefix", configHost.PathPrefix), + slog.Bool("repoAuth", configHost.RepoAuth), + slog.String("source", src), + slog.String("tls", string(tls)), + slog.String("user", configHost.User)) err := rc.hostSet(configHost) if err != nil { - rc.log.WithFields(logrus.Fields{ - "host": configHost.Name, - "user": configHost.User, - "error": err, - }).Warn("Failed to update host config") + rc.slog.Warn("Failed to update host config", + slog.String("host", configHost.Name), + slog.String("user", configHost.User), + slog.String("error", err.Error())) } } } @@ -262,7 +264,7 @@ func (rc *RegClient) hostSet(newHost config.Host) error { err = rc.hosts[name].Merge(newHost, nil) } else { // merge newHost with existing settings - err = rc.hosts[name].Merge(newHost, rc.log) + err = rc.hosts[name].Merge(newHost, rc.slog) } if err != nil { return err diff --git a/vendor/github.com/regclient/regclient/regclient_nowasm.go b/vendor/github.com/regclient/regclient/regclient_nowasm.go new file mode 100644 index 000000000..d99ca1eda --- /dev/null +++ b/vendor/github.com/regclient/regclient/regclient_nowasm.go @@ -0,0 +1,20 @@ +//go:build !wasm +// +build !wasm + +package regclient + +import ( + "log/slog" + + "github.com/sirupsen/logrus" + + "github.com/regclient/regclient/internal/sloghandle" +) + +// WithLog configuring logging with a logrus Logger. +// Note that regclient has switched to log/slog for logging and my eventually deprecate logrus support. +func WithLog(log *logrus.Logger) Opt { + return func(rc *RegClient) { + rc.slog = slog.New(sloghandle.Logrus(log)) + } +} diff --git a/vendor/github.com/regclient/regclient/release.md b/vendor/github.com/regclient/regclient/release.md index 82b6dafaf..92649f6b3 100644 --- a/vendor/github.com/regclient/regclient/release.md +++ b/vendor/github.com/regclient/regclient/release.md @@ -1,74 +1,74 @@ -# Release v0.7.2 - -Breaking Changes: - -The breaking changes are to internal methods and undocumented features that should not be encountered by users. - -- Update scheme to use pqueue instead of throttle. ([PR 803][pr-803]) -- Removes an undocumented API for deleting images from Hub. ([PR 803][pr-803]) -- `config.Host.Throttle()` has been removed. Use `scheme.Throttler` instead. ([PR 813][pr-813]) - -Features: - -- Significant refactor of http APIs to speed up image copies. ([PR 803][pr-803]) -- Add a priority queue for network requests. ([PR 803][pr-803]) -- Move logging into transport and rework backoff. ([PR 803][pr-803]) -- Remove default rate limit. ([PR 803][pr-803]) -- Add priority queue algorithm and reorder image copy steps. ([PR 803][pr-803]) -- Consolidate warnings. ([PR 810][pr-810]) -- Limit number of retries for a request. ([PR 812][pr-812]) -- Add default host config. ([PR 821][pr-821]) - -Fixes: - -- Update GHA output generating steps. ([PR 800][pr-800]) -- Lookup referrers when registry does not give digest with head. ([PR 801][pr-801]) -- Support auth on redirect. ([PR 805][pr-805]) -- Prevent data race when reading blob and seeking. ([PR 814][pr-814]) -- Detect integer overflows on type conversion. ([PR 830][pr-830]) -- Add a warning if syft is not installed. ([PR 841][pr-841]) -- Race condition in the pqueue tests. ([PR 843][pr-843]) -- Dedup warnings on image mod. ([PR 846][pr-846]) - -Chores: - -- Update staticcheck and fix linter warnings for Go 1.23. ([PR 804][pr-804]) -- Remove digest calculation from reghttp. ([PR 803][pr-803]) -- Remove `ReqPerSec` in tests. ([PR 806][pr-806]) -- Move throttle from `config` to `reghttp`. ([PR 813][pr-813]) -- Refactoring to remove globals in regsync. ([PR 815][pr-815]) -- Refactor to remove globals in regbot. ([PR 816][pr-816]) -- Remove throttle package. ([PR 817][pr-817]) -- Update version-bump config for processors. ([PR 828][pr-828]) -- Update config to use yaml anchors and aliases ([PR 829][pr-829]) -- Do not automatically assign myself to GitHub issues. ([PR 831][pr-831]) -- Remove OpenSSF scorecard and best practices. ([PR 832][pr-832]) -- Update docker image base filesystem. ([PR 837][pr-837]) - -Contributors: +# Release v0.8.0 + +## Highlights + +There are three headline changes in this release: slog support, external referrers, and deprecating legacy packages. + +This release switches from logrus to slog. +Migration methods are included to minimize the impact on existing users. +Anyone parsing the logging output from regctl, regsync, and regbot will notice the format has changed. + +External referrers allow referrers to be pushed and pulled from a separate repository from the subject image. +This feature requires users to provide the external repository themselves since a registry has no way to communicate this to the user. +An example use case of this feature are third parties, like security scanners, providing attestations of images they do not control. + +Legacy packages have been disabled by default and will eventually be removed. +To continue using legacy packages until their removal, you may compile with `-tags legacy`. + +## Breaking + +- Breaking: Warning handlers switched from `logrus` to `slog` which will only impact those with a custom warning handler. ([PR 847][pr-847]) +- Breaking: Disable legacy packages by default. ([PR 852][pr-852]) + +## Features + +- Feat: Refactor logging to use log/slog. ([PR 847][pr-847]) +- Feat: Switch regbot to slog. ([PR 849][pr-849]) +- Feat: Switch regctl to slog. ([PR 850][pr-850]) +- Feat: Switch regsync to slog. ([PR 851][pr-851]) +- Feat: Move logrus calls into files excluded by wasm. ([PR 853][pr-853]) +- Feat: Allow plus in ocidir path. ([PR 856][pr-856]) +- Feat: Support referrers in an external repository. ([PR 866][pr-866]) +- Feat: Image mod environment variables. ([PR 867][pr-867]) +- Feat: Include source in referrers response. ([PR 870][pr-870]) +- Feat: Add external flag to regctl artifact put. ([PR 873][pr-873]) +- Feat: Copy image with external referrers. ([PR 874][pr-874]) +- Feat: Document community maintained packages. ([PR 878][pr-878]) +- Feat: Support external referrers in regsync. ([PR 881][pr-881]) +- Feat: Support incomplete subject descriptor. ([PR 885][pr-885]) + +## Fixes + +- Fix: Inject release notes by file. ([PR 854][pr-854]) +- Fix: Platform test for darwin/macos should not add variant. ([PR 879][pr-879]) +- Fix: Handle repeated digest in copy with external referrers. ([PR 882][pr-882]) + +## Chores + +- Chore: Improve error message when inspecting artifacts. ([PR 862][pr-862]) +- Chore: Remove unused short arg parameters. ([PR 877][pr-877]) + +## Contributors - @sudo-bmitch -[pr-800]: https://github.com/regclient/regclient/pull/800 -[pr-801]: https://github.com/regclient/regclient/pull/801 -[pr-804]: https://github.com/regclient/regclient/pull/804 -[pr-803]: https://github.com/regclient/regclient/pull/803 -[pr-805]: https://github.com/regclient/regclient/pull/805 -[pr-806]: https://github.com/regclient/regclient/pull/806 -[pr-810]: https://github.com/regclient/regclient/pull/810 -[pr-812]: https://github.com/regclient/regclient/pull/812 -[pr-813]: https://github.com/regclient/regclient/pull/813 -[pr-814]: https://github.com/regclient/regclient/pull/814 -[pr-815]: https://github.com/regclient/regclient/pull/815 -[pr-816]: https://github.com/regclient/regclient/pull/816 -[pr-817]: https://github.com/regclient/regclient/pull/817 -[pr-821]: https://github.com/regclient/regclient/pull/821 -[pr-828]: https://github.com/regclient/regclient/pull/828 -[pr-829]: https://github.com/regclient/regclient/pull/829 -[pr-830]: https://github.com/regclient/regclient/pull/830 -[pr-831]: https://github.com/regclient/regclient/pull/831 -[pr-832]: https://github.com/regclient/regclient/pull/832 -[pr-837]: https://github.com/regclient/regclient/pull/837 -[pr-841]: https://github.com/regclient/regclient/pull/841 -[pr-843]: https://github.com/regclient/regclient/pull/843 -[pr-846]: https://github.com/regclient/regclient/pull/846 +[pr-847]: https://github.com/regclient/regclient/pull/847 +[pr-849]: https://github.com/regclient/regclient/pull/849 +[pr-850]: https://github.com/regclient/regclient/pull/850 +[pr-851]: https://github.com/regclient/regclient/pull/851 +[pr-852]: https://github.com/regclient/regclient/pull/852 +[pr-853]: https://github.com/regclient/regclient/pull/853 +[pr-854]: https://github.com/regclient/regclient/pull/854 +[pr-856]: https://github.com/regclient/regclient/pull/856 +[pr-862]: https://github.com/regclient/regclient/pull/862 +[pr-866]: https://github.com/regclient/regclient/pull/866 +[pr-867]: https://github.com/regclient/regclient/pull/867 +[pr-870]: https://github.com/regclient/regclient/pull/870 +[pr-873]: https://github.com/regclient/regclient/pull/873 +[pr-874]: https://github.com/regclient/regclient/pull/874 +[pr-877]: https://github.com/regclient/regclient/pull/877 +[pr-878]: https://github.com/regclient/regclient/pull/878 +[pr-879]: https://github.com/regclient/regclient/pull/879 +[pr-881]: https://github.com/regclient/regclient/pull/881 +[pr-882]: https://github.com/regclient/regclient/pull/882 +[pr-885]: https://github.com/regclient/regclient/pull/885 diff --git a/vendor/github.com/regclient/regclient/scheme/ocidir/blob.go b/vendor/github.com/regclient/regclient/scheme/ocidir/blob.go index d23fd507f..a06e922e0 100644 --- a/vendor/github.com/regclient/regclient/scheme/ocidir/blob.go +++ b/vendor/github.com/regclient/regclient/scheme/ocidir/blob.go @@ -6,11 +6,10 @@ import ( "fmt" "io" "io/fs" + "log/slog" "os" "path" - "github.com/sirupsen/logrus" - "github.com/regclient/regclient/internal/reqmeta" "github.com/regclient/regclient/types/blob" "github.com/regclient/regclient/types/descriptor" @@ -55,10 +54,9 @@ func (o *OCIDir) BlobGet(ctx context.Context, r ref.Ref, d descriptor.Descriptor blob.WithReader(fd), blob.WithDesc(d), ) - o.log.WithFields(logrus.Fields{ - "ref": r.CommonName(), - "file": file, - }).Debug("retrieved blob") + o.slog.Debug("retrieved blob", + slog.String("ref", r.CommonName()), + slog.String("file", file)) return br, nil } @@ -150,10 +148,9 @@ func (o *OCIDir) BlobPut(ctx context.Context, r ref.Ref, d descriptor.Descriptor if err != nil { return d, fmt.Errorf("failed to write blob (rename tmp file %s to %s): %w", path.Join(dir, tmpName), file, err) } - o.log.WithFields(logrus.Fields{ - "ref": r.CommonName(), - "file": file, - }).Debug("pushed blob") + o.slog.Debug("pushed blob", + slog.String("ref", r.CommonName()), + slog.String("file", file)) o.mu.Lock() o.refMod(r) diff --git a/vendor/github.com/regclient/regclient/scheme/ocidir/close.go b/vendor/github.com/regclient/regclient/scheme/ocidir/close.go index e038a1e47..23eae0d12 100644 --- a/vendor/github.com/regclient/regclient/scheme/ocidir/close.go +++ b/vendor/github.com/regclient/regclient/scheme/ocidir/close.go @@ -3,11 +3,10 @@ package ocidir import ( "context" "fmt" + "log/slog" "os" "path" - "github.com/sirupsen/logrus" - "github.com/regclient/regclient/types/manifest" "github.com/regclient/regclient/types/ref" ) @@ -26,9 +25,8 @@ func (o *OCIDir) Close(ctx context.Context, r ref.Ref) error { } // perform GC - o.log.WithFields(logrus.Fields{ - "ref": r.CommonName(), - }).Debug("running GC") + o.slog.Debug("running GC", + slog.String("ref", r.CommonName())) dl := map[string]bool{} // recurse through index, manifests, and blob lists, generating a digest list index, err := o.readIndex(r, true) @@ -62,9 +60,8 @@ func (o *OCIDir) Close(ctx context.Context, r ref.Ref) error { for _, digestFile := range digestFiles { digest := fmt.Sprintf("%s:%s", blobDir.Name(), digestFile.Name()) if !dl[digest] { - o.log.WithFields(logrus.Fields{ - "digest": digest, - }).Debug("ocidir garbage collect") + o.slog.Debug("ocidir garbage collect", + slog.String("digest", digest)) // delete err = os.Remove(path.Join(blobsPath, blobDir.Name(), digestFile.Name())) if err != nil { @@ -90,10 +87,9 @@ func (o *OCIDir) closeProcManifest(ctx context.Context, r ref.Ref, m manifest.Ma cm, err := o.manifestGet(ctx, cr) if err != nil { // ignore errors in case a manifest has been deleted or sparse copy - o.log.WithFields(logrus.Fields{ - "ref": cr.CommonName(), - "err": err, - }).Debug("could not retrieve manifest") + o.slog.Debug("could not retrieve manifest", + slog.String("ref", cr.CommonName()), + slog.String("err", err.Error())) continue } err = o.closeProcManifest(ctx, cr, cm, dl) diff --git a/vendor/github.com/regclient/regclient/scheme/ocidir/manifest.go b/vendor/github.com/regclient/regclient/scheme/ocidir/manifest.go index 2be836f68..c4cf0ee85 100644 --- a/vendor/github.com/regclient/regclient/scheme/ocidir/manifest.go +++ b/vendor/github.com/regclient/regclient/scheme/ocidir/manifest.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "io/fs" + "log/slog" "os" "path" @@ -15,7 +16,6 @@ import ( _ "crypto/sha512" "github.com/opencontainers/go-digest" - "github.com/sirupsen/logrus" "github.com/regclient/regclient/scheme" "github.com/regclient/regclient/types/errs" @@ -49,7 +49,7 @@ func (o *OCIDir) ManifestDelete(ctx context.Context, r ref.Ref, opts ...scheme.M if mc.Manifest != nil { if ms, ok := mc.Manifest.(manifest.Subjecter); ok { sDesc, err := ms.GetSubject() - if err == nil && sDesc != nil && sDesc.MediaType != "" && sDesc.Size > 0 { + if err == nil && sDesc != nil && sDesc.Digest != "" { // attempt to delete the referrer, but ignore if the referrer entry wasn't found err = o.referrerDelete(ctx, r, mc.Manifest) if err != nil && !errors.Is(err, errs.ErrNotFound) && !errors.Is(err, fs.ErrNotExist) { @@ -134,10 +134,9 @@ func (o *OCIDir) manifestGet(_ context.Context, r ref.Ref) (manifest.Manifest, e if desc.Size == 0 { desc.Size = int64(len(mb)) } - o.log.WithFields(logrus.Fields{ - "ref": r.CommonName(), - "file": file, - }).Debug("retrieved manifest") + o.slog.Debug("retrieved manifest", + slog.String("ref", r.CommonName()), + slog.String("file", file)) return manifest.New( manifest.WithRef(r), manifest.WithDesc(desc), @@ -279,10 +278,9 @@ func (o *OCIDir) manifestPut(ctx context.Context, r ref.Ref, m manifest.Manifest return err } o.refMod(r) - o.log.WithFields(logrus.Fields{ - "ref": r.CommonName(), - "file": file, - }).Debug("pushed manifest") + o.slog.Debug("pushed manifest", + slog.String("ref", r.CommonName()), + slog.String("file", file)) // update referrers if defined on this manifest if ms, ok := m.(manifest.Subjecter); ok { @@ -290,7 +288,7 @@ func (o *OCIDir) manifestPut(ctx context.Context, r ref.Ref, m manifest.Manifest if err != nil { return err } - if mDesc != nil && mDesc.MediaType != "" && mDesc.Size > 0 { + if mDesc != nil && mDesc.Digest != "" { err = o.referrerPut(ctx, r, m) if err != nil { return err diff --git a/vendor/github.com/regclient/regclient/scheme/ocidir/ocidir.go b/vendor/github.com/regclient/regclient/scheme/ocidir/ocidir.go index 802dec9a2..2dcf189d6 100644 --- a/vendor/github.com/regclient/regclient/scheme/ocidir/ocidir.go +++ b/vendor/github.com/regclient/regclient/scheme/ocidir/ocidir.go @@ -7,13 +7,12 @@ import ( "fmt" "io" "io/fs" + "log/slog" "os" "path" "strings" "sync" - "github.com/sirupsen/logrus" - "github.com/regclient/regclient/internal/pqueue" "github.com/regclient/regclient/internal/reqmeta" "github.com/regclient/regclient/types/descriptor" @@ -32,7 +31,7 @@ const ( // OCIDir is used for accessing OCI Image Layouts defined as a directory type OCIDir struct { - log *logrus.Logger + slog *slog.Logger gc bool modRefs map[string]*ociGC throttle map[string]*pqueue.Queue[reqmeta.Data] @@ -47,7 +46,7 @@ type ociGC struct { type ociConf struct { gc bool - log *logrus.Logger + slog *slog.Logger throttle int } @@ -57,7 +56,7 @@ type Opts func(*ociConf) // New creates a new OCIDir with options func New(opts ...Opts) *OCIDir { conf := ociConf{ - log: &logrus.Logger{Out: io.Discard}, + slog: slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})), gc: true, throttle: defThrottle, } @@ -65,7 +64,7 @@ func New(opts ...Opts) *OCIDir { opt(&conf) } return &OCIDir{ - log: conf.log, + slog: conf.slog, gc: conf.gc, modRefs: map[string]*ociGC{}, throttle: map[string]*pqueue.Queue[reqmeta.Data]{}, @@ -81,11 +80,11 @@ func WithGC(gc bool) Opts { } } -// WithLog provides a logrus logger -// By default logging is disabled -func WithLog(log *logrus.Logger) Opts { +// WithSlog provides a slog logger. +// By default logging is disabled. +func WithSlog(slog *slog.Logger) Opts { return func(c *ociConf) { - c.log = log + c.slog = slog } } diff --git a/vendor/github.com/regclient/regclient/scheme/ocidir/ocidir_nowasm.go b/vendor/github.com/regclient/regclient/scheme/ocidir/ocidir_nowasm.go new file mode 100644 index 000000000..901439455 --- /dev/null +++ b/vendor/github.com/regclient/regclient/scheme/ocidir/ocidir_nowasm.go @@ -0,0 +1,20 @@ +//go:build !wasm +// +build !wasm + +package ocidir + +import ( + "log/slog" + + "github.com/sirupsen/logrus" + + "github.com/regclient/regclient/internal/sloghandle" +) + +// WithLog provides a logrus logger. +// By default logging is disabled. +func WithLog(log *logrus.Logger) Opts { + return func(c *ociConf) { + c.slog = slog.New(sloghandle.Logrus(log)) + } +} diff --git a/vendor/github.com/regclient/regclient/scheme/ocidir/referrer.go b/vendor/github.com/regclient/regclient/scheme/ocidir/referrer.go index a93862b26..7a89d27cf 100644 --- a/vendor/github.com/regclient/regclient/scheme/ocidir/referrer.go +++ b/vendor/github.com/regclient/regclient/scheme/ocidir/referrer.go @@ -10,57 +10,35 @@ import ( "github.com/regclient/regclient/types/manifest" "github.com/regclient/regclient/types/mediatype" v1 "github.com/regclient/regclient/types/oci/v1" - "github.com/regclient/regclient/types/platform" "github.com/regclient/regclient/types/ref" "github.com/regclient/regclient/types/referrer" ) -// ReferrerList returns a list of referrers to a given reference +// ReferrerList returns a list of referrers to a given reference. +// The reference must include the digest. Use [regclient.ReferrerList] to resolve the platform or tag. func (o *OCIDir) ReferrerList(ctx context.Context, r ref.Ref, opts ...scheme.ReferrerOpts) (referrer.ReferrerList, error) { o.mu.Lock() defer o.mu.Unlock() return o.referrerList(ctx, r, opts...) } -func (o *OCIDir) referrerList(ctx context.Context, r ref.Ref, opts ...scheme.ReferrerOpts) (referrer.ReferrerList, error) { +func (o *OCIDir) referrerList(ctx context.Context, rSubject ref.Ref, opts ...scheme.ReferrerOpts) (referrer.ReferrerList, error) { config := scheme.ReferrerConfig{} for _, opt := range opts { opt(&config) } + var r ref.Ref + if config.SrcRepo.IsSet() { + r = config.SrcRepo.SetDigest(rSubject.Digest) + } else { + r = rSubject.SetDigest(rSubject.Digest) + } rl := referrer.ReferrerList{ Tags: []string{}, } - // select a platform from a manifest list - if config.Platform != "" { - p, err := platform.Parse(config.Platform) - if err != nil { - return rl, err - } - m, err := o.manifestGet(ctx, r) - if err != nil { - return rl, err - } - for m.IsList() { - d, err := manifest.GetPlatformDesc(m, &p) - if err != nil { - return rl, err - } - m, err = o.manifestGet(ctx, r.SetDigest(d.Digest.String())) - if err != nil { - return rl, err - } - } - r = r.SetDigest(m.GetDescriptor().Digest.String()) + if rSubject.Digest == "" { + return rl, fmt.Errorf("digest required to query referrers %s", rSubject.CommonName()) } - // if ref is a tag, run a head request for the digest - if r.Digest == "" { - m, err := o.manifestGet(ctx, r) - if err != nil { - return rl, err - } - r = r.SetDigest(m.GetDescriptor().Digest.String()) - } - rl.Subject = r // pull referrer list by tag rlTag, err := referrer.FallbackTag(r) @@ -87,6 +65,10 @@ func (o *OCIDir) referrerList(ctx context.Context, r ref.Ref, opts ...scheme.Ref return rl, fmt.Errorf("manifest is not an OCI index: %s", rlTag.CommonName()) } // update referrer list + rl.Subject = rSubject + if config.SrcRepo.IsSet() { + rl.Source = config.SrcRepo + } rl.Manifest = m rl.Descriptors = ociML.Manifests rl.Annotations = ociML.Annotations @@ -108,7 +90,7 @@ func (o *OCIDir) referrerDelete(ctx context.Context, r ref.Ref, m manifest.Manif return err } // validate/set subject descriptor - if subject == nil || subject.MediaType == "" || subject.Digest == "" || subject.Size <= 0 { + if subject == nil || subject.Digest == "" { return fmt.Errorf("subject is not set%.0w", errs.ErrNotFound) } @@ -152,7 +134,7 @@ func (o *OCIDir) referrerPut(ctx context.Context, r ref.Ref, m manifest.Manifest return err } // validate/set subject descriptor - if subject == nil || subject.MediaType == "" || subject.Digest == "" || subject.Size <= 0 { + if subject == nil || subject.Digest == "" { return fmt.Errorf("subject is not set%.0w", errs.ErrNotFound) } diff --git a/vendor/github.com/regclient/regclient/scheme/reg/blob.go b/vendor/github.com/regclient/regclient/scheme/reg/blob.go index b0a8e5143..f477f8874 100644 --- a/vendor/github.com/regclient/regclient/scheme/reg/blob.go +++ b/vendor/github.com/regclient/regclient/scheme/reg/blob.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "log/slog" "net/http" "net/url" "strconv" @@ -16,7 +17,6 @@ import ( _ "crypto/sha512" "github.com/opencontainers/go-digest" - "github.com/sirupsen/logrus" "github.com/regclient/regclient/internal/reghttp" "github.com/regclient/regclient/internal/reqmeta" @@ -261,10 +261,9 @@ func (reg *Reg) blobGetUploadURL(ctx context.Context, r ref.Ref, d descriptor.De if minSizeStr != "" { minSize, err := strconv.ParseInt(minSizeStr, 10, 64) if err != nil { - reg.log.WithFields(logrus.Fields{ - "size": minSizeStr, - "err": err, - }).Warn("Failed to parse chunk size header") + reg.slog.Warn("Failed to parse chunk size header", + slog.String("size", minSizeStr), + slog.String("err", err.Error())) } else { host := reg.hostGet(r.Registry) if (host.BlobChunk > 0 && minSize > host.BlobChunk) || (host.BlobChunk <= 0 && minSize > reg.blobChunkSize) { @@ -273,10 +272,9 @@ func (reg *Reg) blobGetUploadURL(ctx context.Context, r ref.Ref, d descriptor.De } else { host.BlobChunk = minSize } - reg.log.WithFields(logrus.Fields{ - "size": host.BlobChunk, - "host": host.Name, - }).Debug("Registry requested min chunk size") + reg.slog.Debug("Registry requested min chunk size", + slog.Int64("size", host.BlobChunk), + slog.String("host", host.Name)) } } } @@ -285,17 +283,16 @@ func (reg *Reg) blobGetUploadURL(ctx context.Context, r ref.Ref, d descriptor.De if location == "" { return nil, fmt.Errorf("failed to send blob post, ref %s: %w", r.CommonName(), errs.ErrMissingLocation) } - reg.log.WithFields(logrus.Fields{ - "location": location, - }).Debug("Upload location received") + reg.slog.Debug("Upload location received", + slog.String("location", location)) + // put url may be relative to the above post URL, so parse in that context postURL := resp.HTTPResponse().Request.URL putURL, err := postURL.Parse(location) if err != nil { - reg.log.WithFields(logrus.Fields{ - "location": location, - "err": err, - }).Warn("Location url failed to parse") + reg.slog.Warn("Location url failed to parse", + slog.String("location", location), + slog.String("err", err.Error())) return nil, fmt.Errorf("blob upload url invalid, ref %s: %w", r.CommonName(), err) } return putURL, nil @@ -333,10 +330,9 @@ func (reg *Reg) blobMount(ctx context.Context, rTgt ref.Ref, d descriptor.Descri if minSizeStr != "" { minSize, err := strconv.ParseInt(minSizeStr, 10, 64) if err != nil { - reg.log.WithFields(logrus.Fields{ - "size": minSizeStr, - "err": err, - }).Warn("Failed to parse chunk size header") + reg.slog.Warn("Failed to parse chunk size header", + slog.String("size", minSizeStr), + slog.String("err", err.Error())) } else { host := reg.hostGet(rTgt.Registry) if (host.BlobChunk > 0 && minSize > host.BlobChunk) || (host.BlobChunk <= 0 && minSize > reg.blobChunkSize) { @@ -346,10 +342,9 @@ func (reg *Reg) blobMount(ctx context.Context, rTgt ref.Ref, d descriptor.Descri } else { host.BlobChunk = minSize } - reg.log.WithFields(logrus.Fields{ - "size": host.BlobChunk, - "host": host.Name, - }).Debug("Registry requested min chunk size") + reg.slog.Debug("Registry requested min chunk size", + slog.Int64("size", host.BlobChunk), + slog.String("host", host.Name)) } } } @@ -364,12 +359,11 @@ func (reg *Reg) blobMount(ctx context.Context, rTgt ref.Ref, d descriptor.Descri postURL := resp.HTTPResponse().Request.URL putURL, err := postURL.Parse(location) if err != nil { - reg.log.WithFields(logrus.Fields{ - "digest": d, - "target": rTgt.CommonName(), - "location": location, - "err": err, - }).Warn("Mount location header failed to parse") + reg.slog.Warn("Mount location header failed to parse", + slog.String("digest", d.Digest.String()), + slog.String("target", rTgt.CommonName()), + slog.String("location", location), + slog.String("err", err.Error())) } else { return putURL, uuid, errs.ErrMountReturnedLocation } @@ -532,21 +526,19 @@ func (reg *Reg) blobPutUploadChunked(ctx context.Context, r ref.Ref, d descripto httpResp := resp.HTTPResponse() // distribution-spec is 202, AWS ECR returns a 201 and rejects the put if resp.HTTPResponse().StatusCode == 201 { - reg.log.WithFields(logrus.Fields{ - "ref": r.CommonName(), - "chunkStart": chunkStart, - "chunkSize": chunkSize, - }).Debug("Early accept of chunk in PATCH before PUT request") + reg.slog.Debug("Early accept of chunk in PATCH before PUT request", + slog.String("ref", r.CommonName()), + slog.Int64("chunkStart", chunkStart), + slog.Int("chunkSize", chunkSize)) } else if resp.HTTPResponse().StatusCode >= 400 && resp.HTTPResponse().StatusCode < 500 && resp.HTTPResponse().Header.Get("Location") != "" && resp.HTTPResponse().Header.Get("Range") != "" { retryCur++ - reg.log.WithFields(logrus.Fields{ - "ref": r.CommonName(), - "chunkStart": chunkStart, - "chunkSize": chunkSize, - "range": resp.HTTPResponse().Header.Get("Range"), - }).Debug("Recoverable chunk upload error") + reg.slog.Debug("Recoverable chunk upload error", + slog.String("ref", r.CommonName()), + slog.Int64("chunkStart", chunkStart), + slog.Int("chunkSize", chunkSize), + slog.String("range", resp.HTTPResponse().Header.Get("Range"))) } else if resp.HTTPResponse().StatusCode != 202 { retryCur++ statusResp, statusErr := reg.blobUploadStatus(ctx, r, &chunkURL) @@ -568,9 +560,8 @@ func (reg *Reg) blobPutUploadChunked(ctx context.Context, r ref.Ref, d descripto } location := httpResp.Header.Get("Location") if location != "" { - reg.log.WithFields(logrus.Fields{ - "location": location, - }).Debug("Next chunk upload location received") + reg.slog.Debug("Next chunk upload location received", + slog.String("location", location)) prevURL := httpResp.Request.URL parseURL, err := prevURL.Parse(location) if err != nil { diff --git a/vendor/github.com/regclient/regclient/scheme/reg/manifest.go b/vendor/github.com/regclient/regclient/scheme/reg/manifest.go index e9efb1b32..c9789da7f 100644 --- a/vendor/github.com/regclient/regclient/scheme/reg/manifest.go +++ b/vendor/github.com/regclient/regclient/scheme/reg/manifest.go @@ -5,12 +5,12 @@ import ( "errors" "fmt" "io" + "log/slog" "net/http" "net/url" "strconv" "github.com/opencontainers/go-digest" - "github.com/sirupsen/logrus" "github.com/regclient/regclient/internal/limitread" "github.com/regclient/regclient/internal/reghttp" @@ -49,7 +49,7 @@ func (reg *Reg) ManifestDelete(ctx context.Context, r ref.Ref, opts ...scheme.Ma if mc.Manifest != nil { if mr, ok := mc.Manifest.(manifest.Subjecter); ok { sDesc, err := mr.GetSubject() - if err == nil && sDesc != nil && sDesc.MediaType != "" && sDesc.Size > 0 { + if err == nil && sDesc != nil && sDesc.Digest != "" { // attempt to delete the referrer, but ignore if the referrer entry wasn't found err = reg.referrerDelete(ctx, r, mc.Manifest) if err != nil && !errors.Is(err, errs.ErrNotFound) { @@ -214,9 +214,8 @@ func (reg *Reg) ManifestPut(ctx context.Context, r ref.Ref, m manifest.Manifest, } else if r.Tag != "" { tagOrDigest = r.Tag } else { - reg.log.WithFields(logrus.Fields{ - "ref": r.Reference, - }).Warn("Manifest put requires a tag") + reg.slog.Warn("Manifest put requires a tag", + slog.String("ref", r.Reference)) return errs.ErrMissingTag } // dedup warnings @@ -227,10 +226,9 @@ func (reg *Reg) ManifestPut(ctx context.Context, r ref.Ref, m manifest.Manifest, // create the request body mj, err := m.MarshalJSON() if err != nil { - reg.log.WithFields(logrus.Fields{ - "ref": r.Reference, - "err": err, - }).Warn("Error marshaling manifest") + reg.slog.Warn("Error marshaling manifest", + slog.String("ref", r.Reference), + slog.String("err", err.Error())) return fmt.Errorf("error marshalling manifest for %s: %w", r.CommonName(), err) } @@ -281,7 +279,7 @@ func (reg *Reg) ManifestPut(ctx context.Context, r ref.Ref, m manifest.Manifest, if err != nil { return err } - if mDesc != nil && mDesc.MediaType != "" && mDesc.Size > 0 && mDesc.Digest.String() != "" { + if mDesc != nil && mDesc.Digest.String() != "" { rSubj := r.SetDigest(mDesc.Digest.String()) reg.cacheRL.Delete(rSubj) if mDesc.Digest.String() != resp.HTTPResponse().Header.Get(OCISubjectHeader) { diff --git a/vendor/github.com/regclient/regclient/scheme/reg/referrer.go b/vendor/github.com/regclient/regclient/scheme/reg/referrer.go index 664e75066..2e9757cb4 100644 --- a/vendor/github.com/regclient/regclient/scheme/reg/referrer.go +++ b/vendor/github.com/regclient/regclient/scheme/reg/referrer.go @@ -15,7 +15,6 @@ import ( "github.com/regclient/regclient/types/manifest" "github.com/regclient/regclient/types/mediatype" v1 "github.com/regclient/regclient/types/oci/v1" - "github.com/regclient/regclient/types/platform" "github.com/regclient/regclient/types/ref" "github.com/regclient/regclient/types/referrer" "github.com/regclient/regclient/types/warning" @@ -23,80 +22,33 @@ import ( const OCISubjectHeader = "OCI-Subject" -// ReferrerList returns a list of referrers to a given reference -func (reg *Reg) ReferrerList(ctx context.Context, r ref.Ref, opts ...scheme.ReferrerOpts) (referrer.ReferrerList, error) { +// ReferrerList returns a list of referrers to a given reference. +// The reference must include the digest. Use [regclient.ReferrerList] to resolve the platform or tag. +func (reg *Reg) ReferrerList(ctx context.Context, rSubject ref.Ref, opts ...scheme.ReferrerOpts) (referrer.ReferrerList, error) { config := scheme.ReferrerConfig{} for _, opt := range opts { opt(&config) } + var r ref.Ref + if config.SrcRepo.IsSet() { + r = config.SrcRepo.SetDigest(rSubject.Digest) + } else { + r = rSubject.SetDigest(rSubject.Digest) + } rl := referrer.ReferrerList{ Tags: []string{}, } + if rSubject.Digest == "" { + return rl, fmt.Errorf("digest required to query referrers %s", rSubject.CommonName()) + } // dedup warnings if w := warning.FromContext(ctx); w == nil { ctx = warning.NewContext(ctx, &warning.Warning{Hook: warning.DefaultHook()}) } - // select a platform from a manifest list - if config.Platform != "" { - p, err := platform.Parse(config.Platform) - if err != nil { - return rl, err - } - m, err := reg.ManifestHead(ctx, r) - if err != nil { - return rl, err - } - if m.GetDescriptor().Digest.String() == "" { - m, err = reg.ManifestGet(ctx, r) - if err != nil { - return rl, err - } - } - for m.IsList() { - m, err = reg.ManifestGet(ctx, r) - if err != nil { - return rl, err - } - d, err := manifest.GetPlatformDesc(m, &p) - if err != nil { - return rl, err - } - m, err = reg.ManifestHead(ctx, r.SetDigest(d.Digest.String())) - if err != nil { - return rl, err - } - if m.GetDescriptor().Digest.String() == "" { - m, err = reg.ManifestGet(ctx, r.SetDigest(d.Digest.String())) - if err != nil { - return rl, err - } - } - } - r = r.SetDigest(m.GetDescriptor().Digest.String()) - } - // if ref is a tag, run a head request for the digest - if r.Digest == "" { - m, err := reg.ManifestHead(ctx, r) - if err != nil { - return rl, err - } - if m.GetDescriptor().Digest == "" { - m, err = reg.ManifestGet(ctx, r) - if err != nil { - return rl, err - } - } - if m.GetDescriptor().Digest == "" { - return rl, fmt.Errorf("unable to resolve digest for ref %s", r.CommonName()) - } - r = r.SetDigest(m.GetDescriptor().Digest.String()) - } - rl.Subject = r found := false // try cache - rCache := r.SetDigest(r.Digest) - rl, err := reg.cacheRL.Get(rCache) + rl, err := reg.cacheRL.Get(r) if err == nil { found = true } @@ -113,7 +65,7 @@ func (reg *Reg) ReferrerList(ctx context.Context, r ref.Ref, opts ...scheme.Refe if err == nil { if config.MatchOpt.ArtifactType == "" { // only cache if successful and artifactType is not filtered - reg.cacheRL.Set(rCache, rl) + reg.cacheRL.Set(r, rl) } found = true } @@ -123,9 +75,13 @@ func (reg *Reg) ReferrerList(ctx context.Context, r ref.Ref, opts ...scheme.Refe if !found { rl, err = reg.referrerListByTag(ctx, r) if err == nil { - reg.cacheRL.Set(rCache, rl) + reg.cacheRL.Set(r, rl) } } + rl.Subject = rSubject + if config.SrcRepo.IsSet() { + rl.Source = config.SrcRepo + } if err != nil { return rl, err } @@ -290,7 +246,7 @@ func (reg *Reg) referrerDelete(ctx context.Context, r ref.Ref, m manifest.Manife return err } // validate/set subject descriptor - if subject == nil || subject.MediaType == "" || subject.Digest == "" || subject.Size <= 0 { + if subject == nil || subject.Digest == "" { return fmt.Errorf("refers is not set%.0w", errs.ErrNotFound) } @@ -343,7 +299,7 @@ func (reg *Reg) referrerPut(ctx context.Context, r ref.Ref, m manifest.Manifest) return err } // validate/set subject descriptor - if subject == nil || subject.MediaType == "" || subject.Digest == "" || subject.Size <= 0 { + if subject == nil || subject.Digest == "" { return fmt.Errorf("subject is not set%.0w", errs.ErrNotFound) } @@ -366,7 +322,7 @@ func (reg *Reg) referrerPut(ctx context.Context, r ref.Ref, m manifest.Manifest) if err != nil { return err } - if mDesc != nil && mDesc.MediaType != "" && mDesc.Size > 0 { + if mDesc != nil && mDesc.Digest != "" { return fmt.Errorf("fallback referrers manifest should not have a subject: %s", rSubject.CommonName()) } } diff --git a/vendor/github.com/regclient/regclient/scheme/reg/reg.go b/vendor/github.com/regclient/regclient/scheme/reg/reg.go index 5672ba66e..5f2a27e9c 100644 --- a/vendor/github.com/regclient/regclient/scheme/reg/reg.go +++ b/vendor/github.com/regclient/regclient/scheme/reg/reg.go @@ -2,12 +2,11 @@ package reg import ( + "log/slog" "net/http" "sync" "time" - "github.com/sirupsen/logrus" - "github.com/regclient/regclient/config" "github.com/regclient/regclient/internal/cache" "github.com/regclient/regclient/internal/pqueue" @@ -43,7 +42,7 @@ const ( type Reg struct { reghttp *reghttp.Client reghttpOpts []reghttp.Opts - log *logrus.Logger + slog *slog.Logger hosts map[string]*config.Host hostDefault *config.Host features map[featureKey]*featureVal @@ -235,14 +234,6 @@ func WithHTTPClient(hc *http.Client) Opts { } } -// WithLog injects a logrus Logger configuration -func WithLog(log *logrus.Logger) Opts { - return func(r *Reg) { - r.log = log - r.reghttpOpts = append(r.reghttpOpts, reghttp.WithLog(log)) - } -} - // WithManifestMax sets the push and pull limits for manifests func WithManifestMax(push, pull int64) Opts { return func(r *Reg) { @@ -258,6 +249,14 @@ func WithRetryLimit(l int) Opts { } } +// WithSlog injects a slog Logger configuration +func WithSlog(slog *slog.Logger) Opts { + return func(r *Reg) { + r.slog = slog + r.reghttpOpts = append(r.reghttpOpts, reghttp.WithLog(slog)) + } +} + // WithTransport uses a specific http transport with retryable requests func WithTransport(t *http.Transport) Opts { return func(r *Reg) { diff --git a/vendor/github.com/regclient/regclient/scheme/reg/reg_nowasm.go b/vendor/github.com/regclient/regclient/scheme/reg/reg_nowasm.go new file mode 100644 index 000000000..82a5a82f8 --- /dev/null +++ b/vendor/github.com/regclient/regclient/scheme/reg/reg_nowasm.go @@ -0,0 +1,21 @@ +//go:build !wasm +// +build !wasm + +package reg + +import ( + "log/slog" + + "github.com/sirupsen/logrus" + + "github.com/regclient/regclient/internal/reghttp" + "github.com/regclient/regclient/internal/sloghandle" +) + +// WithLog injects a logrus Logger configuration +func WithLog(log *logrus.Logger) Opts { + return func(r *Reg) { + r.slog = slog.New(sloghandle.Logrus(log)) + r.reghttpOpts = append(r.reghttpOpts, reghttp.WithLog(r.slog)) + } +} diff --git a/vendor/github.com/regclient/regclient/scheme/reg/repo.go b/vendor/github.com/regclient/regclient/scheme/reg/repo.go index 779493dcb..b9b0307c2 100644 --- a/vendor/github.com/regclient/regclient/scheme/reg/repo.go +++ b/vendor/github.com/regclient/regclient/scheme/reg/repo.go @@ -4,12 +4,11 @@ import ( "context" "fmt" "io" + "log/slog" "net/http" "net/url" "strconv" - "github.com/sirupsen/logrus" - "github.com/regclient/regclient/internal/reghttp" "github.com/regclient/regclient/internal/reqmeta" "github.com/regclient/regclient/scheme" @@ -57,10 +56,9 @@ func (reg *Reg) RepoList(ctx context.Context, hostname string, opts ...scheme.Re respBody, err := io.ReadAll(resp) if err != nil { - reg.log.WithFields(logrus.Fields{ - "err": err, - "host": hostname, - }).Warn("Failed to read repo list") + reg.slog.Warn("Failed to read repo list", + slog.String("err", err.Error()), + slog.String("host", hostname)) return nil, fmt.Errorf("failed to read repo list for %s: %w", hostname, err) } mt := mediatype.Base(resp.HTTPResponse().Header.Get("Content-Type")) @@ -71,11 +69,10 @@ func (reg *Reg) RepoList(ctx context.Context, hostname string, opts ...scheme.Re repo.WithHeaders(resp.HTTPResponse().Header), ) if err != nil { - reg.log.WithFields(logrus.Fields{ - "err": err, - "body": string(respBody), - "host": hostname, - }).Warn("Failed to unmarshal repo list") + reg.slog.Warn("Failed to unmarshal repo list", + slog.String("err", err.Error()), + slog.String("body", string(respBody)), + slog.String("host", hostname)) return nil, fmt.Errorf("failed to parse repo list for %s: %w", hostname, err) } return rl, nil diff --git a/vendor/github.com/regclient/regclient/scheme/reg/tag.go b/vendor/github.com/regclient/regclient/scheme/reg/tag.go index 66952aa7a..e24b54be4 100644 --- a/vendor/github.com/regclient/regclient/scheme/reg/tag.go +++ b/vendor/github.com/regclient/regclient/scheme/reg/tag.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "io" + "log/slog" "net/http" "net/url" "strconv" @@ -17,7 +18,6 @@ import ( _ "crypto/sha512" "github.com/opencontainers/go-digest" - "github.com/sirupsen/logrus" "github.com/regclient/regclient/internal/httplink" "github.com/regclient/regclient/internal/reghttp" @@ -160,9 +160,8 @@ func (reg *Reg) TagDelete(ctx context.Context, r ref.Ref) error { return err } } - reg.log.WithFields(logrus.Fields{ - "ref": r.Reference, - }).Debug("Sending dummy manifest to replace tag") + reg.slog.Debug("Sending dummy manifest to replace tag", + slog.String("ref", r.Reference)) // push empty layer _, err = reg.BlobPut(ctx, r, descriptor.Descriptor{Digest: descriptor.EmptyDigest, Size: int64(len(descriptor.EmptyData))}, bytes.NewReader(descriptor.EmptyData)) @@ -185,10 +184,9 @@ func (reg *Reg) TagDelete(ctx context.Context, r ref.Ref) error { r.Digest = tempManifest.GetDescriptor().Digest.String() // delete manifest by digest - reg.log.WithFields(logrus.Fields{ - "ref": r.Reference, - "digest": r.Digest, - }).Debug("Deleting dummy manifest") + reg.slog.Debug("Deleting dummy manifest", + slog.String("ref", r.Reference), + slog.String("digest", r.Digest)) err = reg.ManifestDelete(ctx, r) if err != nil { return fmt.Errorf("failed deleting dummy manifest for %s: %w", r.CommonName(), err) @@ -281,10 +279,9 @@ func (reg *Reg) tagListOCI(ctx context.Context, r ref.Ref, config scheme.TagConf } respBody, err := io.ReadAll(resp) if err != nil { - reg.log.WithFields(logrus.Fields{ - "err": err, - "ref": r.CommonName(), - }).Warn("Failed to read tag list") + reg.slog.Warn("Failed to read tag list", + slog.String("err", err.Error()), + slog.String("ref", r.CommonName())) return nil, fmt.Errorf("failed to read tags for %s: %w", r.CommonName(), err) } tl, err := tag.New( @@ -293,11 +290,10 @@ func (reg *Reg) tagListOCI(ctx context.Context, r ref.Ref, config scheme.TagConf tag.WithResp(resp.HTTPResponse()), ) if err != nil { - reg.log.WithFields(logrus.Fields{ - "err": err, - "body": respBody, - "ref": r.CommonName(), - }).Warn("Failed to unmarshal tag list") + reg.slog.Warn("Failed to unmarshal tag list", + slog.String("err", err.Error()), + slog.String("body", string(respBody)), + slog.String("ref", r.CommonName())) return tl, fmt.Errorf("failed to unmarshal tag list for %s: %w", r.CommonName(), err) } @@ -326,10 +322,9 @@ func (reg *Reg) tagListLink(ctx context.Context, r ref.Ref, _ scheme.TagConfig, } respBody, err := io.ReadAll(resp) if err != nil { - reg.log.WithFields(logrus.Fields{ - "err": err, - "ref": r.CommonName(), - }).Warn("Failed to read tag list") + reg.slog.Warn("Failed to read tag list", + slog.String("err", err.Error()), + slog.String("ref", r.CommonName())) return nil, fmt.Errorf("failed to read tags for %s: %w", r.CommonName(), err) } tl, err := tag.New( @@ -338,11 +333,10 @@ func (reg *Reg) tagListLink(ctx context.Context, r ref.Ref, _ scheme.TagConfig, tag.WithResp(resp.HTTPResponse()), ) if err != nil { - reg.log.WithFields(logrus.Fields{ - "err": err, - "body": respBody, - "ref": r.CommonName(), - }).Warn("Failed to unmarshal tag list") + reg.slog.Warn("Failed to unmarshal tag list", + slog.String("err", err.Error()), + slog.String("body", string(respBody)), + slog.String("ref", r.CommonName())) return tl, fmt.Errorf("failed to unmarshal tag list for %s: %w", r.CommonName(), err) } diff --git a/vendor/github.com/regclient/regclient/scheme/scheme.go b/vendor/github.com/regclient/regclient/scheme/scheme.go index 0ba063fe6..84388a3bb 100644 --- a/vendor/github.com/regclient/regclient/scheme/scheme.go +++ b/vendor/github.com/regclient/regclient/scheme/scheme.go @@ -108,6 +108,7 @@ func WithManifest(m manifest.Manifest) ManifestOpts { type ReferrerConfig struct { MatchOpt descriptor.MatchOpt // filter/sort results Platform string // get referrers for a specific platform + SrcRepo ref.Ref // repo used to query referrers } // ReferrerOpts is used to set options on referrer APIs. @@ -121,12 +122,21 @@ func WithReferrerMatchOpt(mo descriptor.MatchOpt) ReferrerOpts { } // WithReferrerPlatform gets referrers for a single platform from a multi-platform manifest. +// Note that this is implemented by [regclient.ReferrerList] and not the individual scheme implementations. func WithReferrerPlatform(p string) ReferrerOpts { return func(config *ReferrerConfig) { config.Platform = p } } +// WithReferrerSource pulls referrers from a separate source. +// Note that this is implemented by [regclient.ReferrerList] and not the individual scheme implementations. +func WithReferrerSource(r ref.Ref) ReferrerOpts { + return func(config *ReferrerConfig) { + config.SrcRepo = r + } +} + // WithReferrerAT filters by a specific artifactType value. // // Deprecated: replace with [WithReferrerMatchOpt]. @@ -165,6 +175,7 @@ func WithReferrerSort(annotation string, desc bool) ReferrerOpts { func ReferrerFilter(config ReferrerConfig, rlIn referrer.ReferrerList) referrer.ReferrerList { return referrer.ReferrerList{ Subject: rlIn.Subject, + Source: rlIn.Source, Manifest: rlIn.Manifest, Annotations: rlIn.Annotations, Tags: rlIn.Tags, diff --git a/vendor/github.com/regclient/regclient/types/ref/ref.go b/vendor/github.com/regclient/regclient/types/ref/ref.go index ae96d953f..7dbc9684d 100644 --- a/vendor/github.com/regclient/regclient/types/ref/ref.go +++ b/vendor/github.com/regclient/regclient/types/ref/ref.go @@ -29,7 +29,7 @@ var ( hostUpperS = `(?:[a-zA-Z0-9]*[A-Z][a-zA-Z0-9-]*[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[A-Z][a-zA-Z0-9]*)` registryS = `(?:` + hostDomainS + `|` + hostPortS + `|` + hostUpperS + `|localhost(?:` + regexp.QuoteMeta(`:`) + `[0-9]+)?)` repoPartS = `[a-z0-9]+(?:(?:\.|_|__|-+)[a-z0-9]+)*` - pathS = `[/a-zA-Z0-9_\-. ~]+` + pathS = `[/a-zA-Z0-9_\-. ~\+]+` tagS = `[a-zA-Z0-9_][a-zA-Z0-9._-]{0,127}` digestS = `[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}` schemeRE = regexp.MustCompile(`^([a-z]+)://(.+)$`) diff --git a/vendor/github.com/regclient/regclient/types/referrer/referrer.go b/vendor/github.com/regclient/regclient/types/referrer/referrer.go index 6ffe92c6d..5a7bc4f35 100644 --- a/vendor/github.com/regclient/regclient/types/referrer/referrer.go +++ b/vendor/github.com/regclient/regclient/types/referrer/referrer.go @@ -19,6 +19,7 @@ import ( // ReferrerList contains the response to a request for referrers to a subject type ReferrerList struct { Subject ref.Ref `json:"subject"` // subject queried + Source ref.Ref `json:"source"` // source for referrers, if different from subject Descriptors []descriptor.Descriptor `json:"descriptors"` // descriptors found in Index Annotations map[string]string `json:"annotations,omitempty"` // annotations extracted from Index Manifest manifest.Manifest `json:"-"` // returned OCI Index @@ -110,18 +111,21 @@ func (rl ReferrerList) IsEmpty() bool { func (rl ReferrerList) MarshalPretty() ([]byte, error) { buf := &bytes.Buffer{} tw := tabwriter.NewWriter(buf, 0, 0, 1, ' ', 0) - if rl.Subject.Reference != "" { - fmt.Fprintf(tw, "Subject:\t%s\n", rl.Subject.Reference) + var rRef ref.Ref + if rl.Subject.IsSet() { + rRef = rl.Subject + fmt.Fprintf(tw, "Subject:\t%s\n", rl.Subject.CommonName()) + } + if rl.Source.IsSet() { + rRef = rl.Source + fmt.Fprintf(tw, "Source:\t%s\n", rl.Source.CommonName()) } - rRef := rl.Subject - rRef.Tag = "" fmt.Fprintf(tw, "\t\n") fmt.Fprintf(tw, "Referrers:\t\n") for _, d := range rl.Descriptors { fmt.Fprintf(tw, "\t\n") - if rRef.Reference != "" { - rRef.Digest = d.Digest.String() - fmt.Fprintf(tw, " Name:\t%s\n", rRef.CommonName()) + if rRef.IsSet() { + fmt.Fprintf(tw, " Name:\t%s\n", rRef.SetDigest(d.Digest.String()).CommonName()) } err := d.MarshalPrettyTW(tw, " ") if err != nil { diff --git a/vendor/github.com/regclient/regclient/types/slog.go b/vendor/github.com/regclient/regclient/types/slog.go new file mode 100644 index 000000000..99a4f5206 --- /dev/null +++ b/vendor/github.com/regclient/regclient/types/slog.go @@ -0,0 +1,8 @@ +package types + +import "log/slog" + +const ( + // LevelTrace is used for tracing network requests. + LevelTrace = slog.LevelDebug - 4 +) diff --git a/vendor/github.com/regclient/regclient/types/warning/warning.go b/vendor/github.com/regclient/regclient/types/warning/warning.go index 9612fc727..f14fb3337 100644 --- a/vendor/github.com/regclient/regclient/types/warning/warning.go +++ b/vendor/github.com/regclient/regclient/types/warning/warning.go @@ -3,9 +3,8 @@ package warning import ( "context" + "log/slog" "sync" - - "github.com/sirupsen/logrus" ) type contextKey string @@ -14,11 +13,11 @@ var key contextKey = "key" type Warning struct { List []string - Hook *func(context.Context, *logrus.Logger, string) + Hook *func(context.Context, *slog.Logger, string) mu sync.Mutex } -func (w *Warning) Handle(ctx context.Context, log *logrus.Logger, msg string) { +func (w *Warning) Handle(ctx context.Context, slog *slog.Logger, msg string) { w.mu.Lock() defer w.mu.Unlock() // dedup @@ -30,7 +29,7 @@ func (w *Warning) Handle(ctx context.Context, log *logrus.Logger, msg string) { w.List = append(w.List, msg) // handle new warning if hook defined if w.Hook != nil { - (*w.Hook)(ctx, log, msg) + (*w.Hook)(ctx, slog, msg) } } @@ -50,33 +49,31 @@ func FromContext(ctx context.Context) *Warning { return w } -func NewHook(log *logrus.Logger) *func(context.Context, *logrus.Logger, string) { - hook := func(_ context.Context, _ *logrus.Logger, msg string) { +func NewHook(log *slog.Logger) *func(context.Context, *slog.Logger, string) { + hook := func(_ context.Context, _ *slog.Logger, msg string) { logMsg(log, msg) } return &hook } -func DefaultHook() *func(context.Context, *logrus.Logger, string) { - hook := func(_ context.Context, log *logrus.Logger, msg string) { - logMsg(log, msg) +func DefaultHook() *func(context.Context, *slog.Logger, string) { + hook := func(_ context.Context, slog *slog.Logger, msg string) { + logMsg(slog, msg) } return &hook } -func Handle(ctx context.Context, log *logrus.Logger, msg string) { +func Handle(ctx context.Context, slog *slog.Logger, msg string) { // check for context if w := FromContext(ctx); w != nil { - w.Handle(ctx, log, msg) + w.Handle(ctx, slog, msg) return } // fallback to log - logMsg(log, msg) + logMsg(slog, msg) } -func logMsg(log *logrus.Logger, msg string) { - log.WithFields(logrus.Fields{ - "warning": msg, - }).Warn("Registry warning message") +func logMsg(log *slog.Logger, msg string) { + log.Warn("Registry warning message", slog.String("warning", msg)) } diff --git a/vendor/modules.txt b/vendor/modules.txt index ca29bda79..66f68bb2b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -468,7 +468,7 @@ github.com/prometheus/common/model github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs github.com/prometheus/procfs/internal/util -# github.com/regclient/regclient v0.7.2 +# github.com/regclient/regclient v0.8.0 ## explicit; go 1.21 github.com/regclient/regclient github.com/regclient/regclient/config @@ -480,6 +480,7 @@ github.com/regclient/regclient/internal/limitread github.com/regclient/regclient/internal/pqueue github.com/regclient/regclient/internal/reghttp github.com/regclient/regclient/internal/reqmeta +github.com/regclient/regclient/internal/sloghandle github.com/regclient/regclient/internal/strparse github.com/regclient/regclient/internal/timejson github.com/regclient/regclient/internal/units From 725893f7b0bb09acfbbfc3e461a97214525ed789 Mon Sep 17 00:00:00 2001 From: Tariq Ibrahim Date: Wed, 18 Dec 2024 14:53:03 -0800 Subject: [PATCH 2/2] bump regctl version in gitlab-ci Signed-off-by: Tariq Ibrahim --- .common-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.common-ci.yml b/.common-ci.yml index 6a37d7989..6cfd7dba3 100644 --- a/.common-ci.yml +++ b/.common-ci.yml @@ -150,7 +150,7 @@ trigger-pipeline: # Download the regctl binary for use in the release steps .regctl-setup: before_script: - - export REGCTL_VERSION=v0.7.2 + - export REGCTL_VERSION=v0.8.0 - apk add --no-cache curl - mkdir -p bin - curl -sSLo bin/regctl https://github.com/regclient/regclient/releases/download/${REGCTL_VERSION}/regctl-linux-amd64