diff --git a/pkg/imgpkg/cmd/copy_repo_src.go b/pkg/imgpkg/cmd/copy_repo_src.go index 108538f4..9f380566 100644 --- a/pkg/imgpkg/cmd/copy_repo_src.go +++ b/pkg/imgpkg/cmd/copy_repo_src.go @@ -95,33 +95,36 @@ func (c CopyRepoSrc) CopyToRepo(repo string) (*ctlimgset.ProcessedImages, error) return nil, err } - var parentBundle *ctlbundle.Bundle - foundRootBundle := false - for _, processedImage := range processedImages.All() { - if processedImage.ImageIndex != nil { - continue - } + // This is added to not read the lockfile and change the ref for oci-flag. Will be removed once we add an inflate option to copy the refs. + if !c.OciFlags.IsOci() { + var parentBundle *ctlbundle.Bundle + foundRootBundle := false + for _, processedImage := range processedImages.All() { + if processedImage.ImageIndex != nil { + continue + } - if _, ok := processedImage.Labels[rootBundleLabelKey]; ok { - if foundRootBundle { - panic("Internal inconsistency: expected only 1 root bundle") + if _, ok := processedImage.Labels[rootBundleLabelKey]; ok { + if foundRootBundle { + panic("Internal inconsistency: expected only 1 root bundle") + } + foundRootBundle = true + pImage := plainimage.NewFetchedPlainImageWithTag(processedImage.DigestRef, processedImage.Tag, processedImage.Image) + lockReader := ctlbundle.NewImagesLockReader() + parentBundle = ctlbundle.NewBundle(pImage, c.registry, lockReader, ctlbundle.NewFetcherFromProcessedImages(processedImages.All(), c.registry, lockReader)) } - foundRootBundle = true - pImage := plainimage.NewFetchedPlainImageWithTag(processedImage.DigestRef, processedImage.Tag, processedImage.Image) - lockReader := ctlbundle.NewImagesLockReader() - parentBundle = ctlbundle.NewBundle(pImage, c.registry, lockReader, ctlbundle.NewFetcherFromProcessedImages(processedImages.All(), c.registry, lockReader)) } - } - if foundRootBundle { - bundles, _, err := parentBundle.AllImagesLockRefs(c.Concurrency, c.logger) - if err != nil { - return nil, err - } + if foundRootBundle { + bundles, _, err := parentBundle.AllImagesLockRefs(c.Concurrency, c.logger) + if err != nil { + return nil, err + } - for _, bundle := range bundles { - if err := bundle.NoteCopy(processedImages, c.registry, c.logger); err != nil { - return nil, fmt.Errorf("Creating copy information for bundle %s: %s", bundle.DigestRef(), err) + for _, bundle := range bundles { + if err := bundle.NoteCopy(processedImages, c.registry, c.logger); err != nil { + return nil, fmt.Errorf("Creating copy information for bundle %s: %s", bundle.DigestRef(), err) + } } } } diff --git a/pkg/imgpkg/imagedesc/image_intermediate.go b/pkg/imgpkg/imagedesc/image_intermediate.go index be3732aa..caf65787 100644 --- a/pkg/imgpkg/imagedesc/image_intermediate.go +++ b/pkg/imgpkg/imagedesc/image_intermediate.go @@ -14,6 +14,72 @@ type ImageIndexIntermediate struct { tag string } +type ImageIntermediate struct { + Image regv1.Image + ref string + tag string +} + +func (mi ImageIntermediate) Ref() string { + return mi.ref +} + +func (mi *ImageIntermediate) SetRef(ref string) { + mi.ref = ref +} + +func (mi ImageIntermediate) Tag() string { + return mi.tag +} + +func (mi *ImageIntermediate) SetTag(tag string) { + mi.tag = tag +} + +func (mi ImageIntermediate) Layers() ([]regv1.Layer, error) { + return mi.Image.Layers() +} + +func (mi ImageIntermediate) MediaType() (types.MediaType, error) { + return mi.Image.MediaType() +} + +func (mi ImageIntermediate) Size() (int64, error) { + return mi.Image.Size() +} + +func (mi ImageIntermediate) ConfigName() (regv1.Hash, error) { + return mi.Image.ConfigName() +} + +func (mi ImageIntermediate) ConfigFile() (*regv1.ConfigFile, error) { + return mi.Image.ConfigFile() +} + +func (mi ImageIntermediate) RawConfigFile() ([]byte, error) { + return mi.Image.RawConfigFile() +} + +func (mi ImageIntermediate) Digest() (regv1.Hash, error) { + return mi.Image.Digest() +} + +func (mi ImageIntermediate) Manifest() (*regv1.Manifest, error) { + return mi.Image.Manifest() +} + +func (mi ImageIntermediate) RawManifest() ([]byte, error) { + return mi.Image.RawManifest() +} + +func (mi ImageIntermediate) LayerByDigest(h regv1.Hash) (regv1.Layer, error) { + return mi.Image.LayerByDigest(h) +} + +func (mi ImageIntermediate) LayerByDiffID(h regv1.Hash) (regv1.Layer, error) { + return mi.Image.LayerByDiffID(h) +} + func (mi ImageIndexIntermediate) Ref() string { return mi.ref } @@ -59,3 +125,4 @@ func (mi ImageIndexIntermediate) ImageIndex(h regv1.Hash) (regv1.ImageIndex, err } var _ regv1.ImageIndex = ImageIndexIntermediate{} +var _ regv1.Image = ImageIntermediate{} diff --git a/pkg/imgpkg/imageset/tar_image_set.go b/pkg/imgpkg/imageset/tar_image_set.go index 56fb125a..275b701b 100644 --- a/pkg/imgpkg/imageset/tar_image_set.go +++ b/pkg/imgpkg/imageset/tar_image_set.go @@ -129,7 +129,7 @@ func (i *TarImageSet) Import(path string, importRepo regname.Repository, registr var err error if tarisoci { - imgOrIndexes, err = imagetar.NewTarReader(path).ReadOci(importRepo.Name()) + imgOrIndexes, err = imagetar.NewTarReader(path).ReadOci(importRepo) } else { imgOrIndexes, err = imagetar.NewTarReader(path).Read() } diff --git a/pkg/imgpkg/imagetar/tar_reader.go b/pkg/imgpkg/imagetar/tar_reader.go index 9429898f..32681f45 100644 --- a/pkg/imgpkg/imagetar/tar_reader.go +++ b/pkg/imgpkg/imagetar/tar_reader.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "os" + "path/filepath" "github.com/google/go-containerregistry/pkg/name" v1 "github.com/google/go-containerregistry/pkg/v1" @@ -151,9 +152,8 @@ func (r TarReader) getIdsFromManifest(file tarFile) (*imagedesc.ImageRefDescript return ids, nil } -func (r TarReader) ReadOci(reponame string) ([]imagedesc.ImageOrIndex, error) { +func (r TarReader) ReadOci(importRepo name.Repository) ([]imagedesc.ImageOrIndex, error) { - //Check if the path is a OCI layout directory stat, err := os.Stat(r.path) if err != nil { return nil, err @@ -163,39 +163,68 @@ func (r TarReader) ReadOci(reponame string) ([]imagedesc.ImageOrIndex, error) { return nil, fmt.Errorf("path %s is not a directory", r.path) } - //TODO : FromPath checks for index.json but does not check for oci-layout, so add a check for oci-layout here. + _, err = os.Stat(filepath.Join(r.path, "oci-layout")) + if err != nil { + return nil, err + } l, err := layout.FromPath(r.path) if err != nil { return nil, err } - ImageIndex, err := l.ImageIndex() + ii, err := l.ImageIndex() + m, err := ii.IndexManifest() + desc := m.Manifests[0] - ImageIndexIntermediate := imagedesc.ImageIndexIntermediate{ - Index: ImageIndex, - } + var ImageIntermediate imagedesc.ImageIntermediate + var ImageIndexIntermediate imagedesc.ImageIndexIntermediate + var ref string + + if desc.MediaType.IsImage() { + img, err := ii.Image(desc.Digest) + if err != nil { + return nil, err + } + + ImageIntermediate = imagedesc.ImageIntermediate{ + Image: img, + } - // Update ref - digest, err := ImageIndex.Digest() - digestStr := digest.String() - ref := reponame + "@" + digestStr - ImageIndexIntermediate.SetRef(ref) + digest, err := img.Digest() + digestStr := digest.String() + ref = importRepo.Name() + "@" + digestStr - // Create and populate imageOrIndex - var i imagedesc.ImageIndexWithRef = ImageIndexIntermediate + ImageIntermediate.SetRef(ref) + + } else if desc.MediaType.IsIndex() { + idx, err := ii.ImageIndex(desc.Digest) + if err != nil { + return nil, err + } + ImageIndexIntermediate = imagedesc.ImageIndexIntermediate{ + Index: idx, + } + + digest, err := idx.Digest() + digestStr := digest.String() + ref = importRepo.Name() + "@" + digestStr + ImageIndexIntermediate.SetRef(ref) + + } else { + return nil, fmt.Errorf("Unexpected media type: %s", desc.MediaType) + } + var b imagedesc.ImageWithRef = ImageIntermediate imageOrIndex := imagedesc.ImageOrIndex{ - Image: nil, - Index: &i, + Image: &b, + Index: nil, Labels: map[string]string{ - "label1": "value1", - "label2": "value2", + "dev.carvel.imgpkg.copy.root-bundle": "", }, - OrigRef: "original-reference", + OrigRef: "", } - //Add imageOrIndex to the slice of imageOrIndex var imageOrIndexSlice []imagedesc.ImageOrIndex imageOrIndexSlice = append(imageOrIndexSlice, imageOrIndex)