Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
WRKLDS-370: copy manifests from linux/amd64 to all manifests in a list
  • Loading branch information
soltysh committed May 12, 2022
commit 39d1efe95981d4aee0af4d37bb9cf53e359af56c
8 changes: 8 additions & 0 deletions pkg/cli/admin/release/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"os"
"path"
"path/filepath"
"regexp"
"sort"
"strings"
"sync"
Expand Down Expand Up @@ -917,6 +918,13 @@ func (o *NewOptions) extractManifests(is *imageapi.ImageStream, name string, met
opts := extract.NewExtractOptions(genericclioptions.IOStreams{Out: o.Out, ErrOut: o.ErrOut})
opts.ParallelOptions = o.ParallelOptions
opts.SecurityOptions = o.SecurityOptions
// we'll always use manifests from the linux/amd64 image, since the manifests
// won't differ between architectures, at least for now
re, err := regexp.Compile("linux/amd64")
if err != nil {
return err
}
opts.FilterOptions.OSFilter = re
opts.OnlyFiles = true
opts.ImageMetadataCallback = func(m *extract.Mapping, dgst, contentDigest digest.Digest, config *dockerv1client.DockerImageConfig) {
verifier.Verify(dgst, contentDigest)
Expand Down
34 changes: 29 additions & 5 deletions pkg/cli/image/append/append.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ type AppendImageOptions struct {
ConfigurationCallback func(dgst, contentDigest digest.Digest, config *dockerv1client.DockerImageConfig) error
// ToDigest is set after a new image is uploaded
ToDigest digest.Digest
ToSize int64

DropHistory bool
CreatedAt string
Expand Down Expand Up @@ -292,26 +293,46 @@ func (o *AppendImageOptions) appendManifestList(ctx context.Context, createdAt *
toRepo distribution.Repository, toManifests distribution.ManifestService) error {
// process manifestlist
// oldDigest:newDigest mapping so that we can create a new manifestlist
newDigests := make(map[digest.Digest]digest.Digest)
newDigests := make(map[digest.Digest]distribution.Descriptor)
manifestMap, oldList, _, err := imagemanifest.AllManifests(ctx, from.Ref, repo)
for digest, srcManifest := range manifestMap {
err = o.append(ctx, createdAt, from, to, true, repo, srcManifest, manifestLocation, toRepo, toManifests)
// create new ManifestLocation for each digest from the manifestlist
// because append function relies on that data
dgstManifestLocation := imagemanifest.ManifestLocation{Manifest: digest}
// to ensure we can read from the Reader multiple times, especially
// when dealing with ManifestList, where we copy the same layer contents
// (the release-manifests/ directory), we need to wrap it inside TeeReader
// which reads copies data to buffer while reading it allowing re-use
var buf bytes.Buffer
if o.LayerStream != nil {
o.LayerStream = io.TeeReader(o.LayerStream, &buf)
}
err = o.append(ctx, createdAt, from, to, true, repo, srcManifest, dgstManifestLocation, toRepo, toManifests)
if err != nil {
return fmt.Errorf("error appending image %s: %w", digest, err)
}
newDigests[digest] = o.ToDigest
if buf.Len() > 0 {
o.LayerStream = &buf
}
newDigests[digest] = distribution.Descriptor{
Digest: o.ToDigest,
Size: o.ToSize,
}
}

// create new manifestlist from the old one swapping digest with the new ones
newDescriptors := make([]manifestlist.ManifestDescriptor, 0, len(oldList.Manifests))
for _, manifest := range oldList.Manifests {
manifest.Digest = newDigests[manifest.Digest]
descriptor := newDigests[manifest.Digest]
manifest.Digest = descriptor.Digest
manifest.Size = descriptor.Size
newDescriptors = append(newDescriptors, manifest)

}
forPush, err := manifestlist.FromDescriptors(newDescriptors)
if err != nil {
return fmt.Errorf("error creating new manifestlist: %#v", err)
}

// push new manifestlist to registry
toDigest, err := imagemanifest.PutManifestInCompatibleSchema(ctx, forPush, to.Ref.Tag, toManifests, toRepo.Named(), nil, nil)
if err != nil {
Expand Down Expand Up @@ -517,6 +538,7 @@ func (o *AppendImageOptions) append(ctx context.Context, createdAt *time.Time,
return fmt.Errorf("unable to upload the new image manifest: %v", err)
}
klog.V(4).Infof("Created config JSON:\n%s", configJSON)

tag := to.Ref.Tag
if skipTagging {
tag = ""
Expand All @@ -526,6 +548,8 @@ func (o *AppendImageOptions) append(ctx context.Context, createdAt *time.Time,
return fmt.Errorf("unable to convert the image to a compatible schema version: %v", err)
}
o.ToDigest = toDigest
data, _ := json.MarshalIndent(manifest, "", " ")
o.ToSize = int64(len(data))
if !o.DryRun {
toString := to.String()
if skipTagging {
Expand Down