mirror of https://github.com/containers/podman.git
224 lines
7.0 KiB
Go
224 lines
7.0 KiB
Go
//go:build linux || freebsd
|
|
|
|
package integration
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
|
|
. "github.com/containers/podman/v5/test/utils"
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
var _ = Describe("Podman artifact mount", func() {
|
|
BeforeEach(func() {
|
|
SkipIfRemote("artifacts are not supported on the remote client yet due to being in development still")
|
|
})
|
|
|
|
It("podman artifact mount single blob", func() {
|
|
podmanTest.PodmanExitCleanly("artifact", "pull", ARTIFACT_SINGLE)
|
|
|
|
const artifactContent = "mRuO9ykak1Q2j"
|
|
|
|
tests := []struct {
|
|
name string
|
|
mountOpts string
|
|
containerFile string
|
|
}{
|
|
{
|
|
name: "single artifact mount",
|
|
mountOpts: "dst=/test",
|
|
containerFile: "/test/testfile",
|
|
},
|
|
{
|
|
name: "single artifact mount on existing file",
|
|
mountOpts: "dst=/etc/os-release",
|
|
containerFile: "/etc/os-release",
|
|
},
|
|
{
|
|
name: "single artifact mount with title",
|
|
mountOpts: "dst=/tmp,title=testfile",
|
|
containerFile: "/tmp/testfile",
|
|
},
|
|
{
|
|
name: "single artifact mount with digest",
|
|
mountOpts: "dst=/data,digest=sha256:e9510923578af3632946ecf5ae479c1b5f08b47464e707b5cbab9819272a9752",
|
|
containerFile: "/data/sha256-e9510923578af3632946ecf5ae479c1b5f08b47464e707b5cbab9819272a9752",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
By(tt.name)
|
|
// FIXME: we need https://github.com/containers/container-selinux/pull/360 to fix the selinux access problem, until then disable it.
|
|
session := podmanTest.PodmanExitCleanly("run", "--security-opt=label=disable", "--rm", "--mount", "type=artifact,src="+ARTIFACT_SINGLE+","+tt.mountOpts, ALPINE, "cat", tt.containerFile)
|
|
Expect(session.OutputToString()).To(Equal(artifactContent))
|
|
}
|
|
})
|
|
|
|
It("podman artifact mount multi blob", func() {
|
|
podmanTest.PodmanExitCleanly("artifact", "pull", ARTIFACT_MULTI)
|
|
podmanTest.PodmanExitCleanly("artifact", "pull", ARTIFACT_MULTI_NO_TITLE)
|
|
|
|
const (
|
|
artifactContent1 = "xuHWedtC0ADST"
|
|
artifactContent2 = "tAyZczFlgFsi4"
|
|
)
|
|
|
|
type expectedFiles struct {
|
|
file string
|
|
content string
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
mountOpts string
|
|
containerFiles []expectedFiles
|
|
}{
|
|
{
|
|
name: "multi blob with title",
|
|
mountOpts: "src=" + ARTIFACT_MULTI + ",dst=/test",
|
|
containerFiles: []expectedFiles{
|
|
{
|
|
file: "/test/test1",
|
|
content: artifactContent1,
|
|
},
|
|
{
|
|
file: "/test/test2",
|
|
content: artifactContent2,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "multi blob without title",
|
|
mountOpts: "src=" + ARTIFACT_MULTI_NO_TITLE + ",dst=/test",
|
|
containerFiles: []expectedFiles{
|
|
{
|
|
file: "/test/sha256-8257bba28b9d19ac353c4b713b470860278857767935ef7e139afd596cb1bb2d",
|
|
content: artifactContent1,
|
|
},
|
|
{
|
|
file: "/test/sha256-63700c54129c6daaafe3a20850079f82d6d658d69de73d6158d81f920c6fbdd7",
|
|
content: artifactContent2,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "multi blob filter by title",
|
|
mountOpts: "src=" + ARTIFACT_MULTI + ",dst=/test,title=test2",
|
|
containerFiles: []expectedFiles{
|
|
{
|
|
file: "/test/test2",
|
|
content: artifactContent2,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "multi blob filter by digest",
|
|
mountOpts: "src=" + ARTIFACT_MULTI + ",dst=/test,digest=sha256:8257bba28b9d19ac353c4b713b470860278857767935ef7e139afd596cb1bb2d",
|
|
containerFiles: []expectedFiles{
|
|
{
|
|
file: "/test/sha256-8257bba28b9d19ac353c4b713b470860278857767935ef7e139afd596cb1bb2d",
|
|
content: artifactContent1,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
By(tt.name)
|
|
// FIXME: we need https://github.com/containers/container-selinux/pull/360 to fix the selinux access problem, until then disable it.
|
|
args := []string{"run", "--security-opt=label=disable", "--rm", "--mount", "type=artifact," + tt.mountOpts, ALPINE, "cat"}
|
|
for _, f := range tt.containerFiles {
|
|
args = append(args, f.file)
|
|
}
|
|
session := podmanTest.PodmanExitCleanly(args...)
|
|
outs := session.OutputToStringArray()
|
|
Expect(outs).To(HaveLen(len(tt.containerFiles)))
|
|
for i, f := range tt.containerFiles {
|
|
Expect(outs[i]).To(Equal(f.content))
|
|
}
|
|
}
|
|
})
|
|
|
|
It("podman artifact mount remove while in use", func() {
|
|
ctrName := "ctr1"
|
|
artifactName := "localhost/test"
|
|
artifactFileName := "somefile"
|
|
|
|
artifactFile := filepath.Join(podmanTest.TempDir, artifactFileName)
|
|
err := os.WriteFile(artifactFile, []byte("hello world\n"), 0o644)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
podmanTest.PodmanExitCleanly("artifact", "add", artifactName, artifactFile)
|
|
|
|
// FIXME: we need https://github.com/containers/container-selinux/pull/360 to fix the selinux access problem, until then disable it.
|
|
podmanTest.PodmanExitCleanly("run", "--security-opt=label=disable", "--name", ctrName, "-d", "--mount", "type=artifact,src="+artifactName+",dst=/test", ALPINE, "sleep", "100")
|
|
|
|
podmanTest.PodmanExitCleanly("artifact", "rm", artifactName)
|
|
|
|
// file must sill be readable after artifact removal
|
|
session := podmanTest.PodmanExitCleanly("exec", ctrName, "cat", "/test/"+artifactFileName)
|
|
Expect(session.OutputToString()).To(Equal("hello world"))
|
|
|
|
// restart will fail if artifact does not exist
|
|
session = podmanTest.Podman([]string{"restart", "-t0", ctrName})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).To(ExitWithError(125, artifactName+": artifact does not exist"))
|
|
|
|
// create a artifact with the same name again and add another file to ensure it picks up the changes
|
|
artifactFile2Name := "otherfile"
|
|
artifactFile2 := filepath.Join(podmanTest.TempDir, artifactFile2Name)
|
|
err = os.WriteFile(artifactFile2, []byte("second file"), 0o644)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
podmanTest.PodmanExitCleanly("artifact", "add", artifactName, artifactFile, artifactFile2)
|
|
podmanTest.PodmanExitCleanly("start", ctrName)
|
|
|
|
session = podmanTest.PodmanExitCleanly("exec", ctrName, "cat", "/test/"+artifactFileName, "/test/"+artifactFile2Name)
|
|
Expect(session.OutputToString()).To(Equal("hello world second file"))
|
|
})
|
|
|
|
It("podman artifact mount dest conflict", func() {
|
|
tests := []struct {
|
|
name string
|
|
mount string
|
|
}{
|
|
{
|
|
name: "bind mount --volume",
|
|
mount: "--volume=/tmp:/test",
|
|
},
|
|
{
|
|
name: "overlay mount",
|
|
mount: "--volume=/tmp:/test:O",
|
|
},
|
|
{
|
|
name: "named volume",
|
|
mount: "--volume=abc:/test:O",
|
|
},
|
|
{
|
|
name: "bind mount --mount type=bind",
|
|
mount: "--mount=type=bind,src=/tmp,dst=/test",
|
|
},
|
|
{
|
|
name: "image mount",
|
|
mount: "--mount=type=bind,src=someimage,dst=/test",
|
|
},
|
|
{
|
|
name: "tmpfs mount",
|
|
mount: "--tmpfs=/test",
|
|
},
|
|
{
|
|
name: "artifact mount",
|
|
mount: "--mount=type=artifact,src=abc,dst=/test",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
By(tt.name)
|
|
session := podmanTest.Podman([]string{"run", "--rm", "--mount", "type=artifact,src=someartifact,dst=/test", tt.mount, ALPINE})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).To(ExitWithError(125, "/test: duplicate mount destination"))
|
|
}
|
|
})
|
|
})
|