github.com/opencontainers/runc@v1.2.0-rc.1.0.20240520010911-492dc558cdd6/tests/integration/delete.bats (about) 1 #!/usr/bin/env bats 2 3 load helpers 4 5 function setup() { 6 setup_busybox 7 } 8 9 function teardown() { 10 teardown_bundle 11 } 12 13 # See also: "kill KILL [host pidns + init gone]" test in kill.bats. 14 # 15 # This needs to be placed at the top of the bats file to work around 16 # a shellcheck bug. See <https://github.com/koalaman/shellcheck/issues/2873>. 17 function test_runc_delete_host_pidns() { 18 requires cgroups_freezer 19 20 update_config ' .linux.namespaces -= [{"type": "pid"}]' 21 set_cgroups_path 22 if [ $EUID -ne 0 ]; then 23 requires rootless_cgroup 24 # Apparently, for rootless test, when using systemd cgroup manager, 25 # newer versions of systemd clean up the container as soon as its init 26 # process is gone. This is all fine and dandy, except it prevents us to 27 # test this case, thus we skip the test. 28 # 29 # It is not entirely clear which systemd version got this feature: 30 # v245 works fine, and v249 does not. 31 if [ -v RUNC_USE_SYSTEMD ] && [ "$(systemd_version)" -gt 245 ]; then 32 skip "rootless+systemd conflicts with systemd > 245" 33 fi 34 # Can't mount real /proc when rootless + no pidns, 35 # so change it to a bind-mounted one from the host. 36 update_config ' .mounts |= map((select(.type == "proc") 37 | .type = "none" 38 | .source = "/proc" 39 | .options = ["rbind", "nosuid", "nodev", "noexec"] 40 ) // .)' 41 fi 42 43 runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox 44 [ "$status" -eq 0 ] 45 cgpath=$(get_cgroup_path "pids") 46 init_pid=$(cat "$cgpath"/cgroup.procs) 47 48 # Start a few more processes. 49 for _ in 1 2 3 4 5; do 50 __runc exec -d test_busybox sleep 1h 51 done 52 53 # Now kill the container's init process. Since the container do 54 # not have own PID ns, its init is no special and the container 55 # will still be up and running. 56 kill -9 "$init_pid" 57 wait_pids_gone 10 0.2 "$init_pid" 58 59 # Get the list of all container processes. 60 mapfile -t pids < <(cat "$cgpath"/cgroup.procs) 61 echo "pids:" "${pids[@]}" 62 # Sanity check -- make sure all processes exist. 63 for p in "${pids[@]}"; do 64 kill -0 "$p" 65 done 66 67 # Must kill those processes and remove container. 68 runc delete "$@" test_busybox 69 [ "$status" -eq 0 ] 70 71 runc state test_busybox 72 [ "$status" -ne 0 ] # "Container does not exist" 73 74 # Wait and check that all the processes are gone. 75 wait_pids_gone 10 0.2 "${pids[@]}" 76 77 # Make sure cgroup.procs is empty. 78 mapfile -t pids < <(cat "$cgpath"/cgroup.procs || true) 79 if [ ${#pids[@]} -gt 0 ]; then 80 echo "expected empty cgroup.procs, got:" "${pids[@]}" 1>&2 81 return 1 82 fi 83 } 84 85 @test "runc delete" { 86 # Need a permission to create a cgroup. 87 # XXX(@kolyshkin): currently this test does not handle rootless when 88 # fs cgroup driver is used, because in this case cgroup (with a 89 # predefined name) is created by tests/rootless.sh, not by runc. 90 [ $EUID -ne 0 ] && requires systemd 91 set_resources_limit 92 93 runc run -d --console-socket "$CONSOLE_SOCKET" testbusyboxdelete 94 [ "$status" -eq 0 ] 95 96 testcontainer testbusyboxdelete running 97 # Ensure the find statement used later is correct. 98 output=$(find /sys/fs/cgroup -name testbusyboxdelete -o -name \*-testbusyboxdelete.scope 2>/dev/null || true) 99 if [ -z "$output" ]; then 100 fail "expected cgroup not found" 101 fi 102 103 runc kill testbusyboxdelete KILL 104 [ "$status" -eq 0 ] 105 wait_for_container 10 1 testbusyboxdelete stopped 106 107 runc delete testbusyboxdelete 108 [ "$status" -eq 0 ] 109 110 runc state testbusyboxdelete 111 [ "$status" -ne 0 ] 112 113 output=$(find /sys/fs/cgroup -name testbusyboxdelete -o -name \*-testbusyboxdelete.scope 2>/dev/null || true) 114 [ "$output" = "" ] || fail "cgroup not cleaned up correctly: $output" 115 } 116 117 @test "runc delete --force" { 118 # run busybox detached 119 runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox 120 [ "$status" -eq 0 ] 121 122 # check state 123 testcontainer test_busybox running 124 125 # force delete test_busybox 126 runc delete --force test_busybox 127 128 runc state test_busybox 129 [ "$status" -ne 0 ] 130 } 131 132 @test "runc delete --force ignore not exist" { 133 runc delete --force notexists 134 [ "$status" -eq 0 ] 135 } 136 137 # Issue 4047, case "runc delete". 138 @test "runc delete [host pidns + init gone]" { 139 test_runc_delete_host_pidns 140 } 141 142 # Issue 4047, case "runc delete --force" (different code path). 143 @test "runc delete --force [host pidns + init gone]" { 144 test_runc_delete_host_pidns --force 145 } 146 147 @test "runc delete --force [paused container]" { 148 runc run -d --console-socket "$CONSOLE_SOCKET" ct1 149 [ "$status" -eq 0 ] 150 testcontainer ct1 running 151 152 runc pause ct1 153 runc delete --force ct1 154 [ "$status" -eq 0 ] 155 } 156 157 @test "runc delete --force in cgroupv1 with subcgroups" { 158 requires cgroups_v1 root cgroupns 159 set_cgroups_path 160 set_cgroup_mount_writable 161 # enable cgroupns 162 update_config '.linux.namespaces += [{"type": "cgroup"}]' 163 164 local subsystems="memory freezer" 165 166 runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox 167 [ "$status" -eq 0 ] 168 169 testcontainer test_busybox running 170 171 __runc exec -d test_busybox sleep 1d 172 173 # find the pid of sleep 174 pid=$(__runc exec test_busybox ps -a | grep 1d | awk '{print $1}') 175 [[ ${pid} =~ [0-9]+ ]] 176 177 # create a sub-cgroup 178 cat <<EOF | runc exec test_busybox sh 179 set -e -u -x 180 for s in ${subsystems}; do 181 cd /sys/fs/cgroup/\$s 182 mkdir foo 183 cd foo 184 echo ${pid} > tasks 185 cat tasks 186 done 187 EOF 188 [ "$status" -eq 0 ] 189 [[ "$output" =~ [0-9]+ ]] 190 191 for s in ${subsystems}; do 192 name=CGROUP_${s^^}_BASE_PATH 193 eval path=\$"${name}${REL_CGROUPS_PATH}/foo" 194 # shellcheck disable=SC2154 195 [ -d "${path}" ] || fail "test failed to create memory sub-cgroup ($path not found)" 196 done 197 198 runc delete --force test_busybox 199 200 runc state test_busybox 201 [ "$status" -ne 0 ] 202 203 output=$(find /sys/fs/cgroup -wholename '*testbusyboxdelete*' -type d 2>/dev/null || true) 204 [ "$output" = "" ] || fail "cgroup not cleaned up correctly: $output" 205 } 206 207 @test "runc delete --force in cgroupv2 with subcgroups" { 208 requires cgroups_v2 root 209 set_cgroups_path 210 set_cgroup_mount_writable 211 212 # run busybox detached 213 runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox 214 [ "$status" -eq 0 ] 215 216 # check state 217 testcontainer test_busybox running 218 219 # create a sub process 220 __runc exec -d test_busybox sleep 1d 221 222 # find the pid of sleep 223 pid=$(__runc exec test_busybox ps -a | grep 1d | awk '{print $1}') 224 [[ ${pid} =~ [0-9]+ ]] 225 226 # create subcgroups 227 cat <<EOF >nest.sh 228 set -e -u -x 229 cd /sys/fs/cgroup 230 echo +pids > cgroup.subtree_control 231 mkdir foo 232 cd foo 233 echo threaded > cgroup.type 234 echo ${pid} > cgroup.threads 235 cat cgroup.threads 236 EOF 237 runc exec test_busybox sh <nest.sh 238 [ "$status" -eq 0 ] 239 [[ "$output" =~ [0-9]+ ]] 240 241 # check create subcgroups success 242 [ -d "$CGROUP_V2_PATH"/foo ] 243 244 # force delete test_busybox 245 runc delete --force test_busybox 246 247 runc state test_busybox 248 [ "$status" -ne 0 ] 249 250 # check delete subcgroups success 251 [ ! -d "$CGROUP_V2_PATH"/foo ] 252 } 253 254 @test "runc delete removes failed systemd unit" { 255 requires systemd_v244 # Older systemd lacks RuntimeMaxSec support. 256 257 set_cgroups_path 258 update_config ' .annotations += { 259 "org.systemd.property.RuntimeMaxSec": "2", 260 "org.systemd.property.TimeoutStopSec": "1" 261 } 262 | .process.args |= ["/bin/sleep", "10"]' 263 264 runc run -d --console-socket "$CONSOLE_SOCKET" test-failed-unit 265 [ "$status" -eq 0 ] 266 267 wait_for_container 10 1 test-failed-unit stopped 268 269 local user="" 270 [ $EUID -ne 0 ] && user="--user" 271 272 # Expect "unit is not active" exit code. 273 run -3 systemctl status $user "$SD_UNIT_NAME" 274 275 runc delete test-failed-unit 276 # Expect "no such unit" exit code. 277 run -4 systemctl status $user "$SD_UNIT_NAME" 278 }