File: 800-config.bats

package info (click to toggle)
podman 5.4.2%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 23,124 kB
  • sloc: sh: 6,119; perl: 2,710; python: 2,258; ansic: 1,556; makefile: 1,022; xml: 121; ruby: 42; awk: 12; csh: 8
file content (272 lines) | stat: -rw-r--r-- 10,680 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
#!/usr/bin/env bats   -*- bats -*-
#
# Test specific configuration options and overrides
#

load helpers

@test "podman CONTAINERS_CONF - CONTAINERS_CONF in conmon" {
    skip_if_remote "can't check conmon environment over remote"

    # Get the normal runtime for this host
    run_podman info --format '{{ .Host.OCIRuntime.Name }}'
    runtime="$output"
    run_podman info --format "{{ .Host.OCIRuntime.Path }}"
    ocipath="$output"
    run_podman info --format '{{ .Host.DatabaseBackend }}'
    db_backend="$output"

    # Make an innocuous containers.conf in a non-standard location
    conf_tmp="$PODMAN_TMPDIR/containers.conf"
    cat >$conf_tmp <<EOF
[engine]
runtime="$runtime"
database_backend="$db_backend"
[engine.runtimes]
$runtime = ["$ocipath"]
EOF
    CONTAINERS_CONF="$conf_tmp" run_podman run -d $IMAGE sleep infinity
    cid="$output"

    CONTAINERS_CONF="$conf_tmp" run_podman inspect "$cid" --format "{{ .State.ConmonPid }}"
    conmon="$output"

    output="$(tr '\0' '\n' < /proc/$conmon/environ | grep '^CONTAINERS_CONF=')"
    is "$output" "CONTAINERS_CONF=$conf_tmp"

    # Clean up
    # Oddly, sleep can't be interrupted with SIGTERM, so we need the
    # "-f -t 0" to force a SIGKILL
    CONTAINERS_CONF="$conf_tmp" run_podman rm -f -t 0 "$cid"
}

@test "podman CONTAINERS_CONF - override runtime name" {
    skip_if_remote "Can't set CONTAINERS_CONF over remote"

    # Get the path of the normal runtime
    run_podman info --format "{{ .Host.OCIRuntime.Path }}"
    ocipath="$output"
    run_podman info --format '{{ .Host.DatabaseBackend }}'
    db_backend="$output"

    export conf_tmp="$PODMAN_TMPDIR/nonstandard_runtime_name.conf"
    cat > $conf_tmp <<EOF
[engine]
runtime = "nonstandard_runtime_name"
database_backend="$db_backend"
[engine.runtimes]
nonstandard_runtime_name = ["$ocipath"]
EOF

    CONTAINERS_CONF="$conf_tmp" run_podman run -d --rm $IMAGE true
    cid="$output"

    # We need to wait for the container to finish before we can check
    # if it was cleaned up properly.  But in the common case that the
    # container completes fast, and the cleanup *did* happen properly
    # the container is now gone.  So, we need to ignore "no such
    # container" errors from podman wait.
    CONTAINERS_CONF="$conf_tmp" run_podman '?' wait --condition=removing "$cid"
    if [[ $status != 0 ]]; then
        is "$output" "Error:.*no such container" "unexpected error from podman wait"
    fi

    # The --rm option means the container should no longer exist.
    # However https://github.com/containers/podman/issues/12917 meant
    # that the container cleanup triggered by conmon's --exit-cmd
    # could fail, leaving the container in place.
    #
    # We verify that the container is indeed gone, by checking that a
    # podman rm *fails* here - and it has the side effect of cleaning
    # up in the case this test fails.
    CONTAINERS_CONF="$conf_tmp" run_podman 1 rm "$cid"
    is "$output" "Error:.*no such container"
}

