mirror of
https://github.com/containers/podman.git
synced 2025-10-17 03:04:21 +08:00

This commit implements automatic creation timestamp functionality for artifacts as requested in GitHub issue #27081, allowing users to see when artifacts were created. Changes made: - Add org.opencontainers.image.created annotation with Unix nanoseconds timestamp during artifact creation - Preserve original creation timestamp when using --append option - Update artifact inspect and add man pages to document the new functionality - Add comprehensive e2e and system BATS tests to verify creation timestamp behavior - Store timestamp as integer (Unix nanoseconds) for programmatic access The creation timestamp helps users understand artifact freshness, particularly useful for AI models and other time-sensitive artifacts managed by tools like RamaLama. Usage examples: podman artifact add myartifact:latest /path/to/file # Creates with timestamp podman artifact inspect myartifact:latest # Shows created annotation as integer podman artifact add --append myartifact:latest /file2 # Preserves original timestamp Fixes: https://github.com/containers/podman/issues/27081 Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
96 lines
3.0 KiB
Go
96 lines
3.0 KiB
Go
//go:build linux || freebsd
|
|
|
|
package integration
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
. "github.com/containers/podman/v5/test/utils"
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
var _ = Describe("Podman artifact created timestamp", func() {
|
|
|
|
createArtifactFile := func(size int) (string, error) {
|
|
artifactFile := filepath.Join(podmanTest.TempDir, RandomString(12))
|
|
f, err := os.Create(artifactFile)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer f.Close()
|
|
|
|
data := RandomString(size)
|
|
_, err = f.WriteString(data)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return artifactFile, nil
|
|
}
|
|
|
|
It("podman artifact inspect shows created date in RFC3339 format", func() {
|
|
artifactFile, err := createArtifactFile(1024)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
artifactName := "localhost/test/artifact-created"
|
|
|
|
// Record time before creation (with some buffer for slow systems)
|
|
beforeCreate := time.Now().UTC().Add(-time.Second)
|
|
|
|
// Add artifact
|
|
podmanTest.PodmanExitCleanly("artifact", "add", artifactName, artifactFile)
|
|
|
|
// Record time after creation
|
|
afterCreate := time.Now().UTC().Add(time.Second)
|
|
|
|
// Inspect artifact
|
|
a := podmanTest.InspectArtifact(artifactName)
|
|
Expect(a.Name).To(Equal(artifactName))
|
|
|
|
// Check that created annotation exists and is in valid RFC3339 format
|
|
createdStr, exists := a.Manifest.Annotations["org.opencontainers.image.created"]
|
|
Expect(exists).To(BeTrue(), "Should have org.opencontainers.image.created annotation")
|
|
|
|
// Parse the created timestamp as RFC3339Nano
|
|
createdTime, err := time.Parse(time.RFC3339Nano, createdStr)
|
|
Expect(err).ToNot(HaveOccurred(), "Created timestamp should be valid RFC3339Nano format")
|
|
|
|
// Verify timestamp is reasonable (within our time window)
|
|
Expect(createdTime).To(BeTemporally(">=", beforeCreate))
|
|
Expect(createdTime).To(BeTemporally("<=", afterCreate))
|
|
})
|
|
|
|
It("podman artifact append preserves original created date", func() {
|
|
artifactFile1, err := createArtifactFile(1024)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
artifactFile2, err := createArtifactFile(2048)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
artifactName := "localhost/test/artifact-append"
|
|
|
|
// Add initial artifact
|
|
podmanTest.PodmanExitCleanly("artifact", "add", artifactName, artifactFile1)
|
|
|
|
// Get initial created timestamp
|
|
a := podmanTest.InspectArtifact(artifactName)
|
|
originalCreated := a.Manifest.Annotations["org.opencontainers.image.created"]
|
|
Expect(originalCreated).ToNot(BeEmpty())
|
|
|
|
// Wait a moment to ensure timestamps would be different
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
// Append to the artifact
|
|
podmanTest.PodmanExitCleanly("artifact", "add", "--append", artifactName, artifactFile2)
|
|
|
|
// Check that created timestamp is unchanged
|
|
a = podmanTest.InspectArtifact(artifactName)
|
|
currentCreated := a.Manifest.Annotations["org.opencontainers.image.created"]
|
|
Expect(currentCreated).To(Equal(originalCreated), "Created timestamp should not change when appending")
|
|
|
|
// Verify we have 2 layers
|
|
Expect(a.Manifest.Layers).To(HaveLen(2))
|
|
})
|
|
})
|