mirror of
https://github.com/podman-container-tools/podman.git
synced 2026-09-10 01:27:54 +00:00
The rework of namespace handling for rootless CNI broke this, as CNI networks were being computed incorrectly. Fix handling of CNI networks for the Compat Create REST API for containers, and add a test so we don't regress again. Fixes #10569 Signed-off-by: Matthew Heon <mheon@redhat.com>
352 lines
11 KiB
Bash
352 lines
11 KiB
Bash
# -*- sh -*-
|
|
#
|
|
# test container-related endpoints
|
|
#
|
|
|
|
# WORKDIR=/data
|
|
ENV_WORKDIR_IMG=quay.io/libpod/testimage:20200929
|
|
MultiTagName=localhost/test/testformultitag:tag
|
|
|
|
podman pull $IMAGE &>/dev/null
|
|
podman tag $IMAGE $MultiTagName
|
|
podman pull $ENV_WORKDIR_IMG &>/dev/null
|
|
# Unimplemented
|
|
#t POST libpod/containers/create '' 201 'sdf'
|
|
|
|
# Ensure clean slate
|
|
podman rm -a -f &>/dev/null
|
|
|
|
t GET "libpod/containers/json (at start: clean slate)" 200 length=0
|
|
|
|
podman run $IMAGE true
|
|
|
|
t GET libpod/containers/json 200 length=0
|
|
|
|
t GET libpod/containers/json?all=true 200 \
|
|
length=1 \
|
|
.[0].Id~[0-9a-f]\\{64\\} \
|
|
.[0].Image=$IMAGE \
|
|
.[0].Command[0]="true" \
|
|
.[0].State~\\\(exited\\\|stopped\\\) \
|
|
.[0].ExitCode=0 \
|
|
.[0].IsInfra=false
|
|
|
|
# Test compat API for Network Settings (.Network is N/A when rootless)
|
|
network_expect=
|
|
if root; then
|
|
network_expect='.[0].NetworkSettings.Networks.podman.NetworkID=podman'
|
|
fi
|
|
t GET /containers/json?all=true 200 \
|
|
length=1 \
|
|
.[0].Id~[0-9a-f]\\{64\\} \
|
|
.[0].Image=$IMAGE \
|
|
$network_expect
|
|
|
|
# Make sure `limit` works.
|
|
t GET libpod/containers/json?limit=1 200 \
|
|
length=1 \
|
|
.[0].Id~[0-9a-f]\\{64\\} \
|
|
.[0].Image=$IMAGE \
|
|
.[0].Command[0]="true" \
|
|
.[0].State~\\\(exited\\\|stopped\\\) \
|
|
.[0].ExitCode=0 \
|
|
.[0].IsInfra=false
|
|
|
|
# Make sure `last` works, which is an alias for `limit`.
|
|
# See https://github.com/containers/podman/issues/6413.
|
|
t GET libpod/containers/json?last=1 200 \
|
|
length=1 \
|
|
.[0].Id~[0-9a-f]\\{64\\} \
|
|
.[0].Image=$IMAGE \
|
|
.[0].Command[0]="true" \
|
|
.[0].State~\\\(exited\\\|stopped\\\) \
|
|
.[0].ExitCode=0 \
|
|
.[0].IsInfra=false
|
|
|
|
cid=$(jq -r '.[0].Id' <<<"$output")
|
|
|
|
t DELETE libpod/containers/$cid 204
|
|
|
|
# Issue #6799: it should be possible to start a container, even w/o args.
|
|
t POST libpod/containers/create?name=test_noargs Image=${IMAGE} 201 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.Id' <<<"$output")
|
|
# Prior to the fix in #6835, this would fail 500 "args must not be empty"
|
|
t POST libpod/containers/${cid}/start 204
|
|
# Container should exit almost immediately. Wait for it, confirm successful run
|
|
t POST "libpod/containers/${cid}/wait?condition=stopped&condition=exited" 200 '0'
|
|
t GET libpod/containers/${cid}/json 200 \
|
|
.Id=$cid \
|
|
.State.Status~\\\(exited\\\|stopped\\\) \
|
|
.State.Running=false \
|
|
.State.ExitCode=0
|
|
t DELETE libpod/containers/$cid 204
|
|
|
|
CNAME=myfoo
|
|
podman run --name $CNAME $IMAGE -td top
|
|
t GET libpod/containers/json?all=true 200 \
|
|
.[0].Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.[0].Id' <<<"$output")
|
|
|
|
# No such container
|
|
t POST "libpod/commit?container=nonesuch" 404
|
|
|
|
# Comment can only be used with docker format, not OCI
|
|
cparam="repo=newrepo&comment=foo&author=bob"
|
|
t POST "libpod/commit?container=$CNAME&$cparam" 500 \
|
|
.cause="messages are only compatible with the docker image format (-f docker)"
|
|
|
|
# Commit a new image from the container
|
|
t POST "libpod/commit?container=$CNAME" 200 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
iid=$(jq -r '.Id' <<<"$output")
|
|
t GET libpod/images/$iid/json 200 \
|
|
.RepoTags[0]=null \
|
|
.Author="" \
|
|
.Comment=""
|
|
|
|
# Commit a new image w/o tag
|
|
cparam="repo=newrepo&comment=foo&author=bob&format=docker"
|
|
t POST "libpod/commit?container=$CNAME&$cparam" 200
|
|
t GET libpod/images/newrepo:latest/json 200 \
|
|
.RepoTags[0]=localhost/newrepo:latest \
|
|
.Author=bob \
|
|
.Comment=foo
|
|
|
|
# Commit a new image w/ specified tag and author
|
|
cparam="repo=newrepo&tag=v1&author=alice"
|
|
t POST "libpod/commit?container=$cid&$cparam&pause=false" 200
|
|
t GET libpod/images/newrepo:v1/json 200 \
|
|
.RepoTags[0]=localhost/newrepo:v1 \
|
|
.Author=alice
|
|
|
|
# Commit a new image w/ full parameters
|
|
cparam="repo=newrepo&tag=v2&comment=bar&author=eric"
|
|
cparam="$cparam&format=docker&changes=CMD=/bin/foo"
|
|
t POST "libpod/commit?container=${cid:0:12}&$cparam&pause=true" 200
|
|
t GET libpod/images/newrepo:v2/json 200 \
|
|
.RepoTags[0]=localhost/newrepo:v2 \
|
|
.Author=eric \
|
|
.Comment=bar \
|
|
.Config.Cmd[-1]="/bin/foo"
|
|
|
|
# Create a container for testing the container initializing later
|
|
podman create -t -i --name myctr $IMAGE ls
|
|
|
|
# Check configuration before initializing
|
|
t GET libpod/containers/myctr/json 200 \
|
|
.Id~[0-9a-f]\\{64\\} \
|
|
.State.Status="configured" \
|
|
.State.Pid=0 \
|
|
.ResolvConfPath="" \
|
|
.HostnamePath="" \
|
|
.HostsPath="" \
|
|
.NetworkSettings.SandboxKey=""
|
|
|
|
cpid_file=$(jq -r '.ConmonPidFile' <<<"$output")
|
|
userdata_path=$(dirname $cpid_file)
|
|
|
|
# Initializing the container
|
|
t POST libpod/containers/myctr/init 204
|
|
|
|
# Check configuration after initializing
|
|
t GET libpod/containers/myctr/json 200 \
|
|
.Id~[0-9a-f]\\{64\\} \
|
|
.State.Status="created" \
|
|
.State.Pid~[0-9]\\{1\,8\\} \
|
|
.ResolvConfPath=$userdata_path/resolv.conf \
|
|
.HostnamePath=$userdata_path/hostname \
|
|
.HostsPath=$userdata_path/hosts \
|
|
.NetworkSettings.SandboxKey~.*/netns/cni- \
|
|
.OCIConfigPath~.*config\.json \
|
|
.GraphDriver.Data.MergedDir~.*merged
|
|
|
|
# Test TS are in UTC
|
|
t GET containers/myctr/json 200 \
|
|
.Created~.*Z \
|
|
.State.StartedAt~.*Z \
|
|
.State.FinishedAt~.*Z
|
|
|
|
t DELETE images/localhost/newrepo:latest?force=true 200
|
|
t DELETE images/localhost/newrepo:v1?force=true 200
|
|
t DELETE images/localhost/newrepo:v2?force=true 200
|
|
t DELETE libpod/containers/$cid 204
|
|
t DELETE libpod/containers/myctr 204
|
|
t DELETE libpod/containers/bogus 404
|
|
|
|
|
|
# test apiv2 create container with correct entrypoint and cmd
|
|
# --data '{"Image":"quay.io/libpod/alpine_labels:latest","Entrypoint":["echo"],"Cmd":["param1","param2"]}'
|
|
t POST containers/create \
|
|
Image=$IMAGE \
|
|
Entrypoint='["echo"]' \
|
|
Cmd='["param1","param2"]' \
|
|
201 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.Id' <<<"$output")
|
|
t GET containers/$cid/json 200 \
|
|
.Config.Entrypoint[0]="echo" \
|
|
.Config.Cmd[0]="param1" \
|
|
.Config.Cmd[1]="param2" \
|
|
.Path="echo" \
|
|
.Args[0]="param1" \
|
|
.Args[1]="param2"
|
|
t DELETE containers/$cid 204
|
|
|
|
# test only set the entrypoint, Cmd should be []
|
|
t POST containers/create \
|
|
Image=$IMAGE \
|
|
Entrypoint='["echo","param1"]' \
|
|
201 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.Id' <<<"$output")
|
|
t GET containers/$cid/json 200 \
|
|
.Config.Entrypoint[0]="echo" \
|
|
.Config.Entrypoint[1]="param1" \
|
|
.Config.Cmd='[]' \
|
|
.Path="echo" \
|
|
.Args[0]="param1"
|
|
|
|
# create a running container for after
|
|
t POST containers/create Image=$IMAGE Entrypoint='["top"]' 201 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
cid_top=$(jq -r '.Id' <<<"$output")
|
|
network_expect="{}"
|
|
if root; then
|
|
network_expect='.podman.NetworkID=podman'
|
|
fi
|
|
t GET containers/${cid_top}/json 200 \
|
|
.Config.Entrypoint[0]="top" \
|
|
.Config.Cmd='[]' \
|
|
.Path="top"
|
|
.NetworkSettings.Networks="$network_expect"
|
|
t POST containers/${cid_top}/start 204
|
|
# make sure the container is running
|
|
t GET containers/${cid_top}/json 200 \
|
|
.State.Status="running"
|
|
|
|
# 0 means unlimited, need same with docker
|
|
t GET containers/json?limit=0 200 \
|
|
.[0].Id~[0-9a-f]\\{64\\}
|
|
|
|
t GET 'containers/json?limit=0&all=1' 200 \
|
|
.[0].Id~[0-9a-f]\\{64\\} \
|
|
.[1].Id~[0-9a-f]\\{64\\}
|
|
|
|
t GET containers/json?limit=2 200 length=2
|
|
|
|
# Filter with two ids should return both container
|
|
t GET containers/json?filters='{"id":["'${cid}'","'${cid_top}'"]}&all=1' 200 length=2
|
|
# Filter with two ids and status running should return only 1 container
|
|
t GET containers/json?filters='{"id":["'${cid}'","'${cid_top}'"],"status":["running"]}&all=1' 200 \
|
|
length=1 \
|
|
.[0].Id=${cid_top}
|
|
|
|
t POST containers/${cid_top}/stop 204
|
|
|
|
t DELETE containers/$cid 204
|
|
t DELETE containers/$cid_top 204
|
|
|
|
# test the WORKDIR and StopSignal
|
|
t POST containers/create \
|
|
Image=$ENV_WORKDIR_IMG \
|
|
WorkingDir=/dataDir \
|
|
StopSignal=9 \
|
|
201 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.Id' <<<"$output")
|
|
t GET containers/$cid/json 200 \
|
|
.Config.WorkingDir="/dataDir" \
|
|
.Config.StopSignal="9"
|
|
|
|
t DELETE containers/$cid 204
|
|
|
|
# when the image had multi tags, the container's Image should be correct
|
|
# Fixes https://github.com/containers/podman/issues/8547
|
|
t POST containers/create Image=${MultiTagName} 201 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.Id' <<<"$output")
|
|
t GET containers/$cid/json 200 \
|
|
.Image=${MultiTagName}
|
|
t DELETE containers/$cid 204
|
|
t DELETE images/${MultiTagName} 200
|
|
# vim: filetype=sh
|
|
|
|
# Test Volumes field adds an anonymous volume
|
|
t POST containers/create Image=$IMAGE Volumes='{"/test":{}}' 201 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.Id' <<<"$output")
|
|
t GET containers/$cid/json 200 \
|
|
.Mounts[0].Destination="/test"
|
|
|
|
t DELETE containers/$cid?v=true 204
|
|
|
|
# test port mapping
|
|
podman run -d --rm --name bar -p 8080:9090 $IMAGE top
|
|
|
|
t GET containers/json 200 \
|
|
.[0].Ports[0].PrivatePort=9090 \
|
|
.[0].Ports[0].PublicPort=8080 \
|
|
.[0].Ports[0].Type="tcp"
|
|
|
|
podman stop bar
|
|
|
|
#compat api list containers sanity checks
|
|
t GET containers/json?filters='garb1age}' 500 \
|
|
.cause="invalid character 'g' looking for beginning of value"
|
|
t GET containers/json?filters='{"label":["testl' 500 \
|
|
.cause="unexpected end of JSON input"
|
|
|
|
#libpod api list containers sanity checks
|
|
t GET libpod/containers/json?filters='garb1age}' 500 \
|
|
.cause="invalid character 'g' looking for beginning of value"
|
|
t GET libpod/containers/json?filters='{"label":["testl' 500 \
|
|
.cause="unexpected end of JSON input"
|
|
|
|
# Prune containers - bad filter input
|
|
t POST containers/prune?filters='garb1age}' 500 \
|
|
.cause="invalid character 'g' looking for beginning of value"
|
|
t POST libpod/containers/prune?filters='garb1age}' 500 \
|
|
.cause="invalid character 'g' looking for beginning of value"
|
|
|
|
# Prune containers with illformed label
|
|
t POST containers/prune?filters='{"label":["tes' 500 \
|
|
.cause="unexpected end of JSON input"
|
|
t POST libpod/containers/prune?filters='{"label":["tes' 500 \
|
|
.cause="unexpected end of JSON input"
|
|
|
|
t GET libpod/containers/json?filters='{"label":["testlabel"]}' 200 length=0
|
|
|
|
# libpod api: do not use list filters for prune
|
|
t POST libpod/containers/prune?filters='{"name":["anyname"]}' 500 \
|
|
.cause="name is an invalid filter"
|
|
t POST libpod/containers/prune?filters='{"id":["anyid"]}' 500 \
|
|
.cause="id is an invalid filter"
|
|
t POST libpod/containers/prune?filters='{"network":["anynetwork"]}' 500 \
|
|
.cause="network is an invalid filter"
|
|
|
|
# compat api: do not use list filters for prune
|
|
t POST containers/prune?filters='{"name":["anyname"]}' 500 \
|
|
.cause="name is an invalid filter"
|
|
t POST containers/prune?filters='{"id":["anyid"]}' 500 \
|
|
.cause="id is an invalid filter"
|
|
t POST containers/prune?filters='{"network":["anynetwork"]}' 500 \
|
|
.cause="network is an invalid filter"
|
|
|
|
# Test CPU limit (NanoCPUs)
|
|
t POST containers/create Image=$IMAGE HostConfig='{"NanoCpus":500000}' 201 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.Id' <<<"$output")
|
|
t GET containers/$cid/json 200 \
|
|
.HostConfig.NanoCpus=500000
|
|
|
|
t DELETE containers/$cid?v=true 204
|
|
|
|
# Test Compat Create with default network mode (#10569)
|
|
t POST containers/create Image=$IMAGE HostConfig='{"NetworkMode":"default"}' 201 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.Id' <<<"$output")
|
|
t GET containers/$cid/json 200 \
|
|
.HostConfig.NetworkMode="bridge"
|
|
|
|
t DELETE containers/$cid?v=true 204
|