From 9c37fa98339cdd6156a917d2d3dd049419f1bc3a Mon Sep 17 00:00:00 2001 From: Jason Hall Date: Tue, 3 Aug 2021 13:15:29 -0400 Subject: [PATCH 1/5] Add --annotate flag to crane append This flag instructs crane append to annotate the resulting image with information about the base image (name and current digest). This flag is false by default. --- cmd/crane/cmd/append.go | 20 +++++++++++++++++++ go.mod | 2 +- go.sum | 4 ++++ .../image-spec/specs-go/v1/annotations.go | 6 ++++++ .../image-spec/specs-go/v1/config.go | 11 ++++++++++ .../image-spec/specs-go/v1/mediatype.go | 9 +++++++++ .../image-spec/specs-go/version.go | 2 +- vendor/modules.txt | 2 +- 8 files changed, 53 insertions(+), 3 deletions(-) diff --git a/cmd/crane/cmd/append.go b/cmd/crane/cmd/append.go index a4addd111..53ca473a2 100644 --- a/cmd/crane/cmd/append.go +++ b/cmd/crane/cmd/append.go @@ -22,6 +22,8 @@ import ( "github.com/google/go-containerregistry/pkg/name" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/empty" + "github.com/google/go-containerregistry/pkg/v1/mutate" + specsv1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/spf13/cobra" ) @@ -29,6 +31,7 @@ import ( func NewCmdAppend(options *[]crane.Option) *cobra.Command { var baseRef, newTag, outFile string var newLayers []string + var annotate bool appendCmd := &cobra.Command{ Use: "append", @@ -53,6 +56,22 @@ func NewCmdAppend(options *[]crane.Option) *cobra.Command { return fmt.Errorf("appending %v: %v", newLayers, err) } + if baseRef != "" && annotate { + ref, err := name.ParseReference(baseRef) + if err != nil { + return fmt.Errorf("parsing ref %q: %v", baseRef, err) + } + + baseDigest, err := base.Digest() + if err != nil { + return err + } + img = mutate.Annotations(img, map[string]string{ + specsv1.AnnotationBaseImageName: ref.String(), + specsv1.AnnotationBaseImageDigest: baseDigest.String(), + }).(v1.Image) + } + if outFile != "" { if err := crane.Save(img, newTag, outFile); err != nil { return fmt.Errorf("writing output %q: %v", outFile, err) @@ -78,6 +97,7 @@ func NewCmdAppend(options *[]crane.Option) *cobra.Command { appendCmd.Flags().StringVarP(&newTag, "new_tag", "t", "", "Tag to apply to resulting image") appendCmd.Flags().StringSliceVarP(&newLayers, "new_layer", "f", []string{}, "Path to tarball to append to image") appendCmd.Flags().StringVarP(&outFile, "output", "o", "", "Path to new tarball of resulting image") + appendCmd.Flags().BoolVar(&annotate, "annotate", false, "If true, annotate the resulting image as being based on the base image") appendCmd.MarkFlagRequired("new_tag") appendCmd.MarkFlagRequired("new_layer") diff --git a/go.mod b/go.mod index 086b43ba2..4dbf252b7 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect - github.com/opencontainers/image-spec v1.0.1 + github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7 github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sirupsen/logrus v1.8.1 // indirect github.com/spf13/cobra v1.2.1 diff --git a/go.sum b/go.sum index 026976dab..a962eed55 100644 --- a/go.sum +++ b/go.sum @@ -539,6 +539,10 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I 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/image-spec v1.0.2-0.20210708142037-083f635f2b04 h1:FAcfLZ/aXS6exuOySekrOT/GjKPt6988dxiF/ENj828= +github.com/opencontainers/image-spec v1.0.2-0.20210708142037-083f635f2b04/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7 h1:axgApq2XShTLwQii2zAnIkMPlhGVHbAXHUcHezu5G/k= +github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/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= diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go index 35d810895..581cf7cdf 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go @@ -53,4 +53,10 @@ const ( // AnnotationDescription is the annotation key for the human-readable description of the software packaged in the image. AnnotationDescription = "org.opencontainers.image.description" + + // AnnotationBaseImageDigest is the annotation key for the digest of the image's base image. + AnnotationBaseImageDigest = "org.opencontainers.image.base.digest" + + // AnnotationBaseImageName is the annotation key for the image reference of the image's base image. + AnnotationBaseImageName = "org.opencontainers.image.base.name" ) diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go index fe799bd69..ffff4b6d1 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go @@ -89,9 +89,20 @@ type Image struct { // Architecture is the CPU architecture which the binaries in this image are built to run on. Architecture string `json:"architecture"` + // Variant is the variant of the specified CPU architecture which image binaries are intended to run on. + Variant string `json:"variant,omitempty"` + // OS is the name of the operating system which the image is built to run on. OS string `json:"os"` + // OSVersion is an optional field specifying the operating system + // version, for example on Windows `10.0.14393.1066`. + OSVersion string `json:"os.version,omitempty"` + + // OSFeatures is an optional field specifying an array of strings, + // each listing a required OS feature (for example on Windows `win32k`). + OSFeatures []string `json:"os.features,omitempty"` + // Config defines the execution parameters which should be used as a base when running a container using the image. Config ImageConfig `json:"config,omitempty"` diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go index bad7bb97f..4f35ac134 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go @@ -34,6 +34,10 @@ const ( // referenced by the manifest. MediaTypeImageLayerGzip = "application/vnd.oci.image.layer.v1.tar+gzip" + // MediaTypeImageLayerZstd is the media type used for zstd compressed + // layers referenced by the manifest. + MediaTypeImageLayerZstd = "application/vnd.oci.image.layer.v1.tar+zstd" + // MediaTypeImageLayerNonDistributable is the media type for layers referenced by // the manifest but with distribution restrictions. MediaTypeImageLayerNonDistributable = "application/vnd.oci.image.layer.nondistributable.v1.tar" @@ -43,6 +47,11 @@ const ( // restrictions. MediaTypeImageLayerNonDistributableGzip = "application/vnd.oci.image.layer.nondistributable.v1.tar+gzip" + // MediaTypeImageLayerNonDistributableZstd is the media type for zstd + // compressed layers referenced by the manifest but with distribution + // restrictions. + MediaTypeImageLayerNonDistributableZstd = "application/vnd.oci.image.layer.nondistributable.v1.tar+zstd" + // MediaTypeImageConfig specifies the media type for the image configuration. MediaTypeImageConfig = "application/vnd.oci.image.config.v1+json" ) diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/version.go b/vendor/github.com/opencontainers/image-spec/specs-go/version.go index 5d493df23..58f1095ab 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/version.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/version.go @@ -25,7 +25,7 @@ const ( VersionPatch = 1 // VersionDev indicates development branch. Releases will be empty string. - VersionDev = "" + VersionDev = "-dev" ) // Version is the specification version that the package types support. diff --git a/vendor/modules.txt b/vendor/modules.txt index 20335dc86..c6df079a5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -96,7 +96,7 @@ github.com/klauspost/compress/zstd/internal/xxhash ## explicit # github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/go-digest -# github.com/opencontainers/image-spec v1.0.1 +# github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7 ## explicit github.com/opencontainers/image-spec/specs-go github.com/opencontainers/image-spec/specs-go/v1 From 0371bf3557b58a8b199798fc84870f96220c93d1 Mon Sep 17 00:00:00 2001 From: Jason Hall Date: Tue, 3 Aug 2021 13:23:49 -0400 Subject: [PATCH 2/5] update codegen --- cmd/crane/doc/crane_append.md | 1 + go.sum | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/cmd/crane/doc/crane_append.md b/cmd/crane/doc/crane_append.md index 788963ae1..c88c06556 100644 --- a/cmd/crane/doc/crane_append.md +++ b/cmd/crane/doc/crane_append.md @@ -9,6 +9,7 @@ crane append [flags] ### Options ``` + --annotate If true, annotate the resulting image as being based on the base image -b, --base string Name of base image to append to -h, --help help for append -f, --new_layer strings Path to tarball to append to image diff --git a/go.sum b/go.sum index a962eed55..2a62a2f4c 100644 --- a/go.sum +++ b/go.sum @@ -537,10 +537,7 @@ github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go. 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/image-spec v1.0.2-0.20210708142037-083f635f2b04 h1:FAcfLZ/aXS6exuOySekrOT/GjKPt6988dxiF/ENj828= -github.com/opencontainers/image-spec v1.0.2-0.20210708142037-083f635f2b04/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7 h1:axgApq2XShTLwQii2zAnIkMPlhGVHbAXHUcHezu5G/k= github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= From 230714e0772533d860c094b8873326a38fb1a732 Mon Sep 17 00:00:00 2001 From: Jason Hall Date: Wed, 4 Aug 2021 12:42:20 -0400 Subject: [PATCH 3/5] change flag name, don't set base name if it's a digest --- cmd/crane/cmd/append.go | 8 ++++++-- cmd/crane/doc/crane_append.md | 12 ++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/cmd/crane/cmd/append.go b/cmd/crane/cmd/append.go index 53ca473a2..760d52d65 100644 --- a/cmd/crane/cmd/append.go +++ b/cmd/crane/cmd/append.go @@ -61,13 +61,17 @@ func NewCmdAppend(options *[]crane.Option) *cobra.Command { if err != nil { return fmt.Errorf("parsing ref %q: %v", baseRef, err) } + var baseName string + if _, ok := ref.(name.Tag); ok { + baseName = ref.String() + } baseDigest, err := base.Digest() if err != nil { return err } img = mutate.Annotations(img, map[string]string{ - specsv1.AnnotationBaseImageName: ref.String(), + specsv1.AnnotationBaseImageName: baseName, specsv1.AnnotationBaseImageDigest: baseDigest.String(), }).(v1.Image) } @@ -97,7 +101,7 @@ func NewCmdAppend(options *[]crane.Option) *cobra.Command { appendCmd.Flags().StringVarP(&newTag, "new_tag", "t", "", "Tag to apply to resulting image") appendCmd.Flags().StringSliceVarP(&newLayers, "new_layer", "f", []string{}, "Path to tarball to append to image") appendCmd.Flags().StringVarP(&outFile, "output", "o", "", "Path to new tarball of resulting image") - appendCmd.Flags().BoolVar(&annotate, "annotate", false, "If true, annotate the resulting image as being based on the base image") + appendCmd.Flags().BoolVar(&annotate, "set-base-image-annotations", false, "If true, annotate the resulting image as being based on the base image") appendCmd.MarkFlagRequired("new_tag") appendCmd.MarkFlagRequired("new_layer") diff --git a/cmd/crane/doc/crane_append.md b/cmd/crane/doc/crane_append.md index c88c06556..fad5d38f0 100644 --- a/cmd/crane/doc/crane_append.md +++ b/cmd/crane/doc/crane_append.md @@ -9,12 +9,12 @@ crane append [flags] ### Options ``` - --annotate If true, annotate the resulting image as being based on the base image - -b, --base string Name of base image to append to - -h, --help help for append - -f, --new_layer strings Path to tarball to append to image - -t, --new_tag string Tag to apply to resulting image - -o, --output string Path to new tarball of resulting image + -b, --base string Name of base image to append to + -h, --help help for append + -f, --new_layer strings Path to tarball to append to image + -t, --new_tag string Tag to apply to resulting image + -o, --output string Path to new tarball of resulting image + --set-base-image-annotations If true, annotate the resulting image as being based on the base image ``` ### Options inherited from parent commands From 4e71d0d5212d998c5476ab315c8b539868dded4e Mon Sep 17 00:00:00 2001 From: Jason Hall Date: Wed, 4 Aug 2021 12:47:32 -0400 Subject: [PATCH 4/5] use ref.Name() which canonicalizes e.g., ubuntu -> index.docker.io/library/ubuntu --- cmd/crane/cmd/append.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/crane/cmd/append.go b/cmd/crane/cmd/append.go index 760d52d65..515102f39 100644 --- a/cmd/crane/cmd/append.go +++ b/cmd/crane/cmd/append.go @@ -63,7 +63,7 @@ func NewCmdAppend(options *[]crane.Option) *cobra.Command { } var baseName string if _, ok := ref.(name.Tag); ok { - baseName = ref.String() + baseName = ref.Name() } baseDigest, err := base.Digest() From 8fb4beb37be78da96df2e623822e68b9527817cf Mon Sep 17 00:00:00 2001 From: Jason Hall Date: Wed, 4 Aug 2021 15:02:28 -0400 Subject: [PATCH 5/5] don't set empty annotation --- cmd/crane/cmd/append.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/cmd/crane/cmd/append.go b/cmd/crane/cmd/append.go index 515102f39..bb3b67a69 100644 --- a/cmd/crane/cmd/append.go +++ b/cmd/crane/cmd/append.go @@ -61,19 +61,18 @@ func NewCmdAppend(options *[]crane.Option) *cobra.Command { if err != nil { return fmt.Errorf("parsing ref %q: %v", baseRef, err) } - var baseName string - if _, ok := ref.(name.Tag); ok { - baseName = ref.Name() - } baseDigest, err := base.Digest() if err != nil { return err } - img = mutate.Annotations(img, map[string]string{ - specsv1.AnnotationBaseImageName: baseName, + anns := map[string]string{ specsv1.AnnotationBaseImageDigest: baseDigest.String(), - }).(v1.Image) + } + if _, ok := ref.(name.Tag); ok { + anns[specsv1.AnnotationBaseImageName] = ref.Name() + } + img = mutate.Annotations(img, anns).(v1.Image) } if outFile != "" {