Files
podman/test/e2e/artifact_test.go
Brent Baude d7553fabc7 podman artifact
the podman artifact verb is used to manage OCI artifacts.  the following
verbs were added to `podman artifact`:

* add
* inspect
* ls
* pull
* push
* rm

Notable items with this PR:

* all artifact commands and their output are subject to change. i.e.
  consider all of this tech preview
* there is no way to add a file to an artifact that already exists in
  the store.  you would need to delete and recreate the artifact.
* all references to artifacts names should be fully qualified names in
  the form of repo/name:tag (i.e. quay.io/artifact/foobar:latest)
* i understand that we will likely want to be able to attribute things
  like arch, etc to artifact files.  this function is not available yet.

Many thanks to Paul Holzinger for autocompletion PRs and review PRs that
fixed issues early on.

Also fix up some Args function to specify the correct number of args.

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Signed-off-by: Brent Baude <bbaude@redhat.com>
2025-01-21 12:47:30 -06:00

161 lines
6.0 KiB
Go

//go:build linux || freebsd
package integration
import (
"encoding/json"
"fmt"
"github.com/containers/podman/v5/pkg/libartifact"
. "github.com/containers/podman/v5/test/utils"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gexec"
)
var _ = Describe("Podman artifact", func() {
BeforeEach(func() {
SkipIfRemote("artifacts are not supported on the remote client yet due to being in development still")
})
It("podman artifact ls", func() {
artifact1File, err := createArtifactFile(4192)
Expect(err).ToNot(HaveOccurred())
artifact1Name := "localhost/test/artifact1"
podmanTest.PodmanExitCleanly([]string{"artifact", "add", artifact1Name, artifact1File}...)
artifact2File, err := createArtifactFile(10240)
Expect(err).ToNot(HaveOccurred())
artifact2Name := "localhost/test/artifact2"
podmanTest.PodmanExitCleanly([]string{"artifact", "add", artifact2Name, artifact2File}...)
// Should be three items in the list
listSession := podmanTest.PodmanExitCleanly([]string{"artifact", "ls"}...)
Expect(listSession.OutputToStringArray()).To(HaveLen(3))
// --format should work
listFormatSession := podmanTest.PodmanExitCleanly([]string{"artifact", "ls", "--format", "{{.Repository}}"}...)
output := listFormatSession.OutputToStringArray()
// There should be only 2 "lines" because the header should not be output
Expect(output).To(HaveLen(2))
// Make sure the names are what we expect
Expect(output).To(ContainElement(artifact1Name))
Expect(output).To(ContainElement(artifact2Name))
})
It("podman artifact simple add", func() {
artifact1File, err := createArtifactFile(1024)
Expect(err).ToNot(HaveOccurred())
artifact1Name := "localhost/test/artifact1"
podmanTest.PodmanExitCleanly([]string{"artifact", "add", artifact1Name, artifact1File}...)
inspectSingleSession := podmanTest.PodmanExitCleanly([]string{"artifact", "inspect", artifact1Name}...)
a := libartifact.Artifact{}
inspectOut := inspectSingleSession.OutputToString()
err = json.Unmarshal([]byte(inspectOut), &a)
Expect(err).ToNot(HaveOccurred())
Expect(a.Name).To(Equal(artifact1Name))
// Adding an artifact with an existing name should fail
addAgain := podmanTest.Podman([]string{"artifact", "add", artifact1Name, artifact1File})
addAgain.WaitWithDefaultTimeout()
Expect(addAgain).ShouldNot(ExitCleanly())
Expect(addAgain.ErrorToString()).To(Equal(fmt.Sprintf("Error: artifact %s already exists", artifact1Name)))
})
It("podman artifact add multiple", func() {
artifact1File1, err := createArtifactFile(1024)
Expect(err).ToNot(HaveOccurred())
artifact1File2, err := createArtifactFile(8192)
Expect(err).ToNot(HaveOccurred())
artifact1Name := "localhost/test/artifact1"
podmanTest.PodmanExitCleanly([]string{"artifact", "add", artifact1Name, artifact1File1, artifact1File2}...)
inspectSingleSession := podmanTest.PodmanExitCleanly([]string{"artifact", "inspect", artifact1Name}...)
a := libartifact.Artifact{}
inspectOut := inspectSingleSession.OutputToString()
err = json.Unmarshal([]byte(inspectOut), &a)
Expect(err).ToNot(HaveOccurred())
Expect(a.Name).To(Equal(artifact1Name))
var layerCount int
for _, layer := range a.Manifests {
layerCount += len(layer.Layers)
}
Expect(layerCount).To(Equal(2))
})
It("podman artifact push and pull", func() {
artifact1File, err := createArtifactFile(1024)
Expect(err).ToNot(HaveOccurred())
lock, port, err := setupRegistry(nil)
if err == nil {
defer lock.Unlock()
}
Expect(err).ToNot(HaveOccurred())
artifact1Name := fmt.Sprintf("localhost:%s/test/artifact1", port)
podmanTest.PodmanExitCleanly([]string{"artifact", "add", artifact1Name, artifact1File}...)
podmanTest.PodmanExitCleanly([]string{"artifact", "push", "-q", "--tls-verify=false", artifact1Name}...)
podmanTest.PodmanExitCleanly([]string{"artifact", "rm", artifact1Name}...)
podmanTest.PodmanExitCleanly([]string{"artifact", "pull", "--tls-verify=false", artifact1Name}...)
inspectSingleSession := podmanTest.PodmanExitCleanly([]string{"artifact", "inspect", artifact1Name}...)
a := libartifact.Artifact{}
inspectOut := inspectSingleSession.OutputToString()
err = json.Unmarshal([]byte(inspectOut), &a)
Expect(err).ToNot(HaveOccurred())
Expect(a.Name).To(Equal(artifact1Name))
})
It("podman artifact remove", func() {
// Trying to remove an image that does not exist should fail
rmFail := podmanTest.Podman([]string{"artifact", "rm", "foobar"})
rmFail.WaitWithDefaultTimeout()
Expect(rmFail).Should(Exit(125))
Expect(rmFail.ErrorToString()).Should(Equal(fmt.Sprintf("Error: no artifact found with name or digest of %s", "foobar")))
// Add an artifact to remove later
artifact1File, err := createArtifactFile(4192)
Expect(err).ToNot(HaveOccurred())
artifact1Name := "localhost/test/artifact1"
addArtifact1 := podmanTest.PodmanExitCleanly([]string{"artifact", "add", artifact1Name, artifact1File}...)
// Removing that artifact should work
rmWorks := podmanTest.PodmanExitCleanly([]string{"artifact", "rm", artifact1Name}...)
// The digests printed by removal should be the same as the digest that was added
Expect(addArtifact1.OutputToString()).To(Equal(rmWorks.OutputToString()))
// Inspecting that the removed artifact should fail
inspectArtifact := podmanTest.Podman([]string{"artifact", "inspect", artifact1Name})
inspectArtifact.WaitWithDefaultTimeout()
Expect(inspectArtifact).Should(Exit(125))
Expect(inspectArtifact.ErrorToString()).To(Equal(fmt.Sprintf("Error: no artifact found with name or digest of %s", artifact1Name)))
})
It("podman artifact inspect with full or partial digest", func() {
artifact1File, err := createArtifactFile(4192)
Expect(err).ToNot(HaveOccurred())
artifact1Name := "localhost/test/artifact1"
addArtifact1 := podmanTest.PodmanExitCleanly([]string{"artifact", "add", artifact1Name, artifact1File}...)
artifactDigest := addArtifact1.OutputToString()
podmanTest.PodmanExitCleanly([]string{"artifact", "inspect", artifactDigest}...)
podmanTest.PodmanExitCleanly([]string{"artifact", "inspect", artifactDigest[:12]}...)
})
})