mirror of
https://github.com/containers/podman.git
synced 2025-12-01 10:38:05 +08:00
Merge pull request #21653 from nalind/fun-with-artifacts
podman manifest add: support creating artifact manifest on the fly
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
# Tests for manifest list endpoints
|
||||
|
||||
start_registry
|
||||
export REGISTRY_PORT
|
||||
|
||||
# Creates the manifest list
|
||||
t POST /v3.4.0/libpod/manifests/create?name=abc 200 \
|
||||
@@ -28,7 +29,7 @@ RUN >file2
|
||||
EOF
|
||||
)
|
||||
|
||||
# manifest add --anotation tests
|
||||
# manifest add --annotation tests
|
||||
t POST /v3.4.0/libpod/manifests/$id_abc/add images="[\"containers-storage:$id_abc_image\"]" 200
|
||||
t PUT /v4.0.0/libpod/manifests/$id_xyz operation='update' images="[\"containers-storage:$id_xyz_image\"]" annotations="{\"foo\":\"bar\"}" annotation="[\"hoge=fuga\"]" 400 \
|
||||
.cause='can not set both Annotation and Annotations'
|
||||
@@ -66,5 +67,130 @@ t POST "/v4.0.0/libpod/manifests/xyz:latest/registry/localhost:$REGISTRY_PORT%2F
|
||||
t DELETE /v4.0.0/libpod/manifests/$id_abc 200
|
||||
t DELETE /v4.0.0/libpod/manifests/$id_xyz 200
|
||||
|
||||
# manifest add --artifact tests
|
||||
truncate -s 20M $WORKDIR/zeroes
|
||||
function test_artifacts_with_args() {
|
||||
# these values, ideally, are local to our caller
|
||||
local args="$artifact_annotations $artifact_config $artifact_config_type $artifact_exclude_titles $artifact_layer_type $artifact_type"
|
||||
t POST /v5.0.0/libpod/manifests/artifacts 201
|
||||
local id_artifacts=$(jq -r '.Id' <<<"$output")
|
||||
t PUT /v5.0.0/libpod/manifests/$id_artifacts operation='update' $args --form=listed.txt="oh yeah" --form=zeroes=@"$WORKDIR/zeroes" 200
|
||||
t POST "/v5.0.0/libpod/manifests/artifacts:latest/registry/localhost:$REGISTRY_PORT%2Fartifacts:latest?tlsVerify=false&all=true" 200
|
||||
|
||||
local index=$(skopeo inspect --raw --tls-verify=false docker://localhost:$REGISTRY_PORT/artifacts:latest)
|
||||
# jq <<<"$index"
|
||||
local digest=$(jq -r '.manifests[0].digest' <<<"$index")
|
||||
local artifact=$(skopeo inspect --raw --tls-verify=false docker://localhost:$REGISTRY_PORT/artifacts@${digest})
|
||||
# jq <<<"$artifact"
|
||||
|
||||
local expect_type
|
||||
case ${artifact_type} in
|
||||
artifact_type=*)
|
||||
expect_type=${artifact_type#artifact_type=}
|
||||
expect_type=${expect_type:-null};;
|
||||
*)
|
||||
expect_type=application/vnd.unknown.artifact.v1;;
|
||||
esac
|
||||
is $(jq -r '.artifactType'<<<"$artifact") "${expect_type}" "artifactType in artifact manifest with artifact_type arg \"${artifact_type}\""
|
||||
is $(jq -r '.manifests[0].artifactType'<<<"$index") "${expect_type}" "artifactType in image index with artifact_type arg \"${artifact_type}\""
|
||||
|
||||
local expect_annotations
|
||||
case ${artifact_annotations} in
|
||||
artifact_annotations=*)
|
||||
expect_annotations=$(jq -r '.foo' <<<"${artifact_annotations#artifact_annotations=}");;
|
||||
*)
|
||||
expect_annotations=null;;
|
||||
esac
|
||||
is $(jq -r '.annotations["foo"]'<<<"$artifact") "$expect_annotations" "\"foo\" annotation in artifact manifest with artifact_annotations arg \"${artifact_annotations}\""
|
||||
|
||||
local expect_config_size
|
||||
case ${artifact_config} in
|
||||
artifact_config=*)
|
||||
expect_config_size=$(wc -c <<<"${artifact_config#artifact_config=}")
|
||||
expect_config_size=$((expect_config_size-1))
|
||||
if [[ $expect_config_size -eq 0 ]]; then
|
||||
expect_config_size=2
|
||||
fi ;;
|
||||
*)
|
||||
expect_config_size=2;;
|
||||
esac
|
||||
is $(jq -r '.config.size'<<<"$artifact") "$expect_config_size" "size of config blob in artifact manifest with artifact_config arg \"${artifact_config}\""
|
||||
|
||||
local expect_config_type
|
||||
case ${artifact_config_type} in
|
||||
artifact_config_type=*)
|
||||
expect_config_type=${artifact_config_type#artifact_config_type=}
|
||||
if [[ -z "$expect_config_type" ]] ; then
|
||||
if [[ -n "${artifact_config#artifact_config=}" ]] ; then
|
||||
expect_config_type=application/vnd.oci.image.config.v1+json
|
||||
else
|
||||
expect_config_type=application/vnd.oci.empty.v1+json
|
||||
fi
|
||||
fi;;
|
||||
*)
|
||||
if [[ -n "${artifact_config#artifact_config=}" ]] ; then
|
||||
expect_config_type=application/vnd.oci.image.config.v1+json
|
||||
else
|
||||
expect_config_type=application/vnd.oci.empty.v1+json
|
||||
fi;;
|
||||
esac
|
||||
is $(jq -r '.config.mediaType'<<<"$artifact") "$expect_config_type" "mediaType of config blob in artifact manifest with artifact_config_type arg \"${artifact_config_type}\" and artifact_config arg \"${artifact_config}\""
|
||||
|
||||
local expect_first_layer_type expect_second_layer_type
|
||||
case ${artifact_layer_type} in
|
||||
artifact_layer_type=*)
|
||||
expect_first_layer_type=${artifact_layer_type#artifact_layer_type=}
|
||||
expect_first_layer_type=${expect_first_layer_type:-text/plain}
|
||||
expect_second_layer_type=${artifact_layer_type#artifact_layer_type=}
|
||||
expect_second_layer_type=${expect_second_layer_type:-application/octet-stream};;
|
||||
*)
|
||||
expect_first_layer_type=text/plain;
|
||||
expect_second_layer_type=application/octet-stream;;
|
||||
esac
|
||||
is $(jq -r '.layers[0].mediaType'<<<"$artifact") "$expect_first_layer_type" "mediaType of listed.txt layer in artifact manifest with artifact_layer_type arg \"${artifact_layer_type}\""
|
||||
is $(jq -r '.layers[1].mediaType'<<<"$artifact") "$expect_second_layer_type" "mediaType of zeroes layer in artifact manifest with artifact_layer_type arg \"${artifact_layer_type}\""
|
||||
|
||||
local expect_first_title expect_second_title
|
||||
case ${artifact_exclude_titles} in
|
||||
artifact_exclude_titles=true)
|
||||
expect_first_title=null;
|
||||
expect_second_title=null;;
|
||||
*)
|
||||
expect_first_title=listed.txt;
|
||||
expect_second_title=zeroes;;
|
||||
esac
|
||||
is $(jq -r '.layers[0].annotations["org.opencontainers.image.title"]'<<<"$artifact") "$expect_first_title" "org.opencontainers.image.title annotation on listed.txt layer in artifact manifest with artifact_exclude_titles arg \"${artifact_exclude_titles}\""
|
||||
is $(jq -r '.layers[1].annotations["org.opencontainers.image.title"]'<<<"$artifact") "$expect_second_title" "org.opencontainers.image.title annotation on zeroes layer in artifact manifest with artifact_exclude_titles arg \"${artifact_exclude_titles}\""
|
||||
|
||||
t DELETE /v5.0.0/libpod/manifests/$id_artifacts 200
|
||||
}
|
||||
|
||||
function test_artifacts() {
|
||||
local artifact_annotations
|
||||
local artifact_config
|
||||
local artifact_config_type
|
||||
local artifact_exclude_titles
|
||||
local artifact_layer_type
|
||||
local artifact_type
|
||||
for artifact_annotations in "" artifact_annotations='{"foo":"bar"}' ; do
|
||||
test_artifacts_with_args
|
||||
done
|
||||
for artifact_config in "" artifact_config= artifact_config="{}"; do
|
||||
for artifact_config_type in "" artifact_config_type= artifact_config_type=text/plain ; do
|
||||
test_artifacts_with_args
|
||||
done
|
||||
done
|
||||
for artifact_exclude_titles in "" artifact_exclude_titles=true ; do
|
||||
test_artifacts_with_args
|
||||
done
|
||||
for artifact_layer_type in "" artifact_layer_type= artifact_layer_type=text/plain artifact_layer_type=application/octet-stream ; do
|
||||
test_artifacts_with_args
|
||||
done
|
||||
for artifact_type in "" artifact_type= artifact_type=text/plain artifact_type=application/octet-stream ; do
|
||||
test_artifacts_with_args
|
||||
done
|
||||
}
|
||||
test_artifacts
|
||||
|
||||
podman rmi -a
|
||||
stop_registry
|
||||
|
||||
@@ -33,7 +33,7 @@ wait "${child_pid}"
|
||||
APIV2_TEST_EXPECT_TIMEOUT=2 t POST "containers/${CTR}/wait?condition=next-exit" 999
|
||||
like "$(<$WORKDIR/curl.headers.out)" ".*HTTP.* 200 OK.*" \
|
||||
"Received headers from /wait"
|
||||
if [[ -e $WORKDIR/curl.result.out ]]; then
|
||||
if [[ -s $WORKDIR/curl.result.out ]]; then
|
||||
_show_ok 0 "UNEXPECTED: curl on /wait returned results"
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Usage: test-apiv2 [PORT]
|
||||
# Usage: test-apiv2 testglob
|
||||
#
|
||||
# DEVELOPER NOTE: you almost certainly don't need to play in here. See README.
|
||||
#
|
||||
@@ -238,17 +238,17 @@ function jsonify() {
|
||||
function t() {
|
||||
local method=$1; shift
|
||||
local path=$1; shift
|
||||
local -a curl_args
|
||||
local -a curl_args form_args
|
||||
local content_type="application/json"
|
||||
|
||||
local testname="$method $path"
|
||||
|
||||
# POST and PUT requests may be followed by one or more key=value pairs.
|
||||
# Slurp the command line until we see a 3-digit status code.
|
||||
if [[ $method = "POST" || $method == "PUT" || $method = "DELETE" ]]; then
|
||||
if [[ $method = "POST" || $method == "PUT" || $method == "DELETE" ]]; then
|
||||
local -a post_args
|
||||
|
||||
if [[ $method = "POST" ]]; then
|
||||
if [[ $method == "POST" ]]; then
|
||||
function _add_curl_args() { curl_args+=(--data-binary @$1); }
|
||||
else
|
||||
function _add_curl_args() { curl_args+=(--upload-file $1); }
|
||||
@@ -260,6 +260,10 @@ function t() {
|
||||
# --disable makes curl not lookup the curlrc file, it shouldn't affect the tests in any way.
|
||||
-) curl_args+=(--disable);
|
||||
shift;;
|
||||
--form=*) form_args+=(--form);
|
||||
form_args+=("${arg#--form=}");
|
||||
content_type="multipart/form-data";
|
||||
shift;;
|
||||
*=*) post_args+=("$arg");
|
||||
shift;;
|
||||
*.json) _add_curl_args $arg;
|
||||
@@ -276,9 +280,12 @@ function t() {
|
||||
*) die "Internal error: invalid POST arg '$arg'" ;;
|
||||
esac
|
||||
done
|
||||
if [[ -z "$curl_args" ]]; then
|
||||
if [[ -z "${curl_args[*]}" && -z "${form_args[*]}" ]]; then
|
||||
curl_args=(-d $(jsonify ${post_args[*]}))
|
||||
testname="$testname [${curl_args[*]}]"
|
||||
elif [[ -z "${curl_args[*]}" ]]; then
|
||||
curl_args=(--form request.json=$(jsonify ${post_args[*]}) "${form_args[@]}")
|
||||
testname="$testname [${curl_args[*]} ${form_args[*]}]"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -319,14 +326,29 @@ function t() {
|
||||
echo "-------------------------------------------------------------" >>$LOG
|
||||
echo "\$ $testname" >>$LOG
|
||||
rm -f $WORKDIR/curl.*
|
||||
# -s = silent, but --write-out 'format' gives us important response data
|
||||
# The --write-out 'format' gives us important response data.
|
||||
# The hairy "{ ...;rc=$?; } || :" lets us capture curl's exit code and
|
||||
# give a helpful diagnostic if it fails.
|
||||
{ response=$(curl -s -X $method "${curl_args[@]}" \
|
||||
: > $WORKDIR/curl.result.out
|
||||
: > $WORKDIR/curl.result.err
|
||||
{ response=$(curl -X $method "${curl_args[@]}" \
|
||||
-H "Content-type: $content_type" \
|
||||
--dump-header $WORKDIR/curl.headers.out \
|
||||
-v --stderr $WORKDIR/curl.result.err \
|
||||
--write-out '%{http_code}^%{content_type}^%{time_total}' \
|
||||
-o $WORKDIR/curl.result.out "$url"); rc=$?; } || :
|
||||
if [ -n "$PODMAN_TESTS_DUMP_TRACES" ]; then
|
||||
# Dump the results we got back, exactly as we got them back.
|
||||
echo "\$ begin stdout" >>$LOG
|
||||
test -s $WORKDIR/curl.result.out && od -t x1c $WORKDIR/curl.result.out 2>&1 >>$LOG
|
||||
echo "\$ end stdout" >>$LOG
|
||||
echo "\$ begin stderr" >>$LOG
|
||||
test -s $WORKDIR/curl.result.err && cat $WORKDIR/curl.result.err >>$LOG
|
||||
echo "\$ end stderr" >>$LOG
|
||||
echo "\$ begin response code^content_type^time_total" >>$LOG
|
||||
od -t x1c <<< "$response" >>$LOG
|
||||
echo "\$ end response" >>$LOG
|
||||
fi
|
||||
|
||||
# Special case: this means we *expect and want* a timeout
|
||||
if [[ -n "$APIV2_TEST_EXPECT_TIMEOUT" ]]; then
|
||||
|
||||
Reference in New Issue
Block a user