Skip to content

Commit

Permalink
Have --image-refs list all images for multi-arch builds. (#761)
Browse files Browse the repository at this point in the history
* Have `--image-refs` list all images for multi-arch builds.

This change alters the behavior of `--image-refs` to also include all of the image references when a multi-architecture build is being performed.

* Add test coverage for the new path

* Add ref count check to unit test
  • Loading branch information
mattmoor authored Jul 12, 2022
1 parent bd8cfaa commit 8f22858
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 11 deletions.
25 changes: 24 additions & 1 deletion pkg/publish/recorder.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@ package publish
import (
"context"
"io"
"strings"

"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/ko/pkg/build"
"github.com/sigstore/cosign/pkg/oci"
"github.com/sigstore/cosign/pkg/oci/walk"
)

// recorder wraps a publisher implementation in a layer that recordes the published
Expand Down Expand Up @@ -47,7 +51,26 @@ func (r *recorder) Publish(ctx context.Context, br build.Result, ref string) (na
if err != nil {
return nil, err
}
if _, err := r.wc.Write([]byte(result.String() + "\n")); err != nil {

references := make([]string, 0, 20 /* just try to avoid resizing*/)
switch t := br.(type) {
case oci.SignedImageIndex:
if err := walk.SignedEntity(ctx, t, func(ctx context.Context, se oci.SignedEntity) error {
// Both of the SignedEntity types implement Digest()
h, err := se.(interface{ Digest() (v1.Hash, error) }).Digest()
if err != nil {
return err
}
references = append(references, result.Context().Digest(h.String()).String())
return nil
}); err != nil {
return nil, err
}
default:
references = append(references, result.String())
}

if _, err := r.wc.Write([]byte(strings.Join(references, "\n") + "\n")); err != nil {
return nil, err
}
return result, nil
Expand Down
49 changes: 39 additions & 10 deletions pkg/publish/recorder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ package publish
import (
"bytes"
"context"
"fmt"
"strings"
"testing"

"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/random"
"github.com/google/ko/pkg/build"
"github.com/sigstore/cosign/pkg/oci/signed"
)

type cbPublish struct {
Expand All @@ -39,10 +41,13 @@ func (sp *cbPublish) Close() error {
}

func TestRecorder(t *testing.T) {
num := 0
repo := name.MustParseReference("docker.io/ubuntu:latest")
inner := &cbPublish{cb: func(c context.Context, b build.Result, s string) (name.Reference, error) {
num++
return name.ParseReference(fmt.Sprintf("ubuntu:%d", num))
h, err := b.Digest()
if err != nil {
return nil, err
}
return repo.Context().Digest(h.String()), nil
}}

buf := bytes.NewBuffer(nil)
Expand All @@ -52,21 +57,45 @@ func TestRecorder(t *testing.T) {
t.Fatalf("NewRecorder() = %v", err)
}

if _, err := recorder.Publish(context.Background(), nil, ""); err != nil {
img, err := random.Image(3, 3)
if err != nil {
t.Fatalf("random.Image() = %v", err)
}
si := signed.Image(img)

index, err := random.Index(3, 3, 2)
if err != nil {
t.Fatalf("random.Image() = %v", err)
}
sii := signed.ImageIndex(index)

if _, err := recorder.Publish(context.Background(), si, ""); err != nil {
t.Errorf("recorder.Publish() = %v", err)
}
if _, err := recorder.Publish(context.Background(), nil, ""); err != nil {
if _, err := recorder.Publish(context.Background(), si, ""); err != nil {
t.Errorf("recorder.Publish() = %v", err)
}
if _, err := recorder.Publish(context.Background(), nil, ""); err != nil {
if _, err := recorder.Publish(context.Background(), sii, ""); err != nil {
t.Errorf("recorder.Publish() = %v", err)
}
if err := recorder.Close(); err != nil {
t.Errorf("recorder.Close() = %v", err)
}

want, got := "ubuntu:1\nubuntu:2\nubuntu:3\n", buf.String()
if got != want {
t.Errorf("buf.String() = %s, wanted %s", got, want)
refs := strings.Split(strings.TrimSpace(buf.String()), "\n")

if want, got := len(refs), 5; got != want {
t.Errorf("len(refs) = %d, wanted %d", got, want)
}

for _, s := range refs {
ref, err := name.ParseReference(s)
if err != nil {
t.Fatalf("name.ParseReference() = %v", err)
}
// Don't compare the digests, they are random.
if want, got := repo.Context().String(), ref.Context().String(); want != got {
t.Errorf("reference repo = %v, wanted %v", got, want)
}
}
}

0 comments on commit 8f22858

Please sign in to comment.