@test "podman --module - absolute path" {
    skip_if_remote "--module is not supported for remote clients"

    random_data="expected_annotation_$(random_string 15)"
    conf_tmp="$PODMAN_TMPDIR/test.conf"
    cat > $conf_tmp <<EOF
[containers]
annotations=['module=$random_data']
EOF

    run_podman 125 create --module=$conf_tmp -q $IMAGE
    is "$output" "Error: unknown flag: --module
See 'podman create --help'" "--module must be specified before the command"

    run_podman --module=$conf_tmp create -q $IMAGE
    cid="$output"
    run_podman container inspect $cid --format '{{index .Config.Annotations "module"}}'
    is "$output" "$random_data" "container annotation should include the one from the --module"

    run_podman rm -f $cid

    # Nonexistent module path with comma
    nonesuch=${PODMAN_TMPDIR}/nonexistent,withcomma
    run_podman 1 --module=$nonesuch sdfsdfdsf
    is "$output" "Failed to obtain podman configuration: could not resolve module \"$nonesuch\": faccessat $nonesuch: no such file or directory" \
       "--module=ENOENT"
}

@test "podman --module - append arrays" {
    skip_if_remote "--module is not supported for remote clients"

    random_data="expected_annotation_$(random_string 15)"
    conf1_tmp="$PODMAN_TMPDIR/test1.conf"
    conf2_tmp="$PODMAN_TMPDIR/test2.conf"
    conf2_off_tmp="$PODMAN_TMPDIR/test2_off.conf"
    cat > $conf1_tmp <<EOF
[containers]
env=["A=CONF1",{append=true}]
EOF
    cat > $conf2_tmp <<EOF
[containers]
env=["B=CONF2"]
EOF

    cat > $conf2_off_tmp <<EOF
[containers]
env=["B=CONF2_OFF",{append=false}]
EOF

    # Once append is set, all subsequent loads (and the current) will be appended.
    run_podman --module=$conf1_tmp --module=$conf2_tmp run --rm $IMAGE printenv A B
    assert "$output" = "CONF1
CONF2"

    # When explicitly turned off, values are replaced/overridden again.
    run_podman 1 --module=$conf1_tmp --module=$conf2_off_tmp run --rm $IMAGE printenv A B
    assert "$output" = "CONF2_OFF"
}

@test "podman --module - XDG_CONFIG_HOME" {
    skip_if_remote "--module is not supported for remote clients"
    skip_if_not_rootless "loading a module from XDG_CONFIG_HOME requires rootless"

    fake_home="$PODMAN_TMPDIR/home/.config"
    fake_modules_dir="$fake_home/containers/containers.conf.modules"
    mkdir -p $fake_modules_dir

    random_data="expected_annotation_$(random_string 15)"
    module_name="test.conf"
    conf_tmp="$fake_modules_dir/$module_name"
    cat > $conf_tmp <<EOF
[containers]
annotations=['module=$random_data']
EOF

    # Test loading a relative path (test.conf) as a module.  This should find
    # the one in the fake XDG_CONFIG_HOME.  We cannot override /etc or
    # /usr/share in the tests here, so for those paths we need to rely on the
    # unit tests in containers/common/pkg/config and manual QE.
    XDG_CONFIG_HOME=$fake_home run_podman --module $module_name run -d -q $IMAGE sleep infinity
    cid="$output"
    run_podman container inspect $cid --format '{{index .Config.Annotations "module"}}'
    is "$output" "$random_data" "container annotation should include the one from the --module"

    # Now make sure that conmon's exit-command points to the _absolute path_ of
    # the module.
    run_podman container inspect $cid --format "{{ .State.ConmonPid }}"
    conmon_pid="$output"
    is "$(< /proc/$conmon_pid/cmdline)" ".*--exit-command-arg--module--exit-command-arg$conf_tmp.*" "conmon's exit-command uses the module"
    run_podman rm -f -t0 $cid

    # Corrupt module file
    cat > $conf_tmp <<EOF
[containers]
sdf=
EOF
    XDG_CONFIG_HOME=$fake_home run_podman 1 --module $module_name
    is "$output" "Failed to obtain podman configuration: reading additional config \"$conf_tmp\": decode configuration $conf_tmp: toml: line 3 (last key \"containers.sdf\"): expected value but found '\n' instead" \
       "Corrupt module file"

    # Nonexistent module name
    nonesuch=assume-this-does-not-exist-$(random_string)
    XDG_CONFIG_HOME=$fake_home run_podman 1 --module=$nonesuch invalid-command
    expect="Failed to obtain podman configuration: could not resolve module \"$nonesuch\": 3 errors occurred:"
    for dir in $fake_home /etc /usr/share;do
        expect+=$'\n\t'"* faccessat $dir/containers/containers.conf.modules/$nonesuch: no such file or directory"
    done
    is "$output" "$expect" "--module=ENOENT : error message"
}

