From 5dd8c5c692fb85406b5d8dd7bdd06c088badcb4a Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 20 Aug 2026 12:45:45 +0200 Subject: [PATCH 01/21] testregistry: begin rewriting to use distribution registry Set up the test container registry using github.com/distribution/distribution. This delegates more of the registry handling to third party libraries, but will allow us to build a more complete test registry so we can test both pushing and resolving. --- .github/workflows/gitlab-helper.yml | 2 +- .github/workflows/tests.yml | 2 +- .github/workflows/validate-checksums.yml | 2 +- go.mod | 84 ++++++--- go.sum | 228 +++++++++++++++++------ internal/testregistry/testregistry.go | 28 +++ tools/prepare-source.sh | 2 +- 7 files changed, 264 insertions(+), 84 deletions(-) diff --git a/.github/workflows/gitlab-helper.yml b/.github/workflows/gitlab-helper.yml index 38113a5d82..faeb1bcd17 100644 --- a/.github/workflows/gitlab-helper.yml +++ b/.github/workflows/gitlab-helper.yml @@ -25,7 +25,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v7 with: - go-version: "1.24.12" + go-version: "1.25.14" id: go - name: Check out code into the Go module directory diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 060bf7c930..ed67fc5111 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -129,7 +129,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v7 with: - go-version: "1.24.12" + go-version: "1.25.14" id: go - name: Check out code into the Go module directory diff --git a/.github/workflows/validate-checksums.yml b/.github/workflows/validate-checksums.yml index 401110116f..46718cc9a9 100644 --- a/.github/workflows/validate-checksums.yml +++ b/.github/workflows/validate-checksums.yml @@ -24,7 +24,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v7 with: - go-version: "1.24.12" + go-version: "1.25.14" id: go - name: Check out code into the Go module directory diff --git a/go.mod b/go.mod index 7e06f3c41b..d4216bc692 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/osbuild/image-builder -go 1.24.12 +go 1.25.0 require ( cloud.google.com/go/compute v1.45.0 @@ -23,6 +23,7 @@ require ( github.com/cheggaaa/pb/v3 v3.1.7 github.com/containers/common v0.64.2 github.com/containers/image/v5 v5.36.2 + github.com/distribution/distribution/v3 v3.1.1 github.com/gobwas/glob v0.2.3 github.com/gocomply/scap v0.1.3 github.com/google/go-cmp v0.7.0 @@ -45,9 +46,9 @@ require ( go.yaml.in/yaml/v3 v3.0.4 golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 golang.org/x/oauth2 v0.35.0 - golang.org/x/sys v0.41.0 - golang.org/x/term v0.40.0 - golang.org/x/tools v0.40.0 + golang.org/x/sys v0.42.0 + golang.org/x/term v0.41.0 + golang.org/x/tools v0.42.0 google.golang.org/api v0.248.0 gopkg.in/ini.v1 v1.67.3 libvirt.org/go/libvirt v1.12005.0 @@ -64,7 +65,7 @@ require ( cloud.google.com/go/monitoring v1.24.2 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 // indirect github.com/IBM/go-sdk-core/v5 v5.21.0 // indirect @@ -85,6 +86,8 @@ require ( github.com/aws/aws-sdk-go-v2/service/ssooidc v1.37.0 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.44.0 // indirect github.com/aws/smithy-go v1.27.3 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect @@ -94,11 +97,14 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker v28.3.2+incompatible // indirect - github.com/docker/docker-credential-helpers v0.9.3 // indirect + github.com/docker/docker-credential-helpers v0.9.5 // indirect github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-events v0.0.0-20250808211157-605354379745 // indirect + github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dougm/pretty v0.0.0-20160325215624-add1dbc86daf // indirect github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect @@ -120,14 +126,18 @@ require ( github.com/google/s2a-go v0.1.9 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect github.com/googleapis/gax-go/v2 v2.15.0 // indirect + github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/mux v1.8.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/golang-lru/arc/v2 v2.0.5 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/klauspost/pgzip v1.2.6 // indirect github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect @@ -143,12 +153,21 @@ require ( github.com/moby/sys/user v0.4.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/opencontainers/runtime-spec v1.2.1 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/proglottis/gpgme v0.1.4 // indirect + github.com/prometheus/client_golang v1.23.2 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/otlptranslator v1.0.0 // indirect + github.com/prometheus/procfs v0.20.1 // indirect + github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 // indirect + github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 // indirect + github.com/redis/go-redis/v9 v9.7.3 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect @@ -166,25 +185,42 @@ require ( github.com/vbauerster/mpb/v8 v8.10.2 // indirect go.mongodb.org/mongo-driver v1.17.2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/bridges/prometheus v0.67.0 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.39.0 // indirect + go.opentelemetry.io/contrib/exporters/autoexport v0.67.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.39.0 // indirect - go.opentelemetry.io/otel/metric v1.39.0 // indirect - go.opentelemetry.io/otel/sdk v1.39.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.39.0 // indirect - go.opentelemetry.io/otel/trace v1.39.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/crypto v0.47.0 // indirect - golang.org/x/mod v0.31.0 // indirect - golang.org/x/net v0.49.0 // indirect - golang.org/x/sync v0.19.0 // indirect - golang.org/x/text v0.33.0 // indirect - golang.org/x/time v0.12.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect + go.opentelemetry.io/otel v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.64.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 // indirect + go.opentelemetry.io/otel/log v0.19.0 // indirect + go.opentelemetry.io/otel/metric v1.43.0 // indirect + go.opentelemetry.io/otel/sdk v1.43.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.19.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect + go.opentelemetry.io/otel/trace v1.43.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect + golang.org/x/crypto v0.49.0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/net v0.52.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/text v0.35.0 // indirect + golang.org/x/time v0.14.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect - google.golang.org/grpc v1.79.3 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 // indirect + google.golang.org/grpc v1.80.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 41fd4b20a6..2dd71c91a7 100644 --- a/go.sum +++ b/go.sum @@ -54,8 +54,8 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 h1:XRzhVemXdgv github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 h1:DHa2U07rk8syqvCge0QIGMCE1WxGj9njT44GH7zNJLQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.53.0 h1:4LP6hvB4I5ouTbGgWtixJhgED6xdf67twf9PoY96Tbg= @@ -70,6 +70,10 @@ github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1o github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alicebob/miniredis/v2 v2.35.0 h1:QwLphYqCEAo1eu1TqPRN2jgVMPBweeQcR21jeqDCONI= +github.com/alicebob/miniredis/v2 v2.35.0/go.mod h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go-v2 v1.42.1 h1:9eOTgu1z/dVtYpNZ3/8/XbbaX0x/BqE3HUzAzs6K0ek= @@ -112,8 +116,19 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.44.0 h1:bLZ0PolJ8J+HkJHztcXORUpHXBye github.com/aws/aws-sdk-go-v2/service/sts v1.44.0/go.mod h1:9gdl4RrflIdpDb2TlXshWgR1F9TeCkvqDx77Vpr4Z/Q= github.com/aws/smithy-go v1.27.3 h1:F3Zb497UhhskkfpJmfkXswyo+t0sh9OTBnIHjogWbVY= github.com/aws/smithy-go v1.27.3/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheggaaa/pb/v3 v3.1.7 h1:2FsIW307kt7A/rz/ZI2lvPO+v3wKazzE4K/0LtTWsOI= @@ -145,6 +160,10 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/distribution/distribution/v3 v3.1.1 h1:KUbk7C8CfaLXy8kbf/hGq9cad/wCoLB6dbWH6DMbmX0= +github.com/distribution/distribution/v3 v3.1.1/go.mod h1:d7lXwZpph0bVcOj4Aqn0nMrWHIwRQGdiV5TLeI+/w6Y= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/cli v28.3.2+incompatible h1:mOt9fcLE7zaACbxW1GeS65RI67wIJrTnqS3hP2huFsY= @@ -153,10 +172,12 @@ github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBi github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v28.3.2+incompatible h1:wn66NJ6pWB1vBZIilP8G3qQPqHy5XymfYn5vsqeA5oA= github.com/docker/docker v28.3.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= -github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= +github.com/docker/docker-credential-helpers v0.9.5 h1:EFNN8DHvaiK8zVqFA2DT6BjXE0GzfLOZ38ggPTKePkY= +github.com/docker/docker-credential-helpers v0.9.5/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-events v0.0.0-20250808211157-605354379745 h1:yOn6Ze6IbYI/KAw2lw/83ELYvZh6hvsygTVkD0dzMC4= +github.com/docker/go-events v0.0.0-20250808211157-605354379745/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -181,6 +202,9 @@ github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3G github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -198,16 +222,22 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k= github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gocomply/scap v0.1.3 h1:QPadOSsvq2IJzENzHdmbDFefAN1GU4iCyfaKMDLWZ6A= github.com/gocomply/scap v0.1.3/go.mod h1:NF0cOw7BC3SibN3O5+oyIMMMKtQNYCRFIMuaW1u7R9c= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= @@ -226,8 +256,12 @@ github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81 github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= github.com/gophercloud/gophercloud/v2 v2.10.0 h1:NRadC0aHNvy4iMoFXj5AFiPmut/Sj3hAPAo9B59VMGc= github.com/gophercloud/gophercloud/v2 v2.10.0/go.mod h1:Ki/ILhYZr/5EPebrPL9Ej+tUg4lqx71/YH2JWVeU+Qk= +github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= +github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -241,6 +275,10 @@ github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVU github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA= github.com/hashicorp/go-version v1.9.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw= +github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU= +github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= +github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24 h1:liMMTbpW34dhU4az1GN0pTPADwNmvoRSeoZ6PItiqnY= @@ -249,16 +287,21 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/clock v1.2.0 h1:eq4kys+NI0PLngzaHEe7AmPT90XMGIEySD1JfV1PDIs= github.com/jmhodges/clock v1.2.0/go.mod h1:qKjhA7x7u/lQpPB1XAqX1b1lCI/w3/fNuYpI/ZjLynI= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -277,6 +320,7 @@ github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6T github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A= github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -290,10 +334,13 @@ github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= @@ -314,6 +361,7 @@ github.com/osbuild/blueprint v1.32.0 h1:5uZ2SDPI+pUdmFn5T5G6H8mUw18wK9NzxQGiJ0QQ github.com/osbuild/blueprint v1.32.0/go.mod h1:zFiI1IULOe85F/OM8YPhHek7YCpWZENJoxZezJgRvto= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= @@ -323,14 +371,33 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/proglottis/gpgme v0.1.4 h1:3nE7YNA70o2aLjcg63tXMOhPD7bplfE5CBdV+hLAm2M= github.com/proglottis/gpgme v0.1.4/go.mod h1:5LoXMgpE4bttgwwdv9bLs/vwqv3qV7F4glEEZ7mRKrM= -github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= -github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= -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/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= +github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos= +github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= +github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= +github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 h1:EaDatTxkdHG+U3Bk4EUr+DZ7fOGwTfezUiUJMaIcaho= +github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5/go.mod h1:fyalQWdtzDBECAQFBJuQe5bzQ02jGd5Qcbgb97Flm7U= +github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 h1:EfpWLLCyXw8PSM2/XNJLjI3Pb27yVE+gIAfeqp8LUCc= +github.com/redis/go-redis/extra/redisotel/v9 v9.0.5/go.mod h1:WZjPDy7VNzn77AAfnAfVjZNvfJTYfPetfZk5yoSTLaQ= +github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= +github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM= +github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -348,6 +415,7 @@ github.com/sigstore/protobuf-specs v0.4.1 h1:5SsMqZbdkcO/DNHudaxuCUEjj6x29tS2Xby github.com/sigstore/protobuf-specs v0.4.1/go.mod h1:+gXR+38nIa2oEupqDdzg4qSBT0Os+sP7oYv6alWewWc= github.com/sigstore/sigstore v1.9.5 h1:Wm1LT9yF4LhQdEMy5A2JeGRHTrAWGjT3ubE5JUSrGVU= github.com/sigstore/sigstore v1.9.5/go.mod h1:VtxgvGqCmEZN9X2zhFSOkfXxvKUjpy8RpUW39oCtoII= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= github.com/smallstep/pkcs7 v0.1.1 h1:x+rPdt2W088V9Vkjho4KtoggyktZJlMduZAtRHm68LU= @@ -364,10 +432,12 @@ github.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xI github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 h1:pnnLyeX7o/5aX8qUQ69P/mLojDqwda8hFOCBTmP/6hw= github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6/go.mod h1:39R/xuhNgVhi+K0/zst4TLrJrVmbm6LVgl4A0+ZFS5M= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -390,40 +460,77 @@ github.com/vbauerster/mpb/v8 v8.10.2/go.mod h1:+Ja4P92E3/CorSZgfDtK46D7AVbDqmBQR github.com/vmware/govmomi v0.52.0 h1:JyxQ1IQdllrY7PJbv2am9mRsv3p9xWlIQ66bv+XnyLw= github.com/vmware/govmomi v0.52.0/go.mod h1:Yuc9xjznU3BH0rr6g7MNS1QGvxnJlE1vOvTJ7Lx7dqI= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= +github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= go.mongodb.org/mongo-driver v1.17.2 h1:gvZyk8352qSfzyZ2UMWcpDpMSGEr1eqE4T793SqyhzM= go.mongodb.org/mongo-driver v1.17.2/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/bridges/prometheus v0.67.0 h1:dkBzNEAIKADEaFnuESzcXvpd09vxvDZsOjx11gjUqLk= +go.opentelemetry.io/contrib/bridges/prometheus v0.67.0/go.mod h1:Z5RIwRkZgauOIfnG5IpidvLpERjhTninpP1dTG2jTl4= go.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK26LAGkNFw7RHv1DhE= go.opentelemetry.io/contrib/detectors/gcp v1.39.0/go.mod h1:t/OGqzHBa5v6RHZwrDBJ2OirWc+4q/w2fTbLZwAKjTk= +go.opentelemetry.io/contrib/exporters/autoexport v0.67.0 h1:4fnRcNpc6YFtG3zsFw9achKn3XgmxPxuMuqIL5rE8e8= +go.opentelemetry.io/contrib/exporters/autoexport v0.67.0/go.mod h1:qTvIHMFKoxW7HXg02gm6/Wofhq5p3Ib/A/NNt1EoBSQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= -go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= -go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= -go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= -go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= -go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= -go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= -go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= -go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= -go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 h1:deI9UQMoGFgrg5iLPgzueqFPHevDl+28YKfSpPTI6rY= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0/go.mod h1:PFx9NgpNUKXdf7J4Q3agRxMs3Y07QhTCVipKmLsMKnU= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0 h1:HIBTQ3VO5aupLKjC90JgMqpezVXwFuq6Ryjn0/izoag= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0/go.mod h1:ji9vId85hMxqfvICA0Jt8JqEdrXaAkcpkI9HPXya0ro= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 h1:MdKucPl/HbzckWWEisiNqMPhRrAOQX8r4jTuGr636gk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0/go.mod h1:RolT8tWtfHcjajEH5wFIZ4Dgh5jpPdFXYV9pTAk/qjc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0 h1:w1K+pCJoPpQifuVpsKamUdn9U0zM3xUziVOqsGksUrY= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0/go.mod h1:HBy4BjzgVE8139ieRI75oXm3EcDN+6GhD88JT1Kjvxg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 h1:88Y4s2C8oTui1LGM6bTWkw0ICGcOLCAI5l6zsD1j20k= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0/go.mod h1:Vl1/iaggsuRlrHf/hfPJPvVag77kKyvrLeD10kpMl+A= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 h1:3iZJKlCZufyRzPzlQhUIWVmfltrXuGyfjREgGP3UUjc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0/go.mod h1:/G+nUPfhq2e+qiXMGxMwumDrP5jtzU+mWN7/sjT2rak= +go.opentelemetry.io/otel/exporters/prometheus v0.64.0 h1:g0LRDXMX/G1SEZtK8zl8Chm4K6GBwRkjPKE36LxiTYs= +go.opentelemetry.io/otel/exporters/prometheus v0.64.0/go.mod h1:UrgcjnarfdlBDP3GjDIJWe6HTprwSazNjwsI+Ru6hro= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 h1:KJVjPD3rcPb98rIs3HznyJlrfx9ge5oJvxxlGR+P/7s= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0/go.mod h1:K3kRa2ckmHWQaTWQdPRHc7qGXASuVuoEQXzrvlA98Ws= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 h1:lSZHgNHfbmQTPfuTmWVkEu8J8qXaQwuV30pjCcAUvP8= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0/go.mod h1:so9ounLcuoRDu033MW/E0AD4hhUjVqswrMF5FoZlBcw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 h1:s/1iRkCKDfhlh1JF26knRneorus8aOwVIDhvYx9WoDw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0/go.mod h1:UI3wi0FXg1Pofb8ZBiBLhtMzgoTm1TYkMvn71fAqDzs= +go.opentelemetry.io/otel/log v0.19.0 h1:KUZs/GOsw79TBBMfDWsXS+KZ4g2Ckzksd1ymzsIEbo4= +go.opentelemetry.io/otel/log v0.19.0/go.mod h1:5DQYeGmxVIr4n0/BcJvF4upsraHjg6vudJJpnkL6Ipk= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/log v0.19.0 h1:scYVLqT22D2gqXItnWiocLUKGH9yvkkeql5dBDiXyko= +go.opentelemetry.io/otel/sdk/log v0.19.0/go.mod h1:vFBowwXGLlW9AvpuF7bMgnNI95LiW10szrOdvzBHlAg= +go.opentelemetry.io/otel/sdk/log/logtest v0.19.0 h1:BEbF7ZBB6qQloV/Ub1+3NQoOUnVtcGkU3XX4Ws3GQfk= +go.opentelemetry.io/otel/sdk/log/logtest v0.19.0/go.mod h1:Lua81/3yM0wOmoHTokLj9y9ADeA02v1naRrVrkAZuKk= +go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= +go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= -golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 h1:9kj3STMvgqy3YA4VQXBrN7925ICMxD5wzMRcgA30588= golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -431,8 +538,10 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= -golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -441,10 +550,12 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= -golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -452,9 +563,12 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -466,8 +580,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -477,8 +591,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= -golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= -golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= +golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= +golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -488,33 +602,34 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= -golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= -golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= -golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= google.golang.org/api v0.248.0 h1:hUotakSkcwGdYUqzCRc5yGYsg4wXxpkKlW5ryVqvC1Y= google.golang.org/api v0.248.0/go.mod h1:yAFUAF56Li7IuIQbTFoLwXTCI6XCFKueOlS7S9e4F9k= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 h1:VPWxll4HlMw1Vs/qXtN7BvhZqsS9cdAittCNvVENElA= +google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 h1:m8qni9SQFH0tJc1X0vmnpw/0t+AImlSvp30sEupozUg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -522,6 +637,7 @@ gopkg.in/ini.v1 v1.67.3 h1:iM9Lhz5MRSGhHVGGwCuzG9KO8PoirCXj/m/qTmOJJQw= gopkg.in/ini.v1 v1.67.3/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/internal/testregistry/testregistry.go b/internal/testregistry/testregistry.go index 51d770d999..a9398d6cd4 100644 --- a/internal/testregistry/testregistry.go +++ b/internal/testregistry/testregistry.go @@ -2,6 +2,7 @@ package testregistry import ( "bytes" + "context" "encoding/base64" "encoding/json" "fmt" @@ -13,6 +14,8 @@ import ( "sync" "time" + "github.com/distribution/distribution/v3/configuration" + "github.com/distribution/distribution/v3/registry/handlers" "github.com/opencontainers/go-digest" "github.com/containers/image/v5/docker/reference" @@ -21,6 +24,8 @@ import ( "github.com/osbuild/image-builder/internal/common" "github.com/osbuild/image-builder/pkg/arch" "github.com/osbuild/image-builder/pkg/container" + + _ "github.com/distribution/distribution/v3/registry/storage/driver/inmemory" ) /* @@ -424,3 +429,26 @@ func (reg *Registry) Resolve(target string, imgArch arch.Arch) (container.Spec, func (reg *Registry) Close() { reg.server.Close() } + +func NewDistributionRegistry() *Registry { + cfg := &configuration.Configuration{ + Storage: configuration.Storage{ + "inmemory": configuration.Parameters{}, // use inmemory storage driver + }, + } + + ctx := context.Background() + regHandler := handlers.NewApp(ctx, cfg) + + ts := httptest.NewTLSServer(regHandler) + + r := &Registry{ + server: ts, + } + + return r +} + +func (r *Registry) Host() string { + return r.server.Listener.Addr().String() +} diff --git a/tools/prepare-source.sh b/tools/prepare-source.sh index 50a24d01c8..0e5079ab52 100755 --- a/tools/prepare-source.sh +++ b/tools/prepare-source.sh @@ -4,7 +4,7 @@ set -eux # Go version must be consistent with image-builder which uses UBI # container that is typically few months behind -GO_VERSION=1.24.12 +GO_VERSION=1.25.14 GO_BINARY=$(go env GOPATH)/bin/go$GO_VERSION # this is the official way to get a different version of golang From f126a6bd4c5abec1403dcb51904eec4913361d62 Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 20 Aug 2026 12:55:53 +0200 Subject: [PATCH 02/21] testregistry: add method to populate with manifest lists Add a method to the new registry that adds a manifest list with 4 random images for testing. --- go.mod | 6 +- go.sum | 6 ++ internal/testregistry/testregistry.go | 105 ++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index d4216bc692..488a98a227 100644 --- a/go.mod +++ b/go.mod @@ -27,6 +27,7 @@ require ( github.com/gobwas/glob v0.2.3 github.com/gocomply/scap v0.1.3 github.com/google/go-cmp v0.7.0 + github.com/google/go-containerregistry v0.20.3 github.com/google/uuid v1.6.0 github.com/gophercloud/gophercloud/v2 v2.10.0 github.com/hashicorp/go-retryablehttp v0.7.8 @@ -90,6 +91,7 @@ require ( github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect github.com/containers/ocicrypt v1.2.1 // indirect github.com/containers/storage v1.59.1 // indirect @@ -99,6 +101,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/distribution/reference v0.6.0 // indirect + github.com/docker/cli v28.3.2+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker v28.3.2+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.5 // indirect @@ -122,7 +125,6 @@ require ( github.com/go-playground/validator/v10 v10.26.0 // indirect github.com/golang-jwt/jwt/v5 v5.3.0 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/go-containerregistry v0.20.3 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect github.com/googleapis/gax-go/v2 v2.15.0 // indirect @@ -147,6 +149,7 @@ require ( github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mattn/go-sqlite3 v1.14.28 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/sys/capability v0.4.0 // indirect github.com/moby/sys/mountinfo v0.7.2 // indirect @@ -157,6 +160,7 @@ require ( github.com/oklog/ulid v1.3.1 // indirect github.com/opencontainers/runtime-spec v1.2.1 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/proglottis/gpgme v0.1.4 // indirect diff --git a/go.sum b/go.sum index 2dd71c91a7..47412475a2 100644 --- a/go.sum +++ b/go.sum @@ -139,6 +139,8 @@ github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8= +github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU= github.com/containers/common v0.64.2 h1:1xepE7QwQggUXxmyQ1Dbh6Cn0yd7ktk14sN3McSWf5I= github.com/containers/common v0.64.2/go.mod h1:o29GfYy4tefUuShm8mOn2AiL5Mpzdio+viHI7n24KJ4= github.com/containers/image/v5 v5.36.2 h1:GcxYQyAHRF/pLqR4p4RpvKllnNL8mOBn0eZnqJbfTwk= @@ -323,6 +325,8 @@ github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxU github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk= @@ -644,6 +648,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= libvirt.org/go/libvirt v1.12005.0 h1:YKHw7kpDu5OXyK1FKzgSfMCXkcQuEnpr7aFGcjs+7pU= libvirt.org/go/libvirt v1.12005.0/go.mod h1:1WiFE8EjZfq+FCVog+rvr1yatKbKZ9FaFMZgEqxEJqQ= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= diff --git a/internal/testregistry/testregistry.go b/internal/testregistry/testregistry.go index a9398d6cd4..af9cfa66eb 100644 --- a/internal/testregistry/testregistry.go +++ b/internal/testregistry/testregistry.go @@ -3,6 +3,7 @@ package testregistry import ( "bytes" "context" + "crypto/tls" "encoding/base64" "encoding/json" "fmt" @@ -16,6 +17,12 @@ import ( "github.com/distribution/distribution/v3/configuration" "github.com/distribution/distribution/v3/registry/handlers" + "github.com/google/go-containerregistry/pkg/name" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/google/go-containerregistry/pkg/v1/empty" + "github.com/google/go-containerregistry/pkg/v1/mutate" + "github.com/google/go-containerregistry/pkg/v1/random" + "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/opencontainers/go-digest" "github.com/containers/image/v5/docker/reference" @@ -452,3 +459,101 @@ func NewDistributionRegistry() *Registry { func (r *Registry) Host() string { return r.server.Listener.Addr().String() } + +// PopulateWithManifestList adds a manifest list (index) to the registry with +// the given ref. The list contains four containers, one for each architecture +// (amd64, arm64, s390x, ppc64le). +// Returns the manifest list digest and a map of all the digests keyed by the architecture. +func (r *Registry) PopulateWithManifestList(containerRef string) (string, map[string]string, error) { + imageRef := r.Host() + "/" + containerRef + + // Generate four random images, one for each architecture + amd64, err := random.Image(1024, 1) + if err != nil { + return "", nil, fmt.Errorf("failed to generate random container image: %w", err) + } + + arm64, err := random.Image(1024, 1) + if err != nil { + return "", nil, fmt.Errorf("failed to generate random container image: %w", err) + } + + s390x, err := random.Image(2014, 1) + if err != nil { + return "", nil, fmt.Errorf("failed to generate random container image: %w", err) + } + + ppc64le, err := random.Image(2014, 1) + if err != nil { + return "", nil, fmt.Errorf("failed to generate random container image: %w", err) + } + + // Add images to an index and define the architecture + index := mutate.AppendManifests(empty.Index, + mutate.IndexAddendum{ + Add: amd64, + Descriptor: v1.Descriptor{ + Platform: &v1.Platform{ + Architecture: "amd64", + OS: "linux", + }, + }, + }, + mutate.IndexAddendum{ + Add: arm64, + Descriptor: v1.Descriptor{ + Platform: &v1.Platform{ + Architecture: "arm64", + OS: "linux", + }, + }, + }, + mutate.IndexAddendum{ + Add: s390x, + Descriptor: v1.Descriptor{ + Platform: &v1.Platform{ + Architecture: "s390x", + OS: "linux", + }, + }, + }, + mutate.IndexAddendum{ + Add: ppc64le, + Descriptor: v1.Descriptor{ + Platform: &v1.Platform{ + Architecture: "ppc64le", + OS: "linux", + }, + }, + }, + ) + + ref, err := name.ParseReference(imageRef) + if err != nil { + return "", nil, fmt.Errorf("failed to parse reference: %w", err) + } + + tr := &http.Transport{ + // disable TLS verification + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // nolint:gosec // this is a test registry + } + + if err := remote.WriteIndex(ref, index, remote.WithTransport(tr)); err != nil { + return "", nil, fmt.Errorf("failed to push image: %w", err) + } + + digests := make(map[string]string, 4) + indexDigest, err := index.Digest() + if err != nil { + return "", nil, err + } + indexManifest, err := index.IndexManifest() + if err != nil { + return "", nil, err + } + for _, imageManifest := range indexManifest.Manifests { + digests[imageManifest.Platform.Architecture] = imageManifest.Digest.String() + } + + return indexDigest.String(), digests, nil +} From 45b32c2b09c29c6a0bece1397915f0caab2cdc5d Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 20 Aug 2026 13:12:52 +0200 Subject: [PATCH 03/21] container: rewrite resolver tests to use new registry Rewrite the resolver tests to use the new test registry functionality. --- pkg/container/resolver_test.go | 92 +++++++++++----------------------- 1 file changed, 30 insertions(+), 62 deletions(-) diff --git a/pkg/container/resolver_test.go b/pkg/container/resolver_test.go index cc9378bd61..75d2f70a5f 100644 --- a/pkg/container/resolver_test.go +++ b/pkg/container/resolver_test.go @@ -7,9 +7,9 @@ import ( "os/exec" "os/user" "testing" - "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/osbuild/image-builder/internal/common" "github.com/osbuild/image-builder/internal/testregistry" @@ -24,51 +24,39 @@ var forceLocal = flag.Bool( ) func TestResolver(t *testing.T) { + require := require.New(t) - registry := testregistry.New() + registry := testregistry.NewDistributionRegistry() defer registry.Close() - repo := registry.AddRepo("library/osbuild") - ref := registry.GetRef("library/osbuild") - - refs := make([]string, 10) - for i := 0; i < len(refs); i++ { - checksum := repo.AddImage( - []testregistry.Blob{testregistry.NewDataBlobFromBase64(testregistry.RootLayer)}, - []string{"amd64", "ppc64le"}, - fmt.Sprintf("image %d", i), - time.Time{}) - - tag := fmt.Sprintf("%d", i) - repo.AddTag(checksum, tag) - refs[i] = fmt.Sprintf("%s:%s", ref, tag) - } - resolver := container.NewResolver("amd64") + digests := make(map[string]map[string]string) // ref -> arch -> digest - for _, r := range refs { - resolver.Add(container.SourceSpec{ - Source: r, - Name: "", - Digest: common.ToPtr(""), - TLSVerify: common.ToPtr(false), - Local: false, - }) + // add 10 manifest lists and then resolve them, verifying the digests we + // get from the resolver + for i := range 10 { + ref := fmt.Sprintf("library/osbuild:%d", i) + _, images, err := registry.PopulateWithManifestList(ref) + require.NoError(err) + digests[ref] = images } - have, err := resolver.Finish() - assert.NoError(t, err) - assert.NotNil(t, have) - - assert.Len(t, have, len(refs)) - - want := make([]container.Spec, len(refs)) - for i, r := range refs { - spec, err := registry.Resolve(r, arch.ARCH_X86_64) - assert.NoError(t, err) - want[i] = spec + for ref, images := range digests { + for arch, digest := range images { + resolver := container.NewResolver(arch) + resolver.Add(container.SourceSpec{ + Source: registry.GetRef(ref), + Name: "", + Digest: common.ToPtr(""), + TLSVerify: common.ToPtr(false), + Local: false, + }) + + have, err := resolver.Finish() + require.NoError(err) + require.NotNil(have) + require.Equal(digest, have[0].Digest) + } } - - assert.ElementsMatch(t, have, want) } func TestResolverFail(t *testing.T) { @@ -85,33 +73,13 @@ func TestResolverFail(t *testing.T) { assert.Error(t, err) assert.Len(t, specs, 0) - registry := testregistry.New() + registry := testregistry.NewDistributionRegistry() defer registry.Close() - resolver.Add(container.SourceSpec{ - Source: registry.GetRef("repo"), - Name: "", - Digest: common.ToPtr(""), - TLSVerify: common.ToPtr(false), - Local: false, - }) - specs, err = resolver.Finish() - assert.Error(t, err) - assert.Len(t, specs, 0) - - resolver.Add(container.SourceSpec{ - Source: registry.GetRef("repo"), - Name: "", - Digest: common.ToPtr(""), - TLSVerify: common.ToPtr(false), - Local: false, - }) - specs, err = resolver.Finish() - assert.Error(t, err) - assert.Len(t, specs, 0) + badRef := fmt.Sprintf("%s/org/notarepo", registry.Host()) resolver.Add(container.SourceSpec{ - Source: registry.GetRef("repo"), + Source: badRef, Name: "", Digest: common.ToPtr(""), TLSVerify: common.ToPtr(false), From 5f4d2559387d0c6bc86f3617ecb19df658312580 Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 20 Aug 2026 13:56:54 +0200 Subject: [PATCH 04/21] testregistry: return image IDs alongside digests Return the image IDs that were created by the PopulateWithManifestList() function alongside the digests for the new images. --- internal/testregistry/testregistry.go | 55 +++++++++++++++++++++++++-- pkg/container/resolver_test.go | 6 +-- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/internal/testregistry/testregistry.go b/internal/testregistry/testregistry.go index af9cfa66eb..224565564f 100644 --- a/internal/testregistry/testregistry.go +++ b/internal/testregistry/testregistry.go @@ -460,11 +460,26 @@ func (r *Registry) Host() string { return r.server.Listener.Addr().String() } +// Image is a simple struct that holds the image ID and digest of a single +// image. +type Image struct { + imageID string + digest string +} + +func (img Image) ImageID() string { + return img.imageID +} + +func (img Image) Digest() string { + return img.digest +} + // PopulateWithManifestList adds a manifest list (index) to the registry with // the given ref. The list contains four containers, one for each architecture // (amd64, arm64, s390x, ppc64le). // Returns the manifest list digest and a map of all the digests keyed by the architecture. -func (r *Registry) PopulateWithManifestList(containerRef string) (string, map[string]string, error) { +func (r *Registry) PopulateWithManifestList(containerRef string) (string, map[string]Image, error) { imageRef := r.Host() + "/" + containerRef // Generate four random images, one for each architecture @@ -472,21 +487,37 @@ func (r *Registry) PopulateWithManifestList(containerRef string) (string, map[st if err != nil { return "", nil, fmt.Errorf("failed to generate random container image: %w", err) } + amd64ImageID, err := amd64.ConfigName() + if err != nil { + return "", nil, err + } arm64, err := random.Image(1024, 1) if err != nil { return "", nil, fmt.Errorf("failed to generate random container image: %w", err) } + arm64ImageID, err := arm64.ConfigName() + if err != nil { + return "", nil, err + } s390x, err := random.Image(2014, 1) if err != nil { return "", nil, fmt.Errorf("failed to generate random container image: %w", err) } + s390xImageID, err := s390x.ConfigName() + if err != nil { + return "", nil, err + } ppc64le, err := random.Image(2014, 1) if err != nil { return "", nil, fmt.Errorf("failed to generate random container image: %w", err) } + ppc64leImageID, err := ppc64le.ConfigName() + if err != nil { + return "", nil, err + } // Add images to an index and define the architecture index := mutate.AppendManifests(empty.Index, @@ -542,7 +573,6 @@ func (r *Registry) PopulateWithManifestList(containerRef string) (string, map[st return "", nil, fmt.Errorf("failed to push image: %w", err) } - digests := make(map[string]string, 4) indexDigest, err := index.Digest() if err != nil { return "", nil, err @@ -551,9 +581,26 @@ func (r *Registry) PopulateWithManifestList(containerRef string) (string, map[st if err != nil { return "", nil, err } + + images := map[string]Image{ + "amd64": { + imageID: amd64ImageID.String(), + }, + "arm64": { + imageID: arm64ImageID.String(), + }, + "s390x": { + imageID: s390xImageID.String(), + }, + "ppc64le": { + imageID: ppc64leImageID.String(), + }, + } for _, imageManifest := range indexManifest.Manifests { - digests[imageManifest.Platform.Architecture] = imageManifest.Digest.String() + image := images[imageManifest.Platform.Architecture] + image.digest = imageManifest.Digest.String() + images[imageManifest.Platform.Architecture] = image } - return indexDigest.String(), digests, nil + return indexDigest.String(), images, nil } diff --git a/pkg/container/resolver_test.go b/pkg/container/resolver_test.go index 75d2f70a5f..010c2b83f0 100644 --- a/pkg/container/resolver_test.go +++ b/pkg/container/resolver_test.go @@ -29,7 +29,7 @@ func TestResolver(t *testing.T) { registry := testregistry.NewDistributionRegistry() defer registry.Close() - digests := make(map[string]map[string]string) // ref -> arch -> digest + digests := make(map[string]map[string]testregistry.Image) // ref -> arch -> digest // add 10 manifest lists and then resolve them, verifying the digests we // get from the resolver @@ -41,7 +41,7 @@ func TestResolver(t *testing.T) { } for ref, images := range digests { - for arch, digest := range images { + for arch, image := range images { resolver := container.NewResolver(arch) resolver.Add(container.SourceSpec{ Source: registry.GetRef(ref), @@ -54,7 +54,7 @@ func TestResolver(t *testing.T) { have, err := resolver.Finish() require.NoError(err) require.NotNil(have) - require.Equal(digest, have[0].Digest) + require.Equal(image.Digest(), have[0].Digest) } } } From 0eb9fbdbea3e05bac27555955d078fbfd16283a5 Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 20 Aug 2026 14:04:06 +0200 Subject: [PATCH 05/21] container: rewrite container client tests to use new registry Rewrite the container client tests to use the new test registry functionality. --- pkg/container/client_test.go | 57 +++++++++++++++--------------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/pkg/container/client_test.go b/pkg/container/client_test.go index 136f78e2d4..2427728d3d 100644 --- a/pkg/container/client_test.go +++ b/pkg/container/client_test.go @@ -9,7 +9,6 @@ import ( "os/user" "path/filepath" "testing" - "time" "github.com/opencontainers/go-digest" "github.com/stretchr/testify/assert" @@ -23,22 +22,19 @@ import ( // func TestClientResolve(t *testing.T) { + require := require.New(t) - registry := testregistry.New() + registry := testregistry.NewDistributionRegistry() defer registry.Close() - repo := registry.AddRepo("library/osbuild") - listDigest := repo.AddImage( - []testregistry.Blob{testregistry.NewDataBlobFromBase64(testregistry.RootLayer)}, - []string{"amd64", "ppc64le"}, - "cool container", - time.Time{}) + listDigest, images, err := registry.PopulateWithManifestList("library/osbuild") + require.NoError(err) ref := registry.GetRef("library/osbuild") client, err := container.NewClient(ref) - assert.NoError(t, err) - assert.NotNil(t, client) + require.NoError(err) + require.NotNil(client) client.SkipTLSVerify() @@ -47,11 +43,11 @@ func TestClientResolve(t *testing.T) { client.SetArchitectureChoice("amd64") spec, err := client.Resolve(ctx, "", false) - assert.NoError(t, err) - assert.Equal(t, container.Spec{ + require.NoError(err) + require.Equal(container.Spec{ Source: ref, - Digest: "sha256:f29b6cd42a94a574583439addcd6694e6224f0e4b32044c9e3aee4c4856c2a50", - ImageID: "sha256:c2ecf25cf190e76b12b07436ad5140d4ba53d8a136d498705e57a006837a720f", + Digest: images["amd64"].Digest(), + ImageID: images["amd64"].ImageID(), TLSVerify: client.GetTLSVerify(), LocalName: client.Target.String(), ListDigest: listDigest, @@ -61,11 +57,11 @@ func TestClientResolve(t *testing.T) { client.SetArchitectureChoice("ppc64le") spec, err = client.Resolve(ctx, "", false) - assert.NoError(t, err) - assert.Equal(t, container.Spec{ + require.NoError(err) + require.Equal(container.Spec{ Source: ref, - Digest: "sha256:d49eebefb6c7ce5505594bef652bd4adc36f413861bd44209d9b9486310b1264", - ImageID: "sha256:d2ab8fea7f08a22f03b30c13c6ea443121f25e87202a7496e93736efa6fe345a", + Digest: images["ppc64le"].Digest(), + ImageID: images["ppc64le"].ImageID(), TLSVerify: client.GetTLSVerify(), LocalName: client.Target.String(), ListDigest: listDigest, @@ -73,10 +69,10 @@ func TestClientResolve(t *testing.T) { }, spec) // don't have that architecture - client.SetArchitectureChoice("s390x") + client.SetArchitectureChoice("riscv64") _, err = client.Resolve(ctx, "", false) - assert.Error(t, err) + require.Error(err) } func TestClientAuthFilePath(t *testing.T) { @@ -460,28 +456,21 @@ func TestParseImageName(t *testing.T) { func TestGetManifest(t *testing.T) { require := require.New(t) - registry := testregistry.New() + registry := testregistry.NewDistributionRegistry() defer registry.Close() - repo := registry.AddRepo("library/osbuild") - listDigest := repo.AddImage( - []testregistry.Blob{testregistry.NewDataBlobFromBase64(testregistry.RootLayer)}, - []string{"amd64", "arm64"}, - "some kind of container", - time.Time{}, - ) + listDigest, images, err := registry.PopulateWithManifestList("library/image-builder") + require.NoError(err) - // These digests were retrieved by manually inspecting the manifest list in - // the registry after adding the images above. - amd64Digest := "sha256:505fe73a6102a624a46a1732e14e47034b9cca6f1ceaa3ef728aefbb2390f026" - arm64Digest := "sha256:28ddcb768b2624aac065aaa4feccb1be3e340054954183c2908a607b1f133478" + amd64Digest := images["amd64"].Digest() + arm64Digest := images["arm64"].Digest() - ref := registry.GetRef("library/osbuild") + ref := registry.GetRef("library/image-builder") client, err := container.NewClient(ref) client.SkipTLSVerify() require.NoError(err) - require.NotNil(t, client) + require.NotNil(client) ctx := t.Context() From 0cbbfafb902ec889f46e4f64778509f62d8fbc1f Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 20 Aug 2026 14:21:51 +0200 Subject: [PATCH 06/21] container: rewrite blocking resolver tests to use new registry Rewrite the blocking resolver tests to use the new test registry functionality. --- pkg/container/blocking_resolver_test.go | 157 ++++++++++-------------- 1 file changed, 62 insertions(+), 95 deletions(-) diff --git a/pkg/container/blocking_resolver_test.go b/pkg/container/blocking_resolver_test.go index 7015593c59..c87be89324 100644 --- a/pkg/container/blocking_resolver_test.go +++ b/pkg/container/blocking_resolver_test.go @@ -6,9 +6,9 @@ import ( "os/exec" "os/user" "testing" - "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/osbuild/image-builder/internal/common" "github.com/osbuild/image-builder/internal/testregistry" @@ -17,95 +17,84 @@ import ( ) func TestBlockingResolver(t *testing.T) { - registry := testregistry.New() + require := require.New(t) + + registry := testregistry.NewDistributionRegistry() defer registry.Close() - repo := registry.AddRepo("library/osbuild") - ref := registry.GetRef("library/osbuild") - - refs := make([]string, 10) - for i := 0; i < len(refs); i++ { - checksum := repo.AddImage( - []testregistry.Blob{testregistry.NewDataBlobFromBase64(testregistry.RootLayer)}, - []string{"amd64", "ppc64le"}, - fmt.Sprintf("image %d", i), - time.Time{}) - - tag := fmt.Sprintf("%d", i) - repo.AddTag(checksum, tag) - refs[i] = fmt.Sprintf("%s:%s", ref, tag) - } - resolver := container.NewBlockingResolver("amd64") + allImages := make(map[string]map[string]testregistry.Image) // ref -> arch -> digest - for _, r := range refs { - resolver.Add(container.SourceSpec{ - Source: r, - Name: "", - Digest: common.ToPtr(""), - TLSVerify: common.ToPtr(false), - Local: false, - }) + // add 10 manifest lists and then resolve them, verifying the digests we + // get from the resolver + for i := range 10 { + ref := fmt.Sprintf("library/osbuild:%d", i) + _, images, err := registry.PopulateWithManifestList(ref) + require.NoError(err) + allImages[ref] = images } - have, err := resolver.Finish() - assert.NoError(t, err) - assert.NotNil(t, have) - - assert.Len(t, have, len(refs)) + for ref, images := range allImages { + for arch, image := range images { + resolver := container.NewBlockingResolver(arch) + resolver.Add(container.SourceSpec{ + Source: registry.GetRef(ref), + Name: "", + Digest: common.ToPtr(""), + TLSVerify: common.ToPtr(false), + Local: false, + }) - want := make([]container.Spec, len(refs)) - for i, r := range refs { - spec, err := registry.Resolve(r, arch.ARCH_X86_64) - assert.NoError(t, err) - want[i] = spec + have, err := resolver.Finish() + require.NoError(err) + require.NotNil(have) + require.Equal(image.Digest(), have[0].Digest) + } } - - assert.ElementsMatch(t, have, want) } func TestBlockingResolverResolveAll(t *testing.T) { - assert := assert.New(t) - registry := testregistry.New() + // Similar test as above but resolving all containers at the same time + require := require.New(t) + + registry := testregistry.NewDistributionRegistry() defer registry.Close() - repo := registry.AddRepo("library/osbuild") - ref := registry.GetRef("library/osbuild") - - sources := make(map[string][]container.SourceSpec, 2) - expected := make(map[string][]container.Spec, 2) - for _, name := range []string{"pipeline-one", "pipeline-two"} { - for idx := 0; idx < 10; idx++ { - checksum := repo.AddImage( - []testregistry.Blob{testregistry.NewDataBlobFromBase64(testregistry.RootLayer)}, - []string{"amd64", "ppc64le"}, - fmt.Sprintf("image %s %d", name, idx), - time.Time{}) - - tag := fmt.Sprintf("%s%d", name, idx) - repo.AddTag(checksum, tag) - - plSources := sources[name] - refTag := fmt.Sprintf("%s:%s", ref, tag) - sources[name] = append(plSources, container.SourceSpec{ - Source: refTag, - Name: "", + + allImages := make(map[string]map[string]testregistry.Image) // ref -> arch -> digest + + for i := range 10 { + ref := fmt.Sprintf("library/osbuild:%d", i) + _, images, err := registry.PopulateWithManifestList(ref) + require.NoError(err) + refWithHost := registry.GetRef(ref) + allImages[refWithHost] = images + } + + // make one resolver for each arch and resolve all container refs for that + // architecture + for _, arch := range []string{"amd64", "arm64", "s390x", "ppc64le"} { + resolver := container.NewBlockingResolver(arch) + + for refWithHost := range allImages { + resolver.Add(container.SourceSpec{ + Source: refWithHost, + Name: refWithHost, Digest: common.ToPtr(""), TLSVerify: common.ToPtr(false), Local: false, }) - - expSpec, err := registry.Resolve(refTag, arch.ARCH_X86_64) - assert.NoError(err) - expSpecs := expected[name] - expected[name] = append(expSpecs, expSpec) } - } - resolver := container.NewBlockingResolver("amd64") + results, err := resolver.Finish() + require.NoError(err) + require.NotNil(results) - have, err := resolver.ResolveAll(sources) - assert.NoError(err) - assert.NotNil(have) - assert.Equal(have, expected) + for _, result := range results { + // the LocalName should be the Name we added to the source spec, which is refWithHost + expImage := allImages[result.LocalName][arch] + require.Equal(expImage.Digest(), result.Digest) + require.Equal(expImage.ImageID(), result.ImageID) + } + } } func TestBlockingResolverFail(t *testing.T) { @@ -122,7 +111,7 @@ func TestBlockingResolverFail(t *testing.T) { assert.Error(t, err) assert.Len(t, specs, 0) - registry := testregistry.New() + registry := testregistry.NewDistributionRegistry() defer registry.Close() resolver.Add(container.SourceSpec{ @@ -135,28 +124,6 @@ func TestBlockingResolverFail(t *testing.T) { specs, err = resolver.Finish() assert.Error(t, err) assert.Len(t, specs, 0) - - resolver.Add(container.SourceSpec{ - Source: registry.GetRef("repo"), - Name: "", - Digest: common.ToPtr(""), - TLSVerify: common.ToPtr(false), - Local: false, - }) - specs, err = resolver.Finish() - assert.Error(t, err) - assert.Len(t, specs, 0) - - resolver.Add(container.SourceSpec{ - Source: registry.GetRef("repo"), - Name: "", - Digest: common.ToPtr(""), - TLSVerify: common.ToPtr(false), - Local: false, - }) - specs, err = resolver.Finish() - assert.Error(t, err) - assert.Len(t, specs, 0) } func TestBlockingResolverLocalManifest(t *testing.T) { From 5587254bb3c7aea0b36a5a388000391a0066b34b Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 20 Aug 2026 14:22:49 +0200 Subject: [PATCH 07/21] container: adapt TestBlockingResolverResolveAll() for async resolver Adapt the blocking resolver test that resolves multiple containers at once to test the async resolver as well. --- pkg/container/resolver_test.go | 45 ++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/pkg/container/resolver_test.go b/pkg/container/resolver_test.go index 010c2b83f0..6324bee230 100644 --- a/pkg/container/resolver_test.go +++ b/pkg/container/resolver_test.go @@ -59,6 +59,51 @@ func TestResolver(t *testing.T) { } } +func TestResolverResolveAll(t *testing.T) { + // Similar test as above but resolving all containers at the same time + require := require.New(t) + + registry := testregistry.NewDistributionRegistry() + defer registry.Close() + + allImages := make(map[string]map[string]testregistry.Image) // ref -> arch -> digest + + for i := range 10 { + ref := fmt.Sprintf("library/osbuild:%d", i) + _, images, err := registry.PopulateWithManifestList(ref) + require.NoError(err) + refWithHost := registry.GetRef(ref) + allImages[refWithHost] = images + } + + // make one resolver for each arch and resolve all container refs for that + // architecture + for _, arch := range []string{"amd64", "arm64", "s390x", "ppc64le"} { + resolver := container.NewResolver(arch) + + for refWithHost := range allImages { + resolver.Add(container.SourceSpec{ + Source: refWithHost, + Name: refWithHost, + Digest: common.ToPtr(""), + TLSVerify: common.ToPtr(false), + Local: false, + }) + } + + results, err := resolver.Finish() + require.NoError(err) + require.NotNil(results) + + for _, result := range results { + // the LocalName should be the Name we added to the source spec, which is refWithHost + expImage := allImages[result.LocalName][arch] + require.Equal(expImage.Digest(), result.Digest) + require.Equal(expImage.ImageID(), result.ImageID) + } + } +} + func TestResolverFail(t *testing.T) { resolver := container.NewResolver("amd64") From 5402fbc77fadfa4ff8f03f2d0444cfcd8128f9ef Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 20 Aug 2026 14:27:34 +0200 Subject: [PATCH 08/21] testregistry: drop old registry implementation Drop the old registry implementation that maintained its own internal container repositories. Everything is handled by the new implementation now. --- internal/testregistry/testregistry.go | 422 +----------------------- pkg/container/blocking_resolver_test.go | 6 +- pkg/container/client_test.go | 4 +- pkg/container/resolver_test.go | 6 +- 4 files changed, 16 insertions(+), 422 deletions(-) diff --git a/internal/testregistry/testregistry.go b/internal/testregistry/testregistry.go index 224565564f..574bb54c9f 100644 --- a/internal/testregistry/testregistry.go +++ b/internal/testregistry/testregistry.go @@ -1,19 +1,11 @@ package testregistry import ( - "bytes" "context" "crypto/tls" - "encoding/base64" - "encoding/json" "fmt" - "io" "net/http" "net/http/httptest" - "os" - "strings" - "sync" - "time" "github.com/distribution/distribution/v3/configuration" "github.com/distribution/distribution/v3/registry/handlers" @@ -23,421 +15,15 @@ import ( "github.com/google/go-containerregistry/pkg/v1/mutate" "github.com/google/go-containerregistry/pkg/v1/random" "github.com/google/go-containerregistry/pkg/v1/remote" - "github.com/opencontainers/go-digest" - - "github.com/containers/image/v5/docker/reference" - "github.com/containers/image/v5/manifest" - - "github.com/osbuild/image-builder/internal/common" - "github.com/osbuild/image-builder/pkg/arch" - "github.com/osbuild/image-builder/pkg/container" _ "github.com/distribution/distribution/v3/registry/storage/driver/inmemory" ) -/* -A base64 encoded gzipped tarball with the following contents: - - -rw-r--r-- root/root 12 2021-09-17 12:32 hello.txt (Contents: "Hello World") - drwxr-xr-x root/root 0 1970-01-01 01:00 subdir/ - -rw-r--r-- root/root 8 2021-09-17 12:32 subdir/file.txt (Contents: "osbuild") - -rw-r--r-- root/root 7 2021-09-17 12:32 world.txt (Contents: "hello!") - -Can be used with [NewDataBlobFromBase64] to create a data blob for [Repo.AddImage]. -*/ -const RootLayer = `H4sIAAAJbogA/+SWUYqDMBCG53lP4V5g9x8dzRX2Bvtc0VIhEIhKe/wSKxgU6ktjC/O9hMzAQDL8 -/8yltdb9DLeB0gEGKhHCg/UJsBAL54zKFBAC54ZzyrCUSMfYDydPgHfu6R/s5VePilOfzF/of/bv -vG2+lqhyFNGPddP53yjyegCBKcuNROZ77AmBoP+CmbIyqpEM5fqf+3/ubJtsCuz7P1b+L1Du/4f5 -v+vrsVPu/Vq9P3ANk//d+x/MZv8TKNf/Qfqf9v9v5fLXK3/lKEc5ypm4AwAA//8DAE6E6nIAEgAA -` - -// The following code implements a toy container registry to test with - -// Blob interface -type Blob interface { - GetSize() int64 - GetMediaType() string - GetDigest() digest.Digest - - Reader() io.Reader -} - -// dataBlob // -type dataBlob struct { - Data []byte - MediaType string -} - -func NewDataBlobFromBase64(text string) dataBlob { - data, err := base64.StdEncoding.DecodeString(text) - - if err != nil { - panic("decoding of text failed") - } - - return dataBlob{ - Data: data, - } -} - -// Blob interface implementation -func (b dataBlob) GetSize() int64 { - return int64(len(b.Data)) -} - -func (b dataBlob) GetMediaType() string { - if b.MediaType != "" { - return b.MediaType - } - - return manifest.DockerV2Schema2LayerMediaType -} - -func (b dataBlob) GetDigest() digest.Digest { - return digest.FromBytes(b.Data) -} - -func (b dataBlob) Reader() io.Reader { - return bytes.NewReader(b.Data) -} - -func MakeDescriptorForBlob(b Blob) manifest.Schema2Descriptor { - return manifest.Schema2Descriptor{ - MediaType: b.GetMediaType(), - Size: b.GetSize(), - Digest: b.GetDigest(), - } -} - -// SyncMap is a very simple generic map with concurrency-safe accessors. -type SyncMap[T any] struct { - mappy map[string]T - mutex sync.Mutex -} - -func (sm *SyncMap[T]) Add(name string, elem T) { - sm.mutex.Lock() - defer sm.mutex.Unlock() - if sm.mappy == nil { - // magically handle initialising the map on first Add(). - sm.mappy = make(map[string]T) - } - - sm.mappy[name] = elem -} - -func (sm *SyncMap[T]) Get(name string) (T, bool) { - sm.mutex.Lock() - defer sm.mutex.Unlock() - - elem, ok := sm.mappy[name] - return elem, ok -} - -// Repo // -type Repo struct { - blobs SyncMap[Blob] - manifests SyncMap[*manifest.Schema2] - images SyncMap[*manifest.Schema2List] - tags SyncMap[string] -} - -func NewRepo() *Repo { - return &Repo{ - blobs: SyncMap[Blob]{}, - manifests: SyncMap[*manifest.Schema2]{}, - images: SyncMap[*manifest.Schema2List]{}, - tags: SyncMap[string]{}, - } -} - -func (r *Repo) AddBlob(b Blob) manifest.Schema2Descriptor { - desc := MakeDescriptorForBlob(b) - r.blobs.Add(desc.Digest.String(), b) - return desc -} - -func (r *Repo) AddObject(v interface{}, mediaType string) manifest.Schema2Descriptor { - data, err := json.MarshalIndent(v, "", " ") - if err != nil { - panic("could not marshal image object") - } - - blob := dataBlob{ - Data: data, - MediaType: mediaType, - } - - return r.AddBlob(blob) -} - -func (r *Repo) AddManifest(mf *manifest.Schema2) manifest.Schema2Descriptor { - desc := r.AddObject(mf, mf.MediaType) - - r.manifests.Add(desc.Digest.String(), mf) - - return desc -} - -func (r *Repo) AddImage(layers []Blob, arches []string, comment string, ctime time.Time) string { - - blobs := make([]manifest.Schema2Descriptor, len(layers)) - - for i, layer := range layers { - blobs[i] = r.AddBlob(layer) - } - - manifests := make([]manifest.Schema2ManifestDescriptor, len(arches)) - - for i, arch := range arches { - img := manifest.Schema2V1Image{ - Architecture: arch, - OS: "linux", - Author: "osbuild", - Comment: comment, - Created: ctime, - } - - // Add the config object - config := r.AddObject(img, manifest.DockerV2Schema2ConfigMediaType) - - // make and add the manifest object - schema := manifest.Schema2FromComponents(config, blobs) - mf := r.AddManifest(schema) - - desc := manifest.Schema2ManifestDescriptor{ - Schema2Descriptor: mf, - Platform: manifest.Schema2PlatformSpec{ - Architecture: arch, - OS: "linux", - }, - } - - manifests[i] = desc - } - - list := manifest.Schema2ListFromComponents(manifests) - desc := r.AddObject(list, list.MediaType) - checksum := desc.Digest.String() - - r.images.Add(checksum, list) - r.tags.Add("latest", checksum) - - return checksum -} - -func (r *Repo) AddTag(checksum, tag string) { - - if _, ok := r.images.Get(checksum); !ok { - panic("cannot tag: image not found: " + checksum) - } - - r.tags.Add(tag, checksum) -} - -func WriteBlob(blob Blob, w http.ResponseWriter) { - w.Header().Add("Content-Type", blob.GetMediaType()) - w.Header().Add("Content-Length", fmt.Sprintf("%d", blob.GetSize())) - w.Header().Add("Docker-Content-Digest", blob.GetDigest().String()) - w.WriteHeader(http.StatusOK) - - reader := blob.Reader() - - _, err := io.Copy(w, reader) - if err != nil { - fmt.Fprintf(os.Stderr, "error writing blob: %v", err) - } -} - -func BlobIsManifest(blob Blob) bool { - mt := blob.GetMediaType() - return mt == manifest.DockerV2Schema2MediaType || mt == manifest.DockerV2ListMediaType -} - -func (r *Repo) ServeManifest(ref string, w http.ResponseWriter, req *http.Request) { - if checksum, ok := r.tags.Get(ref); ok { - ref = checksum - } - - blob, ok := r.blobs.Get(ref) - if !ok || !BlobIsManifest(blob) { - fmt.Fprintf(os.Stderr, "manifest %s not found", ref) - http.NotFound(w, req) - return - } - - WriteBlob(blob, w) -} - -func (r *Repo) ServeBlob(ref string, w http.ResponseWriter, req *http.Request) { - - blob, ok := r.blobs.Get(ref) - - if !ok { - fmt.Fprintf(os.Stderr, "blob %s not found", ref) - http.NotFound(w, req) - return - } - - WriteBlob(blob, w) -} - -// Registry // - type Registry struct { server *httptest.Server - repos SyncMap[*Repo] -} - -func (reg *Registry) ServeHTTP(w http.ResponseWriter, req *http.Request) { - - parts := strings.SplitN(req.URL.Path, "?", 1) - paths := strings.Split(strings.Trim(parts[0], "/"), "/") - - // Possbile routes - // [1] version-check: /v2/ - // [2] blobs: /v2//blobs/ - // [3] manifest: /v2//manifests/ - // - // we need at least 4 path components and path has to start with "/v2" - - if len(paths) < 1 || paths[0] != "v2" { - http.NotFound(w, req) - return - } - - // [1] version check - if len(paths) == 1 { - w.WriteHeader(200) - return - } else if len(paths) < 4 { - http.NotFound(w, req) - return - } - - // we asserted that we have at least 4 path components - ref := paths[len(paths)-1] - cmd := paths[len(paths)-2] - - repoName := strings.Join(paths[1:len(paths)-2], "/") - - repo, ok := reg.repos.Get(repoName) - if !ok { - fmt.Fprintf(os.Stderr, "repo %s not found", repoName) - http.NotFound(w, req) - return - } - - switch cmd { - case "manifests": - repo.ServeManifest(ref, w, req) - case "blobs": - repo.ServeBlob(ref, w, req) - default: - http.NotFound(w, req) - } } func New() *Registry { - - reg := &Registry{ - repos: SyncMap[*Repo]{ - mappy: make(map[string]*Repo), - }, - } - reg.server = httptest.NewTLSServer(reg) - - return reg -} - -func (reg *Registry) AddRepo(name string) *Repo { - repo := NewRepo() - reg.repos.Add(name, repo) - return repo -} - -func (reg *Registry) GetRef(repo string) string { - return fmt.Sprintf("%s/%s", reg.server.Listener.Addr().String(), repo) -} - -func (reg *Registry) Resolve(target string, imgArch arch.Arch) (container.Spec, error) { - - ref, err := reference.ParseNormalizedNamed(target) - if err != nil { - return container.Spec{}, fmt.Errorf("failed to parse '%s': %w", target, err) - } - - domain := reference.Domain(ref) - - tag := "latest" - var checksum string - - if tagged, ok := ref.(reference.NamedTagged); ok { - tag = tagged.Tag() - } - - if digested, ok := ref.(reference.Digested); ok { - checksum = string(digested.Digest()) - } - - if domain != reg.server.Listener.Addr().String() { - return container.Spec{}, fmt.Errorf("unknown domain") - } - - ref = reference.TrimNamed(ref) - path := reference.Path(ref) - - repo, ok := reg.repos.Get(path) - if !ok { - return container.Spec{}, fmt.Errorf("unknown repo") - } - - if checksum == "" { - checksum, ok = repo.tags.Get(tag) - if !ok { - return container.Spec{}, fmt.Errorf("unknown tag") - } - } - - lst, ok := repo.images.Get(checksum) - listDigest := checksum - - if ok { - checksum = "" - - for _, m := range lst.Manifests { - if common.Must(arch.FromString(m.Platform.Architecture)) == imgArch { - checksum = m.Digest.String() - break - } - } - - if checksum == "" { - return container.Spec{}, fmt.Errorf("unsupported architecture") - } - } - - mf, ok := repo.manifests.Get(checksum) - if !ok { - return container.Spec{}, fmt.Errorf("unknown digest") - } - - return container.Spec{ - Source: ref.String(), - Digest: checksum, - ImageID: mf.ConfigDescriptor.Digest.String(), - LocalName: target, - TLSVerify: common.ToPtr(false), - ListDigest: listDigest, - Arch: imgArch, - }, nil -} - -func (reg *Registry) Close() { - reg.server.Close() -} - -func NewDistributionRegistry() *Registry { cfg := &configuration.Configuration{ Storage: configuration.Storage{ "inmemory": configuration.Parameters{}, // use inmemory storage driver @@ -456,6 +42,14 @@ func NewDistributionRegistry() *Registry { return r } +func (reg *Registry) Close() { + reg.server.Close() +} + +func (reg *Registry) GetRef(repo string) string { + return fmt.Sprintf("%s/%s", reg.server.Listener.Addr().String(), repo) +} + func (r *Registry) Host() string { return r.server.Listener.Addr().String() } diff --git a/pkg/container/blocking_resolver_test.go b/pkg/container/blocking_resolver_test.go index c87be89324..3cc9422874 100644 --- a/pkg/container/blocking_resolver_test.go +++ b/pkg/container/blocking_resolver_test.go @@ -19,7 +19,7 @@ import ( func TestBlockingResolver(t *testing.T) { require := require.New(t) - registry := testregistry.NewDistributionRegistry() + registry := testregistry.New() defer registry.Close() allImages := make(map[string]map[string]testregistry.Image) // ref -> arch -> digest @@ -56,7 +56,7 @@ func TestBlockingResolverResolveAll(t *testing.T) { // Similar test as above but resolving all containers at the same time require := require.New(t) - registry := testregistry.NewDistributionRegistry() + registry := testregistry.New() defer registry.Close() allImages := make(map[string]map[string]testregistry.Image) // ref -> arch -> digest @@ -111,7 +111,7 @@ func TestBlockingResolverFail(t *testing.T) { assert.Error(t, err) assert.Len(t, specs, 0) - registry := testregistry.NewDistributionRegistry() + registry := testregistry.New() defer registry.Close() resolver.Add(container.SourceSpec{ diff --git a/pkg/container/client_test.go b/pkg/container/client_test.go index 2427728d3d..ebeb846e7b 100644 --- a/pkg/container/client_test.go +++ b/pkg/container/client_test.go @@ -24,7 +24,7 @@ import ( func TestClientResolve(t *testing.T) { require := require.New(t) - registry := testregistry.NewDistributionRegistry() + registry := testregistry.New() defer registry.Close() listDigest, images, err := registry.PopulateWithManifestList("library/osbuild") @@ -456,7 +456,7 @@ func TestParseImageName(t *testing.T) { func TestGetManifest(t *testing.T) { require := require.New(t) - registry := testregistry.NewDistributionRegistry() + registry := testregistry.New() defer registry.Close() listDigest, images, err := registry.PopulateWithManifestList("library/image-builder") diff --git a/pkg/container/resolver_test.go b/pkg/container/resolver_test.go index 6324bee230..5d2de34c2a 100644 --- a/pkg/container/resolver_test.go +++ b/pkg/container/resolver_test.go @@ -26,7 +26,7 @@ var forceLocal = flag.Bool( func TestResolver(t *testing.T) { require := require.New(t) - registry := testregistry.NewDistributionRegistry() + registry := testregistry.New() defer registry.Close() digests := make(map[string]map[string]testregistry.Image) // ref -> arch -> digest @@ -63,7 +63,7 @@ func TestResolverResolveAll(t *testing.T) { // Similar test as above but resolving all containers at the same time require := require.New(t) - registry := testregistry.NewDistributionRegistry() + registry := testregistry.New() defer registry.Close() allImages := make(map[string]map[string]testregistry.Image) // ref -> arch -> digest @@ -118,7 +118,7 @@ func TestResolverFail(t *testing.T) { assert.Error(t, err) assert.Len(t, specs, 0) - registry := testregistry.NewDistributionRegistry() + registry := testregistry.New() defer registry.Close() badRef := fmt.Sprintf("%s/org/notarepo", registry.Host()) From 16608388205ea1d6299088ffd15f89bc6fbccd1d Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Fri, 14 Aug 2026 21:22:39 +0200 Subject: [PATCH 09/21] osbuild-upload-container: test with the new registry Use the new testregistry to upload a container using osbuild-upload-container and verify that it was uploaded successfully by resolving the container using our own resolver. The main() function of the osbuild-upload-resolver is split into an upload() function that does the main work so it can be testable. The main() function now only handles command line flags and then calls into the new function. --- cmd/osbuild-upload-container/main.go | 62 ++++++----- cmd/osbuild-upload-container/main_test.go | 122 ++++++++++++++++++++++ 2 files changed, 155 insertions(+), 29 deletions(-) create mode 100644 cmd/osbuild-upload-container/main_test.go diff --git a/cmd/osbuild-upload-container/main.go b/cmd/osbuild-upload-container/main.go index f0fbd8551f..adc778c712 100644 --- a/cmd/osbuild-upload-container/main.go +++ b/cmd/osbuild-upload-container/main.go @@ -11,31 +11,10 @@ import ( "github.com/osbuild/image-builder/pkg/container" ) -func main() { - var filename string - var destination string - var username string - var password string - var tag string - var ignoreTLS bool - - flag.StringVar(&filename, "container", "", "path to the oci-archive to upload (required)") - flag.StringVar(&destination, "destination", "", "destination to upload to (required)") - flag.StringVar(&tag, "tag", "", "destination tag to use for the container") - flag.StringVar(&username, "username", "", "username to use for registry") - flag.StringVar(&password, "password", "", "password to use for registry") - flag.BoolVar(&ignoreTLS, "ignore-tls", false, "ignore tls verification for destination") - flag.Parse() - - if filename == "" || destination == "" { - flag.Usage() - os.Exit(1) - } - +func upload(filename, destination, tag, username, password string, ignoreTLS bool) error { absPath, err := filepath.Abs(filename) if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - return + return err } fmt.Println("Container to upload is:", filename) @@ -43,16 +22,14 @@ func main() { client, err := container.NewClient(destination) if err != nil { - fmt.Fprintf(os.Stderr, "error creating the upload client: %v\n", err) - os.Exit(1) + return fmt.Errorf("error creating the upload client: %w", err) } if password != "" { if username == "" { u, err := user.Current() if err != nil { - fmt.Fprintf(os.Stderr, "error looking up current user: %v\n", err) - os.Exit(1) + return fmt.Errorf("error looking up current user: %w", err) } username = u.Username } @@ -70,9 +47,36 @@ func main() { digest, err := client.UploadImage(ctx, from, tag) if err != nil { - fmt.Fprintf(os.Stderr, "error uploading: %v\n", err) - os.Exit(1) + return fmt.Errorf("error uploading: %w", err) } fmt.Printf("upload done; destination manifest: %s\n", digest.String()) + return nil +} + +func main() { + var filename string + var destination string + var username string + var password string + var tag string + var ignoreTLS bool + + flag.StringVar(&filename, "container", "", "path to the oci-archive to upload (required)") + flag.StringVar(&destination, "destination", "", "destination to upload to (required)") + flag.StringVar(&tag, "tag", "", "destination tag to use for the container") + flag.StringVar(&username, "username", "", "username to use for registry") + flag.StringVar(&password, "password", "", "password to use for registry") + flag.BoolVar(&ignoreTLS, "ignore-tls", false, "ignore tls verification for destination") + flag.Parse() + + if filename == "" || destination == "" { + flag.Usage() + os.Exit(1) + } + + if err := upload(filename, destination, tag, username, password, ignoreTLS); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } } diff --git a/cmd/osbuild-upload-container/main_test.go b/cmd/osbuild-upload-container/main_test.go new file mode 100644 index 0000000000..a619dfe3ae --- /dev/null +++ b/cmd/osbuild-upload-container/main_test.go @@ -0,0 +1,122 @@ +package main + +import ( + "archive/tar" + "io" + "os" + "path/filepath" + "testing" + + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/google/go-containerregistry/pkg/v1/empty" + "github.com/google/go-containerregistry/pkg/v1/layout" + "github.com/google/go-containerregistry/pkg/v1/mutate" + "github.com/google/go-containerregistry/pkg/v1/random" + "github.com/osbuild/image-builder/internal/common" + "github.com/osbuild/image-builder/internal/testregistry" + "github.com/osbuild/image-builder/pkg/container" + "github.com/stretchr/testify/require" +) + +// randOCIArchive generates a random container image and saves it to the given +// path as an OCI archive. Returns the generated image. +func randOCIArchive(t *testing.T, path string) v1.Image { + t.Helper() + + image, err := random.Image(1024, 1) + if err != nil { + t.Fatal(err) + } + + cfg, err := image.ConfigFile() + if err != nil { + t.Fatal(err) + } + cfg.OS = "linux" + cfg.Architecture = "arm64" + image, err = mutate.ConfigFile(image, cfg) + if err != nil { + t.Fatal(err) + } + + layoutDir := t.TempDir() + layoutPath, err := layout.Write(layoutDir, empty.Index) + if err != nil { + t.Fatal(err) + } + if err := layoutPath.AppendImage(image); err != nil { + t.Fatal(err) + } + + outFile, err := os.Create(path) + if err != nil { + t.Fatal(err) + } + defer outFile.Close() + + tw := tar.NewWriter(outFile) + defer tw.Close() + + err = filepath.Walk(layoutDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + rel, _ := filepath.Rel(layoutDir, path) + hdr, err := tar.FileInfoHeader(info, "") + if err != nil { + return err + } + hdr.Name = rel + if err := tw.WriteHeader(hdr); err != nil { + return err + } + if info.IsDir() { + return nil + } + f, err := os.Open(path) // nolint:gosec // path symlink traversal is not an issue here + if err != nil { + return err + } + defer f.Close() + _, err = io.Copy(tw, f) + return err + }) + if err != nil { + t.Fatal(err) + } + + return image +} + +func TestSimpleUpload(t *testing.T) { + ref := "test/osbuild:latest" + require := require.New(t) + registry := testregistry.New() + defer registry.Close() + + pushRef := registry.GetRef(ref) + + tmpdir := t.TempDir() + archivePath := filepath.Join(tmpdir, "container.tar") + + image := randOCIArchive(t, archivePath) + require.NoError(upload(archivePath, pushRef, "latest", "", "", true)) + + // use our own resolver to verify the uploaded image + resolver := container.NewBlockingResolver("arm64") + spec := container.SourceSpec{ + Source: pushRef, + TLSVerify: common.ToPtr(false), + } + res, err := resolver.Resolve(spec) + require.NoError(err) + require.NotNil(res) + + digest, err := image.Digest() + require.NoError(err) + require.Equal(digest.String(), res.Digest) + + config, err := image.ConfigName() + require.NoError(err) + require.Equal(config.String(), res.ImageID) +} From 2200e8b0bb839b7f5b42f05e2b52ad2cea7bcf4b Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 20 Aug 2026 17:12:51 +0200 Subject: [PATCH 10/21] testregistry: support setting basic auth Support starting the registry with basic auth (username and password). --- internal/testregistry/testregistry.go | 37 ++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/internal/testregistry/testregistry.go b/internal/testregistry/testregistry.go index 574bb54c9f..7b0afd0ba0 100644 --- a/internal/testregistry/testregistry.go +++ b/internal/testregistry/testregistry.go @@ -19,11 +19,42 @@ import ( _ "github.com/distribution/distribution/v3/registry/storage/driver/inmemory" ) +type credentials struct { + username string + password string +} + type Registry struct { server *httptest.Server } func New() *Registry { + return newRegistry(nil) +} + +func NewWithCredentials(user, pass string) *Registry { + return newRegistry( + &credentials{ + username: user, + password: pass, + }, + ) +} + +// basicAuthMiddleware intercepts requests to enforce credentials +func basicAuthMiddleware(next http.Handler, creds credentials) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + user, pass, ok := r.BasicAuth() + if !ok || user != creds.username || pass != creds.password { + w.Header().Set("WWW-Authenticate", `Basic realm="Registry"`) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + next.ServeHTTP(w, r) + }) +} + +func newRegistry(creds *credentials) *Registry { cfg := &configuration.Configuration{ Storage: configuration.Storage{ "inmemory": configuration.Parameters{}, // use inmemory storage driver @@ -32,8 +63,12 @@ func New() *Registry { ctx := context.Background() regHandler := handlers.NewApp(ctx, cfg) + var handler http.Handler = regHandler + if creds != nil { + handler = basicAuthMiddleware(handler, *creds) + } - ts := httptest.NewTLSServer(regHandler) + ts := httptest.NewTLSServer(handler) r := &Registry{ server: ts, From 9e9cd8339365bcf69ed504e0f6710e3d1ac262cc Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 20 Aug 2026 17:13:31 +0200 Subject: [PATCH 11/21] osbuild-upload-container: test with credentials Test uploading a container with credentials (username and password). --- cmd/osbuild-upload-container/main_test.go | 61 +++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/cmd/osbuild-upload-container/main_test.go b/cmd/osbuild-upload-container/main_test.go index a619dfe3ae..a6d58222d3 100644 --- a/cmd/osbuild-upload-container/main_test.go +++ b/cmd/osbuild-upload-container/main_test.go @@ -4,6 +4,7 @@ import ( "archive/tar" "io" "os" + "os/exec" "path/filepath" "testing" @@ -120,3 +121,63 @@ func TestSimpleUpload(t *testing.T) { require.NoError(err) require.Equal(config.String(), res.ImageID) } + +// writeAuthFile shells out to skopeo to write the auth file in the +// containers-auth.json format. +func writeAuthFile(t *testing.T, path, registry, user, pass string) { + t.Helper() + cmd := exec.Command( + "skopeo", + "login", + "--tls-verify=false", + "--authfile", path, + "--username", user, + "--password", pass, + registry, + ) + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("failed to write auth file: %s (%v)", string(out), err) + } +} + +func TestUploadWithCredentials(t *testing.T) { + ref := "test2/osbuild:latest" + user := "me" + pass := "osbuild1337" + + require := require.New(t) + registry := testregistry.NewWithCredentials(user, pass) + defer registry.Close() + + pushRef := registry.GetRef(ref) + + tmpdir := t.TempDir() + archivePath := filepath.Join(tmpdir, "container.tar") + + image := randOCIArchive(t, archivePath) + require.NoError(upload(archivePath, pushRef, "latest", user, pass, true)) + + // use our own resolver to verify the uploaded image + resolver := container.NewBlockingResolver("arm64") + + authFilePath := filepath.Join(tmpdir, "auth.json") + writeAuthFile(t, authFilePath, registry.Host(), user, pass) + resolver.SetAuthFilePath(authFilePath) + + spec := container.SourceSpec{ + Source: pushRef, + TLSVerify: common.ToPtr(false), + } + res, err := resolver.Resolve(spec) + require.NoError(err) + require.NotNil(res) + + digest, err := image.Digest() + require.NoError(err) + require.Equal(digest.String(), res.Digest) + + config, err := image.ConfigName() + require.NoError(err) + require.Equal(config.String(), res.ImageID) +} From 8ab60a9e658dbb190a19d4cd5f2cee0d4e8b69dc Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 20 Aug 2026 18:32:44 +0200 Subject: [PATCH 12/21] container: rewrite UploadImage() to use skopeo copy Rewrite the container UploadImage() function to shell out to skopeo copy. It takes care of all the options we currently support by converting them to command line options. The functionality is tested by the new osbuild-upload-container tests. --- go.mod | 11 +---- go.sum | 82 ---------------------------------- pkg/container/client.go | 99 +++++++++++++++++++++-------------------- 3 files changed, 52 insertions(+), 140 deletions(-) diff --git a/go.mod b/go.mod index 488a98a227..2ebb82ada8 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/ec2 v1.316.0 github.com/aws/aws-sdk-go-v2/service/s3 v1.105.0 github.com/cheggaaa/pb/v3 v3.1.7 - github.com/containers/common v0.64.2 github.com/containers/image/v5 v5.36.2 github.com/distribution/distribution/v3 v3.1.1 github.com/gobwas/glob v0.2.3 @@ -71,7 +70,6 @@ require ( github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 // indirect github.com/IBM/go-sdk-core/v5 v5.21.0 // indirect github.com/VividCortex/ewma v1.2.0 // indirect - github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.14 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.30 // indirect @@ -114,6 +112,7 @@ require ( github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect github.com/go-jose/go-jose/v4 v4.1.4 // indirect github.com/go-logr/logr v1.4.3 // indirect @@ -124,16 +123,13 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.26.0 // indirect github.com/golang-jwt/jwt/v5 v5.3.0 // indirect - github.com/golang/protobuf v1.5.4 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect github.com/googleapis/gax-go/v2 v2.15.0 // indirect github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru/arc/v2 v2.0.5 // indirect github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -147,8 +143,6 @@ require ( github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/mattn/go-sqlite3 v1.14.28 // indirect - github.com/miekg/pkcs11 v1.1.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/sys/capability v0.4.0 // indirect @@ -179,14 +173,11 @@ require ( github.com/sigstore/protobuf-specs v0.4.1 // indirect github.com/sigstore/sigstore v1.9.5 // indirect github.com/sirupsen/logrus v1.9.4 // indirect - github.com/smallstep/pkcs7 v0.1.1 // indirect github.com/sony/gobreaker v0.4.2-0.20210216022020-dd874f9dd33b // indirect github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect - github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 // indirect github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect github.com/ulikunitz/xz v0.5.15 // indirect github.com/vbatts/tar-split v0.12.1 // indirect - github.com/vbauerster/mpb/v8 v8.10.2 // indirect go.mongodb.org/mongo-driver v1.17.2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/bridges/prometheus v0.67.0 // indirect diff --git a/go.sum b/go.sum index 47412475a2..d339870b3f 100644 --- a/go.sum +++ b/go.sum @@ -68,8 +68,6 @@ github.com/IBM/ibm-cos-sdk-go v1.12.3 h1:kMIs1nfPY0UXAMcW6bq8O9WOd6KgqiDBnIMd0e/ github.com/IBM/ibm-cos-sdk-go v1.12.3/go.mod h1:dt13UIqJRgfGIlSNlnf17JmAXlBXhfTgXLKV3as8ABk= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= -github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= -github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alicebob/miniredis/v2 v2.35.0 h1:QwLphYqCEAo1eu1TqPRN2jgVMPBweeQcR21jeqDCONI= @@ -135,14 +133,8 @@ github.com/cheggaaa/pb/v3 v3.1.7 h1:2FsIW307kt7A/rz/ZI2lvPO+v3wKazzE4K/0LtTWsOI= github.com/cheggaaa/pb/v3 v3.1.7/go.mod h1:/Ji89zfVPeC/u5j8ukD0MBPHt2bzTYp74lQ7KlgFWTQ= github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= -github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= -github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= -github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8= github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU= -github.com/containers/common v0.64.2 h1:1xepE7QwQggUXxmyQ1Dbh6Cn0yd7ktk14sN3McSWf5I= -github.com/containers/common v0.64.2/go.mod h1:o29GfYy4tefUuShm8mOn2AiL5Mpzdio+viHI7n24KJ4= github.com/containers/image/v5 v5.36.2 h1:GcxYQyAHRF/pLqR4p4RpvKllnNL8mOBn0eZnqJbfTwk= github.com/containers/image/v5 v5.36.2/go.mod h1:b4GMKH2z/5t6/09utbse2ZiLK/c72GuGLFdp7K69eA4= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= @@ -240,7 +232,6 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-containerregistry v0.20.3 h1:oNx7IdTI936V8CQRveCjaxOiegWwvM7kqkbXTpyiovI= @@ -264,15 +255,10 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48= github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA= @@ -320,11 +306,7 @@ github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A= -github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= -github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -422,8 +404,6 @@ github.com/sigstore/sigstore v1.9.5/go.mod h1:VtxgvGqCmEZN9X2zhFSOkfXxvKUjpy8RpU github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= -github.com/smallstep/pkcs7 v0.1.1 h1:x+rPdt2W088V9Vkjho4KtoggyktZJlMduZAtRHm68LU= -github.com/smallstep/pkcs7 v0.1.1/go.mod h1:dL6j5AIz9GHjVEBTXtW+QliALcgM19RtXaTeyxI+AfA= github.com/sony/gobreaker v0.4.2-0.20210216022020-dd874f9dd33b h1:br+bPNZsJWKicw/5rALEo67QHs5weyD5tf8WST+4sJ0= github.com/sony/gobreaker v0.4.2-0.20210216022020-dd874f9dd33b/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= @@ -433,8 +413,6 @@ github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spiffe/go-spiffe/v2 v2.6.0 h1:l+DolpxNWYgruGQVV0xsfeya3CsC7m8iBzDnMpsbLuo= github.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xIx7lEzqblHEs= -github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 h1:pnnLyeX7o/5aX8qUQ69P/mLojDqwda8hFOCBTmP/6hw= -github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6/go.mod h1:39R/xuhNgVhi+K0/zst4TLrJrVmbm6LVgl4A0+ZFS5M= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -459,11 +437,8 @@ github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY= github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo= github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= -github.com/vbauerster/mpb/v8 v8.10.2 h1:2uBykSHAYHekE11YvJhKxYmLATKHAGorZwFlyNw4hHM= -github.com/vbauerster/mpb/v8 v8.10.2/go.mod h1:+Ja4P92E3/CorSZgfDtK46D7AVbDqmBQRTmyTqPElo0= github.com/vmware/govmomi v0.52.0 h1:JyxQ1IQdllrY7PJbv2am9mRsv3p9xWlIQ66bv+XnyLw= github.com/vmware/govmomi v0.52.0/go.mod h1:Yuc9xjznU3BH0rr6g7MNS1QGvxnJlE1vOvTJ7Lx7dqI= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= go.mongodb.org/mongo-driver v1.17.2 h1:gvZyk8352qSfzyZ2UMWcpDpMSGEr1eqE4T793SqyhzM= @@ -528,97 +503,40 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 h1:9kj3STMvgqy3YA4VQXBrN7925ICMxD5wzMRcgA30588= golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= google.golang.org/api v0.248.0 h1:hUotakSkcwGdYUqzCRc5yGYsg4wXxpkKlW5ryVqvC1Y= diff --git a/pkg/container/client.go b/pkg/container/client.go index 6a1517002d..c27f0777ac 100644 --- a/pkg/container/client.go +++ b/pkg/container/client.go @@ -19,9 +19,6 @@ import ( _ "github.com/containers/image/v5/oci/layout" "golang.org/x/sys/unix" - "github.com/containers/common/pkg/retry" - "github.com/containers/image/v5/copy" - "github.com/containers/image/v5/docker" "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/signature" @@ -268,75 +265,81 @@ func parseImageName(name string) (types.ImageReference, error) { return transport.ParseReference(parts[1]) } -// UploadImage takes an container image located at from and uploads it -// to the Target of Client. If tag is set, i.e. not the empty string, -// it will replace any previously set tag or digest of the target. -// Returns the digest of the manifest that was written to the server. +// UploadImage takes a container image located at from and uploads it to the +// Target of Client. If tag is set, i.e. not the empty string, it will replace +// any previously set tag or digest of the target. Returns the digest of the +// manifest that was written to the server. func (cl *Client) UploadImage(ctx context.Context, from, tag string) (digest.Digest, error) { - - targetCtx := *cl.sysCtx - targetCtx.DockerRegistryPushPrecomputeDigests = cl.PrecomputeDigests - - policyContext, err := signature.NewPolicyContext(cl.policy) - - if err != nil { - return "", err - } - - srcRef, err := parseImageName(from) - if err != nil { - return "", fmt.Errorf("invalid source name '%s': %w", from, err) - } - target := cl.Target if tag != "" { target = reference.TrimNamed(target) + + var err error target, err = reference.WithTag(target, tag) if err != nil { - return "", fmt.Errorf("error creating reference with tag '%s': %w", tag, err) + return "", fmt.Errorf("failed to create reference with tag '%s': %w", tag, err) } } - destRef, err := docker.NewReference(target) + // start building skopeo copy command + cmd := exec.CommandContext(ctx, "skopeo") + cmd.Args = append(cmd.Args, "copy", "--all") + + // write the digest to a file so we can return it + digestFile, err := os.CreateTemp("", "image-builder-container-upload-digest-*") if err != nil { - return "", err + return "", fmt.Errorf("failed to create digest file for upload: %w", err) + } + defer os.Remove(digestFile.Name()) + digestFile.Close() + cmd.Args = append(cmd.Args, fmt.Sprintf("--digestfile=%s", digestFile.Name())) + + if cl.PrecomputeDigests { + cmd.Args = append(cmd.Args, "--dest-precompute-digests") } - retryOpts := retry.RetryOptions{ - MaxRetry: cl.MaxRetries, + if cl.MaxRetries > 0 { + cmd.Args = append(cmd.Args, fmt.Sprintf("--retry-times=%d", cl.MaxRetries)) } - var manifestDigest digest.Digest + if tls := cl.GetTLSVerify(); tls != nil && !*tls { + cmd.Args = append(cmd.Args, "--dest-tls-verify=false") + } - err = retry.RetryIfNecessary(ctx, func() error { - manifestBytes, err := copy.Image(ctx, policyContext, destRef, srcRef, ©.Options{ - RemoveSignatures: false, - SignBy: "", - SignPassphrase: "", - ReportWriter: cl.ReportWriter, - SourceCtx: cl.sysCtx, - DestinationCtx: &targetCtx, - ForceManifestMIMEType: "", - ImageListSelection: copy.CopyAllImages, - PreserveDigests: false, - }) + if authfile := cl.GetAuthFilePath(); authfile != "" { + cmd.Args = append(cmd.Args, fmt.Sprintf("--authfile=%s", authfile)) + } - if err != nil { - return err - } + if dockerAuth := cl.sysCtx.DockerAuthConfig; dockerAuth != nil { + cmd.Args = append(cmd.Args, fmt.Sprintf("--dest-creds=%s:%s", dockerAuth.Username, dockerAuth.Password)) + } + + if certPath := cl.sysCtx.DockerCertPath; certPath != "" { + cmd.Args = append(cmd.Args, fmt.Sprintf("--dest-cert-dir=%s", certPath)) + } - manifestDigest, err = manifest.Digest(manifestBytes) + cmd.Args = append(cmd.Args, from, fmt.Sprintf("docker://%s", target.String())) - return err + cmd.Stdout = cl.ReportWriter + cmd.Stderr = cl.ReportWriter - }, &retryOpts) + if err := cmd.Run(); err != nil { + return "", fmt.Errorf("skopeo copy (upload) failed: %w", err) + } + digestData, err := os.ReadFile(digestFile.Name()) if err != nil { - return "", err + return "", fmt.Errorf("failed to read digest file: %w", err) + } + + // parse the digest to verify it's valid + uploadedDigest, err := digest.Parse(strings.TrimSpace(string(digestData))) + if err != nil { + return "", fmt.Errorf("failed to parse digest after upload %q: %w", string(digestData), err) } - return manifestDigest, nil + return uploadedDigest, nil } // A RawManifest contains the raw manifest Data and its MimeType From e3859265585a5b9b8b908e950fce45890b4e4cad Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 20 Aug 2026 18:35:53 +0200 Subject: [PATCH 13/21] container: remove unused client code and properties Drop the parseImageName() function and the policy property of the client. They're not needed anymore. --- go.mod | 9 +------- go.sum | 26 ++--------------------- pkg/container/client.go | 38 ++-------------------------------- pkg/container/client_test.go | 40 ------------------------------------ pkg/container/export_test.go | 2 -- 5 files changed, 5 insertions(+), 110 deletions(-) diff --git a/go.mod b/go.mod index 2ebb82ada8..9edb6d0508 100644 --- a/go.mod +++ b/go.mod @@ -95,7 +95,6 @@ require ( github.com/containers/storage v1.59.1 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect - github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/distribution/reference v0.6.0 // indirect @@ -140,7 +139,6 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -151,13 +149,13 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/nxadm/tail v1.4.11 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/opencontainers/runtime-spec v1.2.1 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/proglottis/gpgme v0.1.4 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.67.5 // indirect @@ -168,14 +166,9 @@ require ( github.com/redis/go-redis/v9 v9.7.3 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect - github.com/sigstore/fulcio v1.6.6 // indirect - github.com/sigstore/protobuf-specs v0.4.1 // indirect - github.com/sigstore/sigstore v1.9.5 // indirect github.com/sirupsen/logrus v1.9.4 // indirect github.com/sony/gobreaker v0.4.2-0.20210216022020-dd874f9dd33b // indirect github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect - github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect github.com/ulikunitz/xz v0.5.15 // indirect github.com/vbatts/tar-split v0.12.1 // indirect go.mongodb.org/mongo-driver v1.17.2 // indirect diff --git a/go.sum b/go.sum index d339870b3f..cf26384e91 100644 --- a/go.sum +++ b/go.sum @@ -22,8 +22,6 @@ cloud.google.com/go/storage v1.56.1 h1:n6gy+yLnHn0hTwBFzNn8zJ1kqWfR91wzdM8hjRF4w cloud.google.com/go/storage v1.56.1/go.mod h1:C9xuCZgFl3buo2HZU/1FncgvvOgTAs/rnh4gF4lMg0s= cloud.google.com/go/trace v1.11.6 h1:2O2zjPzqPYAHrn3OKl029qlqG6W8ZdYaOWRyr8NgMT4= cloud.google.com/go/trace v1.11.6/go.mod h1:GA855OeDEBiBMzcckLPE2kDunIpC72N+Pq8WFieFjnI= -dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= -dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 h1:fou+2+WFTib47nS+nz/ozhEBnvU96bKHy6LjRsY4E28= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0/go.mod h1:t76Ruy8AHvUAC8GfMWJMa0ElSbuIcO03NLpynfbgsPA= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4= @@ -148,8 +146,6 @@ github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03V github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 h1:uX1JmpONuD549D73r6cgnxyUu18Zb7yHAy5AYU0Pm4Q= -github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -190,6 +186,7 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= @@ -217,8 +214,6 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91 github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k= github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= -github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gocomply/scap v0.1.3 h1:QPadOSsvq2IJzENzHdmbDFefAN1GU4iCyfaKMDLWZ6A= @@ -273,8 +268,6 @@ github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24 h1:liMMTbpW github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/jmhodges/clock v1.2.0 h1:eq4kys+NI0PLngzaHEe7AmPT90XMGIEySD1JfV1PDIs= -github.com/jmhodges/clock v1.2.0/go.mod h1:qKjhA7x7u/lQpPB1XAqX1b1lCI/w3/fNuYpI/ZjLynI= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -298,8 +291,6 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec h1:2tTW6cDth2TSgRbAhD7yjZzTQmcN25sDRPEeinR51yQ= -github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec/go.mod h1:TmwEoGCwIti7BCeJ9hescZgRtatxRE+A72pCoPfmcfk= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4= @@ -355,8 +346,6 @@ github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/proglottis/gpgme v0.1.4 h1:3nE7YNA70o2aLjcg63tXMOhPD7bplfE5CBdV+hLAm2M= -github.com/proglottis/gpgme v0.1.4/go.mod h1:5LoXMgpE4bttgwwdv9bLs/vwqv3qV7F4glEEZ7mRKrM= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= @@ -391,16 +380,6 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ= -github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU= -github.com/secure-systems-lab/go-securesystemslib v0.9.0 h1:rf1HIbL64nUpEIZnjLZ3mcNEL9NBPB0iuVjyxvq3LZc= -github.com/secure-systems-lab/go-securesystemslib v0.9.0/go.mod h1:DVHKMcZ+V4/woA/peqr+L0joiRXbPpQ042GgJckkFgw= -github.com/sigstore/fulcio v1.6.6 h1:XaMYX6TNT+8n7Npe8D94nyZ7/ERjEsNGFC+REdi/wzw= -github.com/sigstore/fulcio v1.6.6/go.mod h1:BhQ22lwaebDgIxVBEYOOqLRcN5+xOV+C9bh/GUXRhOk= -github.com/sigstore/protobuf-specs v0.4.1 h1:5SsMqZbdkcO/DNHudaxuCUEjj6x29tS2Xby1BxGU7Zc= -github.com/sigstore/protobuf-specs v0.4.1/go.mod h1:+gXR+38nIa2oEupqDdzg4qSBT0Os+sP7oYv6alWewWc= -github.com/sigstore/sigstore v1.9.5 h1:Wm1LT9yF4LhQdEMy5A2JeGRHTrAWGjT3ubE5JUSrGVU= -github.com/sigstore/sigstore v1.9.5/go.mod h1:VtxgvGqCmEZN9X2zhFSOkfXxvKUjpy8RpUW39oCtoII= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= @@ -429,8 +408,6 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/supakeen/yamlplus v1.1.0 h1:UD0XVXoQ4qYT7aJv1DIKEx1siFe4SWOHx5P2OvBkirw= github.com/supakeen/yamlplus v1.1.0/go.mod h1:NJsFWyxKs90654Jy5E25tY5gCCJ0kcHyWbdNaJndGU0= -github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= -github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs= github.com/ubccr/kerby v0.0.0-20230802201021-412be7bfaee5 h1:EHD1FdySQ5yrgq2Zl1ArSuQoyOhnHXHk913ByaCxn6Q= github.com/ubccr/kerby v0.0.0-20230802201021-412be7bfaee5/go.mod h1:1CL+Iph1+IWFXLD5eHAFP1cysR6Nipc45yv/t5UZs3Y= github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY= @@ -523,6 +500,7 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= diff --git a/pkg/container/client.go b/pkg/container/client.go index c27f0777ac..07026910d7 100644 --- a/pkg/container/client.go +++ b/pkg/container/client.go @@ -21,8 +21,6 @@ import ( "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/manifest" - "github.com/containers/image/v5/signature" - "github.com/containers/image/v5/transports" "github.com/containers/image/v5/types" "github.com/opencontainers/go-digest" @@ -33,8 +31,7 @@ import ( ) const ( - DefaultUserAgent = "osbuild-composer/1.0" - DefaultPolicyPath = "/etc/containers/policy.json" + DefaultUserAgent = "osbuild-composer/1.0" ) // GetDefaultAuthFile returns the authentication file to use for the @@ -107,7 +104,6 @@ type Client struct { UserAgent string // user agent string to use for requests, defaults to DefaultUserAgent // internal state - policy *signature.Policy sysCtx *types.SystemContext store string // another store location other than the main one, useful for testing @@ -122,20 +118,6 @@ func NewClient(target string) (*Client, error) { return nil, fmt.Errorf("failed to parse '%s': %w", target, err) } - var policy *signature.Policy - if _, err := os.Stat(DefaultPolicyPath); err == nil { - policy, err = signature.NewPolicyFromFile(DefaultPolicyPath) - if err != nil { - return nil, err - } - } else { - policy = &signature.Policy{ - Default: []signature.PolicyRequirement{ - signature.NewPRInsecureAcceptAnything(), - }, - } - } - client := Client{ Target: reference.TagNameOnly(ref), @@ -153,8 +135,7 @@ func NewClient(target string) (*Client, error) { AuthFilePath: GetDefaultAuthFile(), }, - policy: policy, - store: "/var/lib/containers/storage", + store: "/var/lib/containers/storage", } // default to the host architecture @@ -250,21 +231,6 @@ func (cl *Client) SkipTLSVerify() { cl.SetTLSVerify(common.ToPtr(false)) } -func parseImageName(name string) (types.ImageReference, error) { - - parts := strings.SplitN(name, ":", 2) - if len(parts) != 2 { - return nil, fmt.Errorf("invalid image name '%s'", name) - } - - transport := transports.Get(parts[0]) - if transport == nil { - return nil, fmt.Errorf("unknown transport '%s'", parts[0]) - } - - return transport.ParseReference(parts[1]) -} - // UploadImage takes a container image located at from and uploads it to the // Target of Client. If tag is set, i.e. not the empty string, it will replace // any previously set tag or digest of the target. Returns the digest of the diff --git a/pkg/container/client_test.go b/pkg/container/client_test.go index ebeb846e7b..aad9ec826e 100644 --- a/pkg/container/client_test.go +++ b/pkg/container/client_test.go @@ -413,46 +413,6 @@ func TestSetArchitectureChoice(t *testing.T) { } } -func TestParseImageName(t *testing.T) { - testCases := []struct { - name string - input string - expectErr string - }{ - { - name: "no-colon", - input: "nocolon", - expectErr: "invalid image name 'nocolon'", - }, - { - name: "unknown-transport", - input: "invalid:/some/path", - expectErr: "unknown transport 'invalid'", - }, - { - name: "valid-oci-archive", - input: "oci-archive:/dev/null", - }, - { - name: "valid-oci", - input: "oci:/dev/null", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - ref, err := container.ParseImageName(tc.input) - if tc.expectErr != "" { - assert.Nil(t, ref) - assert.EqualError(t, err, tc.expectErr) - } else { - assert.NoError(t, err) - assert.NotNil(t, ref) - } - }) - } -} - func TestGetManifest(t *testing.T) { require := require.New(t) diff --git a/pkg/container/export_test.go b/pkg/container/export_test.go index b9588488de..61dd71c153 100644 --- a/pkg/container/export_test.go +++ b/pkg/container/export_test.go @@ -23,5 +23,3 @@ func NewBlockingResolverWithTestClient(arch string, f func(string) (*Client, err func ClientSysctx(cl *Client) *types.SystemContext { return cl.sysCtx } - -var ParseImageName = parseImageName From 340d333a67b88f7e7a24616f98cff47cff707f82 Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 13 Aug 2026 12:45:27 +0200 Subject: [PATCH 14/21] Remove all uses of the graphdriver exclusion compile tags On RHEL and CentOS, the exclude_graphdriver_btrfs tag was needed to compile without support for the btrfs driver from the containers/image dependency. That dependency is now gone and we don't need to specify the tag anymore. The same goes for the other graphdrivers: devicemapper and overlay. Even though we could support those on the two distros, we sometimes specified them to avoid needing the devel package dependency installed. --- .github/workflows/tests.yml | 1 - Makefile | 7 +++---- image-builder.spec | 7 +------ test/scripts/imgtestlib/boot.py | 3 --- 4 files changed, 4 insertions(+), 14 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ed67fc5111..6acb28e003 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -85,7 +85,6 @@ jobs: image: quay.io/centos/centos:${{ matrix.centos_stream.image_tag }} options: --privileged env: - GOFLAGS: "-tags=exclude_graphdriver_btrfs" # workaround for expired cert at source of indirect dependency # (go.opencensus.io/trace) GOPROXY: "https://proxy.golang.org|direct" diff --git a/Makefile b/Makefile index 568c0c6077..374d7f7ada 100644 --- a/Makefile +++ b/Makefile @@ -102,7 +102,7 @@ help: ## Print this usage information # keep in sync with: # https://github.com/containers/podman/blob/2981262215f563461d449b9841741339f4d9a894/Makefile#L51 -TAGS := containers_image_openpgp,exclude_graphdriver_btrfs,exclude_graphdriver_devicemapper +TAGS := containers_image_openpgp ifneq ($(DEBUG),) TAGS := $(TAGS),profiling endif @@ -227,8 +227,7 @@ test: ## run all tests locally # Run unit tests go test -timeout 20m -race ./... # Run unit tests without CGO - # keep tags in sync with BUILDTAGS_CROSS in https://github.com/containers/podman/blob/2981262215f563461d449b9841741339f4d9a894/Makefile#L85 - CGO_ENABLED=0 go test -tags "containers_image_openpgp exclude_graphdriver_btrfs exclude_graphdriver_devicemapper exclude_graphdriver_overlay" ./... + CGO_ENABLED=0 go test -tags "containers_image_openpgp" ./... # Run depsolver tests with force-dnf to make sure it's not skipped for any reason go test -race ./pkg/depsolvednf/... -force-dnf # ensure our tags are consistent @@ -236,7 +235,7 @@ test: ## run all tests locally .PHONY: host-check-test host-check-test: container_built_$(CONTAINER_IMAGE).info ## run all host checks in a container - CGO_ENABLED=0 go test -tags "containers_image_openpgp exclude_graphdriver_btrfs exclude_graphdriver_devicemapper exclude_graphdriver_overlay" \ + CGO_ENABLED=0 go test -tags "containers_image_openpgp" \ -c -o check-host-config.test ./cmd/check-host-config podman run -v .:/app:z --rm --user root -e OSBUILD_TEST_CONTAINER=true -t $(CONTAINER_IMAGE) \ /app/check-host-config.test -test.v -test.run ^TestSmokeAll$$ diff --git a/image-builder.spec b/image-builder.spec index 9bdc2ca948..27538cebb2 100644 --- a/image-builder.spec +++ b/image-builder.spec @@ -81,11 +81,6 @@ export GOFLAGS+=" -mod=vendor" %undefine gomodulesmode %endif -# btrfs-progs-devel is not available on RHEL -%if 0%{?rhel} -GOTAGS="exclude_graphdriver_btrfs" -%endif - export LDFLAGS="${LDFLAGS} -X 'main.version=%{version}'" %gobuild ${GOTAGS:+-tags=$GOTAGS} -o _bin/image-builder %{goipath}/cmd/image-builder @@ -104,7 +99,7 @@ install -m 0644 -vp man/man1/image-builder*.1 %{buildroot}%{_mandir}/man1/ %check export GOFLAGS="-buildmode=pie" %if 0%{?rhel} -export GOFLAGS+=" -mod=vendor -tags=exclude_graphdriver_btrfs" +export GOFLAGS+=" -mod=vendor" export GOPATH=$PWD/_build:%{gopath} # cd inside GOPATH, otherwise go with GO111MODULE=off ignores vendor directory cd $PWD/_build/src/%{goipath} diff --git a/test/scripts/imgtestlib/boot.py b/test/scripts/imgtestlib/boot.py index db12c976a8..d385de4ac0 100644 --- a/test/scripts/imgtestlib/boot.py +++ b/test/scripts/imgtestlib/boot.py @@ -170,9 +170,6 @@ def make_check_host_config(arch): "./cmd/check-host-config"] tags = [ "containers_image_openpgp", - "exclude_graphdriver_btrfs", - "exclude_graphdriver_devicemapper", - "exclude_graphdriver_overlay", ] runcmd_nc( cmd, From 29df56b607fd3856f17f02d760a1ed1572533a78 Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 20 Aug 2026 20:47:18 +0200 Subject: [PATCH 15/21] Remove all uses of the containers_image_openpgp compile tag The containers/image pgp dependency is also gone. --- Makefile | 8 +++----- test/scripts/imgtestlib/boot.py | 4 ---- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 374d7f7ada..890be60881 100644 --- a/Makefile +++ b/Makefile @@ -102,9 +102,8 @@ help: ## Print this usage information # keep in sync with: # https://github.com/containers/podman/blob/2981262215f563461d449b9841741339f4d9a894/Makefile#L51 -TAGS := containers_image_openpgp ifneq ($(DEBUG),) -TAGS := $(TAGS),profiling +TAGS := profiling endif .PHONY: build @@ -227,7 +226,7 @@ test: ## run all tests locally # Run unit tests go test -timeout 20m -race ./... # Run unit tests without CGO - CGO_ENABLED=0 go test -tags "containers_image_openpgp" ./... + CGO_ENABLED=0 go test ./... # Run depsolver tests with force-dnf to make sure it's not skipped for any reason go test -race ./pkg/depsolvednf/... -force-dnf # ensure our tags are consistent @@ -235,8 +234,7 @@ test: ## run all tests locally .PHONY: host-check-test host-check-test: container_built_$(CONTAINER_IMAGE).info ## run all host checks in a container - CGO_ENABLED=0 go test -tags "containers_image_openpgp" \ - -c -o check-host-config.test ./cmd/check-host-config + CGO_ENABLED=0 go test -c -o check-host-config.test ./cmd/check-host-config podman run -v .:/app:z --rm --user root -e OSBUILD_TEST_CONTAINER=true -t $(CONTAINER_IMAGE) \ /app/check-host-config.test -test.v -test.run ^TestSmokeAll$$ diff --git a/test/scripts/imgtestlib/boot.py b/test/scripts/imgtestlib/boot.py index d385de4ac0..bfa208c8c2 100644 --- a/test/scripts/imgtestlib/boot.py +++ b/test/scripts/imgtestlib/boot.py @@ -168,15 +168,11 @@ def make_check_host_config(arch): # build without CGO so no dependencies are needed cmd = ["go", "build", "-o", "check-host-config-" + arch, "./cmd/check-host-config"] - tags = [ - "containers_image_openpgp", - ] runcmd_nc( cmd, extra_env={ "GOARCH": goarch, "CGO_ENABLED": "0", - "GOFLAGS": "-tags=" + ",".join(tags), }, ) From 8d840e55513c713bfd2fb9daebd003c207e10e9f Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 13 Aug 2026 20:41:01 +0200 Subject: [PATCH 16/21] test: drop dependencies from install script Remove btrfs-progs-devel, device-mapper-devel, and gpgme-devel from the dependency install script. --- test/scripts/install-dependencies | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/scripts/install-dependencies b/test/scripts/install-dependencies index 93d90e54f7..7eb6954a0d 100755 --- a/test/scripts/install-dependencies +++ b/test/scripts/install-dependencies @@ -7,12 +7,9 @@ set -e install_deps() { dnf -y install \ awscli2 \ - btrfs-progs-devel \ cloud-utils \ - device-mapper-devel \ gcc \ go \ - gpgme-devel \ iproute \ krb5-devel \ libvirt-devel \ @@ -39,10 +36,8 @@ install_deps() { install_deps_el() { dnf -y install \ awscli2 \ - device-mapper-devel \ gcc \ go \ - gpgme-devel \ krb5-devel \ libvirt-devel \ lorax \ From 931b5732412686fdf14a45094848adc0254567ed Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 13 Aug 2026 12:48:30 +0200 Subject: [PATCH 17/21] README: update dependency descriptions Remove mentions of btrfs-progs-devel and device-mapper-devel. Also remove mentions of cmd/build. This README should be replaced by the Image Builder readme soon. See HMS-10586 --- README.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 9354702090..4af8146349 100644 --- a/README.md +++ b/README.md @@ -65,15 +65,9 @@ The minimal dependencies are: Other dependencies only needed in some cases are: -- `btrfs-progs-devel`, `device-mapper-devel` - build dependencies for the unit tests and projects that import `pkg/container`, which even in that case can be skipped using exclude_graphdriver_btrfs and exclude_graphdriver_devicemapper (see bootc-image-builder). -- `krb5-devel` - build dependency for the unit tests and projects that import `pkg/upload/koji` -- `osbuild-depsolve-dnf` - runtime dependency for the unit tests and projects that import `pkg/depsolvednf`. - or to run `cmd/gen-manifests` and `cmd/build` -- `osbuild` (and subpackages) - runtime dependencies for `cmd/build`. +- `krb5-devel`: build dependency for the unit tests and projects that import `pkg/upload/koji`. +- `osbuild-depsolve-dnf`: runtime dependency for the unit tests and projects that import `pkg/depsolvednf`, or to run `cmd/gen-manifests`. +- `osbuild` (and subpackages): runtime dependencies for building images (processing manifests). ### Repository: From 40519999e43ac86dd463f78ab5951d903cff1ae2 Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Thu, 20 Aug 2026 18:45:30 +0200 Subject: [PATCH 18/21] Remove all mentions of the dropped dependencies Remove all mentions of: - gpgme-devel - btrfs-progs-devel - device-mapper-devel --- .devcontainer/Dockerfile | 2 -- .github/workflows/gobump.yml | 2 +- .github/workflows/tests.yml | 6 +----- CONTRIBUTING.md | 3 --- Containerfile | 2 +- README.image-builder.md | 7 ------- README.md | 1 - bootc-image-builder/Containerfile | 2 +- docs/developer/README.md | 2 +- image-builder.spec | 7 ------- test/README.md | 6 +++--- 11 files changed, 8 insertions(+), 32 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index ae46c25cbd..9750648edd 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -3,7 +3,6 @@ FROM fedora:latest # Install: # - a few packages for convenient usage # - the go compiler -# - gpgme-devel # - osbuild RUN dnf install -y \ fish \ @@ -11,7 +10,6 @@ RUN dnf install -y \ ripgrep \ jq \ go \ - gpgme-devel \ osbuild \ osbuild-lvm2 \ osbuild-luks2 \ diff --git a/.github/workflows/gobump.yml b/.github/workflows/gobump.yml index 4e3443346e..8cff8a2e7d 100644 --- a/.github/workflows/gobump.yml +++ b/.github/workflows/gobump.yml @@ -15,7 +15,7 @@ jobs: - name: Prepare environment and run tests run: | set -xe - sudo dnf -y install git gh golang skopeo libvirt-devel gpgme-devel btrfs-progs-devel krb5-devel + sudo dnf -y install git gh golang skopeo libvirt-devel krb5-devel git clone --depth 1 https://github.com/osbuild/image-builder cd image-builder/ go build ./... diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6acb28e003..444d854a28 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -106,7 +106,7 @@ jobs: run: ./test/scripts/setup-osbuild-repo - name: Install build and test dependencies - run: dnf -y install krb5-devel libvirt-devel gcc git-core go gpgme-devel osbuild-depsolve-dnf device-mapper-devel + run: ./test/scripts/install-dependencies - name: Mark the working directory as safe for git run: git config --global --add safe.directory "$(pwd)" @@ -148,10 +148,6 @@ jobs: - name: Install libvirt devel package run: sudo apt install -y libvirt-dev - # This is needed for the container resolver dependencies - - name: Install libgpgme devel package - run: sudo apt install -y libgpgme-dev libbtrfs-dev libdevmapper-dev podman - - name: Run golangci-lint uses: golangci/golangci-lint-action@v9 with: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 111b9ff558..009e5c5b07 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,9 +14,6 @@ However, there are several command line tools defined in [`cmd/`](https://pkg.go.dev/github.com/osbuild/images@main/cmd) that can help during development and testing. -The build-requirements for Fedora and rpm-based distributions are: -- `gpgme-devel`, `btrfs-progs-devel`, `device-mapper-devel` - To build images, you will also need to install `osbuild` and its sub-packages. See the [HACKING guide](HACKING.md) for more information on development diff --git a/Containerfile b/Containerfile index 5deac767ef..9d80a9256e 100644 --- a/Containerfile +++ b/Containerfile @@ -1,5 +1,5 @@ FROM registry.fedoraproject.org/fedora:44 AS builder -RUN dnf install -y git-core golang gpgme-devel libassuan-devel && mkdir -p /build/ +RUN dnf install -y git-core golang && mkdir -p /build/ WORKDIR /build COPY go.mod go.sum ./ RUN go mod download diff --git a/README.image-builder.md b/README.image-builder.md index f1fc64eaf7..37f02ee899 100644 --- a/README.image-builder.md +++ b/README.image-builder.md @@ -70,13 +70,6 @@ the normal `go` command or use $ make build ``` -To compile without go build tags you will need to install -the required RPMs: - -```console -$ sudo dnf install gpgme-devel -``` - ## Prerequisites Make sure to have the required `osbuild` RPMs installed: diff --git a/README.md b/README.md index 4af8146349..ae27a8da20 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,6 @@ sudo ./test/scripts/install-dependencies The minimal dependencies are: - `go` -- `gpgme-devel` - `libvirt-devel` Other dependencies only needed in some cases are: diff --git a/bootc-image-builder/Containerfile b/bootc-image-builder/Containerfile index 559a4aba82..fc1fbc6496 100644 --- a/bootc-image-builder/Containerfile +++ b/bootc-image-builder/Containerfile @@ -1,5 +1,5 @@ FROM registry.fedoraproject.org/fedora:44 AS builder -RUN dnf install -y git-core golang gpgme-devel libassuan-devel libvirt-devel && mkdir -p /build/bib +RUN dnf install -y git-core golang libvirt-devel && mkdir -p /build/bib COPY go.mod go.sum /build/bib/ RUN cd /build/bib && go mod download # Copy the entire dir to avoid having to conditionally include ".git" as that diff --git a/docs/developer/README.md b/docs/developer/README.md index 2969fef0b2..b5d6972b76 100644 --- a/docs/developer/README.md +++ b/docs/developer/README.md @@ -5,7 +5,7 @@ To build most binaries defined in `cmd` and run tests you will need to install the following dependencies: - dnf -y install gpgme-devel btrfs-progs-devel krb5-devel + dnf -y install krb5-devel To generate manifests, you will need to install the following dependencies: diff --git a/image-builder.spec b/image-builder.spec index 27538cebb2..8d686aaa40 100644 --- a/image-builder.spec +++ b/image-builder.spec @@ -30,15 +30,8 @@ BuildRequires: skopeo # Build requirements of the `kerby/kerby` package BuildRequires: krb5-devel -# Build requirements of 'theproglottis/gpgme' package -BuildRequires: gpgme-devel -BuildRequires: libassuan-devel -# Build requirements of 'github.com/containers/storage' package -BuildRequires: device-mapper-devel BuildRequires: libxcrypt-devel %if 0%{?fedora} -# Build requirements of 'github.com/containers/storage' package -BuildRequires: btrfs-progs-devel # for _tmpfilesdir macro BuildRequires: systemd-rpm-macros # DO NOT REMOVE the BUNDLE_START and BUNDLE_END markers as they are used by 'tools/rpm_spec_add_provides_bundle.sh' to generate the Provides: bundled list diff --git a/test/README.md b/test/README.md index 9268533c9b..2ccb891046 100644 --- a/test/README.md +++ b/test/README.md @@ -32,7 +32,7 @@ While most of this document describes our automatic setup, here are some useful testing/inspection of images is required. Install required packages: -dnf install -y cloud-utils-cloud-localds gpgme-devel btrfs-progs-devel krb5-devel +dnf install -y cloud-utils-cloud-localds krb5-devel To build an image just run `build-image`, then it can be booted with `boot-image` and the switch `--keep-booted` will keep it around for inspection via ssh (not all image types support @@ -57,13 +57,13 @@ vm accordingly. ## Running image build tests locally -Some image build tests are available to run locally via qemu. The easiest way to discover them is to +Some image build tests are available to run locally via qemu. The easiest way to discover them is to run: ```console $ sudo pytest --collect-only ./test/test_build_integration.py ``` This wil give a list of tests and their distro/arch/image-type permuations. Currently there are -two tests: +two tests: 1. Build the artifact (usually a disk image but can be a container) 2. Build the image and boot test it From 8190dd5a70ffec7faee00aa7e5e49557e8c64137 Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Fri, 21 Aug 2026 11:59:33 +0200 Subject: [PATCH 19/21] github: install git for CentOS Stream unit tests --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 444d854a28..cb91ad9a95 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -91,7 +91,7 @@ jobs: steps: - name: Install dnf plugins - run: dnf -y install dnf-plugins-core + run: dnf -y install dnf-plugins-core git-core - name: Enable crb repo run: dnf config-manager --set-enabled crb From db6100483565a18b5c64b698bc0acaa5931ca253 Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Fri, 21 Aug 2026 12:42:31 +0200 Subject: [PATCH 20/21] test: run unit tests on CentOS the same way we do on Fedora Specifically, skip tests that fail in containers because of the way they access the host container storage. These weren't an issue on CentOS before, but now appear to be failing the same way they do in Fedora containers. --- .github/workflows/tests.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cb91ad9a95..7579ca51df 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -115,7 +115,12 @@ jobs: run: dnf -y install openssl - name: Run unit tests - run: make test + # Skip tests that resolve manifests from local container storage. + # They are tested separately (see gitlab-ci.yml) + run: go test -count=1 -race -timeout 20m ./... -test.skip 'TestBlockingResolverLocalManifest|TestResolverLocalManifest|TestGetManifestLocal' + + - name: Run depsolver tests with force-dnf to make sure it's not skipped + run: go test -count=1 -race ./pkg/depsolvednf/... -force-dnf lint: name: "⌨ Lint" From e7e82a8ef14fc200415d7d89340de6dacdd2a8fd Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Fri, 21 Aug 2026 12:54:01 +0200 Subject: [PATCH 21/21] spec: add systemd to BuildRequires We use systemd-escape to generate mount unit names. On installations, this is pulled in by osbuild itself, but tests will fail at build time without it. --- image-builder.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/image-builder.spec b/image-builder.spec index 8d686aaa40..7ebb0ae78e 100644 --- a/image-builder.spec +++ b/image-builder.spec @@ -27,6 +27,8 @@ Source0: https://github.com/osbuild/image-builder/releases/download/v%{ve BuildRequires: %{?go_compiler:compiler(go-compiler)}%{!?go_compiler:golang} BuildRequires: libvirt-devel BuildRequires: skopeo +# We rely on systemd-escape to generate mount unit names. On install, it is pulled in by osbuild. +BuildRequires: systemd # Build requirements of the `kerby/kerby` package BuildRequires: krb5-devel