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  }