Skip to content

Commit

Permalink
test: unit test index sha (#2844)
Browse files Browse the repository at this point in the history
Signed-off-by: Austin Abro <[email protected]>
  • Loading branch information
AustinAbro321 authored Aug 7, 2024
1 parent 447d984 commit 35952d8
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 75 deletions.
39 changes: 22 additions & 17 deletions src/internal/packager/images/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@ import (
"golang.org/x/sync/errgroup"
)

func checkForIndex(refInfo transform.Image, desc *remote.Descriptor) error {
if refInfo.Digest != "" && desc != nil && types.MediaType(desc.MediaType).IsIndex() {
var idx v1.IndexManifest
if err := json.Unmarshal(desc.Manifest, &idx); err != nil {
return fmt.Errorf("unable to unmarshal index.json: %w", err)
}
lines := []string{"The following images are available in the index:"}
name := refInfo.Name
if refInfo.Tag != "" {
name += ":" + refInfo.Tag
}
for _, desc := range idx.Manifests {
lines = append(lines, fmt.Sprintf("image - %s@%s with platform %s", name, desc.Digest.String(), desc.Platform.String()))
}
imageOptions := strings.Join(lines, "\n")
return fmt.Errorf("%s resolved to an OCI image index which is not supported by Zarf, select a specific platform to use: %s", refInfo.Reference, imageOptions)
}
return nil
}

// Pull pulls all of the images from the given config.
func Pull(ctx context.Context, cfg PullConfig) (map[transform.Image]v1.Image, error) {
var longer string
Expand Down Expand Up @@ -146,23 +166,8 @@ func Pull(ctx context.Context, cfg PullConfig) (map[transform.Image]v1.Image, er
}
}

if refInfo.Digest != "" && desc != nil && types.MediaType(desc.MediaType).IsIndex() {
message.Warn("Zarf does not currently support direct consumption of OCI image indexes or Docker manifest lists")

var idx v1.IndexManifest
if err := json.Unmarshal(desc.Manifest, &idx); err != nil {
return fmt.Errorf("unable to unmarshal index manifest: %w", err)
}
lines := []string{"The following images are available in the index:"}
name := refInfo.Name
if refInfo.Tag != "" {
name += ":" + refInfo.Tag
}
for _, desc := range idx.Manifests {
lines = append(lines, fmt.Sprintf("\n(%s) %s@%s", desc.Platform, name, desc.Digest))
}
message.Warn(strings.Join(lines, "\n"))
return fmt.Errorf("%s resolved to an index, please select a specific platform to use", refInfo.Reference)
if err := checkForIndex(refInfo, desc); err != nil {
return err
}

cacheImg, err := utils.OnlyHasImageLayers(img)
Expand Down
69 changes: 69 additions & 0 deletions src/internal/packager/images/pull_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,83 @@ package images

import (
"context"
"encoding/json"
"fmt"
"os"
"path/filepath"
"testing"

v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/stretchr/testify/require"
"github.com/zarf-dev/zarf/src/pkg/transform"
)

func TestCheckForIndex(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
ref string
file string
expectedErr string
}{
{
name: "index sha",
ref: "ghcr.io/zarf-dev/zarf/agent:v0.32.6@sha256:05a82656df5466ce17c3e364c16792ae21ce68438bfe06eeab309d0520c16b48",
file: "agent-index.json",
expectedErr: "%s resolved to an OCI image index which is not supported by Zarf, select a specific platform to use",
},
{
name: "docker manifest list",
ref: "defenseunicorns/zarf-game@sha256:0b694ca1c33afae97b7471488e07968599f1d2470c629f76af67145ca64428af",
file: "game-index.json",
expectedErr: "%s resolved to an OCI image index which is not supported by Zarf, select a specific platform to use",
},
{
name: "image manifest",
ref: "ghcr.io/zarf-dev/zarf/agent:v0.32.6",
file: "agent-manifest.json",
expectedErr: "",
},
{
name: "image manifest sha'd",
ref: "ghcr.io/zarf-dev/zarf/agent:v0.32.6@sha256:b3fabdc7d4ecd0f396016ef78da19002c39e3ace352ea0ae4baa2ce9d5958376",
file: "agent-manifest.json",
expectedErr: "",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
refInfo, err := transform.ParseImageRef(tc.ref)
require.NoError(t, err)
file := filepath.Join("testdata", tc.file)
manifest, err := os.ReadFile(file)
require.NoError(t, err)
var idx v1.IndexManifest
err = json.Unmarshal(manifest, &idx)
require.NoError(t, err)
desc := &remote.Descriptor{
Descriptor: v1.Descriptor{
MediaType: idx.MediaType,
},
Manifest: manifest,
}
err = checkForIndex(refInfo, desc)
if tc.expectedErr != "" {
require.ErrorContains(t, err, fmt.Sprintf(tc.expectedErr, refInfo.Reference))
// Ensure the error message contains the digest of the manifests the user can use
for _, manifest := range idx.Manifests {
require.ErrorContains(t, err, manifest.Digest.String())
}
return
}
require.NoError(t, err)
})
}
}

