From 54c06f3ae8f96c4c84d6facd48fdb5d92acb8d28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jan 2022 01:26:26 +0000 Subject: [PATCH] Bump github.com/google/go-containerregistry from 0.7.0 to 0.8.0 Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.7.0 to 0.8.0. - [Release notes](https://github.com/google/go-containerregistry/releases) - [Changelog](https://github.com/google/go-containerregistry/blob/main/.goreleaser.yml) - [Commits](https://github.com/google/go-containerregistry/compare/v0.7.0...v0.8.0) --- updated-dependencies: - dependency-name: github.com/google/go-containerregistry dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 6 +- go.sum | 41 ++- .../cmd/crane/cmd/append.go | 9 +- .../cmd/crane/cmd/export.go | 7 +- .../cmd/crane/cmd/mutate.go | 118 ++++--- .../cmd/crane/cmd/pull.go | 47 ++- .../cmd/crane/cmd/push.go | 99 +++++- .../cmd/crane/cmd/root.go | 12 +- .../cmd/crane/cmd/util.go | 8 +- .../go-containerregistry/internal/gzip/zip.go | 29 ++ .../internal/verify/verify.go | 25 +- .../internal/windows/windows.go | 115 +++++++ .../go-containerregistry/pkg/authn/README.md | 100 +++++- .../pkg/authn/keychain.go | 76 ++++- .../go-containerregistry/pkg/crane/append.go | 28 ++ .../go-containerregistry/pkg/crane/export.go | 20 +- .../go-containerregistry/pkg/crane/pull.go | 7 +- .../go-containerregistry/pkg/name/check.go | 4 +- .../pkg/registry/blobs.go | 289 +++++++++++++++--- .../pkg/registry/error.go | 33 ++ .../pkg/registry/registry.go | 4 +- .../pkg/v1/mutate/mutate.go | 5 +- .../pkg/v1/partial/compressed.go | 22 +- .../pkg/v1/random/image.go | 2 +- .../pkg/v1/remote/transport/error.go | 5 + .../pkg/v1/remote/transport/transport.go | 4 +- .../pkg/v1/tarball/image.go | 2 +- .../pkg/v1/zz_deepcopy_generated.go | 1 - .../github.com/mitchellh/go-homedir/LICENSE | 21 ++ .../github.com/mitchellh/go-homedir/README.md | 14 + vendor/github.com/mitchellh/go-homedir/go.mod | 1 + .../mitchellh/go-homedir/homedir.go | 167 ++++++++++ .../image-spec/specs-go/v1/index.go | 3 + .../image-spec/specs-go/v1/manifest.go | 3 + .../image-spec/specs-go/version.go | 2 +- vendor/golang.org/x/sys/unix/mkerrors.sh | 2 + vendor/golang.org/x/sys/unix/zerrors_linux.go | 7 + vendor/golang.org/x/sys/unix/ztypes_linux.go | 75 +++++ .../golang.org/x/sys/windows/exec_windows.go | 37 +-- .../golang.org/x/sys/windows/types_windows.go | 41 ++- .../x/tools/go/gcexportdata/gcexportdata.go | 23 +- .../x/tools/go/internal/gcimporter/bexport.go | 3 - .../x/tools/go/internal/gcimporter/bimport.go | 51 ++-- .../go/internal/gcimporter/exportdata.go | 16 +- .../go/internal/gcimporter/gcimporter.go | 12 +- .../x/tools/go/internal/gcimporter/iexport.go | 122 ++++++-- .../x/tools/go/internal/gcimporter/iimport.go | 163 ++++++---- .../go/internal/gcimporter/support_go118.go | 3 + .../x/tools/internal/typeparams/common.go | 7 + .../x/tools/internal/typeparams/normalize.go | 129 +++++--- .../internal/typeparams/typeparams_go117.go | 29 +- .../internal/typeparams/typeparams_go118.go | 5 + vendor/modules.txt | 17 +- 53 files changed, 1702 insertions(+), 369 deletions(-) create mode 100644 vendor/github.com/google/go-containerregistry/internal/windows/windows.go create mode 100644 vendor/github.com/mitchellh/go-homedir/LICENSE create mode 100644 vendor/github.com/mitchellh/go-homedir/README.md create mode 100644 vendor/github.com/mitchellh/go-homedir/go.mod create mode 100644 vendor/github.com/mitchellh/go-homedir/homedir.go diff --git a/go.mod b/go.mod index f585c6f29c..d69aaaf88b 100644 --- a/go.mod +++ b/go.mod @@ -9,15 +9,15 @@ require ( github.com/fsnotify/fsnotify v1.5.1 github.com/go-training/helloworld v0.0.0-20200225145412-ba5f4379d78b github.com/google/go-cmp v0.5.6 - github.com/google/go-containerregistry v0.7.0 + github.com/google/go-containerregistry v0.8.0 github.com/mattmoor/dep-notify v0.0.0-20190205035814-a45dec370a17 - github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7 + github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5 github.com/sigstore/cosign v1.3.2-0.20211120003522-90e2dcfe7b92 github.com/spf13/cobra v1.3.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.10.1 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/tools v0.1.8-0.20211015140901-98f6e0395b11 + golang.org/x/tools v0.1.8 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b k8s.io/apimachinery v0.23.1 sigs.k8s.io/kind v0.11.1 diff --git a/go.sum b/go.sum index 8d00fa1494..277124fea1 100644 --- a/go.sum +++ b/go.sum @@ -35,6 +35,7 @@ cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+Y cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.96.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= @@ -171,6 +172,7 @@ github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2 github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= +github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -286,6 +288,7 @@ github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oD github.com/cavaliercoder/go-rpm v0.0.0-20200122174316-8cb9fd9c31a8/go.mod h1:AZIh1CCnMrcVm6afFf96PBvE2MRpWFco91z8ObJtgDY= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -354,14 +357,16 @@ github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMX github.com/containerd/containerd v1.4.0-beta.2.0.20200729163537-40b22ef07410/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ= github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU= github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= github.com/containerd/containerd v1.5.2/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= -github.com/containerd/containerd v1.5.7 h1:rQyoYtj4KddB3bxG6SAqd4+08gePNyJjRqvOIfV3rkM= github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= +github.com/containerd/containerd v1.5.8 h1:NmkCC1/QxyZFBny8JogwLpOy2f+VEbO/f6bV2Mqtwuw= +github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -400,6 +405,7 @@ github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDG github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= +github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk= github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= @@ -478,8 +484,9 @@ github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/ github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v20.10.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v20.10.10+incompatible h1:kcbwdgWbrBOH8QwQzaJmyriHwF7XIl4HT1qh0HTRys4= github.com/docker/cli v20.10.10+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v20.10.12+incompatible h1:lZlz0uzG+GH+c0plStMUdF/qk3ppmgnswpR5EbqzVGA= +github.com/docker/cli v20.10.12+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= @@ -837,8 +844,9 @@ github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-containerregistry v0.5.2-0.20210609162550-f0ce2270b3b4/go.mod h1:R5WRYyTdQqTchlBhX4q+WICGh8HQIL5wDFoFZv7Jq6Q= -github.com/google/go-containerregistry v0.7.0 h1:u0onUUOcyoCDHEiJoyR1R1gx5er1+r06V5DBhUU5ndk= github.com/google/go-containerregistry v0.7.0/go.mod h1:2zaoelrL0d08gGbpdP3LqyUuBmhWbpD6IOe2s9nLS2k= +github.com/google/go-containerregistry v0.8.0 h1:mtR24eN6rapCN+shds82qFEIWWmg64NPMuyCNT7/Ogc= +github.com/google/go-containerregistry v0.8.0/go.mod h1:wW5v71NHGnQyb4k+gSshjxidrC7lN33MdWEn+Mz9TsI= github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20211102215614-dd49079bb93d/go.mod h1:j3IqhBG3Ox1NXmmhbWU4UmiHVAf2dUgB7le1Ch7JZQ0= github.com/google/go-github/v27 v27.0.6/go.mod h1:/0Gr8pJ55COkmv+S/yPKCczSkUPIM/LnFyubufRNIS0= github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= @@ -929,6 +937,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4G github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= @@ -988,10 +997,13 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/vault/api v1.0.5-0.20200519221902-385fac77e20f/go.mod h1:euTFbi2YJgwcju3imEt919lhJKF68nN1cQPq3aA+kBE= github.com/hashicorp/vault/api v1.1.0/go.mod h1:R3Umvhlxi2TN7Ex2hzOowyeNb+SfbVWI973N+ctaFMk= @@ -1169,6 +1181,7 @@ github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceT github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +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/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= @@ -1267,8 +1280,9 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7 h1:axgApq2XShTLwQii2zAnIkMPlhGVHbAXHUcHezu5G/k= github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5 h1:q37d91F6BO4Jp1UqWiun0dUFYaqv6WsKTLTCaWv+8LY= +github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= @@ -1411,6 +1425,7 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= @@ -1490,6 +1505,7 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= +github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk= github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU= github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= @@ -1597,6 +1613,7 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= @@ -1855,9 +1872,11 @@ golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211111160137-58aab5ef257a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM= +golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2029,11 +2048,14 @@ golang.org/x/sys v0.0.0-20210909193231-528a39cd75f3/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486 h1:5hpz5aRr+W1erYCL5JRhSUBJRph7l9XkNveoExlrKYk= +golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2151,8 +2173,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.1.8-0.20211015140901-98f6e0395b11 h1:tH6DicuZbyfFY5UhxRxZP2ksWtFE8XLpoJX+YFzBIUI= -golang.org/x/tools v0.1.8-0.20211015140901-98f6e0395b11/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w= +golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2206,6 +2228,7 @@ google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3l google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= google.golang.org/api v0.60.0/go.mod h1:d7rl65NZAkEQ90JFzqBjcRq1TVeG5ZoGV3sSpEnnVb4= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2305,6 +2328,8 @@ google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211111162719-482062a4217b/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= diff --git a/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/append.go b/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/append.go index 837749067e..4d4dda7f1d 100644 --- a/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/append.go +++ b/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/append.go @@ -36,7 +36,14 @@ func NewCmdAppend(options *[]crane.Option) *cobra.Command { appendCmd := &cobra.Command{ Use: "append", Short: "Append contents of a tarball to a remote image", - Args: cobra.NoArgs, + Long: `This sub-command pushes an image based on an (optional) +base image, with appended layers containing the contents of the +provided tarballs. + +If the base image is a Windows base image (i.e., its config.OS is "windows"), +the contents of the tarballs will be modified to be suitable for a Windows +container image.`, + Args: cobra.NoArgs, RunE: func(_ *cobra.Command, args []string) error { var base v1.Image var err error diff --git a/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/export.go b/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/export.go index d1f9ac48e4..b6e6b25728 100644 --- a/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/export.go +++ b/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/export.go @@ -32,9 +32,12 @@ func NewCmdExport(options *[]crane.Option) *cobra.Command { # Write tarball to file crane export ubuntu ubuntu.tar`, - Args: cobra.ExactArgs(2), + Args: cobra.RangeArgs(1, 2), RunE: func(_ *cobra.Command, args []string) error { - src, dst := args[0], args[1] + src, dst := args[0], "-" + if len(args) > 1 { + dst = args[1] + } f, err := openFile(dst) if err != nil { diff --git a/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/mutate.go b/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/mutate.go index 72789c2b6d..fbf8f3b305 100644 --- a/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/mutate.go +++ b/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/mutate.go @@ -15,8 +15,8 @@ package cmd import ( + "errors" "fmt" - "log" "strings" "github.com/google/go-containerregistry/pkg/crane" @@ -28,36 +28,45 @@ import ( // NewCmdMutate creates a new cobra.Command for the mutate subcommand. func NewCmdMutate(options *[]crane.Option) *cobra.Command { - var lbls []string - var entrypoint string + var labels map[string]string + var annotations map[string]string + var entrypoint, cmd []string + var envVars map[string]string + var newLayers []string + var newRef string - var anntns []string mutateCmd := &cobra.Command{ Use: "mutate", - Short: "Modify image labels and annotations", + Short: "Modify image labels and annotations. The container must be pushed to a registry, and the manifest is updated there.", Args: cobra.ExactArgs(1), - Run: func(_ *cobra.Command, args []string) { + RunE: func(_ *cobra.Command, args []string) error { // Pull image and get config. ref := args[0] - if len(anntns) != 0 { + if len(annotations) != 0 { desc, err := crane.Head(ref, *options...) if err != nil { - log.Fatalf("checking %s: %v", ref, err) + return err } if desc.MediaType.IsIndex() { - log.Fatalf("mutating annotations on an index is not yet supported") + return errors.New("mutating annotations on an index is not yet supported") } } img, err := crane.Pull(ref, *options...) if err != nil { - log.Fatalf("pulling %s: %v", ref, err) + return fmt.Errorf("pulling %s: %w", ref, err) + } + if len(newLayers) != 0 { + img, err = crane.Append(img, newLayers...) + if err != nil { + return fmt.Errorf("appending %v: %w", newLayers, err) + } } cfg, err := img.ConfigFile() if err != nil { - log.Fatalf("getting config: %v", err) + return err } cfg = cfg.DeepCopy() @@ -66,30 +75,38 @@ func NewCmdMutate(options *[]crane.Option) *cobra.Command { cfg.Config.Labels = map[string]string{} } - labels, err := splitKeyVals(lbls) - if err != nil { - log.Fatal(err) + if err := validateKeyVals(labels); err != nil { + return err } for k, v := range labels { cfg.Config.Labels[k] = v } - annotations, err := splitKeyVals(anntns) - if err != nil { - log.Fatal(err) + if err := validateKeyVals(annotations); err != nil { + return err + } + + // set envvars if specified + if err := setEnvVars(cfg, envVars); err != nil { + return err } // Set entrypoint. - if entrypoint != "" { - // NB: This doesn't attempt to do anything smart about splitting the string into multiple entrypoint elements. - cfg.Config.Entrypoint = []string{entrypoint} + if len(entrypoint) > 0 { + cfg.Config.Entrypoint = entrypoint + cfg.Config.Cmd = nil // This matches Docker's behavior. + } + + // Set cmd. + if len(cmd) > 0 { + cfg.Config.Cmd = cmd } // Mutate and write image. img, err = mutate.Config(img, cfg.Config) if err != nil { - log.Fatalf("mutating config: %v", err) + return fmt.Errorf("mutating config: %w", err) } img = mutate.Annotations(img, annotations).(v1.Image) @@ -103,37 +120,66 @@ func NewCmdMutate(options *[]crane.Option) *cobra.Command { } digest, err := img.Digest() if err != nil { - log.Fatalf("digesting new image: %v", err) + return fmt.Errorf("digesting new image: %w", err) } r, err := name.ParseReference(newRef) if err != nil { - log.Fatalf("parsing %s: %v", newRef, err) + return fmt.Errorf("parsing %s: %w", newRef, err) } if _, ok := r.(name.Digest); ok { newRef = r.Context().Digest(digest.String()).String() } if err := crane.Push(img, newRef, *options...); err != nil { - log.Fatalf("pushing %s: %v", newRef, err) + return fmt.Errorf("pushing %s: %w", newRef, err) } fmt.Println(r.Context().Digest(digest.String())) + return nil }, } - mutateCmd.Flags().StringSliceVarP(&anntns, "annotation", "a", nil, "New annotations to add") - mutateCmd.Flags().StringSliceVarP(&lbls, "label", "l", nil, "New labels to add") - mutateCmd.Flags().StringVar(&entrypoint, "entrypoint", "", "New entrypoing to set") + mutateCmd.Flags().StringToStringVarP(&annotations, "annotation", "a", nil, "New annotations to add") + mutateCmd.Flags().StringToStringVarP(&labels, "label", "l", nil, "New labels to add") + mutateCmd.Flags().StringToStringVarP(&envVars, "env", "e", nil, "New envvar to add") + mutateCmd.Flags().StringSliceVar(&entrypoint, "entrypoint", nil, "New entrypoint to set") + mutateCmd.Flags().StringSliceVar(&cmd, "cmd", nil, "New cmd to set") mutateCmd.Flags().StringVarP(&newRef, "tag", "t", "", "New tag to apply to mutated image. If not provided, push by digest to the original image repository.") + mutateCmd.Flags().StringSliceVar(&newLayers, "append", []string{}, "Path to tarball to append to image") return mutateCmd } -// splitKeyVals splits key value pairs which is in form hello=world -func splitKeyVals(kvPairs []string) (map[string]string, error) { - m := map[string]string{} - for _, l := range kvPairs { - parts := strings.SplitN(l, "=", 2) - if len(parts) == 1 { - return nil, fmt.Errorf("parsing label %q, not enough parts", l) +// validateKeyVals ensures no values are empty, returns error if they are +func validateKeyVals(kvPairs map[string]string) error { + for label, value := range kvPairs { + if value == "" { + return fmt.Errorf("parsing label %q, value is empty", label) + } + } + return nil +} + +// setEnvVars override envvars in a config +func setEnvVars(cfg *v1.ConfigFile, envVars map[string]string) error { + newEnv := make([]string, 0, len(cfg.Config.Env)) + for _, old := range cfg.Config.Env { + split := strings.SplitN(old, "=", 2) + if len(split) != 2 { + return fmt.Errorf("invalid key value pair in config: %s", old) + } + // keep order so override if specified again + oldKey := split[0] + if v, ok := envVars[oldKey]; ok { + newEnv = append(newEnv, fmt.Sprintf("%s=%s", oldKey, v)) + delete(envVars, oldKey) + } else { + newEnv = append(newEnv, old) + } + } + isWindows := cfg.OS == "windows" + for k, v := range envVars { + if isWindows { + k = strings.ToUpper(k) } - m[parts[0]] = parts[1] + newEnv = append(newEnv, fmt.Sprintf("%s=%s", k, v)) } - return m, nil + cfg.Config.Env = newEnv + return nil } diff --git a/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/pull.go b/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/pull.go index f45e77c592..8bb242cf85 100644 --- a/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/pull.go +++ b/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/pull.go @@ -18,8 +18,11 @@ import ( "fmt" "github.com/google/go-containerregistry/pkg/crane" + "github.com/google/go-containerregistry/pkg/name" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/cache" + "github.com/google/go-containerregistry/pkg/v1/layout" + "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/spf13/cobra" ) @@ -29,20 +32,42 @@ func NewCmdPull(options *[]crane.Option) *cobra.Command { cmd := &cobra.Command{ Use: "pull IMAGE TARBALL", - Short: "Pull remote images by reference and store their contents in a tarball", + Short: "Pull remote images by reference and store their contents locally", Args: cobra.MinimumNArgs(2), RunE: func(_ *cobra.Command, args []string) error { imageMap := map[string]v1.Image{} + indexMap := map[string]v1.ImageIndex{} srcList, path := args[:len(args)-1], args[len(args)-1] for _, src := range srcList { - img, err := crane.Pull(src, *options...) + o := crane.GetOptions(*options...) + ref, err := name.ParseReference(src, o.Name...) if err != nil { - return fmt.Errorf("pulling %s: %w", src, err) + return fmt.Errorf("parsing reference %q: %w", src, err) + } + + rmt, err := remote.Get(ref, o.Remote...) + if err != nil { + return err + } + + // If we're writing an index to a layout and --platform hasn't been set, + // pull the entire index, not just a child image. + if format == "oci" && rmt.MediaType.IsIndex() && o.Platform == nil { + idx, err := rmt.ImageIndex() + if err != nil { + return err + } + indexMap[src] = idx + continue + } + + img, err := rmt.Image() + if err != nil { + return err } if cachePath != "" { img = cache.Image(img, cache.NewFilesystemCache(cachePath)) } - imageMap[src] = img } @@ -59,6 +84,20 @@ func NewCmdPull(options *[]crane.Option) *cobra.Command { if err := crane.MultiSaveOCI(imageMap, path); err != nil { return fmt.Errorf("saving oci image layout %s: %w", path, err) } + + // crane.MultiSaveOCI doesn't support index, so just append these at the end. + p, err := layout.FromPath(path) + if err != nil { + return err + } + for ref, idx := range indexMap { + anns := map[string]string{ + "dev.ggcr.image.name": ref, + } + if err := p.AppendIndex(idx, layout.WithAnnotations(anns)); err != nil { + return err + } + } default: return fmt.Errorf("unexpected --format: %q (valid values are: tarball, legacy, and oci)", format) } diff --git a/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/push.go b/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/push.go index affb4091c5..5de2ed050c 100644 --- a/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/push.go +++ b/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/push.go @@ -16,25 +16,112 @@ package cmd import ( "fmt" + "io/ioutil" + "os" "github.com/google/go-containerregistry/pkg/crane" + "github.com/google/go-containerregistry/pkg/name" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/google/go-containerregistry/pkg/v1/layout" + "github.com/google/go-containerregistry/pkg/v1/partial" + "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/spf13/cobra" ) // NewCmdPush creates a new cobra.Command for the push subcommand. func NewCmdPush(options *[]crane.Option) *cobra.Command { - return &cobra.Command{ - Use: "push TARBALL IMAGE", - Short: "Push image contents as a tarball to a remote registry", + index := false + imageRefs := "" + cmd := &cobra.Command{ + Use: "push PATH IMAGE", + Short: "Push local image contents to a remote registry", + Long: `If the PATH is a directory, it will be read as an OCI image layout. Otherwise, PATH is assumed to be a docker-style tarball.`, Args: cobra.ExactArgs(2), RunE: func(_ *cobra.Command, args []string) error { path, tag := args[0], args[1] - img, err := crane.Load(path) + + img, err := loadImage(path, index) + if err != nil { + return err + } + + o := crane.GetOptions(*options...) + ref, err := name.ParseReference(tag, o.Name...) if err != nil { - return fmt.Errorf("loading %s as tarball: %w", path, err) + return err + } + var h v1.Hash + switch t := img.(type) { + case v1.Image: + if err := remote.Write(ref, t, o.Remote...); err != nil { + return err + } + if h, err = t.Digest(); err != nil { + return err + } + case v1.ImageIndex: + if err := remote.WriteIndex(ref, t, o.Remote...); err != nil { + return err + } + if h, err = t.Digest(); err != nil { + return err + } + default: + return fmt.Errorf("cannot push type (%T) to registry", img) } - return crane.Push(img, tag, *options...) + digest := ref.Context().Digest(h.String()) + if imageRefs != "" { + return ioutil.WriteFile(imageRefs, []byte(digest.String()), 0600) + } + // TODO(mattmoor): think about printing the digest to standard out + // to facilitate command composition similar to ko build. + + return nil }, } + cmd.Flags().BoolVar(&index, "index", false, "push a collection of images as a single index, currently required if PATH contains multiple images") + cmd.Flags().StringVar(&imageRefs, "image-refs", "", "path to file where a list of the published image references will be written") + return cmd +} + +func loadImage(path string, index bool) (partial.WithRawManifest, error) { + stat, err := os.Stat(path) + if err != nil { + return nil, err + } + + if !stat.IsDir() { + img, err := crane.Load(path) + if err != nil { + return nil, fmt.Errorf("loading %s as tarball: %w", path, err) + } + return img, nil + } + + l, err := layout.ImageIndexFromPath(path) + if err != nil { + return nil, fmt.Errorf("loading %s as OCI layout: %w", path, err) + } + + if index { + return l, nil + } + + m, err := l.IndexManifest() + if err != nil { + return nil, err + } + if len(m.Manifests) != 1 { + return nil, fmt.Errorf("layout contains %d entries, consider --index", len(m.Manifests)) + } + + desc := m.Manifests[0] + if desc.MediaType.IsImage() { + return l.Image(desc.Digest) + } else if desc.MediaType.IsIndex() { + return l.ImageIndex(desc.Digest) + } + + return nil, fmt.Errorf("layout contains non-image (mediaType: %q), consider --index", desc.MediaType) } diff --git a/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/root.go b/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/root.go index 87f36fa7d5..31d997ab54 100644 --- a/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/root.go +++ b/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/root.go @@ -39,7 +39,6 @@ func New(use, short string, options []crane.Option) *cobra.Command { verbose := false insecure := false platform := &platformValue{} - var osVersion string root := &cobra.Command{ Use: use, @@ -64,14 +63,12 @@ func New(use, short string, options []crane.Option) *cobra.Command { options = append(options, crane.WithUserAgent(fmt.Sprintf("%s/%s", binary, Version))) } - if osVersion != "" { - platform.platform.OSVersion = osVersion - } - options = append(options, crane.WithPlatform(platform.platform)) transport := remote.DefaultTransport.Clone() - transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: insecure} + transport.TLSClientConfig = &tls.Config{ + InsecureSkipVerify: insecure, //nolint: gosec + } var rt http.RoundTripper = transport // Add any http headers if they are set in the config file. @@ -116,8 +113,7 @@ func New(use, short string, options []crane.Option) *cobra.Command { root.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable debug logs") root.PersistentFlags().BoolVar(&insecure, "insecure", false, "Allow image references to be fetched without TLS") - root.PersistentFlags().Var(platform, "platform", "Specifies the platform in the form os/arch[/variant] (e.g. linux/amd64).") - root.PersistentFlags().StringVar(&osVersion, "osversion", "", "Specifies the OS version.") + root.PersistentFlags().Var(platform, "platform", "Specifies the platform in the form os/arch[/variant][:osversion] (e.g. linux/amd64).") return root } diff --git a/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/util.go b/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/util.go index 2240c6b661..ebcf3ab76f 100644 --- a/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/util.go +++ b/vendor/github.com/google/go-containerregistry/cmd/crane/cmd/util.go @@ -48,7 +48,13 @@ func parsePlatform(platform string) (*v1.Platform, error) { } p := &v1.Platform{} - parts := strings.Split(platform, "/") + + parts := strings.SplitN(platform, ":", 2) + if len(parts) == 2 { + p.OSVersion = parts[1] + } + + parts = strings.Split(parts[0], "/") if len(parts) < 2 { return nil, fmt.Errorf("failed to parse platform '%s': expected format os/arch[/variant]", platform) diff --git a/vendor/github.com/google/go-containerregistry/internal/gzip/zip.go b/vendor/github.com/google/go-containerregistry/internal/gzip/zip.go index e7d673ff6b..1a52694e8d 100644 --- a/vendor/github.com/google/go-containerregistry/internal/gzip/zip.go +++ b/vendor/github.com/google/go-containerregistry/internal/gzip/zip.go @@ -115,3 +115,32 @@ func Is(r io.Reader) (bool, error) { } return bytes.Equal(magicHeader, gzipMagicHeader), nil } + +// PeekReader is an io.Reader that also implements Peek a la bufio.Reader. +type PeekReader interface { + io.Reader + Peek(n int) ([]byte, error) +} + +// Peek detects whether the input stream is gzip compressed. +// +// If r implements Peek, we will use that directly, otherwise a small number +// of bytes are buffered to Peek at the gzip header, and the returned +// PeekReader can be used as a replacement for the consumed input io.Reader. +func Peek(r io.Reader) (bool, PeekReader, error) { + var pr PeekReader + if p, ok := r.(PeekReader); ok { + pr = p + } else { + pr = bufio.NewReader(r) + } + header, err := pr.Peek(2) + if err != nil { + // https://github.com/google/go-containerregistry/issues/367 + if err == io.EOF { + return false, pr, nil + } + return false, pr, err + } + return bytes.Equal(header, gzipMagicHeader), pr, nil +} diff --git a/vendor/github.com/google/go-containerregistry/internal/verify/verify.go b/vendor/github.com/google/go-containerregistry/internal/verify/verify.go index 9d62214f6f..463f7e4b39 100644 --- a/vendor/github.com/google/go-containerregistry/internal/verify/verify.go +++ b/vendor/github.com/google/go-containerregistry/internal/verify/verify.go @@ -38,6 +38,18 @@ type verifyReader struct { gotSize, wantSize int64 } +// Error provides information about the failed hash verification. +type Error struct { + got string + want v1.Hash + gotSize int64 +} + +func (v Error) Error() string { + return fmt.Sprintf("error verifying %s checksum after reading %d bytes; got %q, want %q", + v.want.Algorithm, v.gotSize, v.got, v.want) +} + // Read implements io.Reader func (vc *verifyReader) Read(b []byte) (int, error) { n, err := vc.inner.Read(b) @@ -46,10 +58,13 @@ func (vc *verifyReader) Read(b []byte) (int, error) { if vc.wantSize != SizeUnknown && vc.gotSize != vc.wantSize { return n, fmt.Errorf("error verifying size; got %d, want %d", vc.gotSize, vc.wantSize) } - got := hex.EncodeToString(vc.hasher.Sum(make([]byte, 0, vc.hasher.Size()))) + got := hex.EncodeToString(vc.hasher.Sum(nil)) if want := vc.expected.Hex; got != want { - return n, fmt.Errorf("error verifying %s checksum after reading %d bytes; got %q, want %q", - vc.expected.Algorithm, vc.gotSize, got, want) + return n, Error{ + got: vc.expected.Algorithm + ":" + got, + want: vc.expected, + gotSize: vc.gotSize, + } } } return n, err @@ -69,9 +84,9 @@ func ReadCloser(r io.ReadCloser, size int64, h v1.Hash) (io.ReadCloser, error) { if err != nil { return nil, err } - var r2 io.Reader = r + r2 := io.TeeReader(r, w) // pass all writes to the hasher. if size != SizeUnknown { - r2 = io.LimitReader(io.TeeReader(r, w), size) + r2 = io.LimitReader(r2, size) // if we know the size, limit to that size. } return &and.ReadCloser{ Reader: &verifyReader{ diff --git a/vendor/github.com/google/go-containerregistry/internal/windows/windows.go b/vendor/github.com/google/go-containerregistry/internal/windows/windows.go new file mode 100644 index 0000000000..f6a1ade08b --- /dev/null +++ b/vendor/github.com/google/go-containerregistry/internal/windows/windows.go @@ -0,0 +1,115 @@ +// Copyright 2021 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package windows + +import ( + "archive/tar" + "bytes" + "errors" + "fmt" + "io" + "io/ioutil" + "path" + "strings" + + "github.com/google/go-containerregistry/internal/gzip" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/google/go-containerregistry/pkg/v1/tarball" +) + +// userOwnerAndGroupSID is a magic value needed to make the binary executable +// in a Windows container. +// +// owner: BUILTIN/Users group: BUILTIN/Users ($sddlValue="O:BUG:BU") +const userOwnerAndGroupSID = "AQAAgBQAAAAkAAAAAAAAAAAAAAABAgAAAAAABSAAAAAhAgAAAQIAAAAAAAUgAAAAIQIAAA==" + +// Windows returns a Layer that is converted to be pullable on Windows. +func Windows(layer v1.Layer) (v1.Layer, error) { + // TODO: do this lazily. + + layerReader, err := layer.Uncompressed() + if err != nil { + return nil, fmt.Errorf("getting layer: %w", err) + } + defer layerReader.Close() + tarReader := tar.NewReader(layerReader) + w := new(bytes.Buffer) + tarWriter := tar.NewWriter(w) + defer tarWriter.Close() + + for _, dir := range []string{"Files", "Hives"} { + if err := tarWriter.WriteHeader(&tar.Header{ + Name: dir, + Typeflag: tar.TypeDir, + // Use a fixed Mode, so that this isn't sensitive to the directory and umask + // under which it was created. Additionally, windows can only set 0222, + // 0444, or 0666, none of which are executable. + Mode: 0555, + Format: tar.FormatPAX, + }); err != nil { + return nil, fmt.Errorf("writing %s directory: %w", dir, err) + } + } + + for { + header, err := tarReader.Next() + if errors.Is(err, io.EOF) { + break + } + if err != nil { + return nil, fmt.Errorf("reading layer: %w", err) + } + + if strings.HasPrefix(header.Name, "Files/") { + return nil, fmt.Errorf("file path %q already suitable for Windows", header.Name) + } + + header.Name = path.Join("Files", header.Name) + header.Format = tar.FormatPAX + + // TODO: this seems to make the file executable on Windows; + // only do this if the file should be executable. + if header.PAXRecords == nil { + header.PAXRecords = map[string]string{} + } + header.PAXRecords["MSWINDOWS.rawsd"] = userOwnerAndGroupSID + + if err := tarWriter.WriteHeader(header); err != nil { + return nil, fmt.Errorf("writing tar header: %w", err) + } + + if header.Typeflag == tar.TypeReg { + if _, err = io.Copy(tarWriter, tarReader); err != nil { + return nil, fmt.Errorf("writing layer file: %w", err) + } + } + } + + if err := tarWriter.Close(); err != nil { + return nil, err + } + + b := w.Bytes() + // gzip the contents, then create the layer + opener := func() (io.ReadCloser, error) { + return gzip.ReadCloser(ioutil.NopCloser(bytes.NewReader(b))), nil + } + layer, err = tarball.LayerFromOpener(opener) + if err != nil { + return nil, fmt.Errorf("creating layer: %w", err) + } + + return layer, nil +} diff --git a/vendor/github.com/google/go-containerregistry/pkg/authn/README.md b/vendor/github.com/google/go-containerregistry/pkg/authn/README.md index 1eb17c7ab1..115789885e 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/authn/README.md +++ b/vendor/github.com/google/go-containerregistry/pkg/authn/README.md @@ -4,15 +4,15 @@ This README outlines how we acquire and use credentials when interacting with a registry. -As much as possible, we attempt to emulate docker's authentication behavior and configuration so that this library "just works" if you've already configured credentials that work with docker; however, when things don't work, a basic understanding of what's going on can help with debugging. +As much as possible, we attempt to emulate `docker`'s authentication behavior and configuration so that this library "just works" if you've already configured credentials that work with `docker`; however, when things don't work, a basic understanding of what's going on can help with debugging. -The official documentation for how docker authentication works is (reasonably) scattered across several different sites and GitHub repositories, so we've tried to summarize the relevant bits here. +The official documentation for how authentication with `docker` works is (reasonably) scattered across several different sites and GitHub repositories, so we've tried to summarize the relevant bits here. ## tl;dr for consumers of this package By default, [`pkg/v1/remote`](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/remote) uses [`Anonymous`](https://godoc.org/github.com/google/go-containerregistry/pkg/authn#Anonymous) credentials (i.e. _none_), which for most registries will only allow read access to public images. -To use the credentials found in your docker config file, you can use the [`DefaultKeychain`](https://godoc.org/github.com/google/go-containerregistry/pkg/authn#DefaultKeychain), e.g.: +To use the credentials found in your Docker config file, you can use the [`DefaultKeychain`](https://godoc.org/github.com/google/go-containerregistry/pkg/authn#DefaultKeychain), e.g.: ```go package main @@ -42,15 +42,95 @@ func main() { } ``` -(If you're only using [gcr.io](https://gcr.io), see the [`pkg/v1/google.Keychain`](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/google#Keychain), which emulates [`docker-credential-gcr`](https://github.com/GoogleCloudPlatform/docker-credential-gcr).) +The `DefaultKeychain` will use credentials as described in your Docker config file -- usually `~/.docker/config.json`, or `%USERPROFILE%\.docker\config.json` on Windows -- or the location described by the `DOCKER_CONFIG` environment variable, if set. -## The Config File +If those are not found, `DefaultKeychain` will look for credentials configured using [Podman's expectation](https://docs.podman.io/en/latest/markdown/podman-login.1.html) that these are found in `${XDG_RUNTIME_DIR}/containers/auth.json`. -This file contains various configuration options for docker and is (by default) located at: -* `$HOME/.docker/config.json` (on linux and darwin), or -* `%USERPROFILE%\.docker\config.json` (on windows). +[See below](#docker-config-auth) for more information about what is configured in this file. -You can override this location with the `DOCKER_CONFIG` environment variable. +## Emulating Cloud Provider Credential Helpers + +[`pkg/v1/google.Keychain`](https://pkg.go.dev/github.com/google/go-containerregistry/pkg/v1/google#Keychain) provides a `Keychain` implementation that emulates [`docker-credential-gcr`](https://github.com/GoogleCloudPlatform/docker-credential-gcr) to find credentials in the environment. +See [`google.NewEnvAuthenticator`](https://pkg.go.dev/github.com/google/go-containerregistry/pkg/v1/google#NewEnvAuthenticator) and [`google.NewGcloudAuthenticator`](https://pkg.go.dev/github.com/google/go-containerregistry/pkg/v1/google#NewGcloudAuthenticator) for more information. + +To emulate other credential helpers without requiring them to be available as executables, [`NewKeychainFromHelper`](https://pkg.go.dev/github.com/google/go-containerregistry/pkg/authn#NewKeychainFromHelper) provides an adapter that takes a Go implementation satisfying a subset of the [`credentials.Helper`](https://pkg.go.dev/github.com/docker/docker-credential-helpers/credentials#Helper) interface, and makes it available as a `Keychain`. + +This means that you can emulate, for example, [Amazon ECR's `docker-credential-ecr-login` credential helper](https://github.com/awslabs/amazon-ecr-credential-helper) using the same implementation: + +```go +import ( + ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login" + "github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api" + + "github.com/google/go-containerregistry/pkg/authn" + "github.com/google/go-containerregistry/pkg/v1/remote" +) + +func main() { + // ... + ecrHelper := ecr.ECRHelper{ClientFactory: api.DefaultClientFactory()} + img, err := remote.Get(ref, remote.WithAuthFromKeychain(authn.NewKeychainFromHelper(ecrHelper))) + if err != nil { + panic(err) + } + // ... +} +``` + +Likewise, you can emulate [Azure's ACR `docker-credential-acr-env` credential helper](https://github.com/chrismellard/docker-credential-acr-env): + +```go +import ( + "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper" + + "github.com/google/go-containerregistry/pkg/authn" + "github.com/google/go-containerregistry/pkg/v1/remote" +) + +func main() { + // ... + acrHelper := credhelper.NewACRCredentialsHelper() + img, err := remote.Get(ref, remote.WithAuthFromKeychain(authn.NewKeychainFromHelper(acrHelper))) + if err != nil { + panic(err) + } + // ... +} +``` + + + +## Using Multiple `Keychain`s + +[`NewMultiKeychain`](https://pkg.go.dev/github.com/google/go-containerregistry/pkg/authn#NewMultiKeychain) allows you to specify multiple `Keychain` implementations, which will be checked in order when credentials are needed. + +For example: + +```go +kc := authn.NewMultiKeychain( + authn.DefaultKeychain, + google.Keychain, + authn.NewFromHelper(ecr.ECRHelper{ClientFactory: api.DefaultClientFactory{}}), + authn.NewFromHelper(acr.ACRCredHelper{}), +) +``` + +This multi-keychain will: + +- first check for credentials found in the Docker config file, as describe above, then +- check for GCP credentials available in the environment, as described above, then +- check for ECR credentials by emulating the ECR credential helper, then +- check for ACR credentials by emulating the ACR credential helper. + +If any keychain implementation is able to provide credentials for the request, they will be used, and further keychain implementations will not be consulted. + +If no implementations are able to provide credentials, `Anonymous` credentials will be used. + +## Docker Config Auth + +What follows attempts to gather useful information about Docker's config.json and make it available in one place. + +If you have questions, please [file an issue](https://github.com/google/go-containerregistry/issues/new). ### Plaintext @@ -92,7 +172,7 @@ For what it's worth, this config file is equivalent to: ### Helpers -If you log in like this, docker will warn you that you should use a [credential helper](https://docs.docker.com/engine/reference/commandline/login/#credentials-store), and you should! +If you log in like this, `docker` will warn you that you should use a [credential helper](https://docs.docker.com/engine/reference/commandline/login/#credentials-store), and you should! To configure a global credential helper: ```json diff --git a/vendor/github.com/google/go-containerregistry/pkg/authn/keychain.go b/vendor/github.com/google/go-containerregistry/pkg/authn/keychain.go index e9795009b5..f79b7260e8 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/authn/keychain.go +++ b/vendor/github.com/google/go-containerregistry/pkg/authn/keychain.go @@ -16,11 +16,14 @@ package authn import ( "os" + "path/filepath" "sync" "github.com/docker/cli/cli/config" + "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/types" "github.com/google/go-containerregistry/pkg/name" + "github.com/mitchellh/go-homedir" ) // Resource represents a registry or repository that can be authenticated against. @@ -62,9 +65,52 @@ const ( func (dk *defaultKeychain) Resolve(target Resource) (Authenticator, error) { dk.mu.Lock() defer dk.mu.Unlock() - cf, err := config.Load(os.Getenv("DOCKER_CONFIG")) - if err != nil { - return nil, err + + // Podman users may have their container registry auth configured in a + // different location, that Docker packages aren't aware of. + // If the Docker config file isn't found, we'll fallback to look where + // Podman configures it, and parse that as a Docker auth config instead. + + // First, check $HOME/.docker/config.json + foundDockerConfig := false + home, err := homedir.Dir() + if err == nil { + if _, err := os.Stat(filepath.Join(home, ".docker/config.json")); err == nil { + foundDockerConfig = true + } + } + // If $HOME/.docker/config.json isn't found, check $DOCKER_CONFIG (if set) + if !foundDockerConfig && os.Getenv("DOCKER_CONFIG") != "" { + if _, err := os.Stat(filepath.Join(os.Getenv("DOCKER_CONFIG"), "config.json")); err == nil { + foundDockerConfig = true + } + } + // If either of those locations are found, load it using Docker's + // config.Load, which may fail if the config can't be parsed. + // + // If neither was found, look for Podman's auth at + // $XDG_RUNTIME_DIR/containers/auth.json and attempt to load it as a + // Docker config. + // + // If neither are found, fallback to Anonymous. + var cf *configfile.ConfigFile + if foundDockerConfig { + cf, err = config.Load(os.Getenv("DOCKER_CONFIG")) + if err != nil { + return nil, err + } + } else { + f, err := os.Open(filepath.Join(os.Getenv("XDG_RUNTIME_DIR"), "containers/auth.json")) + if os.IsNotExist(err) { + return Anonymous, nil + } else if err != nil { + return nil, err + } + defer f.Close() + cf, err = config.LoadFromReader(f) + if err != nil { + return nil, err + } } // See: @@ -92,3 +138,27 @@ func (dk *defaultKeychain) Resolve(target Resource) (Authenticator, error) { RegistryToken: cfg.RegistryToken, }), nil } + +// Helper is a subset of the Docker credential helper credentials.Helper +// interface used by NewKeychainFromHelper. +// +// See: +// https://pkg.go.dev/github.com/docker/docker-credential-helpers/credentials#Helper +type Helper interface { + Get(serverURL string) (string, string, error) +} + +// NewKeychainFromHelper returns a Keychain based on a Docker credential helper +// implementation that can Get username and password credentials for a given +// server URL. +func NewKeychainFromHelper(h Helper) Keychain { return wrapper{h} } + +type wrapper struct{ h Helper } + +func (w wrapper) Resolve(r Resource) (Authenticator, error) { + u, p, err := w.h.Get(r.String()) + if err != nil { + return Anonymous, nil + } + return FromConfig(AuthConfig{Username: u, Password: p}), nil +} diff --git a/vendor/github.com/google/go-containerregistry/pkg/crane/append.go b/vendor/github.com/google/go-containerregistry/pkg/crane/append.go index 4f660d8fc9..92d6b7b3b0 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/crane/append.go +++ b/vendor/github.com/google/go-containerregistry/pkg/crane/append.go @@ -18,14 +18,35 @@ import ( "fmt" "os" + "github.com/google/go-containerregistry/internal/windows" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/mutate" "github.com/google/go-containerregistry/pkg/v1/stream" "github.com/google/go-containerregistry/pkg/v1/tarball" ) +func isWindows(img v1.Image) (bool, error) { + if img == nil { + return false, nil + } + cfg, err := img.ConfigFile() + if err != nil { + return false, err + } + return cfg != nil && cfg.OS == "windows", nil +} + // Append reads a layer from path and appends it the the v1.Image base. +// +// If the base image is a Windows base image (i.e., its config.OS is +// "windows"), the contents of the tarballs will be modified to be suitable for +// a Windows container image.`, func Append(base v1.Image, paths ...string) (v1.Image, error) { + win, err := isWindows(base) + if err != nil { + return nil, fmt.Errorf("getting base image: %w", err) + } + layers := make([]v1.Layer, 0, len(paths)) for _, path := range paths { layer, err := getLayer(path) @@ -33,6 +54,13 @@ func Append(base v1.Image, paths ...string) (v1.Image, error) { return nil, fmt.Errorf("reading layer %q: %w", path, err) } + if win { + layer, err = windows.Windows(layer) + if err != nil { + return nil, fmt.Errorf("converting %q for Windows: %w", path, err) + } + } + layers = append(layers, layer) } diff --git a/vendor/github.com/google/go-containerregistry/pkg/crane/export.go b/vendor/github.com/google/go-containerregistry/pkg/crane/export.go index 29334912ec..5d6da1dca8 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/crane/export.go +++ b/vendor/github.com/google/go-containerregistry/pkg/crane/export.go @@ -22,8 +22,26 @@ import ( ) // Export writes the filesystem contents (as a tarball) of img to w. +// If img has a single layer, just write the (uncompressed) contents to w so +// that this "just works" for images that just wrap a single blob. func Export(img v1.Image, w io.Writer) error { + layers, err := img.Layers() + if err != nil { + return err + } + if len(layers) == 1 { + // If it's a single layer, we don't have to flatten the filesystem. + // An added perk of skipping mutate.Extract here is that this works + // for non-tarball layers. + l := layers[0] + rc, err := l.Uncompressed() + if err != nil { + return err + } + _, err = io.Copy(w, rc) + return err + } fs := mutate.Extract(img) - _, err := io.Copy(w, fs) + _, err = io.Copy(w, fs) return err } diff --git a/vendor/github.com/google/go-containerregistry/pkg/crane/pull.go b/vendor/github.com/google/go-containerregistry/pkg/crane/pull.go index 7e6e5b7b6e..b19ac7c212 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/crane/pull.go +++ b/vendor/github.com/google/go-containerregistry/pkg/crane/pull.go @@ -133,8 +133,11 @@ func MultiSaveOCI(imgMap map[string]v1.Image, path string) error { return err } } - for _, img := range imgMap { - if err = p.AppendImage(img); err != nil { + for ref, img := range imgMap { + anns := map[string]string{ + "dev.ggcr.image.name": ref, + } + if err = p.AppendImage(img, layout.WithAnnotations(anns)); err != nil { return err } } diff --git a/vendor/github.com/google/go-containerregistry/pkg/name/check.go b/vendor/github.com/google/go-containerregistry/pkg/name/check.go index c15cc03b3c..e9a240a3e5 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/name/check.go +++ b/vendor/github.com/google/go-containerregistry/pkg/name/check.go @@ -35,9 +35,9 @@ func stripRunesFn(runes string) func(rune) rune { func checkElement(name, element, allowedRunes string, minRunes, maxRunes int) error { numRunes := utf8.RuneCountInString(element) if (numRunes < minRunes) || (maxRunes < numRunes) { - return newErrBadName("%s must be between %d and %d runes in length: %s", name, minRunes, maxRunes, element) + return newErrBadName("%s must be between %d and %d characters in length: %s", name, minRunes, maxRunes, element) } else if len(strings.Map(stripRunesFn(allowedRunes), element)) != 0 { - return newErrBadName("%s can only contain the runes `%s`: %s", name, allowedRunes, element) + return newErrBadName("%s can only contain the characters `%s`: %s", name, allowedRunes, element) } return nil } diff --git a/vendor/github.com/google/go-containerregistry/pkg/registry/blobs.go b/vendor/github.com/google/go-containerregistry/pkg/registry/blobs.go index 0672272712..9677d69d95 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/registry/blobs.go +++ b/vendor/github.com/google/go-containerregistry/pkg/registry/blobs.go @@ -16,15 +16,20 @@ package registry import ( "bytes" - "crypto/sha256" - "encoding/hex" + "context" + "errors" "fmt" "io" + "io/ioutil" + "log" "math/rand" "net/http" "path" "strings" "sync" + + "github.com/google/go-containerregistry/internal/verify" + v1 "github.com/google/go-containerregistry/pkg/v1" ) // Returns whether this url should be handled by the blob handler @@ -44,10 +49,91 @@ func isBlob(req *http.Request) bool { elem[len(elem)-2] == "uploads") } +// blobHandler represents a minimal blob storage backend, capable of serving +// blob contents. +type blobHandler interface { + // Get gets the blob contents, or errNotFound if the blob wasn't found. + Get(ctx context.Context, repo string, h v1.Hash) (io.ReadCloser, error) +} + +// blobStatHandler is an extension interface representing a blob storage +// backend that can serve metadata about blobs. +type blobStatHandler interface { + // Stat returns the size of the blob, or errNotFound if the blob wasn't + // found, or redirectError if the blob can be found elsewhere. + Stat(ctx context.Context, repo string, h v1.Hash) (int64, error) +} + +// blobPutHandler is an extension interface representing a blob storage backend +// that can write blob contents. +type blobPutHandler interface { + // Put puts the blob contents. + // + // The contents will be verified against the expected size and digest + // as the contents are read, and an error will be returned if these + // don't match. Implementations should return that error, or a wrapper + // around that error, to return the correct error when these don't match. + Put(ctx context.Context, repo string, h v1.Hash, rc io.ReadCloser) error +} + +// redirectError represents a signal that the blob handler doesn't have the blob +// contents, but that those contents are at another location which registry +// clients should redirect to. +type redirectError struct { + // Location is the location to find the contents. + Location string + + // Code is the HTTP redirect status code to return to clients. + Code int +} + +func (e redirectError) Error() string { return fmt.Sprintf("redirecting (%d): %s", e.Code, e.Location) } + +// errNotFound represents an error locating the blob. +var errNotFound = errors.New("not found") + +type memHandler struct { + m map[string][]byte + lock sync.Mutex +} + +func (m *memHandler) Stat(_ context.Context, _ string, h v1.Hash) (int64, error) { + m.lock.Lock() + defer m.lock.Unlock() + + b, found := m.m[h.String()] + if !found { + return 0, errNotFound + } + return int64(len(b)), nil +} +func (m *memHandler) Get(_ context.Context, _ string, h v1.Hash) (io.ReadCloser, error) { + m.lock.Lock() + defer m.lock.Unlock() + + b, found := m.m[h.String()] + if !found { + return nil, errNotFound + } + return ioutil.NopCloser(bytes.NewReader(b)), nil +} +func (m *memHandler) Put(_ context.Context, _ string, h v1.Hash, rc io.ReadCloser) error { + m.lock.Lock() + defer m.lock.Unlock() + + defer rc.Close() + all, err := ioutil.ReadAll(rc) + if err != nil { + return err + } + m.m[h.String()] = all + return nil +} + // blobs type blobs struct { - // Blobs are content addresses. we store them globally underneath their sha and make no distinctions per image. - contents map[string][]byte + blobHandler blobHandler + // Each upload gets a unique id that writes occur to until finalized. uploads map[string][]byte lock sync.Mutex @@ -72,43 +158,127 @@ func (b *blobs) handle(resp http.ResponseWriter, req *http.Request) *regError { digest := req.URL.Query().Get("digest") contentRange := req.Header.Get("Content-Range") + repo := req.URL.Host + path.Join(elem[1:len(elem)-2]...) + switch req.Method { case http.MethodHead: - b.lock.Lock() - defer b.lock.Unlock() - b, ok := b.contents[target] - if !ok { + h, err := v1.NewHash(target) + if err != nil { return ®Error{ - Status: http.StatusNotFound, - Code: "BLOB_UNKNOWN", - Message: "Unknown blob", + Status: http.StatusBadRequest, + Code: "NAME_INVALID", + Message: "invalid digest", } } - resp.Header().Set("Content-Length", fmt.Sprint(len(b))) - resp.Header().Set("Docker-Content-Digest", target) + var size int64 + if bsh, ok := b.blobHandler.(blobStatHandler); ok { + size, err = bsh.Stat(req.Context(), repo, h) + if errors.Is(err, errNotFound) { + return regErrBlobUnknown + } else if err != nil { + var rerr redirectError + if errors.As(err, &rerr) { + http.Redirect(resp, req, rerr.Location, rerr.Code) + return nil + } + return regErrInternal(err) + } + } else { + rc, err := b.blobHandler.Get(req.Context(), repo, h) + if errors.Is(err, errNotFound) { + return regErrBlobUnknown + } else if err != nil { + var rerr redirectError + if errors.As(err, &rerr) { + http.Redirect(resp, req, rerr.Location, rerr.Code) + return nil + } + return regErrInternal(err) + } + defer rc.Close() + size, err = io.Copy(ioutil.Discard, rc) + if err != nil { + return regErrInternal(err) + } + } + + resp.Header().Set("Content-Length", fmt.Sprint(size)) + resp.Header().Set("Docker-Content-Digest", h.String()) resp.WriteHeader(http.StatusOK) return nil case http.MethodGet: - b.lock.Lock() - defer b.lock.Unlock() - b, ok := b.contents[target] - if !ok { + h, err := v1.NewHash(target) + if err != nil { return ®Error{ - Status: http.StatusNotFound, - Code: "BLOB_UNKNOWN", - Message: "Unknown blob", + Status: http.StatusBadRequest, + Code: "NAME_INVALID", + Message: "invalid digest", + } + } + + var size int64 + var r io.Reader + if bsh, ok := b.blobHandler.(blobStatHandler); ok { + size, err = bsh.Stat(req.Context(), repo, h) + if errors.Is(err, errNotFound) { + return regErrBlobUnknown + } else if err != nil { + var rerr redirectError + if errors.As(err, &rerr) { + http.Redirect(resp, req, rerr.Location, rerr.Code) + return nil + } + return regErrInternal(err) + } + + rc, err := b.blobHandler.Get(req.Context(), repo, h) + if errors.Is(err, errNotFound) { + return regErrBlobUnknown + } else if err != nil { + var rerr redirectError + if errors.As(err, &rerr) { + http.Redirect(resp, req, rerr.Location, rerr.Code) + return nil + } + + return regErrInternal(err) } + defer rc.Close() + r = rc + } else { + tmp, err := b.blobHandler.Get(req.Context(), repo, h) + if errors.Is(err, errNotFound) { + return regErrBlobUnknown + } else if err != nil { + var rerr redirectError + if errors.As(err, &rerr) { + http.Redirect(resp, req, rerr.Location, rerr.Code) + return nil + } + + return regErrInternal(err) + } + defer tmp.Close() + var buf bytes.Buffer + io.Copy(&buf, tmp) + size = int64(buf.Len()) + r = &buf } - resp.Header().Set("Content-Length", fmt.Sprint(len(b))) - resp.Header().Set("Docker-Content-Digest", target) + resp.Header().Set("Content-Length", fmt.Sprint(size)) + resp.Header().Set("Docker-Content-Digest", h.String()) resp.WriteHeader(http.StatusOK) - io.Copy(resp, bytes.NewReader(b)) + io.Copy(resp, r) return nil case http.MethodPost: + bph, ok := b.blobHandler.(blobPutHandler) + if !ok { + return regErrUnsupported + } + // It is weird that this is "target" instead of "service", but // that's how the index math works out above. if target != "uploads" { @@ -120,22 +290,25 @@ func (b *blobs) handle(resp http.ResponseWriter, req *http.Request) *regError { } if digest != "" { - l := &bytes.Buffer{} - io.Copy(l, req.Body) - rd := sha256.Sum256(l.Bytes()) - d := "sha256:" + hex.EncodeToString(rd[:]) - if d != digest { - return ®Error{ - Status: http.StatusBadRequest, - Code: "DIGEST_INVALID", - Message: "digest does not match contents", - } + h, err := v1.NewHash(digest) + if err != nil { + return regErrDigestInvalid } - b.lock.Lock() - defer b.lock.Unlock() - b.contents[d] = l.Bytes() - resp.Header().Set("Docker-Content-Digest", d) + vrc, err := verify.ReadCloser(req.Body, req.ContentLength, h) + if err != nil { + return regErrInternal(err) + } + defer vrc.Close() + + if err = bph.Put(req.Context(), repo, h, vrc); err != nil { + if errors.As(err, &verify.Error{}) { + log.Printf("Digest mismatch: %v", err) + return regErrDigestMismatch + } + return regErrInternal(err) + } + resp.Header().Set("Docker-Content-Digest", h.String()) resp.WriteHeader(http.StatusCreated) return nil } @@ -202,6 +375,11 @@ func (b *blobs) handle(resp http.ResponseWriter, req *http.Request) *regError { return nil case http.MethodPut: + bph, ok := b.blobHandler.(blobPutHandler) + if !ok { + return regErrUnsupported + } + if service != "uploads" { return ®Error{ Status: http.StatusBadRequest, @@ -220,21 +398,40 @@ func (b *blobs) handle(resp http.ResponseWriter, req *http.Request) *regError { b.lock.Lock() defer b.lock.Unlock() - l := bytes.NewBuffer(b.uploads[target]) - io.Copy(l, req.Body) - rd := sha256.Sum256(l.Bytes()) - d := "sha256:" + hex.EncodeToString(rd[:]) - if d != digest { + + h, err := v1.NewHash(digest) + if err != nil { return ®Error{ Status: http.StatusBadRequest, - Code: "DIGEST_INVALID", - Message: "digest does not match contents", + Code: "NAME_INVALID", + Message: "invalid digest", + } + } + + defer req.Body.Close() + in := ioutil.NopCloser(io.MultiReader(bytes.NewBuffer(b.uploads[target]), req.Body)) + + size := int64(verify.SizeUnknown) + if req.ContentLength > 0 { + size = int64(len(b.uploads[target])) + req.ContentLength + } + + vrc, err := verify.ReadCloser(in, size, h) + if err != nil { + return regErrInternal(err) + } + defer vrc.Close() + + if err := bph.Put(req.Context(), repo, h, vrc); err != nil { + if errors.As(err, &verify.Error{}) { + log.Printf("Digest mismatch: %v", err) + return regErrDigestMismatch } + return regErrInternal(err) } - b.contents[d] = l.Bytes() delete(b.uploads, target) - resp.Header().Set("Docker-Content-Digest", d) + resp.Header().Set("Docker-Content-Digest", h.String()) resp.WriteHeader(http.StatusCreated) return nil diff --git a/vendor/github.com/google/go-containerregistry/pkg/registry/error.go b/vendor/github.com/google/go-containerregistry/pkg/registry/error.go index 64e98671c3..f8e126dace 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/registry/error.go +++ b/vendor/github.com/google/go-containerregistry/pkg/registry/error.go @@ -44,3 +44,36 @@ func (r *regError) Write(resp http.ResponseWriter) error { }, }) } + +// regErrInternal returns an internal server error. +func regErrInternal(err error) *regError { + return ®Error{ + Status: http.StatusInternalServerError, + Code: "INTERNAL_SERVER_ERROR", + Message: err.Error(), + } +} + +var regErrBlobUnknown = ®Error{ + Status: http.StatusNotFound, + Code: "BLOB_UNKNOWN", + Message: "Unknown blob", +} + +var regErrUnsupported = ®Error{ + Status: http.StatusMethodNotAllowed, + Code: "UNSUPPORTED", + Message: "Unsupported operation", +} + +var regErrDigestMismatch = ®Error{ + Status: http.StatusBadRequest, + Code: "DIGEST_INVALID", + Message: "digest does not match contents", +} + +var regErrDigestInvalid = ®Error{ + Status: http.StatusBadRequest, + Code: "NAME_INVALID", + Message: "invalid digest", +} diff --git a/vendor/github.com/google/go-containerregistry/pkg/registry/registry.go b/vendor/github.com/google/go-containerregistry/pkg/registry/registry.go index c56dae26d6..00a7ff9265 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/registry/registry.go +++ b/vendor/github.com/google/go-containerregistry/pkg/registry/registry.go @@ -77,8 +77,8 @@ func New(opts ...Option) http.Handler { r := ®istry{ log: log.New(os.Stderr, "", log.LstdFlags), blobs: blobs{ - contents: map[string][]byte{}, - uploads: map[string][]byte{}, + blobHandler: &memHandler{m: map[string][]byte{}}, + uploads: map[string][]byte{}, }, manifests: manifests{ manifests: map[string]map[string]manifest{}, diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/mutate.go b/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/mutate.go index d88ecbfb76..7a1f59fed2 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/mutate.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/mutate.go @@ -299,7 +299,7 @@ func extract(img v1.Image, w io.Writer) error { if !tombstone { tarWriter.WriteHeader(header) if header.Size > 0 { - if _, err := io.Copy(tarWriter, tarReader); err != nil { + if _, err := io.CopyN(tarWriter, tarReader, header.Size); err != nil { return err } } @@ -409,7 +409,8 @@ func layerTime(layer v1.Layer, t time.Time) (v1.Layer, error) { } if header.Typeflag == tar.TypeReg { - if _, err = io.Copy(tarWriter, tarReader); err != nil { + // TODO(#1168): This should be lazy, and not buffer the entire layer contents. + if _, err = io.CopyN(tarWriter, tarReader, header.Size); err != nil { return nil, fmt.Errorf("writing layer file: %w", err) } } diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/partial/compressed.go b/vendor/github.com/google/go-containerregistry/pkg/v1/partial/compressed.go index 2e6e548ac9..c999517289 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/partial/compressed.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/partial/compressed.go @@ -17,6 +17,7 @@ package partial import ( "io" + "github.com/google/go-containerregistry/internal/and" "github.com/google/go-containerregistry/internal/gzip" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/types" @@ -45,11 +46,28 @@ type compressedLayerExtender struct { // Uncompressed implements v1.Layer func (cle *compressedLayerExtender) Uncompressed() (io.ReadCloser, error) { - r, err := cle.Compressed() + rc, err := cle.Compressed() if err != nil { return nil, err } - return gzip.UnzipReadCloser(r) + + // Often, the "compressed" bytes are not actually gzip-compressed. + // Peek at the first two bytes to determine whether or not it's correct to + // wrap this with gzip.UnzipReadCloser. + gzipped, pr, err := gzip.Peek(rc) + if err != nil { + return nil, err + } + prc := &and.ReadCloser{ + Reader: pr, + CloseFunc: rc.Close, + } + + if !gzipped { + return prc, nil + } + + return gzip.UnzipReadCloser(prc) } // DiffID implements v1.Layer diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/random/image.go b/vendor/github.com/google/go-containerregistry/pkg/v1/random/image.go index adcc25f62e..6399412bef 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/random/image.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/random/image.go @@ -81,7 +81,7 @@ func Image(byteSize, layers int64) (v1.Image, error) { // Layer returns a layer with pseudo-randomly generated content. func Layer(byteSize int64, mt types.MediaType) (v1.Layer, error) { - fileName := fmt.Sprintf("random_file_%d.txt", mrand.Int()) + fileName := fmt.Sprintf("random_file_%d.txt", mrand.Int()) //nolint: gosec // Hash the contents as we write it out to the buffer. var b bytes.Buffer diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/error.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/error.go index 2c57f1a31c..b94b180ccf 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/error.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/error.go @@ -155,6 +155,10 @@ const ( UnsupportedErrorCode ErrorCode = "UNSUPPORTED" TooManyRequestsErrorCode ErrorCode = "TOOMANYREQUESTS" UnknownErrorCode ErrorCode = "UNKNOWN" + + // This isn't defined by either docker or OCI spec, but is defined by docker/distribution: + // https://github.com/distribution/distribution/blob/6a977a5a754baa213041443f841705888107362a/registry/api/errcode/register.go#L60 + UnavailableErrorCode ErrorCode = "UNAVAILABLE" ) // TODO: Include other error types. @@ -162,6 +166,7 @@ var temporaryErrorCodes = map[ErrorCode]struct{}{ BlobUploadInvalidErrorCode: {}, TooManyRequestsErrorCode: {}, UnknownErrorCode: {}, + UnavailableErrorCode: {}, } var temporaryStatusCodes = map[int]struct{}{ diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/transport.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/transport.go index ea40e3a4fb..121904df3a 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/transport.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/transport.go @@ -68,9 +68,7 @@ func NewWithContext(ctx context.Context, reg name.Registry, auth authn.Authentic } switch pr.challenge.Canonical() { - case anonymous: - return &Wrapper{t}, nil - case basic: + case anonymous, basic: return &Wrapper{&basicTransport{inner: t, auth: auth, target: reg.RegistryStr()}}, nil case bearer: // We require the realm, which tells us where to send our Basic auth to turn it into Bearer auth. diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/tarball/image.go b/vendor/github.com/google/go-containerregistry/pkg/v1/tarball/image.go index 564a5ef765..b2e44df756 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/tarball/image.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/tarball/image.go @@ -236,7 +236,7 @@ func extractFileFromTar(opener Opener, filePath string) (io.ReadCloser, error) { if hdr.Name == filePath { if hdr.Typeflag == tar.TypeSymlink || hdr.Typeflag == tar.TypeLink { currentDir := filepath.Dir(filePath) - return extractFileFromTar(opener, path.Join(currentDir, hdr.Linkname)) + return extractFileFromTar(opener, path.Join(currentDir, path.Clean(hdr.Linkname))) } close = false return tarFile{ diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/zz_deepcopy_generated.go b/vendor/github.com/google/go-containerregistry/pkg/v1/zz_deepcopy_generated.go index 0cb1586f1e..b32b8b77a1 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/zz_deepcopy_generated.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/zz_deepcopy_generated.go @@ -1,4 +1,3 @@ -//go:build !ignore_autogenerated // +build !ignore_autogenerated // Copyright 2018 Google LLC All Rights Reserved. diff --git a/vendor/github.com/mitchellh/go-homedir/LICENSE b/vendor/github.com/mitchellh/go-homedir/LICENSE new file mode 100644 index 0000000000..f9c841a51e --- /dev/null +++ b/vendor/github.com/mitchellh/go-homedir/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Mitchell Hashimoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/mitchellh/go-homedir/README.md b/vendor/github.com/mitchellh/go-homedir/README.md new file mode 100644 index 0000000000..d70706d5b3 --- /dev/null +++ b/vendor/github.com/mitchellh/go-homedir/README.md @@ -0,0 +1,14 @@ +# go-homedir + +This is a Go library for detecting the user's home directory without +the use of cgo, so the library can be used in cross-compilation environments. + +Usage is incredibly simple, just call `homedir.Dir()` to get the home directory +for a user, and `homedir.Expand()` to expand the `~` in a path to the home +directory. + +**Why not just use `os/user`?** The built-in `os/user` package requires +cgo on Darwin systems. This means that any Go code that uses that package +cannot cross compile. But 99% of the time the use for `os/user` is just to +retrieve the home directory, which we can do for the current user without +cgo. This library does that, enabling cross-compilation. diff --git a/vendor/github.com/mitchellh/go-homedir/go.mod b/vendor/github.com/mitchellh/go-homedir/go.mod new file mode 100644 index 0000000000..7efa09a043 --- /dev/null +++ b/vendor/github.com/mitchellh/go-homedir/go.mod @@ -0,0 +1 @@ +module github.com/mitchellh/go-homedir diff --git a/vendor/github.com/mitchellh/go-homedir/homedir.go b/vendor/github.com/mitchellh/go-homedir/homedir.go new file mode 100644 index 0000000000..25378537ea --- /dev/null +++ b/vendor/github.com/mitchellh/go-homedir/homedir.go @@ -0,0 +1,167 @@ +package homedir + +import ( + "bytes" + "errors" + "os" + "os/exec" + "path/filepath" + "runtime" + "strconv" + "strings" + "sync" +) + +// DisableCache will disable caching of the home directory. Caching is enabled +// by default. +var DisableCache bool + +var homedirCache string +var cacheLock sync.RWMutex + +// Dir returns the home directory for the executing user. +// +// This uses an OS-specific method for discovering the home directory. +// An error is returned if a home directory cannot be detected. +func Dir() (string, error) { + if !DisableCache { + cacheLock.RLock() + cached := homedirCache + cacheLock.RUnlock() + if cached != "" { + return cached, nil + } + } + + cacheLock.Lock() + defer cacheLock.Unlock() + + var result string + var err error + if runtime.GOOS == "windows" { + result, err = dirWindows() + } else { + // Unix-like system, so just assume Unix + result, err = dirUnix() + } + + if err != nil { + return "", err + } + homedirCache = result + return result, nil +} + +// Expand expands the path to include the home directory if the path +// is prefixed with `~`. If it isn't prefixed with `~`, the path is +// returned as-is. +func Expand(path string) (string, error) { + if len(path) == 0 { + return path, nil + } + + if path[0] != '~' { + return path, nil + } + + if len(path) > 1 && path[1] != '/' && path[1] != '\\' { + return "", errors.New("cannot expand user-specific home dir") + } + + dir, err := Dir() + if err != nil { + return "", err + } + + return filepath.Join(dir, path[1:]), nil +} + +// Reset clears the cache, forcing the next call to Dir to re-detect +// the home directory. This generally never has to be called, but can be +// useful in tests if you're modifying the home directory via the HOME +// env var or something. +func Reset() { + cacheLock.Lock() + defer cacheLock.Unlock() + homedirCache = "" +} + +func dirUnix() (string, error) { + homeEnv := "HOME" + if runtime.GOOS == "plan9" { + // On plan9, env vars are lowercase. + homeEnv = "home" + } + + // First prefer the HOME environmental variable + if home := os.Getenv(homeEnv); home != "" { + return home, nil + } + + var stdout bytes.Buffer + + // If that fails, try OS specific commands + if runtime.GOOS == "darwin" { + cmd := exec.Command("sh", "-c", `dscl -q . -read /Users/"$(whoami)" NFSHomeDirectory | sed 's/^[^ ]*: //'`) + cmd.Stdout = &stdout + if err := cmd.Run(); err == nil { + result := strings.TrimSpace(stdout.String()) + if result != "" { + return result, nil + } + } + } else { + cmd := exec.Command("getent", "passwd", strconv.Itoa(os.Getuid())) + cmd.Stdout = &stdout + if err := cmd.Run(); err != nil { + // If the error is ErrNotFound, we ignore it. Otherwise, return it. + if err != exec.ErrNotFound { + return "", err + } + } else { + if passwd := strings.TrimSpace(stdout.String()); passwd != "" { + // username:password:uid:gid:gecos:home:shell + passwdParts := strings.SplitN(passwd, ":", 7) + if len(passwdParts) > 5 { + return passwdParts[5], nil + } + } + } + } + + // If all else fails, try the shell + stdout.Reset() + cmd := exec.Command("sh", "-c", "cd && pwd") + cmd.Stdout = &stdout + if err := cmd.Run(); err != nil { + return "", err + } + + result := strings.TrimSpace(stdout.String()) + if result == "" { + return "", errors.New("blank output when reading home directory") + } + + return result, nil +} + +func dirWindows() (string, error) { + // First prefer the HOME environmental variable + if home := os.Getenv("HOME"); home != "" { + return home, nil + } + + // Prefer standard environment variable USERPROFILE + if home := os.Getenv("USERPROFILE"); home != "" { + return home, nil + } + + drive := os.Getenv("HOMEDRIVE") + path := os.Getenv("HOMEPATH") + home := drive + path + if drive == "" || path == "" { + return "", errors.New("HOMEDRIVE, HOMEPATH, or USERPROFILE are blank") + } + + return home, nil +} diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go index 4e6c4b2362..82da6c6a89 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go @@ -21,6 +21,9 @@ import "github.com/opencontainers/image-spec/specs-go" type Index struct { specs.Versioned + // MediaType specificies the type of this document data structure e.g. `application/vnd.oci.image.index.v1+json` + MediaType string `json:"mediaType,omitempty"` + // Manifests references platform specific manifests. Manifests []Descriptor `json:"manifests"` diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go index 7ff32c40ba..d72d15ce4b 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go @@ -20,6 +20,9 @@ import "github.com/opencontainers/image-spec/specs-go" type Manifest struct { specs.Versioned + // MediaType specificies the type of this document data structure e.g. `application/vnd.oci.image.manifest.v1+json` + MediaType string `json:"mediaType,omitempty"` + // Config references a configuration object for a container, by digest. // The referenced configuration object is a JSON blob that the runtime uses to set up the container. Config Descriptor `json:"config"` diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/version.go b/vendor/github.com/opencontainers/image-spec/specs-go/version.go index 58f1095ab0..31f99cf645 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/version.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/version.go @@ -22,7 +22,7 @@ const ( // VersionMinor is for functionality in a backwards-compatible manner VersionMinor = 0 // VersionPatch is for backwards-compatible bug fixes - VersionPatch = 1 + VersionPatch = 2 // VersionDev indicates development branch. Releases will be empty string. VersionDev = "-dev" diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 4945739ea0..a47b035f9a 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -261,6 +261,7 @@ struct ltchars { #include #include #include +#include #include #include @@ -606,6 +607,7 @@ ccflags="$@" $2 ~ /^MTD/ || $2 ~ /^OTP/ || $2 ~ /^MEM/ || + $2 ~ /^WG/ || $2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)} $2 ~ /^__WCOREFLAG$/ {next} $2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)} diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index d175aae896..bcc45d1085 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -2826,6 +2826,13 @@ const ( WDIOS_TEMPPANIC = 0x4 WDIOS_UNKNOWN = -0x1 WEXITED = 0x4 + WGALLOWEDIP_A_MAX = 0x3 + WGDEVICE_A_MAX = 0x8 + WGPEER_A_MAX = 0xa + WG_CMD_MAX = 0x1 + WG_GENL_NAME = "wireguard" + WG_GENL_VERSION = 0x1 + WG_KEY_LEN = 0x20 WIN_ACKMEDIACHANGE = 0xdb WIN_CHECKPOWERMODE1 = 0xe5 WIN_CHECKPOWERMODE2 = 0x98 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index 37b521436b..f6f0d79c42 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -867,6 +867,7 @@ const ( CTRL_CMD_NEWMCAST_GRP = 0x7 CTRL_CMD_DELMCAST_GRP = 0x8 CTRL_CMD_GETMCAST_GRP = 0x9 + CTRL_CMD_GETPOLICY = 0xa CTRL_ATTR_UNSPEC = 0x0 CTRL_ATTR_FAMILY_ID = 0x1 CTRL_ATTR_FAMILY_NAME = 0x2 @@ -875,12 +876,19 @@ const ( CTRL_ATTR_MAXATTR = 0x5 CTRL_ATTR_OPS = 0x6 CTRL_ATTR_MCAST_GROUPS = 0x7 + CTRL_ATTR_POLICY = 0x8 + CTRL_ATTR_OP_POLICY = 0x9 + CTRL_ATTR_OP = 0xa CTRL_ATTR_OP_UNSPEC = 0x0 CTRL_ATTR_OP_ID = 0x1 CTRL_ATTR_OP_FLAGS = 0x2 CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 CTRL_ATTR_MCAST_GRP_NAME = 0x1 CTRL_ATTR_MCAST_GRP_ID = 0x2 + CTRL_ATTR_POLICY_UNSPEC = 0x0 + CTRL_ATTR_POLICY_DO = 0x1 + CTRL_ATTR_POLICY_DUMP = 0x2 + CTRL_ATTR_POLICY_DUMP_MAX = 0x2 ) const ( @@ -3968,3 +3976,70 @@ type MountAttr struct { Propagation uint64 Userns_fd uint64 } + +const ( + WG_CMD_GET_DEVICE = 0x0 + WG_CMD_SET_DEVICE = 0x1 + WGDEVICE_F_REPLACE_PEERS = 0x1 + WGDEVICE_A_UNSPEC = 0x0 + WGDEVICE_A_IFINDEX = 0x1 + WGDEVICE_A_IFNAME = 0x2 + WGDEVICE_A_PRIVATE_KEY = 0x3 + WGDEVICE_A_PUBLIC_KEY = 0x4 + WGDEVICE_A_FLAGS = 0x5 + WGDEVICE_A_LISTEN_PORT = 0x6 + WGDEVICE_A_FWMARK = 0x7 + WGDEVICE_A_PEERS = 0x8 + WGPEER_F_REMOVE_ME = 0x1 + WGPEER_F_REPLACE_ALLOWEDIPS = 0x2 + WGPEER_F_UPDATE_ONLY = 0x4 + WGPEER_A_UNSPEC = 0x0 + WGPEER_A_PUBLIC_KEY = 0x1 + WGPEER_A_PRESHARED_KEY = 0x2 + WGPEER_A_FLAGS = 0x3 + WGPEER_A_ENDPOINT = 0x4 + WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL = 0x5 + WGPEER_A_LAST_HANDSHAKE_TIME = 0x6 + WGPEER_A_RX_BYTES = 0x7 + WGPEER_A_TX_BYTES = 0x8 + WGPEER_A_ALLOWEDIPS = 0x9 + WGPEER_A_PROTOCOL_VERSION = 0xa + WGALLOWEDIP_A_UNSPEC = 0x0 + WGALLOWEDIP_A_FAMILY = 0x1 + WGALLOWEDIP_A_IPADDR = 0x2 + WGALLOWEDIP_A_CIDR_MASK = 0x3 +) + +const ( + NL_ATTR_TYPE_INVALID = 0x0 + NL_ATTR_TYPE_FLAG = 0x1 + NL_ATTR_TYPE_U8 = 0x2 + NL_ATTR_TYPE_U16 = 0x3 + NL_ATTR_TYPE_U32 = 0x4 + NL_ATTR_TYPE_U64 = 0x5 + NL_ATTR_TYPE_S8 = 0x6 + NL_ATTR_TYPE_S16 = 0x7 + NL_ATTR_TYPE_S32 = 0x8 + NL_ATTR_TYPE_S64 = 0x9 + NL_ATTR_TYPE_BINARY = 0xa + NL_ATTR_TYPE_STRING = 0xb + NL_ATTR_TYPE_NUL_STRING = 0xc + NL_ATTR_TYPE_NESTED = 0xd + NL_ATTR_TYPE_NESTED_ARRAY = 0xe + NL_ATTR_TYPE_BITFIELD32 = 0xf + + NL_POLICY_TYPE_ATTR_UNSPEC = 0x0 + NL_POLICY_TYPE_ATTR_TYPE = 0x1 + NL_POLICY_TYPE_ATTR_MIN_VALUE_S = 0x2 + NL_POLICY_TYPE_ATTR_MAX_VALUE_S = 0x3 + NL_POLICY_TYPE_ATTR_MIN_VALUE_U = 0x4 + NL_POLICY_TYPE_ATTR_MAX_VALUE_U = 0x5 + NL_POLICY_TYPE_ATTR_MIN_LENGTH = 0x6 + NL_POLICY_TYPE_ATTR_MAX_LENGTH = 0x7 + NL_POLICY_TYPE_ATTR_POLICY_IDX = 0x8 + NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE = 0x9 + NL_POLICY_TYPE_ATTR_BITFIELD32_MASK = 0xa + NL_POLICY_TYPE_ATTR_PAD = 0xb + NL_POLICY_TYPE_ATTR_MASK = 0xc + NL_POLICY_TYPE_ATTR_MAX = 0xc +) diff --git a/vendor/golang.org/x/sys/windows/exec_windows.go b/vendor/golang.org/x/sys/windows/exec_windows.go index 7a11e83b7e..855698bb28 100644 --- a/vendor/golang.org/x/sys/windows/exec_windows.go +++ b/vendor/golang.org/x/sys/windows/exec_windows.go @@ -9,8 +9,6 @@ package windows import ( errorspkg "errors" "unsafe" - - "golang.org/x/sys/internal/unsafeheader" ) // EscapeArg rewrites command line argument s as prescribed @@ -147,8 +145,12 @@ func NewProcThreadAttributeList(maxAttrCount uint32) (*ProcThreadAttributeListCo } return nil, err } + alloc, err := LocalAlloc(LMEM_FIXED, uint32(size)) + if err != nil { + return nil, err + } // size is guaranteed to be ≥1 by InitializeProcThreadAttributeList. - al := &ProcThreadAttributeListContainer{data: (*ProcThreadAttributeList)(unsafe.Pointer(&make([]byte, size)[0]))} + al := &ProcThreadAttributeListContainer{data: (*ProcThreadAttributeList)(unsafe.Pointer(alloc))} err = initializeProcThreadAttributeList(al.data, maxAttrCount, 0, &size) if err != nil { return nil, err @@ -157,36 +159,17 @@ func NewProcThreadAttributeList(maxAttrCount uint32) (*ProcThreadAttributeListCo } // Update modifies the ProcThreadAttributeList using UpdateProcThreadAttribute. -// Note that the value passed to this function will be copied into memory -// allocated by LocalAlloc, the contents of which should not contain any -// Go-managed pointers, even if the passed value itself is a Go-managed -// pointer. func (al *ProcThreadAttributeListContainer) Update(attribute uintptr, value unsafe.Pointer, size uintptr) error { - alloc, err := LocalAlloc(LMEM_FIXED, uint32(size)) - if err != nil { - return err - } - var src, dst []byte - hdr := (*unsafeheader.Slice)(unsafe.Pointer(&src)) - hdr.Data = value - hdr.Cap = int(size) - hdr.Len = int(size) - hdr = (*unsafeheader.Slice)(unsafe.Pointer(&dst)) - hdr.Data = unsafe.Pointer(alloc) - hdr.Cap = int(size) - hdr.Len = int(size) - copy(dst, src) - al.heapAllocations = append(al.heapAllocations, alloc) - return updateProcThreadAttribute(al.data, 0, attribute, unsafe.Pointer(alloc), size, nil, nil) + al.pointers = append(al.pointers, value) + return updateProcThreadAttribute(al.data, 0, attribute, value, size, nil, nil) } // Delete frees ProcThreadAttributeList's resources. func (al *ProcThreadAttributeListContainer) Delete() { deleteProcThreadAttributeList(al.data) - for i := range al.heapAllocations { - LocalFree(Handle(al.heapAllocations[i])) - } - al.heapAllocations = nil + LocalFree(Handle(unsafe.Pointer(al.data))) + al.data = nil + al.pointers = nil } // List returns the actual ProcThreadAttributeList to be passed to StartupInfoEx. diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 73087bf5e5..bb31abda41 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -938,8 +938,8 @@ type StartupInfoEx struct { type ProcThreadAttributeList struct{} type ProcThreadAttributeListContainer struct { - data *ProcThreadAttributeList - heapAllocations []uintptr + data *ProcThreadAttributeList + pointers []unsafe.Pointer } type ProcessInformation struct { @@ -2749,6 +2749,43 @@ type PROCESS_BASIC_INFORMATION struct { InheritedFromUniqueProcessId uintptr } +type SYSTEM_PROCESS_INFORMATION struct { + NextEntryOffset uint32 + NumberOfThreads uint32 + WorkingSetPrivateSize int64 + HardFaultCount uint32 + NumberOfThreadsHighWatermark uint32 + CycleTime uint64 + CreateTime int64 + UserTime int64 + KernelTime int64 + ImageName NTUnicodeString + BasePriority int32 + UniqueProcessID uintptr + InheritedFromUniqueProcessID uintptr + HandleCount uint32 + SessionID uint32 + UniqueProcessKey *uint32 + PeakVirtualSize uintptr + VirtualSize uintptr + PageFaultCount uint32 + PeakWorkingSetSize uintptr + WorkingSetSize uintptr + QuotaPeakPagedPoolUsage uintptr + QuotaPagedPoolUsage uintptr + QuotaPeakNonPagedPoolUsage uintptr + QuotaNonPagedPoolUsage uintptr + PagefileUsage uintptr + PeakPagefileUsage uintptr + PrivatePageCount uintptr + ReadOperationCount int64 + WriteOperationCount int64 + OtherOperationCount int64 + ReadTransferCount int64 + WriteTransferCount int64 + OtherTransferCount int64 +} + // SystemInformationClasses for NtQuerySystemInformation and NtSetSystemInformation const ( SystemBasicInformation = iota diff --git a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go index fc8beea5d8..cec819d641 100644 --- a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go +++ b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go @@ -50,11 +50,24 @@ func Find(importPath, srcDir string) (filename, path string) { // additional trailing data beyond the end of the export data. func NewReader(r io.Reader) (io.Reader, error) { buf := bufio.NewReader(r) - _, err := gcimporter.FindExportData(buf) - // If we ever switch to a zip-like archive format with the ToC - // at the end, we can return the correct portion of export data, - // but for now we must return the entire rest of the file. - return buf, err + _, size, err := gcimporter.FindExportData(buf) + if err != nil { + return nil, err + } + + if size >= 0 { + // We were given an archive and found the __.PKGDEF in it. + // This tells us the size of the export data, and we don't + // need to return the entire file. + return &io.LimitedReader{ + R: buf, + N: size, + }, nil + } else { + // We were given an object file. As such, we don't know how large + // the export data is and must return the entire file. + return buf, nil + } } // Read reads export data from in, decodes it, and returns type diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go index 072005af89..0a3cdb9a3b 100644 --- a/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go @@ -34,9 +34,6 @@ import ( // (suspected) format errors, and whenever a change is made to the format. const debugFormat = false // default: false -// If trace is set, debugging output is printed to std out. -const trace = false // default: false - // Current export format version. Increase with each format change. // Note: The latest binary (non-indexed) export format is at version 6. // This exporter is still at level 4, but it doesn't matter since diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go index b023120001..b85de01470 100644 --- a/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go @@ -74,9 +74,10 @@ func BImportData(fset *token.FileSet, imports map[string]*types.Package, data [] pathList: []string{""}, // empty string is mapped to 0 fake: fakeFileSet{ fset: fset, - files: make(map[string]*token.File), + files: make(map[string]*fileInfo), }, } + defer p.fake.setLines() // set lines for files in fset // read version info var versionstr string @@ -338,37 +339,49 @@ func (p *importer) pos() token.Pos { // Synthesize a token.Pos type fakeFileSet struct { fset *token.FileSet - files map[string]*token.File + files map[string]*fileInfo } +type fileInfo struct { + file *token.File + lastline int +} + +const maxlines = 64 * 1024 + func (s *fakeFileSet) pos(file string, line, column int) token.Pos { // TODO(mdempsky): Make use of column. - // Since we don't know the set of needed file positions, we - // reserve maxlines positions per file. - const maxlines = 64 * 1024 + // Since we don't know the set of needed file positions, we reserve maxlines + // positions per file. We delay calling token.File.SetLines until all + // positions have been calculated (by way of fakeFileSet.setLines), so that + // we can avoid setting unnecessary lines. See also golang/go#46586. f := s.files[file] if f == nil { - f = s.fset.AddFile(file, -1, maxlines) + f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)} s.files[file] = f - // Allocate the fake linebreak indices on first use. - // TODO(adonovan): opt: save ~512KB using a more complex scheme? - fakeLinesOnce.Do(func() { - fakeLines = make([]int, maxlines) - for i := range fakeLines { - fakeLines[i] = i - } - }) - f.SetLines(fakeLines) } - if line > maxlines { line = 1 } + if line > f.lastline { + f.lastline = line + } - // Treat the file as if it contained only newlines - // and column=1: use the line number as the offset. - return f.Pos(line - 1) + // Return a fake position assuming that f.file consists only of newlines. + return token.Pos(f.file.Base() + line - 1) +} + +func (s *fakeFileSet) setLines() { + fakeLinesOnce.Do(func() { + fakeLines = make([]int, maxlines) + for i := range fakeLines { + fakeLines[i] = i + } + }) + for _, f := range s.files { + f.file.SetLines(fakeLines[:f.lastline]) + } } var ( diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go b/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go index f33dc5613e..f6437feb1c 100644 --- a/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go @@ -16,7 +16,7 @@ import ( "strings" ) -func readGopackHeader(r *bufio.Reader) (name string, size int, err error) { +func readGopackHeader(r *bufio.Reader) (name string, size int64, err error) { // See $GOROOT/include/ar.h. hdr := make([]byte, 16+12+6+6+8+10+2) _, err = io.ReadFull(r, hdr) @@ -28,7 +28,8 @@ func readGopackHeader(r *bufio.Reader) (name string, size int, err error) { fmt.Printf("header: %s", hdr) } s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10])) - size, err = strconv.Atoi(s) + length, err := strconv.Atoi(s) + size = int64(length) if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' { err = fmt.Errorf("invalid archive header") return @@ -42,8 +43,8 @@ func readGopackHeader(r *bufio.Reader) (name string, size int, err error) { // file by reading from it. The reader must be positioned at the // start of the file before calling this function. The hdr result // is the string before the export data, either "$$" or "$$B". -// -func FindExportData(r *bufio.Reader) (hdr string, err error) { +// The size result is the length of the export data in bytes, or -1 if not known. +func FindExportData(r *bufio.Reader) (hdr string, size int64, err error) { // Read first line to make sure this is an object file. line, err := r.ReadSlice('\n') if err != nil { @@ -54,7 +55,7 @@ func FindExportData(r *bufio.Reader) (hdr string, err error) { if string(line) == "!\n" { // Archive file. Scan to __.PKGDEF. var name string - if name, _, err = readGopackHeader(r); err != nil { + if name, size, err = readGopackHeader(r); err != nil { return } @@ -70,6 +71,7 @@ func FindExportData(r *bufio.Reader) (hdr string, err error) { err = fmt.Errorf("can't find export data (%v)", err) return } + size -= int64(len(line)) } // Now at __.PKGDEF in archive or still at beginning of file. @@ -86,8 +88,12 @@ func FindExportData(r *bufio.Reader) (hdr string, err error) { err = fmt.Errorf("can't find export data (%v)", err) return } + size -= int64(len(line)) } hdr = string(line) + if size < 0 { + size = -1 + } return } diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go index e8cba6b237..3ab66830d7 100644 --- a/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go @@ -29,8 +29,14 @@ import ( "text/scanner" ) -// debugging/development support -const debug = false +const ( + // Enable debug during development: it adds some additional checks, and + // prevents errors from being recovered. + debug = false + + // If trace is set, debugging output is printed to std out. + trace = false +) var pkgExts = [...]string{".a", ".o"} @@ -179,7 +185,7 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func var hdr string buf := bufio.NewReader(rc) - if hdr, err = FindExportData(buf); err != nil { + if hdr, _, err = FindExportData(buf); err != nil { return } diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go index be8b7459af..b4d51f352f 100644 --- a/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go @@ -11,6 +11,7 @@ package gcimporter import ( "bytes" "encoding/binary" + "fmt" "go/ast" "go/constant" "go/token" @@ -19,6 +20,7 @@ import ( "math/big" "reflect" "sort" + "strings" "golang.org/x/tools/internal/typeparams" ) @@ -33,15 +35,15 @@ const bundleVersion = 0 // The package path of the top-level package will not be recorded, // so that calls to IImportData can override with a provided package path. func IExportData(out io.Writer, fset *token.FileSet, pkg *types.Package) error { - return iexportCommon(out, fset, false, []*types.Package{pkg}) + return iexportCommon(out, fset, false, iexportVersion, []*types.Package{pkg}) } // IExportBundle writes an indexed export bundle for pkgs to out. func IExportBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error { - return iexportCommon(out, fset, true, pkgs) + return iexportCommon(out, fset, true, iexportVersion, pkgs) } -func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*types.Package) (err error) { +func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, version int, pkgs []*types.Package) (err error) { if !debug { defer func() { if e := recover(); e != nil { @@ -57,9 +59,11 @@ func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*type p := iexporter{ fset: fset, + version: version, allPkgs: map[*types.Package]bool{}, stringIndex: map[string]uint64{}, declIndex: map[types.Object]uint64{}, + tparamNames: map[types.Object]string{}, typIndex: map[types.Type]uint64{}, } if !bundle { @@ -119,7 +123,7 @@ func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*type if bundle { hdr.uint64(bundleVersion) } - hdr.uint64(iexportVersion) + hdr.uint64(uint64(p.version)) hdr.uint64(uint64(p.strings.Len())) hdr.uint64(dataLen) @@ -136,8 +140,12 @@ func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*type // non-compiler tools and includes a complete package description // (i.e., name and height). func (w *exportWriter) writeIndex(index map[types.Object]uint64) { + type pkgObj struct { + obj types.Object + name string // qualified name; differs from obj.Name for type params + } // Build a map from packages to objects from that package. - pkgObjs := map[*types.Package][]types.Object{} + pkgObjs := map[*types.Package][]pkgObj{} // For the main index, make sure to include every package that // we reference, even if we're not exporting (or reexporting) @@ -150,7 +158,8 @@ func (w *exportWriter) writeIndex(index map[types.Object]uint64) { } for obj := range index { - pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], obj) + name := w.p.indexName(obj) + pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], pkgObj{obj, name}) } var pkgs []*types.Package @@ -158,7 +167,7 @@ func (w *exportWriter) writeIndex(index map[types.Object]uint64) { pkgs = append(pkgs, pkg) sort.Slice(objs, func(i, j int) bool { - return indexName(objs[i]) < indexName(objs[j]) + return objs[i].name < objs[j].name }) } @@ -175,29 +184,26 @@ func (w *exportWriter) writeIndex(index map[types.Object]uint64) { objs := pkgObjs[pkg] w.uint64(uint64(len(objs))) for _, obj := range objs { - w.string(indexName(obj)) - w.uint64(index[obj]) + w.string(obj.name) + w.uint64(index[obj.obj]) } } } // indexName returns the 'indexed' name of an object. It differs from -// obj.Name() only for type parameter names, where we include the subscripted -// type parameter ID. -// -// TODO(rfindley): remove this once we no longer need subscripts. -func indexName(obj types.Object) (res string) { - if _, ok := obj.(*types.TypeName); ok { - if tparam, ok := obj.Type().(*typeparams.TypeParam); ok { - return types.TypeString(tparam, func(*types.Package) string { return "" }) - } +// obj.Name() only for type parameter names, where the name is qualified by +// owner. +func (p *iexporter) indexName(obj types.Object) (res string) { + if name := p.tparamNames[obj]; name != "" { + return name } return obj.Name() } type iexporter struct { - fset *token.FileSet - out *bytes.Buffer + fset *token.FileSet + out *bytes.Buffer + version int localpkg *types.Package @@ -211,9 +217,21 @@ type iexporter struct { strings intWriter stringIndex map[string]uint64 - data0 intWriter - declIndex map[types.Object]uint64 - typIndex map[types.Type]uint64 + data0 intWriter + declIndex map[types.Object]uint64 + tparamNames map[types.Object]string // typeparam->qualified name + typIndex map[types.Type]uint64 + + indent int // for tracing support +} + +func (p *iexporter) trace(format string, args ...interface{}) { + if !trace { + // Call sites should also be guarded, but having this check here allows + // easily enabling/disabling debug trace statements. + return + } + fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) } // stringOff returns the offset of s within the string section. @@ -239,7 +257,7 @@ func (p *iexporter) pushDecl(obj types.Object) { return } - p.declIndex[obj] = ^uint64(0) // mark n present in work queue + p.declIndex[obj] = ^uint64(0) // mark obj present in work queue p.declTodo.pushTail(obj) } @@ -262,6 +280,14 @@ func (w *exportWriter) exportPath(pkg *types.Package) string { } func (p *iexporter) doDecl(obj types.Object) { + if trace { + p.trace("exporting decl %v (%T)", obj, obj) + p.indent++ + defer func() { + p.indent-- + p.trace("=> %s", obj) + }() + } w := p.newWriter() w.setPkg(obj.Pkg(), false) @@ -291,7 +317,7 @@ func (p *iexporter) doDecl(obj types.Object) { // other places in the signature and function that they // are used. if tparams := typeparams.ForSignature(sig); tparams.Len() > 0 { - w.tparamList(tparams, obj.Pkg()) + w.tparamList(obj, tparams, obj.Pkg()) } w.signature(sig) @@ -306,7 +332,15 @@ func (p *iexporter) doDecl(obj types.Object) { if tparam, ok := t.(*typeparams.TypeParam); ok { w.tag('P') w.pos(obj.Pos()) - w.typ(tparam.Constraint(), obj.Pkg()) + constraint := tparam.Constraint() + if p.version >= iexportVersionGo1_18 { + implicit := false + if iface, _ := constraint.(*types.Interface); iface != nil { + implicit = typeparams.IsImplicit(iface) + } + w.bool(implicit) + } + w.typ(constraint, obj.Pkg()) break } @@ -331,7 +365,7 @@ func (p *iexporter) doDecl(obj types.Object) { w.pos(obj.Pos()) if typeparams.ForNamed(named).Len() > 0 { - w.tparamList(typeparams.ForNamed(named), obj.Pkg()) + w.tparamList(obj, typeparams.ForNamed(named), obj.Pkg()) } underlying := obj.Type().Underlying() @@ -348,6 +382,15 @@ func (p *iexporter) doDecl(obj types.Object) { w.pos(m.Pos()) w.string(m.Name()) sig, _ := m.Type().(*types.Signature) + + // Receiver type parameters are type arguments of the receiver type, so + // their name must be qualified before exporting recv. + rparams := typeparams.RecvTypeParams(sig) + for i := 0; i < rparams.Len(); i++ { + rparam := rparams.At(i) + name := obj.Name() + "." + m.Name() + "." + rparam.Obj().Name() + w.p.tparamNames[rparam.Obj()] = name + } w.param(sig.Recv()) w.signature(sig) } @@ -364,7 +407,7 @@ func (w *exportWriter) tag(tag byte) { } func (w *exportWriter) pos(pos token.Pos) { - if iexportVersion >= iexportVersionPosCol { + if w.p.version >= iexportVersionPosCol { w.posV1(pos) } else { w.posV0(pos) @@ -447,9 +490,11 @@ func (w *exportWriter) pkg(pkg *types.Package) { } func (w *exportWriter) qualifiedIdent(obj types.Object) { + name := w.p.indexName(obj) + // Ensure any referenced declarations are written out too. w.p.pushDecl(obj) - w.string(indexName(obj)) + w.string(name) w.pkg(obj.Pkg()) } @@ -483,6 +528,14 @@ func (w *exportWriter) startType(k itag) { } func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) { + if trace { + w.p.trace("exporting type %s (%T)", t, t) + w.p.indent++ + defer func() { + w.p.indent-- + w.p.trace("=> %s", t) + }() + } switch t := t.(type) { case *types.Named: if targs := typeparams.NamedTypeArgs(t); targs.Len() > 0 { @@ -619,10 +672,14 @@ func (w *exportWriter) typeList(ts *typeparams.TypeList, pkg *types.Package) { } } -func (w *exportWriter) tparamList(list *typeparams.TypeParamList, pkg *types.Package) { +func (w *exportWriter) tparamList(owner types.Object, list *typeparams.TypeParamList, pkg *types.Package) { ll := uint64(list.Len()) w.uint64(ll) for i := 0; i < list.Len(); i++ { + tparam := list.At(i) + // Qualify the type parameter name before exporting its type. + name := owner.Name() + "." + tparam.Obj().Name() + w.p.tparamNames[tparam.Obj()] = name w.typ(list.At(i), pkg) } } @@ -643,6 +700,9 @@ func (w *exportWriter) param(obj types.Object) { func (w *exportWriter) value(typ types.Type, v constant.Value) { w.typ(typ, nil) + if w.p.version >= iexportVersionGo1_18 { + w.int64(int64(v.Kind())) + } switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { case types.IsBoolean: @@ -832,7 +892,7 @@ func (w *exportWriter) localIdent(obj types.Object) { return } - name := indexName(obj) + name := obj.Name() if name == "_" { w.string("_") return diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go index 8843db0198..cdb332cd15 100644 --- a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go @@ -45,13 +45,20 @@ func (r *intReader) uint64() uint64 { } // Keep this in sync with constants in iexport.go. +// +// Temporarily, the x/tools importer accepts generic code at both version 1 and +// 2. However, version 2 contains some breaking changes on top of version 1: +// - the 'implicit' bit is added to exported constraints +// - a 'kind' byte is added to constant values (not yet done) +// +// Once we've completed the bump to version 2 in the standard library, we'll +// remove support for generics here at version 1. const ( iexportVersionGo1_11 = 0 iexportVersionPosCol = 1 + iexportVersionGo1_18 = 2 // TODO: before release, change this back to 2. iexportVersionGenerics = iexportVersionPosCol - - iexportVersionCurrent = iexportVersionGenerics ) type ident struct { @@ -124,9 +131,9 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data version = int64(r.uint64()) switch version { - case /* iexportVersionGenerics, */ iexportVersionPosCol, iexportVersionGo1_11: + case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11: default: - if version > iexportVersionGenerics { + if version > iexportVersionGo1_18 { errorf("unstable iexport format version %d, just rebuild compiler and std library", version) } else { errorf("unknown iexport format version %d", version) @@ -142,9 +149,8 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data r.Seek(sLen+dLen, io.SeekCurrent) p := iimporter{ - exportVersion: version, - ipath: path, - version: int(version), + version: int(version), + ipath: path, stringData: stringData, stringCache: make(map[uint64]string), @@ -154,14 +160,15 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data pkgIndex: make(map[*types.Package]map[string]uint64), typCache: make(map[uint64]types.Type), // Separate map for typeparams, keyed by their package and unique - // name (name with subscript). + // name. tparamIndex: make(map[ident]types.Type), fake: fakeFileSet{ fset: fset, - files: make(map[string]*token.File), + files: make(map[string]*fileInfo), }, } + defer p.fake.setLines() // set lines for files in fset for i, pt := range predeclared() { p.typCache[uint64(i)] = pt @@ -247,9 +254,8 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data } type iimporter struct { - exportVersion int64 - ipath string - version int + version int + ipath string stringData []byte stringCache map[uint64]string @@ -262,9 +268,28 @@ type iimporter struct { fake fakeFileSet interfaceList []*types.Interface + + indent int // for tracing support +} + +func (p *iimporter) trace(format string, args ...interface{}) { + if !trace { + // Call sites should also be guarded, but having this check here allows + // easily enabling/disabling debug trace statements. + return + } + fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) } func (p *iimporter) doDecl(pkg *types.Package, name string) { + if debug { + p.trace("import decl %s", name) + p.indent++ + defer func() { + p.indent-- + p.trace("=> %s", name) + }() + } // See if we've already imported this declaration. if obj := pkg.Scope().Lookup(name); obj != nil { return @@ -306,7 +331,7 @@ func (p *iimporter) pkgAt(off uint64) *types.Package { } func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { - if t, ok := p.typCache[off]; ok && (base == nil || !isInterface(t)) { + if t, ok := p.typCache[off]; ok && canReuse(base, t) { return t } @@ -318,12 +343,30 @@ func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { r.declReader.Reset(p.declData[off-predeclReserved:]) t := r.doType(base) - if base == nil || !isInterface(t) { + if canReuse(base, t) { p.typCache[off] = t } return t } +// canReuse reports whether the type rhs on the RHS of the declaration for def +// may be re-used. +// +// Specifically, if def is non-nil and rhs is an interface type with methods, it +// may not be re-used because we have a convention of setting the receiver type +// for interface methods to def. +func canReuse(def *types.Named, rhs types.Type) bool { + if def == nil { + return true + } + iface, _ := rhs.(*types.Interface) + if iface == nil { + return true + } + // Don't use iface.Empty() here as iface may not be complete. + return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0 +} + type importReader struct { p *iimporter declReader bytes.Reader @@ -381,15 +424,13 @@ func (r *importReader) obj(name string) { // If the receiver has any targs, set those as the // rparams of the method (since those are the // typeparams being used in the method sig/body). - targs := typeparams.NamedTypeArgs(baseType(recv.Type())) + base := baseType(recv.Type()) + assert(base != nil) + targs := typeparams.NamedTypeArgs(base) var rparams []*typeparams.TypeParam if targs.Len() > 0 { - rparams := make([]*typeparams.TypeParam, targs.Len()) + rparams = make([]*typeparams.TypeParam, targs.Len()) for i := range rparams { - // TODO(rfindley): this is less tolerant than the standard library - // go/internal/gcimporter, which calls under(...) and is tolerant - // of nil rparams. Bring them in sync by making the standard - // library importer stricter. rparams[i] = targs.At(i).(*typeparams.TypeParam) } } @@ -403,34 +444,35 @@ func (r *importReader) obj(name string) { // We need to "declare" a typeparam in order to have a name that // can be referenced recursively (if needed) in the type param's // bound. - if r.p.exportVersion < iexportVersionGenerics { + if r.p.version < iexportVersionGenerics { errorf("unexpected type param type") } - // Temporarily strip both type parameter subscripts and path prefixes, - // while we replace subscripts with prefixes in the compiler. - // TODO(rfindley): remove support for subscripts once the compiler changes - // have landed. - name0, _ := parseSubscript(name) + // Remove the "path" from the type param name that makes it unique ix := strings.LastIndex(name, ".") - name0 = name0[ix+1:] + if ix < 0 { + errorf("missing path for type param") + } + name0 := name[ix+1:] tn := types.NewTypeName(pos, r.currPkg, name0, nil) t := typeparams.NewTypeParam(tn, nil) - // The check below is disabled so that we can support both path-prefixed - // and subscripted type parameter names. - // if sub == 0 { - // errorf("name %q missing subscript", name) - // } - - // TODO(rfindley): can we use a different, stable ID? - // t.SetId(sub) - // To handle recursive references to the typeparam within its // bound, save the partial type in tparamIndex before reading the bounds. id := ident{r.currPkg.Name(), name} r.p.tparamIndex[id] = t - - typeparams.SetTypeParamConstraint(t, r.typ()) + var implicit bool + if r.p.version >= iexportVersionGo1_18 { + implicit = r.bool() + } + constraint := r.typ() + if implicit { + iface, _ := constraint.(*types.Interface) + if iface == nil { + errorf("non-interface constraint marked implicit") + } + typeparams.MarkImplicit(iface) + } + typeparams.SetTypeParamConstraint(t, constraint) case 'V': typ := r.typ() @@ -448,6 +490,10 @@ func (r *importReader) declare(obj types.Object) { func (r *importReader) value() (typ types.Type, val constant.Value) { typ = r.typ() + if r.p.version >= iexportVersionGo1_18 { + // TODO: add support for using the kind. + _ = constant.Kind(r.int64()) + } switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { case types.IsBoolean: @@ -590,7 +636,7 @@ func (r *importReader) qualifiedIdent() (*types.Package, string) { } func (r *importReader) pos() token.Pos { - if r.p.exportVersion >= iexportVersionPosCol { + if r.p.version >= iexportVersionPosCol { r.posv1() } else { r.posv0() @@ -638,8 +684,17 @@ func isInterface(t types.Type) bool { func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) } func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } -func (r *importReader) doType(base *types.Named) types.Type { - switch k := r.kind(); k { +func (r *importReader) doType(base *types.Named) (res types.Type) { + k := r.kind() + if debug { + r.p.trace("importing type %d (base: %s)", k, base) + r.p.indent++ + defer func() { + r.p.indent-- + r.p.trace("=> %s", res) + }() + } + switch k { default: errorf("unexpected kind tag in %q: %v", r.p.ipath, k) return nil @@ -711,7 +766,7 @@ func (r *importReader) doType(base *types.Named) types.Type { return typ case typeParamType: - if r.p.exportVersion < iexportVersionGenerics { + if r.p.version < iexportVersionGenerics { errorf("unexpected type param type") } pkg, name := r.qualifiedIdent() @@ -725,7 +780,7 @@ func (r *importReader) doType(base *types.Named) types.Type { return r.p.tparamIndex[id] case instanceType: - if r.p.exportVersion < iexportVersionGenerics { + if r.p.version < iexportVersionGenerics { errorf("unexpected instantiation type") } // pos does not matter for instances: they are positioned on the original @@ -744,7 +799,7 @@ func (r *importReader) doType(base *types.Named) types.Type { return t case unionType: - if r.p.exportVersion < iexportVersionGenerics { + if r.p.version < iexportVersionGenerics { errorf("unexpected instantiation type") } terms := make([]*typeparams.Term, r.uint64()) @@ -832,23 +887,3 @@ func baseType(typ types.Type) *types.Named { n, _ := typ.(*types.Named) return n } - -func parseSubscript(name string) (string, uint64) { - // Extract the subscript value from the type param name. We export - // and import the subscript value, so that all type params have - // unique names. - sub := uint64(0) - startsub := -1 - for i, r := range name { - if '₀' <= r && r < '₀'+10 { - if startsub == -1 { - startsub = i - } - sub = sub*10 + uint64(r-'₀') - } - } - if startsub >= 0 { - name = name[:startsub] - } - return name, sub -} diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go b/vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go index 2c98f0acbb..a993843230 100644 --- a/vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go @@ -16,5 +16,8 @@ func additionalPredeclared() []types.Type { return []types.Type{ // comparable types.Universe.Lookup("comparable").Type(), + + // any + types.Universe.Lookup("any").Type(), } } diff --git a/vendor/golang.org/x/tools/internal/typeparams/common.go b/vendor/golang.org/x/tools/internal/typeparams/common.go index 9fc6b4beb8..961d036fdb 100644 --- a/vendor/golang.org/x/tools/internal/typeparams/common.go +++ b/vendor/golang.org/x/tools/internal/typeparams/common.go @@ -13,6 +13,7 @@ package typeparams import ( "go/ast" "go/token" + "go/types" ) // A IndexExprData holds data from both ast.IndexExpr and the new @@ -23,3 +24,9 @@ type IndexExprData struct { Indices []ast.Expr // index expressions Rbrack token.Pos // position of "]" } + +// IsTypeParam reports whether t is a type parameter. +func IsTypeParam(t types.Type) bool { + _, ok := t.(*TypeParam) + return ok +} diff --git a/vendor/golang.org/x/tools/internal/typeparams/normalize.go b/vendor/golang.org/x/tools/internal/typeparams/normalize.go index ef3dbab52a..090f142a5f 100644 --- a/vendor/golang.org/x/tools/internal/typeparams/normalize.go +++ b/vendor/golang.org/x/tools/internal/typeparams/normalize.go @@ -5,6 +5,7 @@ package typeparams import ( + "errors" "fmt" "go/types" "os" @@ -15,54 +16,96 @@ import ( const debug = false -// NormalizeInterface returns the normal form of the interface iface, or nil if iface -// has an empty type set (i.e. there are no types that satisfy iface). If the -// resulting interface is non-nil, it will be identical to iface. +var ErrEmptyTypeSet = errors.New("empty type set") + +// StructuralTerms returns a slice of terms representing the normalized +// structural type restrictions of a type parameter, if any. +// +// Structural type restrictions of a type parameter are created via +// non-interface types embedded in its constraint interface (directly, or via a +// chain of interface embeddings). For example, in the declaration +// type T[P interface{~int; m()}] int +// the structural restriction of the type parameter P is ~int. +// +// With interface embedding and unions, the specification of structural type +// restrictions may be arbitrarily complex. For example, consider the +// following: +// +// type A interface{ ~string|~[]byte } +// +// type B interface{ int|string } +// +// type C interface { ~string|~int } +// +// type T[P interface{ A|B; C }] int // -// An error is returned if the interface type is invalid, or too complicated to -// reasonably normalize (for example, contains unions with more than a hundred -// terms). +// In this example, the structural type restriction of P is ~string|int: A|B +// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, +// which when intersected with C (~string|~int) yields ~string|int. // -// An interface is in normal form if and only if: -// - it has 0 or 1 embedded types. -// - its embedded type is either a types.Union or has a concrete -// (non-interface) underlying type -// - if the embedded type is a union, each term of the union has a concrete -// underlying type, and no terms may be removed without changing the type set -// of the interface -func NormalizeInterface(iface *types.Interface) (*types.Interface, error) { - var methods []*types.Func - for i := 0; i < iface.NumMethods(); i++ { - methods = append(methods, iface.Method(i)) +// StructuralTerms computes these expansions and reductions, producing a +// "normalized" form of the embeddings. A structural restriction is normalized +// if it is a single union containing no interface terms, and is minimal in the +// sense that removing any term changes the set of types satisfying the +// constraint. It is left as a proof for the reader that, modulo sorting, there +// is exactly one such normalized form. +// +// Because the minimal representation always takes this form, StructuralTerms +// returns a slice of tilde terms corresponding to the terms of the union in +// the normalized structural restriction. An error is returned if the +// constraint interface is invalid, exceeds complexity bounds, or has an empty +// type set. In the latter case, StructuralTerms returns ErrEmptyTypeSet. +// +// StructuralTerms makes no guarantees about the order of terms, except that it +// is deterministic. +func StructuralTerms(tparam *TypeParam) ([]*Term, error) { + constraint := tparam.Constraint() + if constraint == nil { + return nil, fmt.Errorf("%s has nil constraint", tparam) + } + iface, _ := constraint.Underlying().(*types.Interface) + if iface == nil { + return nil, fmt.Errorf("constraint is %T, not *types.Interface", constraint.Underlying()) } - var embeddeds []types.Type - tset, err := computeTermSet(iface, make(map[types.Type]*termSet), 0) + return InterfaceTermSet(iface) +} + +// InterfaceTermSet computes the normalized terms for a constraint interface, +// returning an error if the term set cannot be computed or is empty. In the +// latter case, the error will be ErrEmptyTypeSet. +// +// See the documentation of StructuralTerms for more information on +// normalization. +func InterfaceTermSet(iface *types.Interface) ([]*Term, error) { + return computeTermSet(iface) +} + +// UnionTermSet computes the normalized terms for a union, returning an error +// if the term set cannot be computed or is empty. In the latter case, the +// error will be ErrEmptyTypeSet. +// +// See the documentation of StructuralTerms for more information on +// normalization. +func UnionTermSet(union *Union) ([]*Term, error) { + return computeTermSet(union) +} + +func computeTermSet(typ types.Type) ([]*Term, error) { + tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0) if err != nil { return nil, err } - switch { - case tset.terms.isEmpty(): - // Special case: as documented + if tset.terms.isEmpty() { + return nil, ErrEmptyTypeSet + } + if tset.terms.isAll() { return nil, nil - - case tset.terms.isAll(): - // No embeddeds. - - case len(tset.terms) == 1: - if !tset.terms[0].tilde { - embeddeds = append(embeddeds, tset.terms[0].typ) - break - } - fallthrough - default: - var terms []*Term - for _, term := range tset.terms { - terms = append(terms, NewTerm(term.tilde, term.typ)) - } - embeddeds = append(embeddeds, NewUnion(terms)) } - - return types.NewInterfaceType(methods, embeddeds), nil + var terms []*Term + for _, term := range tset.terms { + terms = append(terms, NewTerm(term.tilde, term.typ)) + } + return terms, nil } // A termSet holds the normalized set of terms for a given type. @@ -79,7 +122,7 @@ func indentf(depth int, format string, args ...interface{}) { fmt.Fprintf(os.Stderr, strings.Repeat(".", depth)+format+"\n", args...) } -func computeTermSet(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) { +func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) { if t == nil { panic("nil type") } @@ -120,7 +163,7 @@ func computeTermSet(t types.Type, seen map[types.Type]*termSet, depth int) (res if _, ok := embedded.Underlying().(*TypeParam); ok { return nil, fmt.Errorf("invalid embedded type %T", embedded) } - tset2, err := computeTermSet(embedded, seen, depth+1) + tset2, err := computeTermSetInternal(embedded, seen, depth+1) if err != nil { return nil, err } @@ -134,7 +177,7 @@ func computeTermSet(t types.Type, seen map[types.Type]*termSet, depth int) (res var terms termlist switch t.Type().Underlying().(type) { case *types.Interface: - tset2, err := computeTermSet(t.Type(), seen, depth+1) + tset2, err := computeTermSetInternal(t.Type(), seen, depth+1) if err != nil { return nil, err } diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go index 214eab6667..e509daf7be 100644 --- a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go +++ b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go @@ -75,6 +75,7 @@ func ForFuncType(*ast.FuncType) *ast.FieldList { // this Go version. Its methods panic on use. type TypeParam struct{ types.Type } +func (*TypeParam) Index() int { unsupported(); return 0 } func (*TypeParam) Constraint() types.Type { unsupported(); return nil } func (*TypeParam) Obj() *types.TypeName { unsupported(); return nil } @@ -137,6 +138,10 @@ func IsImplicit(*types.Interface) bool { return false } +// MarkImplicit does nothing, because this Go version does not have implicit +// interfaces. +func MarkImplicit(*types.Interface) {} + // ForNamed returns an empty type parameter list, as type parameters are not // supported at this Go version. func ForNamed(*types.Named) *TypeParamList { @@ -160,19 +165,25 @@ func NamedTypeOrigin(named *types.Named) types.Type { return named } -// Term is a placeholder type, as type parameters are not supported at this Go -// version. Its methods panic on use. -type Term struct{} +// Term holds information about a structural type restriction. +type Term struct { + tilde bool + typ types.Type +} -func (*Term) Tilde() bool { unsupported(); return false } -func (*Term) Type() types.Type { unsupported(); return nil } -func (*Term) String() string { unsupported(); return "" } -func (*Term) Underlying() types.Type { unsupported(); return nil } +func (m *Term) Tilde() bool { return m.tilde } +func (m *Term) Type() types.Type { return m.typ } +func (m *Term) String() string { + pre := "" + if m.tilde { + pre = "~" + } + return pre + m.typ.String() +} // NewTerm is unsupported at this Go version, and panics. func NewTerm(tilde bool, typ types.Type) *Term { - unsupported() - return nil + return &Term{tilde, typ} } // Union is a placeholder type, as type parameters are not supported at this Go diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go index 55c0398e62..e45896fb02 100644 --- a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go +++ b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go @@ -130,6 +130,11 @@ func IsImplicit(iface *types.Interface) bool { return iface.IsImplicit() } +// MarkImplicit calls iface.MarkImplicit(). +func MarkImplicit(iface *types.Interface) { + iface.MarkImplicit() +} + // ForNamed extracts the (possibly empty) type parameter object list from // named. func ForNamed(named *types.Named) *TypeParamList { diff --git a/vendor/modules.txt b/vendor/modules.txt index a2844a6dc7..5e0e152ac5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -5,7 +5,7 @@ github.com/Microsoft/go-winio github.com/Microsoft/go-winio/pkg/guid # github.com/alessio/shellescape v1.4.1 github.com/alessio/shellescape -# github.com/containerd/containerd v1.5.7 +# github.com/containerd/containerd v1.5.8 github.com/containerd/containerd/errdefs github.com/containerd/containerd/log github.com/containerd/containerd/platforms @@ -15,7 +15,7 @@ github.com/containerd/stargz-snapshotter/estargz github.com/containerd/stargz-snapshotter/estargz/errorutil # github.com/cpuguy83/go-md2man/v2 v2.0.1 github.com/cpuguy83/go-md2man/v2/md2man -# github.com/docker/cli v20.10.10+incompatible +# github.com/docker/cli v20.10.12+incompatible github.com/docker/cli/cli/config github.com/docker/cli/cli/config/configfile github.com/docker/cli/cli/config/credentials @@ -84,7 +84,7 @@ github.com/google/go-cmp/cmp/internal/diff github.com/google/go-cmp/cmp/internal/flags github.com/google/go-cmp/cmp/internal/function github.com/google/go-cmp/cmp/internal/value -# github.com/google/go-containerregistry v0.7.0 +# github.com/google/go-containerregistry v0.8.0 ## explicit github.com/google/go-containerregistry/cmd/crane/cmd github.com/google/go-containerregistry/internal/and @@ -96,6 +96,7 @@ github.com/google/go-containerregistry/internal/redact github.com/google/go-containerregistry/internal/retry github.com/google/go-containerregistry/internal/retry/wait github.com/google/go-containerregistry/internal/verify +github.com/google/go-containerregistry/internal/windows github.com/google/go-containerregistry/pkg/authn github.com/google/go-containerregistry/pkg/crane github.com/google/go-containerregistry/pkg/legacy @@ -145,11 +146,13 @@ github.com/magiconair/properties github.com/mattmoor/dep-notify/pkg/graph # github.com/mattn/go-isatty v0.0.14 github.com/mattn/go-isatty +# github.com/mitchellh/go-homedir v1.1.0 +github.com/mitchellh/go-homedir # github.com/mitchellh/mapstructure v1.4.3 github.com/mitchellh/mapstructure # github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/go-digest -# github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7 +# github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5 ## explicit github.com/opencontainers/image-spec/specs-go github.com/opencontainers/image-spec/specs-go/v1 @@ -211,14 +214,14 @@ golang.org/x/crypto/salsa20/salsa golang.org/x/crypto/scrypt # golang.org/x/mod v0.5.1 golang.org/x/mod/semver -# golang.org/x/net v0.0.0-20211209124913-491a49abca63 +# golang.org/x/net v0.0.0-20211216030914-fe4d6282115f golang.org/x/net/internal/socks golang.org/x/net/proxy # golang.org/x/sync v0.0.0-20210220032951-036812b2e83c ## explicit golang.org/x/sync/errgroup golang.org/x/sync/semaphore -# golang.org/x/sys v0.0.0-20211210111614-af8b64212486 +# golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e golang.org/x/sys/cpu golang.org/x/sys/execabs golang.org/x/sys/internal/unsafeheader @@ -230,7 +233,7 @@ golang.org/x/term # golang.org/x/text v0.3.7 golang.org/x/text/transform golang.org/x/text/unicode/norm -# golang.org/x/tools v0.1.8-0.20211015140901-98f6e0395b11 +# golang.org/x/tools v0.1.8 ## explicit golang.org/x/tools/go/gcexportdata golang.org/x/tools/go/internal/gcimporter