diff --git a/common/pkg/libartifact/artifact.go b/common/pkg/libartifact/artifact.go index 2d5934c09d..412d9d24a9 100644 --- a/common/pkg/libartifact/artifact.go +++ b/common/pkg/libartifact/artifact.go @@ -7,6 +7,7 @@ import ( "github.com/opencontainers/go-digest" "go.podman.io/common/pkg/libartifact/types" + "go.podman.io/image/v5/docker/reference" "go.podman.io/image/v5/manifest" ) @@ -58,9 +59,22 @@ type ArtifactList []*Artifact // GetByNameOrDigest returns an artifact, if present, by a given name // Returns an error if not found. func (al ArtifactList) GetByNameOrDigest(nameOrDigest string) (*Artifact, bool, error) { + named, err := reference.Parse(nameOrDigest) + if err != nil { + return nil, false, fmt.Errorf("parsing reference %q: %w", nameOrDigest, err) + } + + // Assert that named implements reference.Named interface + namedRef, ok := named.(reference.Named) + if !ok { + return nil, false, fmt.Errorf("reference %q is not a Named reference", nameOrDigest) + } + + refStr := reference.TagNameOnly(namedRef).String() + // This is the hot route through for _, artifact := range al { - if artifact.Name == nameOrDigest { + if artifact.Name == refStr { return artifact, false, nil } } diff --git a/common/pkg/libartifact/store/store.go b/common/pkg/libartifact/store/store.go index 0665cbe73c..f54b6e6cde 100644 --- a/common/pkg/libartifact/store/store.go +++ b/common/pkg/libartifact/store/store.go @@ -25,6 +25,7 @@ import ( "go.podman.io/common/libimage" "go.podman.io/common/pkg/libartifact" libartTypes "go.podman.io/common/pkg/libartifact/types" + "go.podman.io/image/v5/docker/reference" "go.podman.io/image/v5/image" "go.podman.io/image/v5/manifest" "go.podman.io/image/v5/oci/layout" @@ -98,14 +99,14 @@ func (as ArtifactStore) Remove(ctx context.Context, name string) (*digest.Digest return nil, err } - arty, nameIsDigest, err := artifacts.GetByNameOrDigest(name) + arty, _, err := artifacts.GetByNameOrDigest(name) if err != nil { return nil, err } - if nameIsDigest { - name = arty.Name - } - ir, err := layout.NewReference(as.storePath, name) + + // Use the canonical name from the found artifact, which will include the tag + // if one was resolved by GetByNameOrDigest. + ir, err := layout.NewReference(as.storePath, arty.Name) if err != nil { return nil, err } @@ -186,7 +187,17 @@ func (as ArtifactStore) Push(ctx context.Context, src, dest string, opts libimag as.lock.Lock() defer as.lock.Unlock() - srcRef, err := layout.NewReference(as.storePath, src) + artifacts, err := as.getArtifacts(ctx, nil) + if err != nil { + return "", err + } + + arty, _, err := artifacts.GetByNameOrDigest(src) + if err != nil { + return "", err + } + + srcRef, err := layout.NewReference(as.storePath, arty.Name) if err != nil { return "", err } @@ -214,6 +225,18 @@ func (as ArtifactStore) Add(ctx context.Context, dest string, artifactBlobs []li return nil, ErrEmptyArtifactName } + named, err := reference.Parse(dest) + if err != nil { + return nil, fmt.Errorf("parsing reference %q: %w", dest, err) + } + + namedRef, ok := named.(reference.Named) + if !ok { + return nil, fmt.Errorf("reference %q is not a Named reference", dest) + } + + dest = reference.TagNameOnly(namedRef).String() + if options.Append && len(options.ArtifactMIMEType) > 0 { return nil, errors.New("append option is not compatible with type option") } @@ -416,20 +439,16 @@ func getArtifactAndImageSource(ctx context.Context, as ArtifactStore, nameOrDige return nil, nil, err } - arty, nameIsDigest, err := artifacts.GetByNameOrDigest(nameOrDigest) + arty, _, err := artifacts.GetByNameOrDigest(nameOrDigest) if err != nil { return nil, nil, err } - name := nameOrDigest - if nameIsDigest { - name = arty.Name - } if len(arty.Manifest.Layers) == 0 { return nil, nil, errors.New("the artifact has no blobs, nothing to extract") } - ir, err := layout.NewReference(as.storePath, name) + ir, err := layout.NewReference(as.storePath, arty.Name) if err != nil { return nil, nil, err }