Files
podman/test/system/700-play.bats
Valentin Rothberg 8684d41e38 k8systemd: run k8s workloads in systemd
Support running `podman play kube` in systemd by exploiting the
previously added "service containers".  During `play kube`, a service
container is started before all the pods and containers, and is stopped
last.  The service container communicates its conmon PID via sdnotify.

Add a new systemd template to dispatch such k8s workloads.  The argument
of the template is the path to the k8s file.  Note that the path must be
escaped for systemd not to bark:

Let's assume we have a `top.yaml` file in the home directory:
```
$ escaped=$(systemd-escape ~/top.yaml)
$ systemctl --user start podman-play-kube@$escaped.service
```

Closes: https://issues.redhat.com/browse/RUN-1287
Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
2022-05-17 10:18:58 +02:00

357 lines
10 KiB
Bash

#!/usr/bin/env bats -*- bats -*-
#
# Test podman play
#
load helpers
# This is a long ugly way to clean up pods and remove the pause image
function teardown() {
run_podman pod rm -t 0 -f -a
run_podman rm -t 0 -f -a
run_podman image list --format '{{.ID}} {{.Repository}}'
while read id name; do
if [[ "$name" =~ /podman-pause ]]; then
run_podman rmi $id
fi
done <<<"$output"
basic_teardown
}
testYaml="
apiVersion: v1
kind: Pod
metadata:
labels:
app: test
name: test_pod
spec:
containers:
- command:
- sleep
- \"100\"
env:
- name: PATH
value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- name: TERM
value: xterm
- name: container
value: podman
image: $IMAGE
name: test
resources: {}
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
allowPrivilegeEscalation: true
capabilities: {}
privileged: false
seLinuxOptions:
level: \"s0:c1,c2\"
readOnlyRootFilesystem: false
volumeMounts:
- mountPath: /testdir:z
name: home-podman-testdir
workingDir: /
volumes:
- hostPath:
path: TESTDIR
type: Directory
name: home-podman-testdir
status: {}
"
RELABEL="system_u:object_r:container_file_t:s0"
@test "podman play with stdin" {
TESTDIR=$PODMAN_TMPDIR/testdir
mkdir -p $TESTDIR
echo "$testYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml
run_podman play kube - < $PODMAN_TMPDIR/test.yaml
if [ -e /usr/sbin/selinuxenabled -a /usr/sbin/selinuxenabled ]; then
run ls -Zd $TESTDIR
is "$output" "${RELABEL} $TESTDIR" "selinux relabel should have happened"
fi
# Make sure that the K8s pause image isn't pulled but the local podman-pause is built.
run_podman images
run_podman 1 image exists k8s.gcr.io/pause
run_podman version --format "{{.Server.Version}}-{{.Server.Built}}"
run_podman image exists localhost/podman-pause:$output
run_podman stop -a -t 0
run_podman pod rm -t 0 -f test_pod
}
@test "podman play" {
TESTDIR=$PODMAN_TMPDIR/testdir
mkdir -p $TESTDIR
echo "$testYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml
run_podman play kube $PODMAN_TMPDIR/test.yaml
if [ -e /usr/sbin/selinuxenabled -a /usr/sbin/selinuxenabled ]; then
run ls -Zd $TESTDIR
is "$output" "${RELABEL} $TESTDIR" "selinux relabel should have happened"
fi
run_podman stop -a -t 0
run_podman pod rm -t 0 -f test_pod
}
@test "podman play --service-container" {
skip_if_remote "service containers only work locally"
# Create the YAMl file
yaml_source="$PODMAN_TMPDIR/test.yaml"
cat >$yaml_source <<EOF
apiVersion: v1
kind: Pod
metadata:
labels:
app: test
name: test_pod
spec:
containers:
- command:
- top
image: $IMAGE
name: test
resources: {}
EOF
run_podman play kube --service-container=true $yaml_source
# The name of the service container is predictable: the first 12 characters
# of the hash of the YAML file followed by the "-service" suffix
yaml_sha=$(sha256sum $yaml_source)
service_container="${yaml_sha:0:12}-service"
# Make sure that the service container exists and runs.
run_podman container inspect $service_container --format "{{.State.Running}}"
is "$output" "true"
# Stop the *main* container and make sure that
# 1) The pod transitions to Exited
# 2) The service container is stopped
# #) The service container is marked as an service container
run_podman stop test_pod-test
_ensure_pod_state test_pod Exited
_ensure_container_running $service_container false
run_podman container inspect $service_container --format "{{.IsService}}"
is "$output" "true"
# Restart the pod, make sure the service is running again
run_podman pod restart test_pod
run_podman container inspect $service_container --format "{{.State.Running}}"
is "$output" "true"
# Check for an error when trying to remove the service container
run_podman 125 container rm $service_container
is "$output" "Error: container .* is the service container of pod(s) .* and cannot be removed without removing the pod(s)"
# Kill the pod and make sure the service is not running
run_podman pod kill test_pod
_ensure_container_running $service_container false
# Remove the pod and make sure the service is removed along with it
run_podman pod rm test_pod
run_podman 1 container exists $service_container
}
@test "podman play --network" {
TESTDIR=$PODMAN_TMPDIR/testdir
mkdir -p $TESTDIR
echo "$testYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml
run_podman 125 play kube --network host $PODMAN_TMPDIR/test.yaml
is "$output" ".*invalid value passed to --network: bridge or host networking must be configured in YAML" "podman plan-network should fail with --network host"
run_podman play kube --network slirp4netns:port_handler=slirp4netns $PODMAN_TMPDIR/test.yaml
run_podman pod inspect --format {{.InfraContainerID}} "${lines[1]}"
infraID="$output"
run_podman container inspect --format "{{.HostConfig.NetworkMode}}" $infraID
is "$output" "slirp4netns" "network mode slirp4netns is set for the container"
run_podman stop -a -t 0
run_podman pod rm -t 0 -f test_pod
run_podman play kube --network none $PODMAN_TMPDIR/test.yaml
run_podman pod inspect --format {{.InfraContainerID}} "${lines[1]}"
infraID="$output"
run_podman container inspect --format "{{.HostConfig.NetworkMode}}" $infraID
is "$output" "none" "network mode none is set for the container"
run_podman stop -a -t 0
run_podman pod rm -t 0 -f test_pod
}
@test "podman play with user from image" {
TESTDIR=$PODMAN_TMPDIR/testdir
mkdir -p $TESTDIR
testUserYaml="
apiVersion: v1
kind: Pod
metadata:
labels:
app: test
name: test_pod
spec:
containers:
- command:
- id
env:
- name: PATH
value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- name: TERM
value: xterm
- name: container
value: podman
image: userimage
name: test
resources: {}
status: {}
"
cat > $PODMAN_TMPDIR/Containerfile << _EOF
from $IMAGE
USER bin
_EOF
echo "$testUserYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml
run_podman build -t userimage $PODMAN_TMPDIR
run_podman play kube --start=false $PODMAN_TMPDIR/test.yaml
run_podman inspect --format "{{ .Config.User }}" test_pod-test
is "$output" bin "expect container within pod to run as the bin user"
run_podman stop -a -t 0
run_podman pod rm -t 0 -f test_pod
run_podman rmi -f userimage:latest
}
@test "podman play --build --context-dir" {
skip_if_remote "--build is not supported in context remote"
testUserYaml="
apiVersion: v1
kind: Pod
metadata:
labels:
app: test
name: test_pod
spec:
containers:
- command:
- id
env:
- name: PATH
value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- name: TERM
value: xterm
- name: container
value: podman
image: quay.io/libpod/userimage
name: test
resources: {}
status: {}
"
mkdir -p $PODMAN_TMPDIR/userimage
cat > $PODMAN_TMPDIR/userimage/Containerfile << _EOF
from $IMAGE
USER bin
_EOF
echo "$testUserYaml" > $PODMAN_TMPDIR/test.yaml
run_podman 125 play kube --build --start=false $PODMAN_TMPDIR/test.yaml
run_podman play kube --replace --context-dir=$PODMAN_TMPDIR --build --start=false $PODMAN_TMPDIR/test.yaml
run_podman inspect --format "{{ .Config.User }}" test_pod-test
is "$output" bin "expect container within pod to run as the bin user"
run_podman stop -a -t 0
run_podman pod rm -t 0 -f test_pod
run_podman rmi -f userimage:latest
cd $PODMAN_TMPDIR
run_podman play kube --replace --build --start=false $PODMAN_TMPDIR/test.yaml
run_podman inspect --format "{{ .Config.User }}" test_pod-test
is "$output" bin "expect container within pod to run as the bin user"
run_podman stop -a -t 0
run_podman pod rm -t 0 -f test_pod
run_podman rmi -f userimage:latest
}
@test "podman play --annotation" {
TESTDIR=$PODMAN_TMPDIR/testdir
RANDOMSTRING=$(random_string 15)
mkdir -p $TESTDIR
echo "$testYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml
run_podman play kube --annotation "name=$RANDOMSTRING" $PODMAN_TMPDIR/test.yaml
run_podman inspect --format "{{ .Config.Annotations }}" test_pod-test
is "$output" ".*name:$RANDOMSTRING" "Annotation should be added to pod"
run_podman stop -a -t 0
run_podman pod rm -t 0 -f test_pod
}
@test "podman play --annotation > Max" {
TESTDIR=$PODMAN_TMPDIR/testdir
RANDOMSTRING=$(random_string 65)
mkdir -p $TESTDIR
echo "$testYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml
run_podman 125 play kube --annotation "name=$RANDOMSTRING" $PODMAN_TMPDIR/test.yaml
assert "$output" =~ "annotation exceeds maximum size, 63, of kubernetes annotation:" "Expected to fail with Length greater than 63"
}
@test "podman play Yaml with annotation > Max" {
RANDOMSTRING=$(random_string 65)
testBadYaml="
apiVersion: v1
kind: Pod
metadata:
annotations:
test: ${RANDOMSTRING}
labels:
app: test
name: test_pod
spec:
containers:
- command:
- id
env:
- name: PATH
value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- name: TERM
value: xterm
- name: container
value: podman
image: quay.io/libpod/userimage
name: test
resources: {}
status: {}
"
TESTDIR=$PODMAN_TMPDIR/testdir
mkdir -p $TESTDIR
echo "$testBadYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml
run_podman 125 play kube - < $PODMAN_TMPDIR/test.yaml
assert "$output" =~ "invalid annotation \"test\"=\"$RANDOMSTRING\"" "Expected to fail with annotation length greater than 63"
}
@test "podman play kube - default log driver" {
TESTDIR=$PODMAN_TMPDIR/testdir
mkdir -p $TESTDIR
echo "$testYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml
# Get the default log driver
run_podman info --format "{{.Host.LogDriver}}"
default_driver=$output
# Make sure that the default log driver is used
run_podman play kube $PODMAN_TMPDIR/test.yaml
run_podman inspect --format "{{.HostConfig.LogConfig.Type}}" test_pod-test
is "$output" "$default_driver" "play kube uses default log driver"
run_podman stop -a -t 0
run_podman pod rm -t 0 -f test_pod
}