diff --git a/cmd/podman/artifact/list.go b/cmd/podman/artifact/list.go index c17261a497..a1d09b5857 100644 --- a/cmd/podman/artifact/list.go +++ b/cmd/podman/artifact/list.go @@ -38,12 +38,29 @@ type listFlagType struct { } type artifactListOutput struct { - Digest string - Repository string - Size string - Tag string - Created string - VirtualSize string + Digest string + Repository string + Size string + Tag string + created time.Time + VirtualSize string + virtualBytes int64 +} + +// Created returns human-readable elapsed time since artifact was created +func (a artifactListOutput) Created() string { + if a.created.IsZero() { + return "" + } + return units.HumanDuration(time.Since(a.created)) + " ago" +} + +// CreatedAt returns the full timestamp string of when the artifact was created +func (a artifactListOutput) CreatedAt() string { + if a.created.IsZero() { + return "" + } + return a.created.String() } var ( @@ -109,23 +126,23 @@ func outputTemplate(cmd *cobra.Command, lrs []*entities.ArtifactListReport) erro artifactHash = artifactDigest.Encoded() } - var created string + var createdTime time.Time createdAnnotation, ok := lr.Manifest.Annotations[imgspecv1.AnnotationCreated] if ok { - createdTime, err := time.Parse(time.RFC3339Nano, createdAnnotation) + createdTime, err = time.Parse(time.RFC3339Nano, createdAnnotation) if err != nil { return err } - created = units.HumanDuration(time.Since(createdTime)) + " ago" } artifacts = append(artifacts, artifactListOutput{ - Digest: artifactHash, - Repository: named.Name(), - Size: units.HumanSize(float64(lr.Artifact.TotalSizeBytes())), - Tag: tag, - Created: created, - VirtualSize: fmt.Sprintf("%d", lr.Artifact.TotalSizeBytes()), + Digest: artifactHash, + Repository: named.Name(), + Size: units.HumanSize(float64(lr.Artifact.TotalSizeBytes())), + Tag: tag, + created: createdTime, + VirtualSize: fmt.Sprintf("%d", lr.Artifact.TotalSizeBytes()), + virtualBytes: lr.Artifact.TotalSizeBytes(), }) } diff --git a/docs/source/markdown/podman-artifact-ls.1.md.in b/docs/source/markdown/podman-artifact-ls.1.md.in index d2b6203639..81cedd5783 100644 --- a/docs/source/markdown/podman-artifact-ls.1.md.in +++ b/docs/source/markdown/podman-artifact-ls.1.md.in @@ -19,6 +19,7 @@ Print results with a Go template. | **Placeholder** | **Description** | |-----------------|------------------------------------------------| | .Created | Elapsed time since the artifact was created | +| .CreatedAt | Full timestamp of when the artifact was created| | .Digest | The computed digest of the artifact's manifest | | .Repository | Repository name of the artifact | | .Size | Size artifact in human readable units | diff --git a/test/e2e/artifact_test.go b/test/e2e/artifact_test.go index 73a7a896b6..daed989753 100644 --- a/test/e2e/artifact_test.go +++ b/test/e2e/artifact_test.go @@ -88,6 +88,16 @@ var _ = Describe("Podman artifact", func() { // Assuming the test runs less than a minute humanReadableDurationRegexp := `^(Less than a second|1 second|\d+ seconds) ago$` Expect(created).To(ContainElements(MatchRegexp(humanReadableDurationRegexp), MatchRegexp(humanReadableDurationRegexp))) + + // Check if .CreatedAt is reported correctly + createdAtFormatSession := podmanTest.PodmanExitCleanly("artifact", "ls", "--format", "{{.CreatedAt}}") + createdAt := createdAtFormatSession.OutputToStringArray() + + Expect(createdAt).To(HaveLen(2)) + + // Verify the timestamp format looks like "2025-10-23 12:34:56.789 +0000 UTC" + timestampRegexp := `^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(\.\d+)? \+\d{4} UTC$` + Expect(createdAt).To(ContainElements(MatchRegexp(timestampRegexp), MatchRegexp(timestampRegexp))) }) It("podman artifact simple add", func() {