summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/e2e/pod_initcontainers_test.go171
-rw-r--r--test/e2e/run_test.go11
-rw-r--r--test/system/255-auto-update.bats117
3 files changed, 294 insertions, 5 deletions
diff --git a/test/e2e/pod_initcontainers_test.go b/test/e2e/pod_initcontainers_test.go
new file mode 100644
index 000000000..606294f51
--- /dev/null
+++ b/test/e2e/pod_initcontainers_test.go
@@ -0,0 +1,171 @@
+package integration
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+
+ "github.com/containers/podman/v3/libpod/define"
+ . "github.com/containers/podman/v3/test/utils"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/gexec"
+)
+
+var _ = Describe("Podman init containers", func() {
+ var (
+ tempdir string
+ err error
+ podmanTest *PodmanTestIntegration
+ )
+
+ BeforeEach(func() {
+ tempdir, err = CreateTempDirInTempDir()
+ if err != nil {
+ os.Exit(1)
+ }
+ podmanTest = PodmanTestCreate(tempdir)
+ podmanTest.Setup()
+ podmanTest.SeedImages()
+ })
+
+ AfterEach(func() {
+ podmanTest.Cleanup()
+ f := CurrentGinkgoTestDescription()
+ processTestResult(f)
+
+ })
+
+ It("podman create init container without --pod should fail", func() {
+ session := podmanTest.Podman([]string{"create", "--init-ctr", "always", ALPINE, "top"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(125))
+ })
+
+ It("podman create init container with bad init type should fail", func() {
+ session := podmanTest.Podman([]string{"create", "--init-ctr", "unknown", "--pod", "new:foobar", ALPINE, "top"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(125))
+ })
+
+ It("podman init containers should not degrade pod status", func() {
+ // create a pod
+ topPod := podmanTest.Podman([]string{"create", "-t", "--pod", "new:foobar", ALPINE, "top"})
+ topPod.WaitWithDefaultTimeout()
+ Expect(topPod).Should(Exit(0))
+ // add an init container
+ session := podmanTest.Podman([]string{"create", "--init-ctr", "always", "--pod", "foobar", ALPINE, "date"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ // start a pod
+ start := podmanTest.Podman([]string{"pod", "start", "foobar"})
+ start.WaitWithDefaultTimeout()
+ Expect(start).Should(Exit(0))
+
+ inspect := podmanTest.Podman([]string{"pod", "inspect", "foobar"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect).Should(Exit(0))
+ data := inspect.InspectPodToJSON()
+ Expect(data.State).To(Equal(define.PodStateRunning))
+ })
+
+ It("podman create init container should fail in running pod", func() {
+ // create a running pod
+ topPod := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:foobar", ALPINE, "top"})
+ topPod.WaitWithDefaultTimeout()
+ Expect(topPod).Should(Exit(0))
+ // adding init-ctr to running pod should fail
+ session := podmanTest.Podman([]string{"create", "--init-ctr", "always", "--pod", "foobar", ALPINE, "date"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(125))
+ })
+
+ It("podman make sure init container runs before pod containers", func() {
+ filename := filepath.Join("/dev/shm", RandomString(12))
+ content := RandomString(16)
+ session := podmanTest.Podman([]string{"create", "--init-ctr", "always", "--pod", "new:foobar", ALPINE, "bin/sh", "-c", fmt.Sprintf("echo %s > %s", content, filename)})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ verify := podmanTest.Podman([]string{"create", "--pod", "foobar", "-t", ALPINE, "top"})
+ verify.WaitWithDefaultTimeout()
+ Expect(verify).Should(Exit(0))
+ start := podmanTest.Podman([]string{"pod", "start", "foobar"})
+ start.WaitWithDefaultTimeout()
+ Expect(start).Should(Exit(0))
+ checkLog := podmanTest.Podman([]string{"exec", "-it", verify.OutputToString(), "cat", filename})
+ checkLog.WaitWithDefaultTimeout()
+ Expect(checkLog).Should(Exit(0))
+ Expect(checkLog.OutputToString()).To(Equal(content))
+ })
+
+ It("podman make sure oneshot container is removed", func() {
+ filename := filepath.Join("/dev/shm", RandomString(12))
+ content := RandomString(16)
+ session := podmanTest.Podman([]string{"create", "--init-ctr", "oneshot", "--pod", "new:foobar", ALPINE, "bin/sh", "-c", fmt.Sprintf("echo %s > %s", content, filename)})
+ session.WaitWithDefaultTimeout()
+ initContainerID := session.OutputToString()
+ Expect(session).Should(Exit(0))
+ verify := podmanTest.Podman([]string{"create", "--pod", "foobar", "-t", ALPINE, "top"})
+ verify.WaitWithDefaultTimeout()
+ Expect(verify).Should(Exit(0))
+ start := podmanTest.Podman([]string{"pod", "start", "foobar"})
+ start.WaitWithDefaultTimeout()
+ Expect(start).Should(Exit(0))
+ check := podmanTest.Podman([]string{"container", "exists", initContainerID})
+ check.WaitWithDefaultTimeout()
+ // Container was rm'd
+ //Expect(check).Should(Exit(1))
+ Expect(check.ExitCode()).To(Equal(1), "I dont understand why the other way does not work")
+ // Lets double check with a stop and start
+ stopPod := podmanTest.Podman([]string{"pod", "stop", "foobar"})
+ stopPod.WaitWithDefaultTimeout()
+ Expect(stopPod).Should(Exit(0))
+ startPod := podmanTest.Podman([]string{"pod", "start", "foobar"})
+ startPod.WaitWithDefaultTimeout()
+ Expect(startPod).Should(Exit(0))
+
+ // Because no init was run, the file should not even exist
+ doubleCheck := podmanTest.Podman([]string{"exec", "-it", verify.OutputToString(), "cat", filename})
+ doubleCheck.WaitWithDefaultTimeout()
+ Expect(doubleCheck).Should(Exit(1))
+
+ })
+
+ It("podman ensure always init containers always run", func() {
+ filename := filepath.Join("/dev/shm", RandomString(12))
+
+ // Write the date to a file
+ session := podmanTest.Podman([]string{"create", "--init-ctr", "always", "--pod", "new:foobar", ALPINE, "bin/sh", "-c", fmt.Sprintf("date > %s", filename)})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ verify := podmanTest.Podman([]string{"create", "--pod", "foobar", "-t", ALPINE, "top"})
+ verify.WaitWithDefaultTimeout()
+ Expect(verify).Should(Exit(0))
+ start := podmanTest.Podman([]string{"pod", "start", "foobar"})
+ start.WaitWithDefaultTimeout()
+ Expect(start).Should(Exit(0))
+
+ // capture the date written
+ checkLog := podmanTest.Podman([]string{"exec", "-it", verify.OutputToString(), "cat", filename})
+ checkLog.WaitWithDefaultTimeout()
+ firstResult := checkLog.OutputToString()
+ Expect(checkLog).Should(Exit(0))
+
+ // Stop and start the pod
+ stopPod := podmanTest.Podman([]string{"pod", "stop", "foobar"})
+ stopPod.WaitWithDefaultTimeout()
+ Expect(stopPod).Should(Exit(0))
+ startPod := podmanTest.Podman([]string{"pod", "start", "foobar"})
+ startPod.WaitWithDefaultTimeout()
+ Expect(startPod).Should(Exit(0))
+
+ // Check the file again with exec
+ secondCheckLog := podmanTest.Podman([]string{"exec", "-it", verify.OutputToString(), "cat", filename})
+ secondCheckLog.WaitWithDefaultTimeout()
+ Expect(secondCheckLog).Should(Exit(0))
+
+ // Dates should not match
+ Expect(firstResult).ToNot(Equal(secondCheckLog.OutputToString()))
+ })
+
+})
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 3c65c02d1..d68aa6ac4 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -1790,4 +1790,15 @@ WORKDIR /madethis`, BB)
_, err = strconv.Atoi(containerPID) // Make sure it's a proper integer
Expect(err).To(BeNil())
})
+
+ It("podman run check personality support", func() {
+ // TODO: Remove this as soon as this is merged and made available in our CI https://github.com/opencontainers/runc/pull/3126.
+ if !strings.Contains(podmanTest.OCIRuntime, "crun") {
+ Skip("Test only works on crun")
+ }
+ session := podmanTest.Podman([]string{"run", "--personality=LINUX32", "--name=testpersonality", ALPINE, "uname", "-a"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(ContainSubstring("i686"))
+ })
})
diff --git a/test/system/255-auto-update.bats b/test/system/255-auto-update.bats
index 6fb40f41e..4e242e1f1 100644
--- a/test/system/255-auto-update.bats
+++ b/test/system/255-auto-update.bats
@@ -26,9 +26,17 @@ function teardown() {
done < $SNAME_FILE
rm -f $SNAME_FILE
- run_podman ? rmi quay.io/libpod/alpine:latest
- run_podman ? rmi quay.io/libpod/busybox:latest
- run_podman ? rmi quay.io/libpod/localtest:latest
+ run_podman ? rmi -f \
+ quay.io/libpod/alpine:latest \
+ quay.io/libpod/busybox:latest \
+ quay.io/libpod/localtest:latest \
+ quay.io/libpod/autoupdatebroken:latest \
+ quay.io/libpod/test:latest \
+ quay.io/libpod/fedora:31
+
+ # The rollback tests may leave some dangling images behind, so let's prune
+ # them to leave a clean state.
+ run_podman ? image prune -f
basic_teardown
}
@@ -43,18 +51,30 @@ function teardown() {
function generate_service() {
local target_img_basename=$1
local autoupdate=$2
+ local command=$3
+ local extraArgs=$4
+ local noTag=$5
+
+ # Unless specified, set a default command.
+ if [[ -z "$command" ]]; then
+ command="top -d 120"
+ fi
# Container name. Include the autoupdate type, to make debugging easier.
# IMPORTANT: variable 'cname' is passed (out of scope) up to caller!
cname=c_${autoupdate//\'/}_$(random_string)
target_img="quay.io/libpod/$target_img_basename:latest"
- run_podman tag $IMAGE $target_img
+
+ if [[ -z "$noTag" ]]; then
+ run_podman tag $IMAGE $target_img
+ fi
+
if [[ -n "$autoupdate" ]]; then
label="--label io.containers.autoupdate=$autoupdate"
else
label=""
fi
- run_podman run -d --name $cname $label $target_img top -d 120
+ run_podman create $extraArgs --name $cname $label $target_img $command
(cd $UNIT_DIR; run_podman generate systemd --new --files --name $cname)
echo "container-$cname" >> $SNAME_FILE
@@ -128,6 +148,38 @@ function _confirm_update() {
_confirm_update $cname $ori_image
}
+@test "podman auto-update - label io.containers.autoupdate=image with rollback" {
+ # Note: the autoupdatebroken image is empty on purpose so it cannot be
+ # executed and force a rollback. The rollback test for the local policy
+ # is exercising the case where the container doesn't send a ready message.
+ image=quay.io/libpod/autoupdatebroken
+
+ run_podman tag $IMAGE $image
+ generate_service autoupdatebroken image
+
+ _wait_service_ready container-$cname.service
+ run_podman auto-update --dry-run --format "{{.Unit}},{{.Image}},{{.Updated}},{{.Policy}}"
+ is "$output" ".*container-$cname.service,$image:latest,pending,registry.*" "Image update is pending."
+
+ run_podman container inspect --format "{{.Image}}" $cname
+ oldID="$output"
+
+ run_podman inspect --format "{{.ID}}" $cname
+ containerID="$output"
+
+ run_podman auto-update --format "{{.Unit}},{{.Image}},{{.Updated}},{{.Policy}}"
+ is "$output" "Trying to pull.*" "Image is updated."
+ is "$output" ".*container-$cname.service,$image:latest,rolled back,registry.*" "Image has been rolled back."
+
+ run_podman container inspect --format "{{.Image}}" $cname
+ is "$output" "$oldID" "container rolled back to previous image"
+
+ run_podman container inspect --format "{{.ID}}" $cname
+ if [[ $output == $containerID ]]; then
+ die "container has not been restarted during rollback (previous id: $containerID, current id: $output)"
+ fi
+}
+
@test "podman auto-update - label io.containers.autoupdate=disabled" {
generate_service alpine disabled
@@ -168,6 +220,61 @@ function _confirm_update() {
_confirm_update $cname $ori_image
}
+@test "podman auto-update - label io.containers.autoupdate=local with rollback" {
+ # sdnotify fails with runc 1.0.0-3-dev2 on Ubuntu. Let's just
+ # assume that we work only with crun, nothing else.
+ # [copied from 260-sdnotify.bats]
+ runtime=$(podman_runtime)
+ if [[ "$runtime" != "crun" ]]; then
+ skip "this test only works with crun, not $runtime"
+ fi
+
+ dockerfile1=$PODMAN_TMPDIR/Dockerfile.1
+ cat >$dockerfile1 <<EOF
+FROM quay.io/libpod/fedora:31
+RUN echo -e "#!/bin/sh\n\
+printenv NOTIFY_SOCKET; echo READY; systemd-notify --ready;\n\
+trap 'echo Received SIGTERM, finishing; exit' SIGTERM; echo WAITING; while :; do sleep 0.1; done" \
+>> /runme
+RUN chmod +x /runme
+EOF
+
+ dockerfile2=$PODMAN_TMPDIR/Dockerfile.2
+ cat >$dockerfile2 <<EOF
+FROM quay.io/libpod/fedora:31
+RUN echo -e "#!/bin/sh\n\
+exit 1" >> /runme
+RUN chmod +x /runme
+EOF
+ image=test
+
+ # Generate a healthy image that will run correctly.
+ run_podman build -t quay.io/libpod/$image -f $dockerfile1
+ podman image inspect --format "{{.ID}}" $image
+ oldID="$output"
+
+ generate_service $image local /runme --sdnotify=container noTag
+ _wait_service_ready container-$cname.service
+
+ run_podman auto-update --dry-run --format "{{.Unit}},{{.Image}},{{.Updated}},{{.Policy}}"
+ is "$output" ".*container-$cname.service,quay.io/libpod/$image:latest,false,local.*" "No update available"
+
+ # Generate an unhealthy image that will fail.
+ run_podman build -t quay.io/libpod/$image -f $dockerfile2
+ podman image inspect --format "{{.ID}}" $image
+ newID="$output"
+
+ run_podman auto-update --dry-run --format "{{.Unit}},{{.Image}},{{.Updated}},{{.Policy}}"
+ is "$output" ".*container-$cname.service,quay.io/libpod/$image:latest,pending,local.*" "Image updated is pending"
+
+ # Note: we rollback automatically by default.
+ run_podman auto-update --format "{{.Unit}},{{.Image}},{{.Updated}},{{.Policy}}"
+ is "$output" ".*container-$cname.service,quay.io/libpod/$image:latest,rolled back,local.*" "Rolled back to old image"
+
+ # Make sure that new container is not using the new image ID anymore.
+ _confirm_update $cname $newID
+}
+
@test "podman auto-update with multiple services" {
# Preserve original image ID, to confirm that it changes (or not)
run_podman inspect --format "{{.Id}}" $IMAGE