diff options
Diffstat (limited to 'test')
48 files changed, 940 insertions, 142 deletions
diff --git a/test/apiv2/01-basic.at b/test/apiv2/01-basic.at index 9d4b04edb..f550d5fc3 100644 --- a/test/apiv2/01-basic.at +++ b/test/apiv2/01-basic.at @@ -59,7 +59,10 @@ t GET info 200 \ .DefaultRuntime~.*$runtime \ .MemTotal~[0-9]\\+ -# Timing: make sure server stays responsive +# Timing: make sure server stays responsive. +# Because /info may need to check storage, it may be slow the first time. +# Let's invoke it once to prime caches, then run ten queries in a timed loop. +t GET info 200 t0=$SECONDS for i in $(seq 1 10); do # FIXME: someday: refactor t(), separate out the 'curl' logic so we @@ -70,7 +73,8 @@ t1=$SECONDS delta_t=$((t1 - t2)) # Desired number of seconds in which we expect to run. -want=7 +# FIXME: 10 seconds is a lot! PR #8076 opened to investigate why. +want=10 if [ $delta_t -le $want ]; then _show_ok 1 "Time for ten /info requests ($delta_t seconds) <= ${want}s" else diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at index 7fbcd2e9c..c7055dfc4 100644 --- a/test/apiv2/20-containers.at +++ b/test/apiv2/20-containers.at @@ -206,16 +206,6 @@ t POST containers/${cid_top}/stop "" 204 t DELETE containers/$cid 204 t DELETE containers/$cid_top 204 -# test the apiv2 create, shouldn't ignore the ENV and WORKDIR from the image -t POST containers/create '"Image":"'$ENV_WORKDIR_IMG'","Env":["testKey1"]' 201 \ - .Id~[0-9a-f]\\{64\\} -cid=$(jq -r '.Id' <<<"$output") -t GET containers/$cid/json 200 \ - .Config.Env~.*REDIS_VERSION= \ - .Config.Env~.*testKey1= \ - .Config.WorkingDir="/data" # default is /data -t DELETE containers/$cid 204 - # test the WORKDIR and StopSignal t POST containers/create '"Image":"'$ENV_WORKDIR_IMG'","WorkingDir":"/dataDir","StopSignal":"9"' 201 \ .Id~[0-9a-f]\\{64\\} diff --git a/test/apiv2/30-volumes.at b/test/apiv2/30-volumes.at index b599680e3..2c38954b6 100644 --- a/test/apiv2/30-volumes.at +++ b/test/apiv2/30-volumes.at @@ -3,12 +3,64 @@ # volume-related tests # -# -# FIXME: endpoints seem to be unimplemented, return 404 -# -if false; then -t GET libpod/volumes/json 200 null -t POST libpod/volumes/create name=foo 201 -fi +## create volume +t GET libpod/info 200 +volumepath=$(jq -r ".store.volumePath" <<<"$output") +t POST libpod/volumes/create name=foo1 201 \ + .Name=foo1 \ + .Driver=local \ + .Mountpoint=$volumepath/foo1/_data \ + .CreatedAt~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* \ + .Labels={} \ + .Options=null +t POST libpod/volumes/create '' 201 +t POST libpod/volumes/create \ + '"Name":"foo2","Label":{"testlabel":"testonly"},"Options":{"type":"tmpfs","o":"nodev,noexec"}}' 201 \ + .Name=foo2 \ + .Labels.testlabel=testonly \ + .Options.type=tmpfs \ + .Options.o=nodev,noexec + +# Negative test +# We have created a volume named "foo1" +t POST libpod/volumes/create name=foo1 500 \ + .cause="volume already exists" \ + .message~.* \ + .response=500 + +## list volume +t GET libpod/volumes/json 200 \ + .[0].Name~.* \ + .[0].Mountpoint~.* \ + .[0].CreatedAt~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* +# -G --data-urlencode 'filters={"name":["foo1"]}' +t GET libpod/volumes/json?filters=%7B%22name%22%3A%5B%22foo1%22%5D%7D 200 length=1 .[0].Name=foo1 +# -G --data-urlencode 'filters={"name":["notexist"]}' +t GET libpod/volumes/json?filters=%7B%22name%22%3A%5B%22notexists%22%5D%7D 200 length=0 + +## inspect volume +t GET libpod/volumes/foo1/json 200 \ + .Name=foo1 \ + .Mountpoint=$volumepath/foo1/_data \ + .CreatedAt~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* +t GET libpod/volumes/notexist/json 404 \ + .cause="no such volume" \ + .message~.* \ + .response=404 + +## Remove volumes +t DELETE libpod/volumes/foo1 204 +#After remove foo1 volume, this volume should not exist +t GET libpod/volumes/foo1/json 404 +# Negative test +t DELETE libpod/volumes/foo1 404 \ + .cause="no such volume" \ + .message~.* \ + .response=404 + +## Prune volumes +t POST libpod/volumes/prune "" 200 +#After prune volumes, there should be no volume existing +t GET libpod/volumes/json 200 length=0 # vim: filetype=sh diff --git a/test/apiv2/test-apiv2 b/test/apiv2/test-apiv2 index 78325eb24..c8ca9df3f 100755 --- a/test/apiv2/test-apiv2 +++ b/test/apiv2/test-apiv2 @@ -179,7 +179,7 @@ function t() { # POST requests require an extra params arg if [[ $method = "POST" ]]; then curl_args="-d $(jsonify $1)" - testname="$testname [$1]" + testname="$testname [$curl_args]" shift fi @@ -204,21 +204,30 @@ function t() { echo "-------------------------------------------------------------" >>$LOG echo "\$ $testname" >>$LOG rm -f $WORKDIR/curl.* - curl -s -X $method ${curl_args} \ - -H 'Content-type: application/json' \ - --dump-header $WORKDIR/curl.headers.out \ - -o $WORKDIR/curl.result.out "$url" - - if [[ $? -eq 7 ]]; then - echo "FATAL: curl failure on $url - cannot continue" >&2 + # -s = silent, but --write-out 'format' gives us important response data + response=$(curl -s -X $method ${curl_args} \ + -H 'Content-type: application/json' \ + --dump-header $WORKDIR/curl.headers.out \ + --write-out '%{http_code}^%{content_type}^%{time_total}' \ + -o $WORKDIR/curl.result.out "$url") + + # Any error from curl is instant bad news, from which we can't recover + rc=$? + if [[ $rc -ne 0 ]]; then + echo "FATAL: curl failure ($rc) on $url - cannot continue" >&2 exit 1 fi - cat $WORKDIR/curl.headers.out >>$LOG 2>/dev/null || true + # Show returned headers (without trailing ^M or empty lines) in log file. + # Sometimes -- I can't remember why! -- we don't get headers. + if [[ -e $WORKDIR/curl.headers.out ]]; then + tr -d '\015' < $WORKDIR/curl.headers.out | egrep '.' >>$LOG + fi - # Log results, if text. If JSON, filter through jq for readability. - content_type=$(sed -ne 's/^Content-Type:[ ]\+//pi' <$WORKDIR/curl.headers.out) + IFS='^' read actual_code content_type time_total <<<"$response" + printf "X-Response-Time: ${time_total}s\n\n" >>$LOG + # Log results, if text. If JSON, filter through jq for readability. if [[ $content_type =~ /octet ]]; then output="[$(file --brief $WORKDIR/curl.result.out)]" echo "$output" >>$LOG @@ -233,10 +242,8 @@ function t() { fi # Test return code - actual_code=$(head -n1 $WORKDIR/curl.headers.out | awk '/^HTTP/ { print $2}') is "$actual_code" "$expected_code" "$testname : status" - # Special case: 204/304, by definition, MUST NOT return content (rfc2616) if [[ $expected_code = 204 || $expected_code = 304 ]]; then if [ -n "$*" ]; then diff --git a/test/e2e/attach_test.go b/test/e2e/attach_test.go index 8065f6298..0c27e05c7 100644 --- a/test/e2e/attach_test.go +++ b/test/e2e/attach_test.go @@ -40,7 +40,7 @@ var _ = Describe("Podman attach", func() { }) It("podman attach to non-running container", func() { - session := podmanTest.Podman([]string{"create", "--name", "test1", "-d", "-i", ALPINE, "ls"}) + session := podmanTest.Podman([]string{"create", "--name", "test1", "-i", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -50,7 +50,7 @@ var _ = Describe("Podman attach", func() { }) It("podman container attach to non-running container", func() { - session := podmanTest.Podman([]string{"container", "create", "--name", "test1", "-d", "-i", ALPINE, "ls"}) + session := podmanTest.Podman([]string{"container", "create", "--name", "test1", "-i", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go index 5155bcbc7..572e55fe5 100644 --- a/test/e2e/build_test.go +++ b/test/e2e/build_test.go @@ -220,7 +220,6 @@ var _ = Describe("Podman build", func() { }) It("podman build --http_proxy flag", func() { - SkipIfRemote("FIXME: This is broken should be fixed") // This is hanging currently. os.Setenv("http_proxy", "1.2.3.4") if IsRemote() { podmanTest.StopRemoteService() diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index e36c86690..3814d161d 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -235,14 +235,7 @@ func PodmanTestCreateUtil(tempDir string, remote bool) *PodmanTestIntegration { ociRuntime := os.Getenv("OCI_RUNTIME") if ociRuntime == "" { - var err error - ociRuntime, err = exec.LookPath("crun") - // If we cannot find the crun binary, setting to something static as we have no way - // to return an error. The tests will fail and point out that the runc binary could - // not be found nicely. - if err != nil { - ociRuntime = "/usr/bin/runc" - } + ociRuntime = "crun" } os.Setenv("DISABLE_HC_SYSTEMD", "true") CNIConfigDir := "/etc/cni/net.d" @@ -522,6 +515,14 @@ func (s *PodmanSessionIntegration) InspectPodToJSON() define.InspectPodData { return i } +// InspectPodToJSON takes the sessions output from an inspect and returns json +func (s *PodmanSessionIntegration) InspectPodArrToJSON() []define.InspectPodData { + var i []define.InspectPodData + err := jsoniter.Unmarshal(s.Out.Contents(), &i) + Expect(err).To(BeNil()) + return i +} + // CreatePod creates a pod with no infra container // it optionally takes a pod name func (p *PodmanTestIntegration) CreatePod(name string) (*PodmanSessionIntegration, int, string) { @@ -628,6 +629,13 @@ func SkipIfRootless(reason string) { } } +func SkipIfNotRootless(reason string) { + checkReason(reason) + if os.Geteuid() == 0 { + ginkgo.Skip("[notRootless]: " + reason) + } +} + func SkipIfNotFedora() { info := GetHostDistributionInfo() if info.Distribution != "fedora" { @@ -673,3 +681,9 @@ func (p *PodmanTestIntegration) PodmanAsUser(args []string, uid, gid uint32, cwd podmanSession := p.PodmanAsUserBase(args, uid, gid, cwd, env, false, false, nil) return &PodmanSessionIntegration{podmanSession} } + +// We don't support running Varlink when local +func (p *PodmanTestIntegration) RestartRemoteService() { + p.StopRemoteService() + p.StartRemoteService() +} diff --git a/test/e2e/cp_test.go b/test/e2e/cp_test.go index 0a9fa990c..6d349ba5b 100644 --- a/test/e2e/cp_test.go +++ b/test/e2e/cp_test.go @@ -204,6 +204,42 @@ var _ = Describe("Podman cp", func() { os.Remove("file.tar") }) + It("podman cp tar --extract", func() { + testctr := "testctr" + setup := podmanTest.RunTopContainer(testctr) + setup.WaitWithDefaultTimeout() + Expect(setup.ExitCode()).To(Equal(0)) + + session := podmanTest.Podman([]string{"exec", testctr, "mkdir", "/foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + path, err := os.Getwd() + Expect(err).To(BeNil()) + testDirPath := filepath.Join(path, "TestDir4") + err = os.Mkdir(testDirPath, 0777) + Expect(err).To(BeNil()) + defer os.RemoveAll(testDirPath) + f, err := os.Create(filepath.Join(testDirPath, "a.txt")) + Expect(err).To(BeNil()) + _, err = f.Write([]byte("Hello World!!!\n")) + f.Close() + cmd := exec.Command("tar", "-cvf", "file.tar", "TestDir4") + exec.Command("tar", "-cvf", "/home/mvasek/file.tar", testDirPath) + _, err = cmd.Output() + Expect(err).To(BeNil()) + defer os.Remove("file.tar") + + session = podmanTest.Podman([]string{"cp", "--extract", "file.tar", "testctr:/foo/"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"exec", testctr, "cat", "/foo/TestDir4/a.txt"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("Hello World!!!")) + }) + It("podman cp symlink", func() { session := podmanTest.Podman([]string{"run", "-d", ALPINE, "top"}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go index 96a234446..6b0f7a7af 100644 --- a/test/e2e/create_test.go +++ b/test/e2e/create_test.go @@ -626,4 +626,22 @@ var _ = Describe("Podman create", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(BeZero()) }) + + It("podman create -d should fail, can not detach create containers", func() { + session := podmanTest.Podman([]string{"create", "-d", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(125)) + Expect(session.ErrorToString()).To(ContainSubstring("unknown shorthand flag")) + + session = podmanTest.Podman([]string{"create", "--detach", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(125)) + Expect(session.ErrorToString()).To(ContainSubstring("unknown flag")) + + session = podmanTest.Podman([]string{"create", "--detach-keys", "ctrl-x", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(125)) + Expect(session.ErrorToString()).To(ContainSubstring("unknown flag")) + }) + }) diff --git a/test/e2e/events_test.go b/test/e2e/events_test.go index bea8caa93..b37bd584e 100644 --- a/test/e2e/events_test.go +++ b/test/e2e/events_test.go @@ -10,6 +10,7 @@ import ( . "github.com/containers/podman/v2/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" ) var _ = Describe("Podman events", func() { @@ -126,26 +127,31 @@ var _ = Describe("Podman events", func() { SkipIfNotFedora() _, ec, _ := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) + test := podmanTest.Podman([]string{"events", "--stream=false", "--format", "json"}) test.WaitWithDefaultTimeout() - Expect(test.ExitCode()).To(BeZero()) + Expect(test).To(Exit(0)) + jsonArr := test.OutputToStringArray() - Expect(len(jsonArr)).To(Not(BeZero())) + Expect(test.OutputToStringArray()).ShouldNot(BeEmpty()) + eventsMap := make(map[string]string) err := json.Unmarshal([]byte(jsonArr[0]), &eventsMap) - Expect(err).To(BeNil()) - _, exist := eventsMap["Status"] - Expect(exist).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + + Expect(eventsMap).To(HaveKey("Status")) test = podmanTest.Podman([]string{"events", "--stream=false", "--format", "{{json.}}"}) test.WaitWithDefaultTimeout() - Expect(test.ExitCode()).To(BeZero()) + Expect(test).To(Exit(0)) + jsonArr = test.OutputToStringArray() - Expect(len(jsonArr)).To(Not(BeZero())) + Expect(test.OutputToStringArray()).ShouldNot(BeEmpty()) + eventsMap = make(map[string]string) err = json.Unmarshal([]byte(jsonArr[0]), &eventsMap) - Expect(err).To(BeNil()) - _, exist = eventsMap["Status"] - Expect(exist).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + + Expect(eventsMap).To(HaveKey("Status")) }) }) diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go index da2f67754..765844265 100644 --- a/test/e2e/generate_systemd_test.go +++ b/test/e2e/generate_systemd_test.go @@ -244,7 +244,7 @@ var _ = Describe("Podman generate systemd", func() { }) It("podman generate systemd --new with explicit detaching param in middle", func() { - n := podmanTest.Podman([]string{"create", "--name", "foo", "-d", "alpine", "top"}) + n := podmanTest.Podman([]string{"create", "--name", "foo", "alpine", "top"}) n.WaitWithDefaultTimeout() Expect(n.ExitCode()).To(Equal(0)) @@ -253,7 +253,7 @@ var _ = Describe("Podman generate systemd", func() { Expect(session.ExitCode()).To(Equal(0)) // Grepping the output (in addition to unit tests) - found, _ := session.GrepString("--name foo -d alpine top") + found, _ := session.GrepString("--name foo alpine top") Expect(found).To(BeTrue()) }) diff --git a/test/e2e/info_test.go b/test/e2e/info_test.go index 49f5f0ce6..bc4e6212b 100644 --- a/test/e2e/info_test.go +++ b/test/e2e/info_test.go @@ -5,9 +5,9 @@ import ( "io/ioutil" "os" "os/exec" + "os/user" "path/filepath" - "github.com/containers/podman/v2/pkg/rootless" . "github.com/containers/podman/v2/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -78,39 +78,35 @@ var _ = Describe("Podman Info", func() { }) It("podman info rootless storage path", func() { - if !rootless.IsRootless() { - Skip("test of rootless_storage_path is only meaningful as rootless") - } + SkipIfNotRootless("test of rootless_storage_path is only meaningful as rootless") SkipIfRemote("Only tests storage on local client") - oldHOME, hasHOME := os.LookupEnv("HOME") + configPath := filepath.Join(podmanTest.TempDir, ".config", "containers", "storage.conf") + os.Setenv("CONTAINERS_STORAGE_CONF", configPath) defer func() { - if hasHOME { - os.Setenv("HOME", oldHOME) - } else { - os.Unsetenv("HOME") - } + os.Unsetenv("CONTAINERS_STORAGE_CONF") }() - os.Setenv("HOME", podmanTest.TempDir) - configPath := filepath.Join(os.Getenv("HOME"), ".config", "containers", "storage.conf") err := os.RemoveAll(filepath.Dir(configPath)) Expect(err).To(BeNil()) err = os.MkdirAll(filepath.Dir(configPath), os.ModePerm) Expect(err).To(BeNil()) - rootlessStoragePath := `"/tmp/$HOME/$USER/$UID"` + rootlessStoragePath := `"/tmp/$HOME/$USER/$UID/storage"` driver := `"overlay"` storageOpt := `"/usr/bin/fuse-overlayfs"` storageConf := []byte(fmt.Sprintf("[storage]\ndriver=%s\nrootless_storage_path=%s\n[storage.options]\nmount_program=%s", driver, rootlessStoragePath, storageOpt)) err = ioutil.WriteFile(configPath, storageConf, os.ModePerm) Expect(err).To(BeNil()) - expect := filepath.Join("/tmp", os.Getenv("HOME"), os.Getenv("USER"), os.Getenv("UID")) + u, err := user.Current() + Expect(err).To(BeNil()) + + expect := filepath.Join("/tmp", os.Getenv("HOME"), u.Username, u.Uid, "storage") podmanPath := podmanTest.PodmanTest.PodmanBinary cmd := exec.Command(podmanPath, "info", "--format", "{{.Store.GraphRoot}}") out, err := cmd.CombinedOutput() fmt.Println(string(out)) Expect(err).To(BeNil()) - Expect(string(out)).To(ContainSubstring(expect)) + Expect(string(out)).To(Equal(expect)) }) }) diff --git a/test/e2e/init_test.go b/test/e2e/init_test.go index baa5c5717..3e64cfda2 100644 --- a/test/e2e/init_test.go +++ b/test/e2e/init_test.go @@ -45,7 +45,7 @@ var _ = Describe("Podman init", func() { }) It("podman init single container by ID", func() { - session := podmanTest.Podman([]string{"create", "-d", ALPINE, "ls"}) + session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) cid := session.OutputToString() @@ -61,7 +61,7 @@ var _ = Describe("Podman init", func() { It("podman init single container by name", func() { name := "test1" - session := podmanTest.Podman([]string{"create", "--name", name, "-d", ALPINE, "ls"}) + session := podmanTest.Podman([]string{"create", "--name", name, ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) init := podmanTest.Podman([]string{"init", name}) @@ -76,7 +76,7 @@ var _ = Describe("Podman init", func() { It("podman init latest container", func() { SkipIfRemote("--latest flag n/a") - session := podmanTest.Podman([]string{"create", "-d", ALPINE, "ls"}) + session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) init := podmanTest.Podman([]string{"init", "--latest"}) @@ -90,10 +90,10 @@ var _ = Describe("Podman init", func() { }) It("podman init all three containers, one running", func() { - session := podmanTest.Podman([]string{"create", "--name", "test1", "-d", ALPINE, "ls"}) + session := podmanTest.Podman([]string{"create", "--name", "test1", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session2 := podmanTest.Podman([]string{"create", "--name", "test2", "-d", ALPINE, "ls"}) + session2 := podmanTest.Podman([]string{"create", "--name", "test2", ALPINE, "ls"}) session2.WaitWithDefaultTimeout() Expect(session2.ExitCode()).To(Equal(0)) session3 := podmanTest.Podman([]string{"run", "--name", "test3", "-d", ALPINE, "top"}) diff --git a/test/e2e/inspect_test.go b/test/e2e/inspect_test.go index d4de7a65c..e8a82f9a1 100644 --- a/test/e2e/inspect_test.go +++ b/test/e2e/inspect_test.go @@ -289,4 +289,145 @@ var _ = Describe("Podman inspect", func() { Expect(baseJSON[0].HostConfig.SecurityOpt).To(Equal([]string{"label=type:spc_t,label=level:s0", "seccomp=unconfined"})) }) + It("podman inspect pod", func() { + podName := "testpod" + create := podmanTest.PodmanNoCache([]string{"pod", "create", "--name", podName}) + create.WaitWithDefaultTimeout() + Expect(create.ExitCode()).To(Equal(0)) + + inspect := podmanTest.Podman([]string{"inspect", podName}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect.IsJSONOutputValid()).To(BeTrue()) + podData := inspect.InspectPodArrToJSON() + Expect(podData[0].Name).To(Equal(podName)) + }) + + It("podman inspect pod with type", func() { + podName := "testpod" + create := podmanTest.PodmanNoCache([]string{"pod", "create", "--name", podName}) + create.WaitWithDefaultTimeout() + Expect(create.ExitCode()).To(Equal(0)) + + inspect := podmanTest.Podman([]string{"inspect", "--type", "pod", podName}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect.IsJSONOutputValid()).To(BeTrue()) + podData := inspect.InspectPodArrToJSON() + Expect(podData[0].Name).To(Equal(podName)) + }) + + It("podman inspect latest pod", func() { + SkipIfRemote("--latest flag n/a") + podName := "testpod" + create := podmanTest.PodmanNoCache([]string{"pod", "create", "--name", podName}) + create.WaitWithDefaultTimeout() + Expect(create.ExitCode()).To(Equal(0)) + + inspect := podmanTest.Podman([]string{"inspect", "--type", "pod", "--latest"}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect.IsJSONOutputValid()).To(BeTrue()) + podData := inspect.InspectPodArrToJSON() + Expect(podData[0].Name).To(Equal(podName)) + }) + It("podman inspect latest defaults to latest container", func() { + SkipIfRemote("--latest flag n/a") + podName := "testpod" + pod := podmanTest.PodmanNoCache([]string{"pod", "create", "--name", podName}) + pod.WaitWithDefaultTimeout() + Expect(pod.ExitCode()).To(Equal(0)) + + inspect1 := podmanTest.Podman([]string{"inspect", "--type", "pod", podName}) + inspect1.WaitWithDefaultTimeout() + Expect(inspect1.ExitCode()).To(Equal(0)) + Expect(inspect1.IsJSONOutputValid()).To(BeTrue()) + podData := inspect1.InspectPodArrToJSON() + infra := podData[0].Containers[0].Name + + inspect := podmanTest.Podman([]string{"inspect", "--latest"}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect.IsJSONOutputValid()).To(BeTrue()) + containerData := inspect.InspectContainerToJSON() + Expect(containerData[0].Name).To(Equal(infra)) + }) + + It("podman inspect network", func() { + name, path := generateNetworkConfig(podmanTest) + defer removeConf(path) + + session := podmanTest.Podman([]string{"inspect", name, "--format", "{{.cniVersion}}"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.LineInOutputContains("0.3.0")).To(BeTrue()) + }) + + It("podman inspect a volume", func() { + session := podmanTest.Podman([]string{"volume", "create", "myvol"}) + session.WaitWithDefaultTimeout() + volName := session.OutputToString() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"inspect", volName}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.IsJSONOutputValid()).To(BeTrue()) + }) + + It("podman inspect a volume with --format", func() { + session := podmanTest.Podman([]string{"volume", "create", "myvol"}) + session.WaitWithDefaultTimeout() + volName := session.OutputToString() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"inspect", "--format", "{{.Name}}", volName}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(Equal(volName)) + }) + It("podman inspect --type container on a pod should fail", func() { + podName := "testpod" + create := podmanTest.PodmanNoCache([]string{"pod", "create", "--name", podName}) + create.WaitWithDefaultTimeout() + Expect(create.ExitCode()).To(Equal(0)) + + inspect := podmanTest.Podman([]string{"inspect", "--type", "container", podName}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).To(ExitWithError()) + }) + + It("podman inspect --type network on a container should fail", func() { + ctrName := "testctr" + create := podmanTest.PodmanNoCache([]string{"create", "--name", ctrName, ALPINE}) + create.WaitWithDefaultTimeout() + Expect(create.ExitCode()).To(Equal(0)) + + inspect := podmanTest.Podman([]string{"inspect", "--type", "network", ctrName}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).To(ExitWithError()) + }) + + It("podman inspect --type pod on a container should fail", func() { + ctrName := "testctr" + create := podmanTest.PodmanNoCache([]string{"create", "--name", ctrName, ALPINE}) + create.WaitWithDefaultTimeout() + Expect(create.ExitCode()).To(Equal(0)) + + inspect := podmanTest.Podman([]string{"inspect", "--type", "pod", ctrName}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).To(ExitWithError()) + }) + + It("podman inspect --type volume on a container should fail", func() { + ctrName := "testctr" + create := podmanTest.PodmanNoCache([]string{"create", "--name", ctrName, ALPINE}) + create.WaitWithDefaultTimeout() + Expect(create.ExitCode()).To(Equal(0)) + + inspect := podmanTest.Podman([]string{"inspect", "--type", "volume", ctrName}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).To(ExitWithError()) + }) + }) diff --git a/test/e2e/logs_test.go b/test/e2e/logs_test.go index 664d4831e..4214bd50e 100644 --- a/test/e2e/logs_test.go +++ b/test/e2e/logs_test.go @@ -148,7 +148,7 @@ var _ = Describe("Podman logs", func() { }) It("podman logs on a created container should result in 0 exit code", func() { - session := podmanTest.Podman([]string{"create", "-dt", "--name", "log", ALPINE}) + session := podmanTest.Podman([]string{"create", "-t", "--name", "log", ALPINE}) session.WaitWithDefaultTimeout() Expect(session).To(Exit(0)) diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index 3906fa49d..7ab8dc6f8 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -1447,4 +1447,23 @@ MemoryReservation: {{ .HostConfig.MemoryReservation }}`}) Expect(inspect.OutputToString()).To(ContainSubstring("Memory: " + expectedMemoryLimit)) } }) + + It("podman play kube reports invalid image name", func() { + invalidImageName := "./myimage" + + pod := getPod( + withCtr( + getCtr( + withImage(invalidImageName), + ), + ), + ) + err := generateKubeYaml("pod", pod, kubeYaml) + Expect(err).To(BeNil()) + + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube.ExitCode()).To(Equal(125)) + Expect(kube.ErrorToString()).To(ContainSubstring(invalidImageName)) + }) }) diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go index f69b6ca7b..95870788e 100644 --- a/test/e2e/pod_create_test.go +++ b/test/e2e/pod_create_test.go @@ -245,6 +245,24 @@ var _ = Describe("Podman pod create", func() { } }) + It("podman container in pod with IP address shares IP address", func() { + SkipIfRootless("Rootless does not support --ip") + podName := "test" + ctrName := "testCtr" + ip := GetRandomIPAddress() + podCreate := podmanTest.Podman([]string{"pod", "create", "--ip", ip, "--name", podName}) + podCreate.WaitWithDefaultTimeout() + Expect(podCreate.ExitCode()).To(Equal(0)) + podCtr := podmanTest.Podman([]string{"run", "--name", ctrName, "--pod", podName, "-d", "-t", ALPINE, "top"}) + podCtr.WaitWithDefaultTimeout() + Expect(podCtr.ExitCode()).To(Equal(0)) + ctrInspect := podmanTest.Podman([]string{"inspect", ctrName}) + ctrInspect.WaitWithDefaultTimeout() + Expect(ctrInspect.ExitCode()).To(Equal(0)) + ctrJSON := ctrInspect.InspectContainerToJSON() + Expect(ctrJSON[0].NetworkSettings.IPAddress).To(Equal(ip)) + }) + It("podman create pod with IP address and no infra should fail", func() { name := "test" ip := GetRandomIPAddress() @@ -428,4 +446,34 @@ entrypoint ["/fromimage"] Expect(check.ExitCode()).To(Equal(0)) Expect(check.OutputToString()).To(Equal("[port_handler=slirp4netns]")) }) + + It("podman pod status test", func() { + podName := "testpod" + create := podmanTest.Podman([]string{"pod", "create", "--name", podName}) + create.WaitWithDefaultTimeout() + Expect(create.ExitCode()).To(Equal(0)) + + status1 := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{ .State }}", podName}) + status1.WaitWithDefaultTimeout() + Expect(status1.ExitCode()).To(Equal(0)) + Expect(strings.Contains(status1.OutputToString(), "Created")).To(BeTrue()) + + ctr1 := podmanTest.Podman([]string{"run", "--pod", podName, "-d", ALPINE, "top"}) + ctr1.WaitWithDefaultTimeout() + Expect(ctr1.ExitCode()).To(Equal(0)) + + status2 := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{ .State }}", podName}) + status2.WaitWithDefaultTimeout() + Expect(status2.ExitCode()).To(Equal(0)) + Expect(strings.Contains(status2.OutputToString(), "Running")).To(BeTrue()) + + ctr2 := podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"}) + ctr2.WaitWithDefaultTimeout() + Expect(ctr2.ExitCode()).To(Equal(0)) + + status3 := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{ .State }}", podName}) + status3.WaitWithDefaultTimeout() + Expect(status3.ExitCode()).To(Equal(0)) + Expect(strings.Contains(status3.OutputToString(), "Degraded")).To(BeTrue()) + }) }) diff --git a/test/e2e/pod_rm_test.go b/test/e2e/pod_rm_test.go index 24643e6b2..24e945d5a 100644 --- a/test/e2e/pod_rm_test.go +++ b/test/e2e/pod_rm_test.go @@ -167,7 +167,7 @@ var _ = Describe("Podman pod rm", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"create", "-d", "--pod", podid1, ALPINE, "ls"}) + session = podmanTest.Podman([]string{"create", "--pod", podid1, ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go index 48ef566ce..11d0b8c9b 100644 --- a/test/e2e/ps_test.go +++ b/test/e2e/ps_test.go @@ -324,7 +324,7 @@ var _ = Describe("Podman ps", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"create", "-dt", ALPINE, "top"}) + session = podmanTest.Podman([]string{"create", "-t", ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -411,18 +411,43 @@ var _ = Describe("Podman ps", func() { Expect(output).To(ContainSubstring(podName)) }) - It("podman ps test with port range", func() { - session := podmanTest.RunTopContainer("") + It("podman ps test with single port range", func() { + session := podmanTest.Podman([]string{"run", "-dt", "-p", "2000-2006:2000-2006", ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"run", "-dt", "-p", "2000-2006:2000-2006", ALPINE, "top"}) + session = podmanTest.Podman([]string{"ps", "--format", "{{.Ports}}"}) + session.WaitWithDefaultTimeout() + Expect(session.OutputToString()).To(ContainSubstring("0.0.0.0:2000-2006")) + }) + + It("podman ps test with invalid port range", func() { + session := podmanTest.Podman([]string{ + "run", "-p", "1000-2000:2000-3000", "-p", "1999-2999:3001-4001", ALPINE, + }) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(125)) + Expect(session.ErrorToString()).To(ContainSubstring("conflicting port mappings for host port 1999")) + }) + + It("podman ps test with multiple port range", func() { + session := podmanTest.Podman([]string{ + "run", "-dt", + "-p", "3000-3001:3000-3001", + "-p", "3100-3102:4000-4002", + "-p", "30080:30080", + "-p", "30443:30443", + "-p", "8000:8080", + ALPINE, "top"}, + ) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"ps", "--format", "{{.Ports}}"}) session.WaitWithDefaultTimeout() - Expect(session.OutputToString()).To(ContainSubstring("0.0.0.0:2000-2006")) + Expect(session.OutputToString()).To(ContainSubstring( + "0.0.0.0:3000-3001->3000-3001/tcp, 0.0.0.0:3100-3102->4000-4002/tcp, 0.0.0.0:8000->8080/tcp, 0.0.0.0:30080->30080/tcp, 0.0.0.0:30443->30443/tcp", + )) }) It("podman ps sync flag", func() { diff --git a/test/e2e/restart_test.go b/test/e2e/restart_test.go index 789b4dee5..114bd481a 100644 --- a/test/e2e/restart_test.go +++ b/test/e2e/restart_test.go @@ -54,7 +54,7 @@ var _ = Describe("Podman restart", func() { }) It("Podman restart stopped container by ID", func() { - session := podmanTest.Podman([]string{"create", "-d", ALPINE, "ls"}) + session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) cid := session.OutputToString() diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index e14482db7..9f6fd8602 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -357,7 +357,7 @@ var _ = Describe("Podman run networking", func() { }) It("podman run network expose ports in image metadata", func() { - session := podmanTest.Podman([]string{"create", "--name", "test", "-dt", "-P", nginx}) + session := podmanTest.Podman([]string{"create", "--name", "test", "-t", "-P", nginx}) session.Wait(90) Expect(session.ExitCode()).To(Equal(0)) results := podmanTest.Podman([]string{"inspect", "test"}) @@ -571,4 +571,27 @@ var _ = Describe("Podman run networking", func() { podrm.WaitWithDefaultTimeout() Expect(podrm.ExitCode()).To(BeZero()) }) + + It("podman run net=host adds entry to /etc/hosts", func() { + run := podmanTest.Podman([]string{"run", "--net=host", ALPINE, "cat", "/etc/hosts"}) + run.WaitWithDefaultTimeout() + Expect(run.ExitCode()).To(BeZero()) + Expect(strings.Contains(run.OutputToString(), "127.0.1.1")).To(BeTrue()) + }) + + It("podman run with --net=host and --hostname sets correct hostname", func() { + hostname := "testctr" + run := podmanTest.Podman([]string{"run", "--net=host", "--hostname", hostname, ALPINE, "hostname"}) + run.WaitWithDefaultTimeout() + Expect(run.ExitCode()).To(BeZero()) + Expect(strings.Contains(run.OutputToString(), hostname)).To(BeTrue()) + }) + + It("podman run with --net=none adds hostname to /etc/hosts", func() { + hostname := "testctr" + run := podmanTest.Podman([]string{"run", "--net=none", "--hostname", hostname, ALPINE, "hostname"}) + run.WaitWithDefaultTimeout() + Expect(run.ExitCode()).To(BeZero()) + Expect(strings.Contains(run.OutputToString(), hostname)).To(BeTrue()) + }) }) diff --git a/test/e2e/run_security_labels.go b/test/e2e/run_security_labels.go index 2a0b0467d..0c5621e3f 100644 --- a/test/e2e/run_security_labels.go +++ b/test/e2e/run_security_labels.go @@ -94,7 +94,7 @@ var _ = Describe("Podman generate kube", func() { test1.WaitWithDefaultTimeout() Expect(test1.ExitCode()).To(BeZero()) - commit := podmanTest.Podman([]string{"commit", "-c", "label=io.containers.capabilities=sys_chroot,net_raw", "test1", "image1"}) + commit := podmanTest.Podman([]string{"commit", "-c", "label=io.containers.capabilities=sys_chroot,setuid", "test1", "image1"}) commit.WaitWithDefaultTimeout() Expect(commit.ExitCode()).To(BeZero()) @@ -108,7 +108,7 @@ var _ = Describe("Podman generate kube", func() { ctr := inspect.InspectContainerToJSON() caps := strings.Join(ctr[0].EffectiveCaps, ",") - Expect(caps).To(Equal("CAP_SYS_CHROOT,CAP_NET_RAW")) + Expect(caps).To(Equal("CAP_SYS_CHROOT,CAP_SETUID")) }) diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go index 92d3418e3..1c8a67123 100644 --- a/test/e2e/run_volume_test.go +++ b/test/e2e/run_volume_test.go @@ -489,7 +489,7 @@ VOLUME /test/` Expect(err).To(Not(BeNil())) // Make sure modifications in container disappear when container is stopped - session = podmanTest.Podman([]string{"create", "-d", "-v", fmt.Sprintf("%s:/run/test:O", mountPath), ALPINE, "top"}) + session = podmanTest.Podman([]string{"create", "-v", fmt.Sprintf("%s:/run/test:O", mountPath), ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"start", "-l"}) diff --git a/test/e2e/runlabel_test.go b/test/e2e/runlabel_test.go index 81a746b86..7c0b8bc9b 100644 --- a/test/e2e/runlabel_test.go +++ b/test/e2e/runlabel_test.go @@ -88,12 +88,15 @@ var _ = Describe("podman container runlabel", func() { result := podmanTest.Podman([]string{"container", "runlabel", "RUN", ALPINE}) result.WaitWithDefaultTimeout() Expect(result).To(ExitWithError()) + // should not panic when label missing the value or don't have the label + Expect(result.LineInOutputContains("panic")).NotTo(BeTrue()) }) It("podman container runlabel bogus label in remote image should result in non-zero exit", func() { result := podmanTest.Podman([]string{"container", "runlabel", "RUN", "docker.io/library/ubuntu:latest"}) result.WaitWithDefaultTimeout() Expect(result).To(ExitWithError()) - + // should not panic when label missing the value or don't have the label + Expect(result.LineInOutputContains("panic")).NotTo(BeTrue()) }) It("podman container runlabel global options", func() { diff --git a/test/e2e/save_test.go b/test/e2e/save_test.go index 1f1258be3..79fc4d737 100644 --- a/test/e2e/save_test.go +++ b/test/e2e/save_test.go @@ -1,8 +1,12 @@ package integration import ( + "io/ioutil" "os" + "os/exec" "path/filepath" + "strconv" + "strings" "github.com/containers/podman/v2/pkg/rootless" . "github.com/containers/podman/v2/test/utils" @@ -116,6 +120,71 @@ var _ = Describe("Podman save", func() { Expect(save).To(ExitWithError()) }) + It("podman save remove signature", func() { + SkipIfRootless("FIXME: Need get in rootless push sign") + if podmanTest.Host.Arch == "ppc64le" { + Skip("No registry image for ppc64le") + } + tempGNUPGHOME := filepath.Join(podmanTest.TempDir, "tmpGPG") + err := os.Mkdir(tempGNUPGHOME, os.ModePerm) + Expect(err).To(BeNil()) + origGNUPGHOME := os.Getenv("GNUPGHOME") + err = os.Setenv("GNUPGHOME", tempGNUPGHOME) + Expect(err).To(BeNil()) + defer os.Setenv("GNUPGHOME", origGNUPGHOME) + + port := 5000 + session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", strings.Join([]string{strconv.Itoa(port), strconv.Itoa(port)}, ":"), "docker.io/registry:2.6"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) { + Skip("Cannot start docker registry.") + } + + cmd := exec.Command("gpg", "--import", "sign/secret-key.asc") + err = cmd.Run() + Expect(err).To(BeNil()) + + cmd = exec.Command("cp", "/etc/containers/registries.d/default.yaml", "default.yaml") + if err = cmd.Run(); err != nil { + Skip("no signature store to verify") + } + defer func() { + cmd = exec.Command("cp", "default.yaml", "/etc/containers/registries.d/default.yaml") + cmd.Run() + }() + + cmd = exec.Command("cp", "sign/key.gpg", "/tmp/key.gpg") + Expect(cmd.Run()).To(BeNil()) + sigstore := ` +default-docker: + sigstore: file:///var/lib/containers/sigstore + sigstore-staging: file:///var/lib/containers/sigstore +` + Expect(ioutil.WriteFile("/etc/containers/registries.d/default.yaml", []byte(sigstore), 0755)).To(BeNil()) + + session = podmanTest.Podman([]string{"tag", ALPINE, "localhost:5000/alpine"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"push", "--tls-verify=false", "--sign-by", "foo@bar.com", "localhost:5000/alpine"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"rmi", ALPINE, "localhost:5000/alpine"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"pull", "--tls-verify=false", "--signature-policy=sign/policy.json", "localhost:5000/alpine"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + outfile := filepath.Join(podmanTest.TempDir, "temp.tar") + save := podmanTest.Podman([]string{"save", "remove-signatures=true", "-o", outfile, "localhost:5000/alpine"}) + save.WaitWithDefaultTimeout() + Expect(save).To(ExitWithError()) + }) + It("podman save image with digest reference", func() { // pull a digest reference session := podmanTest.PodmanNoCache([]string{"pull", ALPINELISTDIGEST}) diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go index 0cf005529..4f2751099 100644 --- a/test/e2e/search_test.go +++ b/test/e2e/search_test.go @@ -237,7 +237,6 @@ registries = ['{{.Host}}:{{.Port}}']` }) It("podman search attempts HTTP if registry is in registries.insecure and force secure is false", func() { - SkipIfRemote("--tls-verify is not supported on podman-remote search") if podmanTest.Host.Arch == "ppc64le" { Skip("No registry image for ppc64le") } @@ -264,6 +263,10 @@ registries = ['{{.Host}}:{{.Port}}']` registryFileTmpl.Execute(&buffer, registryEndpoints[4]) podmanTest.setRegistriesConfigEnv(buffer.Bytes()) ioutil.WriteFile(fmt.Sprintf("%s/registry4.conf", tempdir), buffer.Bytes(), 0644) + if IsRemote() { + podmanTest.RestartRemoteService() + defer podmanTest.RestartRemoteService() + } search := podmanTest.PodmanNoCache([]string{"search", image}) search.WaitWithDefaultTimeout() @@ -278,7 +281,7 @@ registries = ['{{.Host}}:{{.Port}}']` }) It("podman search doesn't attempt HTTP if force secure is true", func() { - SkipIfRemote("--tls-verify is not supported on podman-remote search") + SkipIfRemote("FIXME This should work on podman-remote") if podmanTest.Host.Arch == "ppc64le" { Skip("No registry image for ppc64le") } @@ -303,6 +306,10 @@ registries = ['{{.Host}}:{{.Port}}']` registryFileTmpl.Execute(&buffer, registryEndpoints[5]) podmanTest.setRegistriesConfigEnv(buffer.Bytes()) ioutil.WriteFile(fmt.Sprintf("%s/registry5.conf", tempdir), buffer.Bytes(), 0644) + if IsRemote() { + podmanTest.RestartRemoteService() + defer podmanTest.RestartRemoteService() + } search := podmanTest.PodmanNoCache([]string{"search", image, "--tls-verify=true"}) search.WaitWithDefaultTimeout() @@ -317,7 +324,7 @@ registries = ['{{.Host}}:{{.Port}}']` }) It("podman search doesn't attempt HTTP if registry is not listed as insecure", func() { - SkipIfRemote("--tls-verify is not supported on podman-remote search") + SkipIfRemote("FIXME This should work on podman-remote") if podmanTest.Host.Arch == "ppc64le" { Skip("No registry image for ppc64le") } @@ -343,6 +350,11 @@ registries = ['{{.Host}}:{{.Port}}']` podmanTest.setRegistriesConfigEnv(buffer.Bytes()) ioutil.WriteFile(fmt.Sprintf("%s/registry6.conf", tempdir), buffer.Bytes(), 0644) + if IsRemote() { + podmanTest.RestartRemoteService() + defer podmanTest.RestartRemoteService() + } + search := podmanTest.PodmanNoCache([]string{"search", image}) search.WaitWithDefaultTimeout() @@ -393,6 +405,11 @@ registries = ['{{.Host}}:{{.Port}}']` podmanTest.setRegistriesConfigEnv(buffer.Bytes()) ioutil.WriteFile(fmt.Sprintf("%s/registry8.conf", tempdir), buffer.Bytes(), 0644) + if IsRemote() { + podmanTest.RestartRemoteService() + defer podmanTest.RestartRemoteService() + } + search := podmanTest.PodmanNoCache([]string{"search", "my-alpine"}) search.WaitWithDefaultTimeout() diff --git a/test/e2e/sign/key.gpg b/test/e2e/sign/key.gpg new file mode 100644 index 000000000..32968fc04 --- /dev/null +++ b/test/e2e/sign/key.gpg @@ -0,0 +1,30 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQENBF8kNqwBCAC0x3Kog+WlDNwcR6rWIP8Gj2T6LrQ2/3knSyAWzTgC/OBB6Oh0 +KAokXLjy8J3diG3EaSltE7erGG/bZCz8jYvMiwDJScON4zzidotqjoY80E+NeRDg +CC0gqvqmh0ftJIjYNBHzSxqrGRQwzwZU+u6ezlE8+0dvsHcHY+MRnxXJQrdM07EP +Prp85kKckChDlJ1tyGUB/YHieFQmOW5+TERA7ZqQOAQ12Vviv6V4kNfEJJq3MS2c +csZpO323tcHt3oebqsZCIElhX7uVw6GAeCw1tm4NZXs4g1yIC21Of/hzPeC18F72 +splCgKaAOiE9w/nMGLNEYy2NzgEclZLs2Y7jABEBAAG0FGZvb2JhciA8Zm9vQGJh +ci5jb20+iQFUBBMBCAA+FiEERyT4ac7LLibByeabqaoHAy6P2bIFAl8kNqwCGwMF +CQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQqaoHAy6P2bKtuggAgv54 +/F8wgi+uMrtFr8rqNtZMDyXRxfXaXUy5uGNfqHD83yqxweEqxiA8lmFkRHixPWtg +Z2MniFXMVc9kVmg8GNIIuzewXrPqtXztvuURQo9phK68v8fXEqqT6K25wtq8TiQZ +0J3mQIJPPTMe3pCCOyR6+W3iMtQp2AmitxKbzLP3J3GG2i0rG5S147A2rPnzTeMY +hds819+JE7jNMD7FkV+TcQlOVl4wyOQhNEJcjb6rA6EUe5+s85pIFTBSyPMJpJ03 +Y0dLdcSGpKdncGTK2X9+hS96G1+FP/t8hRIDblqUHtBRXe3Ozz6zSqpqu1DbAQSM +bIrLYxXfnZEN+ro0dLkBDQRfJDasAQgAncvLLZUHZkJWDPka3ocysJ7+/lmrXyAj +T3D4r7UM4oaLBOMKjvaKSDw1uW5qYmTxnnsqFDI0O5+XJxD1/0qEf6l2oUpnILdx +Vruf28FuvymbsyhDgs+MBoHz0jLWWPHUW2oWLIqcvaF0BePQ1GS6UoZlmZejsLww +cSpbaAHJng7An/iLuqOBr5EdUA5XMXqmdMFDrjh0uZezImJ2Eacu/hshBdu3IY49 +J5XP18GWrSdUnP27cv3tOii9j5Lfl8QAvCN89vkALIU3eZtnMlWZqLgl5o6COVFm +zpyx+iHOoCznQBt0aGoSNmE/dAqWIQS/xCSFqMHI6kNd9N0oR0rEHwARAQABiQE8 +BBgBCAAmFiEERyT4ac7LLibByeabqaoHAy6P2bIFAl8kNqwCGwwFCQPCZwAACgkQ +qaoHAy6P2bJfjQgAje6YR+p1QaNlTN9l4t2kGzy9RhkfYMrTgI2fEqbS9bFJUy3Y +3mH+vj/r2gN/kaN8LHH4K1d7fAohBsFqSI0flzHHIx2rfti9zAlbXcAErbnG+f0f +k0AaqU7KelU35vjPfNe6Vn7ky6G9CC6jW04NkLZDNFA2GusdYf1aM0LWew5t4WZa +quLVFhL36q9eHaogO/fcPR/quvQefHokk+b541ytwMN9l/g43rTbCvAjrUDHwipb +Gbw91Wg2XjbecRiCXDKWds2M149BpxUzY5xHFtD5t5WSEE/SkkryGTMmTxS3tuQZ +9PdtCPGrNDO6Ts/amORF04Tf+YMJgfv3IWxMeQ== +=y0uZ +-----END PGP PUBLIC KEY BLOCK----- diff --git a/test/e2e/sign/policy.json b/test/e2e/sign/policy.json new file mode 100644 index 000000000..ab01137bf --- /dev/null +++ b/test/e2e/sign/policy.json @@ -0,0 +1,18 @@ +{ + "default": [ + { + "type": "insecureAcceptAnything" + } + ], + "transports": { + "docker": { + "localhost:5000": [ + { + "type": "signedBy", + "keyType": "GPGKeys", + "keyPath": "/tmp/key.gpg" + } + ] + } + } +} diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go index 35b5cab6e..942e00123 100644 --- a/test/e2e/start_test.go +++ b/test/e2e/start_test.go @@ -40,7 +40,7 @@ var _ = Describe("Podman start", func() { }) It("podman start single container by id", func() { - session := podmanTest.Podman([]string{"create", "-d", ALPINE, "ls"}) + session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) cid := session.OutputToString() @@ -50,7 +50,7 @@ var _ = Describe("Podman start", func() { }) It("podman container start single container by id", func() { - session := podmanTest.Podman([]string{"container", "create", "-d", ALPINE, "ls"}) + session := podmanTest.Podman([]string{"container", "create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) cid := session.OutputToString() @@ -61,7 +61,7 @@ var _ = Describe("Podman start", func() { }) It("podman container start single container by short id", func() { - session := podmanTest.Podman([]string{"container", "create", "-d", ALPINE, "ls"}) + session := podmanTest.Podman([]string{"container", "create", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) cid := session.OutputToString() @@ -74,7 +74,7 @@ var _ = Describe("Podman start", func() { It("podman start single container by name", func() { name := "foobar99" - session := podmanTest.Podman([]string{"create", "-d", "--name", name, ALPINE, "ls"}) + session := podmanTest.Podman([]string{"create", "--name", name, ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"start", name}) @@ -98,10 +98,10 @@ var _ = Describe("Podman start", func() { }) It("podman start multiple containers", func() { - session := podmanTest.Podman([]string{"create", "-d", "--name", "foobar99", ALPINE, "ls"}) + session := podmanTest.Podman([]string{"create", "--name", "foobar99", ALPINE, "ls"}) session.WaitWithDefaultTimeout() cid1 := session.OutputToString() - session2 := podmanTest.Podman([]string{"create", "-d", "--name", "foobar100", ALPINE, "ls"}) + session2 := podmanTest.Podman([]string{"create", "--name", "foobar100", ALPINE, "ls"}) session2.WaitWithDefaultTimeout() cid2 := session2.OutputToString() session = podmanTest.Podman([]string{"start", cid1, cid2}) @@ -110,7 +110,7 @@ var _ = Describe("Podman start", func() { }) It("podman start multiple containers with bogus", func() { - session := podmanTest.Podman([]string{"create", "-d", "--name", "foobar99", ALPINE, "ls"}) + session := podmanTest.Podman([]string{"create", "--name", "foobar99", ALPINE, "ls"}) session.WaitWithDefaultTimeout() cid1 := session.OutputToString() session = podmanTest.Podman([]string{"start", cid1, "doesnotexist"}) diff --git a/test/e2e/stop_test.go b/test/e2e/stop_test.go index 1437fd066..c25709a63 100644 --- a/test/e2e/stop_test.go +++ b/test/e2e/stop_test.go @@ -242,7 +242,7 @@ var _ = Describe("Podman stop", func() { defer os.RemoveAll(tmpDir) - session := podmanTest.Podman([]string{"create", "--cidfile", tmpFile, "-d", ALPINE, "top"}) + session := podmanTest.Podman([]string{"create", "--cidfile", tmpFile, ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) cid := session.OutputToStringArray()[0] diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go index 9e717a0eb..218c250cd 100644 --- a/test/e2e/systemd_test.go +++ b/test/e2e/systemd_test.go @@ -59,7 +59,7 @@ WantedBy=multi-user.target Expect(stop.ExitCode()).To(Equal(0)) }() - create := podmanTest.Podman([]string{"create", "-d", "--name", "redis", "redis"}) + create := podmanTest.Podman([]string{"create", "--name", "redis", "redis"}) create.WaitWithDefaultTimeout() Expect(create.ExitCode()).To(Equal(0)) diff --git a/test/e2e/toolbox_test.go b/test/e2e/toolbox_test.go index 6122cee19..fbff8d19e 100644 --- a/test/e2e/toolbox_test.go +++ b/test/e2e/toolbox_test.go @@ -222,7 +222,7 @@ var _ = Describe("Toolbox-specific testing", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - Expect(WaitContainerReady(podmanTest, "test", "READY", 2, 1)).To(BeTrue()) + Expect(WaitContainerReady(podmanTest, "test", "READY", 5, 1)).To(BeTrue()) expectedOutput := fmt.Sprintf("%s:x:%s:%s::%s:%s", username, uid, gid, homeDir, shell) @@ -257,7 +257,7 @@ var _ = Describe("Toolbox-specific testing", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - Expect(WaitContainerReady(podmanTest, "test", "READY", 2, 1)).To(BeTrue()) + Expect(WaitContainerReady(podmanTest, "test", "READY", 5, 1)).To(BeTrue()) session = podmanTest.Podman([]string{"exec", "test", "cat", "/etc/group"}) session.WaitWithDefaultTimeout() @@ -301,7 +301,7 @@ var _ = Describe("Toolbox-specific testing", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - Expect(WaitContainerReady(podmanTest, "test", "READY", 2, 1)).To(BeTrue()) + Expect(WaitContainerReady(podmanTest, "test", "READY", 5, 1)).To(BeTrue()) expectedUser := fmt.Sprintf("%s:x:%s:%s::%s:%s", username, uid, gid, homeDir, shell) @@ -358,11 +358,23 @@ var _ = Describe("Toolbox-specific testing", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - Expect(WaitContainerReady(podmanTest, "test", "READY", 2, 1)).To(BeTrue()) + Expect(WaitContainerReady(podmanTest, "test", "READY", 5, 1)).To(BeTrue()) session = podmanTest.Podman([]string{"logs", "test"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring("READY")) }) + + It("podman run --userns=keep-id check $HOME", func() { + var session *PodmanSessionIntegration + + currentUser, err := user.Current() + Expect(err).To(BeNil()) + session = podmanTest.Podman([]string{"run", "-v", fmt.Sprintf("%s:%s", currentUser.HomeDir, currentUser.HomeDir), "--userns=keep-id", fedoraToolbox, "sh", "-c", "echo $HOME"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(currentUser.HomeDir)) + }) + }) diff --git a/test/e2e/trust_test.go b/test/e2e/trust_test.go index 82b0f9f26..987023e4c 100644 --- a/test/e2e/trust_test.go +++ b/test/e2e/trust_test.go @@ -74,4 +74,26 @@ var _ = Describe("Podman trust", func() { } Expect(teststruct["default"][0]["type"]).To(Equal("insecureAcceptAnything")) }) + + It("podman image trust show --json", func() { + session := podmanTest.Podman([]string{"image", "trust", "show", "--json"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.IsJSONOutputValid()).To(BeTrue()) + var teststruct []map[string]string + json.Unmarshal(session.Out.Contents(), &teststruct) + Expect(teststruct[0]["name"]).To(Equal("* (default)")) + Expect(teststruct[0]["repo_name"]).To(Equal("default")) + Expect(teststruct[0]["type"]).To(Equal("accept")) + Expect(teststruct[1]["type"]).To(Equal("insecureAcceptAnything")) + }) + + It("podman image trust show --raw", func() { + session := podmanTest.Podman([]string{"image", "trust", "show", "--raw"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.IsJSONOutputValid()).To(BeTrue()) + Expect(session.OutputToString()).To(ContainSubstring("default")) + Expect(session.OutputToString()).To(ContainSubstring("insecureAcceptAnything")) + }) }) diff --git a/test/e2e/wait_test.go b/test/e2e/wait_test.go index 4f0129a47..aa8a1f245 100644 --- a/test/e2e/wait_test.go +++ b/test/e2e/wait_test.go @@ -46,6 +46,7 @@ var _ = Describe("Podman wait", func() { Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"wait", cid}) session.Wait() + Expect(session.ExitCode()).To(Equal(0)) }) It("podman wait on a sleeping container", func() { @@ -55,22 +56,60 @@ var _ = Describe("Podman wait", func() { Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"wait", cid}) session.Wait(20) + Expect(session.ExitCode()).To(Equal(0)) }) It("podman wait on latest container", func() { session := podmanTest.Podman([]string{"run", "-d", ALPINE, "sleep", "1"}) session.Wait(20) Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"wait", "-l"}) - session.Wait(20) + if IsRemote() { + session = podmanTest.Podman([]string{"wait", session.OutputToString()}) + } else { + session = podmanTest.Podman([]string{"wait", "-l"}) + } + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) }) It("podman container wait on latest container", func() { session := podmanTest.Podman([]string{"container", "run", "-d", ALPINE, "sleep", "1"}) session.Wait(20) Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"container", "wait", "-l"}) + if IsRemote() { + session = podmanTest.Podman([]string{"container", "wait", session.OutputToString()}) + } else { + session = podmanTest.Podman([]string{"container", "wait", "-l"}) + } + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + }) + + It("podman container wait on latest container with --interval flag", func() { + session := podmanTest.Podman([]string{"container", "run", "-d", ALPINE, "sleep", "1"}) session.Wait(20) + Expect(session.ExitCode()).To(Equal(0)) + session = podmanTest.Podman([]string{"container", "wait", "-i", "5000", session.OutputToString()}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + }) + + It("podman container wait on latest container with --interval flag", func() { + session := podmanTest.Podman([]string{"container", "run", "-d", ALPINE, "sleep", "1"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session = podmanTest.Podman([]string{"container", "wait", "--interval", "1s", session.OutputToString()}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + }) + + It("podman container wait on container with bogus --interval", func() { + session := podmanTest.Podman([]string{"container", "run", "-d", ALPINE, "sleep", "1"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session = podmanTest.Podman([]string{"container", "wait", "--interval", "100days", session.OutputToString()}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(125)) }) It("podman wait on three containers", func() { diff --git a/test/endpoint/setup.go b/test/endpoint/setup.go index 56cab06b0..6bbc8d2bc 100644 --- a/test/endpoint/setup.go +++ b/test/endpoint/setup.go @@ -51,14 +51,7 @@ func Setup(tempDir string) *EndpointTestIntegration { ociRuntime := os.Getenv("OCI_RUNTIME") if ociRuntime == "" { - var err error - ociRuntime, err = exec.LookPath("runc") - // If we cannot find the runc binary, setting to something static as we have no way - // to return an error. The tests will fail and point out that the runc binary could - // not be found nicely. - if err != nil { - ociRuntime = "/usr/bin/runc" - } + ociRuntime = "runc" } os.Setenv("DISABLE_HC_SYSTEMD", "true") CNIConfigDir := "/etc/cni/net.d" diff --git a/test/system/015-help.bats b/test/system/015-help.bats index 651fdcd09..22db8be8a 100644 --- a/test/system/015-help.bats +++ b/test/system/015-help.bats @@ -6,7 +6,7 @@ # provides its own --help output. If the usage message ends in '[command]', # treat it as a subcommand, and recurse into its own list of sub-subcommands. # -# Any usage message that ends in '[flags]' is interpreted as a command +# Any usage message that ends in '[options]' is interpreted as a command # that takes no further arguments; we confirm by running with 'invalid-arg' # and confirming that it exits with error status and message. # @@ -17,7 +17,7 @@ load helpers function podman_commands() { dprint "$@" run_podman help "$@" |\ - awk '/^Available Commands:/{ok=1;next}/^Flags:/{ok=0}ok { print $1 }' |\ + awk '/^Available Commands:/{ok=1;next}/^Options:/{ok=0}ok { print $1 }' |\ grep . "$output" } @@ -42,7 +42,7 @@ function check_help() { # e.g. 'podman ps' should not show 'podman container ps' in usage # Trailing space in usage handles 'podman system renumber' which - # has no ' [flags]' + # has no ' [options]' is "$usage " " $command_string .*" "Usage string matches command" # If usage ends in '[command]', recurse into subcommands @@ -52,25 +52,25 @@ function check_help() { continue fi - # We had someone write upper-case '[FLAGS]' once. Prevent it. - if expr "$usage" : '.*\[FLAG' >/dev/null; then - die "'flags' string must be lower-case in usage: $usage" + # We had someone write upper-case '[OPTIONS]' once. Prevent it. + if expr "$usage" : '.*\[OPTION' >/dev/null; then + die "'options' string must be lower-case in usage: $usage" fi - # We had someone do 'podman foo ARG [flags]' one time. Yeah, no. - if expr "$usage" : '.*[A-Z].*\[flag' >/dev/null; then - die "'flags' must precede arguments in usage: $usage" + # We had someone do 'podman foo ARG [options]' one time. Yeah, no. + if expr "$usage" : '.*[A-Z].*\[option' >/dev/null; then + die "'options' must precede arguments in usage: $usage" fi - # Cross-check: if usage includes '[flags]', there must be a - # longer 'Flags:' section in the full --help output; vice-versa, - # if 'Flags:' is in full output, usage line must have '[flags]'. - if expr "$usage" : '.*\[flag' >/dev/null; then - if ! expr "$full_help" : ".*Flags:" >/dev/null; then - die "$command_string: Usage includes '[flags]' but has no 'Flags:' subsection" + # Cross-check: if usage includes '[options]', there must be a + # longer 'Options:' section in the full --help output; vice-versa, + # if 'Options:' is in full output, usage line must have '[options]'. + if expr "$usage" : '.*\[option' >/dev/null; then + if ! expr "$full_help" : ".*Options:" >/dev/null; then + die "$command_string: Usage includes '[options]' but has no 'Options:' subsection" fi - elif expr "$full_help" : ".*Flags:" >/dev/null; then - die "$command_string: --help has 'Flags:' section but no '[flags]' in synopsis" + elif expr "$full_help" : ".*Options:" >/dev/null; then + die "$command_string: --help has 'Options:' section but no '[options]' in synopsis" fi # If usage lists no arguments (strings in ALL CAPS), confirm @@ -102,7 +102,7 @@ function check_help() { # If usage has required arguments, try running without them. # The expression here is 'first capital letter is not in [BRACKETS]'. - # It is intended to handle 'podman foo [flags] ARG' but not ' [ARG]'. + # It is intended to handle 'podman foo [options] ARG' but not ' [ARG]'. if expr "$usage" : '[^A-Z]\+ [A-Z]' >/dev/null; then # Exceptions: these commands don't work rootless if is_rootless; then diff --git a/test/system/030-run.bats b/test/system/030-run.bats index 766948ecc..6b6964c63 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -303,8 +303,36 @@ echo $rand | 0 | $rand # This would always work on root, but is new behavior on rootless: #6829 # adds a user entry to /etc/passwd + whoami=$(id -un) run_podman run --rm --userns=keep-id $IMAGE id -un - is "$output" "$(id -un)" "username on container with keep-id" + is "$output" "$whoami" "username on container with keep-id" + + # Setting user should also set $HOME (#8013). + # Test setup below runs three cases: one with an existing home dir + # and two without (one without any volume mounts, one with a misspelled + # username). In every case, initial cwd should be /home/podman because + # that's the container-defined WORKDIR. In the case of an existing + # home dir, $HOME and ~ (passwd entry) will be /home/user; otherwise + # they should be /home/podman. + if is_rootless; then + tests=" + | /home/podman /home/podman /home/podman | no vol mount +/home/x$whoami | /home/podman /home/podman /home/podman | bad vol mount +/home/$whoami | /home/podman /home/$whoami /home/$whoami | vol mount +" + while read vol expect name; do + opts= + if [[ "$vol" != "''" ]]; then + opts="-v $vol" + fi + run_podman run --rm $opts --userns=keep-id \ + $IMAGE sh -c 'echo $(pwd;printenv HOME;echo ~)' + is "$output" "$expect" "run with --userns=keep-id and $name sets \$HOME" + done < <(parse_table "$tests") + + # Clean up volumes + run_podman volume rm -a + fi # --privileged should make no difference run_podman run --rm --privileged --userns=keep-id $IMAGE id -un @@ -385,6 +413,17 @@ json-file | f else is "$output" "" "LogPath (driver=$driver)" fi + + if [[ $driver != 'none' ]]; then + run_podman logs myctr + is "$output" "$msg" "check that podman logs works as expected" + else + run_podman 125 logs myctr + if ! is_remote; then + is "$output" ".*this container is using the 'none' log driver, cannot read logs.*" \ + "podman logs does not work with none log driver" + fi + fi run_podman rm myctr done < <(parse_table "$tests") @@ -432,4 +471,55 @@ json-file | f is "$output" "$expect" "podman run with --tz=local, matches host" } +# run with --runtime should preserve the named runtime +@test "podman run : full path to --runtime is preserved" { + skip_if_remote "podman-remote does not support --runtime option" + + # Get configured runtime + run_podman info --format '{{.Host.OCIRuntime.Path}}' + runtime="$output" + + # Assumes that /var/tmp is not mounted noexec; this is usually safe + new_runtime="/var/tmp/myruntime$(random_string 12)" + cp --preserve $runtime $new_runtime + + run_podman run -d --runtime "$new_runtime" $IMAGE sleep 60 + cid="$output" + + run_podman inspect --format '{{.OCIRuntime}}' $cid + is "$output" "$new_runtime" "podman inspect shows configured runtime" + run_podman kill $cid + run_podman rm $cid + rm -f $new_runtime +} + +# Regression test for issue #8082 +@test "podman run : look up correct image name" { + # Create a 2nd tag for the local image. Force to lower case, and apply it. + local newtag="localhost/$(random_string 10)/$(random_string 8)" + newtag=${newtag,,} + run_podman tag $IMAGE $newtag + + # Create a container with the 2nd tag and make sure that it's being + # used. #8082 always inaccurately used the 1st tag. + run_podman create $newtag + cid="$output" + + run_podman inspect --format "{{.ImageName}}" $cid + is "$output" "$newtag" "container .ImageName is the container-create name" + + # Same thing, but now with a :tag, and making sure it works with --name + newtag2="${newtag}:$(random_string 6|tr A-Z a-z)" + run_podman tag $IMAGE $newtag2 + + cname="$(random_string 14|tr A-Z a-z)" + run_podman create --name $cname $newtag2 + run_podman inspect --format "{{.ImageName}}" $cname + is "$output" "$newtag2" "container .ImageName is the container-create name" + + # Clean up. + run_podman rm $cid $cname + run_podman untag $IMAGE $newtag $newtag2 +} + # vim: filetype=sh diff --git a/test/system/055-rm.bats b/test/system/055-rm.bats index 7176ae4b8..0107114b5 100644 --- a/test/system/055-rm.bats +++ b/test/system/055-rm.bats @@ -41,11 +41,14 @@ load helpers run_podman create --name $rand $IMAGE /bin/true # Create a container that podman does not know about - run buildah from $IMAGE - cid="$output" + external_cid=$(buildah from $IMAGE) + + # Plain 'exists' should fail, but should succeed with --external + run_podman 1 container exists $external_cid + run_podman container exists --external $external_cid # rm should succeed - run_podman rm $rand $cid + run_podman rm $rand $external_cid } # I'm sorry! This test takes 13 seconds. There's not much I can do about it, diff --git a/test/system/070-build.bats b/test/system/070-build.bats index 287323bbf..0741357ed 100644 --- a/test/system/070-build.bats +++ b/test/system/070-build.bats @@ -224,6 +224,12 @@ EOF # Confirm that 'podman inspect' shows the expected values # FIXME: can we rely on .Env[0] being PATH, and the rest being in order?? run_podman image inspect build_test + + # (Assert that output is formatted, not a one-line blob: #8011) + if [[ "${#lines[*]}" -lt 10 ]]; then + die "Output from 'image inspect' is only ${#lines[*]} lines; see #8011" + fi + tests=" Env[1] | MYENV1=$s_env1 Env[2] | MYENV2=this-should-be-overridden-by-env-host diff --git a/test/system/090-events.bats b/test/system/090-events.bats new file mode 100644 index 000000000..8a9db41fa --- /dev/null +++ b/test/system/090-events.bats @@ -0,0 +1,27 @@ +#!/usr/bin/env bats -*- bats -*- +# +# tests for podman events functionality +# + +load helpers + +@test "events with a filter by label" { + skip_if_remote "FIXME: -remote does not include labels in event output" + cname=test-$(random_string 30 | tr A-Z a-z) + labelname=$(random_string 10) + labelvalue=$(random_string 15) + + run_podman run --label $labelname=$labelvalue --name $cname --rm $IMAGE ls + + expect=".* container start [0-9a-f]\+ (image=$IMAGE, name=$cname,.* ${labelname}=${labelvalue}" + run_podman events --filter type=container --filter container=$cname --filter label=${labelname}=${labelvalue} --filter event=start --stream=false + is "$output" "$expect" "filtering by container name and label" + + # Same thing, but without the container-name filter + run_podman events --filter type=container --filter label=${labelname}=${labelvalue} --filter event=start --stream=false + is "$output" "$expect" "filtering just by label" + + # Now filter just by container name, no label + run_podman events --filter type=container --filter container=$cname --filter event=start --stream=false + is "$output" "$expect" "filtering just by label" +} diff --git a/test/system/140-diff.bats b/test/system/140-diff.bats index 01ec5430e..1277f9bbe 100644 --- a/test/system/140-diff.bats +++ b/test/system/140-diff.bats @@ -32,4 +32,26 @@ load helpers run_podman rm $n } +@test "podman diff with buildah container " { + rand_file=$(random_string 10) + buildah from --name buildahctr $IMAGE + buildah run buildahctr sh -c "touch /$rand_file;rm /etc/services" + + run_podman diff --format json buildahctr + + # Expected results for each type of diff + declare -A expect=( + [added]="/$rand_file" + [changed]="/etc" + [deleted]="/etc/services" + ) + + for field in ${!expect[@]}; do + result=$(jq -r -c ".${field}[]" <<<"$output") + is "$result" "${expect[$field]}" "$field" + done + + buildah rm buildahctr +} + # vim: filetype=sh diff --git a/test/system/160-volumes.bats b/test/system/160-volumes.bats index 1c1e0f4ae..9f4bb76a2 100644 --- a/test/system/160-volumes.bats +++ b/test/system/160-volumes.bats @@ -213,6 +213,12 @@ EOF run_podman volume create $vol done + # (Assert that output is formatted, not a one-line blob: #8011) + run_podman volume inspect ${v[1]} + if [[ "${#lines[*]}" -lt 10 ]]; then + die "Output from 'volume inspect' is only ${#lines[*]} lines; see #8011" + fi + # Run two containers: one mounting v1, one mounting v2 & v3 run_podman run --name c1 --volume ${v[1]}:/vol1 $IMAGE date run_podman run --name c2 --volume ${v[2]}:/vol2 -v ${v[3]}:/vol3 \ diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats index 2ae038dfe..1d17c8cad 100644 --- a/test/system/200-pod.bats +++ b/test/system/200-pod.bats @@ -66,6 +66,12 @@ function teardown() { run_podman pod exists $podname run_podman pod exists $podid + # (Assert that output is formatted, not a one-line blob: #8021) + run_podman pod inspect $podname + if [[ "${#lines[*]}" -lt 10 ]]; then + die "Output from 'pod inspect' is only ${#lines[*]} lines; see #8011" + fi + # Randomly-assigned port in the 5xxx range for port in $(shuf -i 5000-5999);do if ! { exec 3<> /dev/tcp/127.0.0.1/$port; } &>/dev/null; then diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats index 9bd3e15a1..ac3ae2f98 100644 --- a/test/system/250-systemd.bats +++ b/test/system/250-systemd.bats @@ -42,7 +42,7 @@ function teardown() { cname=$(random_string) # See #7407 for --pull=always. - run_podman create --pull=always --name $cname --label "io.containers.autoupdate=image" --detach $IMAGE top + run_podman create --pull=always --name $cname --label "io.containers.autoupdate=image" $IMAGE top run_podman generate systemd --new $cname echo "$output" > "$UNIT_FILE" diff --git a/test/system/260-sdnotify.bats b/test/system/260-sdnotify.bats index 06aa3bba7..c99ba4fa6 100644 --- a/test/system/260-sdnotify.bats +++ b/test/system/260-sdnotify.bats @@ -12,8 +12,6 @@ _SOCAT_LOG= function setup() { skip_if_remote "systemd tests are meaningless over remote" - skip "FIXME FIXME FIXME, is this what's causing the CI hang???" - # Skip if systemd is not running systemctl list-units &>/dev/null || skip "systemd not available" @@ -109,6 +107,7 @@ function _assert_mainpid_is_conmon() { # Done. Stop container, clean up. run_podman exec $cid touch /stop + run_podman wait $cid run_podman rm $cid _stop_socat } @@ -144,6 +143,7 @@ function _assert_mainpid_is_conmon() { # Done. Stop container, clean up. run_podman exec $cid touch /stop + run_podman wait $cid run_podman rm $cid run_podman rmi $_FEDORA _stop_socat diff --git a/test/system/420-cgroups.bats b/test/system/420-cgroups.bats new file mode 100644 index 000000000..615e43e6c --- /dev/null +++ b/test/system/420-cgroups.bats @@ -0,0 +1,34 @@ +#!/usr/bin/env bats -*- bats -*- +# +# cgroups-related tests +# + +load helpers + +@test "podman run, preserves initial --cgroup-manager" { + skip_if_remote "podman-remote does not support --cgroup-manager" + + if is_rootless && is_cgroupsv1; then + skip "not supported as rootless under cgroups v1" + fi + + # Find out our default cgroup manager, and from that, get the non-default + run_podman info --format '{{.Host.CgroupManager}}' + case "$output" in + systemd) other="cgroupfs" ;; + cgroupfs) other="systemd" ;; + *) die "Unknown CgroupManager '$output'" ;; + esac + + run_podman --cgroup-manager=$other run --name myc $IMAGE true + run_podman container inspect --format '{{.HostConfig.CgroupManager}}' myc + is "$output" "$other" "podman preserved .HostConfig.CgroupManager" + + # Restart the container, without --cgroup-manager option (ie use default) + # Prior to #7970, this would fail with an OCI runtime error + run_podman start myc + + run_podman rm myc +} + +# vim: filetype=sh diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats index a923402ac..44cc731cf 100644 --- a/test/system/500-networking.bats +++ b/test/system/500-networking.bats @@ -90,7 +90,12 @@ load helpers run_podman network create --subnet "${mysubnet}.0/24" $mynetname is "$output" ".*/cni/net.d/$mynetname.conflist" "output of 'network create'" - # WARNING: this pulls a ~100MB image from quay.io, hence is slow/flaky + # (Assert that output is formatted, not a one-line blob: #8011) + run_podman network inspect $mynetname + if [[ "${#lines[*]}" -lt 5 ]]; then + die "Output from 'pod inspect' is only ${#lines[*]} lines; see #8011" + fi + run_podman run --rm --network $mynetname $IMAGE ip a is "$output" ".* inet ${mysubnet}\.2/24 brd ${mysubnet}\.255 " \ "sdfsdf" diff --git a/test/system/helpers.bash b/test/system/helpers.bash index c6c2c12df..2cced10c2 100644 --- a/test/system/helpers.bash +++ b/test/system/helpers.bash @@ -34,6 +34,14 @@ function basic_setup() { # Clean up all containers run_podman rm --all --force + # ...including external (buildah) ones + run_podman ps --all --external --format '{{.ID}} {{.Names}}' + for line in "${lines[@]}"; do + set $line + echo "# setup(): removing stray external container $1 ($2)" >&3 + run_podman rm $1 + done + # Clean up all images except those desired found_needed_image= run_podman images --all --format '{{.Repository}}:{{.Tag}} {{.ID}}' @@ -245,9 +253,10 @@ function is_cgroupsv1() { ! is_cgroupsv2 } +# True if cgroups v2 are enabled function is_cgroupsv2() { cgroup_type=$(stat -f -c %T /sys/fs/cgroup) - test "$cgroup_type" = "cgroupfs" + test "$cgroup_type" = "cgroup2fs" } ########################### @@ -297,6 +306,15 @@ function skip_if_no_selinux() { fi } +####################### +# skip_if_cgroupsv1 # ...with an optional message +####################### +function skip_if_cgroupsv1() { + if ! is_cgroupsv2; then + skip "${1:-test requires cgroupsv2}" + fi +} + ######### # die # Abort with helpful message ######### |