From f3109fe7fda48b76ac07d72d74a23b863291b9a9 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Tue, 2 Nov 2021 02:45:19 +0000 Subject: [PATCH 01/26] Adding OCI to Kptfile schema --- pkg/api/kptfile/v1/types.go | 23 +++++++++++++++++ site/reference/schema/kptfile/kptfile.json | 30 ++++++++++++++++++++++ site/reference/schema/kptfile/kptfile.yaml | 26 +++++++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/pkg/api/kptfile/v1/types.go b/pkg/api/kptfile/v1/types.go index f099d5824d..8a53713c81 100644 --- a/pkg/api/kptfile/v1/types.go +++ b/pkg/api/kptfile/v1/types.go @@ -65,6 +65,9 @@ type OriginType string const ( // GitOrigin specifies a package as having been cloned from a git repository. GitOrigin OriginType = "git" + + // OciOrigin specifies a package as having been pulled from an OCI image repository. + OciOrigin OriginType = "oci" ) // UpdateStrategyType defines the strategy for updating a package from upstream. @@ -121,6 +124,9 @@ type Upstream struct { // Git is the locator for a package stored on Git. Git *Git `yaml:"git,omitempty" json:"git,omitempty"` + // Oci is the locator for a package stored in an OCI image registry. + Oci *Oci `yaml:"oci,omitempty" json:"oci,omitempty"` + // UpdateStrategy declares how a package will be updated from upstream. UpdateStrategy UpdateStrategyType `yaml:"updateStrategy,omitempty" json:"updateStrategy,omitempty"` } @@ -139,6 +145,13 @@ type Git struct { Ref string `yaml:"ref,omitempty" json:"ref,omitempty"` } +// Oci is the user-specified locator for a package in an OCI image registry. +type Oci struct { + // Image is the OCI image repository for the package. + // e.g. 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY_NAME/app-frontend:latest' + Image string `yaml:"image,omitempty" json:"image,omitempty"` +} + // UpstreamLock is a resolved locator for the last fetch of the package. type UpstreamLock struct { // Type is the type of origin. @@ -146,6 +159,9 @@ type UpstreamLock struct { // Git is the resolved locator for a package on Git. Git *GitLock `yaml:"git,omitempty" json:"git,omitempty"` + + // Oci is the resolved locator for a package in an OCI image registry. + Oci *OciLock `yaml:"oci,omitempty" json:"oci,omitempty"` } // GitLock is the resolved locator for a package on Git. @@ -167,6 +183,13 @@ type GitLock struct { Commit string `yaml:"commit,omitempty" json:"commit,omitempty"` } +// OciLock is the resolved locator for a package in an OCI image registry. +type OciLock struct { + // Image is the OCI image repository for the package. + // e.g. 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY_NAME/app-frontend@sha256:b0c94f11d856e59673daca566857a7ead126ef8e2b6915ed662804f858d7eaea' + Image string `yaml:"image,omitempty" json:"image,omitempty"` +} + // PackageInfo contains optional information about the package such as license, documentation, etc. // These fields are not consumed by any functionality in kpt and are simply passed through. // Note that like any other KRM resource, humans and automation can also use `metadata.labels` and diff --git a/site/reference/schema/kptfile/kptfile.json b/site/reference/schema/kptfile/kptfile.json index 1eea9f4613..94cbaa3bdd 100644 --- a/site/reference/schema/kptfile/kptfile.json +++ b/site/reference/schema/kptfile/kptfile.json @@ -180,6 +180,30 @@ }, "x-go-package": "sigs.k8s.io/kustomize/kyaml/yaml" }, + "Oci": { + "type": "object", + "title": "Oci is the user-specified locator for a package in an OCI image registry.", + "properties": { + "image": { + "description": "Image is the OCI image repository for the package.\ne.g. 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY_NAME/app-frontend:latest'", + "type": "string", + "x-go-name": "Image" + } + }, + "x-go-package": "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" + }, + "OciLock": { + "type": "object", + "title": "OciLock is the resolved locator for a package in an OCI image registry.", + "properties": { + "image": { + "description": "Image is the OCI image repository for the package.\ne.g. 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY_NAME/app-frontend@sha256:b0c94f11d856e59673daca566857a7ead126ef8e2b6915ed662804f858d7eaea'", + "type": "string", + "x-go-name": "Image" + } + }, + "x-go-package": "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" + }, "OriginType": { "type": "string", "title": "OriginType defines the type of origin for a package.", @@ -356,6 +380,9 @@ "git": { "$ref": "#/definitions/Git" }, + "oci": { + "$ref": "#/definitions/Oci" + }, "type": { "$ref": "#/definitions/OriginType" }, @@ -372,6 +399,9 @@ "git": { "$ref": "#/definitions/GitLock" }, + "oci": { + "$ref": "#/definitions/OciLock" + }, "type": { "$ref": "#/definitions/OriginType" } diff --git a/site/reference/schema/kptfile/kptfile.yaml b/site/reference/schema/kptfile/kptfile.yaml index 3c1dd48b8a..2a2d04a7bd 100644 --- a/site/reference/schema/kptfile/kptfile.yaml +++ b/site/reference/schema/kptfile/kptfile.yaml @@ -159,6 +159,28 @@ definitions: x-go-name: Namespace type: object x-go-package: sigs.k8s.io/kustomize/kyaml/yaml + Oci: + properties: + image: + description: |- + Image is the OCI image repository for the package. + e.g. 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY_NAME/app-frontend:latest' + type: string + x-go-name: Image + title: Oci is the user-specified locator for a package in an OCI image registry. + type: object + x-go-package: github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1 + OciLock: + properties: + image: + description: |- + Image is the OCI image repository for the package. + e.g. 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY_NAME/app-frontend@sha256:b0c94f11d856e59673daca566857a7ead126ef8e2b6915ed662804f858d7eaea' + type: string + x-go-name: Image + title: OciLock is the resolved locator for a package in an OCI image registry. + type: object + x-go-package: github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1 OriginType: title: OriginType defines the type of origin for a package. type: string @@ -303,6 +325,8 @@ definitions: properties: git: $ref: '#/definitions/Git' + oci: + $ref: '#/definitions/Oci' type: $ref: '#/definitions/OriginType' updateStrategy: @@ -314,6 +338,8 @@ definitions: properties: git: $ref: '#/definitions/GitLock' + oci: + $ref: '#/definitions/OciLock' type: $ref: '#/definitions/OriginType' title: UpstreamLock is a resolved locator for the last fetch of the package. From 18caf382a1bcbd2346fd679dde729863723cbd62 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Tue, 2 Nov 2021 02:48:07 +0000 Subject: [PATCH 02/26] Adding OCI to error utils --- internal/errors/errors.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/errors/errors.go b/internal/errors/errors.go index 4800ffbfa0..4c34e89a8f 100644 --- a/internal/errors/errors.go +++ b/internal/errors/errors.go @@ -142,6 +142,7 @@ const ( InvalidParam // Value is not valid. MissingParam // Required value is missing or empty. Git // Errors from Git + OCI // Errors from OCI IO // Error doing IO operations YAML // yaml document can't be parsed ) @@ -160,6 +161,8 @@ func (c Class) String() string { return "missing parameter value" case Git: return "git error" + case OCI: + return "OCI error" case IO: return "IO error" case YAML: From 70bbde01ea178aff0513c0821f6b536d296befb6 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Tue, 2 Nov 2021 03:36:51 +0000 Subject: [PATCH 03/26] Adding OCI argument parsing to kpt pkg get --- go.mod | 3 +- go.sum | 554 +++++++++++++++++++++++- internal/cmdget/cmdget.go | 29 +- internal/docs/generated/pkgdocs/docs.go | 9 +- internal/util/get/get.go | 3 + internal/util/parse/parse.go | 46 +- 6 files changed, 618 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index 1562742cc5..c06e18e29a 100644 --- a/go.mod +++ b/go.mod @@ -5,12 +5,13 @@ go 1.16 require ( github.com/cpuguy83/go-md2man/v2 v2.0.0 github.com/go-errors/errors v1.4.0 + github.com/google/go-containerregistry v0.6.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/igorsobreira/titlecase v0.0.0-20140109233139-4156b5b858ac github.com/otiai10/copy v1.6.0 github.com/philopon/go-toposort v0.0.0-20170620085441-9be86dbd762f github.com/posener/complete/v2 v2.0.1-alpha.12 - github.com/spf13/cobra v1.1.3 + github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.0 github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca diff --git a/go.sum b/go.sum index f022283da8..b51ff7ba30 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -8,31 +9,52 @@ cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0 h1:3ithwDMr7/3vpAMXiH+ZQnYbuIsh+OPhUPMFC9enmn0= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0 h1:bAMqZidYkmIsUqe6PtkEPT7Q+vfizScn+jfNA6jwK9c= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= 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= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest v0.11.12 h1:gI8ytXbxMfI+IVbI9mP2JGCTXIuhHLgRlvQ9X4PsnHE= github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= +github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.5 h1:Y3bBUV4rTuxenJJs41HU3qmqsb+auo+a3Lz+PlJPpL0= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/logger v0.2.0 h1:e4RVHVZKC5p6UANLJHkM4OfR1UKZPj8Wt8Pcx+3oqrE= @@ -44,6 +66,24 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= +github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= +github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= +github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= +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/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= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -52,6 +92,7 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= @@ -62,7 +103,9 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -74,14 +117,25 @@ github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:l github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= +github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -89,21 +143,117 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= +github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= +github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= +github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= +github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= +github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= +github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E= +github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= +github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= +github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI= +github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= +github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= +github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= +github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= +github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= +github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= +github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +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.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.2/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= +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= +github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo= +github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= +github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= +github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= +github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= +github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= +github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= +github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= +github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU= +github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk= +github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g= +github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= +github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= +github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0= +github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA= +github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow= +github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms= +github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c= +github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= +github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= +github.com/containerd/stargz-snapshotter/estargz v0.7.0/go.mod h1:83VWDqHnurTKliEB0YvWMiCfLDwv4Cjj1X9Vk98GJZw= +github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +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/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= +github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= +github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw= +github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y= +github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= +github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= +github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= +github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4= +github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -113,15 +263,35 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= +github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= +github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= +github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= +github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= +github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/docker/cli v20.10.7+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/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= +github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -134,7 +304,12 @@ github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkg github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -148,10 +323,14 @@ github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTg github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= +github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= @@ -161,6 +340,7 @@ github.com/go-errors/errors v1.4.0/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -222,10 +402,20 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= +github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= +github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -240,11 +430,15 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -254,9 +448,11 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= @@ -265,21 +461,36 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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.6.0 h1:niQ+8XD//kKgArIFwDVBXsWVWbde16LPdHMyNwSC8h4= +github.com/google/go-containerregistry v0.6.0/go.mod h1:euCCtNbZ6tKqi1E72vwDj2xZcN5ttKpZLfa/wSo5iLw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= @@ -296,7 +507,9 @@ github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9 github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -308,15 +521,18 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +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/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= @@ -338,15 +554,22 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/igorsobreira/titlecase v0.0.0-20140109233139-4156b5b858ac h1:AfRcPFr4uK97K6YaYi9XmNY/cTPF+cLspaXocdqkdCQ= github.com/igorsobreira/titlecase v0.0.0-20140109233139-4156b5b858ac/go.mod h1:KOzUkqpWM2xArNm82cehGc5PBFYV1Qadzzt81aJi7F0= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -354,21 +577,30 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.0/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -382,6 +614,7 @@ github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -389,14 +622,18 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= +github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -406,10 +643,17 @@ github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUb github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= +github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= +github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -420,6 +664,8 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -432,6 +678,7 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -442,22 +689,46 @@ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= +github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.2 h1:HFB2fbVIlhIfCfOW81bZFbiC/RvnpXSdhbF2/DJr134= github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= +github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.12.0 h1:p4oGGk2M2UJc0wWN4lHFvIB71lxsh0T/UiKCCgFADY8= github.com/onsi/gomega v1.12.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= 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/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= +github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= +github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= +github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= +github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -477,6 +748,8 @@ github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIw github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= @@ -485,10 +758,12 @@ github.com/philopon/go-toposort v0.0.0-20170620085441-9be86dbd762f/go.mod h1:/iR github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= @@ -498,30 +773,39 @@ github.com/posener/complete/v2 v2.0.1-alpha.12/go.mod h1://JlL91cS2JV7rOl6LVHrRq github.com/posener/script v1.0.4 h1:nSuXW5ZdmFnQIueLB2s0qvs4oNsUloM1Zydzh75v42w= github.com/posener/script v1.0.4/go.mod h1:Rg3ijooqulo05aGLyGsHoLmIOUzHUVK19WVgrYBPU/E= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= +github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -529,54 +813,73 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 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/spyzhov/ajson v0.4.2 h1:JMByd/jZApPKDvNsmO90X2WWGbmT2ahDFp73QhZbg3s= github.com/spyzhov/ajson v0.4.2/go.mod h1:63V+CGM6f1Bu/p4nLIN8885ojBdt88TbLoSFzyqMuVA= +github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -585,51 +888,86 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= +github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= +github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI= github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 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/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= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -638,11 +976,14 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -665,6 +1006,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -674,10 +1017,14 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -693,10 +1040,13 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -704,27 +1054,54 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/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-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -740,41 +1117,81 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= @@ -785,17 +1202,20 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -834,18 +1254,36 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -856,20 +1294,36 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= 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= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -879,14 +1333,39 @@ google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -896,9 +1375,26 @@ google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -912,8 +1408,10 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= @@ -922,18 +1420,23 @@ gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -957,33 +1460,56 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= +k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= +k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= k8s.io/api v0.21.1 h1:94bbZ5NTjdINJEdzOkpS4vdPhkb1VFpTYC9zh43f75c= k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s= k8s.io/apiextensions-apiserver v0.21.1 h1:AA+cnsb6w7SZ1vD32Z+zdgfXdXY8X9uGX5bN6EoPEIo= k8s.io/apiextensions-apiserver v0.21.1/go.mod h1:KESQFCGjqVcVsZ9g0xX5bacMjyX5emuWcS2arzdEouA= +k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= k8s.io/apimachinery v0.21.1 h1:Q6XuHGlj2xc+hlMCvqyYfbv3H7SRGn2c8NycxJquDVs= k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= +k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= +k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= +k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= k8s.io/apiserver v0.21.1/go.mod h1:nLLYZvMWn35glJ4/FZRhzLG/3MPxAaZTgV4FJZdr+tY= k8s.io/cli-runtime v0.21.1 h1:Oj/iZxa7LLXrhzShaLNF4rFJEIEBTDHj0dJw4ra2vX4= k8s.io/cli-runtime v0.21.1/go.mod h1:TI9Bvl8lQWZB2KqE91QLCp9AZE4l29zNFnj/x4IX4Fw= +k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= +k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= +k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= k8s.io/client-go v0.21.1 h1:bhblWYLZKUu+pm50plvQF8WpY6TXdRRtcS/K9WauOj4= k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs= k8s.io/code-generator v0.21.1/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q= +k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= +k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= +k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= k8s.io/component-base v0.21.1 h1:iLpj2btXbR326s/xNQWmPNGu0gaYSjzn7IN/5i28nQw= k8s.io/component-base v0.21.1/go.mod h1:NgzFZ2qu4m1juby4TnrmpR8adRk6ka62YdH5DkIIyKA= k8s.io/component-helpers v0.21.1/go.mod h1:FtC1flbiQlosHQrLrRUulnKxE4ajgWCGy/67fT2GRlQ= +k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= +k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kubectl v0.21.1 h1:ySEusoeSgSDSiSBncDMsNrthSa3OSlXqT4R2rf1VFTw= k8s.io/kubectl v0.21.1/go.mod h1:PMYR88MqESuysBM/MX+Vu4JbX/50nY4d4kny+SPEI2U= +k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/metrics v0.21.1/go.mod h1:pyDVLsLe++FIGDBFU80NcW4xMFsuiVTWL8Zfi7+PpNo= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210517184530-5a248b5acedc/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= @@ -992,6 +1518,7 @@ k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/cli-utils v0.26.0 h1:N1X1NVN19+daTihVimkSVNMgiVPIHG9OO3SJPh6SBQI= sigs.k8s.io/cli-utils v0.26.0/go.mod h1:myCFn83XMe7vC1ZX5CEJJIY2cqsl6IxYI727mLW1mfE= @@ -1007,6 +1534,7 @@ sigs.k8s.io/kustomize/kyaml v0.10.20/go.mod h1:TYWhGwW9vjoRh3rWqBwB/ZOXyEGRVWe7G sigs.k8s.io/kustomize/kyaml v0.11.2-0.20210920224623-c47fc4860720 h1:pL/hMigoxtZ9THfFBXvwtHUeoy93h3INK/VC6oR9QwA= sigs.k8s.io/kustomize/kyaml v0.11.2-0.20210920224623-c47fc4860720/go.mod h1:FTJxEZ86ScK184NpGSAQcfEqee0nul8oLCK30D47m4E= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8= sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/internal/cmdget/cmdget.go b/internal/cmdget/cmdget.go index e82695053a..e6617a52b3 100644 --- a/internal/cmdget/cmdget.go +++ b/internal/cmdget/cmdget.go @@ -38,7 +38,7 @@ func NewRunner(ctx context.Context, parent string) *Runner { ctx: ctx, } c := &cobra.Command{ - Use: "get REPO_URI[.git]/PKG_PATH[@VERSION] [LOCAL_DEST_DIRECTORY]", + Use: "get {REPO_URI[.git]/PKG_PATH[@VERSION]|IMAGE:TAG} [LOCAL_DEST_DIRECTORY]", Args: cobra.MinimumNArgs(1), Short: docs.GetShort, Long: docs.GetShort + "\n" + docs.GetLong, @@ -81,15 +81,14 @@ func (r *Runner) preRunE(_ *cobra.Command, args []string) error { args[1] = resolvedPath } } - t, err := parse.GitParseArgs(r.ctx, args) + destination, err := r.parseArgs(args) if err != nil { - return errors.E(op, err) + return err } - r.Get.Git = &t.Git - p, err := pkg.New(t.Destination) + p, err := pkg.New(destination) if err != nil { - return errors.E(op, types.UniquePath(t.Destination), err) + return errors.E(op, types.UniquePath(destination), err) } r.Get.Destination = string(p.UniquePath) @@ -101,6 +100,24 @@ func (r *Runner) preRunE(_ *cobra.Command, args []string) error { return nil } +func (r *Runner) parseArgs(args []string) (string, error) { + const op errors.Op = "cmdget.preRunE" + + t1, err1 := parse.GitParseArgs(r.ctx, args) + if err1 == nil { + r.Get.Git = &t1.Git + return t1.Destination, nil + } + + t2, err2 := parse.OciParseArgs(r.ctx, args) + if err2 == nil { + r.Get.Oci = &t2.Oci + return t2.Destination, nil + } + + return "", errors.E(op, err1, err2) +} + func (r *Runner) runE(c *cobra.Command, _ []string) error { const op errors.Op = "cmdget.runE" if err := r.Get.Run(r.ctx); err != nil { diff --git a/internal/docs/generated/pkgdocs/docs.go b/internal/docs/generated/pkgdocs/docs.go index bb1970edca..1101882d20 100644 --- a/internal/docs/generated/pkgdocs/docs.go +++ b/internal/docs/generated/pkgdocs/docs.go @@ -97,7 +97,7 @@ var DiffExamples = ` var GetShort = `Fetch a package from a git repo.` var GetLong = ` - kpt pkg get REPO_URI[.git]/PKG_PATH[@VERSION] [LOCAL_DEST_DIRECTORY] [flags] + kpt pkg get {REPO_URI[.git]/PKG_PATH[@VERSION]|IMAGE:TAG} [LOCAL_DEST_DIRECTORY] [flags] Args: @@ -119,6 +119,13 @@ Args: A git tag, branch, ref or commit for the remote version of the package to fetch. Defaults to the default branch of the repository. + IMAGE: + Reference to an OCI image containing a package in the root directory. + + TAG: + An image tag or @sha256 digest for the remote version of the image + to fetch. Defaults to the 'latest' tag on the image. + LOCAL_DEST_DIRECTORY: The local directory to write the package to. Defaults to a subdirectory of the current working directory named after the upstream package. diff --git a/internal/util/get/get.go b/internal/util/get/get.go index 47cfabe800..449d01b7ee 100644 --- a/internal/util/get/get.go +++ b/internal/util/get/get.go @@ -41,6 +41,9 @@ type Command struct { // Git contains information about the git repo to fetch Git *kptfilev1.Git + // Oci contains information about the OCI image to fetch + Oci *kptfilev1.Oci + // Destination is the output directory to clone the package to. Defaults to the name of the package -- // either the base repo name, or the base subdirectory name. Destination string diff --git a/internal/util/parse/parse.go b/internal/util/parse/parse.go index 7bedafa6bc..5ccc786516 100644 --- a/internal/util/parse/parse.go +++ b/internal/util/parse/parse.go @@ -24,16 +24,52 @@ import ( "github.com/GoogleContainerTools/kpt/internal/gitutil" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" + "github.com/google/go-containerregistry/pkg/name" "sigs.k8s.io/kustomize/kyaml/errors" ) -type Target struct { +type OciTarget struct { + kptfilev1.Oci + Destination string +} + +func OciParseArgs(ctx context.Context, args []string) (OciTarget, error) { + oci := OciTarget{} + if args[0] == "-" { + return oci, nil + } + + return targetFromImageReference(args[0], args[1]) +} + +func targetFromImageReference(image, dest string) (OciTarget, error) { + ref, err := name.ParseReference(image) + if err != nil { + return OciTarget{}, err + } + + registry := ref.Context().RegistryStr() + repository := ref.Context().RepositoryStr() + destination, err := getDest(dest, registry, repository) + if err != nil { + return OciTarget{}, err + } + + return OciTarget{ + Oci: kptfilev1.Oci{ + Image: ref.Name(), + }, + Destination: destination, + }, nil +} + +type GitTarget struct { kptfilev1.Git Destination string } -func GitParseArgs(ctx context.Context, args []string) (Target, error) { - g := Target{} +func GitParseArgs(ctx context.Context, args []string) (GitTarget, error) { + g := GitTarget{} if args[0] == "-" { return g, nil } @@ -84,8 +120,8 @@ func GitParseArgs(ctx context.Context, args []string) (Target, error) { } // targetFromPkgURL parses a pkg url and destination into kptfile git info and local destination Target -func targetFromPkgURL(ctx context.Context, pkgURL, dest string) (Target, error) { - g := Target{} +func targetFromPkgURL(ctx context.Context, pkgURL, dest string) (GitTarget, error) { + g := GitTarget{} var repo, dir, version string parts := strings.Split(pkgURL, ".git") repo = strings.TrimSuffix(parts[0], "/") From 8d98ce527a88f362008d91077dda40b309a5c2a2 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Tue, 2 Nov 2021 04:17:33 +0000 Subject: [PATCH 04/26] Adding get/fetch validation --- internal/util/fetch/fetch.go | 38 +++++++++++++------ internal/util/get/get.go | 72 +++++++++++++++++++++++------------- 2 files changed, 72 insertions(+), 38 deletions(-) diff --git a/internal/util/fetch/fetch.go b/internal/util/fetch/fetch.go index 1d384a0f5e..957073c75b 100644 --- a/internal/util/fetch/fetch.go +++ b/internal/util/fetch/fetch.go @@ -75,21 +75,35 @@ func (c Command) validate(kf *kptfilev1.KptFile) error { if kf.Upstream == nil { return errors.E(op, errors.MissingParam, fmt.Errorf("kptfile doesn't contain upstream information")) } + switch kf.Upstream.Type{ + case kptfilev1.GitOrigin: + if kf.Upstream.Git == nil { + return errors.E(op, errors.MissingParam, fmt.Errorf("kptfile upstream doesn't have git information")) + } + + g := kf.Upstream.Git + if len(g.Repo) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify repo")) + } + if len(g.Ref) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify ref")) + } + if len(g.Directory) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify directory")) + } - if kf.Upstream.Git == nil { - return errors.E(op, errors.MissingParam, fmt.Errorf("kptfile upstream doesn't have git information")) - } + case kptfilev1.OciOrigin: + if kf.Upstream.Oci == nil { + return errors.E(op, errors.MissingParam, fmt.Errorf("kptfile upstream doesn't have oci information")) + } + if len(kf.Upstream.Oci.Image) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify image")) + } - g := kf.Upstream.Git - if len(g.Repo) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify repo")) - } - if len(g.Ref) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify ref")) - } - if len(g.Directory) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify directory")) + default: + return errors.E(op, errors.MissingParam, fmt.Errorf("kptfile upstream type must be one of: %s,%s", kptfilev1.GitOrigin, kptfilev1.OciOrigin)) } + return nil } diff --git a/internal/util/get/get.go b/internal/util/get/get.go index 449d01b7ee..2ff99e1252 100644 --- a/internal/util/get/get.go +++ b/internal/util/get/get.go @@ -73,18 +73,27 @@ func (c Command) Run(ctx context.Context) error { return errors.E(op, errors.IO, types.UniquePath(c.Destination), err) } - // normalize path to a filepath - repoDir := c.Git.Directory - if !strings.HasSuffix(repoDir, "file://") { - repoDir = filepath.Join(path.Split(repoDir)) - } - c.Git.Directory = repoDir - kf := kptfileutil.DefaultKptfile(c.Name) - kf.Upstream = &kptfilev1.Upstream{ - Type: kptfilev1.GitOrigin, - Git: c.Git, - UpdateStrategy: c.UpdateStrategy, + if c.Git != nil { + // normalize path to a filepath + repoDir := c.Git.Directory + if !strings.HasSuffix(repoDir, "file://") { + repoDir = filepath.Join(path.Split(repoDir)) + } + c.Git.Directory = repoDir + + kf.Upstream = &kptfilev1.Upstream{ + Type: kptfilev1.GitOrigin, + Git: c.Git, + UpdateStrategy: c.UpdateStrategy, + } + } + if c.Oci != nil { + kf.Upstream = &kptfilev1.Upstream{ + Type: kptfilev1.OciOrigin, + Oci: c.Oci, + UpdateStrategy: c.UpdateStrategy, + } } err = kptfileutil.WriteFile(c.Destination, kf) @@ -129,7 +138,12 @@ func (c Command) fetchPackages(ctx context.Context, rootPkg *pkg.Pkg) error { if kf.Upstream != nil && kf.UpstreamLock == nil { packageCount += 1 pr.PrintPackage(p, !(p == rootPkg)) - pr.Printf("Fetching %s@%s\n", kf.Upstream.Git.Repo, kf.Upstream.Git.Ref) + switch(kf.Upstream.Type){ + case kptfilev1.GitOrigin: + pr.Printf("Fetching %s@%s\n", kf.Upstream.Git.Repo, kf.Upstream.Git.Ref) + case kptfilev1.OciOrigin: + pr.Printf("Fetching %s\n", kf.Upstream.Oci.Image) + } err := (&fetch.Command{ Pkg: p, }).Run(ctx) @@ -153,23 +167,29 @@ func (c Command) fetchPackages(ctx context.Context, rootPkg *pkg.Pkg) error { // DefaultValues sets values to the default values if they were unspecified func (c *Command) DefaultValues() error { const op errors.Op = "get.DefaultValues" - if c.Git == nil { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify git repo information")) + if c.Git == nil && c.Oci == nil { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify git repo or image reference information")) } - g := c.Git - if len(g.Repo) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify repo")) - } - if len(g.Ref) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify ref")) - } - if len(c.Destination) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify destination")) + if c.Git != nil { + g := c.Git + if len(g.Repo) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify repo")) + } + if len(g.Ref) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify ref")) + } + if len(c.Destination) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify destination")) + } + if len(g.Directory) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify directory")) + } } - if len(g.Directory) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify directory")) + if c.Oci != nil { + if len(c.Oci.Image) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify image")) + } } - if !filepath.IsAbs(c.Destination) { return errors.E(op, errors.InvalidParam, fmt.Errorf("destination must be an absolute path")) } From 747dbd07d44d41aeb6e011aa8b31d50fa0854192 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Tue, 2 Nov 2021 04:58:40 +0000 Subject: [PATCH 05/26] Adding pull and untar to support kpt get --- go.sum | 11 +++ internal/util/fetch/fetch.go | 140 ++++++++++++++++++++++++++++++-- pkg/kptfile/kptfileutil/util.go | 26 ++++++ 3 files changed, 168 insertions(+), 9 deletions(-) diff --git a/go.sum b/go.sum index b51ff7ba30..53a56cfb02 100644 --- a/go.sum +++ b/go.sum @@ -217,6 +217,7 @@ github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJ github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c= github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= +github.com/containerd/stargz-snapshotter/estargz v0.7.0 h1:1d/rydzTywc76lnjJb6qbPCiTiCwts49AzKps/Ecblw= github.com/containerd/stargz-snapshotter/estargz v0.7.0/go.mod h1:83VWDqHnurTKliEB0YvWMiCfLDwv4Cjj1X9Vk98GJZw= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= @@ -277,11 +278,15 @@ github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/docker/cli v20.10.7+incompatible h1:pv/3NqibQKphWZiAskMzdz8w0PRbtTaEB+f6NwdU7Is= github.com/docker/cli v20.10.7+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= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ= github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= @@ -452,6 +457,7 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -592,6 +598,7 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.0 h1:2T7tUoQrQT+fQWdaY5rjWztFGAFwbGD04iPJg90ZiOs= github.com/klauspost/compress v1.13.0/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -713,8 +720,10 @@ github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1 github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= 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 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= github.com/opencontainers/image-spec v1.0.1/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= @@ -837,6 +846,7 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -1101,6 +1111,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/internal/util/fetch/fetch.go b/internal/util/fetch/fetch.go index 957073c75b..78119992e7 100644 --- a/internal/util/fetch/fetch.go +++ b/internal/util/fetch/fetch.go @@ -15,14 +15,20 @@ package fetch import ( + "archive/tar" "context" "fmt" + "io" "io/ioutil" "os" "path" "path/filepath" "strings" + "github.com/google/go-containerregistry/pkg/gcrane" + "github.com/google/go-containerregistry/pkg/name" + "github.com/google/go-containerregistry/pkg/v1/mutate" + "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/otiai10/copy" "github.com/GoogleContainerTools/kpt/internal/errors" @@ -55,15 +61,24 @@ func (c Command) Run(ctx context.Context) error { return errors.E(op, c.Pkg.UniquePath, err) } - g := kf.Upstream.Git - repoSpec := &git.RepoSpec{ - OrgRepo: g.Repo, - Path: g.Directory, - Ref: g.Ref, - } - err = cloneAndCopy(ctx, repoSpec, c.Pkg.UniquePath.String()) - if err != nil { - return errors.E(op, c.Pkg.UniquePath, err) + switch kf.Upstream.Type { + case kptfilev1.GitOrigin: + g := kf.Upstream.Git + repoSpec := &git.RepoSpec{ + OrgRepo: g.Repo, + Path: g.Directory, + Ref: g.Ref, + } + err = cloneAndCopy(ctx, repoSpec, c.Pkg.UniquePath.String()) + if err != nil { + return errors.E(op, c.Pkg.UniquePath, err) + } + case kptfilev1.OciOrigin: + // TODO(dejardin) more research into remote options? + err = pullAndCopy(ctx, kf.Upstream.Oci.Image, c.Pkg.UniquePath.String(), remote.WithAuthFromKeychain(gcrane.Keychain)) + if err != nil { + return errors.E(op, c.Pkg.UniquePath, err) + } } return nil } @@ -269,3 +284,110 @@ func copyDir(ctx context.Context, srcDir string, dstDir string) error { } return copy.Copy(srcDir, dstDir, opts) } + + +func pullAndCopy(ctx context.Context, imageName string, dest string, options ...remote.Option) error { + const op errors.Op = "fetch.pullAndCopy" + // pr := printer.FromContextOrDie(ctx) + + // We need to create a temp directory where we can copy the content of the repo. + // During update, we need to checkout multiple versions of the same repo, so + // we can't do merges directly from the cache. + dir, err := ioutil.TempDir("", "kpt-get-") + if err != nil { + return errors.E(op, errors.Internal, fmt.Errorf("error creating temp directory: %w", err)) + } + defer os.RemoveAll(dir) + + imageDigest, err := OciPullAndExtract(ctx, imageName, dir, options...) + if err != nil { + return errors.E(op, errors.OCI, types.UniquePath(dest), err) + } + + sourcePath := dir + if err := pkgutil.CopyPackage(sourcePath, dest, true, pkg.All); err != nil { + return errors.E(op, types.UniquePath(dest), err) + } + + if err := kptfileutil.UpdateKptfileWithoutOrigin(dest, sourcePath, false); err != nil { + return errors.E(op, types.UniquePath(dest), err) + } + + if err := kptfileutil.UpdateUpstreamLockFromOCI(dest, imageDigest); err != nil { + return errors.E(op, errors.OCI, types.UniquePath(dest), err) + } + + return nil +} + +// OciPullAndExtract uses current credentials (gcloud auth) to pull and +// extract (untar) image files to target directory. The desired version or digest must +// be in the imageName, and the resolved image sha256 digest is returned. +func OciPullAndExtract(ctx context.Context, imageName string, dir string, options ...remote.Option) (name.Reference, error) { + const op errors.Op = "fetch.OciPullAndExtract" + + ref, err := name.ParseReference(imageName) + if err != nil { + return nil, fmt.Errorf("parsing reference %q: %v", imageName, err) + } + + // Pull image from source using provided options for auth credentials + image, err := remote.Image(ref, options...) + if err != nil { + return nil, fmt.Errorf("pulling image %s: %v", imageName, err) + } + + // Stream image files as if single tar (merged layers) + ioReader := mutate.Extract(image) + defer ioReader.Close() + + // Write contents to target dir + // TODO look for a more robust example of an untar loop + tarReader := tar.NewReader(ioReader) + for { + hdr, err := tarReader.Next() + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + path := filepath.Join(dir, hdr.Name) + switch { + case hdr.FileInfo().IsDir(): + if err := os.MkdirAll(path, hdr.FileInfo().Mode()); err != nil { + return nil, err + } + case hdr.Linkname != "": + if err := os.Symlink(hdr.Linkname, path); err != nil { + // just warn for now + fmt.Fprintln(os.Stderr, err) + // return err + } + default: + file, err := os.OpenFile(path, + os.O_WRONLY|os.O_CREATE|os.O_TRUNC, + os.FileMode(hdr.Mode), + ) + if err != nil { + return nil, err + } + defer file.Close() + + _, err = io.Copy(file, tarReader) + if err != nil { + return nil, err + } + } + } + + // Determine the digest of the image that was extracted + imageDigestHash, err := image.Digest() + if err != nil { + return nil, errors.E(op, fmt.Errorf("error calculating image digest: %w", err)) + } + imageDigest := ref.Context().Digest("sha256:" + imageDigestHash.Hex) + + // Return the image with digest when successful, needed for upstreamLock + return imageDigest, nil +} diff --git a/pkg/kptfile/kptfileutil/util.go b/pkg/kptfile/kptfileutil/util.go index 830095d741..dabdbfbae1 100644 --- a/pkg/kptfile/kptfileutil/util.go +++ b/pkg/kptfile/kptfileutil/util.go @@ -28,6 +28,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/types" "github.com/GoogleContainerTools/kpt/internal/util/git" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" + "github.com/google/go-containerregistry/pkg/name" "sigs.k8s.io/kustomize/kyaml/yaml" "sigs.k8s.io/kustomize/kyaml/yaml/merge3" ) @@ -223,6 +224,31 @@ func UpdateUpstreamLockFromGit(path string, spec *git.RepoSpec) error { return nil } +// UpdateUpstreamLockFromOCI updates the upstreamLock of the package specified +// by path by using the values from spec. The image reference provided must +// be the image sha256 digest in order for later updates to work correctly. +func UpdateUpstreamLockFromOCI(path string, image name.Reference) error { + const op errors.Op = "kptfileutil.UpdateUpstreamLockFromOCI" + // read KptFile cloned with the package if it exists + kpgfile, err := pkg.ReadKptfile(path) + if err != nil { + return errors.E(op, types.UniquePath(path), err) + } + + // populate the cloneFrom values so we know where the package came from + kpgfile.UpstreamLock = &kptfilev1.UpstreamLock{ + Type: kptfilev1.OciOrigin, + Oci: &kptfilev1.OciLock{ + Image: image.Name(), + }, + } + err = WriteFile(path, kpgfile) + if err != nil { + return errors.E(op, types.UniquePath(path), err) + } + return nil +} + func merge(localKf, updatedKf, originalKf *kptfilev1.KptFile) error { localBytes, err := yaml.Marshal(localKf) if err != nil { From 13a63297c6aadbe9865fd47e0883e6b6d061704f Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Tue, 2 Nov 2021 05:16:01 +0000 Subject: [PATCH 06/26] Making change in md file --- site/reference/cli/pkg/get/README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/site/reference/cli/pkg/get/README.md b/site/reference/cli/pkg/get/README.md index 6288bae159..2fba974125 100644 --- a/site/reference/cli/pkg/get/README.md +++ b/site/reference/cli/pkg/get/README.md @@ -18,7 +18,7 @@ local directory. ``` -kpt pkg get REPO_URI[.git]/PKG_PATH[@VERSION] [LOCAL_DEST_DIRECTORY] [flags] +kpt pkg get {REPO_URI[.git]/PKG_PATH[@VERSION]|IMAGE:TAG} [LOCAL_DEST_DIRECTORY] [flags] ``` #### Args @@ -42,6 +42,13 @@ VERSION: A git tag, branch, ref or commit for the remote version of the package to fetch. Defaults to the default branch of the repository. +IMAGE: + Reference to an OCI image containing a package in the root directory. + +TAG: + An image tag or @sha256 digest for the remote version of the image + to fetch. Defaults to the 'latest' tag on the image. + LOCAL_DEST_DIRECTORY: The local directory to write the package to. Defaults to a subdirectory of the current working directory named after the upstream package. From 582ba3b4a47e3b2a518e5121de756a8d8822cf86 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Tue, 2 Nov 2021 23:12:00 +0000 Subject: [PATCH 07/26] go fmt and fixing tests * Adds `oci://` to disambiguate `kpt pkg get` argument --- internal/cmdget/cmdget.go | 3 ++- internal/cmdget/cmdget_test.go | 1 + internal/docs/generated/pkgdocs/docs.go | 2 +- internal/util/fetch/fetch.go | 5 ++--- internal/util/get/get.go | 2 +- internal/util/get/get_test.go | 2 +- internal/util/parse/parse.go | 12 +++++++++--- pkg/test/live/runner.go | 2 +- 8 files changed, 18 insertions(+), 11 deletions(-) diff --git a/internal/cmdget/cmdget.go b/internal/cmdget/cmdget.go index e6617a52b3..52f9e171cd 100644 --- a/internal/cmdget/cmdget.go +++ b/internal/cmdget/cmdget.go @@ -17,6 +17,7 @@ package cmdget import ( "context" + "fmt" "os" "strings" @@ -115,7 +116,7 @@ func (r *Runner) parseArgs(args []string) (string, error) { return t2.Destination, nil } - return "", errors.E(op, err1, err2) + return "", errors.E(op, fmt.Errorf("%v %v", err1, err2)) } func (r *Runner) runE(c *cobra.Command, _ []string) error { diff --git a/internal/cmdget/cmdget_test.go b/internal/cmdget/cmdget_test.go index 02ffe964bb..1249833889 100644 --- a/internal/cmdget/cmdget_test.go +++ b/internal/cmdget/cmdget_test.go @@ -345,6 +345,7 @@ func TestCmd_Execute_flagAndArgParsing(t *testing.T) { validations: func(repo, dir string, r *cmdget.Runner, err error) { assert.Error(t, err) assert.Contains(t, err.Error(), "specify '.git'") + assert.Contains(t, err.Error(), "specify 'oci://'") }, }, "valid strategy provided": { diff --git a/internal/docs/generated/pkgdocs/docs.go b/internal/docs/generated/pkgdocs/docs.go index 1101882d20..088945afc1 100644 --- a/internal/docs/generated/pkgdocs/docs.go +++ b/internal/docs/generated/pkgdocs/docs.go @@ -125,7 +125,7 @@ Args: TAG: An image tag or @sha256 digest for the remote version of the image to fetch. Defaults to the 'latest' tag on the image. - + LOCAL_DEST_DIRECTORY: The local directory to write the package to. Defaults to a subdirectory of the current working directory named after the upstream package. diff --git a/internal/util/fetch/fetch.go b/internal/util/fetch/fetch.go index 78119992e7..65b095ce83 100644 --- a/internal/util/fetch/fetch.go +++ b/internal/util/fetch/fetch.go @@ -90,12 +90,12 @@ func (c Command) validate(kf *kptfilev1.KptFile) error { if kf.Upstream == nil { return errors.E(op, errors.MissingParam, fmt.Errorf("kptfile doesn't contain upstream information")) } - switch kf.Upstream.Type{ + switch kf.Upstream.Type { case kptfilev1.GitOrigin: if kf.Upstream.Git == nil { return errors.E(op, errors.MissingParam, fmt.Errorf("kptfile upstream doesn't have git information")) } - + g := kf.Upstream.Git if len(g.Repo) == 0 { return errors.E(op, errors.MissingParam, fmt.Errorf("must specify repo")) @@ -285,7 +285,6 @@ func copyDir(ctx context.Context, srcDir string, dstDir string) error { return copy.Copy(srcDir, dstDir, opts) } - func pullAndCopy(ctx context.Context, imageName string, dest string, options ...remote.Option) error { const op errors.Op = "fetch.pullAndCopy" // pr := printer.FromContextOrDie(ctx) diff --git a/internal/util/get/get.go b/internal/util/get/get.go index 2ff99e1252..64d5b99e46 100644 --- a/internal/util/get/get.go +++ b/internal/util/get/get.go @@ -138,7 +138,7 @@ func (c Command) fetchPackages(ctx context.Context, rootPkg *pkg.Pkg) error { if kf.Upstream != nil && kf.UpstreamLock == nil { packageCount += 1 pr.PrintPackage(p, !(p == rootPkg)) - switch(kf.Upstream.Type){ + switch kf.Upstream.Type { case kptfilev1.GitOrigin: pr.Printf("Fetching %s@%s\n", kf.Upstream.Git.Repo, kf.Upstream.Git.Ref) case kptfilev1.OciOrigin: diff --git a/internal/util/get/get_test.go b/internal/util/get/get_test.go index 96c0ca0198..1e30107261 100644 --- a/internal/util/get/get_test.go +++ b/internal/util/get/get_test.go @@ -48,7 +48,7 @@ func TestCommand_Run_failEmptyRepo(t *testing.T) { if !assert.Error(t, err) { t.FailNow() } - assert.Contains(t, err.Error(), "must specify git repo information") + assert.Contains(t, err.Error(), "must specify git repo or image reference information") } // TestCommand_Run_failEmptyRepo verifies that Command fail if not repo is provided. diff --git a/internal/util/parse/parse.go b/internal/util/parse/parse.go index 5ccc786516..f082c91f7c 100644 --- a/internal/util/parse/parse.go +++ b/internal/util/parse/parse.go @@ -35,11 +35,17 @@ type OciTarget struct { func OciParseArgs(ctx context.Context, args []string) (OciTarget, error) { oci := OciTarget{} - if args[0] == "-" { + if args[0] == "-" { return oci, nil } - return targetFromImageReference(args[0], args[1]) + // The prefix must occur, and must not have other characters before it + arg0parts := strings.SplitN(args[0], "oci://", 2) + if len(arg0parts) != 2 || len(arg0parts[0]) != 0 { + return oci, errors.Errorf("ambiguous image:tag specify 'oci://' before argument: %s", args[0]) + } + + return targetFromImageReference(arg0parts[1], args[1]) } func targetFromImageReference(image, dest string) (OciTarget, error) { @@ -56,7 +62,7 @@ func targetFromImageReference(image, dest string) (OciTarget, error) { } return OciTarget{ - Oci: kptfilev1.Oci{ + Oci: kptfilev1.Oci{ Image: ref.Name(), }, Destination: destination, diff --git a/pkg/test/live/runner.go b/pkg/test/live/runner.go index 0de4a45e9e..d4720f0b37 100644 --- a/pkg/test/live/runner.go +++ b/pkg/test/live/runner.go @@ -32,7 +32,7 @@ import ( ) const ( - KindClusterName = "live-e2e-test" + KindClusterName = "live-e2e-test" K8sVersionEnvName = "K8S_VERSION" ) From d7a7f59b0127fde768ff5fab29e8059742730c70 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Thu, 4 Nov 2021 02:47:31 +0000 Subject: [PATCH 08/26] Factoring upstream fetcher out of switch cases --- internal/cmdget/cmdget.go | 4 +- internal/testutil/setup_manager.go | 9 +- internal/util/fetch/fetch.go | 315 +----------------------- internal/util/get/example_test.go | 25 +- internal/util/get/get.go | 65 ++--- internal/util/get/get_test.go | 69 +++--- internal/util/update/update.go | 6 +- internal/util/upstream/git.go | 239 ++++++++++++++++++ internal/util/upstream/git_test.go | 96 ++++++++ internal/util/upstream/oci.go | 162 ++++++++++++ internal/util/upstream/upstream.go | 37 +++ internal/util/upstream/upstream_test.go | 116 +++++++++ 12 files changed, 733 insertions(+), 410 deletions(-) create mode 100644 internal/util/upstream/git.go create mode 100644 internal/util/upstream/git_test.go create mode 100644 internal/util/upstream/oci.go create mode 100644 internal/util/upstream/upstream.go create mode 100644 internal/util/upstream/upstream_test.go diff --git a/internal/cmdget/cmdget.go b/internal/cmdget/cmdget.go index 52f9e171cd..58e4351692 100644 --- a/internal/cmdget/cmdget.go +++ b/internal/cmdget/cmdget.go @@ -29,6 +29,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/util/cmdutil" "github.com/GoogleContainerTools/kpt/internal/util/get" "github.com/GoogleContainerTools/kpt/internal/util/parse" + "github.com/GoogleContainerTools/kpt/internal/util/upstream" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/spf13/cobra" ) @@ -107,12 +108,13 @@ func (r *Runner) parseArgs(args []string) (string, error) { t1, err1 := parse.GitParseArgs(r.ctx, args) if err1 == nil { r.Get.Git = &t1.Git + r.Get.Upstream = upstream.NewGitUpstream(&t1.Git) return t1.Destination, nil } t2, err2 := parse.OciParseArgs(r.ctx, args) if err2 == nil { - r.Get.Oci = &t2.Oci + r.Get.Upstream = upstream.NewOciUpstream(&t2.Oci) return t2.Destination, nil } diff --git a/internal/testutil/setup_manager.go b/internal/testutil/setup_manager.go index 8b5ab5c057..da66ba8be5 100644 --- a/internal/testutil/setup_manager.go +++ b/internal/testutil/setup_manager.go @@ -25,6 +25,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/printer/fake" "github.com/GoogleContainerTools/kpt/internal/testutil/pkgbuilder" "github.com/GoogleContainerTools/kpt/internal/util/get" + "github.com/GoogleContainerTools/kpt/internal/util/upstream" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/yaml" @@ -106,11 +107,11 @@ func (g *TestSetupManager) Init() bool { // Get the content from the upstream repo into the local workspace. if !assert.NoError(g.T, get.Command{ Destination: filepath.Join(g.LocalWorkspace.WorkspaceDirectory, g.targetDir), - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: g.Repos[Upstream].RepoDirectory, Ref: g.GetRef, Directory: g.GetSubDirectory, - }}.Run(fake.CtxWithDefaultPrinter())) { + })}.Run(fake.CtxWithDefaultPrinter())) { return false } localGit, err := gitutil.NewLocalGitRunner(g.LocalWorkspace.WorkspaceDirectory) @@ -202,11 +203,11 @@ func UpdateGitDir(t *testing.T, name string, gitDir GitDirectory, changes []Cont func (g *TestSetupManager) GetSubPkg(dest, repo, upstreamDir string) { assert.NoError(g.T, get.Command{ Destination: path.Join(g.LocalWorkspace.FullPackagePath(), dest), - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: g.Repos[repo].RepoDirectory, Ref: g.GetRef, Directory: path.Join(g.GetSubDirectory, upstreamDir), - }}.Run(fake.CtxWithDefaultPrinter())) + })}.Run(fake.CtxWithDefaultPrinter())) localGit, err := gitutil.NewLocalGitRunner(g.LocalWorkspace.WorkspaceDirectory) assert.NoError(g.T, err) diff --git a/internal/util/fetch/fetch.go b/internal/util/fetch/fetch.go index 65b095ce83..cc11aa3151 100644 --- a/internal/util/fetch/fetch.go +++ b/internal/util/fetch/fetch.go @@ -15,31 +15,13 @@ package fetch import ( - "archive/tar" "context" "fmt" - "io" - "io/ioutil" - "os" - "path" - "path/filepath" - "strings" - - "github.com/google/go-containerregistry/pkg/gcrane" - "github.com/google/go-containerregistry/pkg/name" - "github.com/google/go-containerregistry/pkg/v1/mutate" - "github.com/google/go-containerregistry/pkg/v1/remote" - "github.com/otiai10/copy" "github.com/GoogleContainerTools/kpt/internal/errors" - "github.com/GoogleContainerTools/kpt/internal/gitutil" "github.com/GoogleContainerTools/kpt/internal/pkg" - "github.com/GoogleContainerTools/kpt/internal/printer" - "github.com/GoogleContainerTools/kpt/internal/types" - "github.com/GoogleContainerTools/kpt/internal/util/git" - "github.com/GoogleContainerTools/kpt/internal/util/pkgutil" + "github.com/GoogleContainerTools/kpt/internal/util/upstream" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" - "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" ) // Command takes the upstream information in the Kptfile at the path for the @@ -61,25 +43,15 @@ func (c Command) Run(ctx context.Context) error { return errors.E(op, c.Pkg.UniquePath, err) } - switch kf.Upstream.Type { - case kptfilev1.GitOrigin: - g := kf.Upstream.Git - repoSpec := &git.RepoSpec{ - OrgRepo: g.Repo, - Path: g.Directory, - Ref: g.Ref, - } - err = cloneAndCopy(ctx, repoSpec, c.Pkg.UniquePath.String()) - if err != nil { - return errors.E(op, c.Pkg.UniquePath, err) - } - case kptfilev1.OciOrigin: - // TODO(dejardin) more research into remote options? - err = pullAndCopy(ctx, kf.Upstream.Oci.Image, c.Pkg.UniquePath.String(), remote.WithAuthFromKeychain(gcrane.Keychain)) - if err != nil { - return errors.E(op, c.Pkg.UniquePath, err) - } + upstream, err := upstream.NewUpstream(kf) + if err != nil { + return errors.E(op, c.Pkg.UniquePath, err) + } + + if err := upstream.FetchUpstream(ctx, c.Pkg.UniquePath.String()); err != nil { + return errors.E(op, c.Pkg.UniquePath, err) } + return nil } @@ -121,272 +93,3 @@ func (c Command) validate(kf *kptfilev1.KptFile) error { return nil } - -// cloneAndCopy fetches the provided repo and copies the content into the -// directory specified by dest. The provided name is set as `metadata.name` -// of the Kptfile of the package. -func cloneAndCopy(ctx context.Context, r *git.RepoSpec, dest string) error { - const op errors.Op = "fetch.cloneAndCopy" - pr := printer.FromContextOrDie(ctx) - - err := ClonerUsingGitExec(ctx, r) - if err != nil { - return errors.E(op, errors.Git, types.UniquePath(dest), err) - } - defer os.RemoveAll(r.Dir) - - sourcePath := filepath.Join(r.Dir, r.Path) - pr.Printf("Adding package %q.\n", strings.TrimPrefix(r.Path, "/")) - if err := pkgutil.CopyPackage(sourcePath, dest, true, pkg.All); err != nil { - return errors.E(op, types.UniquePath(dest), err) - } - - if err := kptfileutil.UpdateKptfileWithoutOrigin(dest, sourcePath, false); err != nil { - return errors.E(op, types.UniquePath(dest), err) - } - - if err := kptfileutil.UpdateUpstreamLockFromGit(dest, r); err != nil { - return errors.E(op, errors.Git, types.UniquePath(dest), err) - } - return nil -} - -// ClonerUsingGitExec uses a local git install, as opposed -// to say, some remote API, to obtain a local clone of -// a remote repo. It looks for tags with the directory as a prefix to allow -// for versioning multiple kpt packages in a single repo independently. It -// relies on the private clonerUsingGitExec function to try fetching different -// refs. -func ClonerUsingGitExec(ctx context.Context, repoSpec *git.RepoSpec) error { - const op errors.Op = "fetch.ClonerUsingGitExec" - - // Create a local representation of the upstream repo. This will initialize - // the cache for the specified repo uri if it isn't already there. It also - // fetches and caches all tag and branch refs from the upstream repo. - upstreamRepo, err := gitutil.NewGitUpstreamRepo(ctx, repoSpec.CloneSpec()) - if err != nil { - return errors.E(op, errors.Git, errors.Repo(repoSpec.CloneSpec()), err) - } - - // Check if we have a ref in the upstream that matches the package-specific - // reference. If we do, we use that reference. - ps := strings.Split(repoSpec.Path, "/") - for len(ps) != 0 { - p := path.Join(ps...) - packageRef := path.Join(strings.TrimLeft(p, "/"), repoSpec.Ref) - if _, found := upstreamRepo.ResolveTag(packageRef); found { - repoSpec.Ref = packageRef - break - } - ps = ps[:len(ps)-1] - } - - // Pull the required ref into the repo git cache. - dir, err := upstreamRepo.GetRepo(ctx, []string{repoSpec.Ref}) - if err != nil { - return errors.E(op, errors.Git, errors.Repo(repoSpec.CloneSpec()), err) - } - - gitRunner, err := gitutil.NewLocalGitRunner(dir) - if err != nil { - return errors.E(op, errors.Git, errors.Repo(repoSpec.CloneSpec()), err) - } - - // Find the commit SHA for the ref that was just fetched. We need the SHA - // rather than the ref to be able to do a hard reset of the cache repo. - commit, found := upstreamRepo.ResolveRef(repoSpec.Ref) - if !found { - commit = repoSpec.Ref - } - - // Reset the local repo to the commit we need. Doing a hard reset instead of - // a checkout means we don't create any local branches so we don't need to - // worry about fast-forwarding them with changes from upstream. It also makes - // sure that any changes in the local worktree are cleaned out. - _, err = gitRunner.Run(ctx, "reset", "--hard", commit) - if err != nil { - gitutil.AmendGitExecError(err, func(e *gitutil.GitExecError) { - e.Repo = repoSpec.CloneSpec() - e.Ref = commit - }) - return errors.E(op, errors.Git, errors.Repo(repoSpec.CloneSpec()), err) - } - - // We need to create a temp directory where we can copy the content of the repo. - // During update, we need to checkout multiple versions of the same repo, so - // we can't do merges directly from the cache. - repoSpec.Dir, err = ioutil.TempDir("", "kpt-get-") - if err != nil { - return errors.E(op, errors.Internal, fmt.Errorf("error creating temp directory: %w", err)) - } - repoSpec.Commit = commit - - pkgPath := filepath.Join(dir, repoSpec.Path) - // Verify that the requested path exists in the repo. - _, err = os.Stat(pkgPath) - if os.IsNotExist(err) { - return errors.E(op, - errors.Internal, - err, - fmt.Errorf("path %q does not exist in repo %q", repoSpec.Path, repoSpec.OrgRepo)) - } - - // Copy the content of the pkg into the temp directory. - // Note that we skip the content outside the package directory. - err = copyDir(ctx, pkgPath, repoSpec.AbsPath()) - if err != nil { - return errors.E(op, errors.Internal, fmt.Errorf("error copying package: %w", err)) - } - - // Verify that if a Kptfile exists in the package, it contains the correct - // version of the Kptfile. - _, err = pkg.ReadKptfile(pkgPath) - if err != nil { - // A Kptfile isn't required, so it is fine if there is no Kptfile. - if errors.Is(err, os.ErrNotExist) { - return nil - } - - // If the error is of type KptfileError, we replace it with a - // RemoteKptfileError. This allows us to provide information about the - // git source of the Kptfile instead of the path to some random - // temporary directory. - var kfError *pkg.KptfileError - if errors.As(err, &kfError) { - return &pkg.RemoteKptfileError{ - RepoSpec: repoSpec, - Err: kfError.Err, - } - } - } - return nil -} - -// copyDir copies a src directory to a dst directory. -// copyDir skips copying the .git directory from the src and ignores symlinks. -func copyDir(ctx context.Context, srcDir string, dstDir string) error { - pr := printer.FromContextOrDie(ctx) - opts := copy.Options{ - Skip: func(src string) (bool, error) { - return strings.HasSuffix(src, ".git"), nil - }, - OnSymlink: func(src string) copy.SymlinkAction { - // try to print relative path of symlink - // if we can, else absolute path which is not - // pretty because it contains path to temporary repo dir - displayPath, err := filepath.Rel(srcDir, src) - if err != nil { - displayPath = src - } - pr.Printf("[Warn] Ignoring symlink %q \n", displayPath) - return copy.Skip - }, - } - return copy.Copy(srcDir, dstDir, opts) -} - -func pullAndCopy(ctx context.Context, imageName string, dest string, options ...remote.Option) error { - const op errors.Op = "fetch.pullAndCopy" - // pr := printer.FromContextOrDie(ctx) - - // We need to create a temp directory where we can copy the content of the repo. - // During update, we need to checkout multiple versions of the same repo, so - // we can't do merges directly from the cache. - dir, err := ioutil.TempDir("", "kpt-get-") - if err != nil { - return errors.E(op, errors.Internal, fmt.Errorf("error creating temp directory: %w", err)) - } - defer os.RemoveAll(dir) - - imageDigest, err := OciPullAndExtract(ctx, imageName, dir, options...) - if err != nil { - return errors.E(op, errors.OCI, types.UniquePath(dest), err) - } - - sourcePath := dir - if err := pkgutil.CopyPackage(sourcePath, dest, true, pkg.All); err != nil { - return errors.E(op, types.UniquePath(dest), err) - } - - if err := kptfileutil.UpdateKptfileWithoutOrigin(dest, sourcePath, false); err != nil { - return errors.E(op, types.UniquePath(dest), err) - } - - if err := kptfileutil.UpdateUpstreamLockFromOCI(dest, imageDigest); err != nil { - return errors.E(op, errors.OCI, types.UniquePath(dest), err) - } - - return nil -} - -// OciPullAndExtract uses current credentials (gcloud auth) to pull and -// extract (untar) image files to target directory. The desired version or digest must -// be in the imageName, and the resolved image sha256 digest is returned. -func OciPullAndExtract(ctx context.Context, imageName string, dir string, options ...remote.Option) (name.Reference, error) { - const op errors.Op = "fetch.OciPullAndExtract" - - ref, err := name.ParseReference(imageName) - if err != nil { - return nil, fmt.Errorf("parsing reference %q: %v", imageName, err) - } - - // Pull image from source using provided options for auth credentials - image, err := remote.Image(ref, options...) - if err != nil { - return nil, fmt.Errorf("pulling image %s: %v", imageName, err) - } - - // Stream image files as if single tar (merged layers) - ioReader := mutate.Extract(image) - defer ioReader.Close() - - // Write contents to target dir - // TODO look for a more robust example of an untar loop - tarReader := tar.NewReader(ioReader) - for { - hdr, err := tarReader.Next() - if err == io.EOF { - break - } - if err != nil { - return nil, err - } - path := filepath.Join(dir, hdr.Name) - switch { - case hdr.FileInfo().IsDir(): - if err := os.MkdirAll(path, hdr.FileInfo().Mode()); err != nil { - return nil, err - } - case hdr.Linkname != "": - if err := os.Symlink(hdr.Linkname, path); err != nil { - // just warn for now - fmt.Fprintln(os.Stderr, err) - // return err - } - default: - file, err := os.OpenFile(path, - os.O_WRONLY|os.O_CREATE|os.O_TRUNC, - os.FileMode(hdr.Mode), - ) - if err != nil { - return nil, err - } - defer file.Close() - - _, err = io.Copy(file, tarReader) - if err != nil { - return nil, err - } - } - } - - // Determine the digest of the image that was extracted - imageDigestHash, err := image.Digest() - if err != nil { - return nil, errors.E(op, fmt.Errorf("error calculating image digest: %w", err)) - } - imageDigest := ref.Context().Digest("sha256:" + imageDigestHash.Hex) - - // Return the image with digest when successful, needed for upstreamLock - return imageDigest, nil -} diff --git a/internal/util/get/example_test.go b/internal/util/get/example_test.go index 6d0669e3b7..c818717577 100644 --- a/internal/util/get/example_test.go +++ b/internal/util/get/example_test.go @@ -19,44 +19,45 @@ import ( "github.com/GoogleContainerTools/kpt/internal/printer/fake" "github.com/GoogleContainerTools/kpt/internal/util/get" + "github.com/GoogleContainerTools/kpt/internal/util/upstream" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" ) func ExampleCommand() { - err := get.Command{Git: &kptfilev1.Git{ + err := get.Command{Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: "https://github.com/example-org/example-repo", Ref: "v1.0", - }}.Run(fake.CtxWithDefaultPrinter()) + })}.Run(fake.CtxWithDefaultPrinter()) if err != nil { // handle error } } func ExampleCommand_branch() { - err := get.Command{Git: &kptfilev1.Git{ + err := get.Command{Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: "https://github.com/example-org/example-repo", Ref: "refs/heads/v1.0", - }}.Run(fake.CtxWithDefaultPrinter()) + })}.Run(fake.CtxWithDefaultPrinter()) if err != nil { // handle error } } func ExampleCommand_tag() { - err := get.Command{Git: &kptfilev1.Git{ + err := get.Command{Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: "https://github.com/example-org/example-repo", Ref: "refs/tags/v1.0", - }}.Run(fake.CtxWithDefaultPrinter()) + })}.Run(fake.CtxWithDefaultPrinter()) if err != nil { // handle error } } func ExampleCommand_commit() { - err := get.Command{Git: &kptfilev1.Git{ + err := get.Command{Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: "https://github.com/example-org/example-repo", Ref: "8186bef8e5c0621bf80fa8106bd595aae8b62884", - }}.Run(fake.CtxWithDefaultPrinter()) + })}.Run(fake.CtxWithDefaultPrinter()) if err != nil { // handle error } @@ -64,11 +65,11 @@ func ExampleCommand_commit() { func ExampleCommand_subdir() { err := get.Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: "https://github.com/example-org/example-repo", Ref: "v1.0", Directory: filepath.Join("path", "to", "package"), - }, + }), }.Run(fake.CtxWithDefaultPrinter()) if err != nil { // handle error @@ -77,10 +78,10 @@ func ExampleCommand_subdir() { func ExampleCommand_destination() { err := get.Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: "https://github.com/example-org/example-repo", Ref: "v1.0", - }, + }), Destination: "destination-dir"}.Run(fake.CtxWithDefaultPrinter()) if err != nil { // handle error diff --git a/internal/util/get/get.go b/internal/util/get/get.go index 64d5b99e46..e8e5929182 100644 --- a/internal/util/get/get.go +++ b/internal/util/get/get.go @@ -20,9 +20,7 @@ import ( goerrors "errors" "fmt" "os" - "path" "path/filepath" - "strings" "github.com/GoogleContainerTools/kpt/internal/errors" "github.com/GoogleContainerTools/kpt/internal/pkg" @@ -31,6 +29,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/util/addmergecomment" "github.com/GoogleContainerTools/kpt/internal/util/fetch" "github.com/GoogleContainerTools/kpt/internal/util/stack" + "github.com/GoogleContainerTools/kpt/internal/util/upstream" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" ) @@ -41,8 +40,8 @@ type Command struct { // Git contains information about the git repo to fetch Git *kptfilev1.Git - // Oci contains information about the OCI image to fetch - Oci *kptfilev1.Oci + // Contains information about the upstraem package to fetch + Upstream upstream.Fetcher // Destination is the output directory to clone the package to. Defaults to the name of the package -- // either the base repo name, or the base subdirectory name. @@ -74,27 +73,9 @@ func (c Command) Run(ctx context.Context) error { } kf := kptfileutil.DefaultKptfile(c.Name) - if c.Git != nil { - // normalize path to a filepath - repoDir := c.Git.Directory - if !strings.HasSuffix(repoDir, "file://") { - repoDir = filepath.Join(path.Split(repoDir)) - } - c.Git.Directory = repoDir - kf.Upstream = &kptfilev1.Upstream{ - Type: kptfilev1.GitOrigin, - Git: c.Git, - UpdateStrategy: c.UpdateStrategy, - } - } - if c.Oci != nil { - kf.Upstream = &kptfilev1.Upstream{ - Type: kptfilev1.OciOrigin, - Oci: c.Oci, - UpdateStrategy: c.UpdateStrategy, - } - } + c.Upstream.ApplyUpstream(kf) + kf.Upstream.UpdateStrategy = c.UpdateStrategy err = kptfileutil.WriteFile(c.Destination, kf) if err != nil { @@ -138,13 +119,14 @@ func (c Command) fetchPackages(ctx context.Context, rootPkg *pkg.Pkg) error { if kf.Upstream != nil && kf.UpstreamLock == nil { packageCount += 1 pr.PrintPackage(p, !(p == rootPkg)) - switch kf.Upstream.Type { - case kptfilev1.GitOrigin: - pr.Printf("Fetching %s@%s\n", kf.Upstream.Git.Repo, kf.Upstream.Git.Ref) - case kptfilev1.OciOrigin: - pr.Printf("Fetching %s\n", kf.Upstream.Oci.Image) + + upstream, err := upstream.NewUpstream(kf) + if err != nil { + return errors.E(op, p.UniquePath, err) } - err := (&fetch.Command{ + pr.Printf("Fetching %s\n", upstream.String()) + + err = (&fetch.Command{ Pkg: p, }).Run(ctx) if err != nil { @@ -167,28 +149,11 @@ func (c Command) fetchPackages(ctx context.Context, rootPkg *pkg.Pkg) error { // DefaultValues sets values to the default values if they were unspecified func (c *Command) DefaultValues() error { const op errors.Op = "get.DefaultValues" - if c.Git == nil && c.Oci == nil { + if c.Upstream == nil { return errors.E(op, errors.MissingParam, fmt.Errorf("must specify git repo or image reference information")) } - if c.Git != nil { - g := c.Git - if len(g.Repo) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify repo")) - } - if len(g.Ref) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify ref")) - } - if len(c.Destination) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify destination")) - } - if len(g.Directory) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify directory")) - } - } - if c.Oci != nil { - if len(c.Oci.Image) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify image")) - } + if err := c.Upstream.Validate(); err != nil { + return errors.E(op, err) } if !filepath.IsAbs(c.Destination) { return errors.E(op, errors.InvalidParam, fmt.Errorf("destination must be an absolute path")) diff --git a/internal/util/get/get_test.go b/internal/util/get/get_test.go index 1e30107261..39f2937b6c 100644 --- a/internal/util/get/get_test.go +++ b/internal/util/get/get_test.go @@ -23,6 +23,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/printer/fake" "github.com/GoogleContainerTools/kpt/internal/testutil" "github.com/GoogleContainerTools/kpt/internal/testutil/pkgbuilder" + "github.com/GoogleContainerTools/kpt/internal/util/upstream" . "github.com/GoogleContainerTools/kpt/internal/util/get" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/stretchr/testify/assert" @@ -57,9 +58,9 @@ func TestCommand_Run_failNoRevision(t *testing.T) { defer clean() err := Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: "foo", - }, + }), Destination: w.WorkspaceDirectory, }.Run(fake.CtxWithDefaultPrinter()) if !assert.Error(t, err) { @@ -82,11 +83,11 @@ func TestCommand_Run(t *testing.T) { defer testutil.Chdir(t, w.WorkspaceDirectory)() absPath := filepath.Join(w.WorkspaceDirectory, g.RepoName) - err := Command{Git: &kptfilev1.Git{ + err := Command{Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: "file://" + g.RepoDirectory, Ref: "master", Directory: "/", - }, + }), Destination: absPath}.Run(fake.CtxWithDefaultPrinter()) assert.NoError(t, err) @@ -143,8 +144,8 @@ func TestCommand_Run_subdir(t *testing.T) { defer testutil.Chdir(t, w.WorkspaceDirectory)() absPath := filepath.Join(w.WorkspaceDirectory, subdir) - err := Command{Git: &kptfilev1.Git{ - Repo: g.RepoDirectory, Ref: "refs/heads/master", Directory: subdir}, + err := Command{Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Repo: g.RepoDirectory, Ref: "refs/heads/master", Directory: subdir}), Destination: absPath, }.Run(fake.CtxWithDefaultPrinter()) assert.NoError(t, err) @@ -207,8 +208,8 @@ func TestCommand_Run_subdir_symlinks(t *testing.T) { cliOutput := &bytes.Buffer{} absPath := filepath.Join(w.WorkspaceDirectory, subdir) - err := Command{Git: &kptfilev1.Git{ - Repo: g.RepoDirectory, Ref: "refs/heads/master", Directory: subdir}, + err := Command{Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Repo: g.RepoDirectory, Ref: "refs/heads/master", Directory: subdir}), Destination: absPath, }.Run(fake.CtxWithPrinter(cliOutput, cliOutput)) assert.NoError(t, err) @@ -272,11 +273,11 @@ func TestCommand_Run_destination(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, dest) err := Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "master", Directory: "/", - }, + }), Destination: absPath, }.Run(fake.CtxWithDefaultPrinter()) assert.NoError(t, err) @@ -336,11 +337,11 @@ func TestCommand_Run_subdirAndDestination(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, dest) err := Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "master", Directory: subdir, - }, + }), Destination: absPath, }.Run(fake.CtxWithDefaultPrinter()) assert.NoError(t, err) @@ -416,11 +417,11 @@ func TestCommand_Run_branch(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, g.RepoName) err = Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "refs/heads/exp", Directory: "/", - }, + }), Destination: absPath, }.Run(fake.CtxWithDefaultPrinter()) assert.NoError(t, err) @@ -499,11 +500,11 @@ func TestCommand_Run_tag(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, g.RepoName) err = Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "refs/tags/v2", Directory: "/", - }, + }), Destination: absPath, }.Run(fake.CtxWithDefaultPrinter()) assert.NoError(t, err) @@ -640,11 +641,11 @@ func TestCommand_Run_ref(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, repos[testutil.Upstream].RepoName) err = Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: repos[testutil.Upstream].RepoDirectory, Ref: ref, Directory: tc.directory, - }, + }), Destination: absPath, }.Run(fake.CtxWithDefaultPrinter()) assert.NoError(t, err) @@ -669,11 +670,11 @@ func TestCommand_Run_failExistingDir(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, g.RepoName) err := Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "master", Directory: "/", - }, + }), Destination: absPath, }.Run(fake.CtxWithDefaultPrinter()) assert.NoError(t, err) @@ -723,11 +724,11 @@ func TestCommand_Run_failExistingDir(t *testing.T) { // try to clone and expect a failure err = Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "master", Directory: "/", - }, + }), Destination: absPath, }.Run(fake.CtxWithDefaultPrinter()) if !assert.Error(t, err) { @@ -780,11 +781,11 @@ func TestCommand_Run_nonexistingParentDir(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, "more", "dirs", g.RepoName) err := Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "master", Directory: "/", - }, + }), Destination: absPath, }.Run(fake.CtxWithDefaultPrinter()) assert.NoError(t, err) @@ -800,11 +801,11 @@ func TestCommand_Run_failInvalidRepo(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, "foo") err := Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: "foo", Directory: "/", Ref: "refs/heads/master", - }, + }), Destination: absPath, }.Run(fake.CtxWithDefaultPrinter()) if !assert.Error(t, err) { @@ -830,11 +831,11 @@ func TestCommand_Run_failInvalidBranch(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, g.RepoDirectory) err := Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Directory: "/", Ref: "refs/heads/foo", - }, + }), Destination: absPath, }.Run(fake.CtxWithDefaultPrinter()) if !assert.Error(t, err) { @@ -863,11 +864,11 @@ func TestCommand_Run_failInvalidTag(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, g.RepoDirectory) err := Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Directory: "/", Ref: "refs/tags/foo", - }, + }), Destination: absPath, }.Run(fake.CtxWithDefaultPrinter()) if !assert.Error(t, err) { @@ -1388,11 +1389,11 @@ func TestCommand_Run_subpackages(t *testing.T) { destinationDir := filepath.Join(w.WorkspaceDirectory, targetDir) err = Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: upstreamRepo.RepoDirectory, Directory: tc.directory, Ref: tc.ref, - }, + }), Destination: destinationDir, UpdateStrategy: tc.updateStrategy, }.Run(fake.CtxWithDefaultPrinter()) @@ -1459,11 +1460,11 @@ func TestCommand_Run_symlinks(t *testing.T) { destinationDir := filepath.Join(w.WorkspaceDirectory, upstreamRepo.RepoName) err := Command{ - Git: &kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: upstreamRepo.RepoDirectory, Directory: "/", Ref: "master", - }, + }), Destination: destinationDir, }.Run(fake.CtxWithDefaultPrinter()) if !assert.NoError(t, err) { diff --git a/internal/util/update/update.go b/internal/util/update/update.go index 112bbfc914..752f7e566f 100644 --- a/internal/util/update/update.go +++ b/internal/util/update/update.go @@ -30,10 +30,10 @@ import ( "github.com/GoogleContainerTools/kpt/internal/printer" "github.com/GoogleContainerTools/kpt/internal/types" "github.com/GoogleContainerTools/kpt/internal/util/addmergecomment" - "github.com/GoogleContainerTools/kpt/internal/util/fetch" "github.com/GoogleContainerTools/kpt/internal/util/git" "github.com/GoogleContainerTools/kpt/internal/util/pkgutil" "github.com/GoogleContainerTools/kpt/internal/util/stack" + "github.com/GoogleContainerTools/kpt/internal/util/upstream" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" "sigs.k8s.io/kustomize/kyaml/copyutil" @@ -280,7 +280,7 @@ func (u Command) updateRootPackage(ctx context.Context, p *pkg.Pkg) error { g := kf.Upstream.Git updated := &git.RepoSpec{OrgRepo: g.Repo, Path: g.Directory, Ref: g.Ref} pr.Printf("Fetching upstream from %s@%s\n", kf.Upstream.Git.Repo, kf.Upstream.Git.Ref) - if err := fetch.ClonerUsingGitExec(ctx, updated); err != nil { + if err := upstream.ClonerUsingGitExec(ctx, updated); err != nil { return errors.E(op, p.UniquePath, err) } defer os.RemoveAll(updated.AbsPath()) @@ -290,7 +290,7 @@ func (u Command) updateRootPackage(ctx context.Context, p *pkg.Pkg) error { gLock := kf.UpstreamLock.Git originRepoSpec := &git.RepoSpec{OrgRepo: gLock.Repo, Path: gLock.Directory, Ref: gLock.Commit} pr.Printf("Fetching origin from %s@%s\n", kf.Upstream.Git.Repo, kf.Upstream.Git.Ref) - if err := fetch.ClonerUsingGitExec(ctx, originRepoSpec); err != nil { + if err := upstream.ClonerUsingGitExec(ctx, originRepoSpec); err != nil { return errors.E(op, p.UniquePath, err) } origin = originRepoSpec diff --git a/internal/util/upstream/git.go b/internal/util/upstream/git.go new file mode 100644 index 0000000000..ae5a677b93 --- /dev/null +++ b/internal/util/upstream/git.go @@ -0,0 +1,239 @@ +package upstream + +import ( + "context" + "fmt" + "io/ioutil" + "os" + "path" + "path/filepath" + "strings" + + "github.com/GoogleContainerTools/kpt/internal/errors" + "github.com/GoogleContainerTools/kpt/internal/gitutil" + "github.com/GoogleContainerTools/kpt/internal/pkg" + "github.com/GoogleContainerTools/kpt/internal/printer" + "github.com/GoogleContainerTools/kpt/internal/types" + "github.com/GoogleContainerTools/kpt/internal/util/git" + "github.com/GoogleContainerTools/kpt/internal/util/pkgutil" + v1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" + "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" + "github.com/otiai10/copy" +) + +type gitUpstream struct { + git *v1.Git +} + +var _ Fetcher = &gitUpstream{} + +func NewGitUpstream(git *v1.Git) Fetcher { + return &gitUpstream{ + git: git, + } +} + +func (u* gitUpstream) String() string { + return fmt.Sprintf("%s@%s", u.git.Repo, u.git.Ref) +} + +func (u* gitUpstream) Validate() error { + const op errors.Op = "upstream.Validate" + g := u.git + if len(g.Repo) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify repo")) + } + if len(g.Ref) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify ref")) + } + if len(g.Directory) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify directory")) + } + return nil +} + +func (u* gitUpstream) ApplyUpstream(kf *v1.KptFile) { + repoDir := u.git.Directory + if !strings.HasSuffix(repoDir, "file://") { + repoDir = filepath.Join(path.Split(repoDir)) + } + u.git.Directory = repoDir + + kf.Upstream = &v1.Upstream{ + Type: v1.GitOrigin, + Git: u.git, + } +} + +func (u* gitUpstream) FetchUpstream(ctx context.Context, dest string) error { + repoSpec := &git.RepoSpec{ + OrgRepo: u.git.Repo, + Path: u.git.Directory, + Ref: u.git.Ref, + } + return cloneAndCopy(ctx, repoSpec, dest) +} + + +// cloneAndCopy fetches the provided repo and copies the content into the +// directory specified by dest. The provided name is set as `metadata.name` +// of the Kptfile of the package. +func cloneAndCopy(ctx context.Context, r *git.RepoSpec, dest string) error { + const op errors.Op = "fetch.cloneAndCopy" + pr := printer.FromContextOrDie(ctx) + + err := ClonerUsingGitExec(ctx, r) + if err != nil { + return errors.E(op, errors.Git, types.UniquePath(dest), err) + } + defer os.RemoveAll(r.Dir) + + sourcePath := filepath.Join(r.Dir, r.Path) + pr.Printf("Adding package %q.\n", strings.TrimPrefix(r.Path, "/")) + if err := pkgutil.CopyPackage(sourcePath, dest, true, pkg.All); err != nil { + return errors.E(op, types.UniquePath(dest), err) + } + + if err := kptfileutil.UpdateKptfileWithoutOrigin(dest, sourcePath, false); err != nil { + return errors.E(op, types.UniquePath(dest), err) + } + + if err := kptfileutil.UpdateUpstreamLockFromGit(dest, r); err != nil { + return errors.E(op, errors.Git, types.UniquePath(dest), err) + } + return nil +} + +// ClonerUsingGitExec uses a local git install, as opposed +// to say, some remote API, to obtain a local clone of +// a remote repo. It looks for tags with the directory as a prefix to allow +// for versioning multiple kpt packages in a single repo independently. It +// relies on the private clonerUsingGitExec function to try fetching different +// refs. +func ClonerUsingGitExec(ctx context.Context, repoSpec *git.RepoSpec) error { + const op errors.Op = "fetch.ClonerUsingGitExec" + + // Create a local representation of the upstream repo. This will initialize + // the cache for the specified repo uri if it isn't already there. It also + // fetches and caches all tag and branch refs from the upstream repo. + upstreamRepo, err := gitutil.NewGitUpstreamRepo(ctx, repoSpec.CloneSpec()) + if err != nil { + return errors.E(op, errors.Git, errors.Repo(repoSpec.CloneSpec()), err) + } + + // Check if we have a ref in the upstream that matches the package-specific + // reference. If we do, we use that reference. + ps := strings.Split(repoSpec.Path, "/") + for len(ps) != 0 { + p := path.Join(ps...) + packageRef := path.Join(strings.TrimLeft(p, "/"), repoSpec.Ref) + if _, found := upstreamRepo.ResolveTag(packageRef); found { + repoSpec.Ref = packageRef + break + } + ps = ps[:len(ps)-1] + } + + // Pull the required ref into the repo git cache. + dir, err := upstreamRepo.GetRepo(ctx, []string{repoSpec.Ref}) + if err != nil { + return errors.E(op, errors.Git, errors.Repo(repoSpec.CloneSpec()), err) + } + + gitRunner, err := gitutil.NewLocalGitRunner(dir) + if err != nil { + return errors.E(op, errors.Git, errors.Repo(repoSpec.CloneSpec()), err) + } + + // Find the commit SHA for the ref that was just fetched. We need the SHA + // rather than the ref to be able to do a hard reset of the cache repo. + commit, found := upstreamRepo.ResolveRef(repoSpec.Ref) + if !found { + commit = repoSpec.Ref + } + + // Reset the local repo to the commit we need. Doing a hard reset instead of + // a checkout means we don't create any local branches so we don't need to + // worry about fast-forwarding them with changes from upstream. It also makes + // sure that any changes in the local worktree are cleaned out. + _, err = gitRunner.Run(ctx, "reset", "--hard", commit) + if err != nil { + gitutil.AmendGitExecError(err, func(e *gitutil.GitExecError) { + e.Repo = repoSpec.CloneSpec() + e.Ref = commit + }) + return errors.E(op, errors.Git, errors.Repo(repoSpec.CloneSpec()), err) + } + + // We need to create a temp directory where we can copy the content of the repo. + // During update, we need to checkout multiple versions of the same repo, so + // we can't do merges directly from the cache. + repoSpec.Dir, err = ioutil.TempDir("", "kpt-get-") + if err != nil { + return errors.E(op, errors.Internal, fmt.Errorf("error creating temp directory: %w", err)) + } + repoSpec.Commit = commit + + pkgPath := filepath.Join(dir, repoSpec.Path) + // Verify that the requested path exists in the repo. + _, err = os.Stat(pkgPath) + if os.IsNotExist(err) { + return errors.E(op, + errors.Internal, + err, + fmt.Errorf("path %q does not exist in repo %q", repoSpec.Path, repoSpec.OrgRepo)) + } + + // Copy the content of the pkg into the temp directory. + // Note that we skip the content outside the package directory. + err = copyDir(ctx, pkgPath, repoSpec.AbsPath()) + if err != nil { + return errors.E(op, errors.Internal, fmt.Errorf("error copying package: %w", err)) + } + + // Verify that if a Kptfile exists in the package, it contains the correct + // version of the Kptfile. + _, err = pkg.ReadKptfile(pkgPath) + if err != nil { + // A Kptfile isn't required, so it is fine if there is no Kptfile. + if errors.Is(err, os.ErrNotExist) { + return nil + } + + // If the error is of type KptfileError, we replace it with a + // RemoteKptfileError. This allows us to provide information about the + // git source of the Kptfile instead of the path to some random + // temporary directory. + var kfError *pkg.KptfileError + if errors.As(err, &kfError) { + return &pkg.RemoteKptfileError{ + RepoSpec: repoSpec, + Err: kfError.Err, + } + } + } + return nil +} + +// copyDir copies a src directory to a dst directory. +// copyDir skips copying the .git directory from the src and ignores symlinks. +func copyDir(ctx context.Context, srcDir string, dstDir string) error { + pr := printer.FromContextOrDie(ctx) + opts := copy.Options{ + Skip: func(src string) (bool, error) { + return strings.HasSuffix(src, ".git"), nil + }, + OnSymlink: func(src string) copy.SymlinkAction { + // try to print relative path of symlink + // if we can, else absolute path which is not + // pretty because it contains path to temporary repo dir + displayPath, err := filepath.Rel(srcDir, src) + if err != nil { + displayPath = src + } + pr.Printf("[Warn] Ignoring symlink %q \n", displayPath) + return copy.Skip + }, + } + return copy.Copy(srcDir, dstDir, opts) +} diff --git a/internal/util/upstream/git_test.go b/internal/util/upstream/git_test.go new file mode 100644 index 0000000000..a3595254bc --- /dev/null +++ b/internal/util/upstream/git_test.go @@ -0,0 +1,96 @@ +package upstream + +import ( + "reflect" + "testing" + + v1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" +) + +func TestNewGitFetcher(t *testing.T) { + type args struct { + git *v1.Git + } + tests := []struct { + name string + args args + want Fetcher + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := NewGitUpstream(tt.args.git); !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewGitFetcher() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_gitUpstream_String(t *testing.T) { + type fields struct { + git *v1.Git + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "Returns repo ref string", + fields: fields{ + git: &v1.Git{ + Repo: "https://hostname/repo.git", + Ref: "main", + }, + }, + want: "https://hostname/repo.git@main", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + u := &gitUpstream{ + git: tt.fields.git, + } + if got := u.String(); got != tt.want { + t.Errorf("gitUpstream.String() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_gitUpstream_ApplyUpstream(t *testing.T) { + type fields struct { + git *v1.Git + } + type args struct { + kf *v1.KptFile + } + tests := []struct { + name string + fields fields + args args + }{ + { + name: "Sets upstream to git", + fields: fields{ + git: &v1.Git{ + Repo: "https://hostname/repo.git", + Directory: "dir/path", + Ref: "main", + }, + }, + args: args{ + kf: &v1.KptFile{}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + u := &gitUpstream{ + git: tt.fields.git, + } + u.ApplyUpstream(tt.args.kf) + }) + } +} diff --git a/internal/util/upstream/oci.go b/internal/util/upstream/oci.go new file mode 100644 index 0000000000..a3b67a9c0a --- /dev/null +++ b/internal/util/upstream/oci.go @@ -0,0 +1,162 @@ +package upstream + +import ( + "archive/tar" + "context" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + + "github.com/GoogleContainerTools/kpt/internal/errors" + "github.com/GoogleContainerTools/kpt/internal/pkg" + "github.com/GoogleContainerTools/kpt/internal/types" + "github.com/GoogleContainerTools/kpt/internal/util/pkgutil" + v1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" + "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" + "github.com/google/go-containerregistry/pkg/gcrane" + "github.com/google/go-containerregistry/pkg/name" + "github.com/google/go-containerregistry/pkg/v1/mutate" + "github.com/google/go-containerregistry/pkg/v1/remote" +) + +type ociUpstream struct { + image string +} + +var _ Fetcher = &ociUpstream{} + +func NewOciUpstream(oci * v1.Oci) Fetcher { + return &ociUpstream{ + image: oci.Image, + } +} + +func (u* ociUpstream) String() string { + return u.image +} + +func (u *ociUpstream) ApplyUpstream(kf *v1.KptFile) { + + kf.Upstream = &v1.Upstream{ + Type: v1.OciOrigin, + Oci: &v1.Oci{ + Image: u.image, + }, + } +} + +func (u* ociUpstream) Validate() error { + const op errors.Op = "upstream.Validate" + if len(u.image) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify image")) + } + return nil +} + +func (u *ociUpstream) FetchUpstream(ctx context.Context, dest string) error { + const op errors.Op = "upstream.FetchUpstream" + // pr := printer.FromContextOrDie(ctx) + + // We need to create a temp directory where we can copy the content of the repo. + // During update, we need to checkout multiple versions of the same repo, so + // we can't do merges directly from the cache. + dir, err := ioutil.TempDir("", "kpt-get-") + if err != nil { + return errors.E(op, errors.Internal, fmt.Errorf("error creating temp directory: %w", err)) + } + defer os.RemoveAll(dir) + + imageDigest, err := pullAndExtract(ctx, u.image, dir, remote.WithAuthFromKeychain(gcrane.Keychain)) + if err != nil { + return errors.E(op, errors.OCI, types.UniquePath(dest), err) + } + + sourcePath := dir + if err := pkgutil.CopyPackage(sourcePath, dest, true, pkg.All); err != nil { + return errors.E(op, types.UniquePath(dest), err) + } + + if err := kptfileutil.UpdateKptfileWithoutOrigin(dest, sourcePath, false); err != nil { + return errors.E(op, types.UniquePath(dest), err) + } + + if err := kptfileutil.UpdateUpstreamLockFromOCI(dest, imageDigest); err != nil { + return errors.E(op, errors.OCI, types.UniquePath(dest), err) + } + + return nil +} + +// pullAndExtract uses current credentials (gcloud auth) to pull and +// extract (untar) image files to target directory. The desired version or digest must +// be in the imageName, and the resolved image sha256 digest is returned. +func pullAndExtract(ctx context.Context, imageName string, dir string, options ...remote.Option) (name.Reference, error) { + const op errors.Op = "upstream.pullAndExtract" + + ref, err := name.ParseReference(imageName) + if err != nil { + return nil, fmt.Errorf("parsing reference %q: %v", imageName, err) + } + + // Pull image from source using provided options for auth credentials + image, err := remote.Image(ref, options...) + if err != nil { + return nil, fmt.Errorf("pulling image %s: %v", imageName, err) + } + + // Stream image files as if single tar (merged layers) + ioReader := mutate.Extract(image) + defer ioReader.Close() + + // Write contents to target dir + // TODO look for a more robust example of an untar loop + tarReader := tar.NewReader(ioReader) + for { + hdr, err := tarReader.Next() + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + path := filepath.Join(dir, hdr.Name) + switch { + case hdr.FileInfo().IsDir(): + if err := os.MkdirAll(path, hdr.FileInfo().Mode()); err != nil { + return nil, err + } + case hdr.Linkname != "": + if err := os.Symlink(hdr.Linkname, path); err != nil { + // just warn for now + fmt.Fprintln(os.Stderr, err) + // return err + } + default: + file, err := os.OpenFile(path, + os.O_WRONLY|os.O_CREATE|os.O_TRUNC, + os.FileMode(hdr.Mode), + ) + if err != nil { + return nil, err + } + defer file.Close() + + _, err = io.Copy(file, tarReader) + if err != nil { + return nil, err + } + } + } + + // Determine the digest of the image that was extracted + imageDigestHash, err := image.Digest() + if err != nil { + return nil, errors.E(op, fmt.Errorf("error calculating image digest: %w", err)) + } + imageDigest := ref.Context().Digest("sha256:" + imageDigestHash.Hex) + + // Return the image with digest when successful, needed for upstreamLock + return imageDigest, nil +} diff --git a/internal/util/upstream/upstream.go b/internal/util/upstream/upstream.go new file mode 100644 index 0000000000..00991f78c9 --- /dev/null +++ b/internal/util/upstream/upstream.go @@ -0,0 +1,37 @@ +package upstream + +import ( + "context" + "fmt" + + "github.com/GoogleContainerTools/kpt/internal/errors" + kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" +) + +type Fetcher interface { + fmt.Stringer + Validate() error + ApplyUpstream(kf *kptfilev1.KptFile) + FetchUpstream(ctx context.Context, dest string) error +} + +func NewUpstream(kf *kptfilev1.KptFile) (Fetcher, error) { + const op errors.Op = "upstream.NewUpstreamFetcher" + if kf != nil && kf.Upstream != nil { + switch kf.Upstream.Type{ + case kptfilev1.GitOrigin: + if kf.Upstream.Git != nil { + return &gitUpstream{ + git: kf.Upstream.Git, + }, nil + } + case kptfilev1.OciOrigin: + if kf.Upstream.Oci != nil { + return &ociUpstream{ + image: kf.Upstream.Oci.Image, + }, nil + } + } + } + return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile upstream type must be one of: %s,%s", kptfilev1.GitOrigin, kptfilev1.OciOrigin)) +} diff --git a/internal/util/upstream/upstream_test.go b/internal/util/upstream/upstream_test.go new file mode 100644 index 0000000000..86cd7c7ed2 --- /dev/null +++ b/internal/util/upstream/upstream_test.go @@ -0,0 +1,116 @@ +package upstream + +import ( + "reflect" + "testing" + + kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" +) + +func TestNewUpstream(t *testing.T) { + type args struct { + kf *kptfilev1.KptFile + } + tests := []struct { + name string + args args + want Fetcher + wantErr bool + }{ + { + name: "returns git upstream", + args: args{ + kf: &kptfilev1.KptFile{ + Upstream: &kptfilev1.Upstream{ + Type: kptfilev1.GitOrigin, + Git: &kptfilev1.Git{ + Repo: "repo-name", + Directory: "dir-name", + Ref: "ref-name", + }, + }, + }, + }, + want: &gitUpstream{ + git: &kptfilev1.Git{ + Repo: "repo-name", + Directory: "dir-name", + Ref: "ref-name", + }, + }, + wantErr: false, + }, + { + name: "returns oci upstream", + args: args{ + kf: &kptfilev1.KptFile{ + Upstream: &kptfilev1.Upstream{ + Type: kptfilev1.OciOrigin, + Oci: &kptfilev1.Oci{ + Image: "image-name", + }, + }, + }, + }, + want: &ociUpstream{ + image: "image-name", + }, + wantErr: false, + }, + { + name: "empty type fails", + args: args{ + kf: &kptfilev1.KptFile{ + Upstream: &kptfilev1.Upstream{ + }, + }, + }, + want: nil, + wantErr: true, + }, + { + name: "nil upstream fails", + args: args{ + kf: &kptfilev1.KptFile{}, + }, + want: nil, + wantErr: true, + }, + { + name: "nil git fails", + args: args{ + kf: &kptfilev1.KptFile{ + Upstream: &kptfilev1.Upstream{ + Type: kptfilev1.GitOrigin, + }, + }, + }, + want: nil, + wantErr: true, + }, + { + name: "nil oci fails", + args: args{ + kf: &kptfilev1.KptFile{ + Upstream: &kptfilev1.Upstream{ + Type: kptfilev1.OciOrigin, + }, + }, + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := NewUpstream(tt.args.kf) + if (err != nil) != tt.wantErr { + t.Errorf("NewUpstream() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewUpstream() = %v, want %v", got, tt.want) + } + }) + } +} From 0005f7320cd993daa8d72c948f258f11645e09ab Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Thu, 4 Nov 2021 02:57:20 +0000 Subject: [PATCH 09/26] go fmt fixes --- internal/cmdrender/cmdrender_test.go | 14 ++++ internal/fnruntime/utils_test.go | 14 ++++ internal/testutil/setup_manager.go | 2 +- internal/util/get/get.go | 2 +- internal/util/get/get_test.go | 2 +- internal/util/httputil/httputil.go | 14 ++++ internal/util/parse/parse.go | 2 +- internal/util/upstream/git.go | 29 +++++-- internal/util/upstream/git_test.go | 26 +++++-- internal/util/upstream/oci.go | 30 ++++++-- internal/util/upstream/upstream.go | 20 ++++- internal/util/upstream/upstream_test.go | 77 +++++++++++-------- .../cli-utils/status/printers/list/base.go | 14 ++++ 13 files changed, 185 insertions(+), 61 deletions(-) diff --git a/internal/cmdrender/cmdrender_test.go b/internal/cmdrender/cmdrender_test.go index f595bd08ea..c1614e5b16 100644 --- a/internal/cmdrender/cmdrender_test.go +++ b/internal/cmdrender/cmdrender_test.go @@ -1,3 +1,17 @@ +// Copyright 2021 Google LLC +// +// 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 cmdrender import ( diff --git a/internal/fnruntime/utils_test.go b/internal/fnruntime/utils_test.go index c979584688..dafb230d76 100644 --- a/internal/fnruntime/utils_test.go +++ b/internal/fnruntime/utils_test.go @@ -1,3 +1,17 @@ +// Copyright 2021 Google LLC +// +// 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 fnruntime import ( diff --git a/internal/testutil/setup_manager.go b/internal/testutil/setup_manager.go index da66ba8be5..c771eaaf8d 100644 --- a/internal/testutil/setup_manager.go +++ b/internal/testutil/setup_manager.go @@ -107,7 +107,7 @@ func (g *TestSetupManager) Init() bool { // Get the content from the upstream repo into the local workspace. if !assert.NoError(g.T, get.Command{ Destination: filepath.Join(g.LocalWorkspace.WorkspaceDirectory, g.targetDir), - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ Repo: g.Repos[Upstream].RepoDirectory, Ref: g.GetRef, Directory: g.GetSubDirectory, diff --git a/internal/util/get/get.go b/internal/util/get/get.go index e8e5929182..6f2a313a95 100644 --- a/internal/util/get/get.go +++ b/internal/util/get/get.go @@ -125,7 +125,7 @@ func (c Command) fetchPackages(ctx context.Context, rootPkg *pkg.Pkg) error { return errors.E(op, p.UniquePath, err) } pr.Printf("Fetching %s\n", upstream.String()) - + err = (&fetch.Command{ Pkg: p, }).Run(ctx) diff --git a/internal/util/get/get_test.go b/internal/util/get/get_test.go index 39f2937b6c..d3becdab47 100644 --- a/internal/util/get/get_test.go +++ b/internal/util/get/get_test.go @@ -23,8 +23,8 @@ import ( "github.com/GoogleContainerTools/kpt/internal/printer/fake" "github.com/GoogleContainerTools/kpt/internal/testutil" "github.com/GoogleContainerTools/kpt/internal/testutil/pkgbuilder" - "github.com/GoogleContainerTools/kpt/internal/util/upstream" . "github.com/GoogleContainerTools/kpt/internal/util/get" + "github.com/GoogleContainerTools/kpt/internal/util/upstream" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/kio" diff --git a/internal/util/httputil/httputil.go b/internal/util/httputil/httputil.go index 17a9cc5142..fad80d9689 100644 --- a/internal/util/httputil/httputil.go +++ b/internal/util/httputil/httputil.go @@ -1,3 +1,17 @@ +// Copyright 2021 Google LLC +// +// 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 httputil import ( diff --git a/internal/util/parse/parse.go b/internal/util/parse/parse.go index f082c91f7c..21fca6462c 100644 --- a/internal/util/parse/parse.go +++ b/internal/util/parse/parse.go @@ -35,7 +35,7 @@ type OciTarget struct { func OciParseArgs(ctx context.Context, args []string) (OciTarget, error) { oci := OciTarget{} - if args[0] == "-" { + if args[0] == "-" { return oci, nil } diff --git a/internal/util/upstream/git.go b/internal/util/upstream/git.go index ae5a677b93..cdce4b460f 100644 --- a/internal/util/upstream/git.go +++ b/internal/util/upstream/git.go @@ -1,3 +1,17 @@ +// Copyright 2021 Google LLC +// +// 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 upstream import ( @@ -28,16 +42,16 @@ type gitUpstream struct { var _ Fetcher = &gitUpstream{} func NewGitUpstream(git *v1.Git) Fetcher { - return &gitUpstream{ + return &gitUpstream{ git: git, } } -func (u* gitUpstream) String() string { +func (u *gitUpstream) String() string { return fmt.Sprintf("%s@%s", u.git.Repo, u.git.Ref) } -func (u* gitUpstream) Validate() error { +func (u *gitUpstream) Validate() error { const op errors.Op = "upstream.Validate" g := u.git if len(g.Repo) == 0 { @@ -52,7 +66,7 @@ func (u* gitUpstream) Validate() error { return nil } -func (u* gitUpstream) ApplyUpstream(kf *v1.KptFile) { +func (u *gitUpstream) ApplyUpstream(kf *v1.KptFile) { repoDir := u.git.Directory if !strings.HasSuffix(repoDir, "file://") { repoDir = filepath.Join(path.Split(repoDir)) @@ -60,12 +74,12 @@ func (u* gitUpstream) ApplyUpstream(kf *v1.KptFile) { u.git.Directory = repoDir kf.Upstream = &v1.Upstream{ - Type: v1.GitOrigin, - Git: u.git, + Type: v1.GitOrigin, + Git: u.git, } } -func (u* gitUpstream) FetchUpstream(ctx context.Context, dest string) error { +func (u *gitUpstream) FetchUpstream(ctx context.Context, dest string) error { repoSpec := &git.RepoSpec{ OrgRepo: u.git.Repo, Path: u.git.Directory, @@ -74,7 +88,6 @@ func (u* gitUpstream) FetchUpstream(ctx context.Context, dest string) error { return cloneAndCopy(ctx, repoSpec, dest) } - // cloneAndCopy fetches the provided repo and copies the content into the // directory specified by dest. The provided name is set as `metadata.name` // of the Kptfile of the package. diff --git a/internal/util/upstream/git_test.go b/internal/util/upstream/git_test.go index a3595254bc..a5f46bd056 100644 --- a/internal/util/upstream/git_test.go +++ b/internal/util/upstream/git_test.go @@ -1,3 +1,17 @@ +// Copyright 2021 Google LLC +// +// 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 upstream import ( @@ -37,14 +51,14 @@ func Test_gitUpstream_String(t *testing.T) { want string }{ { - name: "Returns repo ref string", + name: "Returns repo ref string", fields: fields{ git: &v1.Git{ - Repo: "https://hostname/repo.git", - Ref: "main", + Repo: "https://hostname/repo.git", + Ref: "main", }, }, - want: "https://hostname/repo.git@main", + want: "https://hostname/repo.git@main", }, } for _, tt := range tests { @@ -72,7 +86,7 @@ func Test_gitUpstream_ApplyUpstream(t *testing.T) { args args }{ { - name: "Sets upstream to git", + name: "Sets upstream to git", fields: fields{ git: &v1.Git{ Repo: "https://hostname/repo.git", @@ -80,7 +94,7 @@ func Test_gitUpstream_ApplyUpstream(t *testing.T) { Ref: "main", }, }, - args: args{ + args: args{ kf: &v1.KptFile{}, }, }, diff --git a/internal/util/upstream/oci.go b/internal/util/upstream/oci.go index a3b67a9c0a..93b42f8c02 100644 --- a/internal/util/upstream/oci.go +++ b/internal/util/upstream/oci.go @@ -1,3 +1,17 @@ +// Copyright 2021 Google LLC +// +// 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 upstream import ( @@ -27,27 +41,27 @@ type ociUpstream struct { var _ Fetcher = &ociUpstream{} -func NewOciUpstream(oci * v1.Oci) Fetcher { +func NewOciUpstream(oci *v1.Oci) Fetcher { return &ociUpstream{ image: oci.Image, } } -func (u* ociUpstream) String() string { - return u.image +func (u *ociUpstream) String() string { + return u.image } func (u *ociUpstream) ApplyUpstream(kf *v1.KptFile) { - + kf.Upstream = &v1.Upstream{ - Type: v1.OciOrigin, + Type: v1.OciOrigin, Oci: &v1.Oci{ Image: u.image, }, } } -func (u* ociUpstream) Validate() error { +func (u *ociUpstream) Validate() error { const op errors.Op = "upstream.Validate" if len(u.image) == 0 { return errors.E(op, errors.MissingParam, fmt.Errorf("must specify image")) @@ -68,7 +82,7 @@ func (u *ociUpstream) FetchUpstream(ctx context.Context, dest string) error { } defer os.RemoveAll(dir) - imageDigest, err := pullAndExtract(ctx, u.image, dir, remote.WithAuthFromKeychain(gcrane.Keychain)) + imageDigest, err := pullAndExtract(u.image, dir, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) if err != nil { return errors.E(op, errors.OCI, types.UniquePath(dest), err) } @@ -92,7 +106,7 @@ func (u *ociUpstream) FetchUpstream(ctx context.Context, dest string) error { // pullAndExtract uses current credentials (gcloud auth) to pull and // extract (untar) image files to target directory. The desired version or digest must // be in the imageName, and the resolved image sha256 digest is returned. -func pullAndExtract(ctx context.Context, imageName string, dir string, options ...remote.Option) (name.Reference, error) { +func pullAndExtract(imageName string, dir string, options ...remote.Option) (name.Reference, error) { const op errors.Op = "upstream.pullAndExtract" ref, err := name.ParseReference(imageName) diff --git a/internal/util/upstream/upstream.go b/internal/util/upstream/upstream.go index 00991f78c9..255da9e0c0 100644 --- a/internal/util/upstream/upstream.go +++ b/internal/util/upstream/upstream.go @@ -1,3 +1,17 @@ +// Copyright 2021 Google LLC +// +// 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 upstream import ( @@ -18,16 +32,16 @@ type Fetcher interface { func NewUpstream(kf *kptfilev1.KptFile) (Fetcher, error) { const op errors.Op = "upstream.NewUpstreamFetcher" if kf != nil && kf.Upstream != nil { - switch kf.Upstream.Type{ + switch kf.Upstream.Type { case kptfilev1.GitOrigin: if kf.Upstream.Git != nil { - return &gitUpstream{ + return &gitUpstream{ git: kf.Upstream.Git, }, nil } case kptfilev1.OciOrigin: if kf.Upstream.Oci != nil { - return &ociUpstream{ + return &ociUpstream{ image: kf.Upstream.Oci.Image, }, nil } diff --git a/internal/util/upstream/upstream_test.go b/internal/util/upstream/upstream_test.go index 86cd7c7ed2..8aa4284a72 100644 --- a/internal/util/upstream/upstream_test.go +++ b/internal/util/upstream/upstream_test.go @@ -1,3 +1,17 @@ +// Copyright 2021 Google LLC +// +// 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 upstream import ( @@ -18,20 +32,20 @@ func TestNewUpstream(t *testing.T) { wantErr bool }{ { - name: "returns git upstream", - args: args{ + name: "returns git upstream", + args: args{ kf: &kptfilev1.KptFile{ - Upstream: &kptfilev1.Upstream{ - Type: kptfilev1.GitOrigin, - Git: &kptfilev1.Git{ + Upstream: &kptfilev1.Upstream{ + Type: kptfilev1.GitOrigin, + Git: &kptfilev1.Git{ Repo: "repo-name", Directory: "dir-name", Ref: "ref-name", - }, + }, }, }, }, - want: &gitUpstream{ + want: &gitUpstream{ git: &kptfilev1.Git{ Repo: "repo-name", Directory: "dir-name", @@ -41,63 +55,62 @@ func TestNewUpstream(t *testing.T) { wantErr: false, }, { - name: "returns oci upstream", - args: args{ + name: "returns oci upstream", + args: args{ kf: &kptfilev1.KptFile{ - Upstream: &kptfilev1.Upstream{ - Type: kptfilev1.OciOrigin, - Oci: &kptfilev1.Oci{ + Upstream: &kptfilev1.Upstream{ + Type: kptfilev1.OciOrigin, + Oci: &kptfilev1.Oci{ Image: "image-name", - }, + }, }, }, }, - want: &ociUpstream{ + want: &ociUpstream{ image: "image-name", }, wantErr: false, }, { - name: "empty type fails", - args: args{ + name: "empty type fails", + args: args{ kf: &kptfilev1.KptFile{ - Upstream: &kptfilev1.Upstream{ - }, + Upstream: &kptfilev1.Upstream{}, }, }, - want: nil, + want: nil, wantErr: true, }, { - name: "nil upstream fails", - args: args{ + name: "nil upstream fails", + args: args{ kf: &kptfilev1.KptFile{}, }, - want: nil, + want: nil, wantErr: true, }, { - name: "nil git fails", - args: args{ + name: "nil git fails", + args: args{ kf: &kptfilev1.KptFile{ - Upstream: &kptfilev1.Upstream{ - Type: kptfilev1.GitOrigin, + Upstream: &kptfilev1.Upstream{ + Type: kptfilev1.GitOrigin, }, }, }, - want: nil, + want: nil, wantErr: true, }, { - name: "nil oci fails", - args: args{ + name: "nil oci fails", + args: args{ kf: &kptfilev1.KptFile{ - Upstream: &kptfilev1.Upstream{ - Type: kptfilev1.OciOrigin, + Upstream: &kptfilev1.Upstream{ + Type: kptfilev1.OciOrigin, }, }, }, - want: nil, + want: nil, wantErr: true, }, } diff --git a/thirdparty/cli-utils/status/printers/list/base.go b/thirdparty/cli-utils/status/printers/list/base.go index 987ba3c5e0..a23978c83e 100644 --- a/thirdparty/cli-utils/status/printers/list/base.go +++ b/thirdparty/cli-utils/status/printers/list/base.go @@ -1,3 +1,17 @@ +// Copyright 2021 Google LLC +// +// 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 list import ( From 0d9df00d1f837e585758f532f3780de6e04680f1 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Thu, 4 Nov 2021 03:03:04 +0000 Subject: [PATCH 10/26] Ignore scopelint in table tests --- internal/util/upstream/git_test.go | 3 +++ internal/util/upstream/upstream_test.go | 1 + 2 files changed, 4 insertions(+) diff --git a/internal/util/upstream/git_test.go b/internal/util/upstream/git_test.go index a5f46bd056..c9ab2023c7 100644 --- a/internal/util/upstream/git_test.go +++ b/internal/util/upstream/git_test.go @@ -21,6 +21,7 @@ import ( v1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" ) +//nolint:scopelint func TestNewGitFetcher(t *testing.T) { type args struct { git *v1.Git @@ -41,6 +42,7 @@ func TestNewGitFetcher(t *testing.T) { } } +//nolint:scopelint func Test_gitUpstream_String(t *testing.T) { type fields struct { git *v1.Git @@ -73,6 +75,7 @@ func Test_gitUpstream_String(t *testing.T) { } } +//nolint:scopelint func Test_gitUpstream_ApplyUpstream(t *testing.T) { type fields struct { git *v1.Git diff --git a/internal/util/upstream/upstream_test.go b/internal/util/upstream/upstream_test.go index 8aa4284a72..4c66f66fa8 100644 --- a/internal/util/upstream/upstream_test.go +++ b/internal/util/upstream/upstream_test.go @@ -21,6 +21,7 @@ import ( kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" ) +//nolint:scopelint func TestNewUpstream(t *testing.T) { type args struct { kf *kptfilev1.KptFile From 0b406cbbcdf53048fa5cbec7c34faec5693e98ed Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Fri, 5 Nov 2021 04:42:24 +0000 Subject: [PATCH 11/26] Adding support for `kpt pkg update` --- internal/util/fetch/fetch.go | 4 +- internal/util/get/get.go | 2 +- internal/util/update/update.go | 93 +++++++++++---------- internal/util/upstream/git.go | 81 ++++++++++++++++-- internal/util/upstream/git_test.go | 37 --------- internal/util/upstream/oci.go | 104 ++++++++++++++++++++---- internal/util/upstream/upstream.go | 47 ++++++++--- internal/util/upstream/upstream_test.go | 4 +- pkg/kptfile/kptfileutil/util.go | 55 ++++--------- 9 files changed, 269 insertions(+), 158 deletions(-) diff --git a/internal/util/fetch/fetch.go b/internal/util/fetch/fetch.go index cc11aa3151..d384e2d687 100644 --- a/internal/util/fetch/fetch.go +++ b/internal/util/fetch/fetch.go @@ -43,12 +43,12 @@ func (c Command) Run(ctx context.Context) error { return errors.E(op, c.Pkg.UniquePath, err) } - upstream, err := upstream.NewUpstream(kf) + ups, err := upstream.NewUpstream(kf) if err != nil { return errors.E(op, c.Pkg.UniquePath, err) } - if err := upstream.FetchUpstream(ctx, c.Pkg.UniquePath.String()); err != nil { + if err := ups.CloneUpstream(ctx, c.Pkg.UniquePath.String()); err != nil { return errors.E(op, c.Pkg.UniquePath, err) } diff --git a/internal/util/get/get.go b/internal/util/get/get.go index 6f2a313a95..cf60c23046 100644 --- a/internal/util/get/get.go +++ b/internal/util/get/get.go @@ -74,7 +74,7 @@ func (c Command) Run(ctx context.Context) error { kf := kptfileutil.DefaultKptfile(c.Name) - c.Upstream.ApplyUpstream(kf) + kf.Upstream = c.Upstream.BuildUpstream() kf.Upstream.UpdateStrategy = c.UpdateStrategy err = kptfileutil.WriteFile(c.Destination, kf) diff --git a/internal/util/update/update.go b/internal/util/update/update.go index 752f7e566f..cc09dce659 100644 --- a/internal/util/update/update.go +++ b/internal/util/update/update.go @@ -20,7 +20,6 @@ import ( "fmt" "io/ioutil" "os" - "path" "path/filepath" "strings" @@ -30,7 +29,6 @@ import ( "github.com/GoogleContainerTools/kpt/internal/printer" "github.com/GoogleContainerTools/kpt/internal/types" "github.com/GoogleContainerTools/kpt/internal/util/addmergecomment" - "github.com/GoogleContainerTools/kpt/internal/util/git" "github.com/GoogleContainerTools/kpt/internal/util/pkgutil" "github.com/GoogleContainerTools/kpt/internal/util/stack" "github.com/GoogleContainerTools/kpt/internal/util/upstream" @@ -113,23 +111,31 @@ func (u Command) Run(ctx context.Context) error { return errors.E(op, errors.MissingParam, "pkg must be provided") } - // require package is checked into git before trying to update it - if err := checkIfCommitted(ctx, u.Pkg); err != nil { + rootKf, err := u.Pkg.Kptfile() + if err != nil { return errors.E(op, u.Pkg.UniquePath, err) } - rootKf, err := u.Pkg.Kptfile() + rootUps, err := upstream.NewUpstream(rootKf) if err != nil { - return errors.E(op, u.Pkg.UniquePath, err) + return errors.E(op, u.Pkg.UniquePath, fmt.Errorf("package must have an upstream reference: %v", err)) + } + + if rootKf.Upstream.Type == kptfilev1.GitOrigin { + // require package is checked into git before trying to update it + if err := checkIfCommitted(ctx, u.Pkg); err != nil { + return errors.E(op, u.Pkg.UniquePath, err) + } } - if rootKf.Upstream == nil || rootKf.Upstream.Git == nil { - return errors.E(op, u.Pkg.UniquePath, - fmt.Errorf("package must have an upstream reference")) + originalRootKfRef,err := rootUps.Ref() + if err != nil { + return errors.E(op, u.Pkg.UniquePath, err) } - originalRootKfRef := rootKf.Upstream.Git.Ref if u.Ref != "" { - rootKf.Upstream.Git.Ref = u.Ref + if err := rootUps.SetRef(u.Ref); err != nil { + return errors.E(op, u.Pkg.UniquePath, err) + } } if u.Strategy != "" { rootKf.Upstream.UpdateStrategy = u.Strategy @@ -164,11 +170,11 @@ func (u Command) Run(ctx context.Context) error { return errors.E(op, p.UniquePath, err) } - if subKf.Upstream != nil && subKf.Upstream.Git != nil { + if subUps, err := upstream.NewUpstream(subKf); err == nil { // update subpackage kf ref/strategy if current pkg is a subpkg of root pkg or is root pkg // and if original root pkg ref matches the subpkg ref - if shouldUpdateSubPkgRef(subKf, rootKf, originalRootKfRef) { - updateSubKf(subKf, u.Ref, u.Strategy) + if upstream.ShouldUpdateSubPkgRef(subUps, rootUps, originalRootKfRef) { + updateSubKf(subKf, subUps, u.Ref, u.Strategy) err = kptfileutil.WriteFile(subPkg.UniquePath.String(), subKf) if err != nil { return errors.E(op, subPkg.UniquePath, err) @@ -188,24 +194,16 @@ func (u Command) Run(ctx context.Context) error { } // updateSubKf updates subpackage with given ref and update strategy -func updateSubKf(subKf *kptfilev1.KptFile, ref string, strategy kptfilev1.UpdateStrategyType) { +func updateSubKf(subKf *kptfilev1.KptFile, subUps upstream.Fetcher, ref string, strategy kptfilev1.UpdateStrategyType) { // check if explicit ref provided if ref != "" { - subKf.Upstream.Git.Ref = ref + subUps.SetRef(ref) } if strategy != "" { subKf.Upstream.UpdateStrategy = strategy } } -// shouldUpdateSubPkgRef checks if subpkg ref should be updated. -// This is true if pkg has the same upstream repo, upstream directory is within or equal to root pkg directory and original root pkg ref matches the subpkg ref. -func shouldUpdateSubPkgRef(subKf, rootKf *kptfilev1.KptFile, originalRootKfRef string) bool { - return subKf.Upstream.Git.Repo == rootKf.Upstream.Git.Repo && - subKf.Upstream.Git.Ref == originalRootKfRef && - strings.HasPrefix(path.Clean(subKf.Upstream.Git.Directory), path.Clean(rootKf.Upstream.Git.Directory)) -} - func checkIfCommitted(ctx context.Context, p *pkg.Pkg) error { const op errors.Op = "update.checkIfCommitted" g, err := gitutil.NewLocalGitRunner(p.UniquePath.String()) @@ -277,30 +275,35 @@ func (u Command) updateRootPackage(ctx context.Context, p *pkg.Pkg) error { pr := printer.FromContextOrDie(ctx) pr.PrintPackage(p, !(p == u.Pkg)) - g := kf.Upstream.Git - updated := &git.RepoSpec{OrgRepo: g.Repo, Path: g.Directory, Ref: g.Ref} - pr.Printf("Fetching upstream from %s@%s\n", kf.Upstream.Git.Repo, kf.Upstream.Git.Ref) - if err := upstream.ClonerUsingGitExec(ctx, updated); err != nil { + upstream, err := upstream.NewUpstream(kf) + if err != nil { + return errors.E(op, p.UniquePath, err) + } + + updatedAbsPath, err := os.MkdirTemp("", "kpt-updated-") + if err!=nil { + return errors.E(op, p.UniquePath, err) + } + defer os.RemoveAll(updatedAbsPath) + + pr.Printf("Fetching upstream from %s\n", upstream.String()) + commit, err := upstream.FetchUpstream(ctx, updatedAbsPath) + if err!=nil { + return errors.E(op, p.UniquePath, err) + } + + originAbsPath, err := os.MkdirTemp("", "kpt-origin-") + if err!=nil { return errors.E(op, p.UniquePath, err) } - defer os.RemoveAll(updated.AbsPath()) + defer os.RemoveAll(originAbsPath) - var origin repoClone if kf.UpstreamLock != nil { - gLock := kf.UpstreamLock.Git - originRepoSpec := &git.RepoSpec{OrgRepo: gLock.Repo, Path: gLock.Directory, Ref: gLock.Commit} - pr.Printf("Fetching origin from %s@%s\n", kf.Upstream.Git.Repo, kf.Upstream.Git.Ref) - if err := upstream.ClonerUsingGitExec(ctx, originRepoSpec); err != nil { - return errors.E(op, p.UniquePath, err) - } - origin = originRepoSpec - } else { - origin, err = newNilRepoClone() - if err != nil { + pr.Printf("Fetching origin from %s\n", upstream.LockedString()) + if err := upstream.FetchUpstreamLock(ctx, originAbsPath); err != nil { return errors.E(op, p.UniquePath, err) } - } - defer os.RemoveAll(origin.AbsPath()) + } s := stack.New() s.Push(".") @@ -308,8 +311,8 @@ func (u Command) updateRootPackage(ctx context.Context, p *pkg.Pkg) error { for s.Len() > 0 { relPath := s.Pop() localPath := filepath.Join(p.UniquePath.String(), relPath) - updatedPath := filepath.Join(updated.AbsPath(), relPath) - originPath := filepath.Join(origin.AbsPath(), relPath) + updatedPath := filepath.Join(updatedAbsPath, relPath) + originPath := filepath.Join(originAbsPath, relPath) isRoot := false if relPath == "." { @@ -330,7 +333,7 @@ func (u Command) updateRootPackage(ctx context.Context, p *pkg.Pkg) error { } } - if err := kptfileutil.UpdateUpstreamLockFromGit(p.UniquePath.String(), updated); err != nil { + if err := kptfileutil.UpdateUpstreamLock(p.UniquePath.String(), upstream.BuildUpstreamLock(commit)); err != nil { return errors.E(op, p.UniquePath, err) } return nil diff --git a/internal/util/upstream/git.go b/internal/util/upstream/git.go index cdce4b460f..3bad2d8314 100644 --- a/internal/util/upstream/git.go +++ b/internal/util/upstream/git.go @@ -37,6 +37,7 @@ import ( type gitUpstream struct { git *v1.Git + gitLock *v1.GitLock } var _ Fetcher = &gitUpstream{} @@ -51,6 +52,10 @@ func (u *gitUpstream) String() string { return fmt.Sprintf("%s@%s", u.git.Repo, u.git.Ref) } +func (u *gitUpstream) LockedString() string { + return fmt.Sprintf("%s@%s", u.gitLock.Repo, u.gitLock.Commit) +} + func (u *gitUpstream) Validate() error { const op errors.Op = "upstream.Validate" g := u.git @@ -66,20 +71,56 @@ func (u *gitUpstream) Validate() error { return nil } -func (u *gitUpstream) ApplyUpstream(kf *v1.KptFile) { +func (u *gitUpstream) BuildUpstream() *v1.Upstream { repoDir := u.git.Directory if !strings.HasSuffix(repoDir, "file://") { repoDir = filepath.Join(path.Split(repoDir)) } u.git.Directory = repoDir - kf.Upstream = &v1.Upstream{ + return &v1.Upstream{ Type: v1.GitOrigin, Git: u.git, } } -func (u *gitUpstream) FetchUpstream(ctx context.Context, dest string) error { +func (u *gitUpstream) BuildUpstreamLock(digest string) *v1.UpstreamLock { + u.gitLock = &v1.GitLock{ + Repo: u.git.Repo, + Directory: u.git.Directory, + Ref: u.git.Ref, + Commit: digest, + } + return &v1.UpstreamLock{ + Type: v1.GitOrigin, + Git: u.gitLock, + } +} + +func (u *gitUpstream) FetchUpstream(ctx context.Context, dest string) (string, error) { + repoSpec := &git.RepoSpec{ + OrgRepo: u.git.Repo, + Path: u.git.Directory, + Ref: u.git.Ref, + Dir: dest, + } + if err := ClonerUsingGitExec(ctx, repoSpec); err != nil { + return "", err + } + return repoSpec.Commit, nil +} + +func (u *gitUpstream) FetchUpstreamLock(ctx context.Context, dest string) error { + repoSpec := &git.RepoSpec{ + OrgRepo: u.gitLock.Repo, + Path: u.gitLock.Directory, + Ref: u.gitLock.Commit, + Dir: dest, + } + return ClonerUsingGitExec(ctx, repoSpec) +} + +func (u *gitUpstream) CloneUpstream(ctx context.Context, dest string) error { repoSpec := &git.RepoSpec{ OrgRepo: u.git.Repo, Path: u.git.Directory, @@ -88,6 +129,26 @@ func (u *gitUpstream) FetchUpstream(ctx context.Context, dest string) error { return cloneAndCopy(ctx, repoSpec, dest) } +func (u *gitUpstream) Ref() (string, error) { + return u.git.Ref, nil +} + +func (u *gitUpstream) SetRef(ref string) error { + u.git.Ref = ref + return nil +} + +// shouldUpdateSubPkgRef checks if subpkg ref should be updated. +// This is true if pkg has the same upstream repo, upstream directory is within or equal to root pkg directory and original root pkg ref matches the subpkg ref. +func (u *gitUpstream) ShouldUpdateSubPkgRef(rootUpstream Fetcher, originalRootKfRef string) bool { + root, ok := rootUpstream.(*gitUpstream) + return ok && + u.git.Repo == root.git.Repo && + u.git.Ref == originalRootKfRef && + strings.HasPrefix(path.Clean(u.git.Directory), path.Clean(root.git.Directory)) +} + + // cloneAndCopy fetches the provided repo and copies the content into the // directory specified by dest. The provided name is set as `metadata.name` // of the Kptfile of the package. @@ -178,12 +239,14 @@ func ClonerUsingGitExec(ctx context.Context, repoSpec *git.RepoSpec) error { return errors.E(op, errors.Git, errors.Repo(repoSpec.CloneSpec()), err) } - // We need to create a temp directory where we can copy the content of the repo. - // During update, we need to checkout multiple versions of the same repo, so - // we can't do merges directly from the cache. - repoSpec.Dir, err = ioutil.TempDir("", "kpt-get-") - if err != nil { - return errors.E(op, errors.Internal, fmt.Errorf("error creating temp directory: %w", err)) + if repoSpec.Dir == "" { + // We need to create a temp directory where we can copy the content of the repo. + // During update, we need to checkout multiple versions of the same repo, so + // we can't do merges directly from the cache. + repoSpec.Dir, err = ioutil.TempDir("", "kpt-get-") + if err != nil { + return errors.E(op, errors.Internal, fmt.Errorf("error creating temp directory: %w", err)) + } } repoSpec.Commit = commit diff --git a/internal/util/upstream/git_test.go b/internal/util/upstream/git_test.go index c9ab2023c7..bbf07212e6 100644 --- a/internal/util/upstream/git_test.go +++ b/internal/util/upstream/git_test.go @@ -74,40 +74,3 @@ func Test_gitUpstream_String(t *testing.T) { }) } } - -//nolint:scopelint -func Test_gitUpstream_ApplyUpstream(t *testing.T) { - type fields struct { - git *v1.Git - } - type args struct { - kf *v1.KptFile - } - tests := []struct { - name string - fields fields - args args - }{ - { - name: "Sets upstream to git", - fields: fields{ - git: &v1.Git{ - Repo: "https://hostname/repo.git", - Directory: "dir/path", - Ref: "main", - }, - }, - args: args{ - kf: &v1.KptFile{}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - u := &gitUpstream{ - git: tt.fields.git, - } - u.ApplyUpstream(tt.args.kf) - }) - } -} diff --git a/internal/util/upstream/oci.go b/internal/util/upstream/oci.go index 93b42f8c02..c6a4edc89b 100644 --- a/internal/util/upstream/oci.go +++ b/internal/util/upstream/oci.go @@ -22,12 +22,13 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "github.com/GoogleContainerTools/kpt/internal/errors" "github.com/GoogleContainerTools/kpt/internal/pkg" "github.com/GoogleContainerTools/kpt/internal/types" "github.com/GoogleContainerTools/kpt/internal/util/pkgutil" - v1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" + kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" "github.com/google/go-containerregistry/pkg/gcrane" "github.com/google/go-containerregistry/pkg/name" @@ -36,41 +37,70 @@ import ( ) type ociUpstream struct { - image string + oci *kptfilev1.Oci + ociLock *kptfilev1.OciLock } var _ Fetcher = &ociUpstream{} -func NewOciUpstream(oci *v1.Oci) Fetcher { +func NewOciUpstream(oci *kptfilev1.Oci) Fetcher { return &ociUpstream{ - image: oci.Image, + oci: oci, } } func (u *ociUpstream) String() string { - return u.image + return u.oci.Image } -func (u *ociUpstream) ApplyUpstream(kf *v1.KptFile) { +func (u *ociUpstream) LockedString() string { + return u.ociLock.Image +} + +func (u *ociUpstream) BuildUpstream() *kptfilev1.Upstream { + return &kptfilev1.Upstream{ + Type: kptfilev1.OciOrigin, + Oci: u.oci, + } +} + +func (u *ociUpstream) BuildUpstreamLock(digest string) *kptfilev1.UpstreamLock { + u.ociLock.Image = digest - kf.Upstream = &v1.Upstream{ - Type: v1.OciOrigin, - Oci: &v1.Oci{ - Image: u.image, - }, + return &kptfilev1.UpstreamLock{ + Type: kptfilev1.OciOrigin, + Oci: u.ociLock, } } func (u *ociUpstream) Validate() error { const op errors.Op = "upstream.Validate" - if len(u.image) == 0 { + if len(u.oci.Image) == 0 { return errors.E(op, errors.MissingParam, fmt.Errorf("must specify image")) } return nil } -func (u *ociUpstream) FetchUpstream(ctx context.Context, dest string) error { +func (u *ociUpstream) FetchUpstream(ctx context.Context, dest string) (string, error) { const op errors.Op = "upstream.FetchUpstream" + imageDigest, err := pullAndExtract(u.oci.Image, dest, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) + if err != nil { + return "", errors.E(op, errors.OCI, types.UniquePath(dest), err) + } + return imageDigest.Name(), nil +} + +func (u *ociUpstream) FetchUpstreamLock(ctx context.Context, dest string) error { + const op errors.Op = "upstream.FetchUpstreamLock" + _, err := pullAndExtract(u.ociLock.Image, dest, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) + if err != nil { + return errors.E(op, errors.OCI, types.UniquePath(dest), err) + } + return nil +} + +func (u *ociUpstream) CloneUpstream(ctx context.Context, dest string) error { + const op errors.Op = "upstream.FetchUpstreamClone" // pr := printer.FromContextOrDie(ctx) // We need to create a temp directory where we can copy the content of the repo. @@ -82,7 +112,7 @@ func (u *ociUpstream) FetchUpstream(ctx context.Context, dest string) error { } defer os.RemoveAll(dir) - imageDigest, err := pullAndExtract(u.image, dir, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) + imageDigest, err := pullAndExtract(u.oci.Image, dir, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) if err != nil { return errors.E(op, errors.OCI, types.UniquePath(dest), err) } @@ -96,13 +126,57 @@ func (u *ociUpstream) FetchUpstream(ctx context.Context, dest string) error { return errors.E(op, types.UniquePath(dest), err) } - if err := kptfileutil.UpdateUpstreamLockFromOCI(dest, imageDigest); err != nil { + if err := kptfileutil.UpdateUpstreamLock(dest, u.BuildUpstreamLock(imageDigest.String())); err != nil { return errors.E(op, errors.OCI, types.UniquePath(dest), err) } return nil } +func (u *ociUpstream) Ref() (string, error) { + const op errors.Op = "upstream.Ref" + r, err := name.ParseReference(u.oci.Image) + if err != nil { + return "", errors.E(op, errors.Internal, fmt.Errorf("error parsing reference: %s %w", u.oci.Image, err)) + } + return r.Identifier(), nil +} + +func (u *ociUpstream) SetRef(ref string) error { + const op errors.Op = "upstream.SetRef" + r, err := name.ParseReference(u.oci.Image) + if err != nil { + return errors.E(op, errors.Internal, fmt.Errorf("error parsing reference: %s %w", u.oci.Image, err)) + } + + if len(strings.SplitN(ref, "sha256:", 2)[0]) == 0 { + u.oci.Image = r.Context().Digest(ref).Name() + } else { + u.oci.Image = r.Context().Tag(ref).Name() + } + + return nil +} + +// shouldUpdateSubPkgRef checks if subpkg ref should be updated. +// This is true if pkg has the same upstream repo, upstream directory is within or equal to root pkg directory and original root pkg ref matches the subpkg ref. +func (u *ociUpstream) ShouldUpdateSubPkgRef(rootUpstream Fetcher, originalRootKfRef string) bool { + root, ok := rootUpstream.(*ociUpstream) + if !ok { + return false + } + subName, err := name.ParseReference(u.oci.Image) + if err != nil { + return false + } + rootName, err := name.ParseReference(root.oci.Image) + if err != nil { + return false + } + return subName.Context().String() == rootName.Context().String() && + subName.Identifier() == originalRootKfRef +} + // pullAndExtract uses current credentials (gcloud auth) to pull and // extract (untar) image files to target directory. The desired version or digest must // be in the imageName, and the resolved image sha256 digest is returned. diff --git a/internal/util/upstream/upstream.go b/internal/util/upstream/upstream.go index 255da9e0c0..785cdaed51 100644 --- a/internal/util/upstream/upstream.go +++ b/internal/util/upstream/upstream.go @@ -24,9 +24,20 @@ import ( type Fetcher interface { fmt.Stringer + LockedString() string + Validate() error - ApplyUpstream(kf *kptfilev1.KptFile) - FetchUpstream(ctx context.Context, dest string) error + BuildUpstream() *kptfilev1.Upstream + BuildUpstreamLock(digest string) *kptfilev1.UpstreamLock + + FetchUpstream(ctx context.Context, dest string) (string, error) + FetchUpstreamLock(ctx context.Context, dest string) error + + CloneUpstream(ctx context.Context, dest string) error + + Ref() (string, error) + SetRef(ref string) error + ShouldUpdateSubPkgRef(rootUpstream Fetcher, originalRootRef string) bool } func NewUpstream(kf *kptfilev1.KptFile) (Fetcher, error) { @@ -34,18 +45,34 @@ func NewUpstream(kf *kptfilev1.KptFile) (Fetcher, error) { if kf != nil && kf.Upstream != nil { switch kf.Upstream.Type { case kptfilev1.GitOrigin: - if kf.Upstream.Git != nil { - return &gitUpstream{ - git: kf.Upstream.Git, - }, nil + u := &gitUpstream{ + git: &kptfilev1.Git{}, + gitLock: &kptfilev1.GitLock{}, + } + if kf.Upstream != nil && kf.Upstream.Git != nil { + u.git = kf.Upstream.Git } + if kf.UpstreamLock != nil && kf.UpstreamLock.Git != nil { + u.gitLock = kf.UpstreamLock.Git + } + return u, nil case kptfilev1.OciOrigin: - if kf.Upstream.Oci != nil { - return &ociUpstream{ - image: kf.Upstream.Oci.Image, - }, nil + u := &ociUpstream{ + oci: &kptfilev1.Oci{}, + ociLock: &kptfilev1.OciLock{}, + } + if kf.Upstream != nil && kf.Upstream.Oci != nil { + u.oci = kf.Upstream.Oci + } + if kf.UpstreamLock != nil && kf.UpstreamLock.Oci != nil { + u.ociLock = kf.UpstreamLock.Oci } + return u, nil } } return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile upstream type must be one of: %s,%s", kptfilev1.GitOrigin, kptfilev1.OciOrigin)) } + +func ShouldUpdateSubPkgRef(subUpstream Fetcher, rootUpstream Fetcher, originalRootRef string) bool { + return subUpstream.ShouldUpdateSubPkgRef(rootUpstream, originalRootRef) +} diff --git a/internal/util/upstream/upstream_test.go b/internal/util/upstream/upstream_test.go index 4c66f66fa8..fbe1118bff 100644 --- a/internal/util/upstream/upstream_test.go +++ b/internal/util/upstream/upstream_test.go @@ -68,7 +68,9 @@ func TestNewUpstream(t *testing.T) { }, }, want: &ociUpstream{ - image: "image-name", + oci: &kptfilev1.Oci{ + Image: "image-name", + }, }, wantErr: false, }, diff --git a/pkg/kptfile/kptfileutil/util.go b/pkg/kptfile/kptfileutil/util.go index dabdbfbae1..e0c64b3e95 100644 --- a/pkg/kptfile/kptfileutil/util.go +++ b/pkg/kptfile/kptfileutil/util.go @@ -28,7 +28,6 @@ import ( "github.com/GoogleContainerTools/kpt/internal/types" "github.com/GoogleContainerTools/kpt/internal/util/git" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" - "github.com/google/go-containerregistry/pkg/name" "sigs.k8s.io/kustomize/kyaml/yaml" "sigs.k8s.io/kustomize/kyaml/yaml/merge3" ) @@ -195,12 +194,8 @@ func UpdateKptfile(localPath, updatedPath, originPath string, updateUpstream boo return nil } -// UpdateUpstreamLockFromGit updates the upstreamLock of the package specified -// by path by using the values from spec. It will also populate the commit -// field in upstreamLock using the latest commit of the git repo given -// by spec. -func UpdateUpstreamLockFromGit(path string, spec *git.RepoSpec) error { - const op errors.Op = "kptfileutil.UpdateUpstreamLockFromGit" +func UpdateUpstreamLock(path string, upstreamLock *kptfilev1.UpstreamLock) error { + const op errors.Op = "kptfileutil.UpdateUpstreamLock" // read KptFile cloned with the package if it exists kpgfile, err := pkg.ReadKptfile(path) if err != nil { @@ -208,15 +203,8 @@ func UpdateUpstreamLockFromGit(path string, spec *git.RepoSpec) error { } // populate the cloneFrom values so we know where the package came from - kpgfile.UpstreamLock = &kptfilev1.UpstreamLock{ - Type: kptfilev1.GitOrigin, - Git: &kptfilev1.GitLock{ - Repo: spec.OrgRepo, - Directory: spec.Path, - Ref: spec.Ref, - Commit: spec.Commit, - }, - } + kpgfile.UpstreamLock = upstreamLock + err = WriteFile(path, kpgfile) if err != nil { return errors.E(op, types.UniquePath(path), err) @@ -224,29 +212,20 @@ func UpdateUpstreamLockFromGit(path string, spec *git.RepoSpec) error { return nil } -// UpdateUpstreamLockFromOCI updates the upstreamLock of the package specified -// by path by using the values from spec. The image reference provided must -// be the image sha256 digest in order for later updates to work correctly. -func UpdateUpstreamLockFromOCI(path string, image name.Reference) error { - const op errors.Op = "kptfileutil.UpdateUpstreamLockFromOCI" - // read KptFile cloned with the package if it exists - kpgfile, err := pkg.ReadKptfile(path) - if err != nil { - return errors.E(op, types.UniquePath(path), err) - } - - // populate the cloneFrom values so we know where the package came from - kpgfile.UpstreamLock = &kptfilev1.UpstreamLock{ - Type: kptfilev1.OciOrigin, - Oci: &kptfilev1.OciLock{ - Image: image.Name(), +// UpdateUpstreamLockFromGit updates the upstreamLock of the package specified +// by path by using the values from spec. It will also populate the commit +// field in upstreamLock using the latest commit of the git repo given +// by spec. +func UpdateUpstreamLockFromGit(path string, spec *git.RepoSpec) error { + return UpdateUpstreamLock(path, &kptfilev1.UpstreamLock{ + Type: kptfilev1.GitOrigin, + Git: &kptfilev1.GitLock{ + Repo: spec.OrgRepo, + Directory: spec.Path, + Ref: spec.Ref, + Commit: spec.Commit, }, - } - err = WriteFile(path, kpgfile) - if err != nil { - return errors.E(op, types.UniquePath(path), err) - } - return nil + }) } func merge(localKf, updatedKf, originalKf *kptfilev1.KptFile) error { From 7eead5ece64b496e2947af64810a6dbe16cfab96 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Fri, 5 Nov 2021 05:04:37 +0000 Subject: [PATCH 12/26] Fix fmt and tests --- internal/util/update/update.go | 64 +++++++------------------ internal/util/upstream/git.go | 11 ++--- internal/util/upstream/oci.go | 8 ++-- internal/util/upstream/upstream.go | 18 +++---- internal/util/upstream/upstream_test.go | 4 +- 5 files changed, 38 insertions(+), 67 deletions(-) diff --git a/internal/util/update/update.go b/internal/util/update/update.go index cc09dce659..f439699a77 100644 --- a/internal/util/update/update.go +++ b/internal/util/update/update.go @@ -18,7 +18,6 @@ package update import ( "context" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -128,7 +127,7 @@ func (u Command) Run(ctx context.Context) error { } } - originalRootKfRef,err := rootUps.Ref() + originalRootKfRef, err := rootUps.Ref() if err != nil { return errors.E(op, u.Pkg.UniquePath, err) } @@ -174,9 +173,10 @@ func (u Command) Run(ctx context.Context) error { // update subpackage kf ref/strategy if current pkg is a subpkg of root pkg or is root pkg // and if original root pkg ref matches the subpkg ref if upstream.ShouldUpdateSubPkgRef(subUps, rootUps, originalRootKfRef) { - updateSubKf(subKf, subUps, u.Ref, u.Strategy) - err = kptfileutil.WriteFile(subPkg.UniquePath.String(), subKf) - if err != nil { + if err := updateSubKf(subKf, subUps, u.Ref, u.Strategy); err != nil { + return errors.E(op, subPkg.UniquePath, err) + } + if err = kptfileutil.WriteFile(subPkg.UniquePath.String(), subKf); err != nil { return errors.E(op, subPkg.UniquePath, err) } } @@ -194,14 +194,17 @@ func (u Command) Run(ctx context.Context) error { } // updateSubKf updates subpackage with given ref and update strategy -func updateSubKf(subKf *kptfilev1.KptFile, subUps upstream.Fetcher, ref string, strategy kptfilev1.UpdateStrategyType) { +func updateSubKf(subKf *kptfilev1.KptFile, subUps upstream.Fetcher, ref string, strategy kptfilev1.UpdateStrategyType) error { // check if explicit ref provided if ref != "" { - subUps.SetRef(ref) + if err := subUps.SetRef(ref); err != nil { + return err + } } if strategy != "" { subKf.Upstream.UpdateStrategy = strategy } + return nil } func checkIfCommitted(ctx context.Context, p *pkg.Pkg) error { @@ -229,39 +232,6 @@ func checkIfCommitted(ctx context.Context, p *pkg.Pkg) error { return nil } -// repoClone is an interface that represents a clone of a repo on the local -// disk. -type repoClone interface { - AbsPath() string -} - -// newNilRepoClone creates a new nilRepoClone that implements the repoClone -// interface -func newNilRepoClone() (*nilRepoClone, error) { - const op errors.Op = "update.newNilRepoClone" - dir, err := ioutil.TempDir("", "kpt-empty-") - if err != nil { - return nil, errors.E(op, errors.IO, fmt.Errorf("errors creating a temporary directory: %w", err)) - } - return &nilRepoClone{ - dir: dir, - }, nil -} - -// nilRepoClone is an implementation of the repoClone interface, but that -// just represents an empty directory. This simplifies the logic for update -// since we don't have to special case situations where we don't have -// upstream and/or origin. -type nilRepoClone struct { - dir string -} - -// AbsPath returns the absolute path to the local directory for the repo. For -// the nilRepoClone, this will always be an empty directory. -func (nrc *nilRepoClone) AbsPath() string { - return nrc.dir -} - // updateRootPackage updates a local package. It will use the information // about upstream in the Kptfile to fetch upstream and origin, and then // recursively traverse the hierarchy to add/update/delete packages. @@ -277,33 +247,33 @@ func (u Command) updateRootPackage(ctx context.Context, p *pkg.Pkg) error { upstream, err := upstream.NewUpstream(kf) if err != nil { - return errors.E(op, p.UniquePath, err) + return errors.E(op, p.UniquePath, err) } updatedAbsPath, err := os.MkdirTemp("", "kpt-updated-") - if err!=nil { + if err != nil { return errors.E(op, p.UniquePath, err) } defer os.RemoveAll(updatedAbsPath) - + pr.Printf("Fetching upstream from %s\n", upstream.String()) commit, err := upstream.FetchUpstream(ctx, updatedAbsPath) - if err!=nil { + if err != nil { return errors.E(op, p.UniquePath, err) } originAbsPath, err := os.MkdirTemp("", "kpt-origin-") - if err!=nil { + if err != nil { return errors.E(op, p.UniquePath, err) } - defer os.RemoveAll(originAbsPath) + defer os.RemoveAll(originAbsPath) if kf.UpstreamLock != nil { pr.Printf("Fetching origin from %s\n", upstream.LockedString()) if err := upstream.FetchUpstreamLock(ctx, originAbsPath); err != nil { return errors.E(op, p.UniquePath, err) } - } + } s := stack.New() s.Push(".") diff --git a/internal/util/upstream/git.go b/internal/util/upstream/git.go index 3bad2d8314..cdc6ad8ec8 100644 --- a/internal/util/upstream/git.go +++ b/internal/util/upstream/git.go @@ -36,7 +36,7 @@ import ( ) type gitUpstream struct { - git *v1.Git + git *v1.Git gitLock *v1.GitLock } @@ -53,7 +53,7 @@ func (u *gitUpstream) String() string { } func (u *gitUpstream) LockedString() string { - return fmt.Sprintf("%s@%s", u.gitLock.Repo, u.gitLock.Commit) + return fmt.Sprintf("%s@%s", u.gitLock.Repo, u.gitLock.Ref) } func (u *gitUpstream) Validate() error { @@ -102,7 +102,7 @@ func (u *gitUpstream) FetchUpstream(ctx context.Context, dest string) (string, e OrgRepo: u.git.Repo, Path: u.git.Directory, Ref: u.git.Ref, - Dir: dest, + Dir: dest, } if err := ClonerUsingGitExec(ctx, repoSpec); err != nil { return "", err @@ -115,7 +115,7 @@ func (u *gitUpstream) FetchUpstreamLock(ctx context.Context, dest string) error OrgRepo: u.gitLock.Repo, Path: u.gitLock.Directory, Ref: u.gitLock.Commit, - Dir: dest, + Dir: dest, } return ClonerUsingGitExec(ctx, repoSpec) } @@ -142,13 +142,12 @@ func (u *gitUpstream) SetRef(ref string) error { // This is true if pkg has the same upstream repo, upstream directory is within or equal to root pkg directory and original root pkg ref matches the subpkg ref. func (u *gitUpstream) ShouldUpdateSubPkgRef(rootUpstream Fetcher, originalRootKfRef string) bool { root, ok := rootUpstream.(*gitUpstream) - return ok && + return ok && u.git.Repo == root.git.Repo && u.git.Ref == originalRootKfRef && strings.HasPrefix(path.Clean(u.git.Directory), path.Clean(root.git.Directory)) } - // cloneAndCopy fetches the provided repo and copies the content into the // directory specified by dest. The provided name is set as `metadata.name` // of the Kptfile of the package. diff --git a/internal/util/upstream/oci.go b/internal/util/upstream/oci.go index c6a4edc89b..db534f8efc 100644 --- a/internal/util/upstream/oci.go +++ b/internal/util/upstream/oci.go @@ -37,7 +37,7 @@ import ( ) type ociUpstream struct { - oci *kptfilev1.Oci + oci *kptfilev1.Oci ociLock *kptfilev1.OciLock } @@ -60,7 +60,7 @@ func (u *ociUpstream) LockedString() string { func (u *ociUpstream) BuildUpstream() *kptfilev1.Upstream { return &kptfilev1.Upstream{ Type: kptfilev1.OciOrigin, - Oci: u.oci, + Oci: u.oci, } } @@ -69,7 +69,7 @@ func (u *ociUpstream) BuildUpstreamLock(digest string) *kptfilev1.UpstreamLock { return &kptfilev1.UpstreamLock{ Type: kptfilev1.OciOrigin, - Oci: u.ociLock, + Oci: u.ociLock, } } @@ -154,7 +154,7 @@ func (u *ociUpstream) SetRef(ref string) error { } else { u.oci.Image = r.Context().Tag(ref).Name() } - + return nil } diff --git a/internal/util/upstream/upstream.go b/internal/util/upstream/upstream.go index 785cdaed51..476c42fdf1 100644 --- a/internal/util/upstream/upstream.go +++ b/internal/util/upstream/upstream.go @@ -41,29 +41,29 @@ type Fetcher interface { } func NewUpstream(kf *kptfilev1.KptFile) (Fetcher, error) { - const op errors.Op = "upstream.NewUpstreamFetcher" + const op errors.Op = "upstream.NewUpstream" if kf != nil && kf.Upstream != nil { switch kf.Upstream.Type { case kptfilev1.GitOrigin: + if kf.Upstream.Git == nil { + return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile upstream must have git information")) + } u := &gitUpstream{ - git: &kptfilev1.Git{}, + git: kf.Upstream.Git, gitLock: &kptfilev1.GitLock{}, } - if kf.Upstream != nil && kf.Upstream.Git != nil { - u.git = kf.Upstream.Git - } if kf.UpstreamLock != nil && kf.UpstreamLock.Git != nil { u.gitLock = kf.UpstreamLock.Git } return u, nil case kptfilev1.OciOrigin: + if kf.Upstream.Oci == nil { + return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile upstream must have oci information")) + } u := &ociUpstream{ - oci: &kptfilev1.Oci{}, + oci: kf.Upstream.Oci, ociLock: &kptfilev1.OciLock{}, } - if kf.Upstream != nil && kf.Upstream.Oci != nil { - u.oci = kf.Upstream.Oci - } if kf.UpstreamLock != nil && kf.UpstreamLock.Oci != nil { u.ociLock = kf.UpstreamLock.Oci } diff --git a/internal/util/upstream/upstream_test.go b/internal/util/upstream/upstream_test.go index fbe1118bff..ac2a37c16c 100644 --- a/internal/util/upstream/upstream_test.go +++ b/internal/util/upstream/upstream_test.go @@ -52,6 +52,7 @@ func TestNewUpstream(t *testing.T) { Directory: "dir-name", Ref: "ref-name", }, + gitLock: &kptfilev1.GitLock{}, }, wantErr: false, }, @@ -70,7 +71,8 @@ func TestNewUpstream(t *testing.T) { want: &ociUpstream{ oci: &kptfilev1.Oci{ Image: "image-name", - }, + }, + ociLock: &kptfilev1.OciLock{}, }, wantErr: false, }, From da09b7f8f1e5520a6f73e0960e69bd9dfbd43377 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Fri, 5 Nov 2021 05:49:34 +0000 Subject: [PATCH 13/26] Path must be added to returned absPath --- internal/util/update/update.go | 13 +++++++------ internal/util/upstream/git.go | 13 ++++++++----- internal/util/upstream/oci.go | 12 ++++++------ internal/util/upstream/upstream.go | 4 ++-- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/internal/util/update/update.go b/internal/util/update/update.go index f439699a77..e2d03d2f40 100644 --- a/internal/util/update/update.go +++ b/internal/util/update/update.go @@ -250,27 +250,28 @@ func (u Command) updateRootPackage(ctx context.Context, p *pkg.Pkg) error { return errors.E(op, p.UniquePath, err) } - updatedAbsPath, err := os.MkdirTemp("", "kpt-updated-") + updatedTmpPath, err := os.MkdirTemp("", "kpt-updated-") if err != nil { return errors.E(op, p.UniquePath, err) } - defer os.RemoveAll(updatedAbsPath) + defer os.RemoveAll(updatedTmpPath) pr.Printf("Fetching upstream from %s\n", upstream.String()) - commit, err := upstream.FetchUpstream(ctx, updatedAbsPath) + updatedAbsPath, commit, err := upstream.FetchUpstream(ctx, updatedTmpPath) if err != nil { return errors.E(op, p.UniquePath, err) } - originAbsPath, err := os.MkdirTemp("", "kpt-origin-") + originTmpPath, err := os.MkdirTemp("", "kpt-origin-") if err != nil { return errors.E(op, p.UniquePath, err) } - defer os.RemoveAll(originAbsPath) + defer os.RemoveAll(originTmpPath) + originAbsPath := originTmpPath if kf.UpstreamLock != nil { pr.Printf("Fetching origin from %s\n", upstream.LockedString()) - if err := upstream.FetchUpstreamLock(ctx, originAbsPath); err != nil { + if originAbsPath, err = upstream.FetchUpstreamLock(ctx, originTmpPath); err != nil { return errors.E(op, p.UniquePath, err) } } diff --git a/internal/util/upstream/git.go b/internal/util/upstream/git.go index cdc6ad8ec8..4f1bc83561 100644 --- a/internal/util/upstream/git.go +++ b/internal/util/upstream/git.go @@ -97,7 +97,7 @@ func (u *gitUpstream) BuildUpstreamLock(digest string) *v1.UpstreamLock { } } -func (u *gitUpstream) FetchUpstream(ctx context.Context, dest string) (string, error) { +func (u *gitUpstream) FetchUpstream(ctx context.Context, dest string) (string, string, error) { repoSpec := &git.RepoSpec{ OrgRepo: u.git.Repo, Path: u.git.Directory, @@ -105,19 +105,22 @@ func (u *gitUpstream) FetchUpstream(ctx context.Context, dest string) (string, e Dir: dest, } if err := ClonerUsingGitExec(ctx, repoSpec); err != nil { - return "", err + return "", "", err } - return repoSpec.Commit, nil + return path.Join(repoSpec.Dir, repoSpec.Path), repoSpec.Commit, nil } -func (u *gitUpstream) FetchUpstreamLock(ctx context.Context, dest string) error { +func (u *gitUpstream) FetchUpstreamLock(ctx context.Context, dest string) (string, error) { repoSpec := &git.RepoSpec{ OrgRepo: u.gitLock.Repo, Path: u.gitLock.Directory, Ref: u.gitLock.Commit, Dir: dest, } - return ClonerUsingGitExec(ctx, repoSpec) + if err := ClonerUsingGitExec(ctx, repoSpec); err != nil { + return "", err + } + return path.Join(repoSpec.Dir, repoSpec.Path), nil } func (u *gitUpstream) CloneUpstream(ctx context.Context, dest string) error { diff --git a/internal/util/upstream/oci.go b/internal/util/upstream/oci.go index db534f8efc..fd97f35e71 100644 --- a/internal/util/upstream/oci.go +++ b/internal/util/upstream/oci.go @@ -81,22 +81,22 @@ func (u *ociUpstream) Validate() error { return nil } -func (u *ociUpstream) FetchUpstream(ctx context.Context, dest string) (string, error) { +func (u *ociUpstream) FetchUpstream(ctx context.Context, dest string) (string, string, error) { const op errors.Op = "upstream.FetchUpstream" imageDigest, err := pullAndExtract(u.oci.Image, dest, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) if err != nil { - return "", errors.E(op, errors.OCI, types.UniquePath(dest), err) + return "", "", errors.E(op, errors.OCI, types.UniquePath(dest), err) } - return imageDigest.Name(), nil + return dest, imageDigest.Name(), nil } -func (u *ociUpstream) FetchUpstreamLock(ctx context.Context, dest string) error { +func (u *ociUpstream) FetchUpstreamLock(ctx context.Context, dest string) (string, error) { const op errors.Op = "upstream.FetchUpstreamLock" _, err := pullAndExtract(u.ociLock.Image, dest, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) if err != nil { - return errors.E(op, errors.OCI, types.UniquePath(dest), err) + return "", errors.E(op, errors.OCI, types.UniquePath(dest), err) } - return nil + return dest, nil } func (u *ociUpstream) CloneUpstream(ctx context.Context, dest string) error { diff --git a/internal/util/upstream/upstream.go b/internal/util/upstream/upstream.go index 476c42fdf1..fc570e7391 100644 --- a/internal/util/upstream/upstream.go +++ b/internal/util/upstream/upstream.go @@ -30,8 +30,8 @@ type Fetcher interface { BuildUpstream() *kptfilev1.Upstream BuildUpstreamLock(digest string) *kptfilev1.UpstreamLock - FetchUpstream(ctx context.Context, dest string) (string, error) - FetchUpstreamLock(ctx context.Context, dest string) error + FetchUpstream(ctx context.Context, dest string) (absPath string, digest string, err error) + FetchUpstreamLock(ctx context.Context, dest string) (absPath string, err error) CloneUpstream(ctx context.Context, dest string) error From ed10536f18929ba90fe27dae6f99483c90ae53b2 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Fri, 5 Nov 2021 06:03:28 +0000 Subject: [PATCH 14/26] Removing git repo error message check * this startup check probably doesn't make sense any more? the pkg update logic doesn't rely on the state of the local git repo to merge --- internal/util/update/update_test.go | 36 ----------------------------- 1 file changed, 36 deletions(-) diff --git a/internal/util/update/update_test.go b/internal/util/update/update_test.go index eecf897d84..b8630b1fa8 100644 --- a/internal/util/update/update_test.go +++ b/internal/util/update/update_test.go @@ -302,42 +302,6 @@ func TestCommand_Run_noAdd(t *testing.T) { } } -func TestCommand_Run_noGitRepo(t *testing.T) { - d, err := ioutil.TempDir("", "kpt-noGitRepo-test") - if !assert.NoError(t, err) { - t.FailNow() - } - defer os.RemoveAll(d) - - kf := kptfileutil.DefaultKptfile(filepath.Base(d)) - kf.Upstream = &kptfilev1.Upstream{ - Type: kptfilev1.GitOrigin, - Git: &kptfilev1.Git{ - Repo: "https://github.com/GoogleContainerTools/kpt", - Directory: "/", - Ref: "main", - }, - UpdateStrategy: kptfilev1.ResourceMerge, - } - kf.UpstreamLock = &kptfilev1.UpstreamLock{ - Type: kptfilev1.GitOrigin, - Git: &kptfilev1.GitLock{ - Repo: "https://github.com/GoogleContainerTools/kpt", - Directory: "/", - Ref: "main", - Commit: "abc123", - }, - } - - err = Command{ - Pkg: pkgtest.CreatePkgOrFail(t, d), - }.Run(fake.CtxWithDefaultPrinter()) - if !assert.Error(t, err) { - return - } - assert.Contains(t, err.Error(), "is not a git repository") -} - func TestCommand_Run_localPackageChanges(t *testing.T) { testCases := map[string]struct { strategy kptfilev1.UpdateStrategyType From 2c7060246f50bda2855b39a6302af8b87d30c95c Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Thu, 18 Nov 2021 07:53:01 +0000 Subject: [PATCH 15/26] Adding OCI support to kpt pkg diff * Mainly involves using upstream.Fetcher methods --- internal/util/diff/diff.go | 114 +++++++++++++------------------------ 1 file changed, 38 insertions(+), 76 deletions(-) diff --git a/internal/util/diff/diff.go b/internal/util/diff/diff.go index e2f3a20eb7..6bebe04535 100644 --- a/internal/util/diff/diff.go +++ b/internal/util/diff/diff.go @@ -28,10 +28,9 @@ import ( "github.com/GoogleContainerTools/kpt/internal/gitutil" "github.com/GoogleContainerTools/kpt/internal/pkg" "github.com/GoogleContainerTools/kpt/internal/util/addmergecomment" - "github.com/GoogleContainerTools/kpt/internal/util/fetch" "github.com/GoogleContainerTools/kpt/internal/util/pkgutil" + "github.com/GoogleContainerTools/kpt/internal/util/upstream" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" - "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" "sigs.k8s.io/kustomize/kyaml/errors" ) @@ -111,8 +110,8 @@ type Command struct { // PkgDiffer specifies package differ PkgDiffer PkgDiffer - // PkgGetter specifies packaging sourcing adapter - PkgGetter PkgGetter + // Contains information about the upstream package to fetch + Upstream upstream.Fetcher } func (c *Command) Run(ctx context.Context) error { @@ -123,6 +122,15 @@ func (c *Command) Run(ctx context.Context) error { return errors.Errorf("package missing Kptfile at '%s': %v", c.Path, err) } + c.Upstream, err = upstream.NewUpstream(kptFile) + if err != nil { + return errors.Errorf("upstream required: %v", err) + } + upstreamRef, err := c.Upstream.Ref() + if err != nil { + return errors.Errorf("upstream ref required: %v", err) + } + // Create a staging directory to store all compared packages stagingDirectory, err := ioutil.TempDir("", "kpt-") if err != nil { @@ -138,7 +146,7 @@ func (c *Command) Run(ctx context.Context) error { // Stage current package // This prevents prepareForDiff from modifying the local package localPkgName := NameStagingDirectory(LocalPackageSource, - kptFile.Upstream.Git.Ref) + upstreamRef) currPkg, err := stageDirectory(stagingDirectory, localPkgName) if err != nil { return errors.Errorf("failed to create stage dir for current package: %v", err) @@ -150,14 +158,11 @@ func (c *Command) Run(ctx context.Context) error { } // get the upstreamPkg at current version - upstreamPkgName := NameStagingDirectory(RemotePackageSource, - kptFile.Upstream.Git.Ref) - upstreamPkg, err := c.PkgGetter.GetPkg(ctx, - stagingDirectory, - upstreamPkgName, - kptFile.Upstream.Git.Repo, - kptFile.Upstream.Git.Directory, - kptFile.Upstream.Git.Ref) + upstreamPkgName, err := stageDirectory(stagingDirectory, NameStagingDirectory(RemotePackageSource, upstreamRef)) + if err != nil { + return err + } + upstreamPkg, _, err := c.Upstream.FetchUpstream(ctx, upstreamPkgName) if err != nil { return err } @@ -165,13 +170,18 @@ func (c *Command) Run(ctx context.Context) error { var upstreamTargetPkg string if c.Ref == "" { - gur, err := gitutil.NewGitUpstreamRepo(ctx, kptFile.UpstreamLock.Git.Repo) - if err != nil { - return err - } - c.Ref, err = gur.GetDefaultBranch(ctx) - if err != nil { - return err + switch kptFile.UpstreamLock.Type { + case kptfilev1.GitOrigin: + gur, err := gitutil.NewGitUpstreamRepo(ctx, kptFile.UpstreamLock.Git.Repo) + if err != nil { + return err + } + c.Ref, err = gur.GetDefaultBranch(ctx) + if err != nil { + return err + } + case kptfilev1.OciOrigin: + c.Ref = "latest" } } @@ -179,13 +189,14 @@ func (c *Command) Run(ctx context.Context) error { c.DiffType == DiffTypeCombined || c.DiffType == DiffType3Way { // get the upstream pkg at the target version - upstreamTargetPkgName := NameStagingDirectory(TargetRemotePackageSource, - c.Ref) - upstreamTargetPkg, err = c.PkgGetter.GetPkg(ctx, stagingDirectory, - upstreamTargetPkgName, - kptFile.Upstream.Git.Repo, - kptFile.Upstream.Git.Directory, - c.Ref) + upstreamTargetPkgName, err := stageDirectory(stagingDirectory, NameStagingDirectory(TargetRemotePackageSource, c.Ref)) + if err != nil { + return err + } + if err := c.Upstream.SetRef(c.Ref); err != nil { + return err + } + upstreamTargetPkg, _, err = c.Upstream.FetchUpstream(ctx, upstreamTargetPkgName) if err != nil { return err } @@ -231,9 +242,6 @@ func (c *Command) DefaultValues() { if c.Output == nil { c.Output = os.Stdout } - if c.PkgGetter == nil { - c.PkgGetter = defaultPkgGetter{} - } if c.PkgDiffer == nil { c.PkgDiffer = &defaultPkgDiffer{ DiffType: c.DiffType, @@ -322,52 +330,6 @@ func (d *defaultPkgDiffer) prepareForDiff(dir string) error { return nil } -// PkgGetter knows how to fetch a package given a git repo, path and ref. -type PkgGetter interface { - GetPkg(ctx context.Context, stagingDir, targetDir, repo, path, ref string) (dir string, err error) -} - -// defaultPkgGetter uses fetch.Command abstraction to implement PkgGetter. -type defaultPkgGetter struct{} - -// GetPkg checks out a repository into a temporary directory for diffing -// and returns the directory containing the checked out package or an error. -// repo is the git repository the package was cloned from. e.g. https:// -// path is the sub directory of the git repository that the package was cloned from -// ref is the git ref the package was cloned from -func (pg defaultPkgGetter) GetPkg(ctx context.Context, stagingDir, targetDir, repo, path, ref string) (string, error) { - dir, err := stageDirectory(stagingDir, targetDir) - if err != nil { - return dir, err - } - - name := filepath.Base(dir) - kf := kptfileutil.DefaultKptfile(name) - kf.Upstream = &kptfilev1.Upstream{ - Type: kptfilev1.GitOrigin, - Git: &kptfilev1.Git{ - Repo: repo, - Directory: path, - Ref: ref, - }, - } - err = kptfileutil.WriteFile(dir, kf) - if err != nil { - return dir, err - } - - p, err := pkg.New(dir) - if err != nil { - return dir, err - } - - cmdGet := &fetch.Command{ - Pkg: p, - } - err = cmdGet.Run(ctx) - return dir, err -} - // stageDirectory creates a subdirectory of the provided path for temporary operations // path is the parent staged directory and should already exist // subpath is the subdirectory that should be created inside path From f5d191ed6e2209cf3823b5ac334bb7f7f692c18e Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Thu, 9 Dec 2021 04:58:22 +0000 Subject: [PATCH 16/26] Adding prototype kpt pkg pull command Based on design and latest conversations --- commands/pkgcmd.go | 3 +- internal/cmdpull/cmdpull.go | 104 ++++++++++++++++++++++++++++ internal/util/pull/pull.go | 106 +++++++++++++++++++++++++++++ internal/util/upstream/git.go | 39 +++++++++++ internal/util/upstream/oci.go | 39 ++++++++++- internal/util/upstream/upstream.go | 2 + pkg/api/kptfile/v1/types.go | 18 +++++ 7 files changed, 308 insertions(+), 3 deletions(-) create mode 100644 internal/cmdpull/cmdpull.go create mode 100644 internal/util/pull/pull.go diff --git a/commands/pkgcmd.go b/commands/pkgcmd.go index eb6cd75b83..0f9ca21190 100644 --- a/commands/pkgcmd.go +++ b/commands/pkgcmd.go @@ -20,6 +20,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/cmddiff" "github.com/GoogleContainerTools/kpt/internal/cmdget" "github.com/GoogleContainerTools/kpt/internal/cmdinit" + "github.com/GoogleContainerTools/kpt/internal/cmdpull" "github.com/GoogleContainerTools/kpt/internal/cmdupdate" "github.com/GoogleContainerTools/kpt/internal/docs/generated/pkgdocs" "github.com/GoogleContainerTools/kpt/thirdparty/cmdconfig/commands/cmdtree" @@ -47,7 +48,7 @@ func GetPkgCommand(ctx context.Context, name string) *cobra.Command { pkg.AddCommand( cmdget.NewCommand(ctx, name), cmdinit.NewCommand(ctx, name), cmdupdate.NewCommand(ctx, name), cmddiff.NewCommand(ctx, name), - cmdtree.NewCommand(ctx, name), + cmdtree.NewCommand(ctx, name), cmdpull.NewCommand(ctx, name), ) return pkg } diff --git a/internal/cmdpull/cmdpull.go b/internal/cmdpull/cmdpull.go new file mode 100644 index 0000000000..fa954f01e2 --- /dev/null +++ b/internal/cmdpull/cmdpull.go @@ -0,0 +1,104 @@ +package cmdpull + +import ( + "context" + "fmt" + "os" + + docs "github.com/GoogleContainerTools/kpt/internal/docs/generated/pkgdocs" + "github.com/GoogleContainerTools/kpt/internal/errors" + "github.com/GoogleContainerTools/kpt/internal/pkg" + "github.com/GoogleContainerTools/kpt/internal/types" + "github.com/GoogleContainerTools/kpt/internal/util/argutil" + "github.com/GoogleContainerTools/kpt/internal/util/cmdutil" + "github.com/GoogleContainerTools/kpt/internal/util/parse" + "github.com/GoogleContainerTools/kpt/internal/util/pull" + "github.com/GoogleContainerTools/kpt/internal/util/upstream" + "github.com/spf13/cobra" +) + +// NewRunner returns a command runner +func NewRunner(ctx context.Context, parent string) *Runner { + r := &Runner{ + ctx: ctx, + } + c := &cobra.Command{ + Use: "pull {REPO_URI[.git]/PKG_PATH[@VERSION]|IMAGE:TAG} [LOCAL_DEST_DIRECTORY]", + Args: cobra.MinimumNArgs(1), + Short: docs.GetShort, + Long: docs.GetShort + "\n" + docs.GetLong, + Example: docs.GetExamples, + RunE: r.runE, + PreRunE: r.preRunE, + } + cmdutil.FixDocs("kpt", parent, c) + r.Command = c + return r +} + +func NewCommand(ctx context.Context, parent string) *cobra.Command { + return NewRunner(ctx, parent).Command +} + +// Runner contains the run function +type Runner struct { + ctx context.Context + Pull pull.Command + Command *cobra.Command +} + +func (r *Runner) preRunE(_ *cobra.Command, args []string) error { + const op errors.Op = "cmdpull.preRunE" + if len(args) == 1 { + args = append(args, pkg.CurDir) + } else { + _, err := os.Lstat(args[1]) + if err == nil || os.IsExist(err) { + resolvedPath, err := argutil.ResolveSymlink(r.ctx, args[1]) + if err != nil { + return errors.E(op, err) + } + args[1] = resolvedPath + } + } + destination, err := r.parseArgs(args) + if err != nil { + return err + } + + p, err := pkg.New(destination) + if err != nil { + return errors.E(op, types.UniquePath(destination), err) + } + r.Pull.Destination = string(p.UniquePath) + + return nil +} + +func (r *Runner) parseArgs(args []string) (string, error) { + const op errors.Op = "cmdpull.preRunE" + + t1, err1 := parse.GitParseArgs(r.ctx, args) + if err1 == nil { + r.Pull.Git = &t1.Git + r.Pull.Upstream = upstream.NewGitOrigin(&t1.Git) + return t1.Destination, nil + } + + t2, err2 := parse.OciParseArgs(r.ctx, args) + if err2 == nil { + r.Pull.Upstream = upstream.NewOciOrigin(&t2.Oci) + return t2.Destination, nil + } + + return "", errors.E(op, fmt.Errorf("%v %v", err1, err2)) +} + +func (r *Runner) runE(c *cobra.Command, _ []string) error { + const op errors.Op = "cmdpull.runE" + if err := r.Pull.Run(r.ctx); err != nil { + return errors.E(op, types.UniquePath(r.Pull.Destination), err) + } + + return nil +} diff --git a/internal/util/pull/pull.go b/internal/util/pull/pull.go new file mode 100644 index 0000000000..c3d4ada581 --- /dev/null +++ b/internal/util/pull/pull.go @@ -0,0 +1,106 @@ +// Copyright 2019 Google LLC +// +// 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 get contains libraries for fetching packages. +package pull + +import ( + "context" + goerrors "errors" + "fmt" + "os" + "path/filepath" + + "github.com/GoogleContainerTools/kpt/internal/errors" + "github.com/GoogleContainerTools/kpt/internal/pkg" + "github.com/GoogleContainerTools/kpt/internal/types" + "github.com/GoogleContainerTools/kpt/internal/util/upstream" + kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" + "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" +) + +// Command fetches a package from a git repository, copies it to a local +// directory, and expands any remote subpackages. +type Command struct { + // Git contains information about the git repo to fetch + Git *kptfilev1.Git + + // Contains information about the upstraem package to fetch + Upstream upstream.Fetcher + + // Destination is the output directory to clone the package to. Defaults to the name of the package -- + // either the base repo name, or the base subdirectory name. + Destination string +} + +// Run runs the Command. +func (c Command) Run(ctx context.Context) error { + const op errors.Op = "pull.Run" + if err := (&c).DefaultValues(); err != nil { + return errors.E(op, err) + } + + if _, err := os.Stat(c.Destination); !goerrors.Is(err, os.ErrNotExist) { + return errors.E(op, errors.Exist, types.UniquePath(c.Destination), fmt.Errorf("destination directory already exists")) + } + + err := os.MkdirAll(c.Destination, 0700) + if err != nil { + return errors.E(op, errors.IO, types.UniquePath(c.Destination), err) + } + + // TODO(dejardin) need to understand abs path for kpt pkg pull from git + _, digest, err := c.Upstream.FetchOrigin(ctx, c.Destination) + if err != nil { + return errors.E(op, types.UniquePath(c.Destination), err) + } + + kf, err := pkg.ReadKptfile(c.Destination) + if err != nil { + return errors.E(op, types.UniquePath(c.Destination), err) + } + + kf.Origin = c.Upstream.BuildOrigin(digest) + err = kptfileutil.WriteFile(c.Destination, kf) + if err != nil { + return cleanUpDirAndError(c.Destination, err) + } + + return nil +} + +// DefaultValues sets values to the default values if they were unspecified +func (c *Command) DefaultValues() error { + const op errors.Op = "pull.DefaultValues" + if c.Upstream == nil { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify git repo or image reference information")) + } + if err := c.Upstream.Validate(); err != nil { + return errors.E(op, err) + } + if !filepath.IsAbs(c.Destination) { + return errors.E(op, errors.InvalidParam, fmt.Errorf("destination must be an absolute path")) + } + + return nil +} + +func cleanUpDirAndError(destination string, err error) error { + const op errors.Op = "pull.Run" + rmErr := os.RemoveAll(destination) + if rmErr != nil { + return errors.E(op, types.UniquePath(destination), err, rmErr) + } + return errors.E(op, types.UniquePath(destination), err) +} diff --git a/internal/util/upstream/git.go b/internal/util/upstream/git.go index 4f1bc83561..0d0b76b286 100644 --- a/internal/util/upstream/git.go +++ b/internal/util/upstream/git.go @@ -38,6 +38,7 @@ import ( type gitUpstream struct { git *v1.Git gitLock *v1.GitLock + origin *v1.Git } var _ Fetcher = &gitUpstream{} @@ -48,6 +49,12 @@ func NewGitUpstream(git *v1.Git) Fetcher { } } +func NewGitOrigin(git *v1.Git) Fetcher { + return &gitUpstream{ + origin: git, + } +} + func (u *gitUpstream) String() string { return fmt.Sprintf("%s@%s", u.git.Repo, u.git.Ref) } @@ -59,6 +66,9 @@ func (u *gitUpstream) LockedString() string { func (u *gitUpstream) Validate() error { const op errors.Op = "upstream.Validate" g := u.git + if g == nil { + g = u.origin + } if len(g.Repo) == 0 { return errors.E(op, errors.MissingParam, fmt.Errorf("must specify repo")) } @@ -97,6 +107,18 @@ func (u *gitUpstream) BuildUpstreamLock(digest string) *v1.UpstreamLock { } } +func (u *gitUpstream) BuildOrigin(digest string) *v1.Origin { + return &v1.Origin{ + Type: v1.GitOrigin, + Git: &v1.GitLock{ + Repo: u.origin.Repo, + Directory: u.origin.Directory, + Ref: u.origin.Ref, + Commit: digest, + }, + } +} + func (u *gitUpstream) FetchUpstream(ctx context.Context, dest string) (string, string, error) { repoSpec := &git.RepoSpec{ OrgRepo: u.git.Repo, @@ -123,6 +145,23 @@ func (u *gitUpstream) FetchUpstreamLock(ctx context.Context, dest string) (strin return path.Join(repoSpec.Dir, repoSpec.Path), nil } +func (u *gitUpstream) FetchOrigin(ctx context.Context, dest string) (string, string, error) { + repoSpec := &git.RepoSpec{ + OrgRepo: u.origin.Repo, + Path: u.origin.Directory, + Ref: u.origin.Ref, + } + if err := ClonerUsingGitExec(ctx, repoSpec); err != nil { + return "", "", err + } + defer os.RemoveAll(repoSpec.Dir) + if err := pkgutil.CopyPackage(repoSpec.AbsPath(), dest, true, pkg.All); err != nil { + return "", "", err + } + + return dest, repoSpec.Commit, nil +} + func (u *gitUpstream) CloneUpstream(ctx context.Context, dest string) error { repoSpec := &git.RepoSpec{ OrgRepo: u.git.Repo, diff --git a/internal/util/upstream/oci.go b/internal/util/upstream/oci.go index fd97f35e71..090c8b9dca 100644 --- a/internal/util/upstream/oci.go +++ b/internal/util/upstream/oci.go @@ -39,6 +39,7 @@ import ( type ociUpstream struct { oci *kptfilev1.Oci ociLock *kptfilev1.OciLock + origin *kptfilev1.Oci } var _ Fetcher = &ociUpstream{} @@ -49,6 +50,14 @@ func NewOciUpstream(oci *kptfilev1.Oci) Fetcher { } } +func NewOciOrigin(oci *kptfilev1.Oci) Fetcher { + return &ociUpstream{ + origin: &kptfilev1.Oci{ + Image: oci.Image, + }, + } +} + func (u *ociUpstream) String() string { return u.oci.Image } @@ -73,10 +82,27 @@ func (u *ociUpstream) BuildUpstreamLock(digest string) *kptfilev1.UpstreamLock { } } +func (u *ociUpstream) BuildOrigin(digest string) *kptfilev1.Origin { + return &kptfilev1.Origin{ + Type: kptfilev1.OciOrigin, + Oci: &kptfilev1.OciLock{ + Image: u.origin.Image, + Digest: digest, + }, + } +} + func (u *ociUpstream) Validate() error { const op errors.Op = "upstream.Validate" - if len(u.oci.Image) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify image")) + if u.oci != nil { + if len(u.oci.Image) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify image")) + } + } + if u.origin != nil { + if len(u.origin.Image) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify image")) + } } return nil } @@ -99,6 +125,15 @@ func (u *ociUpstream) FetchUpstreamLock(ctx context.Context, dest string) (strin return dest, nil } +func (u *ociUpstream) FetchOrigin(ctx context.Context, dest string) (string, string, error) { + const op errors.Op = "upstream.FetchOrigin" + imageDigest, err := pullAndExtract(u.origin.Image, dest, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) + if err != nil { + return "", "", errors.E(op, errors.OCI, types.UniquePath(dest), err) + } + return dest, imageDigest.Name(), nil +} + func (u *ociUpstream) CloneUpstream(ctx context.Context, dest string) error { const op errors.Op = "upstream.FetchUpstreamClone" // pr := printer.FromContextOrDie(ctx) diff --git a/internal/util/upstream/upstream.go b/internal/util/upstream/upstream.go index fc570e7391..021b811665 100644 --- a/internal/util/upstream/upstream.go +++ b/internal/util/upstream/upstream.go @@ -29,9 +29,11 @@ type Fetcher interface { Validate() error BuildUpstream() *kptfilev1.Upstream BuildUpstreamLock(digest string) *kptfilev1.UpstreamLock + BuildOrigin(digest string) *kptfilev1.Origin FetchUpstream(ctx context.Context, dest string) (absPath string, digest string, err error) FetchUpstreamLock(ctx context.Context, dest string) (absPath string, err error) + FetchOrigin(ctx context.Context, dest string) (absPath string, digest string, err error) CloneUpstream(ctx context.Context, dest string) error diff --git a/pkg/api/kptfile/v1/types.go b/pkg/api/kptfile/v1/types.go index 8a53713c81..f1a2c6cb95 100644 --- a/pkg/api/kptfile/v1/types.go +++ b/pkg/api/kptfile/v1/types.go @@ -49,6 +49,9 @@ type KptFile struct { // UpstreamLock is a resolved locator for the last fetch of the package. UpstreamLock *UpstreamLock `yaml:"upstreamLock,omitempty" json:"upstreamLock,omitempty"` + // Origin is a resolved locator for the last pull or push of the package. + Origin *Origin `yaml:"origin,omitempty" json:"origin,omitempty"` + // Info contains metadata such as license, documentation, etc. Info *PackageInfo `yaml:"info,omitempty" json:"info,omitempty"` @@ -164,6 +167,18 @@ type UpstreamLock struct { Oci *OciLock `yaml:"oci,omitempty" json:"oci,omitempty"` } +// Origin is a resolved locator when the package was last pulled or pushed. +type Origin struct { + // Type is the type of origin. + Type OriginType `yaml:"type,omitempty" json:"type,omitempty"` + + // Git is the resolved locator for a package on Git. + Git *GitLock `yaml:"git,omitempty" json:"git,omitempty"` + + // Oci is the resolved locator for a package in an OCI image registry. + Oci *OciLock `yaml:"oci,omitempty" json:"oci,omitempty"` +} + // GitLock is the resolved locator for a package on Git. type GitLock struct { // Repo is the git repository that was fetched. @@ -188,6 +203,9 @@ type OciLock struct { // Image is the OCI image repository for the package. // e.g. 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY_NAME/app-frontend@sha256:b0c94f11d856e59673daca566857a7ead126ef8e2b6915ed662804f858d7eaea' Image string `yaml:"image,omitempty" json:"image,omitempty"` + + // Digest is the unique sha of the image when it was last pulled. + Digest string `yaml:"digest,omitempty" json:"digest,omitempty"` } // PackageInfo contains optional information about the package such as license, documentation, etc. From bbd67876e20374a70f1b0aae01828e8788d9d0ce Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Thu, 9 Dec 2021 23:45:13 +0000 Subject: [PATCH 17/26] Adding kpt pkg push command --- commands/pkgcmd.go | 2 + go.mod | 1 + go.sum | 2 + internal/cmdpull/cmdpull.go | 1 - internal/cmdpush/cmdpush.go | 160 ++++++++++++++++++++++++++++ internal/util/parse/parse.go | 18 +++- internal/util/pull/pull.go | 4 - internal/util/push/push.go | 155 +++++++++++++++++++++++++++ internal/util/upstream/git.go | 49 ++++++--- internal/util/upstream/oci.go | 162 ++++++++++++++++++++++++++++- internal/util/upstream/upstream.go | 30 ++++++ pkg/kptfile/kptfileutil/util.go | 15 +++ 12 files changed, 574 insertions(+), 25 deletions(-) create mode 100644 internal/cmdpush/cmdpush.go create mode 100644 internal/util/push/push.go diff --git a/commands/pkgcmd.go b/commands/pkgcmd.go index 0f9ca21190..a2b851a2eb 100644 --- a/commands/pkgcmd.go +++ b/commands/pkgcmd.go @@ -21,6 +21,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/cmdget" "github.com/GoogleContainerTools/kpt/internal/cmdinit" "github.com/GoogleContainerTools/kpt/internal/cmdpull" + "github.com/GoogleContainerTools/kpt/internal/cmdpush" "github.com/GoogleContainerTools/kpt/internal/cmdupdate" "github.com/GoogleContainerTools/kpt/internal/docs/generated/pkgdocs" "github.com/GoogleContainerTools/kpt/thirdparty/cmdconfig/commands/cmdtree" @@ -49,6 +50,7 @@ func GetPkgCommand(ctx context.Context, name string) *cobra.Command { cmdget.NewCommand(ctx, name), cmdinit.NewCommand(ctx, name), cmdupdate.NewCommand(ctx, name), cmddiff.NewCommand(ctx, name), cmdtree.NewCommand(ctx, name), cmdpull.NewCommand(ctx, name), + cmdpush.NewCommand(ctx, name), ) return pkg } diff --git a/go.mod b/go.mod index c06e18e29a..ae6d8e6287 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/google/go-containerregistry v0.6.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/igorsobreira/titlecase v0.0.0-20140109233139-4156b5b858ac + github.com/masterminds/semver v1.5.0 // indirect github.com/otiai10/copy v1.6.0 github.com/philopon/go-toposort v0.0.0-20170620085441-9be86dbd762f github.com/posener/complete/v2 v2.0.1-alpha.12 diff --git a/go.sum b/go.sum index 53a56cfb02..4cee3e297a 100644 --- a/go.sum +++ b/go.sum @@ -630,6 +630,8 @@ github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= +github.com/masterminds/semver v1.5.0 h1:hTxJTTY7tjvnWMrl08O6u3G6BLlKVwxSz01lVac9P8U= +github.com/masterminds/semver v1.5.0/go.mod h1:s7KNT9fnd7edGzwwP7RBX4H0v/CYd5qdOLfkL1V75yg= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= diff --git a/internal/cmdpull/cmdpull.go b/internal/cmdpull/cmdpull.go index fa954f01e2..0c9c9898e5 100644 --- a/internal/cmdpull/cmdpull.go +++ b/internal/cmdpull/cmdpull.go @@ -80,7 +80,6 @@ func (r *Runner) parseArgs(args []string) (string, error) { t1, err1 := parse.GitParseArgs(r.ctx, args) if err1 == nil { - r.Pull.Git = &t1.Git r.Pull.Upstream = upstream.NewGitOrigin(&t1.Git) return t1.Destination, nil } diff --git a/internal/cmdpush/cmdpush.go b/internal/cmdpush/cmdpush.go new file mode 100644 index 0000000000..aa6c8c6592 --- /dev/null +++ b/internal/cmdpush/cmdpush.go @@ -0,0 +1,160 @@ +package cmdpush + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strings" + + docs "github.com/GoogleContainerTools/kpt/internal/docs/generated/pkgdocs" + "github.com/GoogleContainerTools/kpt/internal/errors" + "github.com/GoogleContainerTools/kpt/internal/pkg" + "github.com/GoogleContainerTools/kpt/internal/types" + "github.com/GoogleContainerTools/kpt/internal/util/argutil" + "github.com/GoogleContainerTools/kpt/internal/util/cmdutil" + "github.com/GoogleContainerTools/kpt/internal/util/parse" + "github.com/GoogleContainerTools/kpt/internal/util/push" + "github.com/GoogleContainerTools/kpt/internal/util/upstream" + "github.com/spf13/cobra" +) + +// NewRunner returns a command runner +func NewRunner(ctx context.Context, parent string) *Runner { + r := &Runner{ + ctx: ctx, + } + c := &cobra.Command{ + Use: "push [DIR@VERSION] [flags]", + Args: cobra.MaximumNArgs(1), + Short: docs.GetShort, + Long: docs.GetShort + "\n" + docs.GetLong, + Example: docs.GetExamples, + RunE: r.runE, + PreRunE: r.preRunE, + } + + c.Flags().StringVar(&r.Origin, "origin", "", + "assigns or changes the location where the package should be pushed. Default is to push it to "+ + "the origin from which the package was pulled.") + c.Flags().BoolVar(&r.Increment, "increment", false, + "increment the version of the package when pushed. This will increment the DIR@VERSION if provided, "+ + "otherwise it will increment the origin's version when pulled. The version must be semver or integer, and "+ + "may have an optional leading 'v'") + cmdutil.FixDocs("kpt", parent, c) + r.Command = c + return r +} + +func NewCommand(ctx context.Context, parent string) *cobra.Command { + return NewRunner(ctx, parent).Command +} + +// Runner contains the run function +type Runner struct { + ctx context.Context + Push push.Command + Command *cobra.Command + Origin string + Increment bool +} + +func (r *Runner) preRunE(_ *cobra.Command, args []string) error { + if err := r.parseArgs(args); err != nil { + return err + } + + r.Push.Increment = r.Increment + + return nil +} + +func (r *Runner) parseArgs(args []string) error { + const op errors.Op = "cmdpublish.preRunE" + + var path string + var ref string + + if len(args) >= 1 { + parts := strings.Split(args[0], "@") + if len(parts) > 2 { + return errors.E(op, errors.InvalidParam, fmt.Errorf("at most 1 version permitted")) + } + + path = parts[0] + if len(parts) == 2 { + ref = parts[1] + } + } + + if path == "" { + // default to current directory + path = "." + } + + resolvedPath, err := argutil.ResolveSymlink(r.ctx, path) + if err != nil { + return err + } + + if ref != "" { + r.Push.Ref = ref + } + + p, err := pkg.New(resolvedPath) + if err != nil { + return errors.E(op, err) + } + relPath, err := resolveRelPath(p.UniquePath) + if err != nil { + return errors.E(op, p.UniquePath, err) + } + if strings.HasPrefix(relPath, pkg.ParentDir) { + return errors.E(op, p.UniquePath, fmt.Errorf("package path must be under current working directory")) + } + + r.Push.Pkg = p + + if r.Origin != "" { + t1, err1 := parse.GitParseArgs(r.ctx, []string {r.Origin, ""}) + if err1 == nil { + r.Push.Remote = upstream.NewGitOrigin(&t1.Git) + return nil + } + + t2, err2 := parse.OciParseArgs(r.ctx, []string {r.Origin, ""}) + if err2 == nil { + r.Push.Remote = upstream.NewOciOrigin(&t2.Oci) + return nil + } + + return errors.E(op, fmt.Errorf("%v %v", err1, err2)) + } + + return nil +} + +func (r *Runner) runE(c *cobra.Command, _ []string) error { + const op errors.Op = "cmdpush.runE" + if err := r.Push.Run(r.ctx); err != nil { + return errors.E(op, r.Push.Pkg.UniquePath, err) + } + + return nil +} + +func resolveRelPath(path types.UniquePath) (string, error) { + const op errors.Op = "cmdupdate.resolveRelPath" + cwd, err := os.Getwd() + if err != nil { + return "", errors.E(op, errors.IO, + fmt.Errorf("error looking up current working directory: %w", err)) + } + + relPath, err := filepath.Rel(cwd, path.String()) + if err != nil { + return "", errors.E(op, errors.IO, + fmt.Errorf("error resolving the relative path: %w", err)) + } + return relPath, nil +} diff --git a/internal/util/parse/parse.go b/internal/util/parse/parse.go index 21fca6462c..9e526b108c 100644 --- a/internal/util/parse/parse.go +++ b/internal/util/parse/parse.go @@ -114,14 +114,17 @@ func GitParseArgs(ctx context.Context, args []string) (GitTarget, error) { version = defaultRef } - destination, err := getDest(args[1], repo, remoteDir) - if err != nil { - return g, err - } g.Ref = version g.Directory = path.Clean(remoteDir) g.Repo = repo - g.Destination = filepath.Clean(destination) + + if len(args) >= 2 { + destination, err := getDest(args[1], repo, remoteDir) + if err != nil { + return g, err + } + g.Destination = filepath.Clean(destination) + } return g, nil } @@ -286,6 +289,11 @@ func getRepoAndPkg(v string) (string, string, error) { } func getDest(v, repo, subdir string) (string, error) { + // v is "" for commands that do not require an output path + if v == "" { + return "", nil + } + v = filepath.Clean(v) f, err := os.Stat(v) diff --git a/internal/util/pull/pull.go b/internal/util/pull/pull.go index c3d4ada581..36d34de61f 100644 --- a/internal/util/pull/pull.go +++ b/internal/util/pull/pull.go @@ -26,16 +26,12 @@ import ( "github.com/GoogleContainerTools/kpt/internal/pkg" "github.com/GoogleContainerTools/kpt/internal/types" "github.com/GoogleContainerTools/kpt/internal/util/upstream" - kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" ) // Command fetches a package from a git repository, copies it to a local // directory, and expands any remote subpackages. type Command struct { - // Git contains information about the git repo to fetch - Git *kptfilev1.Git - // Contains information about the upstraem package to fetch Upstream upstream.Fetcher diff --git a/internal/util/push/push.go b/internal/util/push/push.go new file mode 100644 index 0000000000..5289c6f888 --- /dev/null +++ b/internal/util/push/push.go @@ -0,0 +1,155 @@ +// Copyright 2019 Google LLC +// +// 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 get contains libraries for fetching packages. +package push + +import ( + "bytes" + "context" + "fmt" + "strings" + + "github.com/GoogleContainerTools/kpt/internal/errors" + "github.com/GoogleContainerTools/kpt/internal/pkg" + "github.com/GoogleContainerTools/kpt/internal/printer" + "github.com/GoogleContainerTools/kpt/internal/util/upstream" + "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" + "github.com/masterminds/semver" +) + +// Command fetches a package from a git repository, copies it to a local +// directory, and expands any remote subpackages. +type Command struct { + // Pkg captures information about the package that should be push. + Pkg *pkg.Pkg + + // Ref is the version to push to origin + Ref string + + // Contains information about the package origin + Remote upstream.Fetcher + + // Increment determines is the version portion of the reference should be increased + Increment bool + + // Origin assigns remote location for push. Ref and Increment will alter parts of this value. + Path string +} + +// Run runs the Command. +func (c Command) Run(ctx context.Context) error { + const op errors.Op = "push.Run" + pr := printer.FromContextOrDie(ctx) + + if err := (&c).DefaultValues(); err != nil { + return errors.E(op, err) + } + + path := c.Pkg.UniquePath.String() + kf, err := c.Pkg.Kptfile() + if err != nil { + return errors.E(op, c.Pkg.UniquePath, err) + } + + if c.Remote == nil { + c.Remote, err = upstream.NewOrigin(kf) + if err != nil { + return errors.E(op, c.Pkg.UniquePath, fmt.Errorf("package must have an origin reference: %v", err)) + } + } + + if c.Ref != "" { + c.Remote.SetOriginRef(c.Ref) + } + + if c.Increment { + // TODO(dejardin) move this logic into a util with test coverage + ref, err := c.Remote.OriginRef() + if err != nil { + return errors.E(op, c.Pkg.UniquePath, fmt.Errorf("missing origin version information: %v", err)) + } + + prefix := "" + if ref != "" && ref[:1] == "v" { + prefix = "v" + } + + dotParts := len(strings.SplitN(ref, ".", 3)) + if dotParts > 3 { + return errors.E(op, c.Pkg.UniquePath, fmt.Errorf("origin version '%s' has more than three dotted parts", ref)) + } + + v, err := semver.NewVersion(ref) + if err != nil { + return errors.E(op, c.Pkg.UniquePath, fmt.Errorf("unable to increment '%s': %v", ref, err)) + } + + var buf bytes.Buffer + switch dotParts { + case 1: + fmt.Fprintf(&buf, "%s%d", prefix, v.Major() + 1) + case 2: + fmt.Fprintf(&buf, "%s%d.%d", prefix, v.Major(), v.Minor() + 1) + case 3: + fmt.Fprintf(&buf, "%s%d.%d.%d", prefix, v.Major(), v.Minor(), v.Patch() + 1) + } + if v.Prerelease() != "" { + fmt.Fprintf(&buf, "-%s", v.Prerelease()) + } + if v.Metadata() != "" { + fmt.Fprintf(&buf, "+%s", v.Metadata()) + } + + pr.Printf("Incrementing %s to %s\n",ref, buf.String()) + + c.Remote.SetOriginRef(buf.String()) + } + + // the kptfile pushed in the package does not have origin data + // this is because the digest will be incorrect. Also, if it is + // pulled from a different location or via different branch, the + // correct origin will be added as part of the pull operation. + kf.Origin = nil + + pr.Printf("Pushing origin %s\n", c.Remote.OriginString()) + + digest, err := c.Remote.PushOrigin(ctx, path, kf) + if err != nil { + return errors.E(op, c.Pkg.UniquePath, err) + } + + pr.Printf("Pushed digest %s\n", digest) + + kf.Origin = c.Remote.BuildOrigin(digest) + err = kptfileutil.WriteFile(path, kf) + if err != nil { + return errors.E(op, c.Pkg.UniquePath, err) + } + + return nil +} + +// DefaultValues sets values to the default values if they were unspecified +func (c *Command) DefaultValues() error { + // const op errors.Op = "pull.DefaultValues" + // if c.Origin == nil { + // return errors.E(op, errors.MissingParam, fmt.Errorf("must specify git repo or image reference information")) + // } + // if err := c.Origin.Validate(); err != nil { + // return errors.E(op, err) + // } + + return nil +} diff --git a/internal/util/upstream/git.go b/internal/util/upstream/git.go index 0d0b76b286..2ab349b09d 100644 --- a/internal/util/upstream/git.go +++ b/internal/util/upstream/git.go @@ -30,6 +30,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/types" "github.com/GoogleContainerTools/kpt/internal/util/git" "github.com/GoogleContainerTools/kpt/internal/util/pkgutil" + kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" v1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" "github.com/otiai10/copy" @@ -38,7 +39,7 @@ import ( type gitUpstream struct { git *v1.Git gitLock *v1.GitLock - origin *v1.Git + origin *v1.GitLock } var _ Fetcher = &gitUpstream{} @@ -51,7 +52,11 @@ func NewGitUpstream(git *v1.Git) Fetcher { func NewGitOrigin(git *v1.Git) Fetcher { return &gitUpstream{ - origin: git, + origin: &v1.GitLock{ + Repo: git.Repo, + Directory: git.Directory, + Ref: git.Ref, + }, } } @@ -63,20 +68,25 @@ func (u *gitUpstream) LockedString() string { return fmt.Sprintf("%s@%s", u.gitLock.Repo, u.gitLock.Ref) } + +func (u *gitUpstream) OriginString() string { + return fmt.Sprintf("%s@%s", u.origin.Repo, u.origin.Ref) +} + + func (u *gitUpstream) Validate() error { const op errors.Op = "upstream.Validate" g := u.git - if g == nil { - g = u.origin - } - if len(g.Repo) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify repo")) - } - if len(g.Ref) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify ref")) - } - if len(g.Directory) == 0 { - return errors.E(op, errors.MissingParam, fmt.Errorf("must specify directory")) + if g != nil { + if len(g.Repo) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify repo")) + } + if len(g.Ref) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify ref")) + } + if len(g.Directory) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify directory")) + } } return nil } @@ -171,6 +181,10 @@ func (u *gitUpstream) CloneUpstream(ctx context.Context, dest string) error { return cloneAndCopy(ctx, repoSpec, dest) } +func (u *gitUpstream) PushOrigin(ctx context.Context, dest string, kptfile *kptfilev1.KptFile) (digest string, err error) { + return "", fmt.Errorf("git push not implemented") +} + func (u *gitUpstream) Ref() (string, error) { return u.git.Ref, nil } @@ -180,6 +194,15 @@ func (u *gitUpstream) SetRef(ref string) error { return nil } +func (u *gitUpstream) OriginRef() (string, error) { + return u.origin.Ref, nil +} + +func (u *gitUpstream) SetOriginRef(ref string) error { + u.origin.Ref = ref + return nil +} + // shouldUpdateSubPkgRef checks if subpkg ref should be updated. // This is true if pkg has the same upstream repo, upstream directory is within or equal to root pkg directory and original root pkg ref matches the subpkg ref. func (u *gitUpstream) ShouldUpdateSubPkgRef(rootUpstream Fetcher, originalRootKfRef string) bool { diff --git a/internal/util/upstream/oci.go b/internal/util/upstream/oci.go index 090c8b9dca..277a4078d9 100644 --- a/internal/util/upstream/oci.go +++ b/internal/util/upstream/oci.go @@ -16,9 +16,12 @@ package upstream import ( "archive/tar" + "bytes" + "compress/gzip" "context" "fmt" "io" + "io/fs" "io/ioutil" "os" "path/filepath" @@ -30,8 +33,10 @@ import ( "github.com/GoogleContainerTools/kpt/internal/util/pkgutil" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" + "github.com/google/go-containerregistry/pkg/crane" "github.com/google/go-containerregistry/pkg/gcrane" "github.com/google/go-containerregistry/pkg/name" + "github.com/google/go-containerregistry/pkg/v1/empty" "github.com/google/go-containerregistry/pkg/v1/mutate" "github.com/google/go-containerregistry/pkg/v1/remote" ) @@ -39,7 +44,7 @@ import ( type ociUpstream struct { oci *kptfilev1.Oci ociLock *kptfilev1.OciLock - origin *kptfilev1.Oci + origin *kptfilev1.OciLock } var _ Fetcher = &ociUpstream{} @@ -52,7 +57,7 @@ func NewOciUpstream(oci *kptfilev1.Oci) Fetcher { func NewOciOrigin(oci *kptfilev1.Oci) Fetcher { return &ociUpstream{ - origin: &kptfilev1.Oci{ + origin: &kptfilev1.OciLock{ Image: oci.Image, }, } @@ -66,6 +71,10 @@ func (u *ociUpstream) LockedString() string { return u.ociLock.Image } +func (u *ociUpstream) OriginString() string { + return u.origin.Image +} + func (u *ociUpstream) BuildUpstream() *kptfilev1.Upstream { return &kptfilev1.Upstream{ Type: kptfilev1.OciOrigin, @@ -168,6 +177,18 @@ func (u *ociUpstream) CloneUpstream(ctx context.Context, dest string) error { return nil } +func (u *ociUpstream) PushOrigin(ctx context.Context, source string, kptfile *kptfilev1.KptFile) (digest string, err error) { + const op errors.Op = "upstream.PushOrigin" + + imageDigest, err := archiveAndPush(u.origin.Image, source, kptfile, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) + if err != nil { + return "",errors.E(op, errors.OCI, types.UniquePath(source), err) + } + + return imageDigest.String(), nil +} + + func (u *ociUpstream) Ref() (string, error) { const op errors.Op = "upstream.Ref" r, err := name.ParseReference(u.oci.Image) @@ -193,6 +214,31 @@ func (u *ociUpstream) SetRef(ref string) error { return nil } +func (u *ociUpstream) OriginRef() (string, error) { + const op errors.Op = "upstream.OriginRef" + r, err := name.ParseReference(u.origin.Image) + if err != nil { + return "", errors.E(op, errors.Internal, fmt.Errorf("error parsing reference: %s %w", u.origin.Image, err)) + } + return r.Identifier(), nil +} + +func (u *ociUpstream) SetOriginRef(ref string) error { + const op errors.Op = "upstream.SetOriginRef" + r, err := name.ParseReference(u.origin.Image) + if err != nil { + return errors.E(op, errors.Internal, fmt.Errorf("error parsing reference: %s %w", u.origin.Image, err)) + } + + if len(strings.SplitN(ref, "sha256:", 2)[0]) == 0 { + u.origin.Image = r.Context().Digest(ref).Name() + } else { + u.origin.Image = r.Context().Tag(ref).Name() + } + + return nil +} + // shouldUpdateSubPkgRef checks if subpkg ref should be updated. // This is true if pkg has the same upstream repo, upstream directory is within or equal to root pkg directory and original root pkg ref matches the subpkg ref. func (u *ociUpstream) ShouldUpdateSubPkgRef(rootUpstream Fetcher, originalRootKfRef string) bool { @@ -283,3 +329,115 @@ func pullAndExtract(imageName string, dir string, options ...remote.Option) (nam // Return the image with digest when successful, needed for upstreamLock return imageDigest, nil } + +// archiveAndPush uses current credentials (gcloud auth) to tar and +// extract (untar) image files to target directory. The desired version or digest must +// be in the imageName, and the resolved image sha256 digest is returned. +func archiveAndPush(imageName string, dir string, kptfile *kptfilev1.KptFile, options ...remote.Option) (name.Reference, error) { + const op errors.Op = "upstream.archiveAndPush" + + ref, err := name.ParseReference(imageName) + if err != nil { + return nil, fmt.Errorf("parsing reference %q: %v", imageName, err) + } + + // Make new layer + tarFile, err := ioutil.TempFile("", "tar") + if err != nil { + return nil, err + } + defer os.Remove(tarFile.Name()) + + if err := func() error { + defer tarFile.Close() + + gw := gzip.NewWriter(tarFile) + defer gw.Close() + + tw := tar.NewWriter(gw) + defer tw.Close() + + if err := filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error { + if err != nil { + return err + } + + relative, err := filepath.Rel(dir, path) + if err != nil { + return err + } + if info.IsDir() && relative == "." { + return nil + } + + // TODO(dejardin) if info is symlink also read link target + link := "" + + // generate tar header + header, err := tar.FileInfoHeader(info, link) + if err != nil { + return err + } + + var buf *bytes.Buffer + if strings.EqualFold(header.Name, "Kptfile") { + buf = &bytes.Buffer{} + kptfileutil.Write(buf, kptfile) + header.Size = int64(buf.Len()) + } + + // must provide real name + // (see https://golang.org/src/archive/tar/common.go?#L626) + header.Name = filepath.ToSlash(relative) + + // write header + if err := tw.WriteHeader(header); err != nil { + return err + } + // if not a dir, write file content + if !info.IsDir() { + data, err := os.Open(path) + if err != nil { + return err + } + if buf != nil { + if _, err := io.Copy(tw, buf); err != nil { + return err + } + } else { + if _, err := io.Copy(tw, data); err != nil { + return err + } + } + } + return nil + }); err != nil { + return err + } + + return nil + }(); err != nil { + return nil, err + } + + // Append new layer + newLayers := []string{tarFile.Name()} + img, err := crane.Append(empty.Image, newLayers...) + if err != nil { + return nil, fmt.Errorf("appending %v: %v", newLayers, err) + } + + if err := remote.Write(ref, img, options...); err != nil { + return nil, fmt.Errorf("pushing image %s: %v", ref, err) + } + + // Determine the digest of the image that was pushed + imageDigestHash, err := img.Digest() + if err != nil { + return nil, errors.E(op, fmt.Errorf("error calculating image digest: %w", err)) + } + imageDigest := ref.Context().Digest("sha256:" + imageDigestHash.Hex) + + // Return the image with digest when successful, needed for upstreamLock + return imageDigest, nil +} diff --git a/internal/util/upstream/upstream.go b/internal/util/upstream/upstream.go index 021b811665..18a689f8a8 100644 --- a/internal/util/upstream/upstream.go +++ b/internal/util/upstream/upstream.go @@ -25,6 +25,7 @@ import ( type Fetcher interface { fmt.Stringer LockedString() string + OriginString() string Validate() error BuildUpstream() *kptfilev1.Upstream @@ -34,12 +35,16 @@ type Fetcher interface { FetchUpstream(ctx context.Context, dest string) (absPath string, digest string, err error) FetchUpstreamLock(ctx context.Context, dest string) (absPath string, err error) FetchOrigin(ctx context.Context, dest string) (absPath string, digest string, err error) + PushOrigin(ctx context.Context, dest string, kptfile *kptfilev1.KptFile) (digest string, err error) CloneUpstream(ctx context.Context, dest string) error Ref() (string, error) SetRef(ref string) error ShouldUpdateSubPkgRef(rootUpstream Fetcher, originalRootRef string) bool + + OriginRef() (string, error) + SetOriginRef(ref string) error } func NewUpstream(kf *kptfilev1.KptFile) (Fetcher, error) { @@ -75,6 +80,31 @@ func NewUpstream(kf *kptfilev1.KptFile) (Fetcher, error) { return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile upstream type must be one of: %s,%s", kptfilev1.GitOrigin, kptfilev1.OciOrigin)) } +func NewOrigin(kf *kptfilev1.KptFile) (Fetcher, error) { + const op errors.Op = "upstream.NewOrigin" + if kf != nil && kf.Origin != nil { + switch kf.Origin.Type { + case kptfilev1.GitOrigin: + if kf.Upstream.Git == nil { + return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile origin must have git information")) + } + u := &gitUpstream{ + origin: kf.Origin.Git, + } + return u, nil + case kptfilev1.OciOrigin: + if kf.Origin.Oci == nil { + return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile origin must have oci information")) + } + u := &ociUpstream{ + origin: kf.Origin.Oci, + } + return u, nil + } + } + return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile origin type must be one of: %s,%s", kptfilev1.GitOrigin, kptfilev1.OciOrigin)) +} + func ShouldUpdateSubPkgRef(subUpstream Fetcher, rootUpstream Fetcher, originalRootRef string) bool { return subUpstream.ShouldUpdateSubPkgRef(rootUpstream, originalRootRef) } diff --git a/pkg/kptfile/kptfileutil/util.go b/pkg/kptfile/kptfileutil/util.go index e0c64b3e95..a697d189f3 100644 --- a/pkg/kptfile/kptfileutil/util.go +++ b/pkg/kptfile/kptfileutil/util.go @@ -18,6 +18,7 @@ import ( "bytes" goerrors "errors" "fmt" + "io" "io/ioutil" "os" "path/filepath" @@ -50,6 +51,20 @@ func WriteFile(dir string, k *kptfilev1.KptFile) error { return nil } +func Write(dst io.Writer, k *kptfilev1.KptFile) error { + const op errors.Op = "kptfileutil.WriteFile" + b, err := yaml.MarshalWithOptions(k, &yaml.EncoderOptions{SeqIndent: yaml.WideSequenceStyle}) + if err != nil { + return err + } + + if _, err := dst.Write(b); err != nil { + return errors.E(op, errors.IO, err) + } + + return nil +} + // ValidateInventory returns true and a nil error if the passed inventory // is valid; otherwiste, false and the reason the inventory is not valid // is returned. A valid inventory must have a non-empty namespace, name, From 074e0eea9084c182ab1ea2e7236f5fd38b8553e8 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Fri, 10 Dec 2021 18:07:09 +0000 Subject: [PATCH 18/26] Minor fixes * Fixing a direct reference to Git field * Adding output to pkg push command --- internal/util/pull/pull.go | 7 +++++++ internal/util/update/common.go | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/internal/util/pull/pull.go b/internal/util/pull/pull.go index 36d34de61f..94351bc619 100644 --- a/internal/util/pull/pull.go +++ b/internal/util/pull/pull.go @@ -24,6 +24,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/errors" "github.com/GoogleContainerTools/kpt/internal/pkg" + "github.com/GoogleContainerTools/kpt/internal/printer" "github.com/GoogleContainerTools/kpt/internal/types" "github.com/GoogleContainerTools/kpt/internal/util/upstream" "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" @@ -43,6 +44,8 @@ type Command struct { // Run runs the Command. func (c Command) Run(ctx context.Context) error { const op errors.Op = "pull.Run" + pr := printer.FromContextOrDie(ctx) + if err := (&c).DefaultValues(); err != nil { return errors.E(op, err) } @@ -56,12 +59,16 @@ func (c Command) Run(ctx context.Context) error { return errors.E(op, errors.IO, types.UniquePath(c.Destination), err) } + pr.Printf("Pulling origin %s\n", c.Upstream.OriginString()) + // TODO(dejardin) need to understand abs path for kpt pkg pull from git _, digest, err := c.Upstream.FetchOrigin(ctx, c.Destination) if err != nil { return errors.E(op, types.UniquePath(c.Destination), err) } + pr.Printf("Pulled digest %s\n", digest) + kf, err := pkg.ReadKptfile(c.Destination) if err != nil { return errors.E(op, types.UniquePath(c.Destination), err) diff --git a/internal/util/update/common.go b/internal/util/update/common.go index 51308708a3..f62d4885f1 100644 --- a/internal/util/update/common.go +++ b/internal/util/update/common.go @@ -39,7 +39,7 @@ func PkgHasUpdatedUpstream(local, origin string) (bool, error) { // If the upstream information in local has changed from origin, it // means the user had updated the package independently and we don't // want to override it. - if !reflect.DeepEqual(localKf.Upstream.Git, originKf.Upstream.Git) { + if !reflect.DeepEqual(localKf.Upstream, originKf.Upstream) { return true, nil } return false, nil From 12a5b1a6e34f0545be661c891c1d6ef25007b36e Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Fri, 10 Dec 2021 18:14:32 +0000 Subject: [PATCH 19/26] Rename upstream pkg to remote --- internal/cmdget/cmdget.go | 6 ++-- internal/cmdpull/cmdpull.go | 6 ++-- internal/cmdpush/cmdpush.go | 6 ++-- internal/testutil/setup_manager.go | 6 ++-- internal/util/diff/diff.go | 6 ++-- internal/util/fetch/fetch.go | 4 +-- internal/util/get/example_test.go | 14 ++++---- internal/util/get/get.go | 6 ++-- internal/util/get/get_test.go | 36 +++++++++---------- internal/util/pull/pull.go | 4 +-- internal/util/push/push.go | 6 ++-- internal/util/{upstream => remote}/git.go | 2 +- .../util/{upstream => remote}/git_test.go | 2 +- internal/util/{upstream => remote}/oci.go | 2 +- .../util/{upstream => remote}/upstream.go | 6 ++-- .../{upstream => remote}/upstream_test.go | 2 +- internal/util/update/update.go | 12 +++---- 17 files changed, 63 insertions(+), 63 deletions(-) rename internal/util/{upstream => remote}/git.go (99%) rename internal/util/{upstream => remote}/git_test.go (99%) rename internal/util/{upstream => remote}/oci.go (99%) rename internal/util/{upstream => remote}/upstream.go (97%) rename internal/util/{upstream => remote}/upstream_test.go (99%) diff --git a/internal/cmdget/cmdget.go b/internal/cmdget/cmdget.go index 58e4351692..71b6602f86 100644 --- a/internal/cmdget/cmdget.go +++ b/internal/cmdget/cmdget.go @@ -29,7 +29,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/util/cmdutil" "github.com/GoogleContainerTools/kpt/internal/util/get" "github.com/GoogleContainerTools/kpt/internal/util/parse" - "github.com/GoogleContainerTools/kpt/internal/util/upstream" + "github.com/GoogleContainerTools/kpt/internal/util/remote" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/spf13/cobra" ) @@ -108,13 +108,13 @@ func (r *Runner) parseArgs(args []string) (string, error) { t1, err1 := parse.GitParseArgs(r.ctx, args) if err1 == nil { r.Get.Git = &t1.Git - r.Get.Upstream = upstream.NewGitUpstream(&t1.Git) + r.Get.Upstream = remote.NewGitUpstream(&t1.Git) return t1.Destination, nil } t2, err2 := parse.OciParseArgs(r.ctx, args) if err2 == nil { - r.Get.Upstream = upstream.NewOciUpstream(&t2.Oci) + r.Get.Upstream = remote.NewOciUpstream(&t2.Oci) return t2.Destination, nil } diff --git a/internal/cmdpull/cmdpull.go b/internal/cmdpull/cmdpull.go index 0c9c9898e5..7d109fe5da 100644 --- a/internal/cmdpull/cmdpull.go +++ b/internal/cmdpull/cmdpull.go @@ -13,7 +13,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/util/cmdutil" "github.com/GoogleContainerTools/kpt/internal/util/parse" "github.com/GoogleContainerTools/kpt/internal/util/pull" - "github.com/GoogleContainerTools/kpt/internal/util/upstream" + "github.com/GoogleContainerTools/kpt/internal/util/remote" "github.com/spf13/cobra" ) @@ -80,13 +80,13 @@ func (r *Runner) parseArgs(args []string) (string, error) { t1, err1 := parse.GitParseArgs(r.ctx, args) if err1 == nil { - r.Pull.Upstream = upstream.NewGitOrigin(&t1.Git) + r.Pull.Upstream = remote.NewGitOrigin(&t1.Git) return t1.Destination, nil } t2, err2 := parse.OciParseArgs(r.ctx, args) if err2 == nil { - r.Pull.Upstream = upstream.NewOciOrigin(&t2.Oci) + r.Pull.Upstream = remote.NewOciOrigin(&t2.Oci) return t2.Destination, nil } diff --git a/internal/cmdpush/cmdpush.go b/internal/cmdpush/cmdpush.go index aa6c8c6592..b801d3ae60 100644 --- a/internal/cmdpush/cmdpush.go +++ b/internal/cmdpush/cmdpush.go @@ -15,7 +15,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/util/cmdutil" "github.com/GoogleContainerTools/kpt/internal/util/parse" "github.com/GoogleContainerTools/kpt/internal/util/push" - "github.com/GoogleContainerTools/kpt/internal/util/upstream" + "github.com/GoogleContainerTools/kpt/internal/util/remote" "github.com/spf13/cobra" ) @@ -118,13 +118,13 @@ func (r *Runner) parseArgs(args []string) error { if r.Origin != "" { t1, err1 := parse.GitParseArgs(r.ctx, []string {r.Origin, ""}) if err1 == nil { - r.Push.Remote = upstream.NewGitOrigin(&t1.Git) + r.Push.Remote = remote.NewGitOrigin(&t1.Git) return nil } t2, err2 := parse.OciParseArgs(r.ctx, []string {r.Origin, ""}) if err2 == nil { - r.Push.Remote = upstream.NewOciOrigin(&t2.Oci) + r.Push.Remote = remote.NewOciOrigin(&t2.Oci) return nil } diff --git a/internal/testutil/setup_manager.go b/internal/testutil/setup_manager.go index c771eaaf8d..1be9e9a458 100644 --- a/internal/testutil/setup_manager.go +++ b/internal/testutil/setup_manager.go @@ -25,7 +25,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/printer/fake" "github.com/GoogleContainerTools/kpt/internal/testutil/pkgbuilder" "github.com/GoogleContainerTools/kpt/internal/util/get" - "github.com/GoogleContainerTools/kpt/internal/util/upstream" + "github.com/GoogleContainerTools/kpt/internal/util/remote" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/yaml" @@ -107,7 +107,7 @@ func (g *TestSetupManager) Init() bool { // Get the content from the upstream repo into the local workspace. if !assert.NoError(g.T, get.Command{ Destination: filepath.Join(g.LocalWorkspace.WorkspaceDirectory, g.targetDir), - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: g.Repos[Upstream].RepoDirectory, Ref: g.GetRef, Directory: g.GetSubDirectory, @@ -203,7 +203,7 @@ func UpdateGitDir(t *testing.T, name string, gitDir GitDirectory, changes []Cont func (g *TestSetupManager) GetSubPkg(dest, repo, upstreamDir string) { assert.NoError(g.T, get.Command{ Destination: path.Join(g.LocalWorkspace.FullPackagePath(), dest), - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: g.Repos[repo].RepoDirectory, Ref: g.GetRef, Directory: path.Join(g.GetSubDirectory, upstreamDir), diff --git a/internal/util/diff/diff.go b/internal/util/diff/diff.go index 6bebe04535..6179060248 100644 --- a/internal/util/diff/diff.go +++ b/internal/util/diff/diff.go @@ -29,7 +29,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/pkg" "github.com/GoogleContainerTools/kpt/internal/util/addmergecomment" "github.com/GoogleContainerTools/kpt/internal/util/pkgutil" - "github.com/GoogleContainerTools/kpt/internal/util/upstream" + "github.com/GoogleContainerTools/kpt/internal/util/remote" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "sigs.k8s.io/kustomize/kyaml/errors" ) @@ -111,7 +111,7 @@ type Command struct { PkgDiffer PkgDiffer // Contains information about the upstream package to fetch - Upstream upstream.Fetcher + Upstream remote.Fetcher } func (c *Command) Run(ctx context.Context) error { @@ -122,7 +122,7 @@ func (c *Command) Run(ctx context.Context) error { return errors.Errorf("package missing Kptfile at '%s': %v", c.Path, err) } - c.Upstream, err = upstream.NewUpstream(kptFile) + c.Upstream, err = remote.NewUpstream(kptFile) if err != nil { return errors.Errorf("upstream required: %v", err) } diff --git a/internal/util/fetch/fetch.go b/internal/util/fetch/fetch.go index d384e2d687..b7ca9a5f21 100644 --- a/internal/util/fetch/fetch.go +++ b/internal/util/fetch/fetch.go @@ -20,7 +20,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/errors" "github.com/GoogleContainerTools/kpt/internal/pkg" - "github.com/GoogleContainerTools/kpt/internal/util/upstream" + "github.com/GoogleContainerTools/kpt/internal/util/remote" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" ) @@ -43,7 +43,7 @@ func (c Command) Run(ctx context.Context) error { return errors.E(op, c.Pkg.UniquePath, err) } - ups, err := upstream.NewUpstream(kf) + ups, err := remote.NewUpstream(kf) if err != nil { return errors.E(op, c.Pkg.UniquePath, err) } diff --git a/internal/util/get/example_test.go b/internal/util/get/example_test.go index c818717577..8ab1765ac1 100644 --- a/internal/util/get/example_test.go +++ b/internal/util/get/example_test.go @@ -19,12 +19,12 @@ import ( "github.com/GoogleContainerTools/kpt/internal/printer/fake" "github.com/GoogleContainerTools/kpt/internal/util/get" - "github.com/GoogleContainerTools/kpt/internal/util/upstream" + "github.com/GoogleContainerTools/kpt/internal/util/remote" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" ) func ExampleCommand() { - err := get.Command{Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + err := get.Command{Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: "https://github.com/example-org/example-repo", Ref: "v1.0", })}.Run(fake.CtxWithDefaultPrinter()) @@ -34,7 +34,7 @@ func ExampleCommand() { } func ExampleCommand_branch() { - err := get.Command{Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + err := get.Command{Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: "https://github.com/example-org/example-repo", Ref: "refs/heads/v1.0", })}.Run(fake.CtxWithDefaultPrinter()) @@ -44,7 +44,7 @@ func ExampleCommand_branch() { } func ExampleCommand_tag() { - err := get.Command{Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + err := get.Command{Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: "https://github.com/example-org/example-repo", Ref: "refs/tags/v1.0", })}.Run(fake.CtxWithDefaultPrinter()) @@ -54,7 +54,7 @@ func ExampleCommand_tag() { } func ExampleCommand_commit() { - err := get.Command{Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + err := get.Command{Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: "https://github.com/example-org/example-repo", Ref: "8186bef8e5c0621bf80fa8106bd595aae8b62884", })}.Run(fake.CtxWithDefaultPrinter()) @@ -65,7 +65,7 @@ func ExampleCommand_commit() { func ExampleCommand_subdir() { err := get.Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: "https://github.com/example-org/example-repo", Ref: "v1.0", Directory: filepath.Join("path", "to", "package"), @@ -78,7 +78,7 @@ func ExampleCommand_subdir() { func ExampleCommand_destination() { err := get.Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: "https://github.com/example-org/example-repo", Ref: "v1.0", }), diff --git a/internal/util/get/get.go b/internal/util/get/get.go index cf60c23046..281fe55919 100644 --- a/internal/util/get/get.go +++ b/internal/util/get/get.go @@ -28,8 +28,8 @@ import ( "github.com/GoogleContainerTools/kpt/internal/types" "github.com/GoogleContainerTools/kpt/internal/util/addmergecomment" "github.com/GoogleContainerTools/kpt/internal/util/fetch" + "github.com/GoogleContainerTools/kpt/internal/util/remote" "github.com/GoogleContainerTools/kpt/internal/util/stack" - "github.com/GoogleContainerTools/kpt/internal/util/upstream" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" ) @@ -41,7 +41,7 @@ type Command struct { Git *kptfilev1.Git // Contains information about the upstraem package to fetch - Upstream upstream.Fetcher + Upstream remote.Fetcher // Destination is the output directory to clone the package to. Defaults to the name of the package -- // either the base repo name, or the base subdirectory name. @@ -120,7 +120,7 @@ func (c Command) fetchPackages(ctx context.Context, rootPkg *pkg.Pkg) error { packageCount += 1 pr.PrintPackage(p, !(p == rootPkg)) - upstream, err := upstream.NewUpstream(kf) + upstream, err := remote.NewUpstream(kf) if err != nil { return errors.E(op, p.UniquePath, err) } diff --git a/internal/util/get/get_test.go b/internal/util/get/get_test.go index d3becdab47..393d16277c 100644 --- a/internal/util/get/get_test.go +++ b/internal/util/get/get_test.go @@ -24,7 +24,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/testutil" "github.com/GoogleContainerTools/kpt/internal/testutil/pkgbuilder" . "github.com/GoogleContainerTools/kpt/internal/util/get" - "github.com/GoogleContainerTools/kpt/internal/util/upstream" + "github.com/GoogleContainerTools/kpt/internal/util/remote" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/kio" @@ -58,7 +58,7 @@ func TestCommand_Run_failNoRevision(t *testing.T) { defer clean() err := Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: "foo", }), Destination: w.WorkspaceDirectory, @@ -83,7 +83,7 @@ func TestCommand_Run(t *testing.T) { defer testutil.Chdir(t, w.WorkspaceDirectory)() absPath := filepath.Join(w.WorkspaceDirectory, g.RepoName) - err := Command{Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + err := Command{Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: "file://" + g.RepoDirectory, Ref: "master", Directory: "/", @@ -144,7 +144,7 @@ func TestCommand_Run_subdir(t *testing.T) { defer testutil.Chdir(t, w.WorkspaceDirectory)() absPath := filepath.Join(w.WorkspaceDirectory, subdir) - err := Command{Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + err := Command{Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "refs/heads/master", Directory: subdir}), Destination: absPath, }.Run(fake.CtxWithDefaultPrinter()) @@ -208,7 +208,7 @@ func TestCommand_Run_subdir_symlinks(t *testing.T) { cliOutput := &bytes.Buffer{} absPath := filepath.Join(w.WorkspaceDirectory, subdir) - err := Command{Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + err := Command{Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "refs/heads/master", Directory: subdir}), Destination: absPath, }.Run(fake.CtxWithPrinter(cliOutput, cliOutput)) @@ -273,7 +273,7 @@ func TestCommand_Run_destination(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, dest) err := Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "master", Directory: "/", @@ -337,7 +337,7 @@ func TestCommand_Run_subdirAndDestination(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, dest) err := Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "master", Directory: subdir, @@ -417,7 +417,7 @@ func TestCommand_Run_branch(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, g.RepoName) err = Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "refs/heads/exp", Directory: "/", @@ -500,7 +500,7 @@ func TestCommand_Run_tag(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, g.RepoName) err = Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "refs/tags/v2", Directory: "/", @@ -641,7 +641,7 @@ func TestCommand_Run_ref(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, repos[testutil.Upstream].RepoName) err = Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: repos[testutil.Upstream].RepoDirectory, Ref: ref, Directory: tc.directory, @@ -670,7 +670,7 @@ func TestCommand_Run_failExistingDir(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, g.RepoName) err := Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "master", Directory: "/", @@ -724,7 +724,7 @@ func TestCommand_Run_failExistingDir(t *testing.T) { // try to clone and expect a failure err = Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "master", Directory: "/", @@ -781,7 +781,7 @@ func TestCommand_Run_nonexistingParentDir(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, "more", "dirs", g.RepoName) err := Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Ref: "master", Directory: "/", @@ -801,7 +801,7 @@ func TestCommand_Run_failInvalidRepo(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, "foo") err := Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: "foo", Directory: "/", Ref: "refs/heads/master", @@ -831,7 +831,7 @@ func TestCommand_Run_failInvalidBranch(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, g.RepoDirectory) err := Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Directory: "/", Ref: "refs/heads/foo", @@ -864,7 +864,7 @@ func TestCommand_Run_failInvalidTag(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, g.RepoDirectory) err := Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: g.RepoDirectory, Directory: "/", Ref: "refs/tags/foo", @@ -1389,7 +1389,7 @@ func TestCommand_Run_subpackages(t *testing.T) { destinationDir := filepath.Join(w.WorkspaceDirectory, targetDir) err = Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: upstreamRepo.RepoDirectory, Directory: tc.directory, Ref: tc.ref, @@ -1460,7 +1460,7 @@ func TestCommand_Run_symlinks(t *testing.T) { destinationDir := filepath.Join(w.WorkspaceDirectory, upstreamRepo.RepoName) err := Command{ - Upstream: upstream.NewGitUpstream(&kptfilev1.Git{ + Upstream: remote.NewGitUpstream(&kptfilev1.Git{ Repo: upstreamRepo.RepoDirectory, Directory: "/", Ref: "master", diff --git a/internal/util/pull/pull.go b/internal/util/pull/pull.go index 94351bc619..71736b7c39 100644 --- a/internal/util/pull/pull.go +++ b/internal/util/pull/pull.go @@ -26,7 +26,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/pkg" "github.com/GoogleContainerTools/kpt/internal/printer" "github.com/GoogleContainerTools/kpt/internal/types" - "github.com/GoogleContainerTools/kpt/internal/util/upstream" + "github.com/GoogleContainerTools/kpt/internal/util/remote" "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" ) @@ -34,7 +34,7 @@ import ( // directory, and expands any remote subpackages. type Command struct { // Contains information about the upstraem package to fetch - Upstream upstream.Fetcher + Upstream remote.Fetcher // Destination is the output directory to clone the package to. Defaults to the name of the package -- // either the base repo name, or the base subdirectory name. diff --git a/internal/util/push/push.go b/internal/util/push/push.go index 5289c6f888..a915fd930f 100644 --- a/internal/util/push/push.go +++ b/internal/util/push/push.go @@ -24,7 +24,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/errors" "github.com/GoogleContainerTools/kpt/internal/pkg" "github.com/GoogleContainerTools/kpt/internal/printer" - "github.com/GoogleContainerTools/kpt/internal/util/upstream" + "github.com/GoogleContainerTools/kpt/internal/util/remote" "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" "github.com/masterminds/semver" ) @@ -39,7 +39,7 @@ type Command struct { Ref string // Contains information about the package origin - Remote upstream.Fetcher + Remote remote.Fetcher // Increment determines is the version portion of the reference should be increased Increment bool @@ -64,7 +64,7 @@ func (c Command) Run(ctx context.Context) error { } if c.Remote == nil { - c.Remote, err = upstream.NewOrigin(kf) + c.Remote, err = remote.NewOrigin(kf) if err != nil { return errors.E(op, c.Pkg.UniquePath, fmt.Errorf("package must have an origin reference: %v", err)) } diff --git a/internal/util/upstream/git.go b/internal/util/remote/git.go similarity index 99% rename from internal/util/upstream/git.go rename to internal/util/remote/git.go index 2ab349b09d..0cbe36465b 100644 --- a/internal/util/upstream/git.go +++ b/internal/util/remote/git.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package upstream +package remote import ( "context" diff --git a/internal/util/upstream/git_test.go b/internal/util/remote/git_test.go similarity index 99% rename from internal/util/upstream/git_test.go rename to internal/util/remote/git_test.go index bbf07212e6..96dc730c74 100644 --- a/internal/util/upstream/git_test.go +++ b/internal/util/remote/git_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package upstream +package remote import ( "reflect" diff --git a/internal/util/upstream/oci.go b/internal/util/remote/oci.go similarity index 99% rename from internal/util/upstream/oci.go rename to internal/util/remote/oci.go index 277a4078d9..907aed514c 100644 --- a/internal/util/upstream/oci.go +++ b/internal/util/remote/oci.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package upstream +package remote import ( "archive/tar" diff --git a/internal/util/upstream/upstream.go b/internal/util/remote/upstream.go similarity index 97% rename from internal/util/upstream/upstream.go rename to internal/util/remote/upstream.go index 18a689f8a8..a159bd8402 100644 --- a/internal/util/upstream/upstream.go +++ b/internal/util/remote/upstream.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package upstream +package remote import ( "context" @@ -48,7 +48,7 @@ type Fetcher interface { } func NewUpstream(kf *kptfilev1.KptFile) (Fetcher, error) { - const op errors.Op = "upstream.NewUpstream" + const op errors.Op = "remote.NewUpstream" if kf != nil && kf.Upstream != nil { switch kf.Upstream.Type { case kptfilev1.GitOrigin: @@ -81,7 +81,7 @@ func NewUpstream(kf *kptfilev1.KptFile) (Fetcher, error) { } func NewOrigin(kf *kptfilev1.KptFile) (Fetcher, error) { - const op errors.Op = "upstream.NewOrigin" + const op errors.Op = "remote.NewOrigin" if kf != nil && kf.Origin != nil { switch kf.Origin.Type { case kptfilev1.GitOrigin: diff --git a/internal/util/upstream/upstream_test.go b/internal/util/remote/upstream_test.go similarity index 99% rename from internal/util/upstream/upstream_test.go rename to internal/util/remote/upstream_test.go index ac2a37c16c..91f8484c00 100644 --- a/internal/util/upstream/upstream_test.go +++ b/internal/util/remote/upstream_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package upstream +package remote import ( "reflect" diff --git a/internal/util/update/update.go b/internal/util/update/update.go index e2d03d2f40..190006ffb8 100644 --- a/internal/util/update/update.go +++ b/internal/util/update/update.go @@ -29,8 +29,8 @@ import ( "github.com/GoogleContainerTools/kpt/internal/types" "github.com/GoogleContainerTools/kpt/internal/util/addmergecomment" "github.com/GoogleContainerTools/kpt/internal/util/pkgutil" + "github.com/GoogleContainerTools/kpt/internal/util/remote" "github.com/GoogleContainerTools/kpt/internal/util/stack" - "github.com/GoogleContainerTools/kpt/internal/util/upstream" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" "sigs.k8s.io/kustomize/kyaml/copyutil" @@ -115,7 +115,7 @@ func (u Command) Run(ctx context.Context) error { return errors.E(op, u.Pkg.UniquePath, err) } - rootUps, err := upstream.NewUpstream(rootKf) + rootUps, err := remote.NewUpstream(rootKf) if err != nil { return errors.E(op, u.Pkg.UniquePath, fmt.Errorf("package must have an upstream reference: %v", err)) } @@ -169,10 +169,10 @@ func (u Command) Run(ctx context.Context) error { return errors.E(op, p.UniquePath, err) } - if subUps, err := upstream.NewUpstream(subKf); err == nil { + if subUps, err := remote.NewUpstream(subKf); err == nil { // update subpackage kf ref/strategy if current pkg is a subpkg of root pkg or is root pkg // and if original root pkg ref matches the subpkg ref - if upstream.ShouldUpdateSubPkgRef(subUps, rootUps, originalRootKfRef) { + if remote.ShouldUpdateSubPkgRef(subUps, rootUps, originalRootKfRef) { if err := updateSubKf(subKf, subUps, u.Ref, u.Strategy); err != nil { return errors.E(op, subPkg.UniquePath, err) } @@ -194,7 +194,7 @@ func (u Command) Run(ctx context.Context) error { } // updateSubKf updates subpackage with given ref and update strategy -func updateSubKf(subKf *kptfilev1.KptFile, subUps upstream.Fetcher, ref string, strategy kptfilev1.UpdateStrategyType) error { +func updateSubKf(subKf *kptfilev1.KptFile, subUps remote.Fetcher, ref string, strategy kptfilev1.UpdateStrategyType) error { // check if explicit ref provided if ref != "" { if err := subUps.SetRef(ref); err != nil { @@ -245,7 +245,7 @@ func (u Command) updateRootPackage(ctx context.Context, p *pkg.Pkg) error { pr := printer.FromContextOrDie(ctx) pr.PrintPackage(p, !(p == u.Pkg)) - upstream, err := upstream.NewUpstream(kf) + upstream, err := remote.NewUpstream(kf) if err != nil { return errors.E(op, p.UniquePath, err) } From dfe2cd588145ddbabf93274cadf59480a68a558a Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Fri, 10 Dec 2021 18:41:54 +0000 Subject: [PATCH 20/26] Refactoring remote names * Rename Fether to Upstream * Split Upstream and Origin implementations --- internal/cmdpull/cmdpull.go | 4 +- internal/cmdpush/cmdpush.go | 4 +- internal/util/diff/diff.go | 2 +- internal/util/get/get.go | 2 +- internal/util/pull/pull.go | 12 ++--- internal/util/push/push.go | 18 +++---- internal/util/remote/git.go | 77 +++++++++++++++++---------- internal/util/remote/git_test.go | 6 +-- internal/util/remote/oci.go | 60 +++++++++++++-------- internal/util/remote/origin.go | 63 ++++++++++++++++++++++ internal/util/remote/upstream.go | 41 ++------------ internal/util/remote/upstream_test.go | 2 +- internal/util/update/update.go | 2 +- 13 files changed, 180 insertions(+), 113 deletions(-) create mode 100644 internal/util/remote/origin.go diff --git a/internal/cmdpull/cmdpull.go b/internal/cmdpull/cmdpull.go index 7d109fe5da..d30bc9a72f 100644 --- a/internal/cmdpull/cmdpull.go +++ b/internal/cmdpull/cmdpull.go @@ -80,13 +80,13 @@ func (r *Runner) parseArgs(args []string) (string, error) { t1, err1 := parse.GitParseArgs(r.ctx, args) if err1 == nil { - r.Pull.Upstream = remote.NewGitOrigin(&t1.Git) + r.Pull.Origin = remote.NewGitOrigin(&t1.Git) return t1.Destination, nil } t2, err2 := parse.OciParseArgs(r.ctx, args) if err2 == nil { - r.Pull.Upstream = remote.NewOciOrigin(&t2.Oci) + r.Pull.Origin = remote.NewOciOrigin(&t2.Oci) return t2.Destination, nil } diff --git a/internal/cmdpush/cmdpush.go b/internal/cmdpush/cmdpush.go index b801d3ae60..0311a5735f 100644 --- a/internal/cmdpush/cmdpush.go +++ b/internal/cmdpush/cmdpush.go @@ -118,13 +118,13 @@ func (r *Runner) parseArgs(args []string) error { if r.Origin != "" { t1, err1 := parse.GitParseArgs(r.ctx, []string {r.Origin, ""}) if err1 == nil { - r.Push.Remote = remote.NewGitOrigin(&t1.Git) + r.Push.Origin = remote.NewGitOrigin(&t1.Git) return nil } t2, err2 := parse.OciParseArgs(r.ctx, []string {r.Origin, ""}) if err2 == nil { - r.Push.Remote = remote.NewOciOrigin(&t2.Oci) + r.Push.Origin = remote.NewOciOrigin(&t2.Oci) return nil } diff --git a/internal/util/diff/diff.go b/internal/util/diff/diff.go index 6179060248..a24925a9db 100644 --- a/internal/util/diff/diff.go +++ b/internal/util/diff/diff.go @@ -111,7 +111,7 @@ type Command struct { PkgDiffer PkgDiffer // Contains information about the upstream package to fetch - Upstream remote.Fetcher + Upstream remote.Upstream } func (c *Command) Run(ctx context.Context) error { diff --git a/internal/util/get/get.go b/internal/util/get/get.go index 281fe55919..52ae5945f3 100644 --- a/internal/util/get/get.go +++ b/internal/util/get/get.go @@ -41,7 +41,7 @@ type Command struct { Git *kptfilev1.Git // Contains information about the upstraem package to fetch - Upstream remote.Fetcher + Upstream remote.Upstream // Destination is the output directory to clone the package to. Defaults to the name of the package -- // either the base repo name, or the base subdirectory name. diff --git a/internal/util/pull/pull.go b/internal/util/pull/pull.go index 71736b7c39..0eda3b7315 100644 --- a/internal/util/pull/pull.go +++ b/internal/util/pull/pull.go @@ -34,7 +34,7 @@ import ( // directory, and expands any remote subpackages. type Command struct { // Contains information about the upstraem package to fetch - Upstream remote.Fetcher + Origin remote.Origin // Destination is the output directory to clone the package to. Defaults to the name of the package -- // either the base repo name, or the base subdirectory name. @@ -59,10 +59,10 @@ func (c Command) Run(ctx context.Context) error { return errors.E(op, errors.IO, types.UniquePath(c.Destination), err) } - pr.Printf("Pulling origin %s\n", c.Upstream.OriginString()) + pr.Printf("Pulling origin %s\n", c.Origin.String()) // TODO(dejardin) need to understand abs path for kpt pkg pull from git - _, digest, err := c.Upstream.FetchOrigin(ctx, c.Destination) + _, digest, err := c.Origin.FetchOrigin(ctx, c.Destination) if err != nil { return errors.E(op, types.UniquePath(c.Destination), err) } @@ -74,7 +74,7 @@ func (c Command) Run(ctx context.Context) error { return errors.E(op, types.UniquePath(c.Destination), err) } - kf.Origin = c.Upstream.BuildOrigin(digest) + kf.Origin = c.Origin.BuildOrigin(digest) err = kptfileutil.WriteFile(c.Destination, kf) if err != nil { return cleanUpDirAndError(c.Destination, err) @@ -86,10 +86,10 @@ func (c Command) Run(ctx context.Context) error { // DefaultValues sets values to the default values if they were unspecified func (c *Command) DefaultValues() error { const op errors.Op = "pull.DefaultValues" - if c.Upstream == nil { + if c.Origin == nil { return errors.E(op, errors.MissingParam, fmt.Errorf("must specify git repo or image reference information")) } - if err := c.Upstream.Validate(); err != nil { + if err := c.Origin.Validate(); err != nil { return errors.E(op, err) } if !filepath.IsAbs(c.Destination) { diff --git a/internal/util/push/push.go b/internal/util/push/push.go index a915fd930f..23eeb27546 100644 --- a/internal/util/push/push.go +++ b/internal/util/push/push.go @@ -39,7 +39,7 @@ type Command struct { Ref string // Contains information about the package origin - Remote remote.Fetcher + Origin remote.Origin // Increment determines is the version portion of the reference should be increased Increment bool @@ -63,20 +63,20 @@ func (c Command) Run(ctx context.Context) error { return errors.E(op, c.Pkg.UniquePath, err) } - if c.Remote == nil { - c.Remote, err = remote.NewOrigin(kf) + if c.Origin == nil { + c.Origin, err = remote.NewOrigin(kf) if err != nil { return errors.E(op, c.Pkg.UniquePath, fmt.Errorf("package must have an origin reference: %v", err)) } } if c.Ref != "" { - c.Remote.SetOriginRef(c.Ref) + c.Origin.SetRef(c.Ref) } if c.Increment { // TODO(dejardin) move this logic into a util with test coverage - ref, err := c.Remote.OriginRef() + ref, err := c.Origin.Ref() if err != nil { return errors.E(op, c.Pkg.UniquePath, fmt.Errorf("missing origin version information: %v", err)) } @@ -114,7 +114,7 @@ func (c Command) Run(ctx context.Context) error { pr.Printf("Incrementing %s to %s\n",ref, buf.String()) - c.Remote.SetOriginRef(buf.String()) + c.Origin.SetRef(buf.String()) } // the kptfile pushed in the package does not have origin data @@ -123,16 +123,16 @@ func (c Command) Run(ctx context.Context) error { // correct origin will be added as part of the pull operation. kf.Origin = nil - pr.Printf("Pushing origin %s\n", c.Remote.OriginString()) + pr.Printf("Pushing origin %s\n", c.Origin.String()) - digest, err := c.Remote.PushOrigin(ctx, path, kf) + digest, err := c.Origin.PushOrigin(ctx, path, kf) if err != nil { return errors.E(op, c.Pkg.UniquePath, err) } pr.Printf("Pushed digest %s\n", digest) - kf.Origin = c.Remote.BuildOrigin(digest) + kf.Origin = c.Origin.BuildOrigin(digest) err = kptfileutil.WriteFile(path, kf) if err != nil { return errors.E(op, c.Pkg.UniquePath, err) diff --git a/internal/util/remote/git.go b/internal/util/remote/git.go index 0cbe36465b..aa39baa0ec 100644 --- a/internal/util/remote/git.go +++ b/internal/util/remote/git.go @@ -31,28 +31,30 @@ import ( "github.com/GoogleContainerTools/kpt/internal/util/git" "github.com/GoogleContainerTools/kpt/internal/util/pkgutil" kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" - v1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" "github.com/otiai10/copy" ) type gitUpstream struct { - git *v1.Git - gitLock *v1.GitLock - origin *v1.GitLock + git *kptfilev1.Git + gitLock *kptfilev1.GitLock } -var _ Fetcher = &gitUpstream{} +type gitOrigin struct { + origin *kptfilev1.GitLock +} + +var _ Upstream = &gitUpstream{} -func NewGitUpstream(git *v1.Git) Fetcher { +func NewGitUpstream(git *kptfilev1.Git) Upstream { return &gitUpstream{ git: git, } } -func NewGitOrigin(git *v1.Git) Fetcher { - return &gitUpstream{ - origin: &v1.GitLock{ +func NewGitOrigin(git *kptfilev1.Git) Origin { + return &gitOrigin{ + origin: &kptfilev1.GitLock{ Repo: git.Repo, Directory: git.Directory, Ref: git.Ref, @@ -68,14 +70,16 @@ func (u *gitUpstream) LockedString() string { return fmt.Sprintf("%s@%s", u.gitLock.Repo, u.gitLock.Ref) } - -func (u *gitUpstream) OriginString() string { +func (u *gitOrigin) String() string { return fmt.Sprintf("%s@%s", u.origin.Repo, u.origin.Ref) } +func (u *gitOrigin) LockedString() string { + return fmt.Sprintf("%s@%s", u.origin.Repo, u.origin.Ref) +} func (u *gitUpstream) Validate() error { - const op errors.Op = "upstream.Validate" + const op errors.Op = "remote.Validate" g := u.git if g != nil { if len(g.Repo) == 0 { @@ -91,36 +95,53 @@ func (u *gitUpstream) Validate() error { return nil } -func (u *gitUpstream) BuildUpstream() *v1.Upstream { +func (u *gitOrigin) Validate() error { + const op errors.Op = "remote.Validate" + g := u.origin + if g != nil { + if len(g.Repo) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify repo")) + } + if len(g.Ref) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify ref")) + } + if len(g.Directory) == 0 { + return errors.E(op, errors.MissingParam, fmt.Errorf("must specify directory")) + } + } + return nil +} + +func (u *gitUpstream) BuildUpstream() *kptfilev1.Upstream { repoDir := u.git.Directory if !strings.HasSuffix(repoDir, "file://") { repoDir = filepath.Join(path.Split(repoDir)) } u.git.Directory = repoDir - return &v1.Upstream{ - Type: v1.GitOrigin, + return &kptfilev1.Upstream{ + Type: kptfilev1.GitOrigin, Git: u.git, } } -func (u *gitUpstream) BuildUpstreamLock(digest string) *v1.UpstreamLock { - u.gitLock = &v1.GitLock{ +func (u *gitUpstream) BuildUpstreamLock(digest string) *kptfilev1.UpstreamLock { + u.gitLock = &kptfilev1.GitLock{ Repo: u.git.Repo, Directory: u.git.Directory, Ref: u.git.Ref, Commit: digest, } - return &v1.UpstreamLock{ - Type: v1.GitOrigin, + return &kptfilev1.UpstreamLock{ + Type: kptfilev1.GitOrigin, Git: u.gitLock, } } -func (u *gitUpstream) BuildOrigin(digest string) *v1.Origin { - return &v1.Origin{ - Type: v1.GitOrigin, - Git: &v1.GitLock{ +func (u *gitOrigin) BuildOrigin(digest string) *kptfilev1.Origin { + return &kptfilev1.Origin{ + Type: kptfilev1.GitOrigin, + Git: &kptfilev1.GitLock{ Repo: u.origin.Repo, Directory: u.origin.Directory, Ref: u.origin.Ref, @@ -155,7 +176,7 @@ func (u *gitUpstream) FetchUpstreamLock(ctx context.Context, dest string) (strin return path.Join(repoSpec.Dir, repoSpec.Path), nil } -func (u *gitUpstream) FetchOrigin(ctx context.Context, dest string) (string, string, error) { +func (u *gitOrigin) FetchOrigin(ctx context.Context, dest string) (string, string, error) { repoSpec := &git.RepoSpec{ OrgRepo: u.origin.Repo, Path: u.origin.Directory, @@ -181,7 +202,7 @@ func (u *gitUpstream) CloneUpstream(ctx context.Context, dest string) error { return cloneAndCopy(ctx, repoSpec, dest) } -func (u *gitUpstream) PushOrigin(ctx context.Context, dest string, kptfile *kptfilev1.KptFile) (digest string, err error) { +func (u *gitOrigin) PushOrigin(ctx context.Context, dest string, kptfile *kptfilev1.KptFile) (digest string, err error) { return "", fmt.Errorf("git push not implemented") } @@ -194,18 +215,18 @@ func (u *gitUpstream) SetRef(ref string) error { return nil } -func (u *gitUpstream) OriginRef() (string, error) { +func (u *gitOrigin) Ref() (string, error) { return u.origin.Ref, nil } -func (u *gitUpstream) SetOriginRef(ref string) error { +func (u *gitOrigin) SetRef(ref string) error { u.origin.Ref = ref return nil } // shouldUpdateSubPkgRef checks if subpkg ref should be updated. // This is true if pkg has the same upstream repo, upstream directory is within or equal to root pkg directory and original root pkg ref matches the subpkg ref. -func (u *gitUpstream) ShouldUpdateSubPkgRef(rootUpstream Fetcher, originalRootKfRef string) bool { +func (u *gitUpstream) ShouldUpdateSubPkgRef(rootUpstream Upstream, originalRootKfRef string) bool { root, ok := rootUpstream.(*gitUpstream) return ok && u.git.Repo == root.git.Repo && diff --git a/internal/util/remote/git_test.go b/internal/util/remote/git_test.go index 96dc730c74..4a5cd6970d 100644 --- a/internal/util/remote/git_test.go +++ b/internal/util/remote/git_test.go @@ -22,21 +22,21 @@ import ( ) //nolint:scopelint -func TestNewGitFetcher(t *testing.T) { +func TestNewGitUpstream(t *testing.T) { type args struct { git *v1.Git } tests := []struct { name string args args - want Fetcher + want Upstream }{ // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := NewGitUpstream(tt.args.git); !reflect.DeepEqual(got, tt.want) { - t.Errorf("NewGitFetcher() = %v, want %v", got, tt.want) + t.Errorf("NewGitUpstream() = %v, want %v", got, tt.want) } }) } diff --git a/internal/util/remote/oci.go b/internal/util/remote/oci.go index 907aed514c..68fe30ab29 100644 --- a/internal/util/remote/oci.go +++ b/internal/util/remote/oci.go @@ -44,19 +44,24 @@ import ( type ociUpstream struct { oci *kptfilev1.Oci ociLock *kptfilev1.OciLock +} + +var _ Upstream = &ociUpstream{} + +type ociOrigin struct { origin *kptfilev1.OciLock } -var _ Fetcher = &ociUpstream{} +var _ Origin = &ociOrigin{} -func NewOciUpstream(oci *kptfilev1.Oci) Fetcher { +func NewOciUpstream(oci *kptfilev1.Oci) Upstream { return &ociUpstream{ oci: oci, } } -func NewOciOrigin(oci *kptfilev1.Oci) Fetcher { - return &ociUpstream{ +func NewOciOrigin(oci *kptfilev1.Oci) Origin { + return &ociOrigin{ origin: &kptfilev1.OciLock{ Image: oci.Image, }, @@ -71,10 +76,14 @@ func (u *ociUpstream) LockedString() string { return u.ociLock.Image } -func (u *ociUpstream) OriginString() string { +func (u *ociOrigin) String() string { return u.origin.Image } +func (u *ociOrigin) LockedString() string { + return u.origin.Digest +} + func (u *ociUpstream) BuildUpstream() *kptfilev1.Upstream { return &kptfilev1.Upstream{ Type: kptfilev1.OciOrigin, @@ -91,7 +100,7 @@ func (u *ociUpstream) BuildUpstreamLock(digest string) *kptfilev1.UpstreamLock { } } -func (u *ociUpstream) BuildOrigin(digest string) *kptfilev1.Origin { +func (u *ociOrigin) BuildOrigin(digest string) *kptfilev1.Origin { return &kptfilev1.Origin{ Type: kptfilev1.OciOrigin, Oci: &kptfilev1.OciLock{ @@ -102,12 +111,17 @@ func (u *ociUpstream) BuildOrigin(digest string) *kptfilev1.Origin { } func (u *ociUpstream) Validate() error { - const op errors.Op = "upstream.Validate" + const op errors.Op = "remote.Validate" if u.oci != nil { if len(u.oci.Image) == 0 { return errors.E(op, errors.MissingParam, fmt.Errorf("must specify image")) } } + return nil +} + +func (u *ociOrigin) Validate() error { + const op errors.Op = "remote.Validate" if u.origin != nil { if len(u.origin.Image) == 0 { return errors.E(op, errors.MissingParam, fmt.Errorf("must specify image")) @@ -117,7 +131,7 @@ func (u *ociUpstream) Validate() error { } func (u *ociUpstream) FetchUpstream(ctx context.Context, dest string) (string, string, error) { - const op errors.Op = "upstream.FetchUpstream" + const op errors.Op = "remote.FetchUpstream" imageDigest, err := pullAndExtract(u.oci.Image, dest, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) if err != nil { return "", "", errors.E(op, errors.OCI, types.UniquePath(dest), err) @@ -126,7 +140,7 @@ func (u *ociUpstream) FetchUpstream(ctx context.Context, dest string) (string, s } func (u *ociUpstream) FetchUpstreamLock(ctx context.Context, dest string) (string, error) { - const op errors.Op = "upstream.FetchUpstreamLock" + const op errors.Op = "remote.FetchUpstreamLock" _, err := pullAndExtract(u.ociLock.Image, dest, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) if err != nil { return "", errors.E(op, errors.OCI, types.UniquePath(dest), err) @@ -134,8 +148,8 @@ func (u *ociUpstream) FetchUpstreamLock(ctx context.Context, dest string) (strin return dest, nil } -func (u *ociUpstream) FetchOrigin(ctx context.Context, dest string) (string, string, error) { - const op errors.Op = "upstream.FetchOrigin" +func (u *ociOrigin) FetchOrigin(ctx context.Context, dest string) (string, string, error) { + const op errors.Op = "remote.FetchOrigin" imageDigest, err := pullAndExtract(u.origin.Image, dest, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) if err != nil { return "", "", errors.E(op, errors.OCI, types.UniquePath(dest), err) @@ -144,7 +158,7 @@ func (u *ociUpstream) FetchOrigin(ctx context.Context, dest string) (string, str } func (u *ociUpstream) CloneUpstream(ctx context.Context, dest string) error { - const op errors.Op = "upstream.FetchUpstreamClone" + const op errors.Op = "remote.FetchUpstreamClone" // pr := printer.FromContextOrDie(ctx) // We need to create a temp directory where we can copy the content of the repo. @@ -177,8 +191,8 @@ func (u *ociUpstream) CloneUpstream(ctx context.Context, dest string) error { return nil } -func (u *ociUpstream) PushOrigin(ctx context.Context, source string, kptfile *kptfilev1.KptFile) (digest string, err error) { - const op errors.Op = "upstream.PushOrigin" +func (u *ociOrigin) PushOrigin(ctx context.Context, source string, kptfile *kptfilev1.KptFile) (digest string, err error) { + const op errors.Op = "remote.PushOrigin" imageDigest, err := archiveAndPush(u.origin.Image, source, kptfile, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) if err != nil { @@ -190,7 +204,7 @@ func (u *ociUpstream) PushOrigin(ctx context.Context, source string, kptfile *kp func (u *ociUpstream) Ref() (string, error) { - const op errors.Op = "upstream.Ref" + const op errors.Op = "remote.Ref" r, err := name.ParseReference(u.oci.Image) if err != nil { return "", errors.E(op, errors.Internal, fmt.Errorf("error parsing reference: %s %w", u.oci.Image, err)) @@ -199,7 +213,7 @@ func (u *ociUpstream) Ref() (string, error) { } func (u *ociUpstream) SetRef(ref string) error { - const op errors.Op = "upstream.SetRef" + const op errors.Op = "remote.SetRef" r, err := name.ParseReference(u.oci.Image) if err != nil { return errors.E(op, errors.Internal, fmt.Errorf("error parsing reference: %s %w", u.oci.Image, err)) @@ -214,8 +228,8 @@ func (u *ociUpstream) SetRef(ref string) error { return nil } -func (u *ociUpstream) OriginRef() (string, error) { - const op errors.Op = "upstream.OriginRef" +func (u *ociOrigin) Ref() (string, error) { + const op errors.Op = "remote.Ref" r, err := name.ParseReference(u.origin.Image) if err != nil { return "", errors.E(op, errors.Internal, fmt.Errorf("error parsing reference: %s %w", u.origin.Image, err)) @@ -223,8 +237,8 @@ func (u *ociUpstream) OriginRef() (string, error) { return r.Identifier(), nil } -func (u *ociUpstream) SetOriginRef(ref string) error { - const op errors.Op = "upstream.SetOriginRef" +func (u *ociOrigin) SetRef(ref string) error { + const op errors.Op = "remote.SetRef" r, err := name.ParseReference(u.origin.Image) if err != nil { return errors.E(op, errors.Internal, fmt.Errorf("error parsing reference: %s %w", u.origin.Image, err)) @@ -241,7 +255,7 @@ func (u *ociUpstream) SetOriginRef(ref string) error { // shouldUpdateSubPkgRef checks if subpkg ref should be updated. // This is true if pkg has the same upstream repo, upstream directory is within or equal to root pkg directory and original root pkg ref matches the subpkg ref. -func (u *ociUpstream) ShouldUpdateSubPkgRef(rootUpstream Fetcher, originalRootKfRef string) bool { +func (u *ociUpstream) ShouldUpdateSubPkgRef(rootUpstream Upstream, originalRootKfRef string) bool { root, ok := rootUpstream.(*ociUpstream) if !ok { return false @@ -262,7 +276,7 @@ func (u *ociUpstream) ShouldUpdateSubPkgRef(rootUpstream Fetcher, originalRootKf // extract (untar) image files to target directory. The desired version or digest must // be in the imageName, and the resolved image sha256 digest is returned. func pullAndExtract(imageName string, dir string, options ...remote.Option) (name.Reference, error) { - const op errors.Op = "upstream.pullAndExtract" + const op errors.Op = "remote.pullAndExtract" ref, err := name.ParseReference(imageName) if err != nil { @@ -334,7 +348,7 @@ func pullAndExtract(imageName string, dir string, options ...remote.Option) (nam // extract (untar) image files to target directory. The desired version or digest must // be in the imageName, and the resolved image sha256 digest is returned. func archiveAndPush(imageName string, dir string, kptfile *kptfilev1.KptFile, options ...remote.Option) (name.Reference, error) { - const op errors.Op = "upstream.archiveAndPush" + const op errors.Op = "remote.archiveAndPush" ref, err := name.ParseReference(imageName) if err != nil { diff --git a/internal/util/remote/origin.go b/internal/util/remote/origin.go new file mode 100644 index 0000000000..23d95e725f --- /dev/null +++ b/internal/util/remote/origin.go @@ -0,0 +1,63 @@ +// Copyright 2021 Google LLC +// +// 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 remote + +import ( + "context" + "fmt" + + "github.com/GoogleContainerTools/kpt/internal/errors" + kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" +) + +type Origin interface { + fmt.Stringer + LockedString() string + + Validate() error + + BuildOrigin(digest string) *kptfilev1.Origin + + FetchOrigin(ctx context.Context, dest string) (absPath string, digest string, err error) + PushOrigin(ctx context.Context, dest string, kptfile *kptfilev1.KptFile) (digest string, err error) + + Ref() (string, error) + SetRef(ref string) error +} + +func NewOrigin(kf *kptfilev1.KptFile) (Origin, error) { + const op errors.Op = "remote.NewOrigin" + if kf != nil && kf.Origin != nil { + switch kf.Origin.Type { + case kptfilev1.GitOrigin: + if kf.Upstream.Git == nil { + return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile origin must have git information")) + } + u := &gitOrigin{ + origin: kf.Origin.Git, + } + return u, nil + case kptfilev1.OciOrigin: + if kf.Origin.Oci == nil { + return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile origin must have oci information")) + } + u := &ociOrigin{ + origin: kf.Origin.Oci, + } + return u, nil + } + } + return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile origin type must be one of: %s,%s", kptfilev1.GitOrigin, kptfilev1.OciOrigin)) +} diff --git a/internal/util/remote/upstream.go b/internal/util/remote/upstream.go index a159bd8402..e73a1d9a38 100644 --- a/internal/util/remote/upstream.go +++ b/internal/util/remote/upstream.go @@ -22,32 +22,26 @@ import ( kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" ) -type Fetcher interface { +type Upstream interface { fmt.Stringer LockedString() string - OriginString() string Validate() error + BuildUpstream() *kptfilev1.Upstream BuildUpstreamLock(digest string) *kptfilev1.UpstreamLock - BuildOrigin(digest string) *kptfilev1.Origin FetchUpstream(ctx context.Context, dest string) (absPath string, digest string, err error) FetchUpstreamLock(ctx context.Context, dest string) (absPath string, err error) - FetchOrigin(ctx context.Context, dest string) (absPath string, digest string, err error) - PushOrigin(ctx context.Context, dest string, kptfile *kptfilev1.KptFile) (digest string, err error) CloneUpstream(ctx context.Context, dest string) error Ref() (string, error) SetRef(ref string) error - ShouldUpdateSubPkgRef(rootUpstream Fetcher, originalRootRef string) bool - - OriginRef() (string, error) - SetOriginRef(ref string) error + ShouldUpdateSubPkgRef(rootUpstream Upstream, originalRootRef string) bool } -func NewUpstream(kf *kptfilev1.KptFile) (Fetcher, error) { +func NewUpstream(kf *kptfilev1.KptFile) (Upstream, error) { const op errors.Op = "remote.NewUpstream" if kf != nil && kf.Upstream != nil { switch kf.Upstream.Type { @@ -80,31 +74,6 @@ func NewUpstream(kf *kptfilev1.KptFile) (Fetcher, error) { return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile upstream type must be one of: %s,%s", kptfilev1.GitOrigin, kptfilev1.OciOrigin)) } -func NewOrigin(kf *kptfilev1.KptFile) (Fetcher, error) { - const op errors.Op = "remote.NewOrigin" - if kf != nil && kf.Origin != nil { - switch kf.Origin.Type { - case kptfilev1.GitOrigin: - if kf.Upstream.Git == nil { - return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile origin must have git information")) - } - u := &gitUpstream{ - origin: kf.Origin.Git, - } - return u, nil - case kptfilev1.OciOrigin: - if kf.Origin.Oci == nil { - return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile origin must have oci information")) - } - u := &ociUpstream{ - origin: kf.Origin.Oci, - } - return u, nil - } - } - return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile origin type must be one of: %s,%s", kptfilev1.GitOrigin, kptfilev1.OciOrigin)) -} - -func ShouldUpdateSubPkgRef(subUpstream Fetcher, rootUpstream Fetcher, originalRootRef string) bool { +func ShouldUpdateSubPkgRef(subUpstream Upstream, rootUpstream Upstream, originalRootRef string) bool { return subUpstream.ShouldUpdateSubPkgRef(rootUpstream, originalRootRef) } diff --git a/internal/util/remote/upstream_test.go b/internal/util/remote/upstream_test.go index 91f8484c00..8a7e8183e3 100644 --- a/internal/util/remote/upstream_test.go +++ b/internal/util/remote/upstream_test.go @@ -29,7 +29,7 @@ func TestNewUpstream(t *testing.T) { tests := []struct { name string args args - want Fetcher + want Upstream wantErr bool }{ { diff --git a/internal/util/update/update.go b/internal/util/update/update.go index 190006ffb8..96c860ed5e 100644 --- a/internal/util/update/update.go +++ b/internal/util/update/update.go @@ -194,7 +194,7 @@ func (u Command) Run(ctx context.Context) error { } // updateSubKf updates subpackage with given ref and update strategy -func updateSubKf(subKf *kptfilev1.KptFile, subUps remote.Fetcher, ref string, strategy kptfilev1.UpdateStrategyType) error { +func updateSubKf(subKf *kptfilev1.KptFile, subUps remote.Upstream, ref string, strategy kptfilev1.UpdateStrategyType) error { // check if explicit ref provided if ref != "" { if err := subUps.SetRef(ref); err != nil { From de2e74fc309b96b9da367de90003d553ba21a2f9 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Fri, 10 Dec 2021 18:52:35 +0000 Subject: [PATCH 21/26] Removing redundant Origin suffix from names --- internal/util/pull/pull.go | 4 ++-- internal/util/push/push.go | 4 ++-- internal/util/remote/git.go | 32 +++++++++++++-------------- internal/util/remote/oci.go | 40 +++++++++++++++++----------------- internal/util/remote/origin.go | 10 ++++----- 5 files changed, 45 insertions(+), 45 deletions(-) diff --git a/internal/util/pull/pull.go b/internal/util/pull/pull.go index 0eda3b7315..2770202312 100644 --- a/internal/util/pull/pull.go +++ b/internal/util/pull/pull.go @@ -62,7 +62,7 @@ func (c Command) Run(ctx context.Context) error { pr.Printf("Pulling origin %s\n", c.Origin.String()) // TODO(dejardin) need to understand abs path for kpt pkg pull from git - _, digest, err := c.Origin.FetchOrigin(ctx, c.Destination) + _, digest, err := c.Origin.Fetch(ctx, c.Destination) if err != nil { return errors.E(op, types.UniquePath(c.Destination), err) } @@ -74,7 +74,7 @@ func (c Command) Run(ctx context.Context) error { return errors.E(op, types.UniquePath(c.Destination), err) } - kf.Origin = c.Origin.BuildOrigin(digest) + kf.Origin = c.Origin.Build(digest) err = kptfileutil.WriteFile(c.Destination, kf) if err != nil { return cleanUpDirAndError(c.Destination, err) diff --git a/internal/util/push/push.go b/internal/util/push/push.go index 23eeb27546..3ef5c203bf 100644 --- a/internal/util/push/push.go +++ b/internal/util/push/push.go @@ -125,14 +125,14 @@ func (c Command) Run(ctx context.Context) error { pr.Printf("Pushing origin %s\n", c.Origin.String()) - digest, err := c.Origin.PushOrigin(ctx, path, kf) + digest, err := c.Origin.Push(ctx, path, kf) if err != nil { return errors.E(op, c.Pkg.UniquePath, err) } pr.Printf("Pushed digest %s\n", digest) - kf.Origin = c.Origin.BuildOrigin(digest) + kf.Origin = c.Origin.Build(digest) err = kptfileutil.WriteFile(path, kf) if err != nil { return errors.E(op, c.Pkg.UniquePath, err) diff --git a/internal/util/remote/git.go b/internal/util/remote/git.go index aa39baa0ec..724e0b08d4 100644 --- a/internal/util/remote/git.go +++ b/internal/util/remote/git.go @@ -41,7 +41,7 @@ type gitUpstream struct { } type gitOrigin struct { - origin *kptfilev1.GitLock + git *kptfilev1.GitLock } var _ Upstream = &gitUpstream{} @@ -54,7 +54,7 @@ func NewGitUpstream(git *kptfilev1.Git) Upstream { func NewGitOrigin(git *kptfilev1.Git) Origin { return &gitOrigin{ - origin: &kptfilev1.GitLock{ + git: &kptfilev1.GitLock{ Repo: git.Repo, Directory: git.Directory, Ref: git.Ref, @@ -71,11 +71,11 @@ func (u *gitUpstream) LockedString() string { } func (u *gitOrigin) String() string { - return fmt.Sprintf("%s@%s", u.origin.Repo, u.origin.Ref) + return fmt.Sprintf("%s@%s", u.git.Repo, u.git.Ref) } func (u *gitOrigin) LockedString() string { - return fmt.Sprintf("%s@%s", u.origin.Repo, u.origin.Ref) + return fmt.Sprintf("%s@%s", u.git.Repo, u.git.Ref) } func (u *gitUpstream) Validate() error { @@ -97,7 +97,7 @@ func (u *gitUpstream) Validate() error { func (u *gitOrigin) Validate() error { const op errors.Op = "remote.Validate" - g := u.origin + g := u.git if g != nil { if len(g.Repo) == 0 { return errors.E(op, errors.MissingParam, fmt.Errorf("must specify repo")) @@ -138,13 +138,13 @@ func (u *gitUpstream) BuildUpstreamLock(digest string) *kptfilev1.UpstreamLock { } } -func (u *gitOrigin) BuildOrigin(digest string) *kptfilev1.Origin { +func (u *gitOrigin) Build(digest string) *kptfilev1.Origin { return &kptfilev1.Origin{ Type: kptfilev1.GitOrigin, Git: &kptfilev1.GitLock{ - Repo: u.origin.Repo, - Directory: u.origin.Directory, - Ref: u.origin.Ref, + Repo: u.git.Repo, + Directory: u.git.Directory, + Ref: u.git.Ref, Commit: digest, }, } @@ -176,11 +176,11 @@ func (u *gitUpstream) FetchUpstreamLock(ctx context.Context, dest string) (strin return path.Join(repoSpec.Dir, repoSpec.Path), nil } -func (u *gitOrigin) FetchOrigin(ctx context.Context, dest string) (string, string, error) { +func (u *gitOrigin) Fetch(ctx context.Context, dest string) (string, string, error) { repoSpec := &git.RepoSpec{ - OrgRepo: u.origin.Repo, - Path: u.origin.Directory, - Ref: u.origin.Ref, + OrgRepo: u.git.Repo, + Path: u.git.Directory, + Ref: u.git.Ref, } if err := ClonerUsingGitExec(ctx, repoSpec); err != nil { return "", "", err @@ -202,7 +202,7 @@ func (u *gitUpstream) CloneUpstream(ctx context.Context, dest string) error { return cloneAndCopy(ctx, repoSpec, dest) } -func (u *gitOrigin) PushOrigin(ctx context.Context, dest string, kptfile *kptfilev1.KptFile) (digest string, err error) { +func (u *gitOrigin) Push(ctx context.Context, dest string, kptfile *kptfilev1.KptFile) (digest string, err error) { return "", fmt.Errorf("git push not implemented") } @@ -216,11 +216,11 @@ func (u *gitUpstream) SetRef(ref string) error { } func (u *gitOrigin) Ref() (string, error) { - return u.origin.Ref, nil + return u.git.Ref, nil } func (u *gitOrigin) SetRef(ref string) error { - u.origin.Ref = ref + u.git.Ref = ref return nil } diff --git a/internal/util/remote/oci.go b/internal/util/remote/oci.go index 68fe30ab29..0e4a445292 100644 --- a/internal/util/remote/oci.go +++ b/internal/util/remote/oci.go @@ -49,7 +49,7 @@ type ociUpstream struct { var _ Upstream = &ociUpstream{} type ociOrigin struct { - origin *kptfilev1.OciLock + oci *kptfilev1.OciLock } var _ Origin = &ociOrigin{} @@ -62,7 +62,7 @@ func NewOciUpstream(oci *kptfilev1.Oci) Upstream { func NewOciOrigin(oci *kptfilev1.Oci) Origin { return &ociOrigin{ - origin: &kptfilev1.OciLock{ + oci: &kptfilev1.OciLock{ Image: oci.Image, }, } @@ -77,11 +77,11 @@ func (u *ociUpstream) LockedString() string { } func (u *ociOrigin) String() string { - return u.origin.Image + return u.oci.Image } func (u *ociOrigin) LockedString() string { - return u.origin.Digest + return u.oci.Digest } func (u *ociUpstream) BuildUpstream() *kptfilev1.Upstream { @@ -100,11 +100,11 @@ func (u *ociUpstream) BuildUpstreamLock(digest string) *kptfilev1.UpstreamLock { } } -func (u *ociOrigin) BuildOrigin(digest string) *kptfilev1.Origin { +func (u *ociOrigin) Build(digest string) *kptfilev1.Origin { return &kptfilev1.Origin{ Type: kptfilev1.OciOrigin, Oci: &kptfilev1.OciLock{ - Image: u.origin.Image, + Image: u.oci.Image, Digest: digest, }, } @@ -122,8 +122,8 @@ func (u *ociUpstream) Validate() error { func (u *ociOrigin) Validate() error { const op errors.Op = "remote.Validate" - if u.origin != nil { - if len(u.origin.Image) == 0 { + if u.oci != nil { + if len(u.oci.Image) == 0 { return errors.E(op, errors.MissingParam, fmt.Errorf("must specify image")) } } @@ -148,9 +148,9 @@ func (u *ociUpstream) FetchUpstreamLock(ctx context.Context, dest string) (strin return dest, nil } -func (u *ociOrigin) FetchOrigin(ctx context.Context, dest string) (string, string, error) { - const op errors.Op = "remote.FetchOrigin" - imageDigest, err := pullAndExtract(u.origin.Image, dest, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) +func (u *ociOrigin) Fetch(ctx context.Context, dest string) (string, string, error) { + const op errors.Op = "remote.Fetch" + imageDigest, err := pullAndExtract(u.oci.Image, dest, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) if err != nil { return "", "", errors.E(op, errors.OCI, types.UniquePath(dest), err) } @@ -191,10 +191,10 @@ func (u *ociUpstream) CloneUpstream(ctx context.Context, dest string) error { return nil } -func (u *ociOrigin) PushOrigin(ctx context.Context, source string, kptfile *kptfilev1.KptFile) (digest string, err error) { - const op errors.Op = "remote.PushOrigin" +func (u *ociOrigin) Push(ctx context.Context, source string, kptfile *kptfilev1.KptFile) (digest string, err error) { + const op errors.Op = "remote.Push" - imageDigest, err := archiveAndPush(u.origin.Image, source, kptfile, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) + imageDigest, err := archiveAndPush(u.oci.Image, source, kptfile, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) if err != nil { return "",errors.E(op, errors.OCI, types.UniquePath(source), err) } @@ -230,24 +230,24 @@ func (u *ociUpstream) SetRef(ref string) error { func (u *ociOrigin) Ref() (string, error) { const op errors.Op = "remote.Ref" - r, err := name.ParseReference(u.origin.Image) + r, err := name.ParseReference(u.oci.Image) if err != nil { - return "", errors.E(op, errors.Internal, fmt.Errorf("error parsing reference: %s %w", u.origin.Image, err)) + return "", errors.E(op, errors.Internal, fmt.Errorf("error parsing reference: %s %w", u.oci.Image, err)) } return r.Identifier(), nil } func (u *ociOrigin) SetRef(ref string) error { const op errors.Op = "remote.SetRef" - r, err := name.ParseReference(u.origin.Image) + r, err := name.ParseReference(u.oci.Image) if err != nil { - return errors.E(op, errors.Internal, fmt.Errorf("error parsing reference: %s %w", u.origin.Image, err)) + return errors.E(op, errors.Internal, fmt.Errorf("error parsing reference: %s %w", u.oci.Image, err)) } if len(strings.SplitN(ref, "sha256:", 2)[0]) == 0 { - u.origin.Image = r.Context().Digest(ref).Name() + u.oci.Image = r.Context().Digest(ref).Name() } else { - u.origin.Image = r.Context().Tag(ref).Name() + u.oci.Image = r.Context().Tag(ref).Name() } return nil diff --git a/internal/util/remote/origin.go b/internal/util/remote/origin.go index 23d95e725f..9578fdaeec 100644 --- a/internal/util/remote/origin.go +++ b/internal/util/remote/origin.go @@ -28,10 +28,10 @@ type Origin interface { Validate() error - BuildOrigin(digest string) *kptfilev1.Origin + Build(digest string) *kptfilev1.Origin - FetchOrigin(ctx context.Context, dest string) (absPath string, digest string, err error) - PushOrigin(ctx context.Context, dest string, kptfile *kptfilev1.KptFile) (digest string, err error) + Fetch(ctx context.Context, dest string) (absPath string, digest string, err error) + Push(ctx context.Context, dest string, kptfile *kptfilev1.KptFile) (digest string, err error) Ref() (string, error) SetRef(ref string) error @@ -46,7 +46,7 @@ func NewOrigin(kf *kptfilev1.KptFile) (Origin, error) { return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile origin must have git information")) } u := &gitOrigin{ - origin: kf.Origin.Git, + git: kf.Origin.Git, } return u, nil case kptfilev1.OciOrigin: @@ -54,7 +54,7 @@ func NewOrigin(kf *kptfilev1.KptFile) (Origin, error) { return nil, errors.E(op, errors.MissingParam, fmt.Errorf("kptfile origin must have oci information")) } u := &ociOrigin{ - origin: kf.Origin.Oci, + oci: kf.Origin.Oci, } return u, nil } From 107e2ff0fc15b6d0d319c46400ba8ca21126d6d4 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Fri, 10 Dec 2021 18:54:45 +0000 Subject: [PATCH 22/26] Adding compile-time interface assertion --- internal/util/remote/git.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/util/remote/git.go b/internal/util/remote/git.go index 724e0b08d4..8b93c4d677 100644 --- a/internal/util/remote/git.go +++ b/internal/util/remote/git.go @@ -40,11 +40,13 @@ type gitUpstream struct { gitLock *kptfilev1.GitLock } +var _ Upstream = &gitUpstream{} + type gitOrigin struct { git *kptfilev1.GitLock } -var _ Upstream = &gitUpstream{} +var _ Origin = &gitOrigin{} func NewGitUpstream(git *kptfilev1.Git) Upstream { return &gitUpstream{ From 43013f2ab442c70c1e2a26a734ff0aa029863d96 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Fri, 10 Dec 2021 18:56:06 +0000 Subject: [PATCH 23/26] go fix formatting --- internal/cmdpull/cmdpull.go | 34 ++++++++++++++------- internal/cmdpush/cmdpush.go | 44 ++++++++++++++++++---------- internal/fnruntime/container_test.go | 1 + internal/util/diff/diff_test.go | 1 + internal/util/push/push.go | 14 ++++----- internal/util/remote/git.go | 4 +-- internal/util/remote/oci.go | 7 ++--- 7 files changed, 67 insertions(+), 38 deletions(-) diff --git a/internal/cmdpull/cmdpull.go b/internal/cmdpull/cmdpull.go index d30bc9a72f..50c27e695b 100644 --- a/internal/cmdpull/cmdpull.go +++ b/internal/cmdpull/cmdpull.go @@ -1,3 +1,17 @@ +// Copyright 2021 Google LLC +// +// 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 cmdpull import ( @@ -23,13 +37,13 @@ func NewRunner(ctx context.Context, parent string) *Runner { ctx: ctx, } c := &cobra.Command{ - Use: "pull {REPO_URI[.git]/PKG_PATH[@VERSION]|IMAGE:TAG} [LOCAL_DEST_DIRECTORY]", - Args: cobra.MinimumNArgs(1), - Short: docs.GetShort, - Long: docs.GetShort + "\n" + docs.GetLong, - Example: docs.GetExamples, - RunE: r.runE, - PreRunE: r.preRunE, + Use: "pull {REPO_URI[.git]/PKG_PATH[@VERSION]|IMAGE:TAG} [LOCAL_DEST_DIRECTORY]", + Args: cobra.MinimumNArgs(1), + Short: docs.GetShort, + Long: docs.GetShort + "\n" + docs.GetLong, + Example: docs.GetExamples, + RunE: r.runE, + PreRunE: r.preRunE, } cmdutil.FixDocs("kpt", parent, c) r.Command = c @@ -42,9 +56,9 @@ func NewCommand(ctx context.Context, parent string) *cobra.Command { // Runner contains the run function type Runner struct { - ctx context.Context - Pull pull.Command - Command *cobra.Command + ctx context.Context + Pull pull.Command + Command *cobra.Command } func (r *Runner) preRunE(_ *cobra.Command, args []string) error { diff --git a/internal/cmdpush/cmdpush.go b/internal/cmdpush/cmdpush.go index 0311a5735f..e065c8cacd 100644 --- a/internal/cmdpush/cmdpush.go +++ b/internal/cmdpush/cmdpush.go @@ -1,3 +1,17 @@ +// Copyright 2021 Google LLC +// +// 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 cmdpush import ( @@ -25,22 +39,22 @@ func NewRunner(ctx context.Context, parent string) *Runner { ctx: ctx, } c := &cobra.Command{ - Use: "push [DIR@VERSION] [flags]", - Args: cobra.MaximumNArgs(1), - Short: docs.GetShort, - Long: docs.GetShort + "\n" + docs.GetLong, - Example: docs.GetExamples, - RunE: r.runE, - PreRunE: r.preRunE, + Use: "push [DIR@VERSION] [flags]", + Args: cobra.MaximumNArgs(1), + Short: docs.GetShort, + Long: docs.GetShort + "\n" + docs.GetLong, + Example: docs.GetExamples, + RunE: r.runE, + PreRunE: r.preRunE, } c.Flags().StringVar(&r.Origin, "origin", "", "assigns or changes the location where the package should be pushed. Default is to push it to "+ - "the origin from which the package was pulled.") + "the origin from which the package was pulled.") c.Flags().BoolVar(&r.Increment, "increment", false, "increment the version of the package when pushed. This will increment the DIR@VERSION if provided, "+ - "otherwise it will increment the origin's version when pulled. The version must be semver or integer, and "+ - "may have an optional leading 'v'") + "otherwise it will increment the origin's version when pulled. The version must be semver or integer, and "+ + "may have an optional leading 'v'") cmdutil.FixDocs("kpt", parent, c) r.Command = c return r @@ -52,9 +66,9 @@ func NewCommand(ctx context.Context, parent string) *cobra.Command { // Runner contains the run function type Runner struct { - ctx context.Context + ctx context.Context Push push.Command - Command *cobra.Command + Command *cobra.Command Origin string Increment bool } @@ -116,13 +130,13 @@ func (r *Runner) parseArgs(args []string) error { r.Push.Pkg = p if r.Origin != "" { - t1, err1 := parse.GitParseArgs(r.ctx, []string {r.Origin, ""}) + t1, err1 := parse.GitParseArgs(r.ctx, []string{r.Origin, ""}) if err1 == nil { r.Push.Origin = remote.NewGitOrigin(&t1.Git) return nil } - - t2, err2 := parse.OciParseArgs(r.ctx, []string {r.Origin, ""}) + + t2, err2 := parse.OciParseArgs(r.ctx, []string{r.Origin, ""}) if err2 == nil { r.Push.Origin = remote.NewOciOrigin(&t2.Oci) return nil diff --git a/internal/fnruntime/container_test.go b/internal/fnruntime/container_test.go index 57af113072..11161f1cd5 100644 --- a/internal/fnruntime/container_test.go +++ b/internal/fnruntime/container_test.go @@ -1,3 +1,4 @@ +//go:build docker // +build docker // Copyright 2021 Google LLC diff --git a/internal/util/diff/diff_test.go b/internal/util/diff/diff_test.go index 353eb84324..e6c4d3bf1c 100644 --- a/internal/util/diff/diff_test.go +++ b/internal/util/diff/diff_test.go @@ -13,6 +13,7 @@ // limitations under the License. // These tests depend on `diff` which is not available on Windows +//go:build !windows // +build !windows // Package diff_test tests the diff package diff --git a/internal/util/push/push.go b/internal/util/push/push.go index 3ef5c203bf..c79e4d5b82 100644 --- a/internal/util/push/push.go +++ b/internal/util/push/push.go @@ -80,7 +80,7 @@ func (c Command) Run(ctx context.Context) error { if err != nil { return errors.E(op, c.Pkg.UniquePath, fmt.Errorf("missing origin version information: %v", err)) } - + prefix := "" if ref != "" && ref[:1] == "v" { prefix = "v" @@ -99,11 +99,11 @@ func (c Command) Run(ctx context.Context) error { var buf bytes.Buffer switch dotParts { case 1: - fmt.Fprintf(&buf, "%s%d", prefix, v.Major() + 1) + fmt.Fprintf(&buf, "%s%d", prefix, v.Major()+1) case 2: - fmt.Fprintf(&buf, "%s%d.%d", prefix, v.Major(), v.Minor() + 1) + fmt.Fprintf(&buf, "%s%d.%d", prefix, v.Major(), v.Minor()+1) case 3: - fmt.Fprintf(&buf, "%s%d.%d.%d", prefix, v.Major(), v.Minor(), v.Patch() + 1) + fmt.Fprintf(&buf, "%s%d.%d.%d", prefix, v.Major(), v.Minor(), v.Patch()+1) } if v.Prerelease() != "" { fmt.Fprintf(&buf, "-%s", v.Prerelease()) @@ -112,16 +112,16 @@ func (c Command) Run(ctx context.Context) error { fmt.Fprintf(&buf, "+%s", v.Metadata()) } - pr.Printf("Incrementing %s to %s\n",ref, buf.String()) + pr.Printf("Incrementing %s to %s\n", ref, buf.String()) c.Origin.SetRef(buf.String()) } // the kptfile pushed in the package does not have origin data - // this is because the digest will be incorrect. Also, if it is + // this is because the digest will be incorrect. Also, if it is // pulled from a different location or via different branch, the // correct origin will be added as part of the pull operation. - kf.Origin = nil + kf.Origin = nil pr.Printf("Pushing origin %s\n", c.Origin.String()) diff --git a/internal/util/remote/git.go b/internal/util/remote/git.go index 8b93c4d677..6d99daa479 100644 --- a/internal/util/remote/git.go +++ b/internal/util/remote/git.go @@ -43,7 +43,7 @@ type gitUpstream struct { var _ Upstream = &gitUpstream{} type gitOrigin struct { - git *kptfilev1.GitLock + git *kptfilev1.GitLock } var _ Origin = &gitOrigin{} @@ -143,7 +143,7 @@ func (u *gitUpstream) BuildUpstreamLock(digest string) *kptfilev1.UpstreamLock { func (u *gitOrigin) Build(digest string) *kptfilev1.Origin { return &kptfilev1.Origin{ Type: kptfilev1.GitOrigin, - Git: &kptfilev1.GitLock{ + Git: &kptfilev1.GitLock{ Repo: u.git.Repo, Directory: u.git.Directory, Ref: u.git.Ref, diff --git a/internal/util/remote/oci.go b/internal/util/remote/oci.go index 0e4a445292..572dd85897 100644 --- a/internal/util/remote/oci.go +++ b/internal/util/remote/oci.go @@ -49,7 +49,7 @@ type ociUpstream struct { var _ Upstream = &ociUpstream{} type ociOrigin struct { - oci *kptfilev1.OciLock + oci *kptfilev1.OciLock } var _ Origin = &ociOrigin{} @@ -103,7 +103,7 @@ func (u *ociUpstream) BuildUpstreamLock(digest string) *kptfilev1.UpstreamLock { func (u *ociOrigin) Build(digest string) *kptfilev1.Origin { return &kptfilev1.Origin{ Type: kptfilev1.OciOrigin, - Oci: &kptfilev1.OciLock{ + Oci: &kptfilev1.OciLock{ Image: u.oci.Image, Digest: digest, }, @@ -196,13 +196,12 @@ func (u *ociOrigin) Push(ctx context.Context, source string, kptfile *kptfilev1. imageDigest, err := archiveAndPush(u.oci.Image, source, kptfile, remote.WithContext(ctx), remote.WithAuthFromKeychain(gcrane.Keychain)) if err != nil { - return "",errors.E(op, errors.OCI, types.UniquePath(source), err) + return "", errors.E(op, errors.OCI, types.UniquePath(source), err) } return imageDigest.String(), nil } - func (u *ociUpstream) Ref() (string, error) { const op errors.Op = "remote.Ref" r, err := name.ParseReference(u.oci.Image) From 0be828025178d03ed58fe5c7f80de0e7e6eb5a70 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Fri, 10 Dec 2021 18:58:15 +0000 Subject: [PATCH 24/26] Adding missing err checks --- internal/util/push/push.go | 8 ++++++-- internal/util/remote/oci.go | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/internal/util/push/push.go b/internal/util/push/push.go index c79e4d5b82..582b6db725 100644 --- a/internal/util/push/push.go +++ b/internal/util/push/push.go @@ -71,7 +71,9 @@ func (c Command) Run(ctx context.Context) error { } if c.Ref != "" { - c.Origin.SetRef(c.Ref) + if err := c.Origin.SetRef(c.Ref); err != nil { + return errors.E(op, c.Pkg.UniquePath, fmt.Errorf("error updating ref: %v", err)) + } } if c.Increment { @@ -114,7 +116,9 @@ func (c Command) Run(ctx context.Context) error { pr.Printf("Incrementing %s to %s\n", ref, buf.String()) - c.Origin.SetRef(buf.String()) + if err := c.Origin.SetRef(buf.String()); err != nil { + return errors.E(op, c.Pkg.UniquePath, fmt.Errorf("error updating ref: %v", err)) + } } // the kptfile pushed in the package does not have origin data diff --git a/internal/util/remote/oci.go b/internal/util/remote/oci.go index 572dd85897..d3fe5092b0 100644 --- a/internal/util/remote/oci.go +++ b/internal/util/remote/oci.go @@ -395,7 +395,9 @@ func archiveAndPush(imageName string, dir string, kptfile *kptfilev1.KptFile, op var buf *bytes.Buffer if strings.EqualFold(header.Name, "Kptfile") { buf = &bytes.Buffer{} - kptfileutil.Write(buf, kptfile) + if err := kptfileutil.Write(buf, kptfile); err != nil { + return err + } header.Size = int64(buf.Len()) } From 39a40e3d062e7cf908327221d6c9257fb8d05e7b Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Fri, 10 Dec 2021 19:10:42 +0000 Subject: [PATCH 25/26] Fixing package reference case --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ae6d8e6287..6247341a25 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,12 @@ module github.com/GoogleContainerTools/kpt go 1.16 require ( + github.com/Masterminds/semver v1.5.0 github.com/cpuguy83/go-md2man/v2 v2.0.0 github.com/go-errors/errors v1.4.0 github.com/google/go-containerregistry v0.6.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/igorsobreira/titlecase v0.0.0-20140109233139-4156b5b858ac - github.com/masterminds/semver v1.5.0 // indirect github.com/otiai10/copy v1.6.0 github.com/philopon/go-toposort v0.0.0-20170620085441-9be86dbd762f github.com/posener/complete/v2 v2.0.1-alpha.12 diff --git a/go.sum b/go.sum index 4cee3e297a..b229d9b65e 100644 --- a/go.sum +++ b/go.sum @@ -66,6 +66,8 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= @@ -630,8 +632,6 @@ github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= -github.com/masterminds/semver v1.5.0 h1:hTxJTTY7tjvnWMrl08O6u3G6BLlKVwxSz01lVac9P8U= -github.com/masterminds/semver v1.5.0/go.mod h1:s7KNT9fnd7edGzwwP7RBX4H0v/CYd5qdOLfkL1V75yg= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= From 9e0334fa04f8a3fa9151a88a5cdfded1d52d8f8c Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Fri, 10 Dec 2021 19:11:52 +0000 Subject: [PATCH 26/26] Fixing case sensitive package --- internal/util/push/push.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/util/push/push.go b/internal/util/push/push.go index 582b6db725..b866c80dcf 100644 --- a/internal/util/push/push.go +++ b/internal/util/push/push.go @@ -26,7 +26,7 @@ import ( "github.com/GoogleContainerTools/kpt/internal/printer" "github.com/GoogleContainerTools/kpt/internal/util/remote" "github.com/GoogleContainerTools/kpt/pkg/kptfile/kptfileutil" - "github.com/masterminds/semver" + "github.com/Masterminds/semver" ) // Command fetches a package from a git repository, copies it to a local