mirror of
https://github.com/containers/podman.git
synced 2025-12-09 15:19:35 +08:00
The logic which checks for duplicated volumes here did not work correctly because it used filepath.Clean(). However the writes to the volDestinations map did not thus the string no longer matched when you included a final slash for example. So we can either call Clean() on all or no paths. I decided to call it on no path because this is what we do right now. Just the check did it. Fixed #18454 Signed-off-by: Paul Holzinger <pholzing@redhat.com>
627 lines
19 KiB
Bash
627 lines
19 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
|
|
# check content type: https://github.com/containers/podman/issues/14647
|
|
response_headers=$(cat "$WORKDIR/curl.headers.out")
|
|
like "$response_headers" ".*Content-Type: application/json.*" "header does not contain application/json"
|
|
|
|
# Regression test for #12904 (race condition in logging code)
|
|
mytext="hi-there-$(random_string 15)"
|
|
podman run --rm -d --replace --name foo $IMAGE sh -c "echo $mytext;sleep 42"
|
|
# Logs output is prepended by ^A^Y (stdout = 1, length = 25 (with newline))
|
|
# Looks like it is missing the required 0 bytes from the message, why?
|
|
t POST "containers/foo/attach?logs=true&stream=false" 200 \
|
|
$'\001\031'$mytext
|
|
t POST "containers/foo/kill" 204
|
|
|
|
podman run -v /tmp:/tmp $IMAGE true
|
|
|
|
t GET libpod/containers/json 200 length=0
|
|
|
|
# bad all input
|
|
t GET libpod/containers/json?all='garb1age' 500 \
|
|
.cause="schema: error converting value for \"all\""
|
|
|
|
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].Mounts~.*/tmp \
|
|
.[0].IsInfra=false
|
|
|
|
# Test compat API for Network Settings (.Network is N/A when rootless)
|
|
network_expect="Networks.slirp4netns.NetworkID=slirp4netns"
|
|
if root; then
|
|
network_expect="Networks.podman.NetworkID=podman"
|
|
fi
|
|
t GET /containers/json?all=true 200 \
|
|
length=1 \
|
|
.[0].Id~[0-9a-f]\\{64\\} \
|
|
.[0].Image=$IMAGE \
|
|
.[0].Mounts~.*/tmp \
|
|
.[0].NetworkSettings.$network_expect
|
|
|
|
# compat API imageid with sha256: prefix
|
|
t GET containers/json?limit=1 200 \
|
|
.[0].ImageID~sha256:[0-9a-f]\\{64\\}
|
|
|
|
# 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")
|
|
|
|
if root; then
|
|
t GET libpod/containers/stats?containers='[$cid]' 200
|
|
else
|
|
if have_cgroupsv2; then
|
|
t GET libpod/containers/stats?containers='[$cid]' 200
|
|
else
|
|
t GET libpod/containers/stats?containers='[$cid]' 409
|
|
fi
|
|
fi
|
|
|
|
# max_usage is not set for cgroupv2
|
|
if have_cgroupsv2; then
|
|
t GET libpod/containers/stats?containers='[$cid]' 200 \
|
|
.memory_stats.max_usage=null
|
|
fi
|
|
|
|
t DELETE libpod/containers/$cid 200 .[0].Id=$cid
|
|
|
|
# Issue #14676: make sure the stats show the memory limit specified for the container
|
|
if root; then
|
|
CTRNAME=ctr-with-limit
|
|
podman run --name $CTRNAME -d -m 512m -v /tmp:/tmp $IMAGE top
|
|
|
|
t GET libpod/containers/$CTRNAME/stats?stream=false 200 \
|
|
.memory_stats.limit=536870912 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
|
|
# Make sure docker compat endpoint shows "id" lowercase
|
|
t GET containers/$CTRNAME/stats?stream=false 200 \
|
|
.memory_stats.limit=536870912 \
|
|
.id~[0-9a-f]\\{64\\}
|
|
|
|
t GET containers/$CTRNAME/top?stream=false 200 \
|
|
.Titles='[
|
|
"PID",
|
|
"USER",
|
|
"TIME",
|
|
"COMMAND"
|
|
]'
|
|
|
|
podman rm -f $CTRNAME
|
|
fi
|
|
|
|
# Issue #15765: make sure the memory limit is capped
|
|
if root; then
|
|
CTRNAME=ctr-with-limit
|
|
podman run --name $CTRNAME -d -m 512m -v /tmp:/tmp $IMAGE top
|
|
|
|
t GET libpod/containers/$CTRNAME/stats?stream=false 200 \
|
|
.memory_stats.limit!=18446744073709552000
|
|
|
|
podman rm -f $CTRNAME
|
|
fi
|
|
|
|
# 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 \
|
|
.Config.Umask=0022 # regression check for #15036
|
|
t DELETE libpod/containers/$cid 200 .[0].Id=$cid
|
|
|
|
CNAME=myfoo
|
|
podman run -d --name $CNAME $IMAGE 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="created" \
|
|
.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="initialized" \
|
|
.State.Pid~[0-9]\\{1\,8\\} \
|
|
.ResolvConfPath=$userdata_path/resolv.conf \
|
|
.HostnamePath=$userdata_path/hostname \
|
|
.HostsPath=$userdata_path/hosts \
|
|
.NetworkSettings.SandboxKey~.*/netns/netns- \
|
|
.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?force=true 200 .[0].Id=$cid
|
|
t DELETE libpod/containers/myctr 200
|
|
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")
|
|
|
|
t GET containers/${cid_top}/json 200 \
|
|
.Config.Entrypoint[0]="top" \
|
|
.Config.Cmd='[]' \
|
|
.Path="top" \
|
|
.NetworkSettings.Networks.podman.NetworkID=podman
|
|
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 \
|
|
.Config.Image=${MultiTagName} \
|
|
.Image~sha256:[0-9a-f]\\{64\\}
|
|
|
|
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 Volumes with bind mount, for some reason docker-py sets this #18454
|
|
t POST containers/create Image=$IMAGE Volumes='{"/test/":{}}' HostConfig='{"Binds":["/tmp:/test/:ro"]}' 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='{"status":["removing"]}' 200 length=0
|
|
t GET libpod/containers/json?filters='{"status":["bogus"]}' 500 \
|
|
.cause="invalid argument"
|
|
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
|
|
|
|
# test create with default netns="host"
|
|
stop_service
|
|
CONTAINERS_CONF=$TESTS_DIR/containers.host-netns.conf start_service
|
|
|
|
# check that the default docker netns "default" is rewritten to "host"
|
|
# when the containers.conf explicitly uses "host"
|
|
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="host"
|
|
|
|
t DELETE containers/$cid?v=true 204
|
|
|
|
# Restart with the default containers.conf for next tests.
|
|
stop_service
|
|
start_service
|
|
|
|
# Test Compat Create with healthcheck, check default values
|
|
t POST containers/create Image=$IMAGE Cmd='["top"]' Healthcheck='{"Test":["true"]}' 201 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.Id' <<<"$output")
|
|
t GET containers/$cid/json 200 \
|
|
.Config.Healthcheck.Interval=30000000000 \
|
|
.Config.Healthcheck.Timeout=30000000000 \
|
|
.Config.Healthcheck.Retries=3
|
|
|
|
# compat api: Test for mount options support
|
|
# Sigh, JSON can't handle octal. 0755(octal) = 493(decimal)
|
|
payload='{"Mounts":[{"Type":"tmpfs","Target":"/mnt/scratch","TmpfsOptions":{"SizeBytes":1024,"Mode":493}}]}'
|
|
t POST containers/create Image=$IMAGE HostConfig="$payload" 201 .Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.Id' <<<"$output")
|
|
t GET containers/$cid/json 200 \
|
|
.HostConfig.Tmpfs['"/mnt/scratch"']~.*size=1024.* \
|
|
.HostConfig.Tmpfs['"/mnt/scratch"']~.*mode=755.*
|
|
|
|
t DELETE containers/$cid?v=true 204
|
|
|
|
# compat api: tmpfs without mount options
|
|
payload='{"Mounts":[{"Type":"tmpfs","Target":"/mnt/scratch"}]}'
|
|
t POST containers/create Image=$IMAGE HostConfig="$payload" 201 .Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.Id' <<<"$output")
|
|
t GET containers/$cid/json 200 \
|
|
.HostConfig.Tmpfs['"/mnt/scratch"']~.*tmpcopyup.* \
|
|
|
|
t DELETE containers/$cid?v=true 204
|
|
|
|
# compat api: bind mount without mount options
|
|
payload='{"Mounts":[{"Type":"bind","Source":"/tmp","Target":"/mnt"}]}'
|
|
t POST containers/create Image=$IMAGE HostConfig="$payload" 201 .Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.Id' <<<"$output")
|
|
t GET containers/$cid/json 200 \
|
|
.HostConfig.Binds[0]~/tmp:/mnt:.* \
|
|
|
|
t DELETE containers/$cid?v=true 204
|
|
|
|
# test apiv2 create/commit
|
|
t POST containers/create \
|
|
Image=$IMAGE \
|
|
Entrypoint='["echo"]' \
|
|
Cmd='["param1","param2"]' \
|
|
201 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.Id' <<<"$output")
|
|
|
|
# No such container
|
|
t POST "commit?container=nonesuch" 404
|
|
|
|
cparam="repo=newrepo&tag=v3&comment=abcd&author=eric"
|
|
cparam="$cparam&format=docker&changes=CMD%20/bin/bar%0aEXPOSE%209090"
|
|
t POST "commit?container=${cid:0:12}&$cparam" 201 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
iid=$(jq -r '.Id' <<<"$output")
|
|
t GET images/$iid/json 200 \
|
|
.RepoTags[0]=docker.io/library/newrepo:v3 \
|
|
.Config.ExposedPorts~.*"9090/tcp" \
|
|
.Config.Cmd~.*"/bin/bar" \
|
|
.Comment="abcd"
|
|
|
|
t DELETE containers/$cid 204
|
|
t DELETE images/docker.io/library/newrepo:v3?force=false 200
|
|
|
|
# test create without default no_hosts
|
|
t POST containers/create \
|
|
Image=$IMAGE \
|
|
201 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.Id' <<<"$output")
|
|
|
|
t POST libpod/containers/$cid/init 204
|
|
|
|
t GET libpod/containers/$cid/json 200
|
|
|
|
cpid_file=$(jq -r '.ConmonPidFile' <<<"$output")
|
|
userdata_path=$(dirname $cpid_file)
|
|
|
|
t GET libpod/containers/$cid/json 200 \
|
|
.HostsPath=$userdata_path/hosts
|
|
|
|
t DELETE containers/$cid 204
|
|
|
|
# test create with default no_hosts=true
|
|
stop_service
|
|
|
|
CONTAINERS_CONF=$TESTS_DIR/containers.no_hosts.conf start_service
|
|
|
|
# check docker and libpod endpoint
|
|
for endpoint in containers/create libpod/containers/create; do
|
|
t POST $endpoint \
|
|
Image=$IMAGE \
|
|
201 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
cid=$(jq -r '.Id' <<<"$output")
|
|
|
|
t POST libpod/containers/$cid/init 204
|
|
|
|
t GET libpod/containers/$cid/json 200 \
|
|
.HostsPath=""
|
|
|
|
t DELETE containers/$cid 204
|
|
done
|
|
|
|
stop_service
|
|
start_service
|
|
|
|
# Our states are different from Docker's.
|
|
# Regression test for #14700 (Docker compat returning unknown "initialized" for status.status) to ensure the stay compatible
|
|
podman create --name status-test $IMAGE sh -c "sleep 3"
|
|
t GET containers/status-test/json 200 .State.Status="created"
|
|
|
|
podman init status-test
|
|
t GET containers/status-test/json 200 .State.Status="created"
|
|
|
|
podman start status-test
|
|
t GET containers/status-test/json 200 .State.Status="running"
|
|
|
|
podman pause status-test
|
|
t GET containers/status-test/json 200 .State.Status="paused"
|
|
|
|
podman unpause status-test
|
|
t GET containers/status-test/json 200 .State.Status="running"
|
|
|
|
podman stop status-test &
|
|
sleep 1
|
|
t GET containers/status-test/json 200 .State.Status="stopping"
|
|
|
|
sleep 3
|
|
t GET containers/status-test/json 200 .State.Status="exited"
|
|
|
|
# test podman generate spec as input for the api
|
|
cname=specgen$(random_string 10)
|
|
podman create --name=$cname $IMAGE
|
|
|
|
TMPD=$(mktemp -d podman-apiv2-test.build.XXXXXXXX)
|
|
|
|
podman generate spec -f ${TMPD}/myspec.json -c $cname
|
|
|
|
# Create a container based on that spec
|
|
t POST libpod/containers/create ${TMPD}/myspec.json 201 \
|
|
.Id~[0-9a-f]\\{64\\}
|
|
|
|
# Verify
|
|
t GET libpod/containers/$cname/json 200 \
|
|
.ImageName=$IMAGE \
|
|
.Name=$cname
|
|
|
|
if root; then
|
|
podman run -dt --name=updateCtr alpine
|
|
echo '{"Memory":{"Limit":500000}, "CPU":{"Shares":123}}' >${TMPD}/update.json
|
|
t POST libpod/containers/updateCtr/update ${TMPD}/update.json 201
|
|
|
|
# Verify
|
|
echo '{ "AttachStdout":true,"Cmd":["cat","/sys/fs/cgroup/cpu.weight"]}' >${TMPD}/exec.json
|
|
t POST containers/updateCtr/exec ${TMPD}/exec.json 201 .Id~[0-9a-f]\\{64\\}
|
|
eid=$(jq -r '.Id' <<<"$output")
|
|
# 002 is the byte length
|
|
t POST exec/$eid/start 200 $'\001\0025'
|
|
|
|
podman rm -f updateCtr
|
|
fi
|
|
|
|
rm -rf $TMPD
|
|
|
|
podman container rm -fa
|