From 88f862f09b7cabc12e4a834d0f6cb6acfe669d3a Mon Sep 17 00:00:00 2001 From: Dennis Leon Date: Mon, 11 Oct 2021 16:36:36 -0700 Subject: [PATCH] SPIKE WIP Authored-by: Dennis Leon --- pkg/imgpkg/imagedesc/image_ref_descriptors.go | 159 ++++++++++++++++++ pkg/imgpkg/plainimage/contents.go | 26 ++- 2 files changed, 184 insertions(+), 1 deletion(-) diff --git a/pkg/imgpkg/imagedesc/image_ref_descriptors.go b/pkg/imgpkg/imagedesc/image_ref_descriptors.go index e8244eada..da29289fb 100644 --- a/pkg/imgpkg/imagedesc/image_ref_descriptors.go +++ b/pkg/imgpkg/imagedesc/image_ref_descriptors.go @@ -109,6 +109,28 @@ func NewImageRefDescriptors(refs []Metadata, registry Registry) (*ImageRefDescri return imageRefDescs, err } +func NewImageRefDescriptorsFromImage(imageMetadata Metadata, image regv1.Image) (*ImageRefDescriptors, error) { + var registry Registry = nil + + imageRefDescs := &ImageRefDescriptors{ + registry: registry, + imageLayers: map[ImageLayerDescriptor]regv1.Layer{}, + } + + var td ImageOrImageIndexDescriptor + + img, err := imageRefDescs.buildImageFromImage(imageMetadata, image) + if err != nil { + return nil, err + } + + td = ImageOrImageIndexDescriptor{Image: &img} + + imageRefDescs.descs = append(imageRefDescs.descs, td) + + return imageRefDescs, err +} + func (ids *ImageRefDescriptors) Descriptors() []ImageOrImageIndexDescriptor { return ids.descs } @@ -158,6 +180,61 @@ func (ids *ImageRefDescriptors) buildImageIndex(ref Metadata, regDesc regv1.Desc return td, nil } +func (ids *ImageRefDescriptors) buildImageIndexFromManifest(ref Metadata, regDesc regv1.ImageIndex) (ImageIndexDescriptor, error) { + mediaType, err := regDesc.MediaType() + if err != nil { + return ImageIndexDescriptor{}, err + } + + digest, err := regDesc.Digest() + if err != nil { + return ImageIndexDescriptor{}, err + } + + td := ImageIndexDescriptor{ + Refs: []string{ref.Ref.Name()}, + MediaType: string(mediaType), + Digest: digest.String(), + Tag: ref.Tag, + Labels: ref.Labels, + } + + imgIndex, err := ids.registry.Index(ref.Ref) + if err != nil { + return td, err + } + + rawManifest, err := imgIndex.RawManifest() + if err != nil { + return td, err + } + + td.Raw = string(rawManifest) + + imgIndexManifest, err := imgIndex.IndexManifest() + if err != nil { + return td, err + } + + for _, manDesc := range imgIndexManifest.Manifests { + if ids.isImageIndex(manDesc) { + imgIndexTd, err := ids.buildImageIndex(Metadata{ids.buildRef(ref.Ref, manDesc.Digest.String()), ref.Tag, ref.Labels}, manDesc) + if err != nil { + return ImageIndexDescriptor{}, err + } + td.Indexes = append(td.Indexes, imgIndexTd) + } else { + imgTd, err := ids.buildImage(Metadata{ids.buildRef(ref.Ref, manDesc.Digest.String()), ref.Tag, ref.Labels}) + if err != nil { + return ImageIndexDescriptor{}, err + } + td.Images = append(td.Images, imgTd) + } + } + + return td, nil +} + func (ids *ImageRefDescriptors) buildImage(ref Metadata) (ImageDescriptor, error) { td := ImageDescriptor{} @@ -245,6 +322,88 @@ func (ids *ImageRefDescriptors) buildImage(ref Metadata) (ImageDescriptor, error return td, nil } +func (ids *ImageRefDescriptors) buildImageFromImage(ref Metadata, img regv1.Image) (ImageDescriptor, error) { + td := ImageDescriptor{} + + cfgDigest, err := img.ConfigName() + if err != nil { + return td, err + } + cfgBlob, err := img.RawConfigFile() + if err != nil { + return td, err + } + + manifestMediaType, err := img.MediaType() + if err != nil { + return td, err + } + manifestDigest, err := img.Digest() + if err != nil { + return td, err + } + manifestBlob, err := img.RawManifest() + if err != nil { + return td, err + } + + td = ImageDescriptor{ + Refs: []string{ref.Ref.String()}, + + Config: ConfigDescriptor{ + Digest: cfgDigest.String(), + Raw: string(cfgBlob), + }, + + Manifest: ManifestDescriptor{ + MediaType: string(manifestMediaType), + Digest: manifestDigest.String(), + Raw: string(manifestBlob), + }, + Tag: ref.Tag, + Labels: ref.Labels, + } + + layers, err := img.Layers() + if err != nil { + return td, err + } + + for _, layer := range layers { + layerMediaType, err := layer.MediaType() + if err != nil { + return td, err + } + layerDigest, err := layer.Digest() + if err != nil { + return td, err + } + layerDiffID, err := layer.DiffID() + if err != nil { + return td, err + } + layerSize, err := layer.Size() + if err != nil { + return td, err + } + + layerTD := ImageLayerDescriptor{ + MediaType: string(layerMediaType), + Digest: layerDigest.String(), + DiffID: layerDiffID.String(), + Size: layerSize, + } + + td.Layers = append(td.Layers, layerTD) + + ids.imageLayersLock.Lock() + ids.imageLayers[layerTD] = layer + ids.imageLayersLock.Unlock() + } + + return td, nil +} + func (*ImageRefDescriptors) isImageIndex(regDesc regv1.Descriptor) bool { switch regDesc.MediaType { case regtypes.OCIImageIndex, regtypes.DockerManifestList: diff --git a/pkg/imgpkg/plainimage/contents.go b/pkg/imgpkg/plainimage/contents.go index ed1c29fa5..499435dc7 100644 --- a/pkg/imgpkg/plainimage/contents.go +++ b/pkg/imgpkg/plainimage/contents.go @@ -5,6 +5,8 @@ package plainimage import ( "fmt" + "io" + "io/ioutil" "os" "path/filepath" "strings" @@ -13,6 +15,8 @@ import ( regname "github.com/google/go-containerregistry/pkg/name" regv1 "github.com/google/go-containerregistry/pkg/v1" ctlimg "github.com/k14s/imgpkg/pkg/imgpkg/image" + "github.com/k14s/imgpkg/pkg/imgpkg/imagedesc" + "github.com/k14s/imgpkg/pkg/imgpkg/imagetar" ) type Contents struct { @@ -43,7 +47,27 @@ func (i Contents) Push(uploadRef regname.Tag, labels map[string]string, writer I defer img.Remove() - err = writer.WriteImage(uploadRef, img) + reference, err := regname.ParseReference("temp") + if err != nil { + return "", err + } + + imageRefDescriptors, err := imagedesc.NewImageRefDescriptorsFromImage(imagedesc.Metadata{ + Ref: reference, + Tag: uploadRef.Name(), + Labels: labels, + }, img) + if err != nil { + return "", err + } + + tarWriter := imagetar.NewTarWriter(imageRefDescriptors, func() (io.WriteCloser, error) { + return ioutil.TempFile("/tmp/", "localbundle.tar") + }, imagetar.TarWriterOpts{1}, ui, imagetar.NewImageLayerWriterCheck(false)) + + err = tarWriter.Write() + + //err = writer.WriteImage(uploadRef, img) if err != nil { return "", fmt.Errorf("Writing '%s': %s", uploadRef.Name(), err) }