github.com/containers/podman/v5@v5.1.0-rc1/test/apiv2/15-manifest.at (about) 1 # -*- sh -*- 2 # 3 # Tests for manifest list endpoints 4 5 start_registry 6 export REGISTRY_PORT 7 8 # Creates the manifest list 9 t POST /v3.4.0/libpod/manifests/create?name=abc 200 \ 10 .Id~[0-9a-f]\\{64\\} 11 id_abc=$(jq -r '.Id' <<<"$output") 12 13 t POST /v4.0.0/libpod/manifests/xyz 201 \ 14 .Id~[0-9a-f]\\{64\\} 15 id_xyz=$(jq -r '.Id' <<<"$output") 16 17 t GET /v3.4.0/libpod/manifests/$id_abc/exists 204 18 t GET /v4.0.0/libpod/manifests/$id_xyz/exists 204 19 20 id_abc_image=$($PODMAN_BIN --root $WORKDIR/server_root image build -q --format=docker -<<EOF 21 FROM alpine 22 RUN >file1 23 EOF 24 ) 25 26 id_xyz_image=$($PODMAN_BIN --root $WORKDIR/server_root image build -q --format=docker -<<EOF 27 FROM alpine 28 RUN >file2 29 EOF 30 ) 31 32 # manifest add --annotation tests 33 t POST /v3.4.0/libpod/manifests/$id_abc/add images="[\"containers-storage:$id_abc_image\"]" 200 34 t PUT /v4.0.0/libpod/manifests/$id_xyz operation='update' images="[\"containers-storage:$id_xyz_image\"]" annotations="{\"foo\":\"bar\"}" annotation="[\"hoge=fuga\"]" 400 \ 35 .cause='can not set both Annotation and Annotations' 36 37 t PUT /v4.0.0/libpod/manifests/$id_xyz operation='update' images="[\"containers-storage:$id_xyz_image\"]" annotations="{\"foo\":\"bar\"}" 200 38 t GET /v4.0.0/libpod/manifests/$id_xyz/json 200 \ 39 .manifests[0].annotations.foo="bar" 40 41 t PUT /v4.0.0/libpod/manifests/$id_xyz operation='update' images="[\"containers-storage:$id_xyz_image\"]" annotation="[\"hoge=fuga\"]" 200 42 t GET /v4.0.0/libpod/manifests/$id_xyz/json 200 \ 43 .manifests[0].annotations.hoge="fuga" 44 45 # manifest annotate tests 46 t GET /v4.0.0/libpod/manifests/$id_xyz/json 200 47 xyz_digest=$(jq -r '.manifests[0].digest' <<<"$output") 48 49 t PUT /v4.0.0/libpod/manifests/$id_xyz operation='annotate' images="[\"containers-storage:$id_xyz_image\"]" annotations="{\"foo2\":\"bar2\"}" annotation="[\"hoge2=fuga2\"]" 400 \ 50 .cause='can not set both Annotation and Annotations' 51 52 t PUT /v4.0.0/libpod/manifests/$id_xyz operation='annotate' images="[\"$xyz_digest\"]" annotations="{\"foo2\":\"bar2\"}" 200 53 t GET /v4.0.0/libpod/manifests/$id_xyz/json 200 \ 54 .manifests[0].annotations.foo2="bar2" 55 56 t PUT /v4.0.0/libpod/manifests/$id_xyz operation='annotate' images="[\"$xyz_digest\"]" annotation="[\"hoge2=fuga2\"]" 200 57 t GET /v4.0.0/libpod/manifests/$id_xyz/json 200 \ 58 .manifests[0].annotations.hoge2="fuga2" 59 60 # registry-related tests 61 t POST "/v3.4.0/libpod/manifests/abc:latest/push?destination=localhost:$REGISTRY_PORT%2Fabc:latest&tlsVerify=false&all=true" 200 62 t POST "/v4.0.0/libpod/manifests/xyz:latest/registry/localhost:$REGISTRY_PORT%2Fxyz:latest?all=true" 400 \ 63 .cause='x509: certificate signed by unknown authority' 64 t POST "/v4.0.0/libpod/manifests/xyz:latest/registry/localhost:$REGISTRY_PORT%2Fxyz:latest?tlsVerify=false&all=true" 200 65 66 # /v3.x cannot delete a manifest list 67 t DELETE /v4.0.0/libpod/manifests/$id_abc 200 68 t DELETE /v4.0.0/libpod/manifests/$id_xyz 200 69 70 # manifest add --artifact tests 71 truncate -s 20M $WORKDIR/zeroes 72 function test_artifacts_with_args() { 73 # these values, ideally, are local to our caller 74 local args="$artifact_annotations $artifact_config $artifact_config_type $artifact_exclude_titles $artifact_layer_type $artifact_type" 75 t POST /v5.0.0/libpod/manifests/artifacts 201 76 local id_artifacts=$(jq -r '.Id' <<<"$output") 77 t PUT /v5.0.0/libpod/manifests/$id_artifacts operation='update' $args --form=listed.txt="oh yeah" --form=zeroes=@"$WORKDIR/zeroes" 200 78 t POST "/v5.0.0/libpod/manifests/artifacts:latest/registry/localhost:$REGISTRY_PORT%2Fartifacts:latest?tlsVerify=false&all=true" 200 79 80 local index=$(skopeo inspect --raw --tls-verify=false docker://localhost:$REGISTRY_PORT/artifacts:latest) 81 # jq <<<"$index" 82 local digest=$(jq -r '.manifests[0].digest' <<<"$index") 83 local artifact=$(skopeo inspect --raw --tls-verify=false docker://localhost:$REGISTRY_PORT/artifacts@${digest}) 84 # jq <<<"$artifact" 85 86 local expect_type 87 case ${artifact_type} in 88 artifact_type=*) 89 expect_type=${artifact_type#artifact_type=} 90 expect_type=${expect_type:-null};; 91 *) 92 expect_type=application/vnd.unknown.artifact.v1;; 93 esac 94 is $(jq -r '.artifactType'<<<"$artifact") "${expect_type}" "artifactType in artifact manifest with artifact_type arg \"${artifact_type}\"" 95 is $(jq -r '.manifests[0].artifactType'<<<"$index") "${expect_type}" "artifactType in image index with artifact_type arg \"${artifact_type}\"" 96 97 local expect_annotations 98 case ${artifact_annotations} in 99 artifact_annotations=*) 100 expect_annotations=$(jq -r '.foo' <<<"${artifact_annotations#artifact_annotations=}");; 101 *) 102 expect_annotations=null;; 103 esac 104 is $(jq -r '.annotations["foo"]'<<<"$artifact") "$expect_annotations" "\"foo\" annotation in artifact manifest with artifact_annotations arg \"${artifact_annotations}\"" 105 106 local expect_config_size 107 case ${artifact_config} in 108 artifact_config=*) 109 expect_config_size=$(wc -c <<<"${artifact_config#artifact_config=}") 110 expect_config_size=$((expect_config_size-1)) 111 if [[ $expect_config_size -eq 0 ]]; then 112 expect_config_size=2 113 fi ;; 114 *) 115 expect_config_size=2;; 116 esac 117 is $(jq -r '.config.size'<<<"$artifact") "$expect_config_size" "size of config blob in artifact manifest with artifact_config arg \"${artifact_config}\"" 118 119 local expect_config_type 120 case ${artifact_config_type} in 121 artifact_config_type=*) 122 expect_config_type=${artifact_config_type#artifact_config_type=} 123 if [[ -z "$expect_config_type" ]] ; then 124 if [[ -n "${artifact_config#artifact_config=}" ]] ; then 125 expect_config_type=application/vnd.oci.image.config.v1+json 126 else 127 expect_config_type=application/vnd.oci.empty.v1+json 128 fi 129 fi;; 130 *) 131 if [[ -n "${artifact_config#artifact_config=}" ]] ; then 132 expect_config_type=application/vnd.oci.image.config.v1+json 133 else 134 expect_config_type=application/vnd.oci.empty.v1+json 135 fi;; 136 esac 137 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}\"" 138 139 local expect_first_layer_type expect_second_layer_type 140 case ${artifact_layer_type} in 141 artifact_layer_type=*) 142 expect_first_layer_type=${artifact_layer_type#artifact_layer_type=} 143 expect_first_layer_type=${expect_first_layer_type:-text/plain} 144 expect_second_layer_type=${artifact_layer_type#artifact_layer_type=} 145 expect_second_layer_type=${expect_second_layer_type:-application/octet-stream};; 146 *) 147 expect_first_layer_type=text/plain; 148 expect_second_layer_type=application/octet-stream;; 149 esac 150 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}\"" 151 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}\"" 152 153 local expect_first_title expect_second_title 154 case ${artifact_exclude_titles} in 155 artifact_exclude_titles=true) 156 expect_first_title=null; 157 expect_second_title=null;; 158 *) 159 expect_first_title=listed.txt; 160 expect_second_title=zeroes;; 161 esac 162 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}\"" 163 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}\"" 164 165 t DELETE /v5.0.0/libpod/manifests/$id_artifacts 200 166 } 167 168 function test_artifacts() { 169 local artifact_annotations 170 local artifact_config 171 local artifact_config_type 172 local artifact_exclude_titles 173 local artifact_layer_type 174 local artifact_type 175 for artifact_annotations in "" artifact_annotations='{"foo":"bar"}' ; do 176 test_artifacts_with_args 177 done 178 for artifact_config in "" artifact_config= artifact_config="{}"; do 179 for artifact_config_type in "" artifact_config_type= artifact_config_type=text/plain ; do 180 test_artifacts_with_args 181 done 182 done 183 for artifact_exclude_titles in "" artifact_exclude_titles=true ; do 184 test_artifacts_with_args 185 done 186 for artifact_layer_type in "" artifact_layer_type= artifact_layer_type=text/plain artifact_layer_type=application/octet-stream ; do 187 test_artifacts_with_args 188 done 189 for artifact_type in "" artifact_type= artifact_type=text/plain artifact_type=application/octet-stream ; do 190 test_artifacts_with_args 191 done 192 } 193 test_artifacts 194 195 podman rmi -a 196 stop_registry