zotregistry.io/zot@v1.4.4-0.20231124084042-02a8ed785457/test/blackbox/annotations.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      if [ ! $(command -v podman) ]; then
    19          echo "you need to install podman as a prerequisite to running the tests" >&3
    20          return 1
    21      fi
    22  
    23      return 0
    24  }
    25  
    26  function setup_file() {
    27      export COSIGN_PASSWORD=""
    28      # Verify prerequisites are available
    29      if ! $(verify_prerequisites); then
    30          exit 1
    31      fi
    32      # Download test data to folder common for the entire suite, not just this file
    33      skopeo --insecure-policy copy --format=oci docker://ghcr.io/project-zot/golang:1.20 oci:${TEST_DATA_DIR}/golang:1.20
    34      # Setup zot server
    35      local zot_root_dir=${BATS_FILE_TMPDIR}/zot
    36      local zot_config_file=${BATS_FILE_TMPDIR}/zot_config.json
    37      mkdir -p ${zot_root_dir}
    38      zot_port=$(get_free_port)
    39      echo ${zot_port} > ${BATS_FILE_TMPDIR}/zot.port
    40      cat > ${zot_config_file}<<EOF
    41  {
    42      "distSpecVersion": "1.1.0-dev",
    43      "storage": {
    44          "rootDirectory": "${zot_root_dir}"
    45      },
    46      "http": {
    47          "address": "0.0.0.0",
    48          "port": "${zot_port}"
    49      },
    50      "log": {
    51          "level": "debug",
    52          "output": "${BATS_FILE_TMPDIR}/zot.log"
    53      },
    54      "extensions":{
    55          "search": {
    56                      "enable": "true"
    57          },
    58          "lint": {
    59                      "enable": "true",
    60                      "mandatoryAnnotations": ["org.opencontainers.image.licenses", "org.opencontainers.image.vendor"]
    61          }
    62      }
    63  }
    64  EOF
    65      cat > ${BATS_FILE_TMPDIR}/stacker.yaml<<EOF
    66  \${{IMAGE_NAME}}:
    67    from:
    68      type: docker
    69      url: docker://\${{IMAGE_NAME}}:\${{IMAGE_TAG}}
    70    annotations:
    71      org.opencontainers.image.title: \${{IMAGE_NAME}}
    72      org.opencontainers.image.description: \${{DESCRIPTION}}
    73      org.opencontainers.image.licenses: \${{LICENSES}}
    74      org.opencontainers.image.vendor: \${{VENDOR}}
    75  EOF
    76      cat > ${BATS_FILE_TMPDIR}/Dockerfile<<EOF
    77  FROM public.ecr.aws/t0x7q1g8/centos:7
    78  CMD ["/bin/sh", "-c", "echo 'It works!'"]
    79  EOF
    80      zot_serve ${ZOT_PATH} ${zot_config_file}
    81      wait_zot_reachable ${zot_port}
    82  }
    83  
    84  function teardown() {
    85      # conditionally printing on failure is possible from teardown but not from from teardown_file
    86      cat ${BATS_FILE_TMPDIR}/zot.log
    87  }
    88  
    89  function teardown_file() {
    90      zot_stop_all
    91      run rm -rf ${HOME}/.config/notation
    92  }
    93  
    94  @test "build image with podman and specify annotations" {
    95      zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port`
    96      run podman build -f ${BATS_FILE_TMPDIR}/Dockerfile -t 127.0.0.1:${zot_port}/annotations:latest . --format oci --annotation org.opencontainers.image.vendor="CentOS" --annotation org.opencontainers.image.licenses="GPLv2"
    97      [ "$status" -eq 0 ]
    98      run podman push 127.0.0.1:${zot_port}/annotations:latest --tls-verify=false --format=oci
    99      [ "$status" -eq 0 ]
   100      run curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList(repo: \"annotations\") { Results { RepoName Tag Manifests {Digest ConfigDigest Size Layers { Size Digest }} Vendor Licenses }}}"}' http://localhost:${zot_port}/v2/_zot/ext/search
   101      [ "$status" -eq 0 ]
   102  
   103      [ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].RepoName') = '"annotations"' ]
   104      [ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].Vendor') = '"CentOS"' ]
   105      [ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].Licenses') = '"GPLv2"' ]
   106  }
   107  
   108  @test "build image with stacker and specify annotations" {
   109      zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port`
   110      run stacker --oci-dir ${BATS_FILE_TMPDIR}/stackeroci --stacker-dir ${BATS_FILE_TMPDIR}/.stacker --roots-dir ${BATS_FILE_TMPDIR}/roots build -f ${BATS_FILE_TMPDIR}/stacker.yaml --substitute IMAGE_NAME="ghcr.io/project-zot/golang" --substitute IMAGE_TAG="1.20" --substitute DESCRIPTION="mydesc" --substitute VENDOR="CentOs" --substitute LICENSES="GPLv2" --substitute COMMIT= --substitute OS=$OS --substitute ARCH=$ARCH
   111      [ "$status" -eq 0 ]
   112      run stacker --oci-dir ${BATS_FILE_TMPDIR}/stackeroci --stacker-dir ${BATS_FILE_TMPDIR}/.stacker --roots-dir ${BATS_FILE_TMPDIR}/roots publish -f ${BATS_FILE_TMPDIR}/stacker.yaml --substitute IMAGE_NAME="ghcr.io/project-zot/golang" --substitute IMAGE_TAG="1.20" --substitute DESCRIPTION="mydesc" --substitute VENDOR="CentOs" --substitute LICENSES="GPLv2" --url docker://127.0.0.1:${zot_port} --tag 1.20 --skip-tls
   113      [ "$status" -eq 0 ]
   114      run curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList(repo: \"ghcr.io/project-zot/golang\") { Results { RepoName Tag Manifests {Digest ConfigDigest Size Layers { Size Digest }} Vendor Licenses Description }}}"}' http://localhost:${zot_port}/v2/_zot/ext/search
   115      [ "$status" -eq 0 ]
   116      [ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].RepoName') = '"ghcr.io/project-zot/golang"' ]
   117      [ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].Description') = '"mydesc"' ]
   118      [ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].Vendor') = '"CentOs"' ]
   119      [ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].Licenses') = '"GPLv2"' ]
   120  }
   121  
   122  @test "sign/verify with cosign (only tag-based signatures)" {
   123      zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port`
   124      run curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList(repo: \"annotations\") { Results { RepoName Tag Manifests {Digest ConfigDigest Size Layers { Size Digest }} Vendor Licenses }}}"}' http://localhost:${zot_port}/v2/_zot/ext/search
   125      [ "$status" -eq 0 ]
   126      [ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].RepoName') = '"annotations"' ]
   127      local digest=$(echo "${lines[-1]}" | jq -r '.data.ImageList.Results[0].Manifests[0].Digest')
   128  
   129      run cosign initialize
   130      [ "$status" -eq 0 ]
   131      run cosign generate-key-pair --output-key-prefix "${BATS_FILE_TMPDIR}/cosign-sign-test"
   132      [ "$status" -eq 0 ]
   133      run cosign sign --key ${BATS_FILE_TMPDIR}/cosign-sign-test.key localhost:${zot_port}/annotations:latest --yes
   134      [ "$status" -eq 0 ]
   135      run cosign verify --key ${BATS_FILE_TMPDIR}/cosign-sign-test.pub localhost:${zot_port}/annotations:latest
   136      [ "$status" -eq 0 ]
   137      local sigName=$(echo "${lines[-1]}" | jq '.[].critical.image."docker-manifest-digest"')
   138      [[ "$sigName" == *"${digest}"* ]]
   139  }
   140  
   141  @test "sign/verify with cosign (only referrers)" {
   142      zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port`
   143      run curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList(repo: \"annotations\") { Results { RepoName Tag Manifests {Digest ConfigDigest Size Layers { Size Digest }} Vendor Licenses }}}"}' http://localhost:${zot_port}/v2/_zot/ext/search
   144      [ "$status" -eq 0 ]
   145      [ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].RepoName') = '"annotations"' ]
   146      local digest=$(echo "${lines[-1]}" | jq -r '.data.ImageList.Results[0].Manifests[0].Digest')
   147  
   148      export COSIGN_OCI_EXPERIMENTAL=1
   149      export COSIGN_EXPERIMENTAL=1
   150      run cosign initialize
   151      [ "$status" -eq 0 ]
   152      run cosign generate-key-pair --output-key-prefix "${BATS_FILE_TMPDIR}/cosign-sign-test-experimental"
   153      [ "$status" -eq 0 ]
   154      run cosign sign --registry-referrers-mode=oci-1-1 --key ${BATS_FILE_TMPDIR}/cosign-sign-test-experimental.key localhost:${zot_port}/annotations:latest --yes
   155      [ "$status" -eq 0 ]
   156      run cosign verify --key ${BATS_FILE_TMPDIR}/cosign-sign-test-experimental.pub localhost:${zot_port}/annotations:latest
   157      [ "$status" -eq 0 ]
   158      local sigName=$(echo "${lines[-1]}" | jq '.[].critical.image."docker-manifest-digest"')
   159      [[ "$sigName" == *"${digest}"* ]]
   160      unset COSIGN_OCI_EXPERIMENTAL
   161      unset COSIGN_EXPERIMENTAL
   162  }
   163  
   164  @test "sign/verify with cosign (tag and referrers)" {
   165      zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port`
   166      run curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList(repo: \"annotations\") { Results { RepoName Tag Manifests {Digest ConfigDigest Size Layers { Size Digest }} Vendor Licenses }}}"}' http://localhost:${zot_port}/v2/_zot/ext/search
   167      [ "$status" -eq 0 ]
   168      [ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].RepoName') = '"annotations"' ]
   169      local digest=$(echo "${lines[-1]}" | jq -r '.data.ImageList.Results[0].Manifests[0].Digest')
   170  
   171      export COSIGN_OCI_EXPERIMENTAL=1
   172      export COSIGN_EXPERIMENTAL=1
   173      run cosign initialize
   174      [ "$status" -eq 0 ]
   175  
   176      run cosign generate-key-pair --output-key-prefix "${BATS_FILE_TMPDIR}/cosign-sign-test-tag-1"
   177      [ "$status" -eq 0 ]
   178      run cosign sign --key ${BATS_FILE_TMPDIR}/cosign-sign-test-tag-1.key localhost:${zot_port}/annotations:latest --yes
   179      [ "$status" -eq 0 ]
   180  
   181      run cosign generate-key-pair --output-key-prefix "${BATS_FILE_TMPDIR}/cosign-sign-test-referrers-1"
   182      [ "$status" -eq 0 ]
   183      run cosign sign --registry-referrers-mode=oci-1-1 --key ${BATS_FILE_TMPDIR}/cosign-sign-test-referrers-1.key localhost:${zot_port}/annotations:latest --yes
   184      [ "$status" -eq 0 ]
   185  
   186      run cosign generate-key-pair --output-key-prefix "${BATS_FILE_TMPDIR}/cosign-sign-test-tag-2"
   187      [ "$status" -eq 0 ]
   188      run cosign sign --key ${BATS_FILE_TMPDIR}/cosign-sign-test-tag-2.key localhost:${zot_port}/annotations:latest --yes
   189      [ "$status" -eq 0 ]
   190  
   191      run cosign verify --key ${BATS_FILE_TMPDIR}/cosign-sign-test-tag-1.pub localhost:${zot_port}/annotations:latest
   192      [ "$status" -eq 0 ]
   193      local sigName=$(echo "${lines[-1]}" | jq '.[].critical.image."docker-manifest-digest"')
   194      [[ "$sigName" == *"${digest}"* ]]
   195      run cosign verify --key ${BATS_FILE_TMPDIR}/cosign-sign-test-tag-2.pub localhost:${zot_port}/annotations:latest
   196      [ "$status" -eq 0 ]
   197      local sigName=$(echo "${lines[-1]}" | jq '.[].critical.image."docker-manifest-digest"')
   198      [[ "$sigName" == *"${digest}"* ]]
   199      run cosign verify --key ${BATS_FILE_TMPDIR}/cosign-sign-test-referrers-1.pub localhost:${zot_port}/annotations:latest
   200      [ "$status" -eq 0 ]
   201      local sigName=$(echo "${lines[-1]}" | jq '.[].critical.image."docker-manifest-digest"')
   202      [[ "$sigName" == *"${digest}"* ]]
   203  
   204      run cosign generate-key-pair --output-key-prefix "${BATS_FILE_TMPDIR}/cosign-sign-test-referrers-2"
   205      [ "$status" -eq 0 ]
   206      run cosign sign --registry-referrers-mode=oci-1-1 --key ${BATS_FILE_TMPDIR}/cosign-sign-test-referrers-2.key localhost:${zot_port}/annotations:latest --yes
   207      [ "$status" -eq 0 ]
   208      run cosign verify --key ${BATS_FILE_TMPDIR}/cosign-sign-test-referrers-2.pub localhost:${zot_port}/annotations:latest
   209      [ "$status" -eq 0 ]
   210      local sigName=$(echo "${lines[-1]}" | jq '.[].critical.image."docker-manifest-digest"')
   211      [[ "$sigName" == *"${digest}"* ]]
   212  
   213      unset COSIGN_OCI_EXPERIMENTAL
   214      unset COSIGN_EXPERIMENTAL
   215  }
   216  
   217  @test "sign/verify with notation" {
   218      zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port`
   219      run curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList(repo: \"annotations\") { Results { RepoName Tag Manifests {Digest ConfigDigest Size Layers { Size Digest }} Vendor Licenses }}}"}' http://localhost:${zot_port}/v2/_zot/ext/search
   220      [ "$status" -eq 0 ]
   221      [ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].RepoName') = '"annotations"' ]
   222      [ "$status" -eq 0 ]
   223  
   224      run notation cert generate-test "notation-sign-test"
   225      [ "$status" -eq 0 ]
   226  
   227      local trust_policy_file=${HOME}/.config/notation/trustpolicy.json
   228  
   229      cat >${trust_policy_file} <<EOF
   230  {
   231      "version": "1.0",
   232      "trustPolicies": [
   233          {
   234              "name": "notation-sign-test",
   235              "registryScopes": [ "*" ],
   236              "signatureVerification": {
   237                  "level" : "strict"
   238              },
   239              "trustStores": [ "ca:notation-sign-test" ],
   240              "trustedIdentities": [
   241                  "*"
   242              ]
   243          }
   244      ]
   245  }
   246  EOF
   247  
   248      run notation sign --key "notation-sign-test" --insecure-registry localhost:${zot_port}/annotations:latest
   249      [ "$status" -eq 0 ]
   250      run notation verify --insecure-registry localhost:${zot_port}/annotations:latest
   251      [ "$status" -eq 0 ]
   252      run notation list --insecure-registry localhost:${zot_port}/annotations:latest
   253      [ "$status" -eq 0 ]
   254  }
   255  
   256  @test "sign/verify with notation( NOTATION_EXPERIMENTAL=1 and --allow-referrers-api )" {
   257      zot_port=`cat ${BATS_FILE_TMPDIR}/zot.port`
   258      run curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList(repo: \"annotations\") { Results { RepoName Tag Manifests {Digest ConfigDigest Size Layers { Size Digest }} Vendor Licenses }}}"}' http://localhost:${zot_port}/v2/_zot/ext/search
   259      [ "$status" -eq 0 ]
   260      [ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].RepoName') = '"annotations"' ]
   261      [ "$status" -eq 0 ]
   262  
   263      run notation cert generate-test "notation-sign-test-experimental"
   264      [ "$status" -eq 0 ]
   265  
   266      local trust_policy_file=${HOME}/.config/notation/trustpolicy.json
   267  
   268      cat >${trust_policy_file} <<EOF
   269  {
   270      "version": "1.0",
   271      "trustPolicies": [
   272          {
   273              "name": "notation-sign-test-experimental",
   274              "registryScopes": [ "*" ],
   275              "signatureVerification": {
   276                  "level" : "strict"
   277              },
   278              "trustStores": [ "ca:notation-sign-test-experimental" ],
   279              "trustedIdentities": [
   280                  "*"
   281              ]
   282          }
   283      ]
   284  }
   285  EOF
   286  
   287      export NOTATION_EXPERIMENTAL=1
   288      run notation sign --allow-referrers-api --key "notation-sign-test-experimental" --insecure-registry localhost:${zot_port}/annotations:latest
   289      [ "$status" -eq 0 ]
   290      run notation verify --allow-referrers-api --insecure-registry localhost:${zot_port}/annotations:latest
   291      [ "$status" -eq 0 ]
   292      run notation list --allow-referrers-api --insecure-registry localhost:${zot_port}/annotations:latest
   293      [ "$status" -eq 0 ]
   294      unset NOTATION_EXPERIMENTAL
   295  }