zotregistry.io/zot@v1.4.4-0.20231124084042-02a8ed785457/test/blackbox/pushpull.bats (about) 1 # Note: Intended to be run as "make run-blackbox-tests" or "make run-blackbox-ci" 2 # Makefile target installs & checks all necessary tooling 3 # Extra tools that are not covered in Makefile target needs to be added in verify_prerequisites() 4 5 load helpers_zot 6 7 function verify_prerequisites { 8 if [ ! $(command -v curl) ]; then 9 echo "you need to install curl as a prerequisite to running the tests" >&3 10 return 1 11 fi 12 13 if [ ! $(command -v jq) ]; then 14 echo "you need to install jq as a prerequisite to running the tests" >&3 15 return 1 16 fi 17 18 return 0 19 } 20 21 function setup_file() { 22 # Verify prerequisites are available 23 if ! $(verify_prerequisites); then 24 exit 1 25 fi 26 # Download test data to folder common for the entire suite, not just this file 27 skopeo --insecure-policy copy --format=oci docker://ghcr.io/project-zot/golang:1.20 oci:${TEST_DATA_DIR}/golang:1.20 28 # Setup zot server 29 local zot_root_dir=${BATS_FILE_TMPDIR}/zot 30 local zot_config_file=${BATS_FILE_TMPDIR}/zot_config.json 31 local oci_data_dir=${BATS_FILE_TMPDIR}/oci 32 mkdir -p ${zot_root_dir} 33 mkdir -p ${oci_data_dir} 34 zot_port=$(get_free_port) 35 echo ${zot_port} > ${BATS_FILE_TMPDIR}/zot.port 36 cat > ${zot_config_file}<<EOF 37 { 38 "distSpecVersion": "1.1.0-dev", 39 "storage": { 40 "rootDirectory": "${zot_root_dir}" 41 }, 42 "http": { 43 "address": "0.0.0.0", 44 "port": "${zot_port}" 45 }, 46 "log": { 47 "level": "debug", 48 "output": "${BATS_FILE_TMPDIR}/zot.log" 49 } 50 } 51 EOF 52 git -C ${BATS_FILE_TMPDIR} clone https://github.com/project-zot/helm-charts.git 53 zot_serve ${ZOT_PATH} ${zot_config_file} 54 wait_zot_reachable ${zot_port} 55 } 56 57 function teardown() { 58 # conditionally printing on failure is possible from teardown but not from from teardown_file 59 cat ${BATS_FILE_TMPDIR}/zot.log 60 } 61 62 function teardown_file() { 63 zot_stop_all 64 } 65 66 @test "push image" { 67 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 68 run skopeo --insecure-policy copy --dest-tls-verify=false \ 69 oci:${TEST_DATA_DIR}/golang:1.20 \ 70 docker://127.0.0.1:${zot_port}/golang:1.20 71 [ "$status" -eq 0 ] 72 run curl http://127.0.0.1:${zot_port}/v2/_catalog 73 [ "$status" -eq 0 ] 74 [ $(echo "${lines[-1]}" | jq '.repositories[]') = '"golang"' ] 75 run curl http://127.0.0.1:${zot_port}/v2/golang/tags/list 76 [ "$status" -eq 0 ] 77 [ $(echo "${lines[-1]}" | jq '.tags[]') = '"1.20"' ] 78 } 79 80 @test "pull image" { 81 local oci_data_dir=${BATS_FILE_TMPDIR}/oci 82 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 83 run skopeo --insecure-policy copy --src-tls-verify=false \ 84 docker://127.0.0.1:${zot_port}/golang:1.20 \ 85 oci:${oci_data_dir}/golang:1.20 86 [ "$status" -eq 0 ] 87 run cat ${BATS_FILE_TMPDIR}/oci/golang/index.json 88 [ "$status" -eq 0 ] 89 [ $(echo "${lines[-1]}" | jq '.manifests[].annotations."org.opencontainers.image.ref.name"') = '"1.20"' ] 90 } 91 92 @test "push image index" { 93 # --multi-arch below pushes an image index (containing many images) instead 94 # of an image manifest (single image) 95 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 96 run skopeo --insecure-policy copy --format=oci --dest-tls-verify=false --multi-arch=all \ 97 docker://public.ecr.aws/docker/library/busybox:latest \ 98 docker://127.0.0.1:${zot_port}/busybox:latest 99 [ "$status" -eq 0 ] 100 run curl http://127.0.0.1:${zot_port}/v2/_catalog 101 [ "$status" -eq 0 ] 102 [ $(echo "${lines[-1]}" | jq '.repositories[0]') = '"busybox"' ] 103 run curl http://127.0.0.1:${zot_port}/v2/busybox/tags/list 104 [ "$status" -eq 0 ] 105 [ $(echo "${lines[-1]}" | jq '.tags[]') = '"latest"' ] 106 } 107 108 @test "pull image index" { 109 local oci_data_dir=${BATS_FILE_TMPDIR}/oci 110 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 111 run skopeo --insecure-policy copy --src-tls-verify=false --multi-arch=all \ 112 docker://127.0.0.1:${zot_port}/busybox:latest \ 113 oci:${oci_data_dir}/busybox:latest 114 [ "$status" -eq 0 ] 115 run cat ${BATS_FILE_TMPDIR}/oci/busybox/index.json 116 [ "$status" -eq 0 ] 117 [ $(echo "${lines[-1]}" | jq '.manifests[].annotations."org.opencontainers.image.ref.name"') = '"latest"' ] 118 run skopeo --insecure-policy --override-arch=arm64 --override-os=linux copy --src-tls-verify=false --multi-arch=all \ 119 docker://127.0.0.1:${zot_port}/busybox:latest \ 120 oci:${oci_data_dir}/busybox:latest 121 [ "$status" -eq 0 ] 122 run cat ${BATS_FILE_TMPDIR}/oci/busybox/index.json 123 [ "$status" -eq 0 ] 124 [ $(echo "${lines[-1]}" | jq '.manifests[].annotations."org.opencontainers.image.ref.name"') = '"latest"' ] 125 run curl -X DELETE http://127.0.0.1:${zot_port}/v2/busybox/manifests/latest 126 [ "$status" -eq 0 ] 127 } 128 129 @test "push oras artifact" { 130 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 131 echo "{\"name\":\"foo\",\"value\":\"bar\"}" > config.json 132 echo "hello world" > artifact.txt 133 run oras push --plain-http 127.0.0.1:${zot_port}/hello-artifact:v2 \ 134 --config config.json:application/vnd.acme.rocket.config.v1+json artifact.txt:text/plain -d -v 135 [ "$status" -eq 0 ] 136 rm -f artifact.txt 137 rm -f config.json 138 } 139 140 @test "pull oras artifact" { 141 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 142 run oras pull --plain-http 127.0.0.1:${zot_port}/hello-artifact:v2 -d -v 143 [ "$status" -eq 0 ] 144 grep -q "hello world" artifact.txt 145 rm -f artifact.txt 146 } 147 148 @test "attach oras artifacts" { 149 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 150 # attach signature 151 echo "{\"artifact\": \"\", \"signature\": \"pat hancock\"}" > ${BATS_FILE_TMPDIR}/signature.json 152 run oras attach --plain-http 127.0.0.1:${zot_port}/golang:1.20 --image-spec v1.1-image --artifact-type 'signature/example' ${BATS_FILE_TMPDIR}/signature.json:application/json 153 [ "$status" -eq 0 ] 154 # attach sbom 155 echo "{\"version\": \"0.0.0.0\", \"artifact\": \"'127.0.0.1:${zot_port}/golang:1.20'\", \"contents\": \"good\"}" > ${BATS_FILE_TMPDIR}/sbom.json 156 run oras attach --plain-http 127.0.0.1:${zot_port}/golang:1.20 --image-spec v1.1-image --artifact-type 'sbom/example' ${BATS_FILE_TMPDIR}/sbom.json:application/json 157 [ "$status" -eq 0 ] 158 } 159 160 @test "discover oras artifacts" { 161 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 162 run oras discover --plain-http -o json 127.0.0.1:${zot_port}/golang:1.20 163 [ "$status" -eq 0 ] 164 [ $(echo "$output" | jq -r ".manifests | length") -eq 2 ] 165 } 166 167 @test "add and list tags using oras" { 168 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 169 run skopeo --insecure-policy copy --dest-tls-verify=false \ 170 oci:${TEST_DATA_DIR}/golang:1.20 \ 171 docker://127.0.0.1:${zot_port}/oras-tags:1.20 172 [ "$status" -eq 0 ] 173 run oras tag --plain-http 127.0.0.1:${zot_port}/oras-tags:1.20 1 new latest 174 [ "$status" -eq 0 ] 175 run oras repo tags --plain-http 127.0.0.1:${zot_port}/oras-tags 176 [ "$status" -eq 0 ] 177 echo "$output" 178 [ $(echo "$output" | wc -l) -eq 4 ] 179 [ "${lines[-1]}" == "new" ] 180 [ "${lines[-2]}" == "latest" ] 181 [ "${lines[-3]}" == "1.20" ] 182 [ "${lines[-4]}" == "1" ] 183 run oras repo tags --plain-http --last new 127.0.0.1:${zot_port}/oras-tags 184 [ "$status" -eq 0 ] 185 echo "$output" 186 [ -z $output ] 187 run oras repo tags --plain-http --last latest 127.0.0.1:${zot_port}/oras-tags 188 [ "$status" -eq 0 ] 189 echo "$output" 190 [ $(echo "$output" | wc -l) -eq 1 ] 191 [ "${lines[-1]}" == "new" ] 192 run oras repo tags --plain-http --last "1.20" 127.0.0.1:${zot_port}/oras-tags 193 [ "$status" -eq 0 ] 194 echo "$output" 195 [ $(echo "$output" | wc -l) -eq 2 ] 196 [ "${lines[-2]}" == "latest" ] 197 [ "${lines[-1]}" == "new" ] 198 run oras repo tags --plain-http --last "1" 127.0.0.1:${zot_port}/oras-tags 199 [ "$status" -eq 0 ] 200 echo "$output" 201 [ $(echo "$output" | wc -l) -eq 3 ] 202 [ "${lines[-3]}" == "1.20" ] 203 [ "${lines[-2]}" == "latest" ] 204 [ "${lines[-1]}" == "new" ] 205 } 206 207 @test "push helm chart" { 208 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 209 run helm package ${BATS_FILE_TMPDIR}/helm-charts/charts/zot -d ${BATS_FILE_TMPDIR} 210 [ "$status" -eq 0 ] 211 local chart_version=$(awk '/version/{printf $2}' ${BATS_FILE_TMPDIR}/helm-charts/charts/zot/Chart.yaml) 212 run helm push ${BATS_FILE_TMPDIR}/zot-${chart_version}.tgz oci://localhost:${zot_port}/zot-chart 213 [ "$status" -eq 0 ] 214 } 215 216 @test "pull helm chart" { 217 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 218 local chart_version=$(awk '/version/{printf $2}' ${BATS_FILE_TMPDIR}/helm-charts/charts/zot/Chart.yaml) 219 run helm pull oci://localhost:${zot_port}/zot-chart/zot --version ${chart_version} -d ${BATS_FILE_TMPDIR} 220 [ "$status" -eq 0 ] 221 } 222 223 @test "push image with regclient" { 224 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 225 run regctl registry set localhost:${zot_port} --tls disabled 226 [ "$status" -eq 0 ] 227 run regctl image copy ocidir://${TEST_DATA_DIR}/golang:1.20 localhost:${zot_port}/test-regclient 228 [ "$status" -eq 0 ] 229 } 230 231 @test "pull image with regclient" { 232 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 233 run regctl image copy localhost:${zot_port}/test-regclient ocidir://${TEST_DATA_DIR}/golang:1.20 234 [ "$status" -eq 0 ] 235 } 236 237 @test "list repositories with regclient" { 238 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 239 run regctl repo ls localhost:${zot_port} 240 [ "$status" -eq 0 ] 241 242 found=0 243 for i in "${lines[@]}" 244 do 245 246 if [ "$i" = 'test-regclient' ]; then 247 found=1 248 fi 249 done 250 [ "$found" -eq 1 ] 251 } 252 253 @test "list image tags with regclient" { 254 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 255 run regctl tag ls localhost:${zot_port}/test-regclient 256 [ "$status" -eq 0 ] 257 258 found=0 259 for i in "${lines[@]}" 260 do 261 262 if [ "$i" = 'latest' ]; then 263 found=1 264 fi 265 done 266 [ "$found" -eq 1 ] 267 } 268 269 @test "push manifest with regclient" { 270 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 271 manifest=$(regctl manifest get localhost:${zot_port}/test-regclient --format=raw-body) 272 run regctl manifest put localhost:${zot_port}/test-regclient:1.0.0 --format oci --content-type application/vnd.oci.image.manifest.v1+json --format oci <<EOF 273 $manifest 274 EOF 275 [ "$status" -eq 0 ] 276 } 277 278 @test "pull manifest with regclient" { 279 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 280 run regctl manifest get localhost:${zot_port}/test-regclient 281 [ "$status" -eq 0 ] 282 } 283 284 @test "pull manifest with docker client" { 285 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 286 run docker pull localhost:${zot_port}/test-regclient 287 [ "$status" -eq 0 ] 288 } 289 290 @test "pull manifest with crictl" { 291 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 292 run crictl pull localhost:${zot_port}/test-regclient 293 [ "$status" -eq 0 ] 294 } 295 296 @test "push OCI artifact with regclient" { 297 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 298 run regctl artifact put localhost:${zot_port}/artifact:demo <<EOF 299 this is an artifact 300 EOF 301 [ "$status" -eq 0 ] 302 } 303 304 @test "pull OCI artifact with regclient" { 305 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 306 run regctl manifest get localhost:${zot_port}/artifact:demo 307 [ "$status" -eq 0 ] 308 run regctl artifact get localhost:${zot_port}/artifact:demo 309 [ "$status" -eq 0 ] 310 [ "${lines[-1]}" == "this is an artifact" ] 311 } 312 313 @test "push OCI artifact references with regclient" { 314 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 315 run regctl artifact put localhost:${zot_port}/manifest-ref:demo <<EOF 316 test artifact 317 EOF 318 [ "$status" -eq 0 ] 319 run regctl artifact list localhost:${zot_port}/manifest-ref:demo --format raw-body 320 [ "$status" -eq 0 ] 321 [ $(echo "${lines[-1]}" | jq '.manifests | length') -eq 0 ] 322 run regctl artifact put --annotation demo=true --annotation format=oci --artifact-type "application/vnd.example.icecream.v1" --subject localhost:${zot_port}/manifest-ref:demo << EOF 323 test reference 324 EOF 325 [ "$status" -eq 0 ] 326 # with artifact media-type 327 run regctl artifact put localhost:${zot_port}/artifact-ref:demo <<EOF 328 test artifact 329 EOF 330 [ "$status" -eq 0 ] 331 run regctl artifact list localhost:${zot_port}/artifact-ref:demo --format raw-body 332 [ "$status" -eq 0 ] 333 [ $(echo "${lines[-1]}" | jq '.manifests | length') -eq 0 ] 334 run regctl artifact put --annotation demo=true --annotation format=oci --artifact-type "application/vnd.example.icecream.v1" --subject localhost:${zot_port}/artifact-ref:demo << EOF 335 test reference 336 EOF 337 [ "$status" -eq 0 ] 338 } 339 340 @test "pull OCI artifact references with regclient" { 341 zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port` 342 run regctl artifact list localhost:${zot_port}/manifest-ref:demo --format raw-body 343 [ "$status" -eq 0 ] 344 [ $(echo "${lines[-1]}" | jq '.manifests | length') -eq 1 ] 345 run regctl artifact list --filter-artifact-type "application/vnd.example.icecream.v1" localhost:${zot_port}/manifest-ref:demo --format raw-body 346 [ "$status" -eq 0 ] 347 [ $(echo "${lines[-1]}" | jq '.manifests | length') -eq 1 ] 348 run regctl artifact list --filter-artifact-type "application/invalid" localhost:${zot_port}/manifest-ref:demo --format raw-body 349 [ "$status" -eq 0 ] 350 [ $(echo "${lines[-1]}" | jq '.manifests | length') -eq 0 ] 351 # with artifact media-type 352 run regctl artifact list localhost:${zot_port}/artifact-ref:demo --format raw-body 353 [ "$status" -eq 0 ] 354 [ $(echo "${lines[-1]}" | jq '.manifests | length') -eq 1 ] 355 run regctl artifact list --filter-artifact-type "application/vnd.example.icecream.v1" localhost:${zot_port}/artifact-ref:demo --format raw-body 356 [ "$status" -eq 0 ] 357 [ $(echo "${lines[-1]}" | jq '.manifests | length') -eq 1 ] 358 run regctl artifact list --filter-artifact-type "application/invalid" localhost:${zot_port}/artifact-ref:demo --format raw-body 359 [ "$status" -eq 0 ] 360 [ $(echo "${lines[-1]}" | jq '.manifests | length') -eq 0 ] 361 }