func TestPull(t *testing.T) {
t.Run("pulling a cosign image is successful and doesn't add anything to the cache", func(t *testing.T) {
ref, err := transform.ParseImageRef("ghcr.io/stefanprodan/podinfo:sha256-57a654ace69ec02ba8973093b6a786faa15640575fbf0dbb603db55aca2ccec8.sig")
Expand Down
50 changes: 50 additions & 0 deletions src/internal/packager/images/testdata/agent-index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:b3fabdc7d4ecd0f396016ef78da19002c39e3ace352ea0ae4baa2ce9d5958376",
"size": 673,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:454bf871b5d826b6a31ab14c983583ae9d9e30c2036606b500368c5b552d8fdf",
"size": 673,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:449cd2cd763614f07219f38f8514b56c7831d583f7c6f767491d3ad31572189c",
"size": 566,
"annotations": {
"vnd.docker.reference.digest": "sha256:b3fabdc7d4ecd0f396016ef78da19002c39e3ace352ea0ae4baa2ce9d5958376",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:2b51d89bf901b4e65dd85d8c6f135278fc7f86bb48608f0681a83291deadd645",
"size": 566,
"annotations": {
"vnd.docker.reference.digest": "sha256:454bf871b5d826b6a31ab14c983583ae9d9e30c2036606b500368c5b552d8fdf",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
}
]
}
21 changes: 21 additions & 0 deletions src/internal/packager/images/testdata/agent-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"digest": "sha256:cd4790c66d0f72eb0e0c12d75c1025478294af876ff0042d1c3501db57b0244b",
"size": 1284
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:32f8946351207153325c9d5eb56c61bbd96f9cd8deaa6dcecc4a3d4867609bec",
"size": 327582
},
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:72dbbe2df2af4ee1b7a0c7ee66782999e8f6f846ffed250aec3738791d941ba7",
"size": 38937433
}
]
}
34 changes: 34 additions & 0 deletions src/internal/packager/images/testdata/game-index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"schemaVersion": 2,
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:f78e442f0f3eb3e9459b5ae6b1a8fda62f8dfe818112e7d130a4e8ae72b3cbff",
"size": 739,
"platform": {
"architecture": "arm",
"os": "linux",
"variant": "v7"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:e4d27fe4b7bf6d5cb7ef02ed0d33ec0846796c09d6ed4bd94c8b946119a01b09",
"size": 739,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:e81b1467b812019f8e8e81450728b084471806dc7e959b7beb9f39933c337e7d",
"size": 739,
"platform": {
"architecture": "amd64",
"os": "linux"
}
}
]
}
40 changes: 0 additions & 40 deletions src/test/e2e/14_create_sha_index_test.go

This file was deleted.

9 changes: 0 additions & 9 deletions src/test/packages/14-index-sha/image-index/zarf.yaml

This file was deleted.

9 changes: 0 additions & 9 deletions src/test/packages/14-index-sha/manifest-list/zarf.yaml

This file was deleted.

0 comments on commit 35952d8

Please sign in to comment.