Skip to content

Commit ada7c2b

Browse files
committed
feat(artifacts): Default to latest tag if not provided
This change implements a feature where podman artifacts will default to using the 'latest' tag if no tag is provided by the user. This aligns the behavior of artifacts with that of container images, providing a more consistent user experience. Fixes: #27083 Requires: containers/container-libs#409 Signed-off-by: Lewis Denny <lewisdenny@me.com>
1 parent de3328b commit ada7c2b

File tree

6 files changed

+34
-19
lines changed

6 files changed

+34
-19
lines changed

pkg/api/handlers/libpod/artifacts.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,11 @@ func PushArtifact(w http.ResponseWriter, r *http.Request) {
346346
return
347347
}
348348

349+
if errors.Is(err, libartifact_types.ErrArtifactNotExist) {
350+
utils.ArtifactNotFound(w, name, err)
351+
return
352+
}
353+
349354
utils.InternalServerError(w, err)
350355
return
351356
}

pkg/domain/infra/abi/artifact.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/sirupsen/logrus"
1616
"go.podman.io/common/libimage"
1717
"go.podman.io/common/pkg/libartifact/types"
18+
"go.podman.io/image/v5/docker/reference"
1819
)
1920

2021
func (ir *ImageEngine) ArtifactInspect(ctx context.Context, name string, _ entities.ArtifactInspectOptions) (*entities.ArtifactInspectReport, error) {
@@ -57,6 +58,16 @@ func (ir *ImageEngine) ArtifactList(ctx context.Context, _ entities.ArtifactList
5758
}
5859

5960
func (ir *ImageEngine) ArtifactPull(ctx context.Context, name string, opts entities.ArtifactPullOptions) (*entities.ArtifactPullReport, error) {
61+
named, err := reference.Parse(name)
62+
if err != nil {
63+
return nil, fmt.Errorf("parsing reference %q: %w", name, err)
64+
}
65+
namedRef, ok := named.(reference.Named)
66+
if !ok {
67+
return nil, fmt.Errorf("reference %q is not a Named reference", name)
68+
}
69+
name = reference.TagNameOnly(namedRef).String()
70+
6071
pullOptions := &libimage.CopyOptions{}
6172
pullOptions.AuthFilePath = opts.AuthFilePath
6273
pullOptions.CertDirPath = opts.CertDirPath

test/apiv2/python/rest_api/test_v2_0_0_artifact.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
class ArtifactTestCase(APITestCase):
1313
def test_add(self):
14-
ARTIFACT_NAME = "quay.io/myimage/myartifact:latest"
14+
ARTIFACT_NAME = "quay.io/myimage/myartifact"
1515
file = ArtifactFile()
1616
parameters: dict[str, str | list[str]] = {
1717
"name": ARTIFACT_NAME,
@@ -43,6 +43,10 @@ def test_add(self):
4343
# Assert blob media type fallback detection is working
4444
self.assertEqual(artifact_layer["mediaType"], "application/octet-stream")
4545

46+
# Assert latest tag was added by default
47+
self.assertEqual(inspect_response_json["Name"], "quay.io/myimage/myartifact:latest")
48+
49+
4650
def test_add_with_replace(self):
4751
ARTIFACT_NAME = "quay.io/myimage/newartifact:latest"
4852

@@ -128,7 +132,7 @@ def test_add_with_append(self):
128132
self.assertEqual(len(artifact_layers), 2)
129133

130134
def test_add_with_artifactMIMEType_override(self):
131-
ARTIFACT_NAME = "quay.io/myimage/myartifact_artifactType:latest"
135+
ARTIFACT_NAME = "quay.io/myimage/myartifact_artifact_type:latest"
132136
file = ArtifactFile()
133137
parameters: dict[str, str | list[str]] = {
134138
"name": ARTIFACT_NAME,
@@ -672,7 +676,7 @@ def test_push_missing_artifact(self):
672676

673677
# Assert return error response is json and contains correct message
674678
self.assertIn(
675-
"no descriptor found for reference",
679+
"artifact does not exist",
676680
rjson["cause"],
677681
)
678682

test/e2e/artifact_created_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ var _ = Describe("Podman artifact created timestamp", func() {
4747

4848
// Inspect artifact
4949
a := podmanTest.InspectArtifact(artifactName)
50-
Expect(a.Name).To(Equal(artifactName))
50+
Expect(a.Name).To(Equal(artifactName + ":latest"))
5151

5252
// Check that created annotation exists and is in valid RFC3339 format
5353
createdStr, exists := a.Manifest.Annotations["org.opencontainers.image.created"]

test/e2e/artifact_test.go

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,12 @@ var _ = Describe("Podman artifact", func() {
9999

100100
a := podmanTest.InspectArtifact(artifact1Name)
101101

102-
Expect(a.Name).To(Equal(artifact1Name))
102+
Expect(a.Name).To(Equal(artifact1Name + ":latest"))
103103

104104
// Adding an artifact with an existing name should fail
105105
addAgain := podmanTest.Podman([]string{"artifact", "add", artifact1Name, artifact1File})
106106
addAgain.WaitWithDefaultTimeout()
107-
Expect(addAgain).Should(ExitWithError(125, fmt.Sprintf("Error: %s: artifact already exists", artifact1Name)))
107+
Expect(addAgain).Should(ExitWithError(125, fmt.Sprintf("Error: %s: artifact already exists", artifact1Name+":latest")))
108108
})
109109

110110
It("podman artifact add with options", func() {
@@ -124,7 +124,7 @@ var _ = Describe("Podman artifact", func() {
124124
podmanTest.PodmanExitCleanly("artifact", "add", "--file-type", yamlType, "--type", artifactType, "--annotation", annotation1, "--annotation", annotation2, artifact1Name, artifact1File)
125125

126126
a := podmanTest.InspectArtifact(artifact1Name)
127-
Expect(a.Name).To(Equal(artifact1Name))
127+
Expect(a.Name).To(Equal(artifact1Name + ":latest"))
128128
Expect(a.Manifest.ArtifactType).To(Equal(artifactType))
129129
Expect(a.Manifest.Layers[0].Annotations["color"]).To(Equal("blue"))
130130
Expect(a.Manifest.Layers[0].Annotations["flavor"]).To(Equal("lemon"))
@@ -149,7 +149,6 @@ var _ = Describe("Podman artifact", func() {
149149
failSession = podmanTest.Podman([]string{"artifact", "add", "--annotation", annotation3, artifact3Name, artifact1File, artifact2File})
150150
failSession.WaitWithDefaultTimeout()
151151
Expect(failSession).Should(ExitWithError(125, "Error: duplicate layers org.opencontainers.image.title labels within an artifact not allowed"))
152-
153152
})
154153

155154
It("podman artifact add multiple", func() {
@@ -163,7 +162,7 @@ var _ = Describe("Podman artifact", func() {
163162
podmanTest.PodmanExitCleanly("artifact", "add", artifact1Name, artifact1File1, artifact1File2)
164163

165164
a := podmanTest.InspectArtifact(artifact1Name)
166-
Expect(a.Name).To(Equal(artifact1Name))
165+
Expect(a.Name).To(Equal(artifact1Name + ":latest"))
167166

168167
Expect(a.Manifest.Layers).To(HaveLen(2))
169168
})
@@ -200,7 +199,7 @@ var _ = Describe("Podman artifact", func() {
200199

201200
a := podmanTest.InspectArtifact(artifact1Name)
202201

203-
Expect(a.Name).To(Equal(artifact1Name))
202+
Expect(a.Name).To(Equal(artifact1Name + ":latest"))
204203
})
205204

206205
It("podman artifact push with authorization", func() {
@@ -508,7 +507,7 @@ var _ = Describe("Podman artifact", func() {
508507
podmanTest.PodmanExitCleanly("artifact", "add", "--append", "--annotation", annotation1, artifact1Name, artifact3File)
509508

510509
a = podmanTest.InspectArtifact(artifact1Name)
511-
Expect(a.Name).To(Equal(artifact1Name))
510+
Expect(a.Name).To(Equal(artifact1Name + ":latest"))
512511
Expect(a.Manifest.Layers).To(HaveLen(3))
513512

514513
for _, l := range a.Manifest.Layers {
@@ -554,7 +553,6 @@ var _ = Describe("Podman artifact", func() {
554553

555554
artifact1Name := "localhost/test/artifact1"
556555
podmanTest.PodmanExitCleanly("artifact", "add", artifact1Name, artifact1File)
557-
558556
f, err := os.OpenFile(artifact1File, os.O_APPEND|os.O_WRONLY, 0o644)
559557
Expect(err).ToNot(HaveOccurred())
560558
_, err = f.WriteString("This is modification.")
@@ -619,16 +617,13 @@ var _ = Describe("Podman artifact", func() {
619617
podmanTest.PodmanExitCleanly("artifact", "add", "--type", artifactType, artifact1Name, artifact1File)
620618

621619
a := podmanTest.InspectArtifact(artifact1Name)
622-
Expect(a.Name).To(Equal(artifact1Name))
620+
Expect(a.Name).To(Equal(artifact1Name + ":latest"))
623621
Expect(a.Manifest.ArtifactType).To(Equal(artifactType))
624622

625623
podmanTest.PodmanExitCleanly("artifact", "add", "--append", artifact1Name, artifact2File)
626624

627625
a = podmanTest.InspectArtifact(artifact1Name)
628-
Expect(a.Name).To(Equal(artifact1Name))
629-
Expect(a.Manifest.ArtifactType).To(Equal(artifactType))
630-
Expect(a.Manifest.Layers).To(HaveLen(2))
631-
626+
Expect(a.Name).To(Equal(artifact1Name + ":latest"))
632627
failSession := podmanTest.Podman([]string{"artifact", "add", "--type", artifactType, "--append", artifact1Name, artifact3File})
633628
failSession.WaitWithDefaultTimeout()
634629
Expect(failSession).Should(ExitWithError(125, "Error: append option is not compatible with type option"))
@@ -647,7 +642,7 @@ var _ = Describe("Podman artifact", func() {
647642

648643
// Inspect artifact
649644
a := podmanTest.InspectArtifact(artifact1Name)
650-
Expect(a.Name).To(Equal(artifact1Name))
645+
Expect(a.Name).To(Equal(artifact1Name + ":latest"))
651646

652647
// Check that created annotation exists and is in valid Unix nanosecond format
653648
createdStr, exists := a.Manifest.Annotations["org.opencontainers.image.created"]

test/e2e/inspect_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ var _ = Describe("Podman inspect", func() {
626626
inspect = podmanTest.Podman([]string{"inspect", "--format", "{{.Name}}", artifactName})
627627
inspect.WaitWithDefaultTimeout()
628628
Expect(inspect).Should(ExitCleanly())
629-
Expect(inspect.OutputToString()).To(Equal(artifactName))
629+
Expect(inspect.OutputToString()).To(Equal(artifactName + ":latest"))
630630

631631
inspect2 := podmanTest.Podman([]string{"inspect", "--format", "{{.Digest}}", artifactName})
632632
inspect2.WaitWithDefaultTimeout()

0 commit comments

Comments
 (0)