diff --git a/go.mod b/go.mod index 89b754c1e..3c16a069c 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/onsi/gomega v1.38.3 github.com/redhat-et/GKM/mcv v0.0.0 github.com/sigstore/cosign/v3 v3.0.4 - github.com/sigstore/rekor v1.5.0 + github.com/sigstore/rekor v1.5.2 github.com/sigstore/sigstore-go v1.1.4 github.com/stretchr/testify v1.11.1 go.uber.org/zap v1.28.0 @@ -47,7 +47,7 @@ require ( github.com/containerd/log v0.1.0 // indirect github.com/containerd/platforms v1.0.0-rc.1 // indirect github.com/containerd/stargz-snapshotter/estargz v0.18.2 // indirect - github.com/containers/buildah v1.42.1 // indirect + github.com/containers/buildah v1.43.2 // indirect github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect github.com/containers/ocicrypt v1.2.1 // indirect github.com/containers/podman/v5 v5.7.0 // indirect @@ -111,7 +111,7 @@ require ( github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-intervals v0.0.2 // indirect - github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 // indirect + github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -135,7 +135,7 @@ require ( github.com/mattn/go-runewidth v0.0.19 // indirect github.com/mattn/go-sqlite3 v1.14.32 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect - github.com/mistifyio/go-zfs/v4 v4.0.0 // indirect + github.com/mistifyio/go-zfs/v3 v3.1.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/sys/atomicwriter v0.1.0 // indirect @@ -168,7 +168,7 @@ require ( github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/procfs v0.20.1 // indirect github.com/sassoftware/relic v7.2.1+incompatible // indirect - github.com/secure-systems-lab/go-securesystemslib v0.10.0 // indirect + github.com/secure-systems-lab/go-securesystemslib v0.11.0 // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect github.com/sigstore/fulcio v1.8.6 // indirect github.com/sigstore/protobuf-specs v0.5.1 // indirect @@ -202,9 +202,9 @@ require ( go.opentelemetry.io/otel/sdk v1.43.0 // indirect go.opentelemetry.io/otel/trace v1.43.0 // indirect go.opentelemetry.io/proto/otlp v1.10.0 // indirect - go.podman.io/common v0.66.1-0.20251111134650-36964d15757a // indirect - go.podman.io/image/v5 v5.38.1-0.20251111134650-36964d15757a // indirect - go.podman.io/storage v1.61.1-0.20251111134650-36964d15757a // indirect + go.podman.io/common v0.67.1 // indirect + go.podman.io/image/v5 v5.39.2 // indirect + go.podman.io/storage v1.62.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect @@ -222,7 +222,7 @@ require ( gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60 // indirect - google.golang.org/grpc v1.81.1 // indirect + google.golang.org/grpc v1.82.1 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect @@ -232,7 +232,7 @@ require ( k8s.io/apiextensions-apiserver v0.35.0 // indirect k8s.io/apiserver v0.35.0 // indirect k8s.io/component-base v0.35.0 // indirect - k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/klog/v2 v2.140.0 // indirect k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect diff --git a/go.sum b/go.sum index 1c9b35f21..05aeee3f2 100644 --- a/go.sum +++ b/go.sum @@ -124,8 +124,8 @@ github.com/containerd/platforms v1.0.0-rc.1 h1:83KIq4yy1erSRgOVHNk1HYdPvzdJ5CnsW github.com/containerd/platforms v1.0.0-rc.1/go.mod h1:J71L7B+aiM5SdIEqmd9wp6THLVRzJGXfNuWCZCllLA4= github.com/containerd/stargz-snapshotter/estargz v0.18.2 h1:yXkZFYIzz3eoLwlTUZKz2iQ4MrckBxJjkmD16ynUTrw= github.com/containerd/stargz-snapshotter/estargz v0.18.2/go.mod h1:XyVU5tcJ3PRpkA9XS2T5us6Eg35yM0214Y+wvrZTBrY= -github.com/containers/buildah v1.42.1 h1:L4jH4Uv6vg6N1QbjnFC6N42izZ+BO3q5yOMA9QXBKgQ= -github.com/containers/buildah v1.42.1/go.mod h1:Lb5bkGcOZWklx4kyMSnEt0mnslKuSswsIGDQwo/zbiQ= +github.com/containers/buildah v1.43.2 h1:KbxgDNWtbMTQtbSElh4e/n8pJa9EDF+/jtIKPr1QtZI= +github.com/containers/buildah v1.43.2/go.mod h1:dXSaAu+S9aiY0j1teX+7btxBKSZlLfWU5LXnXwPaxf8= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/ocicrypt v1.2.1 h1:0qIOTT9DoYwcKmxSt8QJt+VzMY18onl9jUXsxpVhSmM= @@ -315,12 +315,12 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pIsMjahcegHh6rmhqxzIRQIyepY= -github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 h1:EwtI+Al+DeppwYX2oXJCETMO23COyaKGP6fHVpkpWpg= +github.com/google/pprof v0.0.0-20260402051712-545e8a4df936/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= -github.com/google/trillian v1.7.2 h1:EPBxc4YWY4Ak8tcuhyFleY+zYlbCDCa4Sn24e1Ka8Js= -github.com/google/trillian v1.7.2/go.mod h1:mfQJW4qRH6/ilABtPYNBerVJAJ/upxHLX81zxNQw05s= +github.com/google/trillian v1.7.3 h1:hziW+vo4czis48tzx2GK5xRBl/ZxBA9B0/UR5avXOro= +github.com/google/trillian v1.7.3/go.mod h1:qh8iy4x/GvnVXUBd5pK4oncuT1Y9vVYfibQVsR/WpKg= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -428,8 +428,8 @@ github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3v github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A= 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/mistifyio/go-zfs/v4 v4.0.0 h1:sU0+5dX45tdDK5xNZ3HBi95nxUc48FS92qbIZEvpAg4= -github.com/mistifyio/go-zfs/v4 v4.0.0/go.mod h1:weotFtXTHvBwhr9Mv96KYnDkTPBOHFUbm9cBmQpesL0= +github.com/mistifyio/go-zfs/v3 v3.1.0 h1:FZaylcg0hjUp27i23VcJJQiuBeAZjrC8lPqCGM1CopY= +github.com/mistifyio/go-zfs/v3 v3.1.0/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k= 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.1-0.20231216201459-8508981c8b6c h1:cqn374mizHuIWj+OSJCajGr/phAmuMug9qIX3l9CflE= @@ -531,8 +531,8 @@ github.com/sassoftware/relic/v7 v7.6.2 h1:rS44Lbv9G9eXsukknS4mSjIAuuX+lMq/FnStgm github.com/sassoftware/relic/v7 v7.6.2/go.mod h1:kjmP0IBVkJZ6gXeAu35/KCEfca//+PKM6vTAsyDPY+k= github.com/sebdah/goldie/v2 v2.7.1 h1:PkBHymaYdtvEkZV7TmyqKxdmn5/Vcj+8TpATWZjnG5E= github.com/sebdah/goldie/v2 v2.7.1/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI= -github.com/secure-systems-lab/go-securesystemslib v0.10.0 h1:l+H5ErcW0PAehBNrBxoGv1jjNpGYdZ9RcheFkB2WI14= -github.com/secure-systems-lab/go-securesystemslib v0.10.0/go.mod h1:MRKONWmRoFzPNQ9USRF9i1mc7MvAVvF1LlW8X5VWDvk= +github.com/secure-systems-lab/go-securesystemslib v0.11.0 h1:iuCR9kcMFD4QurdKrGvPLoKZLv9YvwPYVr0473BdtFs= +github.com/secure-systems-lab/go-securesystemslib v0.11.0/go.mod h1:+PMOTjUGwHj2vcZ+TFKlb1tXRbrdWE1LYDT5i9JC80Q= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI= @@ -543,8 +543,8 @@ github.com/sigstore/fulcio v1.8.6 h1:vkvRpdhVAZjZHa0ltiJeLSILG9U8ADJoe5Z+RdZSLJk github.com/sigstore/fulcio v1.8.6/go.mod h1:7RwoGdMM0xpc9qc382sjSw7P9OLKbKIwQZXvYz4JPb4= github.com/sigstore/protobuf-specs v0.5.1 h1:/5OPaNuolRJmQfeZLayJGFXMpsRJEdgC6ah1/+7Px7U= github.com/sigstore/protobuf-specs v0.5.1/go.mod h1:DRBzpFuE+LnvQMN10/dU6nBeKwVLGEQ6o2FovN2Rats= -github.com/sigstore/rekor v1.5.0 h1:rL7SghHd5HLCtsCrxw0yQg+NczGvM75EjSPPWuGjaiQ= -github.com/sigstore/rekor v1.5.0/go.mod h1:D7JoVCUkxwQOpPDNYeu+CE8zeBC18Y5uDo6tF8s2rcQ= +github.com/sigstore/rekor v1.5.2 h1:k6pX4o1zFAzAvDbXiVIp5IHj1b0wcDaxsbsbNpuRO8o= +github.com/sigstore/rekor v1.5.2/go.mod h1:WkMnITBccOFauPkT6yte74tF5gC83pefKRGZvNOsbjI= github.com/sigstore/rekor-tiles/v2 v2.0.1 h1:1Wfz15oSRNGF5Dzb0lWn5W8+lfO50ork4PGIfEKjZeo= github.com/sigstore/rekor-tiles/v2 v2.0.1/go.mod h1:Pjsbhzj5hc3MKY8FfVTYHBUHQEnP0ozC4huatu4x7OU= github.com/sigstore/sigstore v1.10.6 h1:YWhMQfTrJSK80QB1pbxjYeAwGKx+5UwWPPAY9hrPPZg= @@ -668,12 +668,12 @@ go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09 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.podman.io/common v0.66.1-0.20251111134650-36964d15757a h1:BDJ1TVYzhdRaKrexLIcd7REPQ84q1kBjVDtUWRrKpIs= -go.podman.io/common v0.66.1-0.20251111134650-36964d15757a/go.mod h1:Eij6QWfo3qNEvBLV4drWCsMoZNY9jAtskoglaiEOCNs= -go.podman.io/image/v5 v5.38.1-0.20251111134650-36964d15757a h1:1pyETjFaS+thtdUa6fs0x79dR2Dzt963DV5m4h/dDTA= -go.podman.io/image/v5 v5.38.1-0.20251111134650-36964d15757a/go.mod h1:tpNQ5CSuO+nGMF9UQHbetupDB6BpkQj3GYxhQVsy+Lo= -go.podman.io/storage v1.61.1-0.20251111134650-36964d15757a h1:R3nOO+65Xto3xN4+aquEwhnODXEEkrtBJ0z1egES52Y= -go.podman.io/storage v1.61.1-0.20251111134650-36964d15757a/go.mod h1:dukEC/YV7ZELYhPRTnkmv0hwPJ+wu3GL2lKJ/2UbiI4= +go.podman.io/common v0.67.1 h1:HddYLJfkfFUmFJ0V3PVoewguFM9eHkqk0g+fOc2B9R4= +go.podman.io/common v0.67.1/go.mod h1:XVmSLtnhJwGb+ImYn6BXiozxVE3mYZJgiiBuDOiOquk= +go.podman.io/image/v5 v5.39.2 h1:EJua/pRtvgLV/a5y8/RvA+ekKukZh0UuKMvLdTmEWFk= +go.podman.io/image/v5 v5.39.2/go.mod h1:SlaR6Pra1ATIx4BcuZ16oafb3QcCHISaKcJbtlN/G/0= +go.podman.io/storage v1.62.0 h1:0QjX1XlzVmbiaulb+aR/CG6p9+pzaqwIeZPe3tEjHbY= +go.podman.io/storage v1.62.0/go.mod h1:A3UBK0XypjNZ6pghRhuxg62+2NIm5lcUGv/7XyMhMUI= go.step.sm/crypto v0.81.0 h1:e+ouzpNt3Xm4dp7HGXhgYB5y4iFik3vh3phHKWmvugU= go.step.sm/crypto v0.81.0/go.mod h1:fsTizqQeASjTXnbv9O00XtRlIuXRkCdoRiJNyXGQujc= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -818,8 +818,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1: google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc= google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60 h1:seT2EwLWM78plQ7wcDfuWBc/4FAEAXDDiaSol4ku4qo= google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ= -google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= +google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= +google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -863,8 +863,8 @@ k8s.io/client-go v0.35.0 h1:IAW0ifFbfQQwQmga0UdoH0yvdqrbwMdq9vIFEhRpxBE= k8s.io/client-go v0.35.0/go.mod h1:q2E5AAyqcbeLGPdoRB+Nxe3KYTfPce1Dnu1myQdqz9o= k8s.io/component-base v0.35.0 h1:+yBrOhzri2S1BVqyVSvcM3PtPyx5GUxCK2tinZz1G94= k8s.io/component-base v0.35.0/go.mod h1:85SCX4UCa6SCFt6p3IKAPej7jSnF3L8EbfSyMZayJR0= -k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= -k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= +k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= k8s.io/utils v0.0.0-20260106112306-0fe9cd71b2f8 h1:oV4uULAC2QPIdMQwjMaNIwykyhWhnhBwX40yd5h9u3U= diff --git a/vendor/github.com/containers/buildah/define/types.go b/vendor/github.com/containers/buildah/define/types.go index 821d6ad36..baed08b6e 100644 --- a/vendor/github.com/containers/buildah/define/types.go +++ b/vendor/github.com/containers/buildah/define/types.go @@ -7,20 +7,20 @@ import ( "fmt" "io" "net/http" - urlpkg "net/url" + neturl "net/url" "os" "os/exec" "path" "path/filepath" "strings" + securejoin "github.com/cyphar/filepath-securejoin" v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" "go.podman.io/image/v5/manifest" "go.podman.io/storage/pkg/archive" "go.podman.io/storage/pkg/chrootarchive" - "go.podman.io/storage/pkg/ioutils" "go.podman.io/storage/types" ) @@ -29,7 +29,7 @@ const ( // identify working containers. Package = "buildah" // Version for the Package. Also used by .packit.sh for Packit builds. - Version = "1.42.1" + Version = "1.43.2" // DefaultRuntime if containers.conf fails. DefaultRuntime = "runc" @@ -171,12 +171,12 @@ type SBOMScanOptions struct { // TempDirForURL checks if the passed-in string looks like a URL or "-". If it // is, TempDirForURL creates a temporary directory, arranges for its contents -// to be the contents of that URL, and returns the temporary directory's path, -// along with the relative name of a subdirectory which should be used as the -// build context (which may be empty or "."). Removal of the temporary -// directory is the responsibility of the caller. If the string doesn't look -// like a URL or "-", TempDirForURL returns empty strings and a nil error code. -func TempDirForURL(dir, prefix, url string) (name string, subdir string, err error) { +// to be the contents of that URL, and returns the temporary directory's path +// (for cleanup) and a relative subdirectory to the build context within it. +// Removal of the temporary directory is the responsibility of the caller. +// If the string doesn't look like a URL or "-", TempDirForURL returns empty +// strings and a nil error code. +func TempDirForURL(dir, prefix, url string) (tempDir string, relativeContextDir string, err error) { if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") && !strings.HasPrefix(url, "git://") && @@ -184,62 +184,67 @@ func TempDirForURL(dir, prefix, url string) (name string, subdir string, err err url != "-" { return "", "", nil } - name, err = os.MkdirTemp(dir, prefix) + tempDir, err = os.MkdirTemp(dir, prefix) if err != nil { return "", "", fmt.Errorf("creating temporary directory for %q: %w", url, err) } - downloadDir := filepath.Join(name, "download") + succeeded := false + defer func() { + if !succeeded { + if err2 := os.RemoveAll(tempDir); err2 != nil { + logrus.Errorf("error removing temporary directory %q: %v", tempDir, err2) + } + } + }() + + downloadDir := filepath.Join(tempDir, "download") if err = os.MkdirAll(downloadDir, 0o700); err != nil { return "", "", fmt.Errorf("creating directory %q for %q: %w", downloadDir, url, err) } - urlParsed, err := urlpkg.Parse(url) - if err != nil { - return "", "", fmt.Errorf("parsing url %q: %w", url, err) + + var contentSubdir string + urlParsed, parseErr := neturl.Parse(url) + if parseErr != nil { + return "", "", fmt.Errorf("parsing url %q: %w", url, parseErr) } - if strings.HasPrefix(url, "git://") || strings.HasSuffix(urlParsed.Path, ".git") { - combinedOutput, gitSubDir, err := cloneToDirectory(url, downloadDir) - if err != nil { - if err2 := os.RemoveAll(name); err2 != nil { - logrus.Debugf("error removing temporary directory %q: %v", name, err2) - } - return "", "", fmt.Errorf("cloning %q to %q:\n%s: %w", url, name, string(combinedOutput), err) + + isGitURL := urlParsed.Scheme == "git" || strings.HasSuffix(urlParsed.Path, ".git") + switch { + case isGitURL: + combinedOutput, gitSubDir, cloneErr := cloneToDirectory(url, downloadDir) + if cloneErr != nil { + return "", "", fmt.Errorf("cloning %q to %q:\n%s: %w", url, tempDir, string(combinedOutput), cloneErr) } - logrus.Debugf("Build context is at %q", filepath.Join(downloadDir, gitSubDir)) - return name, filepath.Join(filepath.Base(downloadDir), gitSubDir), nil - } - if strings.HasPrefix(url, "github.com/") { - ghurl := url - url = fmt.Sprintf("https://%s/archive/master.tar.gz", ghurl) - logrus.Debugf("resolving url %q to %q", ghurl, url) - subdir = path.Base(ghurl) + "-master" - } - if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") { - err = downloadToDirectory(url, downloadDir) - if err != nil { - if err2 := os.RemoveAll(name); err2 != nil { - logrus.Debugf("error removing temporary directory %q: %v", name, err2) - } + contentSubdir = gitSubDir + case strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://"): + if err = downloadToDirectory(url, downloadDir); err != nil { return "", "", err } - logrus.Debugf("Build context is at %q", filepath.Join(downloadDir, subdir)) - return name, filepath.Join(filepath.Base(downloadDir), subdir), nil - } - if url == "-" { - err = stdinToDirectory(downloadDir) - if err != nil { - if err2 := os.RemoveAll(name); err2 != nil { - logrus.Debugf("error removing temporary directory %q: %v", name, err2) - } + case strings.HasPrefix(url, "github.com/"): + ghURL := url + contentSubdir = path.Base(ghURL) + "-master" + downloadURL := fmt.Sprintf("https://%s/archive/master.tar.gz", ghURL) + logrus.Debugf("resolving url %q to %q", ghURL, downloadURL) + if err = downloadToDirectory(downloadURL, downloadDir); err != nil { + return "", "", err + } + case url == "-": + if err = stdinToDirectory(downloadDir); err != nil { return "", "", err } - logrus.Debugf("Build context is at %q", filepath.Join(downloadDir, subdir)) - return name, filepath.Join(filepath.Base(downloadDir), subdir), nil } - logrus.Debugf("don't know how to retrieve %q", url) - if err2 := os.RemoveAll(name); err2 != nil { - logrus.Debugf("error removing temporary directory %q: %v", name, err2) + + contextDir, err := securejoin.SecureJoin(downloadDir, contentSubdir) + if err != nil { + return "", "", fmt.Errorf("resolving subdirectory %q in %q: %w", contentSubdir, downloadDir, err) + } + relativeContextDir, err = filepath.Rel(tempDir, contextDir) + if err != nil { + return "", "", err } - return "", "", errors.New("unreachable code reached") + logrus.Debugf("Build context is at %q", contextDir) + succeeded = true + return tempDir, relativeContextDir, nil } // parseGitBuildContext parses git build context to `repo`, `sub-dir` @@ -316,6 +321,8 @@ func downloadToDirectory(url, dir string) error { if resp.ContentLength == 0 { return fmt.Errorf("no contents in %q", url) } + // Try to extract the response as a tar archive; if that fails, + // assume it is a raw Dockerfile and write it as such. if err := chrootarchive.Untar(resp.Body, dir, nil); err != nil { resp1, err := http.Get(url) if err != nil { @@ -326,10 +333,8 @@ func downloadToDirectory(url, dir string) error { if err != nil { return err } - dockerfile := filepath.Join(dir, "Dockerfile") - // Assume this is a Dockerfile - if err := ioutils.AtomicWriteFile(dockerfile, body, 0o600); err != nil { - return fmt.Errorf("failed to write %q to %q: %w", url, dockerfile, err) + if err := writeFileInRoot(dir, "Dockerfile", body, 0o600); err != nil { + return fmt.Errorf("failed to write %q to %q: %w", url, filepath.Join(dir, "Dockerfile"), err) } } return nil @@ -342,13 +347,43 @@ func stdinToDirectory(dir string) error { if err != nil { return fmt.Errorf("failed to read from stdin: %w", err) } + // Try to extract the buffered input as a tar archive; if that fails, + // assume it is a raw Dockerfile and write it as such. reader := bytes.NewReader(b) if err := chrootarchive.Untar(reader, dir, nil); err != nil { - dockerfile := filepath.Join(dir, "Dockerfile") - // Assume this is a Dockerfile - if err := ioutils.AtomicWriteFile(dockerfile, b, 0o600); err != nil { - return fmt.Errorf("failed to write bytes to %q: %w", dockerfile, err) + if err := writeFileInRoot(dir, "Dockerfile", b, 0o600); err != nil { + return fmt.Errorf("failed to write bytes to %q: %w", filepath.Join(dir, "Dockerfile"), err) } } return nil } + +// writeFileInRoot safely writes data to a file inside root, without following +// symlinks that escape the root directory. +func writeFileInRoot(root, name string, data []byte, perm os.FileMode) error { //nolint:unparam,nolintlint + // Above: + // unparam: 'name' currently only receives "Dockerfile" but will potentially support other files later + // nolintlint: the unparam linter only triggers if there are ≥ 4 instances; we do have that + // with --tests defaulting to true, but not with --tests=false. + + rootHandle, err := os.OpenRoot(root) + if err != nil { + return err + } + defer rootHandle.Close() + + if err := rootHandle.Remove(name); err != nil && !errors.Is(err, os.ErrNotExist) { + return err + } + + fileHandle, err := rootHandle.OpenFile(name, os.O_CREATE|os.O_EXCL|os.O_WRONLY, perm) + if err != nil { + return err + } + + _, err = fileHandle.Write(data) + if closeErr := fileHandle.Close(); closeErr != nil && err == nil { + err = closeErr + } + return err +} diff --git a/vendor/github.com/google/pprof/profile/profile.go b/vendor/github.com/google/pprof/profile/profile.go index 43f561d44..18df65a8d 100644 --- a/vendor/github.com/google/pprof/profile/profile.go +++ b/vendor/github.com/google/pprof/profile/profile.go @@ -278,7 +278,7 @@ func (p *Profile) massageMappings() { // Use heuristics to identify main binary and move it to the top of the list of mappings for i, m := range p.Mapping { - file := strings.TrimSpace(strings.Replace(m.File, "(deleted)", "", -1)) + file := strings.TrimSpace(strings.ReplaceAll(m.File, "(deleted)", "")) if len(file) == 0 { continue } diff --git a/vendor/github.com/google/pprof/profile/proto.go b/vendor/github.com/google/pprof/profile/proto.go index a15696ba1..31bf6bca6 100644 --- a/vendor/github.com/google/pprof/profile/proto.go +++ b/vendor/github.com/google/pprof/profile/proto.go @@ -36,6 +36,7 @@ package profile import ( "errors" "fmt" + "slices" ) type buffer struct { @@ -187,6 +188,16 @@ func le32(p []byte) uint32 { return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24 } +func peekNumVarints(data []byte) (numVarints int) { + for ; len(data) > 0; numVarints++ { + var err error + if _, data, err = decodeVarint(data); err != nil { + break + } + } + return numVarints +} + func decodeVarint(data []byte) (uint64, []byte, error) { var u uint64 for i := 0; ; i++ { @@ -286,6 +297,9 @@ func decodeInt64(b *buffer, x *int64) error { func decodeInt64s(b *buffer, x *[]int64) error { if b.typ == 2 { // Packed encoding + dataLen := peekNumVarints(b.data) + *x = slices.Grow(*x, dataLen) + data := b.data for len(data) > 0 { var u uint64 @@ -316,8 +330,11 @@ func decodeUint64(b *buffer, x *uint64) error { func decodeUint64s(b *buffer, x *[]uint64) error { if b.typ == 2 { - data := b.data // Packed encoding + dataLen := peekNumVarints(b.data) + *x = slices.Grow(*x, dataLen) + + data := b.data for len(data) > 0 { var u uint64 var err error diff --git a/vendor/github.com/mistifyio/go-zfs/v4/.envrc b/vendor/github.com/mistifyio/go-zfs/v3/.envrc similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/.envrc rename to vendor/github.com/mistifyio/go-zfs/v3/.envrc diff --git a/vendor/github.com/mistifyio/go-zfs/v4/.gitignore b/vendor/github.com/mistifyio/go-zfs/v3/.gitignore similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/.gitignore rename to vendor/github.com/mistifyio/go-zfs/v3/.gitignore diff --git a/vendor/github.com/mistifyio/go-zfs/v4/.golangci.yml b/vendor/github.com/mistifyio/go-zfs/v3/.golangci.yml similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/.golangci.yml rename to vendor/github.com/mistifyio/go-zfs/v3/.golangci.yml diff --git a/vendor/github.com/mistifyio/go-zfs/v4/.yamllint b/vendor/github.com/mistifyio/go-zfs/v3/.yamllint similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/.yamllint rename to vendor/github.com/mistifyio/go-zfs/v3/.yamllint diff --git a/vendor/github.com/mistifyio/go-zfs/v4/CHANGELOG.md b/vendor/github.com/mistifyio/go-zfs/v3/CHANGELOG.md similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/CHANGELOG.md rename to vendor/github.com/mistifyio/go-zfs/v3/CHANGELOG.md diff --git a/vendor/github.com/mistifyio/go-zfs/v4/CONTRIBUTING.md b/vendor/github.com/mistifyio/go-zfs/v3/CONTRIBUTING.md similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/CONTRIBUTING.md rename to vendor/github.com/mistifyio/go-zfs/v3/CONTRIBUTING.md diff --git a/vendor/github.com/mistifyio/go-zfs/v4/LICENSE b/vendor/github.com/mistifyio/go-zfs/v3/LICENSE similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/LICENSE rename to vendor/github.com/mistifyio/go-zfs/v3/LICENSE diff --git a/vendor/github.com/mistifyio/go-zfs/v4/Makefile b/vendor/github.com/mistifyio/go-zfs/v3/Makefile similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/Makefile rename to vendor/github.com/mistifyio/go-zfs/v3/Makefile diff --git a/vendor/github.com/mistifyio/go-zfs/v4/README.md b/vendor/github.com/mistifyio/go-zfs/v3/README.md similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/README.md rename to vendor/github.com/mistifyio/go-zfs/v3/README.md diff --git a/vendor/github.com/mistifyio/go-zfs/v4/Vagrantfile b/vendor/github.com/mistifyio/go-zfs/v3/Vagrantfile similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/Vagrantfile rename to vendor/github.com/mistifyio/go-zfs/v3/Vagrantfile diff --git a/vendor/github.com/mistifyio/go-zfs/v4/error.go b/vendor/github.com/mistifyio/go-zfs/v3/error.go similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/error.go rename to vendor/github.com/mistifyio/go-zfs/v3/error.go diff --git a/vendor/github.com/mistifyio/go-zfs/v4/lint.mk b/vendor/github.com/mistifyio/go-zfs/v3/lint.mk similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/lint.mk rename to vendor/github.com/mistifyio/go-zfs/v3/lint.mk diff --git a/vendor/github.com/mistifyio/go-zfs/v4/rules.mk b/vendor/github.com/mistifyio/go-zfs/v3/rules.mk similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/rules.mk rename to vendor/github.com/mistifyio/go-zfs/v3/rules.mk diff --git a/vendor/github.com/mistifyio/go-zfs/v4/shell.nix b/vendor/github.com/mistifyio/go-zfs/v3/shell.nix similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/shell.nix rename to vendor/github.com/mistifyio/go-zfs/v3/shell.nix diff --git a/vendor/github.com/mistifyio/go-zfs/v4/utils.go b/vendor/github.com/mistifyio/go-zfs/v3/utils.go similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/utils.go rename to vendor/github.com/mistifyio/go-zfs/v3/utils.go diff --git a/vendor/github.com/mistifyio/go-zfs/v4/utils_notsolaris.go b/vendor/github.com/mistifyio/go-zfs/v3/utils_notsolaris.go similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/utils_notsolaris.go rename to vendor/github.com/mistifyio/go-zfs/v3/utils_notsolaris.go diff --git a/vendor/github.com/mistifyio/go-zfs/v4/utils_solaris.go b/vendor/github.com/mistifyio/go-zfs/v3/utils_solaris.go similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/utils_solaris.go rename to vendor/github.com/mistifyio/go-zfs/v3/utils_solaris.go diff --git a/vendor/github.com/mistifyio/go-zfs/v4/zfs.go b/vendor/github.com/mistifyio/go-zfs/v3/zfs.go similarity index 99% rename from vendor/github.com/mistifyio/go-zfs/v4/zfs.go rename to vendor/github.com/mistifyio/go-zfs/v3/zfs.go index dbcbc8ae3..1166bdc21 100644 --- a/vendor/github.com/mistifyio/go-zfs/v4/zfs.go +++ b/vendor/github.com/mistifyio/go-zfs/v3/zfs.go @@ -312,7 +312,7 @@ func (d *Dataset) SetProperty(key, val string) error { // A full list of available ZFS properties may be found in the ZFS manual: // https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html. func (d *Dataset) GetProperty(key string) (string, error) { - out, err := zfsOutput("get", "-Hp", key, d.Name) + out, err := zfsOutput("get", "-H", key, d.Name) if err != nil { return "", err } diff --git a/vendor/github.com/mistifyio/go-zfs/v4/zpool.go b/vendor/github.com/mistifyio/go-zfs/v3/zpool.go similarity index 100% rename from vendor/github.com/mistifyio/go-zfs/v4/zpool.go rename to vendor/github.com/mistifyio/go-zfs/v3/zpool.go diff --git a/vendor/github.com/redhat-et/GKM/mcv/pkg/cache/cache.go b/vendor/github.com/redhat-et/GKM/mcv/pkg/cache/cache.go index 2bd47158d..08d779b64 100644 --- a/vendor/github.com/redhat-et/GKM/mcv/pkg/cache/cache.go +++ b/vendor/github.com/redhat-et/GKM/mcv/pkg/cache/cache.go @@ -162,7 +162,7 @@ func SetCachesBuildDir(caches []Cache, path string) { } } -func ExtractCacheDirectory(r io.Reader, cacheType string) ([]string, int64, error) { +func ExtractCacheDirectory(r io.Reader, cacheType string) (extractedDirs []string, extractedBytes int64, err error) { if cacheType == "" { return nil, 0, fmt.Errorf("cache type is empty") } @@ -180,9 +180,7 @@ func ExtractCacheDirectory(r io.Reader, cacheType string) ([]string, int64, erro func extractCacheAndManifestDirectory( r io.Reader, cacheDirPrefix, manifestDirPrefix, extractCacheDir, extractManifestDir string, -) ([]string, int64, error) { - var extractedDirs []string - var extractedBytes int64 +) (extractedDirs []string, extractedBytes int64, err error) { gr, err := gzip.NewReader(r) if err != nil { return nil, 0, fmt.Errorf("failed to parse layer as tar.gz: %v", err) diff --git a/vendor/github.com/redhat-et/GKM/mcv/pkg/cache/triton.go b/vendor/github.com/redhat-et/GKM/mcv/pkg/cache/triton.go index 3b7efe13f..d1b49b0fc 100644 --- a/vendor/github.com/redhat-et/GKM/mcv/pkg/cache/triton.go +++ b/vendor/github.com/redhat-et/GKM/mcv/pkg/cache/triton.go @@ -363,7 +363,7 @@ func (t *TritonCache) SetTmpPath(path string) { } } -func ExtractTritonCacheDirectory(r io.Reader) ([]string, int64, error) { +func ExtractTritonCacheDirectory(r io.Reader) (extractedDirs []string, extractedBytes int64, err error) { return extractCacheAndManifestDirectory( r, constants.MCVTritonCacheDir, diff --git a/vendor/github.com/redhat-et/GKM/mcv/pkg/cache/vllm.go b/vendor/github.com/redhat-et/GKM/mcv/pkg/cache/vllm.go index 08d3689d5..0192ddd19 100644 --- a/vendor/github.com/redhat-et/GKM/mcv/pkg/cache/vllm.go +++ b/vendor/github.com/redhat-et/GKM/mcv/pkg/cache/vllm.go @@ -817,7 +817,7 @@ func (v *VLLMCache) SetTmpPath(path string) { // Extracts the vllm cache and manifest in a given reader for tar.gz. // This is only used for *compat* variant. -func ExtractVLLMCacheDirectory(r io.Reader) ([]string, int64, error) { +func ExtractVLLMCacheDirectory(r io.Reader) (extractedDirs []string, extractedBytes int64, err error) { return extractCacheAndManifestDirectory( r, constants.MCVVLLMCacheDir, diff --git a/vendor/github.com/redhat-et/GKM/mcv/pkg/fetcher/imgfetcher.go b/vendor/github.com/redhat-et/GKM/mcv/pkg/fetcher/imgfetcher.go index 827568080..70aaa95da 100644 --- a/vendor/github.com/redhat-et/GKM/mcv/pkg/fetcher/imgfetcher.go +++ b/vendor/github.com/redhat-et/GKM/mcv/pkg/fetcher/imgfetcher.go @@ -293,7 +293,7 @@ func (i *imgMgr) FetchAndExtractCache(imgName string) error { // extractOCIArtifactImg extracts the triton/vllm cache from the // *oci* variant Kernel Cache image: //TODO ADD URL -func extractOCIArtifactImg(img v1.Image, cacheType string) ([]string, int64, error) { +func extractOCIArtifactImg(img v1.Image, cacheType string) (extractedDirs []string, extractedBytes int64, err error) { if cacheType == "" { return nil, 0, fmt.Errorf("cache type is empty") } @@ -351,7 +351,7 @@ func isCompatLayerMediaType(mt types.MediaType) bool { // extractCompatImg extracts cache from compat-format images (standard tar.gz layers). // See mcv/docs/spec-compat.md. -func extractCompatImg(img v1.Image, cacheType string) ([]string, int64, error) { +func extractCompatImg(img v1.Image, cacheType string) (extractedDirs []string, extractedBytes int64, err error) { if cacheType == "" { return nil, 0, fmt.Errorf("cache type is empty") } @@ -380,8 +380,6 @@ func extractCompatImg(img v1.Image, cacheType string) ([]string, int64, error) { return nil, 0, errors.New("no compat layers found (expect docker or OCI gzip layer media type)") } - var allDirs []string - var totalBytes int64 for _, layer := range compatLayers { r, err := layer.Compressed() if err != nil { @@ -393,10 +391,10 @@ func extractCompatImg(img v1.Image, cacheType string) ([]string, int64, error) { if err != nil { return nil, 0, fmt.Errorf("could not extract %s Kernel Cache: %v", cacheType, err) } - allDirs = append(allDirs, dirs...) - totalBytes += bytesWritten + extractedDirs = append(extractedDirs, dirs...) + extractedBytes += bytesWritten } - return allDirs, totalBytes, nil + return extractedDirs, extractedBytes, nil } // validateExtractedCacheSize validates that the extracted cache size matches the image label. diff --git a/vendor/github.com/secure-systems-lab/go-securesystemslib/dsse/envelope.go b/vendor/github.com/secure-systems-lab/go-securesystemslib/dsse/envelope.go index 8e48cc6fe..933057650 100644 --- a/vendor/github.com/secure-systems-lab/go-securesystemslib/dsse/envelope.go +++ b/vendor/github.com/secure-systems-lab/go-securesystemslib/dsse/envelope.go @@ -1,8 +1,10 @@ package dsse import ( + "bytes" "encoding/base64" "fmt" + "strconv" ) /* @@ -42,9 +44,27 @@ PAE implements the DSSE Pre-Authentic Encoding https://github.com/secure-systems-lab/dsse/blob/master/protocol.md#signature-definition */ func PAE(payloadType string, payload []byte) []byte { - return []byte(fmt.Sprintf("DSSEv1 %d %s %d %s", - len(payloadType), payloadType, - len(payload), payload)) + // Pre-size to avoid reallocation. Previously fmt.Sprintf copied payload + // into a string and []byte(...) copied it again. + const prefix = "DSSEv1 " + const sep = " " + // Max decimal digits for a non-negative int (len() result) on any + // platform: len("9223372036854775807") == 19. Grow is a hint, so a + // slight overestimate is harmless. + const maxDecimalLen = 19 + var b bytes.Buffer + b.Grow(len(prefix) + + maxDecimalLen + len(sep) + len(payloadType) + len(sep) + + maxDecimalLen + len(sep) + len(payload)) + b.WriteString(prefix) + b.WriteString(strconv.Itoa(len(payloadType))) + b.WriteByte(' ') + b.WriteString(payloadType) + b.WriteByte(' ') + b.WriteString(strconv.Itoa(len(payload))) + b.WriteByte(' ') + b.Write(payload) + return b.Bytes() } /* diff --git a/vendor/github.com/secure-systems-lab/go-securesystemslib/dsse/verify.go b/vendor/github.com/secure-systems-lab/go-securesystemslib/dsse/verify.go index 034e4faaf..5c83d2ec0 100644 --- a/vendor/github.com/secure-systems-lab/go-securesystemslib/dsse/verify.go +++ b/vendor/github.com/secure-systems-lab/go-securesystemslib/dsse/verify.go @@ -24,18 +24,26 @@ type AcceptedKey struct { } func (ev *EnvelopeVerifier) Verify(ctx context.Context, e *Envelope) ([]AcceptedKey, error) { + keys, _, err := ev.VerifyAndDecode(ctx, e) + return keys, err +} + +// VerifyAndDecode behaves identically to Verify but also returns the decoded +// envelope payload, allowing callers who need the payload bytes (e.g., for +// hashing or further parsing) to avoid a second base64 decode. +func (ev *EnvelopeVerifier) VerifyAndDecode(ctx context.Context, e *Envelope) ([]AcceptedKey, []byte, error) { if e == nil { - return nil, errors.New("cannot verify a nil envelope") + return nil, nil, errors.New("cannot verify a nil envelope") } if len(e.Signatures) == 0 { - return nil, ErrNoSignature + return nil, nil, ErrNoSignature } // Decode payload (i.e serialized body) body, err := e.DecodeB64Payload() if err != nil { - return nil, err + return nil, nil, err } // Generate PAE(payloadtype, serialized body) paeEnc := PAE(e.PayloadType, body) @@ -48,7 +56,7 @@ func (ev *EnvelopeVerifier) Verify(ctx context.Context, e *Envelope) ([]Accepted for _, s := range e.Signatures { sig, err := b64Decode(s.Sig) if err != nil { - return nil, err + return nil, nil, err } // Loop over the providers. @@ -97,14 +105,14 @@ func (ev *EnvelopeVerifier) Verify(ctx context.Context, e *Envelope) ([]Accepted // Sanity if with some reflect magic this happens. if ev.threshold <= 0 || ev.threshold > len(ev.providers) { - return nil, errors.New("invalid threshold") + return nil, nil, errors.New("invalid threshold") } if len(usedKeyids) < ev.threshold { - return acceptedKeys, fmt.Errorf("accepted signatures do not match threshold, Found: %d, Expected %d", len(acceptedKeys), ev.threshold) + return acceptedKeys, nil, fmt.Errorf("accepted signatures do not match threshold, Found: %d, Expected %d", len(acceptedKeys), ev.threshold) } - return acceptedKeys, nil + return acceptedKeys, body, nil } func NewEnvelopeVerifier(v ...Verifier) (*EnvelopeVerifier, error) { diff --git a/vendor/github.com/sigstore/rekor/pkg/client/rekor_client.go b/vendor/github.com/sigstore/rekor/pkg/client/rekor_client.go index 5f55aa983..cf3060f37 100644 --- a/vendor/github.com/sigstore/rekor/pkg/client/rekor_client.go +++ b/vendor/github.com/sigstore/rekor/pkg/client/rekor_client.go @@ -15,7 +15,10 @@ package client import ( + "bytes" "crypto/tls" + "fmt" + "io" "net/http" "net/url" @@ -29,6 +32,36 @@ import ( "github.com/sigstore/rekor/pkg/util" ) +// maxErrorBodyBytes caps how much of the final response body we embed in +// the error message to avoid flooding terminals with large payloads. +const maxErrorBodyBytes = 512 + +// retryErrorHandler makes the final error surfaced after retries include the +// underlying cause (transport error or final response status + body snippet). +// Without a custom handler retryablehttp's default message is just +// " giving up after N attempt(s)", which hides the actual +// reason the retries failed — especially when the server returned an error +// response (5xx) rather than a transport error. See +// https://github.com/sigstore/rekor/issues/2640. +func retryErrorHandler(resp *http.Response, err error, numTries int) (*http.Response, error) { + if err != nil { + return nil, fmt.Errorf("giving up after %d attempt(s): %w", numTries, err) + } + if resp != nil { + defer resp.Body.Close() + body, readErr := io.ReadAll(io.LimitReader(resp.Body, maxErrorBodyBytes)) + snippet := string(bytes.TrimSpace(body)) + if readErr == nil && snippet != "" { + return nil, fmt.Errorf("giving up after %d attempt(s): status %d: %s", + numTries, resp.StatusCode, snippet) + } + return nil, fmt.Errorf("giving up after %d attempt(s): status %d", + numTries, resp.StatusCode) + } + + return nil, fmt.Errorf("giving up after %d attempt(s)", numTries) +} + func GetRekorClient(rekorServerURL string, opts ...Option) (*client.Rekor, error) { url, err := url.Parse(rekorServerURL) if err != nil { @@ -54,6 +87,7 @@ func GetRekorClient(rekorServerURL string, opts ...Option) (*client.Rekor, error retryableClient.RetryWaitMin = o.RetryWaitMin retryableClient.RetryWaitMax = o.RetryWaitMax retryableClient.Logger = o.Logger + retryableClient.ErrorHandler = retryErrorHandler httpClient := retryableClient.StandardClient() httpClient.Transport = createRoundTripper(httpClient.Transport, o) diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/create_log_entry_parameters.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/create_log_entry_parameters.go index 481fa2bda..5a7418e53 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/create_log_entry_parameters.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/create_log_entry_parameters.go @@ -18,9 +18,6 @@ package entries -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "net/http" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/create_log_entry_responses.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/create_log_entry_responses.go index de665ed9c..198047ed0 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/create_log_entry_responses.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/create_log_entry_responses.go @@ -18,9 +18,6 @@ package entries -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "encoding/json" stderrors "errors" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/entries_client.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/entries_client.go index 24f633cf6..713b0ef67 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/entries_client.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/entries_client.go @@ -18,9 +18,6 @@ package entries -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "github.com/go-openapi/runtime" httptransport "github.com/go-openapi/runtime/client" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_index_parameters.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_index_parameters.go index e22522751..8ec6c2804 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_index_parameters.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_index_parameters.go @@ -18,9 +18,6 @@ package entries -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "net/http" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_index_responses.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_index_responses.go index 40e17b3cf..6be99b7e4 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_index_responses.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_index_responses.go @@ -18,9 +18,6 @@ package entries -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "encoding/json" stderrors "errors" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_uuid_parameters.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_uuid_parameters.go index 5c88b5265..ddd769ad9 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_uuid_parameters.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_uuid_parameters.go @@ -18,9 +18,6 @@ package entries -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "net/http" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_uuid_responses.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_uuid_responses.go index 3498e2728..9ea6b57f1 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_uuid_responses.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/get_log_entry_by_uuid_responses.go @@ -18,9 +18,6 @@ package entries -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "encoding/json" stderrors "errors" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/search_log_query_parameters.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/search_log_query_parameters.go index ed158ce23..ce248ff9a 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/search_log_query_parameters.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/search_log_query_parameters.go @@ -18,9 +18,6 @@ package entries -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "net/http" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/search_log_query_responses.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/search_log_query_responses.go index 13d5ba278..7891f4b91 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/search_log_query_responses.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/entries/search_log_query_responses.go @@ -18,9 +18,6 @@ package entries -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "encoding/json" stderrors "errors" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/index/index_client.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/index/index_client.go index 80db49031..8acf59d4d 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/index/index_client.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/index/index_client.go @@ -18,9 +18,6 @@ package index -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "github.com/go-openapi/runtime" httptransport "github.com/go-openapi/runtime/client" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/index/search_index_parameters.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/index/search_index_parameters.go index c1694193e..90f2e0f32 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/index/search_index_parameters.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/index/search_index_parameters.go @@ -18,9 +18,6 @@ package index -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "net/http" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/index/search_index_responses.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/index/search_index_responses.go index 8c62eca17..951a1254d 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/index/search_index_responses.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/index/search_index_responses.go @@ -18,9 +18,6 @@ package index -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "encoding/json" stderrors "errors" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/pubkey/get_public_key_parameters.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/pubkey/get_public_key_parameters.go index b4248c933..b649e0897 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/pubkey/get_public_key_parameters.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/pubkey/get_public_key_parameters.go @@ -18,9 +18,6 @@ package pubkey -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "net/http" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/pubkey/get_public_key_responses.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/pubkey/get_public_key_responses.go index 70dbc452a..923ee3cf6 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/pubkey/get_public_key_responses.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/pubkey/get_public_key_responses.go @@ -18,9 +18,6 @@ package pubkey -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "encoding/json" stderrors "errors" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/pubkey/pubkey_client.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/pubkey/pubkey_client.go index 7f4db7d8c..d2ed8be91 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/pubkey/pubkey_client.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/pubkey/pubkey_client.go @@ -18,9 +18,6 @@ package pubkey -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "github.com/go-openapi/runtime" httptransport "github.com/go-openapi/runtime/client" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/rekor_client.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/rekor_client.go index bee381118..131c7e163 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/rekor_client.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/rekor_client.go @@ -18,9 +18,6 @@ package client -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "github.com/go-openapi/runtime" httptransport "github.com/go-openapi/runtime/client" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_info_parameters.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_info_parameters.go index e0ae2cdd3..764c2e9d4 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_info_parameters.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_info_parameters.go @@ -18,9 +18,6 @@ package tlog -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "net/http" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_info_responses.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_info_responses.go index 3d98f88cd..5b69389de 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_info_responses.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_info_responses.go @@ -18,9 +18,6 @@ package tlog -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "encoding/json" stderrors "errors" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_proof_parameters.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_proof_parameters.go index 2b21ad887..505ca2cbb 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_proof_parameters.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_proof_parameters.go @@ -18,9 +18,6 @@ package tlog -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "net/http" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_proof_responses.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_proof_responses.go index ae8e50d28..d025173d2 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_proof_responses.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/get_log_proof_responses.go @@ -18,9 +18,6 @@ package tlog -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "encoding/json" stderrors "errors" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/tlog_client.go b/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/tlog_client.go index ff174ebfa..c58fe252c 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/tlog_client.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/client/tlog/tlog_client.go @@ -18,9 +18,6 @@ package tlog -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "github.com/go-openapi/runtime" httptransport "github.com/go-openapi/runtime/client" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/alpine.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/alpine.go index 5607679fd..d3c460e73 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/alpine.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/alpine.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "bytes" "context" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/alpine_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/alpine_schema.go index 00f76926c..646b414b4 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/alpine_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/alpine_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - // AlpineSchema Alpine Package Schema // // # Schema for Alpine package objects diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/alpine_v001_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/alpine_v001_schema.go index c77008ce7..f748022d5 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/alpine_v001_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/alpine_v001_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "encoding/json" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/consistency_proof.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/consistency_proof.go index 804ddd11a..ae87d835f 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/consistency_proof.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/consistency_proof.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "strconv" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/cose.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/cose.go index 8de4083ba..58cd4e3b1 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/cose.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/cose.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "bytes" "context" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/cose_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/cose_schema.go index 8f9016050..325a8a6ab 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/cose_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/cose_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - // CoseSchema COSE Schema // // # COSE for Rekord objects diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/cose_v001_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/cose_v001_schema.go index 9dafe29ce..69a3c0c65 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/cose_v001_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/cose_v001_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "encoding/json" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/dsse.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/dsse.go index dde562054..40b48b304 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/dsse.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/dsse.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "bytes" "context" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/dsse_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/dsse_schema.go index 0dc5c87ed..e9526fc0f 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/dsse_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/dsse_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - // DSSESchema DSSE Schema // // log entry schema for dsse envelopes diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/dsse_v001_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/dsse_v001_schema.go index 8cad568da..efbcff175 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/dsse_v001_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/dsse_v001_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "encoding/json" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/error.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/error.go index ac14f2026..6dcec446c 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/error.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/error.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/hashedrekord.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/hashedrekord.go index b3e1f8a3b..1c2c48bdb 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/hashedrekord.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/hashedrekord.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "bytes" "context" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/hashedrekord_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/hashedrekord_schema.go index 67fc8abab..960dd131b 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/hashedrekord_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/hashedrekord_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - // HashedrekordSchema Hashedrekord Schema // // # Schema for Hashedrekord objects diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/hashedrekord_v001_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/hashedrekord_v001_schema.go index 866842e56..85b3fcbb3 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/hashedrekord_v001_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/hashedrekord_v001_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "encoding/json" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/helm.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/helm.go index d19b8bc8c..3cab983af 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/helm.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/helm.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "bytes" "context" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/helm_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/helm_schema.go index 305a9e16f..4952e3738 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/helm_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/helm_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - // HelmSchema Helm Schema // // # Schema for Helm objects diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/helm_v001_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/helm_v001_schema.go index 1d52e1e4f..3274e1d09 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/helm_v001_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/helm_v001_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "encoding/json" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/inactive_shard_log_info.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/inactive_shard_log_info.go index c555eb2da..7cbcdc9c2 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/inactive_shard_log_info.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/inactive_shard_log_info.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/inclusion_proof.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/inclusion_proof.go index 86f0d7b94..a228b27f9 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/inclusion_proof.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/inclusion_proof.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "strconv" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto.go index 4f208de1d..6a79e4868 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "bytes" "context" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto_schema.go index 142f0a194..2e09d5db1 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - // IntotoSchema Intoto Schema // // # Intoto for Rekord objects diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto_v001_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto_v001_schema.go index d3a6ca42f..912a34c52 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto_v001_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto_v001_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "encoding/json" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto_v002_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto_v002_schema.go index 4ea4dcc58..c3a4c959c 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto_v002_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/intoto_v002_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "encoding/json" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/jar.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/jar.go index 3df3d21b8..71d25cd70 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/jar.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/jar.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "bytes" "context" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/jar_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/jar_schema.go index 0cd3126ef..aedf7c3fd 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/jar_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/jar_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - // JarSchema JAR Schema // // # Schema for JAR objects diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/jar_v001_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/jar_v001_schema.go index 64335c368..f3808966b 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/jar_v001_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/jar_v001_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "encoding/json" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/log_entry.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/log_entry.go index 65cf4f4b7..bd25ee737 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/log_entry.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/log_entry.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" stderrors "errors" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/log_info.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/log_info.go index 6cbb9d64a..b42dfbb24 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/log_info.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/log_info.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" stderrors "errors" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/proposed_entry.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/proposed_entry.go index 5b734a5ff..141730a18 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/proposed_entry.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/proposed_entry.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "bytes" "context" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/rekord.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/rekord.go index 81c8ff054..d86285072 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/rekord.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/rekord.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "bytes" "context" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/rekord_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/rekord_schema.go index 9c33e4044..52f03af05 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/rekord_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/rekord_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - // RekordSchema Rekor Schema // // # Schema for Rekord objects diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/rekord_v001_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/rekord_v001_schema.go index 0f4977ca7..ab3a32336 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/rekord_v001_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/rekord_v001_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "encoding/json" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/rfc3161.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/rfc3161.go index ef8d42e7a..b18aa31a7 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/rfc3161.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/rfc3161.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "bytes" "context" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/rfc3161_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/rfc3161_schema.go index 319358d40..536a1bc74 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/rfc3161_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/rfc3161_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - // Rfc3161Schema Timestamp Schema // // # Schema for RFC 3161 timestamp objects diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/rfc3161_v001_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/rfc3161_v001_schema.go index c2037cd7a..a2d7a3642 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/rfc3161_v001_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/rfc3161_v001_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" stderrors "errors" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/rpm.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/rpm.go index 8b1f10c77..4ff2a264e 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/rpm.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/rpm.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "bytes" "context" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/rpm_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/rpm_schema.go index 2520dfb9c..22b6749ca 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/rpm_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/rpm_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - // RpmSchema RPM Schema // // # Schema for RPM objects diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/rpm_v001_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/rpm_v001_schema.go index a7636bd5f..4506414a4 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/rpm_v001_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/rpm_v001_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "encoding/json" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/search_index.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/search_index.go index 98f7ee84c..ff672558a 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/search_index.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/search_index.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" "encoding/json" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/search_log_query.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/search_log_query.go index 6833c8f6d..874f51f07 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/search_log_query.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/search_log_query.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "bytes" "context" @@ -42,7 +39,7 @@ import ( type SearchLogQuery struct { entriesField []ProposedEntry - // entry u UI ds + // entry UUIDs // Max Items: 10 // Min Items: 1 EntryUUIDs []string `json:"entryUUIDs"` diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/tuf.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/tuf.go index a5f6eff0f..98997da59 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/tuf.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/tuf.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "bytes" "context" diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/tuf_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/tuf_schema.go index 7c944ef92..71f17ca84 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/tuf_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/tuf_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - // TUFSchema TUF Schema // // # Schema for TUF metadata objects diff --git a/vendor/github.com/sigstore/rekor/pkg/generated/models/tuf_v001_schema.go b/vendor/github.com/sigstore/rekor/pkg/generated/models/tuf_v001_schema.go index 69b5e93d6..b66058702 100644 --- a/vendor/github.com/sigstore/rekor/pkg/generated/models/tuf_v001_schema.go +++ b/vendor/github.com/sigstore/rekor/pkg/generated/models/tuf_v001_schema.go @@ -18,9 +18,6 @@ package models -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - import ( "context" stderrors "errors" diff --git a/vendor/github.com/sigstore/rekor/pkg/types/dsse/dsse.go b/vendor/github.com/sigstore/rekor/pkg/types/dsse/dsse.go index 9036fe562..9b8272967 100644 --- a/vendor/github.com/sigstore/rekor/pkg/types/dsse/dsse.go +++ b/vendor/github.com/sigstore/rekor/pkg/types/dsse/dsse.go @@ -55,6 +55,10 @@ func (it BaseDSSEType) UnmarshalEntry(pe models.ProposedEntry) (types.EntryImpl, return nil, errors.New("cannot unmarshal non-DSSE types") } + if in.APIVersion == nil { + return nil, errors.New("api version cannot be nil") + } + return it.VersionedUnmarshal(in, *in.APIVersion) } diff --git a/vendor/github.com/sigstore/rekor/pkg/types/dsse/v0.0.1/entry.go b/vendor/github.com/sigstore/rekor/pkg/types/dsse/v0.0.1/entry.go index 2914bffbe..2d4379330 100644 --- a/vendor/github.com/sigstore/rekor/pkg/types/dsse/v0.0.1/entry.go +++ b/vendor/github.com/sigstore/rekor/pkg/types/dsse/v0.0.1/entry.go @@ -57,6 +57,24 @@ func init() { type V001Entry struct { DSSEObj models.DSSEV001Schema env *dsse.Envelope + + // memory optimization: extract and store these during Unmarshal + // so we can clear the huge payload from memory + extractedIndexKeys []string + isInsertable bool +} + +type indexKeyExtract struct { + Subject []struct { + Digest map[string]string `json:"digest"` + } `json:"subject"` + Predicate json.RawMessage `json:"predicate"` +} + +type materialsExtract struct { + Materials []struct { + Digest map[string]string `json:"digest"` + } `json:"materials"` } func (v V001Entry) APIVersion() string { @@ -108,58 +126,13 @@ func (v V001Entry) IndexKeys() ([]string, error) { return result, nil } - switch v.env.PayloadType { - case in_toto.PayloadType: - - if v.env.Payload == "" { - log.Logger.Info("DSSEObj DSSE payload is empty") - return result, nil - } - decodedPayload, err := v.env.DecodeB64Payload() - if err != nil { - return result, fmt.Errorf("could not decode envelope payload: %w", err) - } - statement, err := parseStatement(decodedPayload) - if err != nil { - return result, err - } - for _, s := range statement.Subject { - for alg, ds := range s.Digest { - result = append(result, alg+":"+ds) - } - } - // Not all in-toto statements will contain a SLSA provenance predicate. - // See https://github.com/in-toto/attestation/blob/main/spec/README.md#predicate - // for other predicates. - if predicate, err := parseSlsaPredicate(decodedPayload); err == nil { - if predicate.Predicate.Materials != nil { - for _, s := range predicate.Predicate.Materials { - for alg, ds := range s.Digest { - result = append(result, alg+":"+ds) - } - } - } - } - default: + if v.env.PayloadType == in_toto.PayloadType { + result = append(result, v.extractedIndexKeys...) + } else { log.Logger.Infof("Unknown DSSE envelope payloadType: %s", v.env.PayloadType) } - return result, nil -} - -func parseStatement(p []byte) (*in_toto.Statement, error) { - ps := in_toto.Statement{} - if err := json.Unmarshal(p, &ps); err != nil { - return nil, err - } - return &ps, nil -} -func parseSlsaPredicate(p []byte) (*in_toto.ProvenanceStatement, error) { - predicate := in_toto.ProvenanceStatement{} - if err := json.Unmarshal(p, &predicate); err != nil { - return nil, err - } - return &predicate, nil + return result, nil } // DecodeEntry performs direct decode into the provided output pointer @@ -344,6 +317,28 @@ func (v *V001Entry) Unmarshal(pe models.ProposedEntry) error { return err } + // extraction of index keys - done here so we can clear the huge strings from memory + if env.PayloadType == in_toto.PayloadType { + var extract indexKeyExtract + if err := json.Unmarshal(decodedPayload, &extract); err == nil { + for _, s := range extract.Subject { + for alg, ds := range s.Digest { + v.extractedIndexKeys = append(v.extractedIndexKeys, alg+":"+ds) + } + } + if extract.Predicate != nil { + var materials materialsExtract + if err := json.Unmarshal(extract.Predicate, &materials); err == nil { + for _, m := range materials.Materials { + for alg, ds := range m.Digest { + v.extractedIndexKeys = append(v.extractedIndexKeys, alg+":"+ds) + } + } + } + } + } + } + payloadHash := sha256.Sum256(decodedPayload) dsseObj.PayloadHash = &models.DSSEV001SchemaPayloadHash{ Algorithm: conv.Pointer(models.DSSEV001SchemaPayloadHashAlgorithmSha256), @@ -359,6 +354,11 @@ func (v *V001Entry) Unmarshal(pe models.ProposedEntry) error { // we've gotten through all processing without error, now update the object we're unmarshalling into v.DSSEObj = *dsseObj v.env = env + v.isInsertable = true + + // memory optimization: clear huge strings/buffers + v.env.Payload = "" + v.DSSEObj.ProposedContent = nil return nil } @@ -533,6 +533,9 @@ func (v V001Entry) ArtifactHash() (string, error) { } func (v V001Entry) Insertable() (bool, error) { + if v.isInsertable { + return true, nil + } if v.DSSEObj.ProposedContent == nil { return false, errors.New("missing proposed content") } diff --git a/vendor/github.com/sigstore/rekor/pkg/types/entries.go b/vendor/github.com/sigstore/rekor/pkg/types/entries.go index 06a8525bd..a39bff407 100644 --- a/vendor/github.com/sigstore/rekor/pkg/types/entries.go +++ b/vendor/github.com/sigstore/rekor/pkg/types/entries.go @@ -22,6 +22,7 @@ import ( "fmt" "net/url" "reflect" + "sync/atomic" "github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer" "github.com/go-openapi/strfmt" @@ -60,6 +61,33 @@ type ProposedEntryIterator interface { // EntryFactory describes a factory function that can generate structs for a specific versioned type type EntryFactory func() EntryImpl +// allowedKindsForSubmission restricts the set of kinds that CreateVersionedEntry +// will accept. +// This restriction only applies to the insertion path. Read paths are unaffected +// so that entries written to the log under a previous configuration are still readable. +var allowedKindsForSubmission atomic.Pointer[map[string]struct{}] + +// SetAllowedKindsForSubmission configures the set of kinds that CreateVersionedEntry +// will accept. +func SetAllowedKindsForSubmission(kinds []string) { + m := make(map[string]struct{}, len(kinds)) + for _, k := range kinds { + m[k] = struct{}{} + } + allowedKindsForSubmission.Store(&m) +} + +// isKindAllowedForSubmission reports whether the given kind may be inserted +// into the log via CreateVersionedEntry. +func isKindAllowedForSubmission(kind string) bool { + m := allowedKindsForSubmission.Load() + if m == nil { + return true + } + _, ok := (*m)[kind] + return ok +} + func NewProposedEntry(ctx context.Context, kind, version string, props ArtifactProperties) (models.ProposedEntry, error) { if tf, found := TypeMap.Load(kind); found { t := tf.(func() TypeImpl)() @@ -80,6 +108,9 @@ func CreateVersionedEntry(pe models.ProposedEntry) (EntryImpl, error) { return nil, err } kind := pe.Kind() + if !isKindAllowedForSubmission(kind) { + return nil, fmt.Errorf("entry kind '%v' is not enabled for submission on this server", kind) + } if tf, found := TypeMap.Load(kind); found { if !tf.(func() TypeImpl)().IsSupportedVersion(ei.APIVersion()) { return nil, fmt.Errorf("entry kind '%v' does not support inserting entries of version '%v'", kind, ei.APIVersion()) diff --git a/vendor/github.com/sigstore/rekor/pkg/types/hashedrekord/hashedrekord.go b/vendor/github.com/sigstore/rekor/pkg/types/hashedrekord/hashedrekord.go index 66395c7a0..778d9e5b4 100644 --- a/vendor/github.com/sigstore/rekor/pkg/types/hashedrekord/hashedrekord.go +++ b/vendor/github.com/sigstore/rekor/pkg/types/hashedrekord/hashedrekord.go @@ -55,6 +55,10 @@ func (rt BaseRekordType) UnmarshalEntry(pe models.ProposedEntry) (types.EntryImp return nil, fmt.Errorf("cannot unmarshal non-hashed Rekord types: %s", pe.Kind()) } + if rekord.APIVersion == nil { + return nil, errors.New("api version cannot be nil") + } + return rt.VersionedUnmarshal(rekord, *rekord.APIVersion) } diff --git a/vendor/github.com/sigstore/rekor/pkg/types/intoto/intoto.go b/vendor/github.com/sigstore/rekor/pkg/types/intoto/intoto.go index 2bfba3946..8aa2b8ddc 100644 --- a/vendor/github.com/sigstore/rekor/pkg/types/intoto/intoto.go +++ b/vendor/github.com/sigstore/rekor/pkg/types/intoto/intoto.go @@ -57,6 +57,10 @@ func (it BaseIntotoType) UnmarshalEntry(pe models.ProposedEntry) (types.EntryImp return nil, errors.New("cannot unmarshal non-Rekord types") } + if in.APIVersion == nil { + return nil, errors.New("api version cannot be nil") + } + return it.VersionedUnmarshal(in, *in.APIVersion) } diff --git a/vendor/github.com/sigstore/rekor/pkg/types/rekord/rekord.go b/vendor/github.com/sigstore/rekor/pkg/types/rekord/rekord.go index 902dbf71e..c02d05d73 100644 --- a/vendor/github.com/sigstore/rekor/pkg/types/rekord/rekord.go +++ b/vendor/github.com/sigstore/rekor/pkg/types/rekord/rekord.go @@ -55,6 +55,10 @@ func (rt BaseRekordType) UnmarshalEntry(pe models.ProposedEntry) (types.EntryImp return nil, errors.New("cannot unmarshal non-Rekord types") } + if rekord.APIVersion == nil { + return nil, errors.New("api version cannot be nil") + } + return rt.VersionedUnmarshal(rekord, *rekord.APIVersion) } diff --git a/vendor/github.com/sigstore/rekor/pkg/types/types.go b/vendor/github.com/sigstore/rekor/pkg/types/types.go index 72722321b..5e327d42e 100644 --- a/vendor/github.com/sigstore/rekor/pkg/types/types.go +++ b/vendor/github.com/sigstore/rekor/pkg/types/types.go @@ -73,11 +73,21 @@ func (rt *RekorType) IsSupportedVersion(proposedVersion string) bool { return slices.Contains(rt.SupportedVersions(), proposedVersion) } +// ListSupportedKinds returns all loaded entry kinds +func ListSupportedKinds() []string { + var l []string + TypeMap.Range(func(k, _ any) bool { + l = append(l, k.(string)) + return true + }) + return l +} + // ListImplementedTypes returns a list of all type strings currently known to // be implemented func ListImplementedTypes() []string { retVal := []string{} - TypeMap.Range(func(k interface{}, v interface{}) bool { + TypeMap.Range(func(k, v any) bool { tf := v.(func() TypeImpl) for _, verStr := range tf().SupportedVersions() { retVal = append(retVal, fmt.Sprintf("%v:%v", k.(string), verStr)) diff --git a/vendor/github.com/sigstore/rekor/pkg/verify/verify.go b/vendor/github.com/sigstore/rekor/pkg/verify/verify.go index 61846923b..7081d34d6 100644 --- a/vendor/github.com/sigstore/rekor/pkg/verify/verify.go +++ b/vendor/github.com/sigstore/rekor/pkg/verify/verify.go @@ -145,7 +145,10 @@ func VerifyInclusion(ctx context.Context, e *models.LogEntryAnon) error { hashes := [][]byte{} for _, h := range e.Verification.InclusionProof.Hashes { - hb, _ := hex.DecodeString(h) + hb, err := hex.DecodeString(h) + if err != nil { + return err + } hashes = append(hashes, hb) } @@ -155,7 +158,11 @@ func VerifyInclusion(ctx context.Context, e *models.LogEntryAnon) error { } // Verify the inclusion proof. - entryBytes, err := base64.StdEncoding.DecodeString(e.Body.(string)) + b, ok := e.Body.(string) + if !ok { + return fmt.Errorf("entry body must be a string, was %T", e.Body) + } + entryBytes, err := base64.StdEncoding.DecodeString(b) if err != nil { return err } diff --git a/vendor/go.podman.io/common/libimage/platform.go b/vendor/go.podman.io/common/libimage/platform.go index 20c0f3c1d..6be272c43 100644 --- a/vendor/go.podman.io/common/libimage/platform.go +++ b/vendor/go.podman.io/common/libimage/platform.go @@ -8,24 +8,20 @@ import ( ) // PlatformPolicy controls the behavior of image-platform matching. -// // Deprecated: new code should use define.PlatformPolicy directly. type PlatformPolicy = define.PlatformPolicy const ( // Only debug log if an image does not match the expected platform. - // // Deprecated: new code should reference define.PlatformPolicyDefault directly. PlatformPolicyDefault = define.PlatformPolicyDefault // Warn if an image does not match the expected platform. - // // Deprecated: new code should reference define.PlatformPolicyWarn directly. PlatformPolicyWarn = define.PlatformPolicyWarn ) // NormalizePlatform normalizes (according to the OCI spec) the specified os, // arch and variant. If left empty, the individual item will be normalized. -// // Deprecated: new code should call libimage/platform.Normalize() instead. func NormalizePlatform(rawOS, rawArch, rawVariant string) (os, arch, variant string) { return platform.Normalize(rawOS, rawArch, rawVariant) diff --git a/vendor/go.podman.io/common/libnetwork/types/network.go b/vendor/go.podman.io/common/libnetwork/types/network.go index 5b15d0803..bc383a5aa 100644 --- a/vendor/go.podman.io/common/libnetwork/types/network.go +++ b/vendor/go.podman.io/common/libnetwork/types/network.go @@ -97,11 +97,12 @@ type NetworkUpdateOptions struct { // NetworkInfo contains the network information. type NetworkInfo struct { - Backend NetworkBackend `json:"backend"` - Version string `json:"version,omitempty"` - Package string `json:"package,omitempty"` - Path string `json:"path,omitempty"` - DNS DNSNetworkInfo `json:"dns,omitempty"` + Backend NetworkBackend `json:"backend"` + Version string `json:"version,omitempty"` + Package string `json:"package,omitempty"` + Path string `json:"path,omitempty"` + DNS DNSNetworkInfo `json:"dns,omitempty"` + DefaultNetwork string `json:"defaultNetwork,omitempty"` } // DNSNetworkInfo contains the DNS information. @@ -322,7 +323,6 @@ type PortMapping struct { } // OCICNIPortMapping maps to the standard CNI portmapping Capability. -// // Deprecated: Do not use this struct for new fields. This only exists // for backwards compatibility. type OCICNIPortMapping struct { diff --git a/vendor/go.podman.io/common/pkg/config/config.go b/vendor/go.podman.io/common/pkg/config/config.go index ae0587f7b..afc45bd7f 100644 --- a/vendor/go.podman.io/common/pkg/config/config.go +++ b/vendor/go.podman.io/common/pkg/config/config.go @@ -248,7 +248,6 @@ type ContainersConfig struct { UserNS string `toml:"userns,omitempty"` // UserNSSize how many UIDs to allocate for automatically created UserNS - // // Deprecated: no user of this field is known. UserNSSize int `toml:"userns_size,omitempty,omitzero"` } @@ -559,7 +558,6 @@ type EngineConfig struct { // PodmanshTimeout is the number of seconds to wait for podmansh logins. // In other words, the timeout for the `podmansh` container to be in running // state. - // // Deprecated: Use podmansh.Timeout instead. podmansh.Timeout has precedence. PodmanshTimeout uint `toml:"podmansh_timeout,omitempty,omitzero"` } @@ -1081,8 +1079,10 @@ func findBindir() string { } execPath, err := os.Executable() if err == nil { - // Resolve symbolic links to find the actual binary file path. - execPath, err = filepath.EvalSymlinks(execPath) + // Resolve symlinks for the binary path. + // On Windows, an additional symlink check is performed; + // on other platforms, this is equivalent to filepath.EvalSymlinks. + execPath, err = safeEvalSymlinks(execPath) } if err != nil { // If failed to find executable (unlikely to happen), warn about it. diff --git a/vendor/go.podman.io/common/pkg/config/config_unix.go b/vendor/go.podman.io/common/pkg/config/config_unix.go index 97befd152..a67c418c0 100644 --- a/vendor/go.podman.io/common/pkg/config/config_unix.go +++ b/vendor/go.podman.io/common/pkg/config/config_unix.go @@ -33,3 +33,7 @@ func userConfigPath() (string, error) { func overrideContainersConfigPath() (string, error) { return overrideContainersConfig, nil } + +func safeEvalSymlinks(filePath string) (string, error) { + return filepath.EvalSymlinks(filePath) +} diff --git a/vendor/go.podman.io/common/pkg/config/config_windows.go b/vendor/go.podman.io/common/pkg/config/config_windows.go index bbaac5ad5..95c8ee235 100644 --- a/vendor/go.podman.io/common/pkg/config/config_windows.go +++ b/vendor/go.podman.io/common/pkg/config/config_windows.go @@ -1,6 +1,10 @@ package config -import "os" +import ( + "io/fs" + "os" + "path/filepath" +) const ( // _configPath is the path to the containers/containers.conf @@ -31,5 +35,29 @@ func overrideContainersConfigPath() (string, error) { } var defaultHelperBinariesDir = []string{ - "C:\\Program Files\\RedHat\\Podman", + // FindHelperBinaries(), as a convention, interprets $BINDIR as the + // directory where the current process binary (i.e. podman) is located. + "$BINDIR", +} + +func safeEvalSymlinks(filePath string) (string, error) { + fileInfo, err := os.Lstat(filePath) + if err != nil { + return "", err + } + if fileInfo.Mode()&fs.ModeSymlink != 0 { + // Only call filepath.EvalSymlinks if it is a symlink. + // Starting with v1.23, EvalSymlinks returns an error for mount points. + // See https://go-review.googlesource.com/c/go/+/565136 for reference. + filePath, err = filepath.EvalSymlinks(filePath) + if err != nil { + return "", err + } + } else { + // Call filepath.Clean when filePath is not a symlink. That's for + // consistency with the symlink case (filepath.EvalSymlinks calls + // Clean after evaluating filePath). + filePath = filepath.Clean(filePath) + } + return filePath, nil } diff --git a/vendor/go.podman.io/common/pkg/config/containers.conf b/vendor/go.podman.io/common/pkg/config/containers.conf index fd337831c..1c9fe54c3 100644 --- a/vendor/go.podman.io/common/pkg/config/containers.conf +++ b/vendor/go.podman.io/common/pkg/config/containers.conf @@ -216,12 +216,12 @@ default_sysctls = [ # #log_driver = "k8s-file" -# Default path for container logs to be stored in. When empty, logs will be stored +# Default path for container logs to be stored in. When empty, logs will be stored # in the container's default storage and removed when the container is removed. -# A subdirectory named with the container ID will be created under the specified +# A subdirectory named with the container ID will be created under the specified # path, and the log file will have the default name `ctr.log` within that directory. # This option can be overridden by the `--log-opt` flag. -# +# #log_path = "" # Maximum size allowed for the container log file. Negative numbers indicate @@ -542,10 +542,14 @@ default_sysctls = [ # #enable_port_reservation = true -# Environment variables to be used when running the container engine (e.g., Podman, Buildah). -# For example "http_proxy=internal.proxy.company.com". -# Note these environment variables will not be used within the container. -# Set the env section under [containers] table, if you want to set environment variables for the container. +# Environment variables to be used when running the container engine (e.g., +# Podman, Buildah). For example "MYVAR=value". These environment variables +# will not be used within the container. Set the env section under the +# [containers] table, if you want to set environment variables for the +# container. +# Note when using this to set http proxy variables then they might get +# leaked into the container depending on if `http_proxy` (under the +# [containers] table) is set to to true (default) or false. # #env = [] @@ -909,7 +913,7 @@ default_sysctls = [ # "https://example.com/linux/amd64/foobar.ami" on a Linux AMD machine. # If unspecified, the default Podman machine image will be used. # -#image = "docker://quay.io/podman/machine-os" +#image = "" # Memory in MB a machine is created with. # diff --git a/vendor/go.podman.io/common/pkg/config/containers.conf-freebsd b/vendor/go.podman.io/common/pkg/config/containers.conf-freebsd index bd999c339..6a8163066 100644 --- a/vendor/go.podman.io/common/pkg/config/containers.conf-freebsd +++ b/vendor/go.podman.io/common/pkg/config/containers.conf-freebsd @@ -169,12 +169,12 @@ default_sysctls = [ # #log_driver = "k8s-file" -# Default path for container logs to be stored in. When empty, logs will be stored +# Default path for container logs to be stored in. When empty, logs will be stored # in the container's default storage and removed when the container is removed. -# A subdirectory named with the container ID will be created under the specified +# A subdirectory named with the container ID will be created under the specified # path, and the log file will have the default name `ctr.log` within that directory. # This option can be overridden by the `--log-opt` flag. -# +# #log_path = "" # Maximum size allowed for the container log file. Negative numbers indicate @@ -393,10 +393,14 @@ default_sysctls = [ # #enable_port_reservation = true -# Environment variables to be used when running the container engine (e.g., Podman, Buildah). -# For example "http_proxy=internal.proxy.company.com". -# Note these environment variables will not be used within the container. -# Set the env section under [containers] table, if you want to set environment variables for the container. +# Environment variables to be used when running the container engine (e.g., +# Podman, Buildah). For example "MYVAR=value". These environment variables +# will not be used within the container. Set the env section under the +# [containers] table, if you want to set environment variables for the +# container. +# Note when using this to set http proxy variables then they might get +# leaked into the container depending on if `http_proxy` (under the +# [containers] table) is set to to true (default) or false. # #env = [] diff --git a/vendor/go.podman.io/common/pkg/config/default.go b/vendor/go.podman.io/common/pkg/config/default.go index 54402d171..3bf0bc169 100644 --- a/vendor/go.podman.io/common/pkg/config/default.go +++ b/vendor/go.podman.io/common/pkg/config/default.go @@ -192,7 +192,6 @@ const ( // DefaultShmSize is the default upper limit on the size of tmpfs mounts. DefaultShmSize = "65536k" // DefaultUserNSSize indicates the default number of UIDs allocated for user namespace within a container. - // // Deprecated: no user of this field is known. DefaultUserNSSize = 65536 // OCIBufSize limits maximum LogSizeMax. @@ -306,11 +305,14 @@ func defaultMachineConfig() MachineConfig { return MachineConfig{ CPUs: uint64(cpus), DiskSize: 100, - Image: "docker://quay.io/podman/machine-os", - Memory: 2048, - User: getDefaultMachineUser(), - Volumes: attributedstring.NewSlice(getDefaultMachineVolumes()), - Rosetta: true, + // TODO: Set machine image default here + // Currently the default is set in Podman as we need time to stabilize + // VM images and locations between different providers. + Image: "", + Memory: 2048, + User: getDefaultMachineUser(), + Volumes: attributedstring.NewSlice(getDefaultMachineVolumes()), + Rosetta: true, } } diff --git a/vendor/go.podman.io/common/version/version.go b/vendor/go.podman.io/common/version/version.go index 4a2be1fe1..cad567fb9 100644 --- a/vendor/go.podman.io/common/version/version.go +++ b/vendor/go.podman.io/common/version/version.go @@ -1,4 +1,4 @@ package version // Version is the version of the build. -const Version = "0.67.0-dev" +const Version = "0.67.1" diff --git a/vendor/go.podman.io/image/v5/copy/blob.go b/vendor/go.podman.io/image/v5/copy/blob.go index 9db6338d7..a881e0623 100644 --- a/vendor/go.podman.io/image/v5/copy/blob.go +++ b/vendor/go.podman.io/image/v5/copy/blob.go @@ -18,8 +18,7 @@ import ( // and returns a complete blobInfo of the copied blob. func (ic *imageCopier) copyBlobFromStream(ctx context.Context, srcReader io.Reader, srcInfo types.BlobInfo, getOriginalLayerCopyWriter func(decompressor compressiontypes.DecompressorFunc) io.Writer, - isConfig bool, toEncrypt bool, bar *progressBar, layerIndex int, emptyLayer bool, -) (types.BlobInfo, error) { + isConfig bool, toEncrypt bool, bar *progressBar, layerIndex int, emptyLayer bool) (types.BlobInfo, error) { // The copying happens through a pipeline of connected io.Readers; // that pipeline is built by updating stream. // === Input: srcReader diff --git a/vendor/go.podman.io/image/v5/copy/compression.go b/vendor/go.podman.io/image/v5/copy/compression.go index 5b57bf176..e3e523029 100644 --- a/vendor/go.podman.io/image/v5/copy/compression.go +++ b/vendor/go.podman.io/image/v5/copy/compression.go @@ -109,8 +109,7 @@ const ( // Returns data for other steps; the caller should eventually call updateCompressionEdits and perhaps recordValidatedBlobData, // and must eventually call close. func (ic *imageCopier) blobPipelineCompressionStep(stream *sourceStream, canModifyBlob bool, srcInfo types.BlobInfo, - detected bpDetectCompressionStepData, -) (*bpCompressionStepData, error) { + detected bpDetectCompressionStepData) (*bpCompressionStepData, error) { // WARNING: If you are adding new reasons to change the blob, update also the OptimizeDestinationImageAlreadyExists // short-circuit conditions layerCompressionChangeSupported := ic.src.CanChangeLayerCompression(stream.info.MediaType) @@ -266,8 +265,7 @@ func (ic *imageCopier) bpcDecompressCompressed(stream *sourceStream, detected bp // This does not change the sourceStream parameter; we include it for symmetry with other // pipeline steps. func (ic *imageCopier) bpcPreserveOriginal(_ *sourceStream, detected bpDetectCompressionStepData, - layerCompressionChangeSupported bool, -) *bpCompressionStepData { + layerCompressionChangeSupported bool) *bpCompressionStepData { logrus.Debugf("Using original blob without modification") // Remember if the original blob was compressed, and if so how, so that if // LayerInfosForCopy() returned something that differs from what was in the @@ -322,8 +320,7 @@ func (d *bpCompressionStepData) updateCompressionEdits(operation *types.LayerCom // and the original srcInfo (which the caller guarantees has been validated). // This must ONLY be called if all data has been validated by OUR code, and is not coming from third parties. func (d *bpCompressionStepData) recordValidatedDigestData(c *copier, uploadedInfo types.BlobInfo, srcInfo types.BlobInfo, - encryptionStep *bpEncryptionStepData, decryptionStep *bpDecryptionStepData, -) error { + encryptionStep *bpEncryptionStepData, decryptionStep *bpDecryptionStepData) error { // Don’t record any associations that involve encrypted data. This is a bit crude, // some blob substitutions (replacing pulls of encrypted data with local reuse of known decryption outcomes) // might be safe, but it’s not trivially obvious, so let’s be conservative for now. diff --git a/vendor/go.podman.io/image/v5/copy/encryption.go b/vendor/go.podman.io/image/v5/copy/encryption.go index 0b7396d8a..59aecf1a1 100644 --- a/vendor/go.podman.io/image/v5/copy/encryption.go +++ b/vendor/go.podman.io/image/v5/copy/encryption.go @@ -84,8 +84,7 @@ type bpEncryptionStepData struct { // srcInfo is primarily used for error messages. // Returns data for other steps; the caller should eventually call updateCryptoOperationAndAnnotations. func (ic *imageCopier) blobPipelineEncryptionStep(stream *sourceStream, toEncrypt bool, srcInfo types.BlobInfo, - decryptionStep *bpDecryptionStepData, -) (*bpEncryptionStepData, error) { + decryptionStep *bpDecryptionStepData) (*bpEncryptionStepData, error) { if !toEncrypt || isOciEncrypted(srcInfo.MediaType) || ic.c.options.OciEncryptConfig == nil { return &bpEncryptionStepData{ encrypting: false, diff --git a/vendor/go.podman.io/image/v5/copy/multiple.go b/vendor/go.podman.io/image/v5/copy/multiple.go index 85bba7288..0594aa20f 100644 --- a/vendor/go.podman.io/image/v5/copy/multiple.go +++ b/vendor/go.podman.io/image/v5/copy/multiple.go @@ -60,9 +60,8 @@ func platformV1ToPlatformComparable(platform *imgspecv1.Platform) platformCompar } osFeatures := slices.Clone(platform.OSFeatures) sort.Strings(osFeatures) - return platformComparable{ - architecture: platform.Architecture, - os: platform.OS, + return platformComparable{architecture: platform.Architecture, + os: platform.OS, // This is strictly speaking ambiguous, fields of OSFeatures can contain a ','. Probably good enough for now. osFeatures: strings.Join(osFeatures, ","), osVersion: platform.OSVersion, @@ -253,8 +252,7 @@ func (c *copier) copyMultipleImages(ctx context.Context) (copiedManifest []byte, UpdateDigest: updated.manifestDigest, UpdateSize: int64(len(updated.manifest)), UpdateCompressionAlgorithms: updated.compressionAlgorithms, - UpdateMediaType: updated.manifestMIMEType, - }) + UpdateMediaType: updated.manifestMIMEType}) case instanceCopyClone: logrus.Debugf("Replicating instance %s (%d/%d)", instance.sourceDigest, i+1, len(instanceCopyList)) c.Printf("Replicating image %s (%d/%d)\n", instance.sourceDigest, i+1, len(instanceCopyList)) @@ -262,8 +260,7 @@ func (c *copier) copyMultipleImages(ctx context.Context) (copiedManifest []byte, updated, err := c.copySingleImage(ctx, unparsedInstance, &instanceCopyList[i].sourceDigest, copySingleImageOptions{ requireCompressionFormatMatch: true, compressionFormat: &instance.cloneCompressionVariant.Algorithm, - compressionLevel: instance.cloneCompressionVariant.Level, - }) + compressionLevel: instance.cloneCompressionVariant.Level}) if err != nil { return nil, fmt.Errorf("replicating image %d/%d from manifest list: %w", i+1, len(instanceCopyList), err) } diff --git a/vendor/go.podman.io/image/v5/copy/sign.go b/vendor/go.podman.io/image/v5/copy/sign.go index 70295538d..96038f3f8 100644 --- a/vendor/go.podman.io/image/v5/copy/sign.go +++ b/vendor/go.podman.io/image/v5/copy/sign.go @@ -54,8 +54,7 @@ func (c *copier) setupSigners() error { // and verifies that they can be used (to avoid copying a large image when we // can tell in advance that it would ultimately fail) func (c *copier) sourceSignatures(ctx context.Context, unparsed private.UnparsedImage, - gettingSignaturesMessage, checkingDestMessage string, -) ([]internalsig.Signature, error) { + gettingSignaturesMessage, checkingDestMessage string) ([]internalsig.Signature, error) { var sigs []internalsig.Signature if c.options.RemoveSignatures { sigs = []internalsig.Signature{} diff --git a/vendor/go.podman.io/image/v5/copy/single.go b/vendor/go.podman.io/image/v5/copy/single.go index 588ad9ab3..36d221133 100644 --- a/vendor/go.podman.io/image/v5/copy/single.go +++ b/vendor/go.podman.io/image/v5/copy/single.go @@ -386,14 +386,14 @@ func (ic *imageCopier) compareImageDestinationManifestEqual(ctx context.Context, destImageSource, err := ic.c.dest.Reference().NewImageSource(ctx, ic.c.options.DestinationCtx) if err != nil { - logrus.Debugf("Unable to create destination image %s source: %v", ic.c.dest.Reference(), err) + logrus.Debugf("Unable to create destination image %s source: %v", transports.ImageName(ic.c.dest.Reference()), err) return nil, nil } defer destImageSource.Close() destManifest, destManifestType, err := destImageSource.GetManifest(ctx, targetInstance) if err != nil { - logrus.Debugf("Unable to get destination image %s/%s manifest: %v", destImageSource, targetInstance, err) + logrus.Debugf("Unable to get destination image %s/%s manifest: %v", transports.ImageName(destImageSource.Reference()), targetInstance, err) return nil, nil } @@ -934,8 +934,7 @@ func updatedBlobInfoFromReuse(inputInfo types.BlobInfo, reusedBlob private.Reuse // perhaps (de/re/)compressing the stream, // and returns a complete blobInfo of the copied blob and perhaps a <-chan diffIDResult if diffIDIsNeeded, to be read by the caller. func (ic *imageCopier) copyLayerFromStream(ctx context.Context, srcStream io.Reader, srcInfo types.BlobInfo, - diffIDIsNeeded bool, toEncrypt bool, bar *progressBar, layerIndex int, emptyLayer bool, -) (types.BlobInfo, <-chan diffIDResult, error) { + diffIDIsNeeded bool, toEncrypt bool, bar *progressBar, layerIndex int, emptyLayer bool) (types.BlobInfo, <-chan diffIDResult, error) { var getDiffIDRecorder func(compressiontypes.DecompressorFunc) io.Writer // = nil var diffIDChan chan diffIDResult diff --git a/vendor/go.podman.io/image/v5/directory/directory_dest.go b/vendor/go.podman.io/image/v5/directory/directory_dest.go index fc82c969f..31842f726 100644 --- a/vendor/go.podman.io/image/v5/directory/directory_dest.go +++ b/vendor/go.podman.io/image/v5/directory/directory_dest.go @@ -90,12 +90,12 @@ func newImageDestination(sys *types.SystemContext, ref dirReference) (private.Im } } else { // create directory if it doesn't exist - if err := os.MkdirAll(ref.resolvedPath, 0o755); err != nil { + if err := os.MkdirAll(ref.resolvedPath, 0755); err != nil { return nil, fmt.Errorf("unable to create directory %q: %w", ref.resolvedPath, err) } } // create version file - err = os.WriteFile(ref.versionPath(), []byte(version), 0o644) + err = os.WriteFile(ref.versionPath(), []byte(version), 0644) if err != nil { return nil, fmt.Errorf("creating version file %q: %w", ref.versionPath(), err) } @@ -170,7 +170,7 @@ func (d *dirImageDestination) PutBlobWithOptions(ctx context.Context, stream io. // ignored and the file is already readable; besides, blobFile.Chmod, i.e. syscall.Fchmod, // always fails on Windows. if runtime.GOOS != "windows" { - if err := blobFile.Chmod(0o644); err != nil { + if err := blobFile.Chmod(0644); err != nil { return private.UploadedBlob{}, err } } @@ -228,7 +228,7 @@ func (d *dirImageDestination) PutManifest(ctx context.Context, manifest []byte, if err != nil { return err } - return os.WriteFile(path, manifest, 0o644) + return os.WriteFile(path, manifest, 0644) } // PutSignaturesWithFormat writes a set of signatures to the destination. @@ -245,7 +245,7 @@ func (d *dirImageDestination) PutSignaturesWithFormat(ctx context.Context, signa if err != nil { return err } - if err := os.WriteFile(path, blob, 0o644); err != nil { + if err := os.WriteFile(path, blob, 0644); err != nil { return err } } diff --git a/vendor/go.podman.io/image/v5/docker/archive/transport.go b/vendor/go.podman.io/image/v5/docker/archive/transport.go index a1b77adbe..706655ddc 100644 --- a/vendor/go.podman.io/image/v5/docker/archive/transport.go +++ b/vendor/go.podman.io/image/v5/docker/archive/transport.go @@ -110,8 +110,7 @@ func NewIndexReference(path string, sourceIndex int) (types.ImageReference, erro // newReference returns a docker archive reference for a path, an optional reference or sourceIndex, // and optionally a tarfile.Reader and/or a tarfile.Writer matching path. func newReference(path string, ref reference.NamedTagged, sourceIndex int, - archiveReader *tarfile.Reader, writer *Writer, -) (types.ImageReference, error) { + archiveReader *tarfile.Reader, writer *Writer) (types.ImageReference, error) { if strings.Contains(path, ":") { return nil, fmt.Errorf("Invalid docker-archive: reference: colon in path %q is not supported", path) } diff --git a/vendor/go.podman.io/image/v5/docker/archive/writer.go b/vendor/go.podman.io/image/v5/docker/archive/writer.go index ea8375bea..0a59d89d0 100644 --- a/vendor/go.podman.io/image/v5/docker/archive/writer.go +++ b/vendor/go.podman.io/image/v5/docker/archive/writer.go @@ -32,7 +32,7 @@ func NewWriter(sys *types.SystemContext, path string) (*Writer, error) { // in the case of a regular file, we don't want to overwrite any pre-existing file // so we check for Size() == 0 below (This is racy, but using O_EXCL would also be racy, // only in a different way. Either way, it’s up to the user to not have two writers to the same path.) - fh, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0o644) + fh, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644) if err != nil { return nil, fmt.Errorf("opening file %q: %w", path, err) } diff --git a/vendor/go.podman.io/image/v5/docker/daemon/daemon_dest.go b/vendor/go.podman.io/image/v5/docker/daemon/daemon_dest.go index ebf7d238e..337ba6331 100644 --- a/vendor/go.podman.io/image/v5/docker/daemon/daemon_dest.go +++ b/vendor/go.podman.io/image/v5/docker/daemon/daemon_dest.go @@ -38,7 +38,10 @@ func newImageDestination(ctx context.Context, sys *types.SystemContext, ref daem return nil, fmt.Errorf("Invalid destination docker-daemon:%s: a destination must be a name:tag", ref.StringWithinTransport()) } - mustMatchRuntimeOS := sys == nil || sys.DockerDaemonHost == client.DefaultDockerHost + var mustMatchRuntimeOS = true + if sys != nil && sys.DockerDaemonHost != client.DefaultDockerHost { + mustMatchRuntimeOS = false + } c, err := newDockerClient(sys) if err != nil { diff --git a/vendor/go.podman.io/image/v5/docker/docker_client.go b/vendor/go.podman.io/image/v5/docker/docker_client.go index b166bfbf2..b6079b0a0 100644 --- a/vendor/go.podman.io/image/v5/docker/docker_client.go +++ b/vendor/go.podman.io/image/v5/docker/docker_client.go @@ -823,8 +823,7 @@ func (c *dockerClient) obtainBearerToken(ctx context.Context, challenge challeng // https://github.com/distribution/distribution/blob/main/docs/spec/auth/oauth.md for challenge and scopes, // and writes it into dest. func (c *dockerClient) getBearerTokenOAuth2(ctx context.Context, dest *bearerToken, challenge challenge, - scopes []authScope, -) error { + scopes []authScope) error { realm, ok := challenge.Parameters["realm"] if !ok { return errors.New("missing realm in bearer auth challenge") @@ -871,8 +870,7 @@ func (c *dockerClient) getBearerTokenOAuth2(ctx context.Context, dest *bearerTok // https://github.com/distribution/distribution/blob/main/docs/spec/auth/token.md for challenge and scopes, // and writes it into dest. func (c *dockerClient) getBearerToken(ctx context.Context, dest *bearerToken, challenge challenge, - scopes []authScope, -) error { + scopes []authScope) error { realm, ok := challenge.Parameters["realm"] if !ok { return errors.New("missing realm in bearer auth challenge") @@ -972,6 +970,11 @@ func (c *dockerClient) detectPropertiesHelper(ctx context.Context) error { if c.sys != nil && c.sys.DockerProxyURL != nil { tr.Proxy = http.ProxyURL(c.sys.DockerProxyURL) } + if c.sys != nil && c.sys.DockerProxy != nil { + tr.Proxy = func(request *http.Request) (*url.URL, error) { + return c.sys.DockerProxy(request.URL) + } + } c.client = &http.Client{Transport: tr} ping := func(scheme string) error { diff --git a/vendor/go.podman.io/image/v5/docker/docker_image_dest.go b/vendor/go.podman.io/image/v5/docker/docker_image_dest.go index 2172d0adc..86077fe93 100644 --- a/vendor/go.podman.io/image/v5/docker/docker_image_dest.go +++ b/vendor/go.podman.io/image/v5/docker/docker_image_dest.go @@ -679,7 +679,7 @@ func (d *dockerImageDestination) putOneSignature(sigURL *url.URL, sig signature. switch sigURL.Scheme { case "file": logrus.Debugf("Writing to %s", sigURL.Path) - err := os.MkdirAll(filepath.Dir(sigURL.Path), 0o755) + err := os.MkdirAll(filepath.Dir(sigURL.Path), 0755) if err != nil { return err } @@ -687,7 +687,7 @@ func (d *dockerImageDestination) putOneSignature(sigURL *url.URL, sig signature. if err != nil { return err } - err = os.WriteFile(sigURL.Path, blob, 0o644) + err = os.WriteFile(sigURL.Path, blob, 0644) if err != nil { return err } @@ -800,8 +800,7 @@ func (d *dockerImageDestination) putSignaturesToSigstoreAttachments(ctx context. } func layerMatchesSigstoreSignature(layer imgspecv1.Descriptor, mimeType string, - payloadBlob []byte, annotations map[string]string, -) bool { + payloadBlob []byte, annotations map[string]string) bool { if layer.MediaType != mimeType || layer.Size != int64(len(payloadBlob)) || // This is not quite correct, we should use the layer’s digest algorithm. diff --git a/vendor/go.podman.io/image/v5/docker/docker_image_src.go b/vendor/go.podman.io/image/v5/docker/docker_image_src.go index 4003af5d2..553dddeef 100644 --- a/vendor/go.podman.io/image/v5/docker/docker_image_src.go +++ b/vendor/go.podman.io/image/v5/docker/docker_image_src.go @@ -129,8 +129,7 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, ref dockerRef // Given a logicalReference and a pullSource, return a dockerImageSource if it is reachable. // The caller must call .Close() on the returned ImageSource. func newImageSourceAttempt(ctx context.Context, sys *types.SystemContext, logicalRef dockerReference, pullSource sysregistriesv2.PullSource, - registryConfig *registryConfiguration, -) (*dockerImageSource, error) { + registryConfig *registryConfiguration) (*dockerImageSource, error) { physicalRef, err := newReference(pullSource.Reference, false) if err != nil { return nil, err diff --git a/vendor/go.podman.io/image/v5/docker/internal/tarfile/dest.go b/vendor/go.podman.io/image/v5/docker/internal/tarfile/dest.go index d078f4dae..812749bad 100644 --- a/vendor/go.podman.io/image/v5/docker/internal/tarfile/dest.go +++ b/vendor/go.podman.io/image/v5/docker/internal/tarfile/dest.go @@ -39,8 +39,7 @@ type Destination struct { // NewDestination returns a tarfile.Destination adding images to the specified Writer. // commitWithOptions implements ImageDestination.CommitWithOptions. func NewDestination(sys *types.SystemContext, archive *Writer, transportName string, ref reference.NamedTagged, - commitWithOptions func(ctx context.Context, options private.CommitOptions) error, -) *Destination { + commitWithOptions func(ctx context.Context, options private.CommitOptions) error) *Destination { repoTags := []reference.NamedTagged{} if ref != nil { repoTags = append(repoTags, ref) diff --git a/vendor/go.podman.io/image/v5/docker/internal/tarfile/writer.go b/vendor/go.podman.io/image/v5/docker/internal/tarfile/writer.go index 604da073a..460224f44 100644 --- a/vendor/go.podman.io/image/v5/docker/internal/tarfile/writer.go +++ b/vendor/go.podman.io/image/v5/docker/internal/tarfile/writer.go @@ -338,26 +338,21 @@ type tarFI struct { func (t *tarFI) Name() string { return t.path } - func (t *tarFI) Size() int64 { return t.size } - func (t *tarFI) Mode() os.FileMode { if t.isSymlink { return os.ModeSymlink } - return 0o444 + return 0444 } - func (t *tarFI) ModTime() time.Time { return time.Unix(0, 0) } - func (t *tarFI) IsDir() bool { return false } - func (t *tarFI) Sys() any { return nil } diff --git a/vendor/go.podman.io/image/v5/internal/manifest/common.go b/vendor/go.podman.io/image/v5/internal/manifest/common.go index 623362cf7..1f2ccb528 100644 --- a/vendor/go.podman.io/image/v5/internal/manifest/common.go +++ b/vendor/go.podman.io/image/v5/internal/manifest/common.go @@ -26,8 +26,7 @@ const ( // identification/version, or other “magic numbers”) before calling this, to cleanly reject unambiguous // data that just isn’t what was expected, as opposed to actually ambiguous data. func ValidateUnambiguousManifestFormat(manifest []byte, expectedMIMEType string, - allowed AllowedManifestFields, -) error { + allowed AllowedManifestFields) error { if allowed >= AllowedFieldFirstUnusedBit { return fmt.Errorf("internal error: invalid allowedManifestFields value %#v", allowed) } diff --git a/vendor/go.podman.io/image/v5/internal/manifest/docker_schema2_list.go b/vendor/go.podman.io/image/v5/internal/manifest/docker_schema2_list.go index 47a5699fb..fdcc42083 100644 --- a/vendor/go.podman.io/image/v5/internal/manifest/docker_schema2_list.go +++ b/vendor/go.podman.io/image/v5/internal/manifest/docker_schema2_list.go @@ -82,8 +82,7 @@ func (list *Schema2ListPublic) UpdateInstances(updates []ListUpdate) error { UpdateDigest: instance.Digest, UpdateSize: instance.Size, UpdateMediaType: instance.MediaType, - ListOperation: ListOpUpdate, - }) + ListOperation: ListOpUpdate}) } return list.editInstances(editInstances) } diff --git a/vendor/go.podman.io/image/v5/internal/manifest/oci_index.go b/vendor/go.podman.io/image/v5/internal/manifest/oci_index.go index 922c8754c..046d8e607 100644 --- a/vendor/go.podman.io/image/v5/internal/manifest/oci_index.go +++ b/vendor/go.podman.io/image/v5/internal/manifest/oci_index.go @@ -79,8 +79,7 @@ func (index *OCI1IndexPublic) UpdateInstances(updates []ListUpdate) error { UpdateDigest: instance.Digest, UpdateSize: instance.Size, UpdateMediaType: instance.MediaType, - ListOperation: ListOpUpdate, - }) + ListOperation: ListOpUpdate}) } return index.editInstances(editInstances) } diff --git a/vendor/go.podman.io/image/v5/internal/signature/signature.go b/vendor/go.podman.io/image/v5/internal/signature/signature.go index 59f4aedef..6f95115a1 100644 --- a/vendor/go.podman.io/image/v5/internal/signature/signature.go +++ b/vendor/go.podman.io/image/v5/internal/signature/signature.go @@ -87,6 +87,7 @@ func FromBlob(blob []byte) (Signature, error) { default: return nil, fmt.Errorf("unrecognized signature format, starting with binary %#x", blob[0]) } + } // UnsupportedFormatError returns an error complaining about sig having an unsupported format. diff --git a/vendor/go.podman.io/image/v5/internal/signature/sigstore.go b/vendor/go.podman.io/image/v5/internal/signature/sigstore.go index a87b4651f..8025cd270 100644 --- a/vendor/go.podman.io/image/v5/internal/signature/sigstore.go +++ b/vendor/go.podman.io/image/v5/internal/signature/sigstore.go @@ -77,7 +77,6 @@ func (s Sigstore) blobChunk() ([]byte, error) { func (s Sigstore) UntrustedMIMEType() string { return s.untrustedMIMEType } - func (s Sigstore) UntrustedPayload() []byte { return bytes.Clone(s.untrustedPayload) } diff --git a/vendor/go.podman.io/image/v5/manifest/common.go b/vendor/go.podman.io/image/v5/manifest/common.go index dc24e1c9c..dde1bf3c8 100644 --- a/vendor/go.podman.io/image/v5/manifest/common.go +++ b/vendor/go.podman.io/image/v5/manifest/common.go @@ -24,10 +24,8 @@ func layerInfosToStrings(infos []LayerInfo) []string { // the map value is a MIME type, or mtsUnsupportedMIMEType to mean "recognized but unsupported". type compressionMIMETypeSet map[string]string -const ( - mtsUncompressed = "" // A key in compressionMIMETypeSet for the uncompressed variant - mtsUnsupportedMIMEType = "" // A value in compressionMIMETypeSet that means “recognized but unsupported” -) +const mtsUncompressed = "" // A key in compressionMIMETypeSet for the uncompressed variant +const mtsUnsupportedMIMEType = "" // A value in compressionMIMETypeSet that means “recognized but unsupported” // findCompressionMIMETypeSet returns a pointer to a compressionMIMETypeSet in variantTable that contains a value of mimeType, or nil if not found func findCompressionMIMETypeSet(variantTable []compressionMIMETypeSet, mimeType string) compressionMIMETypeSet { diff --git a/vendor/go.podman.io/image/v5/manifest/list.go b/vendor/go.podman.io/image/v5/manifest/list.go index 3d8045a8d..846ea7d43 100644 --- a/vendor/go.podman.io/image/v5/manifest/list.go +++ b/vendor/go.podman.io/image/v5/manifest/list.go @@ -5,12 +5,14 @@ import ( "go.podman.io/image/v5/internal/manifest" ) -// SupportedListMIMETypes is a list of the manifest list types that we know how to -// read/manipulate/write. -var SupportedListMIMETypes = []string{ - DockerV2ListMediaType, - imgspecv1.MediaTypeImageIndex, -} +var ( + // SupportedListMIMETypes is a list of the manifest list types that we know how to + // read/manipulate/write. + SupportedListMIMETypes = []string{ + DockerV2ListMediaType, + imgspecv1.MediaTypeImageIndex, + } +) // List is an interface for parsing, modifying lists of image manifests. // Callers can either use this abstract interface without understanding the details of the formats, diff --git a/vendor/go.podman.io/image/v5/oci/internal/oci_util.go b/vendor/go.podman.io/image/v5/oci/internal/oci_util.go index 9620b6384..c4eaed0ee 100644 --- a/vendor/go.podman.io/image/v5/oci/internal/oci_util.go +++ b/vendor/go.podman.io/image/v5/oci/internal/oci_util.go @@ -17,10 +17,8 @@ const ( component = `(?:` + alphanum + `(?:` + separator + alphanum + `)*)` ) -var ( - refRegexp = regexp.MustCompile(`^` + component + `(?:/` + component + `)*$`) - windowsRefRegexp = regexp.MustCompile(`^([a-zA-Z]:\\.+?):(.*)$`) -) +var refRegexp = regexp.MustCompile(`^` + component + `(?:/` + component + `)*$`) +var windowsRefRegexp = regexp.MustCompile(`^([a-zA-Z]:\\.+?):(.*)$`) // ValidateImageName returns nil if the image name is empty or matches the open-containers image name specs. // In any other case an error is returned. diff --git a/vendor/go.podman.io/image/v5/oci/layout/oci_delete.go b/vendor/go.podman.io/image/v5/oci/layout/oci_delete.go index 484cbb66f..7eaf6f088 100644 --- a/vendor/go.podman.io/image/v5/oci/layout/oci_delete.go +++ b/vendor/go.podman.io/image/v5/oci/layout/oci_delete.go @@ -124,7 +124,7 @@ func (ref ociReference) getBlobsToDelete(blobsUsedByDescriptorToDelete map[diges // So, NOTE: the blobPath() call below hard-codes "" even in calls where OCISharedBlobDirPath is set func (ref ociReference) deleteBlobs(blobsToDelete *set.Set[digest.Digest]) error { for digest := range blobsToDelete.All() { - blobPath, err := ref.blobPath(digest, "") // Only delete in the local directory, see comment above + blobPath, err := ref.blobPath(digest, "") //Only delete in the local directory, see comment above if err != nil { return err } @@ -167,7 +167,7 @@ func saveJSON(path string, content any) (retErr error) { if !os.IsNotExist(err) { return err } else { // File does not exist, use default mode - mode = 0o644 + mode = 0644 } } else { mode = existingfi.Mode() diff --git a/vendor/go.podman.io/image/v5/oci/layout/oci_dest.go b/vendor/go.podman.io/image/v5/oci/layout/oci_dest.go index c4eee7db4..2e885bdc3 100644 --- a/vendor/go.podman.io/image/v5/oci/layout/oci_dest.go +++ b/vendor/go.podman.io/image/v5/oci/layout/oci_dest.go @@ -50,9 +50,8 @@ func newImageDestination(sys *types.SystemContext, ref ociReference) (private.Im } } else { index = &imgspecv1.Index{ - Versioned: imgspec.Versioned{ - SchemaVersion: 2, - }, + Versioned: imgspec.Versioned{SchemaVersion: 2}, + MediaType: imgspecv1.MediaTypeImageIndex, Annotations: make(map[string]string), } } @@ -165,7 +164,7 @@ func (d *ociImageDestination) blobFileSyncAndRename(blobFile *os.File, blobDiges // ignored and the file is already readable; besides, blobFile.Chmod, i.e. syscall.Fchmod, // always fails on Windows. if runtime.GOOS != "windows" { - if err := blobFile.Chmod(0o644); err != nil { + if err := blobFile.Chmod(0644); err != nil { return err } } @@ -248,7 +247,7 @@ func (d *ociImageDestination) PutManifest(ctx context.Context, m []byte, instanc if err := ensureParentDirectoryExists(blobPath); err != nil { return err } - if err := os.WriteFile(blobPath, m, 0o644); err != nil { + if err := os.WriteFile(blobPath, m, 0644); err != nil { return err } @@ -312,14 +311,14 @@ func (d *ociImageDestination) CommitWithOptions(ctx context.Context, options pri if err != nil { return err } - if err := os.WriteFile(d.ref.ociLayoutPath(), layoutBytes, 0o644); err != nil { + if err := os.WriteFile(d.ref.ociLayoutPath(), layoutBytes, 0644); err != nil { return err } indexJSON, err := json.Marshal(d.index) if err != nil { return err } - return os.WriteFile(d.ref.indexPath(), indexJSON, 0o644) + return os.WriteFile(d.ref.indexPath(), indexJSON, 0644) } // PutBlobFromLocalFileOption is unused but may receive functionality in the future. @@ -388,7 +387,7 @@ func PutBlobFromLocalFile(ctx context.Context, dest types.ImageDestination, file func ensureDirectoryExists(path string) error { if err := fileutils.Exists(path); err != nil && errors.Is(err, fs.ErrNotExist) { - if err := os.MkdirAll(path, 0o755); err != nil { + if err := os.MkdirAll(path, 0755); err != nil { return err } } diff --git a/vendor/go.podman.io/image/v5/pkg/blobinfocache/default.go b/vendor/go.podman.io/image/v5/pkg/blobinfocache/default.go index e3c28d58c..7fe615e34 100644 --- a/vendor/go.podman.io/image/v5/pkg/blobinfocache/default.go +++ b/vendor/go.podman.io/image/v5/pkg/blobinfocache/default.go @@ -56,7 +56,7 @@ func DefaultCache(sys *types.SystemContext) types.BlobInfoCache { return memory.New() } path := filepath.Join(dir, blobInfoCacheFilename) - if err := os.MkdirAll(dir, 0o700); err != nil { + if err := os.MkdirAll(dir, 0700); err != nil { logrus.Debugf("Error creating parent directories for %s, using a memory-only cache: %v", path, err) return memory.New() } diff --git a/vendor/go.podman.io/image/v5/pkg/blobinfocache/memory/memory.go b/vendor/go.podman.io/image/v5/pkg/blobinfocache/memory/memory.go index 6190284df..84e9b7d6d 100644 --- a/vendor/go.podman.io/image/v5/pkg/blobinfocache/memory/memory.go +++ b/vendor/go.podman.io/image/v5/pkg/blobinfocache/memory/memory.go @@ -186,8 +186,7 @@ func (mem *cache) RecordDigestCompressorData(anyDigest digest.Digest, data blobi // v2Options is not nil if the caller is CandidateLocations2: this allows including candidates with unknown location, and filters out candidates // with unknown compression. func (mem *cache) appendReplacementCandidates(candidates []prioritize.CandidateWithTime, transport types.ImageTransport, scope types.BICTransportScope, digest digest.Digest, - v2Options *blobinfocache.CandidateLocations2Options, -) []prioritize.CandidateWithTime { + v2Options *blobinfocache.CandidateLocations2Options) []prioritize.CandidateWithTime { compressionData := blobinfocache.DigestCompressorData{ BaseVariantCompressor: blobinfocache.UnknownCompression, SpecificVariantCompressor: blobinfocache.UnknownCompression, @@ -231,8 +230,7 @@ func (mem *cache) CandidateLocations2(transport types.ImageTransport, scope type // candidateLocations implements CandidateLocations / CandidateLocations2. // v2Options is not nil if the caller is CandidateLocations2. func (mem *cache) candidateLocations(transport types.ImageTransport, scope types.BICTransportScope, primaryDigest digest.Digest, canSubstitute bool, - v2Options *blobinfocache.CandidateLocations2Options, -) []blobinfocache.BICReplacementCandidate2 { + v2Options *blobinfocache.CandidateLocations2Options) []blobinfocache.BICReplacementCandidate2 { mem.mutex.Lock() defer mem.mutex.Unlock() res := []prioritize.CandidateWithTime{} diff --git a/vendor/go.podman.io/image/v5/pkg/blobinfocache/none/none.go b/vendor/go.podman.io/image/v5/pkg/blobinfocache/none/none.go index e242ce29e..88c9024fd 100644 --- a/vendor/go.podman.io/image/v5/pkg/blobinfocache/none/none.go +++ b/vendor/go.podman.io/image/v5/pkg/blobinfocache/none/none.go @@ -8,7 +8,8 @@ import ( ) // noCache implements a dummy BlobInfoCache which records no data. -type noCache struct{} +type noCache struct { +} // NoCache implements BlobInfoCache by not recording any data. // diff --git a/vendor/go.podman.io/image/v5/pkg/blobinfocache/sqlite/sqlite.go b/vendor/go.podman.io/image/v5/pkg/blobinfocache/sqlite/sqlite.go index 3e6916637..1d0127573 100644 --- a/vendor/go.podman.io/image/v5/pkg/blobinfocache/sqlite/sqlite.go +++ b/vendor/go.podman.io/image/v5/pkg/blobinfocache/sqlite/sqlite.go @@ -542,8 +542,7 @@ func (sqc *cache) RecordDigestCompressorData(anyDigest digest.Digest, data blobi // v2Options is not nil if the caller is CandidateLocations2: this allows including candidates with unknown location, and filters out candidates // with unknown compression. func (sqc *cache) appendReplacementCandidates(candidates []prioritize.CandidateWithTime, tx *sql.Tx, transport types.ImageTransport, scope types.BICTransportScope, digest digest.Digest, - v2Options *blobinfocache.CandidateLocations2Options, -) ([]prioritize.CandidateWithTime, error) { + v2Options *blobinfocache.CandidateLocations2Options) ([]prioritize.CandidateWithTime, error) { compressionData := blobinfocache.DigestCompressorData{ BaseVariantCompressor: blobinfocache.UnknownCompression, SpecificVariantCompressor: blobinfocache.UnknownCompression, @@ -612,8 +611,7 @@ func (sqc *cache) CandidateLocations2(transport types.ImageTransport, scope type // candidateLocations implements CandidateLocations / CandidateLocations2. // v2Options is not nil if the caller is CandidateLocations2. func (sqc *cache) candidateLocations(transport types.ImageTransport, scope types.BICTransportScope, primaryDigest digest.Digest, canSubstitute bool, - v2Options *blobinfocache.CandidateLocations2Options, -) []blobinfocache.BICReplacementCandidate2 { + v2Options *blobinfocache.CandidateLocations2Options) []blobinfocache.BICReplacementCandidate2 { var uncompressedDigest digest.Digest // = "" res, err := transaction(sqc, func(tx *sql.Tx) ([]prioritize.CandidateWithTime, error) { res := []prioritize.CandidateWithTime{} @@ -670,6 +668,7 @@ func (sqc *cache) candidateLocations(transport types.ImageTransport, scope types return []blobinfocache.BICReplacementCandidate2{} // FIXME? Log err (but throttle the log volume on repeated accesses)? } return prioritize.DestructivelyPrioritizeReplacementCandidates(res, primaryDigest, uncompressedDigest) + } // CandidateLocations returns a prioritized, limited, number of blobs and their locations that could possibly be reused diff --git a/vendor/go.podman.io/image/v5/pkg/docker/config/config.go b/vendor/go.podman.io/image/v5/pkg/docker/config/config.go index 755a49554..56d4eb916 100644 --- a/vendor/go.podman.io/image/v5/pkg/docker/config/config.go +++ b/vendor/go.podman.io/image/v5/pkg/docker/config/config.go @@ -640,7 +640,7 @@ func modifyJSON(sys *types.SystemContext, editor func(fileContents *dockerConfig } dir := filepath.Dir(path.path) - if err = os.MkdirAll(dir, 0o700); err != nil { + if err = os.MkdirAll(dir, 0700); err != nil { return "", err } @@ -659,7 +659,7 @@ func modifyJSON(sys *types.SystemContext, editor func(fileContents *dockerConfig return "", fmt.Errorf("marshaling JSON %q: %w", path.path, err) } - if err = ioutils.AtomicWriteFile(path.path, newData, 0o600); err != nil { + if err = ioutils.AtomicWriteFile(path.path, newData, 0600); err != nil { return "", fmt.Errorf("writing to file %q: %w", path.path, err) } } @@ -683,7 +683,7 @@ func modifyDockerConfigJSON(sys *types.SystemContext, editor func(fileContents * path := sys.DockerCompatAuthFilePath dir := filepath.Dir(path) - if err := os.MkdirAll(dir, 0o700); err != nil { + if err := os.MkdirAll(dir, 0700); err != nil { return "", err } @@ -719,6 +719,7 @@ func modifyDockerConfigJSON(sys *types.SystemContext, editor func(fileContents * if rawCH, ok := rawContents["credHelpers"]; ok { if err := json.Unmarshal(rawCH, &syntheticContents.CredHelpers); err != nil { return "", fmt.Errorf(`unmarshaling "credHelpers" in JSON at %q: %w`, path, err) + } } @@ -738,7 +739,7 @@ func modifyDockerConfigJSON(sys *types.SystemContext, editor func(fileContents * return "", fmt.Errorf("marshaling JSON %q: %w", path, err) } - if err = ioutils.AtomicWriteFile(path, newData, 0o600); err != nil { + if err = ioutils.AtomicWriteFile(path, newData, 0600); err != nil { return "", fmt.Errorf("writing to file %q: %w", path, err) } } diff --git a/vendor/go.podman.io/image/v5/pkg/sysregistriesv2/shortnames.go b/vendor/go.podman.io/image/v5/pkg/sysregistriesv2/shortnames.go index 0da7c693b..8c72ce7ff 100644 --- a/vendor/go.podman.io/image/v5/pkg/sysregistriesv2/shortnames.go +++ b/vendor/go.podman.io/image/v5/pkg/sysregistriesv2/shortnames.go @@ -174,7 +174,7 @@ func editShortNameAlias(ctx *types.SystemContext, name string, value *string) (r delete(conf.Aliases, name) } - f, err := os.OpenFile(confPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600) + f, err := os.OpenFile(confPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { return err } @@ -343,7 +343,7 @@ func shortNameAliasesConfPathAndLock(ctx *types.SystemContext) (string, *lockfil return "", nil, err } // Make sure the path to file exists. - if err := os.MkdirAll(filepath.Dir(shortNameAliasesConfPath), 0o700); err != nil { + if err := os.MkdirAll(filepath.Dir(shortNameAliasesConfPath), 0700); err != nil { return "", nil, err } diff --git a/vendor/go.podman.io/image/v5/pkg/sysregistriesv2/system_registries_v2.go b/vendor/go.podman.io/image/v5/pkg/sysregistriesv2/system_registries_v2.go index 0cf44571d..1a1fcccf8 100644 --- a/vendor/go.podman.io/image/v5/pkg/sysregistriesv2/system_registries_v2.go +++ b/vendor/go.podman.io/image/v5/pkg/sysregistriesv2/system_registries_v2.go @@ -438,8 +438,8 @@ func (config *V2RegistriesConf) postProcessRegistries() error { return err } - // FIXME: unqualifiedSearchRegistries now also accepts empty values - // and shouldn't + //FIXME: unqualifiedSearchRegistries now also accepts empty values + //and shouldn't // https://github.com/containers/image/pull/1191#discussion_r610623216 if mir.Location == "" { return &InvalidRegistries{s: "invalid condition: mirror location is unset"} diff --git a/vendor/go.podman.io/image/v5/sif/load.go b/vendor/go.podman.io/image/v5/sif/load.go index e64e4e832..43937b63e 100644 --- a/vendor/go.podman.io/image/v5/sif/load.go +++ b/vendor/go.podman.io/image/v5/sif/load.go @@ -99,10 +99,10 @@ func writeInjectedScript(extractedRootPath string, injectedScript []byte) error } filePath := filepath.Join(extractedRootPath, injectedScriptTargetPath) parentDirPath := filepath.Dir(filePath) - if err := os.MkdirAll(parentDirPath, 0o755); err != nil { + if err := os.MkdirAll(parentDirPath, 0755); err != nil { return fmt.Errorf("creating %s: %w", parentDirPath, err) } - if err := os.WriteFile(filePath, injectedScript, 0o755); err != nil { + if err := os.WriteFile(filePath, injectedScript, 0755); err != nil { return fmt.Errorf("writing %s to %s: %w", injectedScriptTargetPath, filePath, err) } return nil @@ -120,7 +120,7 @@ func createTarFromSIFInputs(ctx context.Context, tarPath, squashFSPath string, i conversionCommand := fmt.Sprintf("unsquashfs -d %s -f %s && tar --acls --xattrs -C %s -cpf %s ./", extractedRootPath, squashFSPath, extractedRootPath, tarPath) script := "#!/bin/sh\n" + conversionCommand + "\n" - if err := os.WriteFile(scriptPath, []byte(script), 0o755); err != nil { + if err := os.WriteFile(scriptPath, []byte(script), 0755); err != nil { return err } defer os.Remove(scriptPath) diff --git a/vendor/go.podman.io/image/v5/signature/docker.go b/vendor/go.podman.io/image/v5/signature/docker.go index 3e6c3fa95..954eda4a5 100644 --- a/vendor/go.podman.io/image/v5/signature/docker.go +++ b/vendor/go.podman.io/image/v5/signature/docker.go @@ -49,8 +49,7 @@ func SignDockerManifest(m []byte, dockerReference string, mech SigningMechanism, // VerifyDockerManifestSignature checks that unverifiedSignature uses expectedKeyIdentity to sign unverifiedManifest as expectedDockerReference, // using mech. func VerifyDockerManifestSignature(unverifiedSignature, unverifiedManifest []byte, - expectedDockerReference string, mech SigningMechanism, expectedKeyIdentity string, -) (*Signature, error) { + expectedDockerReference string, mech SigningMechanism, expectedKeyIdentity string) (*Signature, error) { sig, _, err := VerifyImageManifestSignatureUsingKeyIdentityList(unverifiedSignature, unverifiedManifest, expectedDockerReference, mech, []string{expectedKeyIdentity}) return sig, err } @@ -59,8 +58,7 @@ func VerifyDockerManifestSignature(unverifiedSignature, unverifiedManifest []byt // to sign unverifiedManifest as expectedDockerReference, using mech. Returns the verified signature and the key identity that // was used to verify it. func VerifyImageManifestSignatureUsingKeyIdentityList(unverifiedSignature, unverifiedManifest []byte, - expectedDockerReference string, mech SigningMechanism, expectedKeyIdentities []string, -) (*Signature, string, error) { + expectedDockerReference string, mech SigningMechanism, expectedKeyIdentities []string) (*Signature, string, error) { expectedRef, err := reference.ParseNormalizedNamed(expectedDockerReference) if err != nil { return nil, "", err diff --git a/vendor/go.podman.io/image/v5/signature/fulcio_cert.go b/vendor/go.podman.io/image/v5/signature/fulcio_cert.go index 203ed2ca5..e9d98368f 100644 --- a/vendor/go.podman.io/image/v5/signature/fulcio_cert.go +++ b/vendor/go.podman.io/image/v5/signature/fulcio_cert.go @@ -200,8 +200,7 @@ func parseLeafCertFromPEM(untrustedCertificateBytes []byte) (*x509.Certificate, func verifyRekorFulcio(rekorPublicKeys []*ecdsa.PublicKey, fulcioTrustRoot *fulcioTrustRoot, untrustedRekorSET []byte, untrustedCertificateBytes []byte, untrustedIntermediateChainBytes []byte, untrustedBase64Signature string, - untrustedPayloadBytes []byte, -) (crypto.PublicKey, error) { + untrustedPayloadBytes []byte) (crypto.PublicKey, error) { rekorSETTime, err := internal.VerifyRekorSET(rekorPublicKeys, untrustedRekorSET, untrustedCertificateBytes, untrustedBase64Signature, untrustedPayloadBytes) if err != nil { diff --git a/vendor/go.podman.io/image/v5/signature/internal/rekor_set.go b/vendor/go.podman.io/image/v5/signature/internal/rekor_set.go index 391f53a27..1c20e496a 100644 --- a/vendor/go.podman.io/image/v5/signature/internal/rekor_set.go +++ b/vendor/go.podman.io/image/v5/signature/internal/rekor_set.go @@ -51,10 +51,8 @@ func (s *UntrustedRekorSET) strictUnmarshalJSON(data []byte) error { } // A compile-time check that UntrustedRekorSET and *UntrustedRekorSET implements json.Marshaler -var ( - _ json.Marshaler = UntrustedRekorSET{} - _ json.Marshaler = (*UntrustedRekorSET)(nil) -) +var _ json.Marshaler = UntrustedRekorSET{} +var _ json.Marshaler = (*UntrustedRekorSET)(nil) // MarshalJSON implements the json.Marshaler interface. func (s UntrustedRekorSET) MarshalJSON() ([]byte, error) { @@ -84,10 +82,8 @@ func (p *UntrustedRekorPayload) strictUnmarshalJSON(data []byte) error { } // A compile-time check that UntrustedRekorPayload and *UntrustedRekorPayload implements json.Marshaler -var ( - _ json.Marshaler = UntrustedRekorPayload{} - _ json.Marshaler = (*UntrustedRekorPayload)(nil) -) +var _ json.Marshaler = UntrustedRekorPayload{} +var _ json.Marshaler = (*UntrustedRekorPayload)(nil) // MarshalJSON implements the json.Marshaler interface. func (p UntrustedRekorPayload) MarshalJSON() ([]byte, error) { @@ -161,6 +157,7 @@ func VerifyRekorSET(publicKeys []*ecdsa.PublicKey, unverifiedRekorSET []byte, un } if hashedRekordV001.Signature.PublicKey == nil { return time.Time{}, NewInvalidSignatureError(`Missing "signature.publicKey" field in hashedrekord`) + } rekorKeyOrCertPEM, rest := pem.Decode(hashedRekordV001.Signature.PublicKey.Content) if rekorKeyOrCertPEM == nil { @@ -215,6 +212,7 @@ func VerifyRekorSET(publicKeys []*ecdsa.PublicKey, unverifiedRekorSET []byte, un rekorPayloadHash, err := hex.DecodeString(*hashedRekordV001.Data.Hash.Value) if err != nil { return time.Time{}, NewInvalidSignatureError(fmt.Sprintf(`Invalid "data.hash.value" field in hashedrekord: %v`, err)) + } unverifiedPayloadHash := sha256.Sum256(unverifiedPayloadBytes) if !bytes.Equal(rekorPayloadHash, unverifiedPayloadHash[:]) { diff --git a/vendor/go.podman.io/image/v5/signature/internal/sigstore_payload.go b/vendor/go.podman.io/image/v5/signature/internal/sigstore_payload.go index e59bc79a9..682360bae 100644 --- a/vendor/go.podman.io/image/v5/signature/internal/sigstore_payload.go +++ b/vendor/go.podman.io/image/v5/signature/internal/sigstore_payload.go @@ -48,10 +48,8 @@ func NewUntrustedSigstorePayload(dockerManifestDigest digest.Digest, dockerRefer } // A compile-time check that UntrustedSigstorePayload and *UntrustedSigstorePayload implements json.Marshaler -var ( - _ json.Marshaler = UntrustedSigstorePayload{} - _ json.Marshaler = (*UntrustedSigstorePayload)(nil) -) +var _ json.Marshaler = UntrustedSigstorePayload{} +var _ json.Marshaler = (*UntrustedSigstorePayload)(nil) // MarshalJSON implements the json.Marshaler interface. func (s UntrustedSigstorePayload) MarshalJSON() ([]byte, error) { @@ -98,7 +96,7 @@ func (s *UntrustedSigstorePayload) strictUnmarshalJSON(data []byte) error { var creatorID string var timestamp float64 - gotCreatorID, gotTimestamp := false, false + var gotCreatorID, gotTimestamp = false, false // /usr/bin/cosign generates "optional": null if there are no user-specified annotations. if !bytes.Equal(optional, []byte("null")) { if err := ParanoidUnmarshalJSONObject(optional, func(key string) any { diff --git a/vendor/go.podman.io/image/v5/signature/policy_config.go b/vendor/go.podman.io/image/v5/signature/policy_config.go index 5e0653119..50f445148 100644 --- a/vendor/go.podman.io/image/v5/signature/policy_config.go +++ b/vendor/go.podman.io/image/v5/signature/policy_config.go @@ -394,7 +394,7 @@ var _ json.Unmarshaler = (*prSignedBy)(nil) func (pr *prSignedBy) UnmarshalJSON(data []byte) error { *pr = prSignedBy{} var tmp prSignedBy - gotKeyPath, gotKeyPaths, gotKeyData := false, false, false + var gotKeyPath, gotKeyPaths, gotKeyData = false, false, false var signedIdentity json.RawMessage if err := internal.ParanoidUnmarshalJSONObject(data, func(key string) any { switch key { diff --git a/vendor/go.podman.io/image/v5/signature/policy_eval_sigstore.go b/vendor/go.podman.io/image/v5/signature/policy_eval_sigstore.go index eb29bd8b5..cee04dc4e 100644 --- a/vendor/go.podman.io/image/v5/signature/policy_eval_sigstore.go +++ b/vendor/go.podman.io/image/v5/signature/policy_eval_sigstore.go @@ -210,6 +210,7 @@ func (pr *prSigstoreSigned) prepareTrustRoot() (*sigstoreSignedTrustRoot, error) pkECDSA, ok := pk.(*ecdsa.PublicKey) if !ok { return nil, fmt.Errorf("Rekor public key %d is not using ECDSA", index+1) + } res.rekorPublicKeys = append(res.rekorPublicKeys, pkECDSA) } diff --git a/vendor/go.podman.io/image/v5/signature/policy_reference_match.go b/vendor/go.podman.io/image/v5/signature/policy_reference_match.go index df57c7d95..0755c0399 100644 --- a/vendor/go.podman.io/image/v5/signature/policy_reference_match.go +++ b/vendor/go.podman.io/image/v5/signature/policy_reference_match.go @@ -56,7 +56,6 @@ func matchRepoDigestOrExactReferenceValues(intended, signature reference.Named) return false } } - func (prm *prmMatchRepoDigestOrExact) matchesDockerReference(image private.UnparsedImage, signatureDockerReference string) bool { intended, signature, err := parseImageAndDockerReference(image, signatureDockerReference) if err != nil { diff --git a/vendor/go.podman.io/image/v5/signature/simple.go b/vendor/go.podman.io/image/v5/signature/simple.go index 8ec1517ea..8711f6908 100644 --- a/vendor/go.podman.io/image/v5/signature/simple.go +++ b/vendor/go.podman.io/image/v5/signature/simple.go @@ -74,10 +74,8 @@ func newUntrustedSignature(dockerManifestDigest digest.Digest, dockerReference s } // A compile-time check that untrustedSignature and *untrustedSignature implements json.Marshaler -var ( - _ json.Marshaler = untrustedSignature{} - _ json.Marshaler = (*untrustedSignature)(nil) -) +var _ json.Marshaler = untrustedSignature{} +var _ json.Marshaler = (*untrustedSignature)(nil) // MarshalJSON implements the json.Marshaler interface. func (s untrustedSignature) MarshalJSON() ([]byte, error) { @@ -124,7 +122,7 @@ func (s *untrustedSignature) strictUnmarshalJSON(data []byte) error { var creatorID string var timestamp float64 - gotCreatorID, gotTimestamp := false, false + var gotCreatorID, gotTimestamp = false, false if err := internal.ParanoidUnmarshalJSONObject(optional, func(key string) any { switch key { case "creator": diff --git a/vendor/go.podman.io/image/v5/storage/storage_dest.go b/vendor/go.podman.io/image/v5/storage/storage_dest.go index 000be3ccd..590957000 100644 --- a/vendor/go.podman.io/image/v5/storage/storage_dest.go +++ b/vendor/go.podman.io/image/v5/storage/storage_dest.go @@ -267,7 +267,7 @@ func (s *storageImageDestination) putBlobToPendingFile(stream io.Reader, blobinf // Set up to digest the blob if necessary, and count its size while saving it to a file. filename := s.computeNextBlobCacheFile() - file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_EXCL, 0o600) + file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_EXCL, 0600) if err != nil { return private.UploadedBlob{}, fmt.Errorf("creating temporary file %q: %w", filename, err) } @@ -285,6 +285,7 @@ func (s *storageImageDestination) putBlobToPendingFile(stream io.Reader, blobinf decompressed, err := archive.DecompressStream(stream) if err != nil { return "", "", 0, fmt.Errorf("setting up to decompress blob: %w", err) + } defer decompressed.Close() @@ -347,6 +348,7 @@ func (f *zstdFetcher) GetBlobAt(chunks []chunked.ImageSourceChunk) (chan io.Read err = chunked.ErrBadRequest{} } return rc, errs, err + } // PutBlobPartial attempts to create a blob using the data that is already present diff --git a/vendor/go.podman.io/image/v5/storage/storage_image.go b/vendor/go.podman.io/image/v5/storage/storage_image.go index 7d1466835..d493c14db 100644 --- a/vendor/go.podman.io/image/v5/storage/storage_image.go +++ b/vendor/go.podman.io/image/v5/storage/storage_image.go @@ -11,9 +11,11 @@ import ( "go.podman.io/storage" ) -// ErrNoSuchImage is returned when we attempt to access an image which -// doesn't exist in the storage area. -var ErrNoSuchImage = storage.ErrNotAnImage +var ( + // ErrNoSuchImage is returned when we attempt to access an image which + // doesn't exist in the storage area. + ErrNoSuchImage = storage.ErrNotAnImage +) // manifestBigDataKey returns a key suitable for recording a manifest with the specified digest using storage.Store.ImageBigData and related functions. // If a specific manifest digest is explicitly requested by the user, the key returned by this function should be used preferably; diff --git a/vendor/go.podman.io/image/v5/tarball/tarball_src.go b/vendor/go.podman.io/image/v5/tarball/tarball_src.go index a8af4b325..3194f9520 100644 --- a/vendor/go.podman.io/image/v5/tarball/tarball_src.go +++ b/vendor/go.podman.io/image/v5/tarball/tarball_src.go @@ -179,9 +179,8 @@ func (r *tarballReference) NewImageSource(ctx context.Context, sys *types.System // Populate a manifest with the configuration blob and the layers. manifest := imgspecv1.Manifest{ - Versioned: imgspecs.Versioned{ - SchemaVersion: 2, - }, + Versioned: imgspecs.Versioned{SchemaVersion: 2}, + MediaType: imgspecv1.MediaTypeImageManifest, Config: imgspecv1.Descriptor{ Digest: configID, Size: int64(len(configBytes)), diff --git a/vendor/go.podman.io/image/v5/tarball/tarball_transport.go b/vendor/go.podman.io/image/v5/tarball/tarball_transport.go index ccd60d375..8c26e0c38 100644 --- a/vendor/go.podman.io/image/v5/tarball/tarball_transport.go +++ b/vendor/go.podman.io/image/v5/tarball/tarball_transport.go @@ -16,12 +16,15 @@ const ( separator = ":" ) -// Transport implements the types.ImageTransport interface for "tarball:" images, -// which are makeshift images constructed using one or more possibly-compressed tar -// archives. -var Transport = &tarballTransport{} +var ( + // Transport implements the types.ImageTransport interface for "tarball:" images, + // which are makeshift images constructed using one or more possibly-compressed tar + // archives. + Transport = &tarballTransport{} +) -type tarballTransport struct{} +type tarballTransport struct { +} func (t *tarballTransport) Name() string { return transportName diff --git a/vendor/go.podman.io/image/v5/types/types.go b/vendor/go.podman.io/image/v5/types/types.go index 41f1a632e..de25dabcd 100644 --- a/vendor/go.podman.io/image/v5/types/types.go +++ b/vendor/go.podman.io/image/v5/types/types.go @@ -668,6 +668,10 @@ type SystemContext struct { DockerRegistryPushPrecomputeDigests bool // DockerProxyURL specifies proxy configuration schema (like socks5://username:password@ip:port) DockerProxyURL *url.URL + // DockerProxy is a function that determines the proxy URL for a given request URL. + // If set, this takes precedence over DockerProxyURL. The function should return the proxy URL to use, + // or nil if no proxy should be used for the given request. + DockerProxy func(reqURL *url.URL) (*url.URL, error) // === docker/daemon.Transport overrides === // A directory containing a CA certificate (ending with ".crt"), diff --git a/vendor/go.podman.io/image/v5/version/version.go b/vendor/go.podman.io/image/v5/version/version.go index e2dd251d2..3e2a9d82d 100644 --- a/vendor/go.podman.io/image/v5/version/version.go +++ b/vendor/go.podman.io/image/v5/version/version.go @@ -8,10 +8,10 @@ const ( // VersionMinor is for functionality in a backwards-compatible manner VersionMinor = 39 // VersionPatch is for backwards-compatible bug fixes - VersionPatch = 0 + VersionPatch = 2 // VersionDev indicates development branch. Releases will be empty string. - VersionDev = "-dev" + VersionDev = "" ) // Version is the specification version that the package types support. diff --git a/vendor/go.podman.io/storage/.golangci.yml b/vendor/go.podman.io/storage/.golangci.yml index 7c367815b..ad4dec0c1 100644 --- a/vendor/go.podman.io/storage/.golangci.yml +++ b/vendor/go.podman.io/storage/.golangci.yml @@ -18,7 +18,3 @@ linters: - all - -ST1003 # https://staticcheck.dev/docs/checks/#ST1003 Poorly chosen identifier. - -QF1008 # https://staticcheck.dev/docs/checks/#QF1008 Omit embedded fields from selector expression. - -issues: - max-issues-per-linter: 0 - max-same-issues: 0 diff --git a/vendor/go.podman.io/storage/Makefile b/vendor/go.podman.io/storage/Makefile index cf19be195..d411ce38c 100644 --- a/vendor/go.podman.io/storage/Makefile +++ b/vendor/go.podman.io/storage/Makefile @@ -69,10 +69,6 @@ install: install.docs lint: golangci-lint run --build-tags="$(AUTOTAGS) $(TAGS)" -.PHONY: fmt -fmt: - golangci-lint fmt - help: ## this help @awk 'BEGIN {FS = ":.*?## "} /^[a-z A-Z_-]+:.*?## / {gsub(" ",",",$$1);gsub("\\\\n",sprintf("\n%22c"," "), $$2);printf "\033[36m%-21s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) diff --git a/vendor/go.podman.io/storage/VERSION b/vendor/go.podman.io/storage/VERSION index bb55a51f6..76d053620 100644 --- a/vendor/go.podman.io/storage/VERSION +++ b/vendor/go.podman.io/storage/VERSION @@ -1 +1 @@ -1.62.0-dev +1.62.0 diff --git a/vendor/go.podman.io/storage/drivers/driver.go b/vendor/go.podman.io/storage/drivers/driver.go index fed80751b..38706dc99 100644 --- a/vendor/go.podman.io/storage/drivers/driver.go +++ b/vendor/go.podman.io/storage/drivers/driver.go @@ -47,7 +47,6 @@ type CreateOpts struct { MountLabel string StorageOpt map[string]string *idtools.IDMappings - ignoreChownErrors bool } // MountOpts contains optional arguments for Driver.Get() methods. @@ -184,7 +183,7 @@ type DiffDriver interface { // layer with the specified id and parent, returning the size of the // new layer in bytes. // The io.Reader must be an uncompressed stream. - ApplyDiff(id string, parent string, options ApplyDiffOpts) (size int64, err error) + ApplyDiff(id string, options ApplyDiffOpts) (size int64, err error) // DiffSize calculates the changes between the specified id // and its parent and returns the size in bytes of the changes // relative to its base filesystem directory. @@ -299,6 +298,19 @@ type DriverWithDiffer interface { DifferTarget(id string) (string, error) } +// ApplyDiffStaging is an interface for driver who can apply the diff without holding the main storage lock. +// This API is experimental and can be changed without bumping the major version number. +type ApplyDiffStaging interface { + // StartStagingDiffToApply applies the new layer into a temporary directory. + // It returns a CleanupTempDirFunc which can be nil or set regardless if the function return an error or not. + // StagedAddition is only set when there is no error returned and the int64 value returns the size of the layer. + // This can be done without holding the storage lock, if a parent is given the caller must check for existence + // beforehand while holding a lock. + StartStagingDiffToApply(parent string, options ApplyDiffOpts) (tempdir.CleanupTempDirFunc, *tempdir.StagedAddition, int64, error) + // CommitStagedLayer commits the staged layer from StartStagingDiffToApply(). This must be done while holding the storage lock. + CommitStagedLayer(id string, commit *tempdir.StagedAddition) error +} + // Capabilities defines a list of capabilities a driver may implement. // These capabilities are not required; however, they do determine how a // graphdriver can be used. diff --git a/vendor/go.podman.io/storage/drivers/fsdiff.go b/vendor/go.podman.io/storage/drivers/fsdiff.go index 77f98d49d..89d18e6d3 100644 --- a/vendor/go.podman.io/storage/drivers/fsdiff.go +++ b/vendor/go.podman.io/storage/drivers/fsdiff.go @@ -151,7 +151,7 @@ func (gdw *NaiveDiffDriver) Changes(id string, idMappings *idtools.IDMappings, p // ApplyDiff extracts the changeset from the given diff into the // layer with the specified id and parent, returning the size of the // new layer in bytes. -func (gdw *NaiveDiffDriver) ApplyDiff(id, parent string, options ApplyDiffOpts) (int64, error) { +func (gdw *NaiveDiffDriver) ApplyDiff(id string, options ApplyDiffOpts) (int64, error) { driver := gdw.ProtoDriver if options.Mappings == nil { diff --git a/vendor/go.podman.io/storage/drivers/overlay/overlay.go b/vendor/go.podman.io/storage/drivers/overlay/overlay.go index c08e06046..2eb720c18 100644 --- a/vendor/go.podman.io/storage/drivers/overlay/overlay.go +++ b/vendor/go.podman.io/storage/drivers/overlay/overlay.go @@ -995,27 +995,15 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr return d.create(id, parent, opts, true) } -func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, readOnly bool) (retErr error) { - dir, homedir, _ := d.dir2(id, readOnly) - - disableQuota := readOnly - - var uidMaps []idtools.IDMap - var gidMaps []idtools.IDMap - - if opts != nil && opts.IDMappings != nil { - uidMaps = opts.IDMappings.UIDs() - gidMaps = opts.IDMappings.GIDs() - } - - // Make the link directory if it does not exist - if err := idtools.MkdirAllAs(path.Join(homedir, linkDir), 0o755, 0, 0); err != nil { - return err - } - +// getLayerPermissions returns the base permissions to use for the layer directories. +// The first return value is the idPair to create the possible parent directories with. +// The second return value is the mode how it should be stored on disk. +// The third return value is the mode the layer expects to have which may be stored +// in an xattr when using forceMask, without forceMask both values are the same. +func (d *Driver) getLayerPermissions(parent string, uidMaps, gidMaps []idtools.IDMap) (idtools.IDPair, idtools.Stat, idtools.Stat, error) { rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps) if err != nil { - return err + return idtools.IDPair{}, idtools.Stat{}, idtools.Stat{}, err } idPair := idtools.IDPair{ @@ -1023,10 +1011,6 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, readOnl GID: rootGID, } - if err := idtools.MkdirAllAndChownNew(path.Dir(dir), 0o755, idPair); err != nil { - return err - } - st := idtools.Stat{IDs: idPair, Mode: defaultPerms} if parent != "" { @@ -1037,7 +1021,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, readOnl } else { systemSt, err := system.Stat(parentDiff) if err != nil { - return err + return idtools.IDPair{}, idtools.Stat{}, idtools.Stat{}, err } st.IDs.UID = int(systemSt.UID()) st.IDs.GID = int(systemSt.GID()) @@ -1045,6 +1029,42 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, readOnl } } + forcedSt := st + if d.options.forceMask != nil { + forcedSt.IDs = idPair + forcedSt.Mode = *d.options.forceMask + } + + return idPair, forcedSt, st, nil +} + +func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, readOnly bool) (retErr error) { + dir, homedir, _ := d.dir2(id, readOnly) + + disableQuota := readOnly + + var uidMaps []idtools.IDMap + var gidMaps []idtools.IDMap + + if opts != nil && opts.IDMappings != nil { + uidMaps = opts.IDMappings.UIDs() + gidMaps = opts.IDMappings.GIDs() + } + + // Make the link directory if it does not exist + if err := idtools.MkdirAllAs(path.Join(homedir, linkDir), 0o755, 0, 0); err != nil { + return err + } + + idPair, forcedSt, st, err := d.getLayerPermissions(parent, uidMaps, gidMaps) + if err != nil { + return err + } + + if err := idtools.MkdirAllAndChownNew(path.Dir(dir), 0o755, idPair); err != nil { + return err + } + if err := fileutils.Lexists(dir); err == nil { logrus.Warnf("Trying to create a layer %#v while directory %q already exists; removing it first", id, dir) // Don’t just os.RemoveAll(dir) here; d.Remove also removes the link in linkDir, @@ -1088,12 +1108,6 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, readOnl } } - forcedSt := st - if d.options.forceMask != nil { - forcedSt.IDs = idPair - forcedSt.Mode = *d.options.forceMask - } - diff := path.Join(dir, "diff") if err := idtools.MkdirAs(diff, forcedSt.Mode, forcedSt.IDs.UID, forcedSt.IDs.GID); err != nil { return err @@ -1356,6 +1370,14 @@ func (d *Driver) getTempDirRoot(id string) string { return filepath.Join(d.home, tempDirName) } +// getTempDirRootForNewLayer returns the correct temp directory root based on where +// the layer should be created. +// +// This must be kept in sync with GetTempDirRootDirs(). +func (d *Driver) getTempDirRootForNewLayer() string { + return filepath.Join(d.homeDirForImageStore(), tempDirName) +} + func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) { tempDirRoot := d.getTempDirRoot(id) t, err := tempdir.NewTempDir(tempDirRoot) @@ -2369,31 +2391,94 @@ func (d *Driver) DifferTarget(id string) (string, error) { return d.getDiffPath(id) } -// ApplyDiff applies the new layer into a root -func (d *Driver) ApplyDiff(id, parent string, options graphdriver.ApplyDiffOpts) (size int64, err error) { - if !d.isParent(id, parent) { - if d.options.ignoreChownErrors { - options.IgnoreChownErrors = d.options.ignoreChownErrors +// StartStagingDiffToApply applies the new layer into a temporary directory. +// It returns a CleanupTempDirFunc which can be nil or set regardless if the function return an error or not. +// StagedAddition is only set when there is no error returned and the int64 value returns the size of the layer. +// This can be done without holding the storage lock, if a parent is given the caller must check for existence +// beforehand while holding a lock. +// +// This API is experimental and can be changed without bumping the major version number. +func (d *Driver) StartStagingDiffToApply(parent string, options graphdriver.ApplyDiffOpts) (tempdir.CleanupTempDirFunc, *tempdir.StagedAddition, int64, error) { + tempDirRoot := d.getTempDirRootForNewLayer() + t, err := tempdir.NewTempDir(tempDirRoot) + if err != nil { + return nil, nil, -1, err + } + + sa, err := t.StageAddition() + if err != nil { + return t.Cleanup, nil, -1, err + } + + _, forcedSt, st, err := d.getLayerPermissions(parent, options.Mappings.UIDs(), options.Mappings.GIDs()) + if err != nil { + // If we have a ENOENT it means the parent was removed which can happen as we are unlocked here. + // In this case also wrap ErrLayerUnknown which some callers can handle to retry after recreating the parent. + if errors.Is(err, fs.ErrNotExist) { + err = fmt.Errorf("parent layer %q: %w: %w", parent, graphdriver.ErrLayerUnknown, err) } - if d.options.forceMask != nil { - options.ForceMask = d.options.forceMask + return t.Cleanup, nil, -1, err + } + + if err := idtools.MkdirAs(sa.Path, forcedSt.Mode, forcedSt.IDs.UID, forcedSt.IDs.GID); err != nil { + return t.Cleanup, nil, -1, err + } + + if d.options.forceMask != nil { + st.Mode |= os.ModeDir + if err := idtools.SetContainersOverrideXattr(sa.Path, st); err != nil { + return t.Cleanup, nil, -1, err } - return d.naiveDiff.ApplyDiff(id, parent, options) } - idMappings := options.Mappings - if idMappings == nil { - idMappings = &idtools.IDMappings{} + size, err := d.applyDiff(sa.Path, options) + if err != nil { + return t.Cleanup, nil, -1, err + } + + return t.Cleanup, sa, size, nil +} + +// CommitStagedLayer that was created with StartStagingDiffToApply(). +// +// This API is experimental and can be changed without bumping the major version number. +func (d *Driver) CommitStagedLayer(id string, sa *tempdir.StagedAddition) error { + applyDir, err := d.getDiffPath(id) + if err != nil { + return err + } + + // The os.Rename() function used by CommitFunc errors when the target directory already + // exists, as such delete the dir. The create() function creates it and it would be more + // complicated to code in a way that it didn't create it. + if err := os.Remove(applyDir); err != nil { + return err } + return sa.Commit(applyDir) +} + +// ApplyDiff applies the new layer into a root +func (d *Driver) ApplyDiff(id string, options graphdriver.ApplyDiffOpts) (size int64, err error) { applyDir, err := d.getDiffPath(id) if err != nil { return 0, err } + return d.applyDiff(applyDir, options) +} + +// ApplyDiff applies the new layer into a root. +// This can run concurrently with any other driver operations, as such it is the +// callers responsibility to ensure the target path passed is safe to use if that is the case. +func (d *Driver) applyDiff(target string, options graphdriver.ApplyDiffOpts) (size int64, err error) { + idMappings := options.Mappings + if idMappings == nil { + idMappings = &idtools.IDMappings{} + } - logrus.Debugf("Applying tar in %s", applyDir) + logrus.Debugf("Applying tar in %s", target) // Overlay doesn't need the parent id to apply the diff - if err := untar(options.Diff, applyDir, &archive.TarOptions{ + if err := untar(options.Diff, target, &archive.TarOptions{ UIDMaps: idMappings.UIDs(), GIDMaps: idMappings.GIDs(), IgnoreChownErrors: d.options.ignoreChownErrors, @@ -2404,7 +2489,7 @@ func (d *Driver) ApplyDiff(id, parent string, options graphdriver.ApplyDiffOpts) return 0, err } - return directory.Size(applyDir) + return directory.Size(target) } func (d *Driver) getComposefsData(id string) string { diff --git a/vendor/go.podman.io/storage/drivers/template.go b/vendor/go.podman.io/storage/drivers/template.go deleted file mode 100644 index 03da13c5b..000000000 --- a/vendor/go.podman.io/storage/drivers/template.go +++ /dev/null @@ -1,52 +0,0 @@ -package graphdriver - -import ( - "github.com/sirupsen/logrus" - "go.podman.io/storage/pkg/idtools" -) - -// TemplateDriver is just barely enough of a driver that we can implement a -// naive version of CreateFromTemplate on top of it. -type TemplateDriver interface { - DiffDriver - CreateReadWrite(id, parent string, opts *CreateOpts) error - Create(id, parent string, opts *CreateOpts) error - Remove(id string) error -} - -// CreateFromTemplate creates a layer with the same contents and parent as -// another layer. Internally, it may even depend on that other layer -// continuing to exist, as if it were actually a child of the child layer. -func NaiveCreateFromTemplate(d TemplateDriver, id, template string, templateIDMappings *idtools.IDMappings, parent string, parentIDMappings *idtools.IDMappings, opts *CreateOpts, readWrite bool) error { - var err error - if readWrite { - err = d.CreateReadWrite(id, parent, opts) - } else { - err = d.Create(id, parent, opts) - } - if err != nil { - return err - } - diff, err := d.Diff(template, templateIDMappings, parent, parentIDMappings, opts.MountLabel) - if err != nil { - if err2 := d.Remove(id); err2 != nil { - logrus.Errorf("Removing layer %q: %v", id, err2) - } - return err - } - defer diff.Close() - - applyOptions := ApplyDiffOpts{ - Diff: diff, - Mappings: templateIDMappings, - MountLabel: opts.MountLabel, - IgnoreChownErrors: opts.ignoreChownErrors, - } - if _, err = d.ApplyDiff(id, parent, applyOptions); err != nil { - if err2 := d.Remove(id); err2 != nil { - logrus.Errorf("Removing layer %q: %v", id, err2) - } - return err - } - return nil -} diff --git a/vendor/go.podman.io/storage/drivers/vfs/driver.go b/vendor/go.podman.io/storage/drivers/vfs/driver.go index ffd3bd24e..b90c2046c 100644 --- a/vendor/go.podman.io/storage/drivers/vfs/driver.go +++ b/vendor/go.podman.io/storage/drivers/vfs/driver.go @@ -132,11 +132,11 @@ func (d *Driver) CreateFromTemplate(id, template string, templateIDMappings *idt } // ApplyDiff applies the new layer into a root -func (d *Driver) ApplyDiff(id, parent string, options graphdriver.ApplyDiffOpts) (size int64, err error) { +func (d *Driver) ApplyDiff(id string, options graphdriver.ApplyDiffOpts) (size int64, err error) { if d.ignoreChownErrors { options.IgnoreChownErrors = d.ignoreChownErrors } - return d.naiveDiff.ApplyDiff(id, parent, options) + return d.naiveDiff.ApplyDiff(id, options) } // CreateReadWrite creates a layer that is writable for use as a container diff --git a/vendor/go.podman.io/storage/drivers/zfs/zfs.go b/vendor/go.podman.io/storage/drivers/zfs/zfs.go index b994278bb..8660dbaa3 100644 --- a/vendor/go.podman.io/storage/drivers/zfs/zfs.go +++ b/vendor/go.podman.io/storage/drivers/zfs/zfs.go @@ -12,7 +12,7 @@ import ( "sync" "time" - zfs "github.com/mistifyio/go-zfs/v4" + zfs "github.com/mistifyio/go-zfs/v3" "github.com/opencontainers/selinux/go-selinux/label" "github.com/sirupsen/logrus" graphdriver "go.podman.io/storage/drivers" diff --git a/vendor/go.podman.io/storage/internal/tempdir/tempdir.go b/vendor/go.podman.io/storage/internal/tempdir/tempdir.go index 6522c45d1..bd852688c 100644 --- a/vendor/go.podman.io/storage/internal/tempdir/tempdir.go +++ b/vendor/go.podman.io/storage/internal/tempdir/tempdir.go @@ -6,6 +6,7 @@ import ( "io/fs" "os" "path/filepath" + "strconv" "strings" "github.com/sirupsen/logrus" @@ -91,6 +92,26 @@ type TempDir struct { counter uint64 } +// StagedAddition is a temporary object which holds the information of where to +// put the data into and then use Commit() to move the data into the final location. +type StagedAddition struct { + // Path is the temporary path. The path is not created so caller must create + // a file or directory on it in order to use Commit(). The path is only valid + // until Commit() is called or until the TempDir instance Cleanup() method is used. + Path string +} + +// Commit the staged content into its final destination by using os.Rename(). +// That means the dest must be on the same on the same fs as the root directory +// that was given to NewTempDir() and the dest must not exist yet. +// Commit must only be called once per instance returned from the +// StagedAddition() call. +func (s *StagedAddition) Commit(destination string) error { + err := os.Rename(s.Path, destination) + s.Path = "" // invalidate Path to avoid reuse + return err +} + // CleanupTempDirFunc is a function type that can be returned by operations // which need to perform cleanup actions later. type CleanupTempDirFunc func() error @@ -190,6 +211,23 @@ func NewTempDir(rootDir string) (*TempDir, error) { return td, nil } +// StageAddition creates a new temporary path that is returned as field in the StagedAddition +// struct. The returned type StagedAddition has a Commit() function to move the content from +// the temporary location to the final one. +// +// The caller MUST call Commit() before Cleanup() is called on the TempDir, otherwise the +// staged content will be deleted and the Commit() will fail. +// If the TempDir has been cleaned up already, this method will return an error. +func (td *TempDir) StageAddition() (*StagedAddition, error) { + if td.tempDirLock == nil { + return nil, fmt.Errorf("temp dir instance not initialized or already cleaned up") + } + fileName := strconv.FormatUint(td.counter, 10) + "-addition" + tmpAddPath := filepath.Join(td.tempDirPath, fileName) + td.counter++ + return &StagedAddition{Path: tmpAddPath}, nil +} + // StageDeletion moves the specified file into the instance's temporary directory. // The temporary directory must already exist (created during NewTempDir). // Files are renamed with a counter-based prefix (e.g., "0-filename", "1-filename") to ensure uniqueness. diff --git a/vendor/go.podman.io/storage/layers.go b/vendor/go.podman.io/storage/layers.go index 64d3f5c72..d485c9b4f 100644 --- a/vendor/go.podman.io/storage/layers.go +++ b/vendor/go.podman.io/storage/layers.go @@ -31,6 +31,7 @@ import ( "go.podman.io/storage/pkg/ioutils" "go.podman.io/storage/pkg/lockfile" "go.podman.io/storage/pkg/mount" + "go.podman.io/storage/pkg/pools" "go.podman.io/storage/pkg/stringid" "go.podman.io/storage/pkg/system" "go.podman.io/storage/pkg/tarlog" @@ -195,11 +196,53 @@ type DiffOptions struct { Compression *archive.Compression } -// stagedLayerOptions are the options passed to .create to populate a staged +// layerCreationContents are the options passed to .create to populate a staged // layer -type stagedLayerOptions struct { +type layerCreationContents struct { + // These are used via the zstd:chunked pull paths DiffOutput *drivers.DriverWithDifferOutput DiffOptions *drivers.ApplyDiffWithDifferOpts + + // stagedLayerExtraction is used by the normal tar layer extraction. + stagedLayerExtraction *maybeStagedLayerExtraction +} + +// maybeStagedLayerExtraction is a helper to encapsulate details around extracting +// a layer potentially before we even take a look if the driver implements the +// ApplyDiffStaging interface. +// This should be initialized with layerStore.newMaybeStagedLayerExtraction() +type maybeStagedLayerExtraction struct { + // diff contains the tar archive, can be compressed, must be non nil, but can be at EOF when the content was already staged + diff io.Reader + // staging interface of the storage driver, set when the driver supports staging and nil otherwise + staging drivers.ApplyDiffStaging + // result is a placeholder for the applyDiff() result so we can pass that down the stack easily. + // If result is not nil the layer was staged successfully, if this is set stagedTarSplit and + // stagedLayer must be set as well. + result *applyDiffResult + + // stagedTarSplit is the temp file where we staged the tar split file + stagedTarSplit *tempdir.StagedAddition + // stagedLayer is the temp directory where we staged the extracted layer content + stagedLayer *tempdir.StagedAddition + + // cleanupFuncs contains the set of tempdir cleanup function that get executed in cleanup() + cleanupFuncs []tempdir.CleanupTempDirFunc +} + +type applyDiffResult struct { + compressedDigest digest.Digest + compressedSize int64 + compressionType archive.Compression + uncompressedDigest digest.Digest + uncompressedSize int64 + // size of the data, including the full size of sparse files, and excluding all metadata + // It is neither compressedSize nor uncompressedSize. + // The use case for this seems unclear, it gets returned in PutLayer() but in the Podman + // stack at least that value is never used so maybe we can look into removing this. + size int64 + uids []uint32 + gids []uint32 } // roLayerStore wraps a graph driver, adding the ability to refer to layers by @@ -216,6 +259,11 @@ type roLayerStore interface { // stopReading releases locks obtained by startReading. stopReading() + // checkIdOrNameConflict checks if the id or names are already in use and returns an + // error in that case. As Special case if the layer already exists it returns it as + // well together with the error. + checkIdOrNameConflict(id string, names []string) (*Layer, error) + // Exists checks if a layer with the specified name or ID is known. Exists(id string) bool @@ -288,7 +336,7 @@ type rwLayerStore interface { // underlying drivers do not themselves distinguish between writeable // and read-only layers. Returns the new layer structure and the size of the // diff which was applied to its parent to initialize its contents. - create(id string, parent *Layer, names []string, mountLabel string, options map[string]string, moreOptions *LayerOptions, writeable bool, diff io.Reader, slo *stagedLayerOptions) (*Layer, int64, error) + create(id string, parent *Layer, names []string, mountLabel string, options map[string]string, moreOptions *LayerOptions, writeable bool, contents *layerCreationContents) (*Layer, int64, error) // updateNames modifies names associated with a layer based on (op, names). updateNames(id string, names []string, op updateNameOperation) error @@ -354,6 +402,14 @@ type rwLayerStore interface { // Dedup deduplicates layers in the store. dedup(drivers.DedupArgs) (drivers.DedupResult, error) + + // newMaybeStagedLayerExtraction initializes a new maybeStagedLayerExtraction. The caller + // must call maybeStagedLayerExtraction.cleanup() to remove any temporary files. + newMaybeStagedLayerExtraction(diff io.Reader) *maybeStagedLayerExtraction + + // stageWithUnlockedStore stages the layer content without needing the store locked. + // If the driver does not support stage addition then this is a NOP and does nothing. + stageWithUnlockedStore(m *maybeStagedLayerExtraction, parent string, options *LayerOptions) error } type multipleLockFile struct { @@ -1307,13 +1363,8 @@ func (r *layerStore) Status() ([][2]string, error) { // Requires startWriting. func (r *layerStore) PutAdditionalLayer(id string, parentLayer *Layer, names []string, aLayer drivers.AdditionalLayer) (layer *Layer, err error) { - if duplicateLayer, idInUse := r.byid[id]; idInUse { - return duplicateLayer, ErrDuplicateID - } - for _, name := range names { - if _, nameInUse := r.byname[name]; nameInUse { - return nil, ErrDuplicateName - } + if layer, err := r.checkIdOrNameConflict(id, names); err != nil { + return layer, err } parent := "" @@ -1378,8 +1429,25 @@ func (r *layerStore) pickStoreLocation(volatile, writeable bool) layerLocations } } +// checkIdOrNameConflict checks if the id or names are already in use and returns an +// error in that case. As Special case if the layer already exists it returns it as +// well together with the error. +// +// Requires startReading or startWriting. +func (r *layerStore) checkIdOrNameConflict(id string, names []string) (*Layer, error) { + if duplicateLayer, idInUse := r.byid[id]; idInUse { + return duplicateLayer, ErrDuplicateID + } + for _, name := range names { + if _, nameInUse := r.byname[name]; nameInUse { + return nil, ErrDuplicateName + } + } + return nil, nil +} + // Requires startWriting. -func (r *layerStore) create(id string, parentLayer *Layer, names []string, mountLabel string, options map[string]string, moreOptions *LayerOptions, writeable bool, diff io.Reader, slo *stagedLayerOptions) (layer *Layer, size int64, err error) { +func (r *layerStore) create(id string, parentLayer *Layer, names []string, mountLabel string, options map[string]string, moreOptions *LayerOptions, writeable bool, contents *layerCreationContents) (layer *Layer, size int64, err error) { if moreOptions == nil { moreOptions = &LayerOptions{} } @@ -1400,14 +1468,8 @@ func (r *layerStore) create(id string, parentLayer *Layer, names []string, mount _, idInUse = r.byid[id] } } - if duplicateLayer, idInUse := r.byid[id]; idInUse { - return duplicateLayer, -1, ErrDuplicateID - } - names = dedupeStrings(names) - for _, name := range names { - if _, nameInUse := r.byname[name]; nameInUse { - return nil, -1, ErrDuplicateName - } + if layer, err := r.checkIdOrNameConflict(id, names); err != nil { + return layer, -1, err } parent := "" if parentLayer != nil { @@ -1568,18 +1630,31 @@ func (r *layerStore) create(id string, parentLayer *Layer, names []string, mount } size = -1 - if diff != nil { - if size, err = r.applyDiffWithOptions(layer.ID, moreOptions, diff); err != nil { - cleanupFailureContext = "applying layer diff" - return nil, -1, err - } - } else if slo != nil { - if err := r.applyDiffFromStagingDirectory(layer.ID, slo.DiffOutput, slo.DiffOptions); err != nil { - cleanupFailureContext = "applying staged directory diff" - return nil, -1, err + if contents != nil { + if contents.stagedLayerExtraction != nil { + if contents.stagedLayerExtraction.result != nil { + // The layer is staged, just commit it and update the metadata. + if err := contents.stagedLayerExtraction.commitLayer(r, layer.ID); err != nil { + cleanupFailureContext = "committing staged layer diff" + return nil, -1, err + } + r.applyDiffResultToLayer(layer, contents.stagedLayerExtraction.result) + } else { + // The diff was not staged, apply it now here instead. + if size, err = r.applyDiffWithOptions(layer.ID, moreOptions, contents.stagedLayerExtraction.diff); err != nil { + cleanupFailureContext = "applying layer diff" + return nil, -1, err + } + } + } else { + // staging logic for the chunked pull path + if err := r.applyDiffFromStagingDirectory(layer.ID, contents.DiffOutput, contents.DiffOptions); err != nil { + cleanupFailureContext = "applying staged directory diff" + return nil, -1, err + } } } else { - // applyDiffWithOptions() would have updated r.bycompressedsum + // The layer creation content above would have updated r.bycompressedsum // and r.byuncompressedsum for us, but if we used a template // layer, we didn't call it, so add the new layer as candidates // for searches for layers by checksum @@ -2398,37 +2473,118 @@ func (r *layerStore) ApplyDiff(to string, diff io.Reader) (size int64, err error return r.applyDiffWithOptions(to, nil, diff) } -// Requires startWriting. -func (r *layerStore) applyDiffWithOptions(to string, layerOptions *LayerOptions, diff io.Reader) (size int64, err error) { - if !r.lockfile.IsReadWrite() { - return -1, fmt.Errorf("not allowed to modify layer contents at %q: %w", r.layerdir, ErrStoreIsReadOnly) +func createTarSplitFile(r *layerStore, layerID string) (*os.File, error) { + if err := os.MkdirAll(filepath.Dir(r.tspath(layerID)), 0o700); err != nil { + return nil, err } + return os.OpenFile(r.tspath(layerID), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o600) +} - layer, ok := r.lookup(to) - if !ok { - return -1, ErrLayerUnknown +// newMaybeStagedLayerExtraction initializes a new maybeStagedLayerExtraction. The caller +// must call maybeStagedLayerExtraction.cleanup() to remove any temporary files. +func (r *layerStore) newMaybeStagedLayerExtraction(diff io.Reader) *maybeStagedLayerExtraction { + m := &maybeStagedLayerExtraction{ + diff: diff, + } + if d, ok := r.driver.(drivers.ApplyDiffStaging); ok { + m.staging = d } + return m +} + +func (sl *maybeStagedLayerExtraction) cleanup() error { + return tempdir.CleanupTemporaryDirectories(sl.cleanupFuncs...) +} +// stageWithUnlockedStore stages the layer content without needing the store locked. +// If the driver does not support stage addition then this is a NOP and does nothing. +// This should be done without holding the storage lock, if a parent is given the caller +// must check for existence beforehand while holding a lock. +func (r *layerStore) stageWithUnlockedStore(sl *maybeStagedLayerExtraction, parent string, layerOptions *LayerOptions) (retErr error) { + if sl.staging == nil { + return nil + } + td, err := tempdir.NewTempDir(filepath.Join(r.layerdir, tempDirPath)) + if err != nil { + return err + } + sl.cleanupFuncs = append(sl.cleanupFuncs, td.Cleanup) + + stagedTarSplit, err := td.StageAddition() + if err != nil { + return err + } + sl.stagedTarSplit = stagedTarSplit + + f, err := os.OpenFile(stagedTarSplit.Path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o600) + if err != nil { + return err + } + // make sure to check for errors on close and return that one. + defer func() { + closeErr := f.Close() + if retErr == nil { + retErr = closeErr + } + }() + + result, err := applyDiff(layerOptions, sl.diff, f, func(payload io.Reader) (int64, error) { + cleanup, stagedLayer, size, err := sl.staging.StartStagingDiffToApply(parent, drivers.ApplyDiffOpts{ + Diff: payload, + Mappings: idtools.NewIDMappingsFromMaps(layerOptions.UIDMap, layerOptions.GIDMap), + // MountLabel is not supported for the unlocked extraction, see the comment in (*store).PutLayer() + MountLabel: "", + }) + sl.cleanupFuncs = append(sl.cleanupFuncs, cleanup) + sl.stagedLayer = stagedLayer + return size, err + }) + if err != nil { + return err + } + + if err := f.Sync(); err != nil { + return fmt.Errorf("sync staged tar-split file: %w", err) + } + + sl.result = result + return nil +} + +// commitLayer() commits the content that was staged in stageWithUnlockedStore() +// +// Requires startWriting. +func (sl *maybeStagedLayerExtraction) commitLayer(r *layerStore, layerID string) error { + err := sl.stagedTarSplit.Commit(r.tspath(layerID)) + if err != nil { + return err + } + return sl.staging.CommitStagedLayer(layerID, sl.stagedLayer) +} + +// applyDiff can be called without holding any store locks so if the supplied +// applyDriverFunc requires locking the caller must ensure proper locking. +func applyDiff(layerOptions *LayerOptions, diff io.Reader, tarSplitFile *os.File, applyDriverFunc func(io.Reader) (int64, error)) (*applyDiffResult, error) { header := make([]byte, 10240) n, err := diff.Read(header) if err != nil && err != io.EOF { - return -1, err + return nil, err } compression := archive.DetectCompression(header[:n]) defragmented := io.MultiReader(bytes.NewReader(header[:n]), diff) - // Decide if we need to compute digests - var compressedDigest, uncompressedDigest digest.Digest // = "" + result := applyDiffResult{} + var compressedDigester, uncompressedDigester digest.Digester // = nil if layerOptions != nil && layerOptions.OriginalDigest != "" && layerOptions.OriginalDigest.Algorithm() == digest.Canonical { - compressedDigest = layerOptions.OriginalDigest + result.compressedDigest = layerOptions.OriginalDigest } else { compressedDigester = digest.Canonical.Digester() } if layerOptions != nil && layerOptions.UncompressedDigest != "" && layerOptions.UncompressedDigest.Algorithm() == digest.Canonical { - uncompressedDigest = layerOptions.UncompressedDigest + result.uncompressedDigest = layerOptions.UncompressedDigest } else if compression != archive.Uncompressed { uncompressedDigester = digest.Canonical.Digester() } @@ -2442,13 +2598,15 @@ func (r *layerStore) applyDiffWithOptions(to string, layerOptions *LayerOptions, compressedCounter := ioutils.NewWriteCounter(compressedWriter) defragmented = io.TeeReader(defragmented, compressedCounter) - tsdata := bytes.Buffer{} + tarSplitWriter := pools.BufioWriter32KPool.Get(tarSplitFile) + defer pools.BufioWriter32KPool.Put(tarSplitWriter) + uidLog := make(map[uint32]struct{}) gidLog := make(map[uint32]struct{}) var uncompressedCounter *ioutils.WriteCounter - size, err = func() (int64, error) { // A scope for defer - compressor, err := pgzip.NewWriterLevel(&tsdata, pgzip.BestSpeed) + size, err := func() (int64, error) { // A scope for defer + compressor, err := pgzip.NewWriterLevel(tarSplitWriter, pgzip.BestSpeed) if err != nil { return -1, err } @@ -2481,62 +2639,108 @@ func (r *layerStore) applyDiffWithOptions(to string, layerOptions *LayerOptions, if err != nil { return -1, err } - options := drivers.ApplyDiffOpts{ - Diff: payload, - Mappings: r.layerMappings(layer), - MountLabel: layer.MountLabel, - } - size, err := r.driver.ApplyDiff(layer.ID, layer.Parent, options) - if err != nil { - return -1, err - } - return size, err + + return applyDriverFunc(payload) }() if err != nil { - return -1, err + return nil, err } - if err := os.MkdirAll(filepath.Dir(r.tspath(layer.ID)), 0o700); err != nil { - return -1, err - } - if err := ioutils.AtomicWriteFile(r.tspath(layer.ID), tsdata.Bytes(), 0o600); err != nil { - return -1, err + if err := tarSplitWriter.Flush(); err != nil { + return nil, fmt.Errorf("failed to flush tar-split writer buffer: %w", err) } + if compressedDigester != nil { - compressedDigest = compressedDigester.Digest() + result.compressedDigest = compressedDigester.Digest() } if uncompressedDigester != nil { - uncompressedDigest = uncompressedDigester.Digest() + result.uncompressedDigest = uncompressedDigester.Digest() } - if uncompressedDigest == "" && compression == archive.Uncompressed { - uncompressedDigest = compressedDigest + if result.uncompressedDigest == "" && compression == archive.Uncompressed { + result.uncompressedDigest = result.compressedDigest } - updateDigestMap(&r.bycompressedsum, layer.CompressedDigest, compressedDigest, layer.ID) - layer.CompressedDigest = compressedDigest if layerOptions != nil && layerOptions.OriginalDigest != "" && layerOptions.OriginalSize != nil { - layer.CompressedSize = *layerOptions.OriginalSize + result.compressedSize = *layerOptions.OriginalSize } else { - layer.CompressedSize = compressedCounter.Count + result.compressedSize = compressedCounter.Count } - updateDigestMap(&r.byuncompressedsum, layer.UncompressedDigest, uncompressedDigest, layer.ID) - layer.UncompressedDigest = uncompressedDigest - layer.UncompressedSize = uncompressedCounter.Count - layer.CompressionType = compression - layer.UIDs = make([]uint32, 0, len(uidLog)) + result.uncompressedSize = uncompressedCounter.Count + result.compressionType = compression + + result.uids = make([]uint32, 0, len(uidLog)) for uid := range uidLog { - layer.UIDs = append(layer.UIDs, uid) + result.uids = append(result.uids, uid) } - slices.Sort(layer.UIDs) - layer.GIDs = make([]uint32, 0, len(gidLog)) + slices.Sort(result.uids) + result.gids = make([]uint32, 0, len(gidLog)) for gid := range gidLog { - layer.GIDs = append(layer.GIDs, gid) + result.gids = append(result.gids, gid) + } + slices.Sort(result.gids) + + result.size = size + + return &result, err +} + +// Requires startWriting. +func (r *layerStore) applyDiffWithOptions(to string, layerOptions *LayerOptions, diff io.Reader) (_ int64, retErr error) { + if !r.lockfile.IsReadWrite() { + return -1, fmt.Errorf("not allowed to modify layer contents at %q: %w", r.layerdir, ErrStoreIsReadOnly) + } + + layer, ok := r.lookup(to) + if !ok { + return -1, ErrLayerUnknown } - slices.Sort(layer.GIDs) + + tarSplitFile, err := createTarSplitFile(r, layer.ID) + if err != nil { + return -1, err + } + // make sure to check for errors on close and return that one. + defer func() { + closeErr := tarSplitFile.Close() + if retErr == nil { + retErr = closeErr + } + }() + + result, err := applyDiff(layerOptions, diff, tarSplitFile, func(payload io.Reader) (int64, error) { + options := drivers.ApplyDiffOpts{ + Diff: payload, + Mappings: r.layerMappings(layer), + MountLabel: layer.MountLabel, + } + return r.driver.ApplyDiff(layer.ID, options) + }) + if err != nil { + return -1, err + } + + if err := tarSplitFile.Sync(); err != nil { + return -1, fmt.Errorf("sync tar-split file: %w", err) + } + + r.applyDiffResultToLayer(layer, result) err = r.saveFor(layer) - return size, err + return result.size, err +} + +// Requires startWriting. +func (r *layerStore) applyDiffResultToLayer(layer *Layer, result *applyDiffResult) { + updateDigestMap(&r.bycompressedsum, layer.CompressedDigest, result.compressedDigest, layer.ID) + layer.CompressedDigest = result.compressedDigest + layer.CompressedSize = result.compressedSize + updateDigestMap(&r.byuncompressedsum, layer.UncompressedDigest, result.uncompressedDigest, layer.ID) + layer.UncompressedDigest = result.uncompressedDigest + layer.UncompressedSize = result.uncompressedSize + layer.CompressionType = result.compressionType + layer.UIDs = result.uids + layer.GIDs = result.gids } // Requires (startReading or?) startWriting. @@ -2553,7 +2757,7 @@ func (r *layerStore) DifferTarget(id string) (string, error) { } // Requires startWriting. -func (r *layerStore) applyDiffFromStagingDirectory(id string, diffOutput *drivers.DriverWithDifferOutput, options *drivers.ApplyDiffWithDifferOpts) error { +func (r *layerStore) applyDiffFromStagingDirectory(id string, diffOutput *drivers.DriverWithDifferOutput, options *drivers.ApplyDiffWithDifferOpts) (retErr error) { ddriver, ok := r.driver.(drivers.DriverWithDiffer) if !ok { return ErrNotSupported @@ -2597,10 +2801,23 @@ func (r *layerStore) applyDiffFromStagingDirectory(id string, diffOutput *driver } if diffOutput.TarSplit != nil { - tsdata := bytes.Buffer{} - compressor, err := pgzip.NewWriterLevel(&tsdata, pgzip.BestSpeed) + tarSplitFile, err := createTarSplitFile(r, layer.ID) if err != nil { - compressor = pgzip.NewWriter(&tsdata) + return err + } + // make sure to check for errors on close and return that one. + defer func() { + closeErr := tarSplitFile.Close() + if retErr == nil { + retErr = closeErr + } + }() + tarSplitWriter := pools.BufioWriter32KPool.Get(tarSplitFile) + defer pools.BufioWriter32KPool.Put(tarSplitWriter) + + compressor, err := pgzip.NewWriterLevel(tarSplitWriter, pgzip.BestSpeed) + if err != nil { + compressor = pgzip.NewWriter(tarSplitWriter) } if _, err := diffOutput.TarSplit.Seek(0, io.SeekStart); err != nil { return err @@ -2614,11 +2831,12 @@ func (r *layerStore) applyDiffFromStagingDirectory(id string, diffOutput *driver return err } compressor.Close() - if err := os.MkdirAll(filepath.Dir(r.tspath(layer.ID)), 0o700); err != nil { - return err + + if err := tarSplitWriter.Flush(); err != nil { + return fmt.Errorf("failed to flush tar-split writer buffer: %w", err) } - if err := ioutils.AtomicWriteFile(r.tspath(layer.ID), tsdata.Bytes(), 0o600); err != nil { - return err + if err := tarSplitFile.Sync(); err != nil { + return fmt.Errorf("sync tar-split file: %w", err) } } for k, v := range diffOutput.BigData { diff --git a/vendor/go.podman.io/storage/pkg/chunked/storage_linux.go b/vendor/go.podman.io/storage/pkg/chunked/storage_linux.go index 6e7ea30f4..23baef9a4 100644 --- a/vendor/go.podman.io/storage/pkg/chunked/storage_linux.go +++ b/vendor/go.podman.io/storage/pkg/chunked/storage_linux.go @@ -18,7 +18,7 @@ import ( "syscall" "github.com/containerd/stargz-snapshotter/estargz" - "github.com/cyphar/filepath-securejoin/pathrs-lite" + securejoin "github.com/cyphar/filepath-securejoin" jsoniter "github.com/json-iterator/go" "github.com/klauspost/compress/zstd" "github.com/klauspost/pgzip" @@ -2040,10 +2040,10 @@ func (fg *stagedFileGetter) Get(filename string) (io.ReadCloser, error) { } filename = path } - pathFD, err := pathrs.OpenatInRoot(fg.rootDir, filename) + pathFD, err := securejoin.OpenatInRoot(fg.rootDir, filename) if err != nil { return nil, err } defer pathFD.Close() - return pathrs.Reopen(pathFD, unix.O_RDONLY) + return securejoin.Reopen(pathFD, unix.O_RDONLY) } diff --git a/vendor/go.podman.io/storage/pkg/idtools/idtools_supported.go b/vendor/go.podman.io/storage/pkg/idtools/idtools_supported.go index 9a17f5701..8a3076a0f 100644 --- a/vendor/go.podman.io/storage/pkg/idtools/idtools_supported.go +++ b/vendor/go.podman.io/storage/pkg/idtools/idtools_supported.go @@ -20,6 +20,12 @@ struct subid_range get_range(struct subid_range *ranges, int i) return ranges[i]; } +// helper for stderr to avoid referencing C.stderr from Go code, +// which breaks cgo on musl due to stderr being declared as FILE *const +static FILE *subid_stderr(void) { + return stderr; +} + #if !defined(SUBID_ABI_MAJOR) || (SUBID_ABI_MAJOR < 4) # define subid_init libsubid_init # define subid_get_uid_ranges get_subuid_ranges @@ -44,7 +50,7 @@ func readSubid(username string, isUser bool) (ranges, error) { } onceInit.Do(func() { - C.subid_init(C.CString("storage"), C.stderr) + C.subid_init(C.CString("storage"), C.subid_stderr()) }) cUsername := C.CString(username) diff --git a/vendor/go.podman.io/storage/pkg/lockfile/lockfile.go b/vendor/go.podman.io/storage/pkg/lockfile/lockfile.go index 52b4fe597..3a8a4bc39 100644 --- a/vendor/go.podman.io/storage/pkg/lockfile/lockfile.go +++ b/vendor/go.podman.io/storage/pkg/lockfile/lockfile.go @@ -420,7 +420,10 @@ func (l *LockFile) tryLock(lType rawfilelock.LockType) error { if !success { return fmt.Errorf("resource temporarily unavailable") } - l.stateMutex.Lock() + if !l.stateMutex.TryLock() { + rwMutexUnlocker() + return fmt.Errorf("resource temporarily unavailable") + } defer l.stateMutex.Unlock() if l.counter == 0 { // If we're the first reference on the lock, we need to open the file again. diff --git a/vendor/go.podman.io/storage/store.go b/vendor/go.podman.io/storage/store.go index 84019a494..3d8ea5075 100644 --- a/vendor/go.podman.io/storage/store.go +++ b/vendor/go.podman.io/storage/store.go @@ -1449,12 +1449,48 @@ func (s *store) canUseShifting(uidmap, gidmap []idtools.IDMap) bool { return s.graphDriver.SupportsShifting(uidmap, gidmap) } +// On entry: +// - rlstore must be locked for reading or writing +// - rlstores MUST NOT be locked +// Returns an extra unlock function to unlock any potentially read locked rlstores by this function. +// The unlock function is always set and thus must always be called. +func getParentLayer(rlstore roLayerStore, rlstores []roLayerStore, parent string) (*Layer, func(), error) { + // function we return to the caller so the caller gets the right stores locked and can unlock at the proper time themselves + var lockedLayerStores []roLayerStore + unlock := func() { + for _, i := range lockedLayerStores { + i.stopReading() + } + } + for _, l := range append([]roLayerStore{rlstore}, rlstores...) { + lstore := l + if lstore != rlstore { + if err := lstore.startReading(); err != nil { + return nil, unlock, err + } + lockedLayerStores = append(lockedLayerStores, lstore) + } + if l, err := lstore.Get(parent); err == nil && l != nil { + return l, unlock, nil + } + } + + return nil, unlock, ErrLayerUnknown +} + // On entry: // - rlstore must be locked for writing // - rlstores MUST NOT be locked -func (s *store) putLayer(rlstore rwLayerStore, rlstores []roLayerStore, id, parent string, names []string, mountLabel string, writeable bool, lOptions *LayerOptions, diff io.Reader, slo *stagedLayerOptions) (*Layer, int64, error) { +// +// Returns the new copied LayerOptions with mappings set, the parent Layer and +// an extra unlock function to unlock any potentially read locked rlstores by this function. +// The unlock function is always set and thus must always be called. +func populateLayerOptions(s *store, rlstore rwLayerStore, rlstores []roLayerStore, parent string, lOptions *LayerOptions) (*LayerOptions, *Layer, func(), error) { + // WARNING: Update also the freshLayer checks in store.PutLayer if adding more logic here. var parentLayer *Layer var options LayerOptions + // make sure we always return a valid func instead of nil so the caller can call it without checking + unlock := func() {} if lOptions != nil { options = *lOptions options.BigData = slices.Clone(lOptions.BigData) @@ -1469,53 +1505,32 @@ func (s *store) putLayer(rlstore rwLayerStore, rlstores []roLayerStore, id, pare uidMap := options.UIDMap gidMap := options.GIDMap if parent != "" { - var ilayer *Layer - for _, l := range append([]roLayerStore{rlstore}, rlstores...) { - lstore := l - if lstore != rlstore { - if err := lstore.startReading(); err != nil { - return nil, -1, err - } - defer lstore.stopReading() - } - if l, err := lstore.Get(parent); err == nil && l != nil { - ilayer = l - parent = ilayer.ID - break - } - } - if ilayer == nil { - return nil, -1, ErrLayerUnknown + var err error + parentLayer, unlock, err = getParentLayer(rlstore, rlstores, parent) + if err != nil { + return nil, nil, unlock, err } - parentLayer = ilayer if err := s.containerStore.startWriting(); err != nil { - return nil, -1, err + return nil, nil, unlock, err } defer s.containerStore.stopWriting() containers, err := s.containerStore.Containers() if err != nil { - return nil, -1, err + return nil, nil, unlock, err } for _, container := range containers { if container.LayerID == parent { - return nil, -1, ErrParentIsContainer + return nil, nil, unlock, ErrParentIsContainer } } if !options.HostUIDMapping && len(options.UIDMap) == 0 { - uidMap = ilayer.UIDMap + uidMap = parentLayer.UIDMap } if !options.HostGIDMapping && len(options.GIDMap) == 0 { - gidMap = ilayer.GIDMap + gidMap = parentLayer.GIDMap } } else { - // FIXME? It’s unclear why we are holding containerStore locked here at all - // (and because we are not modifying it, why it is a write lock, not a read lock). - if err := s.containerStore.startWriting(); err != nil { - return nil, -1, err - } - defer s.containerStore.stopWriting() - if !options.HostUIDMapping && len(options.UIDMap) == 0 { uidMap = s.uidMap } @@ -1533,7 +1548,7 @@ func (s *store) putLayer(rlstore rwLayerStore, rlstores []roLayerStore, id, pare GIDMap: copySlicePreferringNil(gidMap), } } - return rlstore.create(id, parentLayer, names, mountLabel, nil, &options, writeable, diff, slo) + return &options, parentLayer, unlock, nil } func (s *store) PutLayer(id, parent string, names []string, mountLabel string, writeable bool, lOptions *LayerOptions, diff io.Reader) (*Layer, int64, error) { @@ -1541,11 +1556,92 @@ func (s *store) PutLayer(id, parent string, names []string, mountLabel string, w if err != nil { return nil, -1, err } + + var ( + contents *layerCreationContents + options *LayerOptions + parentLayer *Layer + ) + + if diff != nil { + m := rlstore.newMaybeStagedLayerExtraction(diff) + defer func() { + if err := m.cleanup(); err != nil { + logrus.Errorf("Error cleaning up temporary directories: %v", err) + } + }() + // driver can do unlocked staging so do that without holding the layer lock + // Special case we only support it when no mount label is used. c/image doesn't set it for layers + // and the overlay driver doesn't use it for extract today so it would be safe even when set but + // that is not exactly obvious and if someone would implement the ApplyDiffStaging interface for + // another driver that may be no longer true. So for now simply fall back to the locked extract path + // to ensure we don't cause any weird issues here. + if m.staging != nil && mountLabel == "" { + // func so we have a scope for defer, we don't want to hold the lock for stageWithUnlockedStore() + layer, err := func() (*Layer, error) { + if err := rlstore.startWriting(); err != nil { + return nil, err + } + defer rlstore.stopWriting() + + if layer, err := rlstore.checkIdOrNameConflict(id, names); err != nil { + return layer, err + } + + var unlockLayerStores func() + options, parentLayer, unlockLayerStores, err = populateLayerOptions(s, rlstore, rlstores, parent, lOptions) + unlockLayerStores() + return nil, err + }() + if err != nil { + return layer, -1, err + } + + // make sure to use the resolved full ID if there is a parent + if parentLayer != nil { + parent = parentLayer.ID + } + + if err := rlstore.stageWithUnlockedStore(m, parent, options); err != nil { + return nil, -1, err + } + } + + contents = &layerCreationContents{ + stagedLayerExtraction: m, + } + } + if err := rlstore.startWriting(); err != nil { return nil, -1, err } defer rlstore.stopWriting() - return s.putLayer(rlstore, rlstores, id, parent, names, mountLabel, writeable, lOptions, diff, nil) + + if options == nil { + var unlockLayerStores func() + options, parentLayer, unlockLayerStores, err = populateLayerOptions(s, rlstore, rlstores, parent, lOptions) + defer unlockLayerStores() + if err != nil { + return nil, -1, err + } + } else if parent != "" { + // We used the staged extraction without holding the lock. + // Check again that the parent layer is still valid and exists. + freshLayer, unlockLayerStores, err := getParentLayer(rlstore, rlstores, parent) + defer unlockLayerStores() + if err != nil { + return nil, -1, err + } + // In populateLayerOptions() we get the ID mappings in order to extract correctly, ensure the freshly + // looked up parent Layer still has the same mappings to prevent silent UID/GID corruption. + if !slices.Equal(freshLayer.UIDMap, parentLayer.UIDMap) || !slices.Equal(freshLayer.GIDMap, parentLayer.GIDMap) { + // Fatal problem. Mappings changed so the parent must be considered different now. + // Since we consumed the diff there is no we to recover, return error to caller. The caller would need to retry. + // How likely is that and would need to return a special error so c/image could do the retries? + return nil, -1, fmt.Errorf("error during staged layer apply, parent layer %q changed id mappings while the content was extracted, must retry layer creation", parent) + } + } + return rlstore.create(id, parentLayer, names, mountLabel, nil, options, writeable, contents) } func (s *store) CreateLayer(id, parent string, names []string, mountLabel string, writeable bool, options *LayerOptions) (*Layer, error) { @@ -1753,7 +1849,7 @@ func (s *store) imageTopLayerForMapping(image *Image, ristore roImageStore, rlst } } layerOptions.TemplateLayer = layer.ID - mappedLayer, _, err := rlstore.create("", parentLayer, nil, layer.MountLabel, nil, &layerOptions, false, nil, nil) + mappedLayer, _, err := rlstore.create("", parentLayer, nil, layer.MountLabel, nil, &layerOptions, false, nil) if err != nil { return nil, fmt.Errorf("creating an ID-mapped copy of layer %q: %w", layer.ID, err) } @@ -1924,7 +2020,7 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat options.Flags[mountLabelFlag] = mountLabel } - clayer, _, err := rlstore.create(layer, imageTopLayer, nil, mlabel, options.StorageOpt, layerOptions, true, nil, nil) + clayer, _, err := rlstore.create(layer, imageTopLayer, nil, mlabel, options.StorageOpt, layerOptions, true, nil) if err != nil { return nil, err } @@ -3182,11 +3278,16 @@ func (s *store) ApplyStagedLayer(args ApplyStagedLayerOptions) (*Layer, error) { // if the layer doesn't exist yet, try to create it. - slo := stagedLayerOptions{ + contents := layerCreationContents{ DiffOutput: args.DiffOutput, DiffOptions: args.DiffOptions, } - layer, _, err = s.putLayer(rlstore, rlstores, args.ID, args.ParentLayer, args.Names, args.MountLabel, args.Writeable, args.LayerOptions, nil, &slo) + options, parentLayer, unlockLayerStores, err := populateLayerOptions(s, rlstore, rlstores, args.ParentLayer, args.LayerOptions) + defer unlockLayerStores() + if err != nil { + return nil, err + } + layer, _, err = rlstore.create(args.ID, parentLayer, args.Names, args.MountLabel, nil, options, args.Writeable, &contents) return layer, err } diff --git a/vendor/go.podman.io/storage/userns.go b/vendor/go.podman.io/storage/userns.go index f22a1cfe9..91bfc27c9 100644 --- a/vendor/go.podman.io/storage/userns.go +++ b/vendor/go.podman.io/storage/userns.go @@ -8,7 +8,7 @@ import ( "os/user" "strconv" - pathrs "github.com/cyphar/filepath-securejoin/pathrs-lite" + securejoin "github.com/cyphar/filepath-securejoin" libcontainerUser "github.com/moby/sys/user" "github.com/sirupsen/logrus" drivers "go.podman.io/storage/drivers" @@ -197,7 +197,7 @@ outer: // We need to create a temporary layer so we can mount it and lookup the // maximum IDs used. - clayer, _, err := rlstore.create("", topLayer, nil, "", nil, layerOptions, false, nil, nil) + clayer, _, err := rlstore.create("", topLayer, nil, "", nil, layerOptions, false, nil) if err != nil { return 0, err } @@ -331,11 +331,11 @@ func getAutoUserNSIDMappings( // Securely open (read-only) a file in a container mount. func secureOpen(containerMount, file string) (*os.File, error) { - tmpFile, err := pathrs.OpenInRoot(containerMount, file) + tmpFile, err := securejoin.OpenInRoot(containerMount, file) if err != nil { return nil, err } defer tmpFile.Close() - return pathrs.Reopen(tmpFile, unix.O_RDONLY) + return securejoin.Reopen(tmpFile, unix.O_RDONLY) } diff --git a/vendor/google.golang.org/grpc/balancer/balancer.go b/vendor/google.golang.org/grpc/balancer/balancer.go index 326888ae3..7e3dbaad2 100644 --- a/vendor/google.golang.org/grpc/balancer/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/balancer.go @@ -60,7 +60,7 @@ func Register(b Builder) { if !envconfig.CaseSensitiveBalancerRegistries { name = strings.ToLower(name) if name != b.Name() { - logger.Warningf("Balancer registered with name %q. grpc-go will be switching to case sensitive balancer registries soon. After 2 releases, we will enable the env var by default.", b.Name()) + logger.Warningf("Balancer registered with name %q. grpc-go has switched to case sensitive balancer registries. GRPC_GO_EXPERIMENTAL_CASE_SENSITIVE_BALANCER_REGISTRIES env variable will be removed in release v1.82.0", b.Name()) } } m[name] = b @@ -85,7 +85,7 @@ func Get(name string) Builder { if !envconfig.CaseSensitiveBalancerRegistries { lowerName := strings.ToLower(name) if lowerName != name { - logger.Warningf("Balancer retrieved for name %q. grpc-go will be switching to case sensitive balancer registries soon. After 2 releases, we will enable the env var by default.", name) + logger.Warningf("Balancer retrieved for name %q. grpc-go has switched to case sensitive balancer registries. GRPC_GO_EXPERIMENTAL_CASE_SENSITIVE_BALANCER_REGISTRIES env variable will be removed in release v1.82.0", name) } name = lowerName } diff --git a/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go b/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go index 518a69d57..d48bc304c 100644 --- a/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go +++ b/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go @@ -35,9 +35,9 @@ import ( "google.golang.org/grpc/balancer" "google.golang.org/grpc/balancer/pickfirst/internal" "google.golang.org/grpc/connectivity" + "google.golang.org/grpc/experimental/balancer/weight" expstats "google.golang.org/grpc/experimental/stats" "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/internal/balancer/weight" "google.golang.org/grpc/internal/envconfig" internalgrpclog "google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/internal/pretty" diff --git a/vendor/google.golang.org/grpc/dialoptions.go b/vendor/google.golang.org/grpc/dialoptions.go index 4ec5f9cd0..3af08e1ab 100644 --- a/vendor/google.golang.org/grpc/dialoptions.go +++ b/vendor/google.golang.org/grpc/dialoptions.go @@ -173,10 +173,8 @@ func newJoinDialOption(opts ...DialOption) DialOption { // If this option is set to true every connection will release the buffer after // flushing the data on the wire. // -// # Experimental -// -// Notice: This API is EXPERIMENTAL and may be changed or removed in a -// later release. +// Deprecated: shared write buffer is enabled by default. WithSharedWriteBuffer +// will be removed in a future release. func WithSharedWriteBuffer(val bool) DialOption { return newFuncDialOption(func(o *dialOptions) { o.copts.SharedWriteBuffer = val @@ -229,6 +227,14 @@ func WithInitialConnWindowSize(s int32) DialOption { // WithStaticStreamWindowSize returns a DialOption which sets the initial // stream window size to the value provided and disables dynamic flow control. +// +// Note that this also disables dynamic flow control for the connection, +// falling back to a default static connection-level window of 64KB. To +// use a larger connection-level window, you must also use the +// [WithStaticConnWindowSize] DialOption. +// +// Most users should not configure static flow control windows unless +// operating in a memory-constrained environment. func WithStaticStreamWindowSize(s int32) DialOption { return newFuncDialOption(func(o *dialOptions) { o.copts.InitialWindowSize = s @@ -239,6 +245,14 @@ func WithStaticStreamWindowSize(s int32) DialOption { // WithStaticConnWindowSize returns a DialOption which sets the initial // connection window size to the value provided and disables dynamic flow // control. +// +// Note that this also disables dynamic flow control for individual streams, +// falling back to a default static connection-level window of 64KB. To +// explicitly configure the stream-level window size, you must also use the +// [WithStaticStreamWindowSize] DialOption. +// +// Most users should not configure static flow control windows unless +// operating in a memory-constrained environment. func WithStaticConnWindowSize(s int32) DialOption { return newFuncDialOption(func(o *dialOptions) { o.copts.InitialConnWindowSize = s diff --git a/vendor/google.golang.org/grpc/encoding/encoding.go b/vendor/google.golang.org/grpc/encoding/encoding.go index 296f38c3a..bfa8b268f 100644 --- a/vendor/google.golang.org/grpc/encoding/encoding.go +++ b/vendor/google.golang.org/grpc/encoding/encoding.go @@ -66,6 +66,9 @@ type Compressor interface { // Decompress reads data from r, decompresses it, and provides the // uncompressed data via the returned io.Reader. If an error occurs while // initializing the decompressor, that error is returned instead. + // + // The returned io.Reader may optionally implement io.ReadCloser, and if it + // does, gRPC will call Close() exactly once. Decompress(r io.Reader) (io.Reader, error) // Name is the name of the compression codec and is used to set the content // coding header. The result must be static; the result cannot change diff --git a/vendor/google.golang.org/grpc/encoding/gzip/gzip.go b/vendor/google.golang.org/grpc/encoding/gzip/gzip.go index 153e4dbfb..65908d9a2 100644 --- a/vendor/google.golang.org/grpc/encoding/gzip/gzip.go +++ b/vendor/google.golang.org/grpc/encoding/gzip/gzip.go @@ -81,6 +81,8 @@ func (z *writer) Close() error { return z.Writer.Close() } +var _ io.Closer = &reader{} + type reader struct { *gzip.Reader pool *sync.Pool @@ -102,14 +104,16 @@ func (c *compressor) Decompress(r io.Reader) (io.Reader, error) { return z, nil } -func (z *reader) Read(p []byte) (n int, err error) { - n, err = z.Reader.Read(p) - if err == io.EOF { - z.pool.Put(z) - } +func (r *reader) Read(p []byte) (n int, err error) { + n, err = r.Reader.Read(p) return n, err } +func (r *reader) Close() error { + defer r.pool.Put(r) + return r.Reader.Close() +} + func (c *compressor) Name() string { return Name } diff --git a/vendor/google.golang.org/grpc/internal/balancer/weight/weight.go b/vendor/google.golang.org/grpc/experimental/balancer/weight/weight.go similarity index 71% rename from vendor/google.golang.org/grpc/internal/balancer/weight/weight.go rename to vendor/google.golang.org/grpc/experimental/balancer/weight/weight.go index 11beb07d1..beab9e07c 100644 --- a/vendor/google.golang.org/grpc/internal/balancer/weight/weight.go +++ b/vendor/google.golang.org/grpc/experimental/balancer/weight/weight.go @@ -16,23 +16,23 @@ * */ -// Package weight contains utilities to manage endpoint weights. Weights are -// used by LB policies such as ringhash to distribute load across multiple -// endpoints. +// Package weight contains utilities to manage endpoint weights. +// Weights may be used by LB policies to distribute load across +// multiple endpoints. +// +// # Experimental +// +// Notice: All APIs in this package are EXPERIMENTAL and may be changed +// or removed in a later release. package weight -import ( - "fmt" - - "google.golang.org/grpc/resolver" -) +import "google.golang.org/grpc/resolver" // attributeKey is the type used as the key to store EndpointInfo in the // Attributes field of resolver.Endpoint. type attributeKey struct{} -// EndpointInfo will be stored in the Attributes field of Endpoints in order to -// use the ringhash balancer. +// EndpointInfo will be stored in the Attributes field of Endpoints. type EndpointInfo struct { Weight uint32 } @@ -43,22 +43,16 @@ func (a EndpointInfo) Equal(o any) bool { return ok && oa.Weight == a.Weight } -// Set returns a copy of endpoint in which the Attributes field is updated with -// EndpointInfo. +// Set returns a copy of endpoint in which the Attributes field is +// updated with EndpointInfo. func Set(endpoint resolver.Endpoint, epInfo EndpointInfo) resolver.Endpoint { endpoint.Attributes = endpoint.Attributes.WithValue(attributeKey{}, epInfo) return endpoint } -// String returns a human-readable representation of EndpointInfo. -// This method is intended for logging, testing, and debugging purposes only. -// Do not rely on the output format, as it is not guaranteed to remain stable. -func (a EndpointInfo) String() string { - return fmt.Sprintf("Weight: %d", a.Weight) -} - -// FromEndpoint returns the EndpointInfo stored in the Attributes field of an -// endpoint. It returns an empty EndpointInfo if attribute is not found. +// FromEndpoint returns the EndpointInfo stored in the Attributes +// field of an endpoint. It returns an empty EndpointInfo if attribute +// is not found. func FromEndpoint(endpoint resolver.Endpoint) EndpointInfo { v := endpoint.Attributes.Value(attributeKey{}) ei, _ := v.(EndpointInfo) diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go index 9e10fdd2e..537ba0571 100644 --- a/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go +++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.6.1 +// - protoc-gen-go-grpc v1.6.2 // - protoc v5.27.1 // source: grpc/health/v1/health.proto diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index 8ca87a57a..29d332e7b 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -59,6 +59,15 @@ var ( // unconditionally. XDSEndpointHashKeyBackwardCompat = boolFromEnv("GRPC_XDS_ENDPOINT_HASH_KEY_BACKWARD_COMPAT", false) + // LabelServerGoroutines controls setting [runtime/pprof.Labels] on the + // goroutines spawned by [grpc.Server] type. + // For now, this is limited to the goroutines spawned to handle incoming + // requests on the server. + // Set "GRPC_GO_SERVER_GOROUTINE_LABELS" to "grpc.method=true" to + // enable this grpc.method label, or "all" to enable all valid labels. + // This variable is a bit-field. + LabelServerGoroutines = goroutineLabelsFromEnv("GRPC_GO_SERVER_GOROUTINE_LABELS", 0) + // RingHashSetRequestHashKey is set if the ring hash balancer can get the // request hash header by setting the "requestHashHeader" field, according // to gRFC A76. It can be disabled by setting the environment variable @@ -78,12 +87,12 @@ var ( EnableDefaultPortForProxyTarget = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_DEFAULT_PORT_FOR_PROXY_TARGET", true) // CaseSensitiveBalancerRegistries is set if the balancer registry should be - // case-sensitive. This is disabled by default, but can be enabled by setting + // case-sensitive. This is enabled by default, but can be disabled by setting // the env variable "GRPC_GO_EXPERIMENTAL_CASE_SENSITIVE_BALANCER_REGISTRIES" - // to "true". + // to "false". // - // TODO: After 2 releases, we will enable the env var by default. - CaseSensitiveBalancerRegistries = boolFromEnv("GRPC_GO_EXPERIMENTAL_CASE_SENSITIVE_BALANCER_REGISTRIES", false) + // This env varible will be removed in release v1.82.0. + CaseSensitiveBalancerRegistries = boolFromEnv("GRPC_GO_EXPERIMENTAL_CASE_SENSITIVE_BALANCER_REGISTRIES", true) // XDSAuthorityRewrite indicates whether xDS authority rewriting is enabled. // This feature is defined in gRFC A81 and is enabled by setting the @@ -104,22 +113,6 @@ var ( // to "false". XDSRecoverPanicInResourceParsing = boolFromEnv("GRPC_GO_EXPERIMENTAL_XDS_RESOURCE_PANIC_RECOVERY", true) - // DisableStrictPathChecking indicates whether strict path checking is - // disabled. This feature can be disabled by setting the environment - // variable GRPC_GO_EXPERIMENTAL_DISABLE_STRICT_PATH_CHECKING to "true". - // - // When strict path checking is enabled, gRPC will reject requests with - // paths that do not conform to the gRPC over HTTP/2 specification found at - // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md. - // - // When disabled, gRPC will allow paths that do not contain a leading slash. - // Enabling strict path checking is recommended for security reasons, as it - // prevents potential path traversal vulnerabilities. - // - // A future release will remove this environment variable, enabling strict - // path checking behavior unconditionally. - DisableStrictPathChecking = boolFromEnv("GRPC_GO_EXPERIMENTAL_DISABLE_STRICT_PATH_CHECKING", false) - // EnablePriorityLBChildPolicyCache controls whether the priority balancer // should cache child balancers that are removed from the LB policy config, // for a period of 15 minutes. This is disabled by default, but can be @@ -127,6 +120,18 @@ var ( // GRPC_EXPERIMENTAL_ENABLE_PRIORITY_LB_CHILD_POLICY_CACHE to true. EnablePriorityLBChildPolicyCache = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_PRIORITY_LB_CHILD_POLICY_CACHE", false) + // Enable8KBDefaultHeaderListSize indicates that default maximum header list + // size is restricted to 8KB. This is disabled by default, but can be enabled + // by setting the environment variable + // "GRPC_GO_EXPERIMENTAL_ENABLE_8KB_DEFAULT_HEADER_LIST_SIZE" to "true". + // When disabled, the default maximum header list size of 16MB is used. + // + // When enabled, RPCs with a total size of headers exceeding 8KB will fail + // unless explicitly configured otherwise by the user. + // + // TODO: In release v1.82.0, env var will be enabled by default. + Enable8KBDefaultHeaderListSize = boolFromEnv("GRPC_GO_EXPERIMENTAL_ENABLE_8KB_DEFAULT_HEADER_LIST_SIZE", false) + // EnableHTTPFramerReadBufferPooling enables the use of the // readyreader.Reader interface to perform non-memory-pinning reads, // provided the underlying net.Conn supports it. This reduces memory usage @@ -136,6 +141,17 @@ var ( // feature if unforeseen issues arise, and it will be removed in a future // release. EnableHTTPFramerReadBufferPooling = boolFromEnv("GRPC_GO_EXPERIMENTAL_HTTP_FRAMER_READ_BUFFER_POOLING", true) + + // ControlBufferThrottleLimit is the maximum number of control frames that can + // be queued in the control buffer before throttling is applied. The value + // must be between 1 and 10,000, and is set to 100 by default. + // + // This environment variable serves as an escape hatch to increase the + // throttling limit if unforeseen issues arise, and it will be removed in a + // future release. + // + // TODO: Remove this env var once v1.83.0 is release. + ControlBufferThrottleLimit = uint64FromEnv("GRPC_GO_EXPERIMENTAL_CONTROL_BUFFER_THROTTLE_LIMIT", 100, 1, 10000) ) func boolFromEnv(envVar string, def bool) bool { @@ -160,3 +176,52 @@ func uint64FromEnv(envVar string, def, min, max uint64) uint64 { } return v } + +// GoroutineLabels is a bitfield indicating which goroutine labels are enabled. +type GoroutineLabels uint16 + +func goroutineLabelsFromEnv(envVar string, def GoroutineLabels) GoroutineLabels { + val := def + v := os.Getenv(envVar) + if strings.EqualFold(v, "all") { + return AllGoroutineLabels + } else if strings.EqualFold(v, "none") { + return 0 + } + for s := range strings.SplitSeq(v, ",") { + s = strings.TrimSpace(s) + if len(s) == 0 { + continue + } + pre, post, ok := strings.Cut(s, "=") + if !ok { + // no equals sign + continue + } + post = strings.TrimSpace(post) + pre = strings.TrimSpace(pre) + bitDesignator := GoroutineLabels(0) + switch { + case strings.EqualFold(pre, "grpc.method"): + bitDesignator = GoroutineLabelServerMethod + default: + continue + } + if strings.EqualFold(post, "true") { + val |= bitDesignator + } else if strings.EqualFold(post, "false") { + val &^= bitDesignator + } + } + return val +} + +const ( + // GoroutineLabelServerMethod sets the grpc.method label on new + // server-side gRPC streams. + GoroutineLabelServerMethod GoroutineLabels = 1 << iota +) + +// AllGoroutineLabels is an or'd together bitfield of all valid GoroutineLabels +// constant values (above). +const AllGoroutineLabels = GoroutineLabelServerMethod diff --git a/vendor/google.golang.org/grpc/internal/envconfig/xds.go b/vendor/google.golang.org/grpc/internal/envconfig/xds.go index 333d8a0b0..a2312f8ea 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/xds.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/xds.go @@ -89,4 +89,14 @@ var ( // filtered and prefix-propagated to the LRS server. For more details, see: // https://github.com/grpc/proposal/blob/master/A85-lrs-custom-metrics-changes.md XDSORCAToLRSPropEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_ORCA_LRS_PROPAGATION", false) + + // XDSClientExtProcEnabled indicates whether ExtProc filter is enabled on + // the client side. For more details, see: + // https://github.com/grpc/proposal/blob/master/A93-xds-ext-proc.md + XDSClientExtProcEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_EXT_PROC_ON_CLIENT", false) + + // GCPAuthenticationFilterEnabled enables the xDS GCP Authentication + // filter. For more details, see: + // https://github.com/grpc/proposal/blob/master/A83-xds-gcp-authn-filter.md + GCPAuthenticationFilterEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_GCP_AUTHENTICATION_FILTER", false) ) diff --git a/vendor/google.golang.org/grpc/internal/grpcutil/encode_duration.go b/vendor/google.golang.org/grpc/internal/grpcutil/encode_duration.go index b25b0baec..1cc43fc6b 100644 --- a/vendor/google.golang.org/grpc/internal/grpcutil/encode_duration.go +++ b/vendor/google.golang.org/grpc/internal/grpcutil/encode_duration.go @@ -39,7 +39,6 @@ func div(d, r time.Duration) int64 { // // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests func EncodeDuration(t time.Duration) string { - // TODO: This is simplistic and not bandwidth efficient. Improve it. if t <= 0 { return "0n" } diff --git a/vendor/google.golang.org/grpc/internal/resolver/config_selector.go b/vendor/google.golang.org/grpc/internal/resolver/config_selector.go index 3db62ccad..6320e9b57 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/config_selector.go +++ b/vendor/google.golang.org/grpc/internal/resolver/config_selector.go @@ -106,14 +106,24 @@ type ClientStream interface { // ClientInterceptor is an interceptor for gRPC client streams. type ClientInterceptor interface { - // NewStream produces a ClientStream for an RPC which may optionally use - // the provided function to produce a stream for delegation. Note: - // RPCInfo.Context should not be used (will be nil). + // NewStream creates a ClientStream for an RPC. // - // done is invoked when the RPC is finished using its connection, or could - // not be assigned a connection. RPC operations may still occur on - // ClientStream after done is called, since the interceptor is invoked by - // application-layer operations. done must never be nil when called. + // Implementations must delegate stream creation to the provided newStream + // function. To intercept or override stream behavior, implementations + // may wrap the ClientStream returned by the delegate. + // + // Note: RPCInfo.Context is currently unused and will be nil. + // + // The done function is invoked when the RPC has finished using its + // underlying connection or if a connection could not be assigned. Because + // interceptors operate at the application layer, RPC operations may + // continue on the ClientStream even after done has been called. The + // caller must ensure done is non-nil. + // + // To ensure RPC completion notifications propagate through the entire + // interceptor chain, implementations must ensure that the done function + // passed to the delegate newStream invokes the done function passed to + // NewStream. NewStream(ctx context.Context, ri RPCInfo, done func(), newStream func(ctx context.Context, done func()) (ClientStream, error)) (ClientStream, error) // Close closes the interceptor. Once called, no new calls to NewStream are // accepted. Ongoing calls to NewStream are allowed to complete. diff --git a/vendor/google.golang.org/grpc/internal/stats/labels.go b/vendor/google.golang.org/grpc/internal/stats/labels.go index fd33af51a..5ea898cb5 100644 --- a/vendor/google.golang.org/grpc/internal/stats/labels.go +++ b/vendor/google.golang.org/grpc/internal/stats/labels.go @@ -19,24 +19,56 @@ // Package stats provides internal stats related functionality. package stats -import "context" +import ( + "context" + "maps" +) -// Labels are the labels for metrics. -type Labels struct { - // TelemetryLabels are the telemetry labels to record. - TelemetryLabels map[string]string +// LabelCallback is a function that is executed when telemetry +// label keys are updated. +type LabelCallback func(map[string]string) +type telemetryLabelCallbackKey struct{} + +// UpdateLabels executes registered telemetry callbacks with the update labels. Labels +// are copied before being processed by any callbacks to ensure mutations are not +// shared among derived contexts. +// +// It is the responsibility of the registrant to handle conflicts or label resets. +func UpdateLabels(ctx context.Context, update map[string]string) { + executeTelemetryLabelCallbacks(ctx, update) } -type labelsKey struct{} +// RegisterTelemetryLabelCallback registers a callback function that is executed whenever +// telemetry labels are updated. +func RegisterTelemetryLabelCallback(ctx context.Context, callback LabelCallback) context.Context { + if callback == nil { + return ctx + } + + callbacks, ok := ctx.Value(telemetryLabelCallbackKey{}).([]LabelCallback) + if !ok { + return context.WithValue(ctx, telemetryLabelCallbackKey{}, []LabelCallback{callback}) + } + return context.WithValue(ctx, telemetryLabelCallbackKey{}, append(append([]LabelCallback(nil), callbacks...), callback)) -// GetLabels returns the Labels stored in the context, or nil if there is one. -func GetLabels(ctx context.Context) *Labels { - labels, _ := ctx.Value(labelsKey{}).(*Labels) - return labels } -// SetLabels sets the Labels in the context. -func SetLabels(ctx context.Context, labels *Labels) context.Context { - // could also append - return context.WithValue(ctx, labelsKey{}, labels) +// executeTelemetryLabelCallback runs the registered callbacks in the order they were +// registered on the context with the provided labels. If no callbacks are registered +// it does nothing. +// +// To ensure callbacks do not mutate the state of the provided label map it is copied +// before execution. +func executeTelemetryLabelCallbacks(ctx context.Context, labels map[string]string) { + callbacks, ok := ctx.Value(telemetryLabelCallbackKey{}).([]LabelCallback) + if !ok { + return + } + + labelsCopy := map[string]string{} + maps.Copy(labelsCopy, labels) + for _, callback := range callbacks { + callback(labelsCopy) + } + } diff --git a/vendor/google.golang.org/grpc/internal/transport/client_stream.go b/vendor/google.golang.org/grpc/internal/transport/client_stream.go index cd8152ef1..ad382b0fd 100644 --- a/vendor/google.golang.org/grpc/internal/transport/client_stream.go +++ b/vendor/google.golang.org/grpc/internal/transport/client_stream.go @@ -19,6 +19,7 @@ package transport import ( + "fmt" "sync/atomic" "golang.org/x/net/http2" @@ -28,6 +29,12 @@ import ( "google.golang.org/grpc/status" ) +// nonGRPCDataMaxLen is the maximum length of nonGRPCDataBuf. +// +// NOTE: If changed this value, you MUST update the corresponding test in: +// - /test/end2end_test.go:TestHTTPServerSendsNonGRPCHeaderSurfaceFurtherData +const nonGRPCDataMaxLen = 1024 + // ClientStream implements streaming functionality for a gRPC client. type ClientStream struct { Stream // Embed for common stream functionality. @@ -46,7 +53,11 @@ type ClientStream struct { // headerValid indicates whether a valid header was received. Only // meaningful after headerChan is closed (always call waitOnHeader() before // reading its value). - headerValid bool + headerValid bool + + nonGRPCStatus *status.Status // the initial status from the non-gRPC response header, finalized with collected data before closing. + nonGRPCDataBuf []byte // stores the data of a non-gRPC response. + noHeaders bool // set if the client never received headers (set only after the stream is done). headerChanClosed uint32 // set when headerChan is closed. Used to avoid closing headerChan multiple times. bytesReceived atomic.Bool // indicates whether any bytes have been received on this stream @@ -54,6 +65,29 @@ type ClientStream struct { statsHandler stats.Handler // nil for internal streams (e.g., health check, ORCA) where telemetry is not supported. } +func (s *ClientStream) startNonGRPCDataCollection(st *status.Status) { + s.nonGRPCStatus = st + s.nonGRPCDataBuf = make([]byte, 0, nonGRPCDataMaxLen) +} + +// finalizeNonGRPCStatus builds the terminal status by appending the collected +// response body to the original non-gRPC status message. +func (s *ClientStream) finalizeNonGRPCStatus() *status.Status { + msg := fmt.Sprintf("%s\ndata: %q", s.nonGRPCStatus.Message(), s.nonGRPCDataBuf) + return status.New(s.nonGRPCStatus.Code(), msg) +} + +// handleNonGRPCData collects non-gRPC body from the given data frame. +// It returns non-nil value when the stream should be closed with it. +func (s *ClientStream) handleNonGRPCData(f *parsedDataFrame) *status.Status { + n := min(f.data.Len(), nonGRPCDataMaxLen-len(s.nonGRPCDataBuf)) + s.nonGRPCDataBuf = append(s.nonGRPCDataBuf, f.data.ReadOnlyData()[0:n]...) + if len(s.nonGRPCDataBuf) >= nonGRPCDataMaxLen || f.StreamEnded() { + return s.finalizeNonGRPCStatus() + } + return nil +} + // Read reads an n byte message from the input stream. func (s *ClientStream) Read(n int) (mem.BufferSlice, error) { b, err := s.Stream.read(n) diff --git a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go index 7efa52478..b9bae0249 100644 --- a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go +++ b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go @@ -29,6 +29,7 @@ import ( "golang.org/x/net/http2" "golang.org/x/net/http2/hpack" + "google.golang.org/grpc/internal/envconfig" "google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/mem" ) @@ -96,61 +97,70 @@ func (il *itemList) isEmpty() bool { return il.head == nil } -// The following defines various control items which could flow through -// the control buffer of transport. They represent different aspects of -// control tasks, e.g., flow control, settings, streaming resetting, etc. - -// maxQueuedTransportResponseFrames is the most queued "transport response" -// frames we will buffer before preventing new reads from occurring on the -// transport. These are control frames sent in response to client requests, -// such as RST_STREAM due to bad headers or settings acks. -const maxQueuedTransportResponseFrames = 50 +// maxQueuedControlBufferItems is the maximum number of frames (other than +// HEADERS and DATA) that we will buffer before preventing new reads from +// occurring on the transport. These are control frames sent in response to +// client requests, or frames that result in work being scheduled, such as +// RST_STREAM due to bad headers or settings acks. +var maxQueuedControlBufferItems = int(envconfig.ControlBufferThrottleLimit) type cbItem interface { - isTransportResponseFrame() bool + isThrottled() bool } +// throttledItem represents every item in the controlBuffer to which the overall +// throttling limit applies, other than outgoing HEADERS and DATA frames. +type throttledItem struct{} + +func (throttledItem) isThrottled() bool { return true } + +// The following defines various control items which could flow through +// the control buffer of transport. They represent different aspects of +// control tasks, e.g., flow control, settings, streaming resetting, etc. + // registerStream is used to register an incoming stream with loopy writer. type registerStream struct { + throttledItem streamID uint32 wq *writeQuota } -func (*registerStream) isTransportResponseFrame() bool { return false } - -// headerFrame is also used to register stream on the client-side. -type headerFrame struct { +type clientHeaders struct { streamID uint32 hf []hpack.HeaderField - endStream bool // Valid on server side. - initStream func(uint32) error // Used only on the client side. + initStream func(uint32) error onWrite func() - wq *writeQuota // write quota for the stream created. - cleanup *cleanupStream // Valid on the server side. - onOrphaned func(error) // Valid on client-side + wq *writeQuota + onOrphaned func(error) } -func (h *headerFrame) isTransportResponseFrame() bool { - return h.cleanup != nil && h.cleanup.rst // Results in a RST_STREAM +func (*clientHeaders) isThrottled() bool { return false } + +type serverHeaders struct { + streamID uint32 + hf []hpack.HeaderField + endStream bool + onWrite func() + cleanup *cleanupStream } +func (h *serverHeaders) isThrottled() bool { return false } + type cleanupStream struct { + throttledItem streamID uint32 rst bool rstCode http2.ErrCode onWrite func() } -func (c *cleanupStream) isTransportResponseFrame() bool { return c.rst } // Results in a RST_STREAM - type earlyAbortStream struct { + throttledItem streamID uint32 rst bool hf []hpack.HeaderField // Pre-built header fields } -func (*earlyAbortStream) isTransportResponseFrame() bool { return false } - type dataFrame struct { streamID uint32 endStream bool @@ -162,70 +172,60 @@ type dataFrame struct { onEachWrite func() } -func (*dataFrame) isTransportResponseFrame() bool { return false } +func (*dataFrame) isThrottled() bool { return false } type incomingWindowUpdate struct { + throttledItem streamID uint32 increment uint32 } -func (*incomingWindowUpdate) isTransportResponseFrame() bool { return false } - type outgoingWindowUpdate struct { + throttledItem streamID uint32 increment uint32 } -func (*outgoingWindowUpdate) isTransportResponseFrame() bool { - return false // window updates are throttled by thresholds -} - type incomingSettings struct { + throttledItem ss []http2.Setting } -func (*incomingSettings) isTransportResponseFrame() bool { return true } // Results in a settings ACK - type outgoingSettings struct { + throttledItem ss []http2.Setting } -func (*outgoingSettings) isTransportResponseFrame() bool { return false } - type incomingGoAway struct { + throttledItem } -func (*incomingGoAway) isTransportResponseFrame() bool { return false } - type goAway struct { + throttledItem code http2.ErrCode debugData []byte headsUp bool closeConn error // if set, loopyWriter will exit with this error } -func (*goAway) isTransportResponseFrame() bool { return false } - type ping struct { + throttledItem ack bool data [8]byte } -func (*ping) isTransportResponseFrame() bool { return true } - type outFlowControlSizeRequest struct { + throttledItem resp chan uint32 } -func (*outFlowControlSizeRequest) isTransportResponseFrame() bool { return false } - // closeConnection is an instruction to tell the loopy writer to flush the // framer and exit, which will cause the transport's connection to be closed // (by the client or server). The transport itself will close after the reader // encounters the EOF caused by the connection closure. -type closeConnection struct{} - -func (closeConnection) isTransportResponseFrame() bool { return false } +type closeConnection struct { + throttledItem +} type outStreamState int @@ -379,9 +379,9 @@ func (c *controlBuffer) executeAndPut(f func() bool, it cbItem) (bool, error) { c.consumerWaiting = false } c.list.enqueue(it) - if it.isTransportResponseFrame() { + if it.isThrottled() { c.transportResponseFrames++ - if c.transportResponseFrames == maxQueuedTransportResponseFrames { + if c.transportResponseFrames == maxQueuedControlBufferItems { // We are adding the frame that puts us over the threshold; create // a throttling channel. ch := make(chan struct{}) @@ -436,8 +436,8 @@ func (c *controlBuffer) getOnceLocked() (any, error) { return nil, nil } h := c.list.dequeue().(cbItem) - if h.isTransportResponseFrame() { - if c.transportResponseFrames == maxQueuedTransportResponseFrames { + if h.isThrottled() { + if c.transportResponseFrames == maxQueuedControlBufferItems { // We are removing the frame that put us over the // threshold; close and clear the throttling channel. ch := c.trfChan.Swap(nil) @@ -464,10 +464,8 @@ func (c *controlBuffer) finish() { // is still not aware of these yet. for head := c.list.dequeueAll(); head != nil; head = head.next { switch v := head.it.(type) { - case *headerFrame: - if v.onOrphaned != nil { // It will be nil on the server-side. - v.onOrphaned(ErrConnClosing) - } + case *clientHeaders: + v.onOrphaned(ErrConnClosing) case *dataFrame: if !v.processing { v.data.Free() @@ -680,42 +678,38 @@ func (l *loopyWriter) registerStreamHandler(h *registerStream) { l.estdStreams[h.streamID] = str } -func (l *loopyWriter) headerHandler(h *headerFrame) error { - if l.side == serverSide { - str, ok := l.estdStreams[h.streamID] - if !ok { - if l.logger.V(logLevel) { - l.logger.Infof("Unrecognized streamID %d in loopyWriter", h.streamID) - } - return nil - } - // Case 1.A: Server is responding back with headers. - if !h.endStream { - return l.writeHeader(h.streamID, h.endStream, h.hf, h.onWrite) +func (l *loopyWriter) serverHeaderHandler(hdr *serverHeaders) error { + str, ok := l.estdStreams[hdr.streamID] + if !ok { + if l.logger.V(logLevel) { + l.logger.Infof("Unrecognized streamID %d in loopyWriter", hdr.streamID) } - // else: Case 1.B: Server wants to close stream. + return nil + } - if str.state != empty { // either active or waiting on stream quota. - // add it str's list of items. - str.itl.enqueue(h) - return nil - } - if err := l.writeHeader(h.streamID, h.endStream, h.hf, h.onWrite); err != nil { - return err - } - return l.cleanupStreamHandler(h.cleanup) + // Case 1: Server is responding back with headers. + if !hdr.endStream { + return l.writeHeader(hdr.streamID, hdr.endStream, hdr.hf, hdr.onWrite) + } + + // Case 2: Server is closing the stream. + if str.state != empty { // either active or waiting on stream quota. + str.itl.enqueue(hdr) + return nil + } + if err := l.writeHeader(hdr.streamID, hdr.endStream, hdr.hf, hdr.onWrite); err != nil { + return err } - // Case 2: Client wants to originate stream. + return l.cleanupStreamHandler(hdr.cleanup) +} + +func (l *loopyWriter) clientHeaderHandler(hdr *clientHeaders) error { str := &outStream{ - id: h.streamID, + id: hdr.streamID, state: empty, itl: &itemList{}, - wq: h.wq, + wq: hdr.wq, } - return l.originateStream(str, h) -} - -func (l *loopyWriter) originateStream(str *outStream, hdr *headerFrame) error { // l.draining is set when handling GoAway. In which case, we want to avoid // creating new streams. if l.draining { @@ -726,7 +720,7 @@ func (l *loopyWriter) originateStream(str *outStream, hdr *headerFrame) error { if err := hdr.initStream(str.id); err != nil { return err } - if err := l.writeHeader(str.id, hdr.endStream, hdr.hf, hdr.onWrite); err != nil { + if err := l.writeHeader(str.id, false, hdr.hf, hdr.onWrite); err != nil { return err } l.estdStreams[str.id] = str @@ -882,8 +876,10 @@ func (l *loopyWriter) handle(i any) error { return l.incomingSettingsHandler(i) case *outgoingSettings: return l.outgoingSettingsHandler(i) - case *headerFrame: - return l.headerHandler(i) + case *clientHeaders: + return l.clientHeaderHandler(i) + case *serverHeaders: + return l.serverHeaderHandler(i) case *registerStream: l.registerStreamHandler(i) case *cleanupStream: @@ -956,39 +952,16 @@ func (l *loopyWriter) processData() (bool, error) { // from data is copied to h to make as big as the maximum possible HTTP2 frame // size. - if len(dataItem.h) == 0 && reader.Remaining() == 0 { // Empty data frame - // Client sends out empty data frame with endStream = true - if err := l.framer.writeData(dataItem.streamID, dataItem.endStream, nil); err != nil { - return false, err - } - str.itl.dequeue() // remove the empty data item from stream - reader.Close() - if str.itl.isEmpty() { - str.state = empty - } else if trailer, ok := str.itl.peek().(*headerFrame); ok { // the next item is trailers. - if err := l.writeHeader(trailer.streamID, trailer.endStream, trailer.hf, trailer.onWrite); err != nil { - return false, err - } - if err := l.cleanupStreamHandler(trailer.cleanup); err != nil { - return false, err - } - } else { - l.activeStreams.enqueue(str) - } - return false, nil - } - + isEmpty := len(dataItem.h) == 0 && reader.Remaining() == 0 // Figure out the maximum size we can send maxSize := http2MaxFrameLen - if strQuota := int(l.oiws) - str.bytesOutStanding; strQuota <= 0 { // stream-level flow control. + strQuota := int(l.oiws) - str.bytesOutStanding + if strQuota <= 0 && !isEmpty { // stream-level flow control. str.state = waitingOnStreamQuota return false, nil - } else if maxSize > strQuota { - maxSize = strQuota - } - if maxSize > int(l.sendQuota) { // connection-level flow control. - maxSize = int(l.sendQuota) } + maxSize = min(maxSize, max(strQuota, 0)) + maxSize = min(maxSize, int(l.sendQuota)) // connection-level flow control. // Compute how much of the header and data we can send within quota and max frame length hSize := min(maxSize, len(dataItem.h)) dSize := min(maxSize-hSize, reader.Remaining()) @@ -1039,19 +1012,23 @@ func (l *loopyWriter) processData() (bool, error) { reader.Close() str.itl.dequeue() } + return false, l.updateStreamAfterWrite(str) +} + +func (l *loopyWriter) updateStreamAfterWrite(str *outStream) error { if str.itl.isEmpty() { str.state = empty - } else if trailer, ok := str.itl.peek().(*headerFrame); ok { // The next item is trailers. + } else if trailer, ok := str.itl.peek().(*serverHeaders); ok { // the next item is trailers. if err := l.writeHeader(trailer.streamID, trailer.endStream, trailer.hf, trailer.onWrite); err != nil { - return false, err + return err } if err := l.cleanupStreamHandler(trailer.cleanup); err != nil { - return false, err + return err } } else if int(l.oiws)-str.bytesOutStanding <= 0 { // Ran out of stream quota. str.state = waitingOnStreamQuota } else { // Otherwise add it back to the list of active streams. l.activeStreams.enqueue(str) } - return false, nil + return nil } diff --git a/vendor/google.golang.org/grpc/internal/transport/flowcontrol.go b/vendor/google.golang.org/grpc/internal/transport/flowcontrol.go index 7cfbc9637..98cef9ec2 100644 --- a/vendor/google.golang.org/grpc/internal/transport/flowcontrol.go +++ b/vendor/google.golang.org/grpc/internal/transport/flowcontrol.go @@ -115,7 +115,6 @@ func (f *trInFlow) getSize() uint32 { return atomic.LoadUint32(&f.effectiveWindowSize) } -// TODO(mmukhi): Simplify this code. // inFlow deals with inbound flow control type inFlow struct { mu sync.Mutex @@ -174,14 +173,14 @@ func (f *inFlow) maybeAdjust(n uint32) uint32 { // onData is invoked when some data frame is received. It updates pendingData. func (f *inFlow) onData(n uint32) error { f.mu.Lock() + defer f.mu.Unlock() + f.pendingData += n if f.pendingData+f.pendingUpdate > f.limit+f.delta { limit := f.limit rcvd := f.pendingData + f.pendingUpdate - f.mu.Unlock() return fmt.Errorf("received %d-bytes data exceeding the limit %d bytes", rcvd, limit) } - f.mu.Unlock() return nil } @@ -189,8 +188,9 @@ func (f *inFlow) onData(n uint32) error { // to be sent to the peer. func (f *inFlow) onRead(n uint32) uint32 { f.mu.Lock() + defer f.mu.Unlock() + if f.pendingData == 0 { - f.mu.Unlock() return 0 } f.pendingData -= n @@ -205,9 +205,7 @@ func (f *inFlow) onRead(n uint32) uint32 { if f.pendingUpdate >= f.limit/4 { wu := f.pendingUpdate f.pendingUpdate = 0 - f.mu.Unlock() return wu } - f.mu.Unlock() return 0 } diff --git a/vendor/google.golang.org/grpc/internal/transport/handler_server.go b/vendor/google.golang.org/grpc/internal/transport/handler_server.go index 7ab3422b8..a8356c9ad 100644 --- a/vendor/google.golang.org/grpc/internal/transport/handler_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/handler_server.go @@ -479,8 +479,8 @@ func (ht *serverHandlerTransport) runStream() { func (ht *serverHandlerTransport) incrMsgRecv() {} -func (ht *serverHandlerTransport) Drain(string) { - panic("Drain() is not implemented") +func (ht *serverHandlerTransport) Drain(s string) { + ht.Close(errors.New(s)) } // mapRecvMsgError returns the non-nil err into the appropriate diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index d6bc6a6cc..822c09ba6 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -39,6 +39,7 @@ import ( "google.golang.org/grpc/internal" "google.golang.org/grpc/internal/channelz" icredentials "google.golang.org/grpc/internal/credentials" + "google.golang.org/grpc/internal/envconfig" "google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/internal/grpcutil" @@ -318,7 +319,13 @@ func NewHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts } writeBufSize := opts.WriteBufferSize readBufSize := opts.ReadBufferSize + // The default header list size is moving from 16MB to 8KB. The 8KB limit + // is only used if Enable8KBDefaultHeaderListSize is true; otherwise, the + // old 16MB default is used. User-specified options always take precedence. maxHeaderListSize := defaultClientMaxHeaderListSize + if envconfig.Enable8KBDefaultHeaderListSize { + maxHeaderListSize = upcomingDefaultHeaderListSize + } if opts.MaxHeaderListSize != nil { maxHeaderListSize = *opts.MaxHeaderListSize } @@ -799,9 +806,8 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr, handler s close(s.headerChan) } } - hdr := &headerFrame{ - hf: headerFields, - endStream: false, + hdr := &clientHeaders{ + hf: headerFields, initStream: func(uint32) error { t.mu.Lock() // TODO: handle transport closure in loopy instead and remove this @@ -879,8 +885,8 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr, handler s return false } } - if sz > int64(upcomingDefaultHeaderListSize) { - t.logger.Warningf("Header list size to send (%d bytes) is larger than the upcoming default limit (%d bytes). In a future release, this will be restricted to %d bytes.", sz, upcomingDefaultHeaderListSize, upcomingDefaultHeaderListSize) + if !envconfig.Enable8KBDefaultHeaderListSize && sz > int64(upcomingDefaultHeaderListSize) { + t.logger.Warningf("Header list size to send (%d bytes) is larger than the upcoming default limit (%d bytes). In release v1.82.0, GRPC_GO_EXPERIMENTAL_ENABLE_8KB_DEFAULT_HEADER_LIST_SIZE will be enabled by default, enforcing this limit.", sz, upcomingDefaultHeaderListSize) } return true } @@ -1224,10 +1230,30 @@ func (t *http2Client) handleData(f *parsedDataFrame) { t.closeStream(s, io.EOF, true, http2.ErrCodeFlowControl, status.New(codes.Internal, err.Error()), nil, false) return } + + if s.nonGRPCStatus != nil { + // The frame should be handled as a non-gRPC response body + st := s.handleNonGRPCData(f) + if st != nil { + t.closeStream(s, st.Err(), true, http2.ErrCodeProtocol, st, nil, true) + return + } + if w := s.fc.onRead(size); w > 0 { + t.controlBuf.put(&outgoingWindowUpdate{ + streamID: s.id, + increment: w, + }) + } + return + } + dataLen := f.data.Len() if f.Header().Flags.Has(http2.FlagDataPadded) { if w := s.fc.onRead(size - uint32(dataLen)); w > 0 { - t.controlBuf.put(&outgoingWindowUpdate{s.id, w}) + t.controlBuf.put(&outgoingWindowUpdate{ + streamID: s.id, + increment: w, + }) } } if dataLen > 0 { @@ -1468,6 +1494,17 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { return } + // If we are collecting non-gRPC response data and receive a trailing + // HEADERS frame with END_STREAM, finalize the buffered data and close + // the stream. + if s.nonGRPCStatus != nil { + if endStream { + st := s.finalizeNonGRPCStatus() + t.closeStream(s, st.Err(), true, http2.ErrCodeProtocol, st, nil, true) + } + return + } + var ( // If a gRPC Response-Headers has already been received, then it means // that the peer is speaking gRPC and we are in gRPC mode. @@ -1568,7 +1605,12 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { } se := status.New(grpcErrorCode, strings.Join(errs, "; ")) - t.closeStream(s, se.Err(), true, http2.ErrCodeProtocol, se, nil, endStream) + if endStream { + t.closeStream(s, se.Err(), true, http2.ErrCodeProtocol, se, nil, true) + return + } + + s.startNonGRPCDataCollection(se) return } @@ -1839,7 +1881,7 @@ func (t *http2Client) getOutFlowWindow() int64 { resp := make(chan uint32, 1) timer := time.NewTimer(time.Second) defer timer.Stop() - t.controlBuf.put(&outFlowControlSizeRequest{resp}) + t.controlBuf.put(&outFlowControlSizeRequest{resp: resp}) select { case sz := <-resp: return int64(sz) diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index 3a8c36e4f..be8ae9f9c 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -38,11 +38,13 @@ import ( "google.golang.org/protobuf/proto" "google.golang.org/grpc/internal" + "google.golang.org/grpc/internal/envconfig" "google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/internal/grpcutil" "google.golang.org/grpc/internal/pretty" istatus "google.golang.org/grpc/internal/status" "google.golang.org/grpc/internal/syscall" + transportinternal "google.golang.org/grpc/internal/transport/internal" "google.golang.org/grpc/mem" "google.golang.org/grpc/codes" @@ -165,7 +167,13 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, } writeBufSize := config.WriteBufferSize readBufSize := config.ReadBufferSize + // The default header list size is moving from 16MB to 8KB. The 8KB limit + // is only used if Enable8KBDefaultHeaderListSize is true; otherwise, the + // old 16MB default is used. User-specified options always take precedence. maxHeaderListSize := defaultServerMaxHeaderListSize + if envconfig.Enable8KBDefaultHeaderListSize { + maxHeaderListSize = upcomingDefaultHeaderListSize + } if config.MaxHeaderListSize != nil { maxHeaderListSize = *config.MaxHeaderListSize } @@ -802,7 +810,10 @@ func (t *http2Server) handleData(f *parsedDataFrame) { dataLen := f.data.Len() if f.Header().Flags.Has(http2.FlagDataPadded) { if w := s.fc.onRead(size - uint32(dataLen)); w > 0 { - t.controlBuf.put(&outgoingWindowUpdate{s.id, w}) + t.controlBuf.put(&outgoingWindowUpdate{ + streamID: s.id, + increment: w, + }) } } if dataLen > 0 { @@ -948,8 +959,8 @@ func (t *http2Server) checkForHeaderListSize(hf []hpack.HeaderField) bool { return false } } - if sz > int64(upcomingDefaultHeaderListSize) { - t.logger.Warningf("Header list size to send (%d bytes) is larger than the upcoming default limit (%d bytes). In a future release, this will be restricted to %d bytes.", sz, upcomingDefaultHeaderListSize, upcomingDefaultHeaderListSize) + if !envconfig.Enable8KBDefaultHeaderListSize && sz > int64(upcomingDefaultHeaderListSize) { + t.logger.Warningf("Header list size to send (%d bytes) is larger than the upcoming default limit (%d bytes). In release v1.82.0, GRPC_GO_EXPERIMENTAL_ENABLE_8KB_DEFAULT_HEADER_LIST_SIZE will be enabled by default, enforcing this limit.", sz, upcomingDefaultHeaderListSize) } return true } @@ -1039,7 +1050,7 @@ func (t *http2Server) writeHeaderLocked(s *ServerStream) error { headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress}) } headerFields = appendHeaderFieldsFromMD(headerFields, s.header) - hf := &headerFrame{ + hf := &serverHeaders{ streamID: s.id, hf: headerFields, endStream: false, @@ -1107,7 +1118,7 @@ func (t *http2Server) writeStatus(s *ServerStream, st *status.Status) error { // Attach the trailer metadata. headerFields = appendHeaderFieldsFromMD(headerFields, s.trailer) - trailingHeader := &headerFrame{ + trailingHeader := &serverHeaders{ streamID: s.id, hf: headerFields, endStream: true, @@ -1317,7 +1328,7 @@ func (t *http2Server) deleteStream(s *ServerStream, eosReceived bool) { } // finishStream closes the stream and puts the trailing headerFrame into controlbuf. -func (t *http2Server) finishStream(s *ServerStream, rst bool, rstCode http2.ErrCode, hdr *headerFrame, eosReceived bool) { +func (t *http2Server) finishStream(s *ServerStream, rst bool, rstCode http2.ErrCode, hdr *serverHeaders, eosReceived bool) { // In case stream sending and receiving are invoked in separate // goroutines (e.g., bi-directional streaming), cancel needs to be // called to interrupt the potential blocking on other goroutines. @@ -1441,14 +1452,14 @@ func (t *http2Server) socketMetrics() *channelz.EphemeralSocketMetrics { func (t *http2Server) incrMsgSent() { if channelz.IsOn() { t.channelz.SocketMetrics.MessagesSent.Add(1) - t.channelz.SocketMetrics.LastMessageSentTimestamp.Add(1) + t.channelz.SocketMetrics.LastMessageSentTimestamp.Store(transportinternal.TimeNowFunc()) } } func (t *http2Server) incrMsgRecv() { if channelz.IsOn() { t.channelz.SocketMetrics.MessagesReceived.Add(1) - t.channelz.SocketMetrics.LastMessageReceivedTimestamp.Add(1) + t.channelz.SocketMetrics.LastMessageReceivedTimestamp.Store(transportinternal.TimeNowFunc()) } } @@ -1456,7 +1467,7 @@ func (t *http2Server) getOutFlowWindow() int64 { resp := make(chan uint32, 1) timer := time.NewTimer(time.Second) defer timer.Stop() - t.controlBuf.put(&outFlowControlSizeRequest{resp}) + t.controlBuf.put(&outFlowControlSizeRequest{resp: resp}) select { case sz := <-resp: return int64(sz) diff --git a/vendor/google.golang.org/grpc/internal/grpcutil/regex.go b/vendor/google.golang.org/grpc/internal/transport/internal/internal.go similarity index 59% rename from vendor/google.golang.org/grpc/internal/grpcutil/regex.go rename to vendor/google.golang.org/grpc/internal/transport/internal/internal.go index 7a092b2b8..a7c7c7d5a 100644 --- a/vendor/google.golang.org/grpc/internal/grpcutil/regex.go +++ b/vendor/google.golang.org/grpc/internal/transport/internal/internal.go @@ -1,6 +1,6 @@ /* * - * Copyright 2021 gRPC authors. + * Copyright 2026 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,16 +16,10 @@ * */ -package grpcutil +// Package internal contains functionality internal to the transport package. +package internal -import "regexp" - -// FullMatchWithRegex returns whether the full text matches the regex provided. -func FullMatchWithRegex(re *regexp.Regexp, text string) bool { - if len(text) == 0 { - return re.MatchString(text) - } - re.Longest() - rem := re.FindString(text) - return len(rem) == len(text) -} +// TimeNowFunc is a variable that can be set to override the default behavior of +// getting the current time in nanoseconds. It is used in transport code to set +// channelz timestamps, and is exposed here for testing purposes. +var TimeNowFunc func() int64 diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index 1e224576e..6dfae3984 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -35,6 +35,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/internal/channelz" + "google.golang.org/grpc/internal/transport/internal" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/mem" "google.golang.org/grpc/metadata" @@ -46,6 +47,10 @@ import ( const logLevel = 2 +func init() { + internal.TimeNowFunc = func() int64 { return time.Now().UnixNano() } +} + // recvMsg represents the received msg from the transport. All transport // protocol specific info has been removed. type recvMsg struct { diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index ee7f7dead..52f4ea513 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -128,6 +128,16 @@ func NewGZIPDecompressor() Decompressor { } func (d *gzipDecompressor) Do(r io.Reader) ([]byte, error) { + return d.doWithMaxSize(r, math.MaxInt64) +} + +// doWithMaxSize behaves like Do but caps the size of the decompressed +// payload at maxMessageSize+1 bytes. The Decompressor interface does not +// allow extra parameters, so callers inside the package type-assert to +// *gzipDecompressor to invoke this method directly. The +1 byte makes it +// possible for the caller to detect that the limit was exceeded and +// return ResourceExhausted instead of materializing an unbounded payload. +func (d *gzipDecompressor) doWithMaxSize(r io.Reader, maxMessageSize int64) ([]byte, error) { var z *gzip.Reader switch maybeZ := d.pool.Get().(type) { case nil: @@ -148,7 +158,11 @@ func (d *gzipDecompressor) Do(r io.Reader) ([]byte, error) { z.Close() d.pool.Put(z) }() - return io.ReadAll(z) + var src io.Reader = z + if maxMessageSize < math.MaxInt64 { + src = io.LimitReader(z, maxMessageSize+1) + } + return io.ReadAll(src) } func (d *gzipDecompressor) Type() string { @@ -830,15 +844,15 @@ func compress(in mem.BufferSlice, cp Compressor, compressor encoding.Compressor, if compressor != nil { z, err := compressor.Compress(w) if err != nil { - return nil, 0, wrapErr(err) + return nil, compressionNone, wrapErr(err) } for _, b := range in { if _, err := z.Write(b.ReadOnlyData()); err != nil { - return nil, 0, wrapErr(err) + return nil, compressionNone, wrapErr(err) } } if err := z.Close(); err != nil { - return nil, 0, wrapErr(err) + return nil, compressionNone, wrapErr(err) } } else { // This is obviously really inefficient since it fully materializes the data, but @@ -848,7 +862,7 @@ func compress(in mem.BufferSlice, cp Compressor, compressor encoding.Compressor, buf := in.MaterializeToBuffer(pool) defer buf.Free() if err := cp.Do(w, buf.ReadOnlyData()); err != nil { - return nil, 0, wrapErr(err) + return nil, compressionNone, wrapErr(err) } } return out, compressionMade, nil @@ -971,7 +985,20 @@ func recvAndDecompress(p *parser, s recvCompressor, dc Decompressor, maxReceiveM func decompress(compressor encoding.Compressor, d mem.BufferSlice, dc Decompressor, maxReceiveMessageSize int, pool mem.BufferPool) (mem.BufferSlice, error) { if dc != nil { r := d.Reader() - uncompressed, err := dc.Do(r) + // For the built-in gzip decompressor, bound the decompressed output + // at maxReceiveMessageSize+1 so that a small but highly compressed + // payload (a "zip bomb") cannot expand to gigabytes in memory before + // the post-decompression size check below has a chance to fire. The + // Decompressor interface does not accept an extra size parameter, + // so we type-assert to invoke a size-aware helper. Third-party + // Decompressor implementations keep the original Do behavior. + var uncompressed []byte + var err error + if gd, ok := dc.(*gzipDecompressor); ok { + uncompressed, err = gd.doWithMaxSize(r, int64(maxReceiveMessageSize)) + } else { + uncompressed, err = dc.Do(r) + } if err != nil { r.Close() // ensure buffers are reused return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err) @@ -989,6 +1016,9 @@ func decompress(compressor encoding.Compressor, d mem.BufferSlice, dc Decompress r.Close() // ensure buffers are reused return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the message: %v", err) } + if closer, ok := dcReader.(io.Closer); ok { + defer closer.Close() + } // Read at most one byte more than the limit from the decompressor. // Unless the limit is MaxInt64, in which case, that's impossible, so diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index 5229adf71..cf0a20671 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -28,6 +28,7 @@ import ( "net/http" "reflect" "runtime" + "runtime/pprof" "strings" "sync" "sync/atomic" @@ -150,8 +151,6 @@ type Server struct { serverWorkerChannel chan func() serverWorkerChannelClose func() - - strictPathCheckingLogEmitted atomic.Bool } type serverOptions struct { @@ -250,10 +249,8 @@ func newJoinServerOption(opts ...ServerOption) ServerOption { // If this option is set to true every connection will release the buffer after // flushing the data on the wire. // -// # Experimental -// -// Notice: This API is EXPERIMENTAL and may be changed or removed in a -// later release. +// Deprecated: shared write buffer is enabled by default. SharedWriteBuffer +// will be removed in a future release. func SharedWriteBuffer(val bool) ServerOption { return newFuncServerOption(func(o *serverOptions) { o.sharedWriteBuffer = val @@ -302,6 +299,14 @@ func InitialConnWindowSize(s int32) ServerOption { // window size to the value provided and disables dynamic flow control. // The lower bound for window size is 64K and any value smaller than that // will be ignored. +// +// Note that this also disables dynamic flow control for the connection, +// falling back to a default static connection-level window of 64KB. To +// use a larger connection-level window, you must also use the +// [StaticConnWindowSize] ServerOption. +// +// Most users should not configure static flow control windows unless +// operating in a memory-constrained environment. func StaticStreamWindowSize(s int32) ServerOption { return newFuncServerOption(func(o *serverOptions) { o.initialWindowSize = s @@ -313,6 +318,14 @@ func StaticStreamWindowSize(s int32) ServerOption { // window size to the value provided and disables dynamic flow control. // The lower bound for window size is 64K and any value smaller than that // will be ignored. +// +// Note that this also disables dynamic flow control for individual streams, +// falling back to a default static connection-level window of 64KB. To +// explicitly configure the stream-level window size, you must also use the +// [StaticStreamWindowSize] ServerOption. +// +// Most users should not configure static flow control windows unless +// operating in a memory-constrained environment. func StaticConnWindowSize(s int32) ServerOption { return newFuncServerOption(func(o *serverOptions) { o.initialConnWindowSize = s @@ -1787,6 +1800,12 @@ func (s *Server) handleMalformedMethodName(stream *transport.ServerStream, ti *t func (s *Server) handleStream(t transport.ServerTransport, stream *transport.ServerStream) { ctx := stream.Context() ctx = contextWithServer(ctx, s) + if envconfig.LabelServerGoroutines&envconfig.GoroutineLabelServerMethod != 0 { + // This method always runs in its own goroutine, so we can set a + // goroutine label without needing to restore a previous context. + ctx = pprof.WithLabels(ctx, pprof.Labels("grpc.method", stream.Method())) + pprof.SetGoroutineLabels(ctx) + } var ti *traceInfo if EnableTracing { tr := newTrace("grpc.Recv."+methodFamily(stream.Method()), stream.Method()) @@ -1803,28 +1822,11 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Ser } } - sm := stream.Method() - if sm == "" { + sm, found := strings.CutPrefix(stream.Method(), "/") + if !found { s.handleMalformedMethodName(stream, ti) return } - if sm[0] != '/' { - // TODO(easwars): Add a link to the CVE in the below log messages once - // published. - if envconfig.DisableStrictPathChecking { - if old := s.strictPathCheckingLogEmitted.Swap(true); !old { - channelz.Warningf(logger, s.channelz, "grpc: Server.handleStream received malformed method name %q. Allowing it because the environment variable GRPC_GO_EXPERIMENTAL_DISABLE_STRICT_PATH_CHECKING is set to true, but this option will be removed in a future release.", sm) - } - } else { - if old := s.strictPathCheckingLogEmitted.Swap(true); !old { - channelz.Warningf(logger, s.channelz, "grpc: Server.handleStream rejected malformed method name %q. To temporarily allow such requests, set the environment variable GRPC_GO_EXPERIMENTAL_DISABLE_STRICT_PATH_CHECKING to true. Note that this is not recommended as it may allow requests to bypass security policies.", sm) - } - s.handleMalformedMethodName(stream, ti) - return - } - } else { - sm = sm[1:] - } pos := strings.LastIndex(sm, "/") if pos == -1 { s.handleMalformedMethodName(stream, ti) diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 3ccfe515f..53c737fee 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.81.1" +const Version = "1.82.1" diff --git a/vendor/k8s.io/klog/v2/README.md b/vendor/k8s.io/klog/v2/README.md index d45cbe172..a680beb40 100644 --- a/vendor/k8s.io/klog/v2/README.md +++ b/vendor/k8s.io/klog/v2/README.md @@ -48,8 +48,6 @@ How to use klog - For more logging conventions (See [Logging Conventions](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md)) - See our documentation on [pkg.go.dev/k8s.io](https://pkg.go.dev/k8s.io/klog). -**NOTE**: please use the newer go versions that support semantic import versioning in modules, ideally go 1.11.4 or greater. - ### Coexisting with klog/v2 See [this example](examples/coexist_klog_v1_and_v2/) to see how to coexist with both klog/v1 and klog/v2. diff --git a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go index d1a4751c9..73f91ea50 100644 --- a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go +++ b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go @@ -20,7 +20,9 @@ import ( "bytes" "encoding/json" "fmt" + "slices" "strconv" + "strings" "github.com/go-logr/logr" ) @@ -51,139 +53,157 @@ func WithValues(oldKV, newKV []interface{}) []interface{} { return kv } -// MergeKVs deduplicates elements provided in two key/value slices. -// -// Keys in each slice are expected to be unique, so duplicates can only occur -// when the first and second slice contain the same key. When that happens, the -// key/value pair from the second slice is used. The first slice must be well-formed -// (= even key/value pairs). The second one may have a missing value, in which -// case the special "missing value" is added to the result. -func MergeKVs(first, second []interface{}) []interface{} { - maxLength := len(first) + (len(second)+1)/2*2 - if maxLength == 0 { - // Nothing to do at all. - return nil - } - - if len(first) == 0 && len(second)%2 == 0 { - // Nothing to be overridden, second slice is well-formed - // and can be used directly. - return second - } - - // Determine which keys are in the second slice so that we can skip - // them when iterating over the first one. The code intentionally - // favors performance over completeness: we assume that keys are string - // constants and thus compare equal when the string values are equal. A - // string constant being overridden by, for example, a fmt.Stringer is - // not handled. - overrides := map[interface{}]bool{} - for i := 0; i < len(second); i += 2 { - overrides[second[i]] = true - } - merged := make([]interface{}, 0, maxLength) - for i := 0; i+1 < len(first); i += 2 { - key := first[i] - if overrides[key] { - continue - } - merged = append(merged, key, first[i+1]) - } - merged = append(merged, second...) - if len(merged)%2 != 0 { - merged = append(merged, missingValue) - } - return merged -} - type Formatter struct { AnyToStringHook AnyToStringFunc } type AnyToStringFunc func(v interface{}) string -// MergeKVsInto is a variant of MergeKVs which directly formats the key/value -// pairs into a buffer. -func (f Formatter) MergeAndFormatKVs(b *bytes.Buffer, first, second []interface{}) { - if len(first) == 0 && len(second) == 0 { - // Nothing to do at all. - return - } +const missingValue = "(MISSING)" - if len(first) == 0 && len(second)%2 == 0 { - // Nothing to be overridden, second slice is well-formed - // and can be used directly. - for i := 0; i < len(second); i += 2 { - f.KVFormat(b, second[i], second[i+1]) - } - return - } +func FormatKVs(b *bytes.Buffer, kvs ...[]interface{}) { + Formatter{}.FormatKVs(b, kvs...) +} - // Determine which keys are in the second slice so that we can skip - // them when iterating over the first one. The code intentionally - // favors performance over completeness: we assume that keys are string - // constants and thus compare equal when the string values are equal. A - // string constant being overridden by, for example, a fmt.Stringer is - // not handled. - overrides := map[interface{}]bool{} - for i := 0; i < len(second); i += 2 { - overrides[second[i]] = true - } - for i := 0; i < len(first); i += 2 { - key := first[i] - if overrides[key] { - continue +// FormatKVs formats all key/value pairs such that the output contains no +// duplicates ("last one wins"). +func (f Formatter) FormatKVs(b *bytes.Buffer, kvs ...[]interface{}) { + // De-duplication is done by optimistically formatting all key value + // pairs and then cutting out the output of those key/value pairs which + // got overwritten later. + // + // In the common case of no duplicates, the only overhead is tracking + // previous keys. This uses a slice with a simple linear search because + // the number of entries is typically so low that allocating a map or + // keeping a sorted slice with binary search aren't justified. + // + // Using a fixed size here makes the Go compiler use the stack as + // initial backing store for the slice, which is crucial for + // performance. + existing := make([]obsoleteKV, 0, 32) + obsolete := make([]interval, 0, 32) // Sorted by start index. + for _, keysAndValues := range kvs { + for i := 0; i < len(keysAndValues); i += 2 { + var v interface{} + k := keysAndValues[i] + if i+1 < len(keysAndValues) { + v = keysAndValues[i+1] + } else { + v = missingValue + } + var e obsoleteKV + e.start = b.Len() + e.key = f.KVFormat(b, k, v) + e.end = b.Len() + i := findObsoleteEntry(existing, e.key) + if i >= 0 { + data := b.Bytes() + if bytes.Compare(data[existing[i].start:existing[i].end], data[e.start:e.end]) == 0 { + // The new entry gets obsoleted because it's identical. + // This has the advantage that key/value pairs from + // a WithValues call always come first, even if the same + // pair gets added again later. This makes different log + // entries more consistent. + // + // The new entry has a higher start index and thus can be appended. + obsolete = append(obsolete, e.interval) + } else { + // The old entry gets obsoleted because it's value is different. + // + // Sort order is not guaranteed, we have to insert at the right place. + index, _ := slices.BinarySearchFunc(obsolete, existing[i].interval, func(a, b interval) int { return a.start - b.start }) + obsolete = slices.Insert(obsolete, index, existing[i].interval) + existing[i].interval = e.interval + } + } else { + // Instead of appending at the end and doing a + // linear search in findEntry, we could keep + // the slice sorted by key and do a binary search. + // + // Above: + // i, ok := slices.BinarySearchFunc(existing, e, func(a, b entry) int { return strings.Compare(a.key, b.key) }) + // Here: + // existing = slices.Insert(existing, i, e) + // + // But that adds a dependency on the slices package + // and made performance slightly worse, presumably + // because the cost of shifting entries around + // did not pay of with faster lookups. + existing = append(existing, e) + } } - f.KVFormat(b, key, first[i+1]) } - // Round down. - l := len(second) - l = l / 2 * 2 - for i := 1; i < l; i += 2 { - f.KVFormat(b, second[i-1], second[i]) - } - if len(second)%2 == 1 { - f.KVFormat(b, second[len(second)-1], missingValue) - } -} -func MergeAndFormatKVs(b *bytes.Buffer, first, second []interface{}) { - Formatter{}.MergeAndFormatKVs(b, first, second) -} + // If we need to remove some obsolete key/value pairs then move the memory. + if len(obsolete) > 0 { + // Potentially the next remaining output (might itself be obsolete). + from := obsolete[0].end + // Next obsolete entry. + nextObsolete := 1 + // This is the source buffer, before truncation. + all := b.Bytes() + b.Truncate(obsolete[0].start) -const missingValue = "(MISSING)" + for nextObsolete < len(obsolete) { + if from == obsolete[nextObsolete].start { + // Skip also the next obsolete key/value. + from = obsolete[nextObsolete].end + nextObsolete++ + continue + } -// KVListFormat serializes all key/value pairs into the provided buffer. -// A space gets inserted before the first pair and between each pair. -func (f Formatter) KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) { - for i := 0; i < len(keysAndValues); i += 2 { - var v interface{} - k := keysAndValues[i] - if i+1 < len(keysAndValues) { - v = keysAndValues[i+1] - } else { - v = missingValue + // Preserve some output. Write uses copy, which + // explicitly allows source and destination to overlap. + // That could happen here. + valid := all[from:obsolete[nextObsolete].start] + b.Write(valid) + from = obsolete[nextObsolete].end + nextObsolete++ } - f.KVFormat(b, k, v) + // Copy end of buffer. + valid := all[from:] + b.Write(valid) } } -func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) { - Formatter{}.KVListFormat(b, keysAndValues...) +type obsoleteKV struct { + key string + interval +} + +// interval includes the start and excludes the end. +type interval struct { + start int + end int } -func KVFormat(b *bytes.Buffer, k, v interface{}) { - Formatter{}.KVFormat(b, k, v) +func findObsoleteEntry(entries []obsoleteKV, key string) int { + for i, entry := range entries { + if entry.key == key { + return i + } + } + return -1 } // formatAny is the fallback formatter for a value. It supports a hook (for // example, for YAML encoding) and itself uses JSON encoding. func (f Formatter) formatAny(b *bytes.Buffer, v interface{}) { - b.WriteRune('=') if f.AnyToStringHook != nil { - b.WriteString(f.AnyToStringHook(v)) + str := f.AnyToStringHook(v) + if strings.Contains(str, "\n") { + // If it's multi-line, then pass it through writeStringValue to get start/end delimiters, + // which separates it better from any following key/value pair. + writeStringValue(b, str) + return + } + // Otherwise put it directly after the separator, on the same lime, + // The assumption is that the hook returns something where start/end are obvious. + b.WriteRune('=') + b.WriteString(str) return } + b.WriteRune('=') formatAsJSON(b, v) } diff --git a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues_no_slog.go b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues_no_slog.go index d9c7d1546..b8c7e443d 100644 --- a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues_no_slog.go +++ b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues_no_slog.go @@ -28,7 +28,7 @@ import ( // KVFormat serializes one key/value pair into the provided buffer. // A space gets inserted before the pair. -func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) { +func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) string { // This is the version without slog support. Must be kept in sync with // the version in keyvalues_slog.go. @@ -37,13 +37,15 @@ func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) { // https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments // for the sake of performance. Keys with spaces, // special characters, etc. will break parsing. + var key string if sK, ok := k.(string); ok { // Avoid one allocation when the key is a string, which // normally it should be. - b.WriteString(sK) + key = sK } else { - b.WriteString(fmt.Sprintf("%s", k)) + key = fmt.Sprintf("%s", k) } + b.WriteString(key) // The type checks are sorted so that more frequently used ones // come first because that is then faster in the common @@ -94,4 +96,6 @@ func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) { default: f.formatAny(b, v) } + + return key } diff --git a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues_slog.go b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues_slog.go index 89acf9772..8e0084364 100644 --- a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues_slog.go +++ b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues_slog.go @@ -29,8 +29,8 @@ import ( ) // KVFormat serializes one key/value pair into the provided buffer. -// A space gets inserted before the pair. -func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) { +// A space gets inserted before the pair. It returns the key. +func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) string { // This is the version without slog support. Must be kept in sync with // the version in keyvalues_slog.go. @@ -39,13 +39,15 @@ func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) { // https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments // for the sake of performance. Keys with spaces, // special characters, etc. will break parsing. + var key string if sK, ok := k.(string); ok { // Avoid one allocation when the key is a string, which // normally it should be. - b.WriteString(sK) + key = sK } else { - b.WriteString(fmt.Sprintf("%s", k)) + key = fmt.Sprintf("%s", k) } + b.WriteString(key) // The type checks are sorted so that more frequently used ones // come first because that is then faster in the common @@ -112,6 +114,8 @@ func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) { default: f.formatAny(b, v) } + + return key } // generateJSON has the same preference for plain strings as KVFormat. diff --git a/vendor/k8s.io/klog/v2/klog.go b/vendor/k8s.io/klog/v2/klog.go index 47ec9466a..319ffbe24 100644 --- a/vendor/k8s.io/klog/v2/klog.go +++ b/vendor/k8s.io/klog/v2/klog.go @@ -58,15 +58,30 @@ // // -logtostderr=true // Logs are written to standard error instead of to files. -// This shortcuts most of the usual output routing: -// -alsologtostderr, -stderrthreshold and -log_dir have no -// effect and output redirection at runtime with SetOutput is -// ignored. +// By default, all logs are written regardless of severity +// (legacy behavior). To filter logs by severity when +// -logtostderr=true, set -legacy_stderr_threshold_behavior=false +// and use -stderrthreshold. +// With -legacy_stderr_threshold_behavior=true, +// -stderrthreshold has no effect. +// +// The following flags always have no effect: +// -alsologtostderr, -alsologtostderrthreshold, and -log_dir. +// Output redirection at runtime with SetOutput is also ignored. // -alsologtostderr=false // Logs are written to standard error as well as to files. +// -alsologtostderrthreshold=INFO +// Log events at or above this severity are logged to standard +// error when -alsologtostderr=true (no effect when -logtostderr=true). +// Default is INFO to maintain backward compatibility. // -stderrthreshold=ERROR // Log events at or above this severity are logged to standard -// error as well as to files. +// error as well as to files. When -logtostderr=true, this flag +// has no effect unless -legacy_stderr_threshold_behavior=false. +// -legacy_stderr_threshold_behavior=true +// If true, -stderrthreshold is ignored when -logtostderr=true +// (legacy behavior). If false, -stderrthreshold is honored even +// when -logtostderr=true, allowing severity-based filtering. // -log_dir="" // Log files will be written to this directory instead of the // default temporary directory. @@ -156,7 +171,7 @@ func (s *severityValue) Set(value string) error { } threshold = severity.Severity(v) } - logging.stderrThreshold.set(threshold) + s.set(threshold) return nil } @@ -409,6 +424,15 @@ var commandLine flag.FlagSet // init sets up the defaults and creates command line flags. func init() { + // Initialize severity thresholds + logging.stderrThreshold = severityValue{ + Severity: severity.ErrorLog, // Default stderrThreshold is ERROR. + } + logging.alsologtostderrthreshold = severityValue{ + Severity: severity.InfoLog, // Default alsologtostderrthreshold is INFO (to maintain backward compatibility). + } + logging.setVState(0, nil, false) + commandLine.StringVar(&logging.logDir, "log_dir", "", "If non-empty, write log files in this directory (no effect when -logtostderr=true)") commandLine.StringVar(&logging.logFile, "log_file", "", "If non-empty, use this log file (no effect when -logtostderr=true)") commandLine.Uint64Var(&logging.logFileMaxSizeMB, "log_file_max_size", 1800, @@ -416,16 +440,14 @@ func init() { "If the value is 0, the maximum file size is unlimited.") commandLine.BoolVar(&logging.toStderr, "logtostderr", true, "log to standard error instead of files") commandLine.BoolVar(&logging.alsoToStderr, "alsologtostderr", false, "log to standard error as well as files (no effect when -logtostderr=true)") - logging.setVState(0, nil, false) + commandLine.BoolVar(&logging.legacyStderrThresholdBehavior, "legacy_stderr_threshold_behavior", true, "If true, stderrthreshold is ignored when logtostderr=true (legacy behavior). If false, stderrthreshold is honored even when logtostderr=true") commandLine.Var(&logging.verbosity, "v", "number for the log level verbosity") commandLine.BoolVar(&logging.addDirHeader, "add_dir_header", false, "If true, adds the file directory to the header of the log messages") commandLine.BoolVar(&logging.skipHeaders, "skip_headers", false, "If true, avoid header prefixes in the log messages") commandLine.BoolVar(&logging.oneOutput, "one_output", false, "If true, only write logs to their native severity level (vs also writing to each lower severity level; no effect when -logtostderr=true)") commandLine.BoolVar(&logging.skipLogHeaders, "skip_log_headers", false, "If true, avoid headers when opening log files (no effect when -logtostderr=true)") - logging.stderrThreshold = severityValue{ - Severity: severity.ErrorLog, // Default stderrThreshold is ERROR. - } - commandLine.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr when writing to files and stderr (no effect when -logtostderr=true or -alsologtostderr=true)") + commandLine.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr when writing to files and stderr (no effect when -logtostderr=true or -alsologtostderr=true unless -legacy_stderr_threshold_behavior=false)") + commandLine.Var(&logging.alsologtostderrthreshold, "alsologtostderrthreshold", "logs at or above this threshold go to stderr when -alsologtostderr=true (no effect when -logtostderr=true)") commandLine.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging") commandLine.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace") @@ -470,11 +492,13 @@ type settings struct { // Boolean flags. Not handled atomically because the flag.Value interface // does not let us avoid the =true, and that shorthand is necessary for // compatibility. TODO: does this matter enough to fix? Seems unlikely. - toStderr bool // The -logtostderr flag. - alsoToStderr bool // The -alsologtostderr flag. + toStderr bool // The -logtostderr flag. + alsoToStderr bool // The -alsologtostderr flag. + legacyStderrThresholdBehavior bool // The -legacy_stderr_threshold_behavior flag. // Level flag. Handled atomically. - stderrThreshold severityValue // The -stderrthreshold flag. + stderrThreshold severityValue // The -stderrthreshold flag. + alsologtostderrthreshold severityValue // The -alsologtostderrthreshold flag. // Access to all of the following fields must be protected via a mutex. @@ -809,16 +833,21 @@ func (l *loggingT) infoS(logger *logWriter, filter LogFilter, depth int, msg str // printS is called from infoS and errorS if logger is not specified. // set log severity by s func (l *loggingT) printS(err error, s severity.Severity, depth int, msg string, keysAndValues ...interface{}) { - // Only create a new buffer if we don't have one cached. - b := buffer.GetBuffer() // The message is always quoted, even if it contains line breaks. // If developers want multi-line output, they should use a small, fixed // message and put the multi-line output into a value. - b.WriteString(strconv.Quote(msg)) + qMsg := make([]byte, 0, 1024) + qMsg = strconv.AppendQuote(qMsg, msg) + + // Only create a new buffer if we don't have one cached. + b := buffer.GetBuffer() + b.Write(qMsg) + + var errKV []interface{} if err != nil { - serialize.KVListFormat(&b.Buffer, "err", err) + errKV = []interface{}{"err", err} } - serialize.KVListFormat(&b.Buffer, keysAndValues...) + serialize.FormatKVs(&b.Buffer, errKV, keysAndValues) l.printDepth(s, nil, nil, depth+1, &b.Buffer) // Make the buffer available for reuse. buffer.PutBuffer(b) @@ -885,9 +914,25 @@ func (l *loggingT) output(s severity.Severity, logger *logWriter, buf *buffer.Bu } } } else if l.toStderr { - os.Stderr.Write(data) + // When logging to stderr only, check if we should filter by severity. + // This is controlled by the legacy_stderr_threshold_behavior flag. + if l.legacyStderrThresholdBehavior { + // Legacy behavior: always write to stderr, ignore stderrthreshold + os.Stderr.Write(data) + } else { + // New behavior: honor stderrthreshold even when logtostderr=true + if s >= l.stderrThreshold.get() { + os.Stderr.Write(data) + } + } } else { - if alsoToStderr || l.alsoToStderr || s >= l.stderrThreshold.get() { + // Write to stderr if any of these conditions are met: + // - alsoToStderr is set (legacy behavior) + // - alsologtostderr is set and severity meets alsologtostderrthreshold + // - alsologtostderr is not set and severity meets stderrThreshold + if alsoToStderr || + (l.alsoToStderr && s >= l.alsologtostderrthreshold.get()) || + (!l.alsoToStderr && s >= l.stderrThreshold.get()) { os.Stderr.Write(data) } diff --git a/vendor/k8s.io/klog/v2/klogr.go b/vendor/k8s.io/klog/v2/klogr.go index efec96fd4..6204c7bb4 100644 --- a/vendor/k8s.io/klog/v2/klogr.go +++ b/vendor/k8s.io/klog/v2/klogr.go @@ -53,7 +53,7 @@ func (l *klogger) Init(info logr.RuntimeInfo) { } func (l *klogger) Info(level int, msg string, kvList ...interface{}) { - merged := serialize.MergeKVs(l.values, kvList) + merged := serialize.WithValues(l.values, kvList) // Skip this function. VDepth(l.callDepth+1, Level(level)).InfoSDepth(l.callDepth+1, msg, merged...) } @@ -63,7 +63,7 @@ func (l *klogger) Enabled(level int) bool { } func (l *klogger) Error(err error, msg string, kvList ...interface{}) { - merged := serialize.MergeKVs(l.values, kvList) + merged := serialize.WithValues(l.values, kvList) ErrorSDepth(l.callDepth+1, err, msg, merged...) } diff --git a/vendor/k8s.io/klog/v2/klogr_slog.go b/vendor/k8s.io/klog/v2/klogr_slog.go index c77d7baaf..901e28dd3 100644 --- a/vendor/k8s.io/klog/v2/klogr_slog.go +++ b/vendor/k8s.io/klog/v2/klogr_slog.go @@ -63,12 +63,17 @@ func slogOutput(file string, line int, now time.Time, err error, s severity.Seve } // See printS. + qMsg := make([]byte, 0, 1024) + qMsg = strconv.AppendQuote(qMsg, msg) + b := buffer.GetBuffer() - b.WriteString(strconv.Quote(msg)) + b.Write(qMsg) + + var errKV []interface{} if err != nil { - serialize.KVListFormat(&b.Buffer, "err", err) + errKV = []interface{}{"err", err} } - serialize.KVListFormat(&b.Buffer, kvList...) + serialize.FormatKVs(&b.Buffer, errKV, kvList) // See print + header. buf := logging.formatHeader(s, file, line, now) diff --git a/vendor/modules.txt b/vendor/modules.txt index b5866b6d4..65f2911d4 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -85,7 +85,7 @@ github.com/containerd/platforms ## explicit; go 1.24.0 github.com/containerd/stargz-snapshotter/estargz github.com/containerd/stargz-snapshotter/estargz/errorutil -# github.com/containers/buildah v1.42.1 +# github.com/containers/buildah v1.43.2 ## explicit; go 1.24.2 github.com/containers/buildah/define # github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 @@ -467,7 +467,7 @@ github.com/google/go-containerregistry/pkg/v1/types # github.com/google/go-intervals v0.0.2 ## explicit; go 1.12 github.com/google/go-intervals/intervalset -# github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 +# github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 ## explicit; go 1.24.0 github.com/google/pprof/profile # github.com/google/uuid v1.6.0 @@ -585,9 +585,9 @@ github.com/mattn/go-sqlite3 # github.com/miekg/pkcs11 v1.1.1 ## explicit; go 1.12 github.com/miekg/pkcs11 -# github.com/mistifyio/go-zfs/v4 v4.0.0 +# github.com/mistifyio/go-zfs/v3 v3.1.0 ## explicit; go 1.14 -github.com/mistifyio/go-zfs/v4 +github.com/mistifyio/go-zfs/v3 # github.com/mitchellh/go-homedir v1.1.0 ## explicit github.com/mitchellh/go-homedir @@ -761,8 +761,8 @@ github.com/redhat-et/GKM/mcv/pkg/utils ## explicit github.com/sassoftware/relic/lib/pkcs7 github.com/sassoftware/relic/lib/x509tools -# github.com/secure-systems-lab/go-securesystemslib v0.10.0 -## explicit; go 1.24.0 +# github.com/secure-systems-lab/go-securesystemslib v0.11.0 +## explicit; go 1.25.0 github.com/secure-systems-lab/go-securesystemslib/cjson github.com/secure-systems-lab/go-securesystemslib/dsse github.com/secure-systems-lab/go-securesystemslib/encrypted @@ -800,7 +800,7 @@ github.com/sigstore/protobuf-specs/gen/pb-go/common/v1 github.com/sigstore/protobuf-specs/gen/pb-go/dsse github.com/sigstore/protobuf-specs/gen/pb-go/rekor/v1 github.com/sigstore/protobuf-specs/gen/pb-go/trustroot/v1 -# github.com/sigstore/rekor v1.5.0 +# github.com/sigstore/rekor v1.5.2 ## explicit; go 1.25.0 github.com/sigstore/rekor/pkg/client github.com/sigstore/rekor/pkg/generated/client @@ -1030,7 +1030,7 @@ go.opentelemetry.io/proto/otlp/collector/trace/v1 go.opentelemetry.io/proto/otlp/common/v1 go.opentelemetry.io/proto/otlp/resource/v1 go.opentelemetry.io/proto/otlp/trace/v1 -# go.podman.io/common v0.66.1-0.20251111134650-36964d15757a +# go.podman.io/common v0.67.1 ## explicit; go 1.24.2 go.podman.io/common/internal go.podman.io/common/internal/attributedstring @@ -1062,7 +1062,7 @@ go.podman.io/common/pkg/supplemented go.podman.io/common/pkg/systemd go.podman.io/common/pkg/timetype go.podman.io/common/version -# go.podman.io/image/v5 v5.38.1-0.20251111134650-36964d15757a +# go.podman.io/image/v5 v5.39.2 ## explicit; go 1.24.0 go.podman.io/image/v5/copy go.podman.io/image/v5/directory @@ -1129,7 +1129,7 @@ go.podman.io/image/v5/transports go.podman.io/image/v5/transports/alltransports go.podman.io/image/v5/types go.podman.io/image/v5/version -# go.podman.io/storage v1.61.1-0.20251111134650-36964d15757a +# go.podman.io/storage v1.62.0 ## explicit; go 1.24.0 go.podman.io/storage go.podman.io/storage/drivers @@ -1337,7 +1337,7 @@ google.golang.org/genproto/googleapis/api/httpbody ## explicit; go 1.25.0 google.golang.org/genproto/googleapis/rpc/errdetails google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.81.1 +# google.golang.org/grpc v1.82.1 ## explicit; go 1.25.0 google.golang.org/grpc google.golang.org/grpc/attributes @@ -1359,6 +1359,7 @@ google.golang.org/grpc/encoding google.golang.org/grpc/encoding/gzip google.golang.org/grpc/encoding/internal google.golang.org/grpc/encoding/proto +google.golang.org/grpc/experimental/balancer/weight google.golang.org/grpc/experimental/stats google.golang.org/grpc/grpclog google.golang.org/grpc/grpclog/internal @@ -1366,7 +1367,6 @@ google.golang.org/grpc/health/grpc_health_v1 google.golang.org/grpc/internal google.golang.org/grpc/internal/backoff google.golang.org/grpc/internal/balancer/gracefulswitch -google.golang.org/grpc/internal/balancer/weight google.golang.org/grpc/internal/balancerload google.golang.org/grpc/internal/binarylog google.golang.org/grpc/internal/buffer @@ -1392,6 +1392,7 @@ google.golang.org/grpc/internal/stats google.golang.org/grpc/internal/status google.golang.org/grpc/internal/syscall google.golang.org/grpc/internal/transport +google.golang.org/grpc/internal/transport/internal google.golang.org/grpc/internal/transport/networktype google.golang.org/grpc/internal/transport/readyreader google.golang.org/grpc/keepalive @@ -1944,8 +1945,8 @@ k8s.io/component-base/tracing k8s.io/component-base/tracing/api/v1 k8s.io/component-base/version k8s.io/component-base/zpages/features -# k8s.io/klog/v2 v2.130.1 -## explicit; go 1.18 +# k8s.io/klog/v2 v2.140.0 +## explicit; go 1.21 k8s.io/klog/v2 k8s.io/klog/v2/internal/buffer k8s.io/klog/v2/internal/clock