mirror of https://github.com/containers/podman.git
CI: make systemd tests parallel-safe (*)
Mostly just switch to safename. Rewrite setup() to guarantee unique service file names, atomically created. * IMPORTANT NOTE: enabling parallelization on these tests triggers #24010 ("fragment file" flake), but only on my f40 laptop. I have never seen the flake in Cirrus despite many many runs in #23275. I am submitting this for review and merging because even though _something_ is broken, this breakage is unlikely to affect our CI. Signed-off-by: Ed Santiago <santiago@redhat.com>
This commit is contained in:
parent
bb6b2e9e85
commit
faf4604883
|
@ -3,23 +3,29 @@
|
||||||
# Tests generated configurations for systemd.
|
# Tests generated configurations for systemd.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# bats file_tags=ci:parallel
|
||||||
|
|
||||||
load helpers
|
load helpers
|
||||||
load helpers.systemd
|
load helpers.systemd
|
||||||
load helpers.network
|
load helpers.network
|
||||||
|
|
||||||
SERVICE_NAME="podman_test_$(random_string)"
|
SERVICE_NAME=
|
||||||
|
|
||||||
UNIT_FILE="$UNIT_DIR/$SERVICE_NAME.service"
|
UNIT_FILE=
|
||||||
TEMPLATE_FILE="$UNIT_DIR/$SERVICE_NAME@.service"
|
TEMPLATE_FILE=
|
||||||
|
|
||||||
function setup() {
|
function setup() {
|
||||||
skip_if_remote "systemd tests are meaningless over remote"
|
skip_if_remote "systemd tests are meaningless over remote"
|
||||||
|
|
||||||
|
SERVICE_NAME="podman-test-$(safename)"
|
||||||
|
UNIT_FILE="$UNIT_DIR/$SERVICE_NAME.service"
|
||||||
|
TEMPLATE_FILE="$UNIT_DIR/$SERVICE_NAME@.service"
|
||||||
|
|
||||||
basic_setup
|
basic_setup
|
||||||
}
|
}
|
||||||
|
|
||||||
function teardown() {
|
function teardown() {
|
||||||
if [[ -e "$UNIT_FILE" ]]; then
|
if [[ -n "$UNIT_FILE" ]] && [[ -e "$UNIT_FILE" ]]; then
|
||||||
run systemctl stop "$SERVICE_NAME"
|
run systemctl stop "$SERVICE_NAME"
|
||||||
if [ $status -ne 0 ]; then
|
if [ $status -ne 0 ]; then
|
||||||
echo "# WARNING: systemctl stop failed in teardown: $output" >&3
|
echo "# WARNING: systemctl stop failed in teardown: $output" >&3
|
||||||
|
@ -32,6 +38,20 @@ function teardown() {
|
||||||
basic_teardown
|
basic_teardown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Helper to atomically create a systemd unit file from a tmpfile
|
||||||
|
#
|
||||||
|
# Context:
|
||||||
|
# $1 - file created by podman generate systemd; presumed to be in a tmpdir
|
||||||
|
# $2 - desired service file path, presumed to be in /run
|
||||||
|
#
|
||||||
|
# We can't just mv one to the other, because mv is not atomic across
|
||||||
|
# filesystems. (We need atomic, to guarantee that there will never
|
||||||
|
# be an incomplete .service file). Hence the tmp extension.
|
||||||
|
# -Z is because /run and $TMPDIR have different SELinux contexts.
|
||||||
|
function mv-safely() {
|
||||||
|
mv -Z "$1" "$2.tmp.$$" && mv -Z "$2.tmp.$$" "$2"
|
||||||
|
}
|
||||||
|
|
||||||
# Helper to start a systemd service running a container
|
# Helper to start a systemd service running a container
|
||||||
function service_setup() {
|
function service_setup() {
|
||||||
# January 2024: we can no longer do "run_podman generate systemd" followed
|
# January 2024: we can no longer do "run_podman generate systemd" followed
|
||||||
|
@ -40,12 +60,12 @@ function service_setup() {
|
||||||
# stdout + stderr, that warning goes to the unit file. (Today's systemd
|
# stdout + stderr, that warning goes to the unit file. (Today's systemd
|
||||||
# is forgiving about that, but RHEL8 systemd chokes with EINVAL)
|
# is forgiving about that, but RHEL8 systemd chokes with EINVAL)
|
||||||
(
|
(
|
||||||
cd $UNIT_DIR
|
cd $PODMAN_TMPDIR
|
||||||
run_podman generate systemd --files --name \
|
run_podman generate systemd --files --name \
|
||||||
-e http_proxy -e https_proxy -e no_proxy \
|
-e http_proxy -e https_proxy -e no_proxy \
|
||||||
-e HTTP_PROXY -e HTTPS_PROXY -e NO_PROXY \
|
-e HTTP_PROXY -e HTTPS_PROXY -e NO_PROXY \
|
||||||
--new $cname
|
--new $cname
|
||||||
mv "container-$cname.service" $UNIT_FILE
|
mv-safely "container-$cname.service" $UNIT_FILE
|
||||||
)
|
)
|
||||||
run_podman rm $cname
|
run_podman rm $cname
|
||||||
|
|
||||||
|
@ -92,7 +112,7 @@ function service_cleanup() {
|
||||||
"generate systemd emits warning"
|
"generate systemd emits warning"
|
||||||
run_podman rm -f $cid
|
run_podman rm -f $cid
|
||||||
|
|
||||||
cname=$(random_string)
|
cname=c-$(safename)
|
||||||
# See #7407 for --pull=always.
|
# See #7407 for --pull=always.
|
||||||
run_podman create --pull=always --name $cname --label "io.containers.autoupdate=registry" $IMAGE \
|
run_podman create --pull=always --name $cname --label "io.containers.autoupdate=registry" $IMAGE \
|
||||||
sh -c "trap 'echo Received SIGTERM, finishing; exit' SIGTERM; echo WAITING; while :; do sleep 0.1; done"
|
sh -c "trap 'echo Received SIGTERM, finishing; exit' SIGTERM; echo WAITING; while :; do sleep 0.1; done"
|
||||||
|
@ -112,10 +132,10 @@ function service_cleanup() {
|
||||||
|
|
||||||
@test "podman autoupdate local" {
|
@test "podman autoupdate local" {
|
||||||
# Note that the entrypoint may be a JSON string which requires preserving the quotes (see #12477)
|
# Note that the entrypoint may be a JSON string which requires preserving the quotes (see #12477)
|
||||||
cname=$(random_string)
|
cname=c-$(safename)
|
||||||
|
|
||||||
# Create a scratch image (copy of our regular one)
|
# Create a scratch image (copy of our regular one)
|
||||||
image_copy=base$(random_string | tr A-Z a-z)
|
image_copy=base-$(safename)
|
||||||
run_podman tag $IMAGE $image_copy
|
run_podman tag $IMAGE $image_copy
|
||||||
|
|
||||||
# Create a container based on that
|
# Create a container based on that
|
||||||
|
@ -140,7 +160,7 @@ function service_cleanup() {
|
||||||
# These tests can fail in dev. environment because of SELinux.
|
# These tests can fail in dev. environment because of SELinux.
|
||||||
# quick fix: chcon -t container_runtime_exec_t ./bin/podman
|
# quick fix: chcon -t container_runtime_exec_t ./bin/podman
|
||||||
@test "podman generate systemd - envar" {
|
@test "podman generate systemd - envar" {
|
||||||
cname=$(random_string)
|
cname=c-$(safename)
|
||||||
FOO=value BAR=%s run_podman create --name $cname --env FOO -e BAR --env MYVAR=myval \
|
FOO=value BAR=%s run_podman create --name $cname --env FOO -e BAR --env MYVAR=myval \
|
||||||
$IMAGE sh -c 'printenv && echo READY; trap 'exit' SIGTERM; while :; do sleep 0.1; done'
|
$IMAGE sh -c 'printenv && echo READY; trap 'exit' SIGTERM; while :; do sleep 0.1; done'
|
||||||
|
|
||||||
|
@ -162,19 +182,19 @@ function service_cleanup() {
|
||||||
|
|
||||||
# Regression test for #11438
|
# Regression test for #11438
|
||||||
@test "podman generate systemd - restart policy & timeouts" {
|
@test "podman generate systemd - restart policy & timeouts" {
|
||||||
cname=$(random_string)
|
cname=c1-$(safename)
|
||||||
run_podman create --restart=always --name $cname $IMAGE
|
run_podman create --restart=always --name $cname $IMAGE
|
||||||
run_podman generate systemd --new $cname
|
run_podman generate systemd --new $cname
|
||||||
is "$output" ".*Restart=always.*" "Use container's restart policy if set"
|
is "$output" ".*Restart=always.*" "Use container's restart policy if set"
|
||||||
run_podman generate systemd --new --restart-policy=on-failure $cname
|
run_podman generate systemd --new --restart-policy=on-failure $cname
|
||||||
is "$output" ".*Restart=on-failure.*" "Override container's restart policy"
|
is "$output" ".*Restart=on-failure.*" "Override container's restart policy"
|
||||||
|
|
||||||
cname2=$(random_string)
|
cname2=c2-$(safename)
|
||||||
run_podman create --restart=unless-stopped --name $cname2 $IMAGE
|
run_podman create --restart=unless-stopped --name $cname2 $IMAGE
|
||||||
run_podman generate systemd --new $cname2
|
run_podman generate systemd --new $cname2
|
||||||
is "$output" ".*Restart=always.*" "unless-stopped translated to always"
|
is "$output" ".*Restart=always.*" "unless-stopped translated to always"
|
||||||
|
|
||||||
cname3=$(random_string)
|
cname3=c3-$(safename)
|
||||||
run_podman create --restart=on-failure:42 --name $cname3 $IMAGE
|
run_podman create --restart=on-failure:42 --name $cname3 $IMAGE
|
||||||
run_podman generate systemd --new $cname3
|
run_podman generate systemd --new $cname3
|
||||||
is "$output" ".*Restart=on-failure.*" "on-failure:xx is parsed correctly"
|
is "$output" ".*Restart=on-failure.*" "on-failure:xx is parsed correctly"
|
||||||
|
@ -230,14 +250,14 @@ LISTEN_FDNAMES=listen_fdnames" | sort)
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "podman generate - systemd template" {
|
@test "podman generate - systemd template" {
|
||||||
cname=$(random_string)
|
cname=c-$(safename)
|
||||||
run_podman create --name $cname $IMAGE top
|
run_podman create --name $cname $IMAGE top
|
||||||
|
|
||||||
# See note in service_setup() above re: using --files
|
# See note in service_setup() above re: using --files
|
||||||
(
|
(
|
||||||
cd $UNIT_DIR
|
cd $PODMAN_TMPDIR
|
||||||
run_podman generate systemd --template --files -n $cname
|
run_podman generate systemd --template --files -n $cname
|
||||||
mv "container-$cname.service" $TEMPLATE_FILE
|
mv-safely "container-$cname.service" $TEMPLATE_FILE
|
||||||
)
|
)
|
||||||
run_podman rm -f $cname
|
run_podman rm -f $cname
|
||||||
|
|
||||||
|
@ -257,8 +277,8 @@ LISTEN_FDNAMES=listen_fdnames" | sort)
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "podman generate - systemd template no support for pod" {
|
@test "podman generate - systemd template no support for pod" {
|
||||||
cname=$(random_string)
|
cname=c-$(safename)
|
||||||
podname=$(random_string)
|
podname=p-$(safename)
|
||||||
run_podman pod create --name $podname
|
run_podman pod create --name $podname
|
||||||
run_podman run --pod $podname -dt --name $cname $IMAGE top
|
run_podman run --pod $podname -dt --name $cname $IMAGE top
|
||||||
|
|
||||||
|
@ -267,11 +287,10 @@ LISTEN_FDNAMES=listen_fdnames" | sort)
|
||||||
|
|
||||||
run_podman rm -f $cname
|
run_podman rm -f $cname
|
||||||
run_podman pod rm -f $podname
|
run_podman pod rm -f $podname
|
||||||
run_podman rmi $(pause_image)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "podman generate - systemd template only used on --new" {
|
@test "podman generate - systemd template only used on --new" {
|
||||||
cname=$(random_string)
|
cname=c-$(safename)
|
||||||
run_podman create --name $cname $IMAGE top
|
run_podman create --name $cname $IMAGE top
|
||||||
run_podman 125 generate systemd --new=false --template -n $cname
|
run_podman 125 generate systemd --new=false --template -n $cname
|
||||||
is "$output" ".*--template cannot be set" "Error message should be '--template requires --new'"
|
is "$output" ".*--template cannot be set" "Error message should be '--template requires --new'"
|
||||||
|
@ -284,11 +303,12 @@ LISTEN_FDNAMES=listen_fdnames" | sort)
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "podman --systemd sets container_uuid" {
|
@test "podman --systemd sets container_uuid" {
|
||||||
run_podman run --systemd=always --name test $IMAGE printenv container_uuid
|
cname=c-$(safename)
|
||||||
|
run_podman run --systemd=always --name $cname $IMAGE printenv container_uuid
|
||||||
container_uuid=$output
|
container_uuid=$output
|
||||||
run_podman inspect test --format '{{ .ID }}'
|
run_podman inspect $cname --format '{{ .ID }}'
|
||||||
is "${container_uuid}" "${output:0:32}" "UUID should be first 32 chars of Container id"
|
is "${container_uuid}" "${output:0:32}" "UUID should be first 32 chars of Container id"
|
||||||
run_podman rm test
|
run_podman rm $cname
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "podman --systemd fails on cgroup v1 with a private cgroupns" {
|
@test "podman --systemd fails on cgroup v1 with a private cgroupns" {
|
||||||
|
@ -302,8 +322,8 @@ LISTEN_FDNAMES=listen_fdnames" | sort)
|
||||||
@test "podman rootless-netns processes should be in different cgroup" {
|
@test "podman rootless-netns processes should be in different cgroup" {
|
||||||
is_rootless || skip "only meaningful for rootless"
|
is_rootless || skip "only meaningful for rootless"
|
||||||
|
|
||||||
cname=$(random_string)
|
cname=c-$(safename)
|
||||||
local netname=testnet-$(random_string 10)
|
local netname=testnet-$(safename)
|
||||||
|
|
||||||
# create network and container with network
|
# create network and container with network
|
||||||
run_podman network create $netname
|
run_podman network create $netname
|
||||||
|
@ -313,7 +333,7 @@ LISTEN_FDNAMES=listen_fdnames" | sort)
|
||||||
service_setup
|
service_setup
|
||||||
|
|
||||||
# run second container with network
|
# run second container with network
|
||||||
cname2=$(random_string)
|
cname2=c2-$(safename)
|
||||||
run_podman run -d --name $cname2 --network $netname $IMAGE top
|
run_podman run -d --name $cname2 --network $netname $IMAGE top
|
||||||
|
|
||||||
# stop systemd container
|
# stop systemd container
|
||||||
|
@ -332,7 +352,7 @@ LISTEN_FDNAMES=listen_fdnames" | sort)
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "podman create --health-on-failure=kill" {
|
@test "podman create --health-on-failure=kill" {
|
||||||
cname=c_$(random_string)
|
cname=c-$(safename)
|
||||||
run_podman create --name $cname \
|
run_podman create --name $cname \
|
||||||
--health-cmd /home/podman/healthcheck \
|
--health-cmd /home/podman/healthcheck \
|
||||||
--health-on-failure=kill \
|
--health-on-failure=kill \
|
||||||
|
@ -387,30 +407,33 @@ LISTEN_FDNAMES=listen_fdnames" | sort)
|
||||||
install_kube_template
|
install_kube_template
|
||||||
# Create the YAMl file
|
# Create the YAMl file
|
||||||
yaml_source="$PODMAN_TMPDIR/test.yaml"
|
yaml_source="$PODMAN_TMPDIR/test.yaml"
|
||||||
|
podname=p-$(safename)
|
||||||
|
c1=c1-$(safename)
|
||||||
|
c2=c2-$(safename)
|
||||||
cat >$yaml_source <<EOF
|
cat >$yaml_source <<EOF
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Pod
|
kind: Pod
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
io.containers.autoupdate: "local"
|
io.containers.autoupdate: "local"
|
||||||
io.containers.autoupdate/b: "registry"
|
io.containers.autoupdate/$c2: "registry"
|
||||||
labels:
|
labels:
|
||||||
app: test
|
app: test
|
||||||
name: test_pod
|
name: $podname
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- command:
|
- command:
|
||||||
- sh
|
- sh
|
||||||
- -c
|
- -c
|
||||||
- echo a stdout; echo a stderr 1>&2; trap 'exit' SIGTERM; while :; do sleep 0.1; done
|
- echo c1 stdout; echo c1 stderr 1>&2; trap 'exit' SIGTERM; while :; do sleep 0.1; done
|
||||||
image: $IMAGE
|
image: $IMAGE
|
||||||
name: a
|
name: $c1
|
||||||
- command:
|
- command:
|
||||||
- sh
|
- sh
|
||||||
- -c
|
- -c
|
||||||
- echo b stdout; echo b stderr 1>&2; trap 'exit' SIGTERM; while :; do sleep 0.1; done
|
- echo c2 stdout; echo c2 stderr 1>&2; trap 'exit' SIGTERM; while :; do sleep 0.1; done
|
||||||
image: $IMAGE
|
image: $IMAGE
|
||||||
name: b
|
name: $c2
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Dispatch the YAML file
|
# Dispatch the YAML file
|
||||||
|
@ -436,29 +459,29 @@ EOF
|
||||||
is "$output" "Error: container .* is the service container of pod(s) .* and cannot be removed without removing the pod(s)"
|
is "$output" "Error: container .* is the service container of pod(s) .* and cannot be removed without removing the pod(s)"
|
||||||
|
|
||||||
# containers/podman/issues/17482: verify that the log-driver for the Pod's containers is NOT passthrough
|
# containers/podman/issues/17482: verify that the log-driver for the Pod's containers is NOT passthrough
|
||||||
for name in "a" "b"; do
|
for name in "c1" "c2"; do
|
||||||
run_podman container inspect test_pod-${name} --format "{{.HostConfig.LogConfig.Type}}"
|
run_podman container inspect ${podname}-${!name} --format "{{.HostConfig.LogConfig.Type}}"
|
||||||
assert $output != "passthrough"
|
assert $output != "passthrough"
|
||||||
# check that we can get the logs with passthrough when we run in a systemd unit
|
# check that we can get the logs with passthrough when we run in a systemd unit
|
||||||
run_podman logs test_pod-$name
|
run_podman logs ${podname}-${!name}
|
||||||
assert "$output" == "$name stdout
|
assert "$output" == "$name stdout
|
||||||
$name stderr" "logs work with passthrough"
|
$name stderr" "logs work with passthrough"
|
||||||
done
|
done
|
||||||
|
|
||||||
# we cannot assume the ordering between a b, this depends on timing and would flake in CI
|
# we cannot assume the ordering between a b, this depends on timing and would flake in CI
|
||||||
# use --names so we do not have to get the ID
|
# use --names so we do not have to get the ID
|
||||||
run_podman pod logs --names test_pod
|
run_podman pod logs --names $podname
|
||||||
assert "$output" =~ ".*^test_pod-a a stdout.*" "logs from container a shown"
|
assert "$output" =~ ".*^${podname}-${c1} c1 stdout.*" "logs from container 1 shown"
|
||||||
assert "$output" =~ ".*^test_pod-b b stdout.*" "logs from container b shown"
|
assert "$output" =~ ".*^${podname}-${c2} c2 stdout.*" "logs from container 2 shown"
|
||||||
|
|
||||||
# Add a simple `auto-update --dry-run` test here to avoid too much redundancy
|
# Add a simple `auto-update --dry-run` test here to avoid too much redundancy
|
||||||
# with 255-auto-update.bats
|
# with 255-auto-update.bats
|
||||||
run_podman auto-update --dry-run --format "{{.Unit}},{{.Container}},{{.Image}},{{.Updated}},{{.Policy}}"
|
run_podman auto-update --dry-run --format "{{.Unit}},{{.Container}},{{.Image}},{{.Updated}},{{.Policy}}"
|
||||||
is "$output" ".*$service_name,.* (test_pod-a),$IMAGE,false,local.*" "global auto-update policy gets applied"
|
is "$output" ".*$service_name,.* (${podname}-${c1}),$IMAGE,false,local.*" "global auto-update policy gets applied"
|
||||||
is "$output" ".*$service_name,.* (test_pod-b),$IMAGE,false,registry.*" "container-specified auto-update policy gets applied"
|
is "$output" ".*$service_name,.* (${podname}-${c2}),$IMAGE,false,registry.*" "container-specified auto-update policy gets applied"
|
||||||
|
|
||||||
# Kill the pod and make sure the service is not running.
|
# Kill the pod and make sure the service is not running.
|
||||||
run_podman pod kill test_pod
|
run_podman pod kill $podname
|
||||||
for i in {0..20}; do
|
for i in {0..20}; do
|
||||||
# echos are for debugging test flakes
|
# echos are for debugging test flakes
|
||||||
echo "$_LOG_PROMPT systemctl is-active $service_name"
|
echo "$_LOG_PROMPT systemctl is-active $service_name"
|
||||||
|
@ -481,26 +504,25 @@ $name stderr" "logs work with passthrough"
|
||||||
# Clean up
|
# Clean up
|
||||||
systemctl stop $service_name
|
systemctl stop $service_name
|
||||||
run_podman 1 container exists $service_container
|
run_podman 1 container exists $service_container
|
||||||
run_podman 1 pod exists test_pod
|
run_podman 1 pod exists $podname
|
||||||
run_podman rmi $(pause_image)
|
|
||||||
run_podman network rm podman-default-kube-network
|
|
||||||
rm -f $UNIT_DIR/$unit_name
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "podman generate - systemd - DEPRECATED" {
|
@test "podman generate - systemd - DEPRECATED" {
|
||||||
run_podman generate systemd --help
|
run_podman generate systemd --help
|
||||||
is "$output" ".*[DEPRECATED] command:"
|
is "$output" ".*[DEPRECATED] command:"
|
||||||
is "$output" ".*\[DEPRECATED\] Generate systemd units.*"
|
is "$output" ".*\[DEPRECATED\] Generate systemd units.*"
|
||||||
run_podman create --name test $IMAGE
|
|
||||||
run_podman generate systemd test >/dev/null
|
cname=c-$(safename)
|
||||||
|
run_podman create --name $cname $IMAGE
|
||||||
|
run_podman generate systemd $cname >/dev/null
|
||||||
is "$output" ".*[DEPRECATED] command:"
|
is "$output" ".*[DEPRECATED] command:"
|
||||||
run_podman generate --help
|
run_podman generate --help
|
||||||
is "$output" ".*\[DEPRECATED\] Generate systemd units"
|
is "$output" ".*\[DEPRECATED\] Generate systemd units"
|
||||||
run_podman rm test
|
run_podman rm $cname
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "podman passes down the KillSignal and StopTimeout setting" {
|
@test "podman passes down the KillSignal and StopTimeout setting" {
|
||||||
ctr=systemd_test_$(random_string 5)
|
ctr=systemd_test_$(safename)
|
||||||
|
|
||||||
run_podman run -d --name $ctr --stop-signal 5 --stop-timeout 7 --rm $IMAGE top
|
run_podman run -d --name $ctr --stop-signal 5 --stop-timeout 7 --rm $IMAGE top
|
||||||
run_podman inspect $ctr --format '{{ .Id }}'
|
run_podman inspect $ctr --format '{{ .Id }}'
|
||||||
|
|
Loading…
Reference in New Issue