Skip to content

Commit

Permalink
Added support for imageindex and minor changes
Browse files Browse the repository at this point in the history
Signed-off-by: ashpect <[email protected]>
  • Loading branch information
ashpect committed Mar 3, 2024
1 parent d0d653f commit 5b3d191
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 43 deletions.
47 changes: 25 additions & 22 deletions pkg/imgpkg/cmd/copy_repo_src.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
}
Expand Down
67 changes: 67 additions & 0 deletions pkg/imgpkg/imagedesc/image_intermediate.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -59,3 +125,4 @@ func (mi ImageIndexIntermediate) ImageIndex(h regv1.Hash) (regv1.ImageIndex, err
}

var _ regv1.ImageIndex = ImageIndexIntermediate{}
var _ regv1.Image = ImageIntermediate{}
2 changes: 1 addition & 1 deletion pkg/imgpkg/imageset/tar_image_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
69 changes: 49 additions & 20 deletions pkg/imgpkg/imagetar/tar_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand All @@ -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)

Expand Down

0 comments on commit 5b3d191

Please sign in to comment.