diff --git a/libcontainer/integration/checkpoint_test.go b/libcontainer/integration/checkpoint_test.go index c86ec8a0c47..170204f0d6c 100644 --- a/libcontainer/integration/checkpoint_test.go +++ b/libcontainer/integration/checkpoint_test.go @@ -6,6 +6,7 @@ import ( "os" "os/exec" "path/filepath" + "regexp" "strings" "testing" @@ -61,6 +62,12 @@ func testCheckpoint(t *testing.T, userns bool) { t.Skipf("criu binary not found: %v", err) } + // Workaround for https://github.com/opencontainers/runc/issues/3532. + out, err := exec.Command("rpm", "-q", "criu").CombinedOutput() + if err == nil && regexp.MustCompile(`^criu-3\.17-[123]\.el9`).Match(out) { + t.Skip("Test requires criu >= 3.17-4 on CentOS Stream 9.") + } + config := newTemplateConfig(t, &tParam{userns: userns}) factory, err := libcontainer.New(t.TempDir()) ok(t, err) diff --git a/tests/integration/checkpoint.bats b/tests/integration/checkpoint.bats index 4b7e442bb1a..9bf9994004c 100644 --- a/tests/integration/checkpoint.bats +++ b/tests/integration/checkpoint.bats @@ -84,7 +84,7 @@ function runc_restore_with_pipes() { shift ret=0 - __runc --criu "$CRIU" restore -d --work-path "$workdir" --image-path ./image-dir "$@" "$name" <&${in_r} >&${out_w} 2>&${err_w} || ret=$? + __runc restore -d --work-path "$workdir" --image-path ./image-dir "$@" "$name" <&${in_r} >&${out_w} 2>&${err_w} || ret=$? if [ "$ret" -ne 0 ]; then echo "__runc restore $name failed (status: $ret)" exec {err_w}>&- @@ -109,7 +109,7 @@ function simple_cr() { for _ in $(seq 2); do # checkpoint the running container - runc --criu "$CRIU" "$@" checkpoint --work-path ./work-dir test_busybox + runc "$@" checkpoint --work-path ./work-dir test_busybox grep -B 5 Error ./work-dir/dump.log || true [ "$status" -eq 0 ] @@ -117,7 +117,7 @@ function simple_cr() { testcontainer test_busybox checkpointed # restore from checkpoint - runc --criu "$CRIU" "$@" restore -d --work-path ./work-dir --console-socket "$CONSOLE_SOCKET" test_busybox + runc "$@" restore -d --work-path ./work-dir --console-socket "$CONSOLE_SOCKET" test_busybox grep -B 5 Error ./work-dir/restore.log || true [ "$status" -eq 0 ] @@ -162,12 +162,12 @@ function simple_cr() { testcontainer test_busybox running # runc should fail with absolute parent image path. - runc --criu "$CRIU" checkpoint --parent-path "$(pwd)"/parent-dir --work-path ./work-dir --image-path ./image-dir test_busybox + runc checkpoint --parent-path "$(pwd)"/parent-dir --work-path ./work-dir --image-path ./image-dir test_busybox [[ "${output}" == *"--parent-path"* ]] [ "$status" -ne 0 ] # runc should fail with invalid parent image path. - runc --criu "$CRIU" checkpoint --parent-path ./parent-dir --work-path ./work-dir --image-path ./image-dir test_busybox + runc checkpoint --parent-path ./parent-dir --work-path ./work-dir --image-path ./image-dir test_busybox [[ "${output}" == *"--parent-path"* ]] [ "$status" -ne 0 ] } @@ -178,7 +178,7 @@ function simple_cr() { #test checkpoint pre-dump mkdir parent-dir - runc --criu "$CRIU" checkpoint --pre-dump --image-path ./parent-dir test_busybox + runc checkpoint --pre-dump --image-path ./parent-dir test_busybox [ "$status" -eq 0 ] # busybox should still be running @@ -187,7 +187,7 @@ function simple_cr() { # checkpoint the running container mkdir image-dir mkdir work-dir - runc --criu "$CRIU" checkpoint --parent-path ../parent-dir --work-path ./work-dir --image-path ./image-dir test_busybox + runc checkpoint --parent-path ../parent-dir --work-path ./work-dir --image-path ./image-dir test_busybox grep -B 5 Error ./work-dir/dump.log || true [ "$status" -eq 0 ] @@ -203,7 +203,7 @@ function simple_cr() { @test "checkpoint --lazy-pages and restore" { # check if lazy-pages is supported - if ! "${CRIU}" check --feature uffd-noncoop; then + if ! criu check --feature uffd-noncoop; then skip "this criu does not support lazy migration" fi @@ -224,7 +224,7 @@ function simple_cr() { # TCP port for lazy migration port=27277 - __runc --criu "$CRIU" checkpoint --lazy-pages --page-server 0.0.0.0:${port} --status-fd ${lazy_w} --work-path ./work-dir --image-path ./image-dir test_busybox & + __runc checkpoint --lazy-pages --page-server 0.0.0.0:${port} --status-fd ${lazy_w} --work-path ./work-dir --image-path ./image-dir test_busybox & cpt_pid=$! # wait for lazy page server to be ready @@ -242,7 +242,7 @@ function simple_cr() { [ -e image-dir/inventory.img ] # Start CRIU in lazy-daemon mode - ${CRIU} lazy-pages --page-server --address 127.0.0.1 --port ${port} -D image-dir & + criu lazy-pages --page-server --address 127.0.0.1 --port ${port} -D image-dir & lp_pid=$! # Restore lazily from checkpoint. @@ -264,7 +264,7 @@ function simple_cr() { @test "checkpoint and restore in external network namespace" { # check if external_net_ns is supported; only with criu 3.10++ - if ! "${CRIU}" check --feature external_net_ns; then + if ! criu check --feature external_net_ns; then # this criu does not support external_net_ns; skip the test skip "this criu does not support external network namespaces" fi @@ -290,7 +290,7 @@ function simple_cr() { for _ in $(seq 2); do # checkpoint the running container; this automatically tells CRIU to # handle the network namespace defined in config.json as an external - runc --criu "$CRIU" checkpoint --work-path ./work-dir test_busybox + runc checkpoint --work-path ./work-dir test_busybox grep -B 5 Error ./work-dir/dump.log || true [ "$status" -eq 0 ] @@ -298,7 +298,7 @@ function simple_cr() { testcontainer test_busybox checkpointed # restore from checkpoint; this should restore the container into the existing network namespace - runc --criu "$CRIU" restore -d --work-path ./work-dir --console-socket "$CONSOLE_SOCKET" test_busybox + runc restore -d --work-path ./work-dir --console-socket "$CONSOLE_SOCKET" test_busybox grep -B 5 Error ./work-dir/restore.log || true [ "$status" -eq 0 ] @@ -341,7 +341,7 @@ function simple_cr() { testcontainer test_busybox running # checkpoint the running container - runc --criu "$CRIU" checkpoint --work-path ./work-dir test_busybox + runc checkpoint --work-path ./work-dir test_busybox grep -B 5 Error ./work-dir/dump.log || true [ "$status" -eq 0 ] ! test -f ./work-dir/"$tmplog1" @@ -352,7 +352,7 @@ function simple_cr() { test -f ./work-dir/"$tmplog2" && unlink ./work-dir/"$tmplog2" # restore from checkpoint - runc --criu "$CRIU" restore -d --work-path ./work-dir --console-socket "$CONSOLE_SOCKET" test_busybox + runc restore -d --work-path ./work-dir --console-socket "$CONSOLE_SOCKET" test_busybox grep -B 5 Error ./work-dir/restore.log || true [ "$status" -eq 0 ] ! test -f ./work-dir/"$tmplog1" @@ -386,7 +386,7 @@ function simple_cr() { testcontainer test_busybox running # checkpoint the running container - runc --criu "$CRIU" checkpoint --work-path ./work-dir test_busybox + runc checkpoint --work-path ./work-dir test_busybox grep -B 5 Error ./work-dir/dump.log || true [ "$status" -eq 0 ] @@ -398,7 +398,7 @@ function simple_cr() { rm -rf "${bind1:?}"/* # restore from checkpoint - runc --criu "$CRIU" restore -d --work-path ./work-dir --console-socket "$CONSOLE_SOCKET" test_busybox + runc restore -d --work-path ./work-dir --console-socket "$CONSOLE_SOCKET" test_busybox grep -B 5 Error ./work-dir/restore.log || true [ "$status" -eq 0 ] diff --git a/tests/integration/delete.bats b/tests/integration/delete.bats index ea8a3bb6c0c..bb0205c4ebf 100644 --- a/tests/integration/delete.bats +++ b/tests/integration/delete.bats @@ -11,10 +11,22 @@ function teardown() { } @test "runc delete" { + # Need a permission to create a cgroup. + # XXX(@kolyshkin): currently this test does not handle rootless when + # fs cgroup driver is used, because in this case cgroup (with a + # predefined name) is created by tests/rootless.sh, not by runc. + [[ "$ROOTLESS" -ne 0 ]] && requires systemd + set_resources_limit + runc run -d --console-socket "$CONSOLE_SOCKET" testbusyboxdelete [ "$status" -eq 0 ] testcontainer testbusyboxdelete running + # Ensure the find statement used later is correct. + output=$(find /sys/fs/cgroup -name testbusyboxdelete -o -name \*-testbusyboxdelete.scope 2>/dev/null || true) + if [ -z "$output" ]; then + fail "expected cgroup not found" + fi runc kill testbusyboxdelete KILL [ "$status" -eq 0 ] @@ -26,7 +38,7 @@ function teardown() { runc state testbusyboxdelete [ "$status" -ne 0 ] - output=$(find /sys/fs/cgroup -wholename '*testbusyboxdelete*' -type d) + output=$(find /sys/fs/cgroup -name testbusyboxdelete -o -name \*-testbusyboxdelete.scope 2>/dev/null || true) [ "$output" = "" ] || fail "cgroup not cleaned up correctly: $output" } @@ -106,7 +118,7 @@ EOF runc state test_busybox [ "$status" -ne 0 ] - output=$(find /sys/fs/cgroup -wholename '*testbusyboxdelete*' -type d) + output=$(find /sys/fs/cgroup -wholename '*testbusyboxdelete*' -type d 2>/dev/null || true) [ "$output" = "" ] || fail "cgroup not cleaned up correctly: $output" } diff --git a/tests/integration/helpers.bash b/tests/integration/helpers.bash index aaa68dd7c33..ea68bfc868f 100644 --- a/tests/integration/helpers.bash +++ b/tests/integration/helpers.bash @@ -23,9 +23,6 @@ SECCOMP_AGENT="${INTEGRATION_ROOT}/../../contrib/cmd/seccompagent/seccompagent" # shellcheck disable=SC2034 TESTDATA="${INTEGRATION_ROOT}/testdata" -# CRIU PATH -CRIU="$(which criu 2>/dev/null || true)" - # Kernel version KERNEL_VERSION="$(uname -r)" KERNEL_MAJOR="${KERNEL_VERSION%%.*}" @@ -343,6 +340,16 @@ function rootless_cgroup() { [[ "$ROOTLESS_FEATURES" == *"cgroup"* || -n "$RUNC_USE_SYSTEMD" ]] } +# Check if criu is available and working. +function have_criu() { + command -v criu &>/dev/null || return 1 + + # Workaround for https://github.com/opencontainers/runc/issues/3532. + local ver + ver=$(rpm -q criu 2>/dev/null || true) + ! grep -q '^criu-3\.17-[123]\.el9' <<<"$ver" +} + # Allows a test to specify what things it requires. If the environment can't # support it, the test is skipped with a message. function requires() { @@ -350,7 +357,7 @@ function requires() { local skip_me case $var in criu) - if [ ! -e "$CRIU" ]; then + if ! have_criu; then skip_me=1 fi ;;