...
1#!/usr/bin/env bats
2
3load helpers
4
5function setup() {
6 setup_busybox
7 update_config '.process.args = ["/bin/echo", "Hello World"]'
8}
9
10function teardown() {
11 teardown_bundle
12}
13
14@test "runc run" {
15 runc run test_hello
16 [ "$status" -eq 0 ]
17
18 runc state test_hello
19 [ "$status" -ne 0 ]
20}
21
22@test "runc run --keep" {
23 runc run --keep test_run_keep
24 [ "$status" -eq 0 ]
25
26 testcontainer test_run_keep stopped
27
28 runc state test_run_keep
29 [ "$status" -eq 0 ]
30
31 runc delete test_run_keep
32
33 runc state test_run_keep
34 [ "$status" -ne 0 ]
35}
36
37@test "runc run --keep (check cgroup exists)" {
38 # for systemd driver, the unit's cgroup path will be auto removed if container's all processes exited
39 requires no_systemd
40
41 [[ "$ROOTLESS" -ne 0 ]] && requires rootless_cgroup
42
43 set_cgroups_path
44
45 runc run --keep test_run_keep
46 [ "$status" -eq 0 ]
47
48 testcontainer test_run_keep stopped
49
50 runc state test_run_keep
51 [ "$status" -eq 0 ]
52
53 # check that cgroup exists
54 check_cgroup_value "pids.max" "max"
55
56 runc delete test_run_keep
57
58 runc state test_run_keep
59 [ "$status" -ne 0 ]
60}
61
62# https://github.com/opencontainers/runc/issues/3952
63@test "runc run with tmpfs" {
64 requires root
65
66 chmod 'a=rwx,ug+s,+t' rootfs/tmp # set all bits
67 mode=$(stat -c %A rootfs/tmp)
68
69 # shellcheck disable=SC2016
70 update_config '.process.args = ["sh", "-c", "stat -c %A /tmp"]'
71 update_config '.mounts += [{"destination": "/tmp", "type": "tmpfs", "source": "tmpfs", "options":["noexec","nosuid","nodev","rprivate"]}]'
72
73 runc run test_tmpfs
74 [ "$status" -eq 0 ]
75 [ "$output" = "$mode" ]
76}
77
78@test "runc run with tmpfs perms" {
79 # shellcheck disable=SC2016
80 update_config '.process.args = ["sh", "-c", "stat -c %a /tmp/test"]'
81 update_config '.mounts += [{"destination": "/tmp/test", "type": "tmpfs", "source": "tmpfs", "options": ["mode=0444"]}]'
82
83 # Directory is to be created by runc.
84 runc run test_tmpfs
85 [ "$status" -eq 0 ]
86 [ "$output" = "444" ]
87
88 # Run a 2nd time with the pre-existing directory.
89 # Ref: https://github.com/opencontainers/runc/issues/3911
90 runc run test_tmpfs
91 [ "$status" -eq 0 ]
92 [ "$output" = "444" ]
93
94 # Existing directory, custom perms, no mode on the mount,
95 # so it should use the directory's perms.
96 update_config '.mounts[-1].options = []'
97 chmod 0710 rootfs/tmp/test
98 # shellcheck disable=SC2016
99 runc run test_tmpfs
100 [ "$status" -eq 0 ]
101 [ "$output" = "710" ]
102
103 # Add back the mode on the mount, and it should use that instead.
104 # Just for fun, use different perms than was used earlier.
105 # shellcheck disable=SC2016
106 update_config '.mounts[-1].options = ["mode=0410"]'
107 runc run test_tmpfs
108 [ "$status" -eq 0 ]
109 [ "$output" = "410" ]
110}
111
112@test "runc run [joining existing container namespaces]" {
113 # Create a detached container with the namespaces we want. We notably want
114 # to include userns, which requires config-related configuration.
115 if [ $EUID -eq 0 ]; then
116 update_config '.linux.namespaces += [{"type": "user"}]
117 | .linux.uidMappings += [{"containerID": 0, "hostID": 100000, "size": 100}]
118 | .linux.gidMappings += [{"containerID": 0, "hostID": 200000, "size": 200}]'
119 mkdir -p rootfs/{proc,sys,tmp}
120 fi
121 update_config '.process.args = ["sleep", "infinity"]'
122
123 runc run -d --console-socket "$CONSOLE_SOCKET" target_ctr
124 [ "$status" -eq 0 ]
125
126 # Modify our container's configuration such that it is just going to
127 # inherit all of the namespaces of the target container.
128 #
129 # NOTE: We cannot join the mount namespace of another container because of
130 # some quirks of the runtime-spec. In particular, we MUST pivot_root into
131 # root.path and root.path MUST be set in the config, so runc cannot just
132 # ignore root.path when joining namespaces (and root.path doesn't exist
133 # inside root.path, for obvious reasons).
134 #
135 # We could hack around this (create a copy of the rootfs inside the rootfs,
136 # or use a simpler mount namespace target), but those wouldn't be similar
137 # tests to the other namespace joining tests.
138 target_pid="$(__runc state target_ctr | jq .pid)"
139 update_config '.linux.namespaces |= map_values(.path = if .type == "mount" then "" else "/proc/'"$target_pid"'/ns/" + ({"network": "net", "mount": "mnt"}[.type] // .type) end)'
140 # Remove the userns configuration (it cannot be changed).
141 update_config '.linux |= (del(.uidMappings) | del(.gidMappings))'
142
143 runc run -d --console-socket "$CONSOLE_SOCKET" attached_ctr
144 [ "$status" -eq 0 ]
145
146 # Make sure there are two sleep processes in our container.
147 runc exec attached_ctr ps aux
148 [ "$status" -eq 0 ]
149 run -0 grep "sleep infinity" <<<"$output"
150 [ "${#lines[@]}" -eq 2 ]
151
152 # ... that the userns mappings are the same...
153 runc exec attached_ctr cat /proc/self/uid_map
154 [ "$status" -eq 0 ]
155 if [ $EUID -eq 0 ]; then
156 grep -E '^\s+0\s+100000\s+100$' <<<"$output"
157 else
158 grep -E '^\s+0\s+'$EUID'\s+1$' <<<"$output"
159 fi
160 runc exec attached_ctr cat /proc/self/gid_map
161 [ "$status" -eq 0 ]
162 if [ $EUID -eq 0 ]; then
163 grep -E '^\s+0\s+200000\s+200$' <<<"$output"
164 else
165 grep -E '^\s+0\s+'$EUID'\s+1$' <<<"$output"
166 fi
167}
View as plain text