diff --git a/common/libimage/manifest_list.go b/common/libimage/manifest_list.go index d7ee5e6b67..14d00685cb 100644 --- a/common/libimage/manifest_list.go +++ b/common/libimage/manifest_list.go @@ -314,6 +314,29 @@ type ManifestListAddOptions struct { Password string } +func (m *ManifestList) parseNameToExtantReference(ctx context.Context, name string, manifestList bool, what string) (types.ImageReference, error) { + ref, err := alltransports.ParseImageName(name) + if err != nil { + withDocker := fmt.Sprintf("%s://%s", docker.Transport.Name(), name) + ref, err = alltransports.ParseImageName(withDocker) + if err == nil { + var src types.ImageSource + src, err = ref.NewImageSource(ctx, nil) + if err == nil { + src.Close() + } + } + if err != nil { + image, _, lookupErr := m.image.runtime.LookupImage(name, &LookupImageOptions{ManifestList: manifestList}) + if lookupErr != nil { + return nil, fmt.Errorf("locating %s: %q: %w; %q: %w", what, withDocker, err, name, lookupErr) + } + ref, err = image.storageReference, nil + } + } + return ref, err +} + // Add adds one or more manifests to the manifest list and returns the digest // of the added instance. func (m *ManifestList) Add(ctx context.Context, name string, options *ManifestListAddOptions) (digest.Digest, error) { @@ -321,13 +344,9 @@ func (m *ManifestList) Add(ctx context.Context, name string, options *ManifestLi options = &ManifestListAddOptions{} } - ref, err := alltransports.ParseImageName(name) + ref, err := m.parseNameToExtantReference(ctx, name, false, "image to add to manifest list") if err != nil { - withDocker := fmt.Sprintf("%s://%s", docker.Transport.Name(), name) - ref, err = alltransports.ParseImageName(withDocker) - if err != nil { - return "", err - } + return "", err } // Now massage in the copy-related options into the system context. @@ -428,17 +447,9 @@ func (m *ManifestList) AddArtifact(ctx context.Context, options *ManifestListAdd opts.LayerMediaType = &options.LayerType } if options.Subject != "" { - ref, err := alltransports.ParseImageName(options.Subject) + ref, err := m.parseNameToExtantReference(ctx, options.Subject, true, "subject for artifact manifest") if err != nil { - withDocker := fmt.Sprintf("%s://%s", docker.Transport.Name(), options.Subject) - ref, err = alltransports.ParseImageName(withDocker) - if err != nil { - image, _, err := m.image.runtime.LookupImage(options.Subject, &LookupImageOptions{ManifestList: true}) - if err != nil { - return "", fmt.Errorf("locating subject for artifact manifest: %w", err) - } - ref = image.storageReference - } + return "", err } opts.SubjectReference = ref } @@ -541,17 +552,9 @@ func (m *ManifestList) AnnotateInstance(d digest.Digest, options *ManifestListAn } } if options.Subject != "" { - ref, err := alltransports.ParseImageName(options.Subject) + ref, err := m.parseNameToExtantReference(ctx, options.Subject, true, "subject for image index") if err != nil { - withDocker := fmt.Sprintf("%s://%s", docker.Transport.Name(), options.Subject) - ref, err = alltransports.ParseImageName(withDocker) - if err != nil { - image, _, err := m.image.runtime.LookupImage(options.Subject, &LookupImageOptions{ManifestList: true}) - if err != nil { - return fmt.Errorf("locating subject for image index: %w", err) - } - ref = image.storageReference - } + return err } src, err := ref.NewImageSource(ctx, &m.image.runtime.systemContext) if err != nil { diff --git a/common/libimage/manifest_list_test.go b/common/libimage/manifest_list_test.go index 6fc46372b1..7d6e1ceae2 100644 --- a/common/libimage/manifest_list_test.go +++ b/common/libimage/manifest_list_test.go @@ -116,10 +116,22 @@ func TestCreateAndTagManifestList(t *testing.T) { require.NoError(t, err) require.NotNil(t, list) + _, err = runtime.Load(ctx, "testdata/oci-unnamed.tar.gz", nil) + require.NoError(t, err) + + // add a remote reference manifestListOpts := &ManifestListAddOptions{All: true} _, err = list.Add(ctx, "docker://busybox", manifestListOpts) require.NoError(t, err) + // add a remote reference where we have to figure out that it's remote + _, err = list.Add(ctx, "busybox", manifestListOpts) + require.NoError(t, err) + + // add using a local image's ID + _, err = list.Add(ctx, "5c8aca8137ac47e84c69ae93ce650ce967917cc001ba7aad5494073fac75b8b6", manifestListOpts) + require.NoError(t, err) + list, err = runtime.LookupManifestList(listName) require.NoError(t, err) require.NotNil(t, list) diff --git a/common/pkg/config/config_local_test.go b/common/pkg/config/config_local_test.go index 56e97bcf91..91ba58f6dc 100644 --- a/common/pkg/config/config_local_test.go +++ b/common/pkg/config/config_local_test.go @@ -355,25 +355,25 @@ var _ = Describe("Config Local", func() { // Given config1, err := New(nil) // Then - gomega.Expect(err).To(gomega.BeNil()) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) gomega.Expect(config1.Engine.CdiSpecDirs.Get()).To(gomega.Equal([]string{"/etc/cdi"})) // Given default just get default config2, err := NewConfig("testdata/containers_default.conf") // Then - gomega.Expect(err).To(gomega.BeNil()) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) gomega.Expect(config2.Engine.CdiSpecDirs.Get()).To(gomega.Equal([]string{"/etc/cdi"})) // Given override just get override config3, err := NewConfig("testdata/containers_override.conf") // Then - gomega.Expect(err).To(gomega.BeNil()) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) gomega.Expect(config3.Engine.CdiSpecDirs.Get()).To(gomega.Equal([]string{"/somepath"})) // Given override just get override config4, err := NewConfig("testdata/containers_override2.conf") // Then - gomega.Expect(err).To(gomega.BeNil()) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) gomega.Expect(config4.Engine.CdiSpecDirs.Get()).To(gomega.Equal([]string{"/somepath", "/some_other_path"})) })