# Too hard to test in 600-completion.bats because of the remote/rootless check
@test "podman --module - command-line completion" {
    skip_if_remote "--module is not supported for remote clients"
    skip_if_not_rootless "loading a module from XDG_CONFIG_HOME requires rootless"

    fake_home="$PODMAN_TMPDIR/home/.config"
    fake_modules_dir="$fake_home/containers/containers.conf.modules"
    mkdir -p $fake_modules_dir

    m1=m1odule_$(random_string)
    m2=m2$(random_string)

    touch $fake_modules_dir/{$m2,$m1}
    XDG_CONFIG_HOME=$fake_home run_podman __completeNoDesc --module ""
    # Even if there are modules in /etc or elsewhere, these will be first
    assert "${lines[0]}" = "$m1" "completion finds module 1"
    assert "${lines[1]}" = "$m2" "completion finds module 2"
}

@test "podman --module - supported fields" {
    skip_if_remote "--module is not supported for remote clients"

    conf_tmp="$PODMAN_TMPDIR/test.conf"
    cat > $conf_tmp <<EOF
[containers]
env_host=true
privileged=true
EOF

    random_env_var="expected_env_var_$(random_string 15)"
    FOO="$random_env_var" run_podman --module=$conf_tmp run -d --name=$cname $IMAGE top
    cname="$output"

    # Make sure `env_host` is read
    # Only print the env vars that start with "FOO" to avoid printing output that
    # may be considered problematic (see run_podman in helpers.bash).
    run_podman container inspect $cname --format '{{range .Config.Env}} {{if eq "F" (slice . 0 1) }} {{.}} {{end}} {{end}}'
    assert "$output" =~ "FOO=$random_env_var" "--module should yield injecting host env vars into the container"

    # Make sure `privileged` is read during container creation
    run_podman container inspect $cname --format "{{.HostConfig.Privileged}}"
    assert "$output" = "true" "--module should enable a privileged container"

    run_podman rm -f -t0 $cname

    # Make sure `privileged` is read during exec, which requires running a
    # non-privileged container.
    run_podman run -d $IMAGE top
    cname="$output"

    run_podman container exec $cname grep CapBnd /proc/self/status
    non_privileged_caps="$output"
    run_podman --module=$conf_tmp container exec $cname grep CapBnd /proc/self/status
    assert "$output" != "$non_privileged_caps" "--module should enable a privileged exec session"

    run_podman rm -f -t0 $cname
}

@test "podman push CONTAINERS_CONF" {
    skip_if_remote "containers.conf does not effect client side of --remote"

    CONTAINERS_CONF=/dev/null run_podman push --help
    assert "$output" =~ "--compression-format string.*compression format to use \(default \"gzip\"\)" "containers.conf should set default to gzip"
    assert "$output" !~ "compression level to use \(default" "containers.conf should not set default compressionlevel"

    conf_tmp="$PODMAN_TMPDIR/containers.conf"
    cat >$conf_tmp <<EOF
[engine]
compression_format="zstd:chunked"
compression_level=1
EOF
    CONTAINERS_CONF="$conf_tmp" run_podman push --help
    assert "$output" =~ "--compression-format string.*compression format to use \(default \"zstd:chunked\"\)" "containers.conf should set default to zstd:chunked"
    assert "$output" =~ "--compression-level int.*compression level to use \(default 1\)" "containers.conf should set default compressionlevel to 1"
}

# vim: filetype=sh