From ba54dcfb0aa4e2fad5db51037fd4dc29c5dd3419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Min=C3=A1=C5=99?= Date: Fri, 2 Sep 2016 11:16:26 +0200 Subject: [PATCH] New e2e test: fetch manifest schema 2 with old client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michal Minář --- hack/util.sh | 14 ++++++++- test/end-to-end/core.sh | 66 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 74 insertions(+), 6 deletions(-) diff --git a/hack/util.sh b/hack/util.sh index 2b6b22436020..e65d8b92c0da 100644 --- a/hack/util.sh +++ b/hack/util.sh @@ -660,7 +660,19 @@ function install_registry() { readonly -f install_registry function wait_for_registry() { - wait_for_command "oc get endpoints docker-registry --template='{{ len .subsets }}' --config='${ADMIN_KUBECONFIG}' | grep -q '[1-9][0-9]*'" $((5*TIME_MIN)) + local latestversion=$(oc get dc/docker-registry -o jsonpath='{.status.latestVersion}' --config="${ADMIN_KUBECONFIG}") + if [[ -z "${latestversion:-}" ]]; then + echo "Failed to get latest version of docker-registry deployment config" + exit 1 + fi + wait_for_command "oc get rc/docker-registry-$latestversion --template \"{{ index .metadata.annotations \\\"openshift.io/deployment.phase\\\" }}\" --config='${ADMIN_KUBECONFIG}' | grep Complete" $((5*TIME_MIN)) + local registrypod=$(oc get pod -l "deployment=docker-registry-$latestversion" -o jsonpath=$'{.items[*].metadata.name}\n' --config="${ADMIN_KUBECONFIG}" | head -n 1) + if [[ -z "${registrypod:-}" ]]; then + echo "Failed to get docker registry pod name" + exit 1 + fi + local podnamejs='{range .subsets[*]}{range .addresses[*]}{.targetRef.name},{end}{end}' + wait_for_command "oc get endpoints/docker-registry -o 'jsonpath=$podnamejs' --config='${ADMIN_KUBECONFIG}' | egrep -q '(^|,)${registrypod},'" $TIME_MIN local readyjs='{.items[*].status.conditions[?(@.type=="Ready")].status}' wait_for_command "oc get pod -l deploymentconfig=docker-registry -o jsonpath='$readyjs' --config='${ADMIN_KUBECONFIG}' | grep -qi true" $TIME_MIN } diff --git a/test/end-to-end/core.sh b/test/end-to-end/core.sh index 9c23ce143cea..5b575518c84b 100755 --- a/test/end-to-end/core.sh +++ b/test/end-to-end/core.sh @@ -195,12 +195,33 @@ os::cmd::expect_success "oc tag cache/hello-world@${imagedigest} cross:namespace os::cmd::expect_success "docker pull ${DOCKER_REGISTRY}/custom/cross:namespace-pull-id" echo "[INFO] Cross namespace pull successful" -# check to make sure an image-pusher can push an image +# check to make sure an image-pusher can push an image and pull any image +os::cmd::expect_success "oc project ${CLUSTER_ADMIN_CONTEXT}" os::cmd::expect_success 'oc policy add-role-to-user system:image-pusher pusher' +os::cmd::expect_success 'oc policy add-role-to-user -n test admin pusher' os::cmd::expect_success 'oc login -u pusher -p pass' pusher_token=$(oc config view --flatten --minify -o template --template='{{with index .users 0}}{{.user.token}}{{end}}') os::cmd::expect_success_and_text "echo ${pusher_token}" '.+' +echo "[INFO] Fetch manifest V2 schema 2 image with old client using pullthrough" +os::cmd::expect_success "oc project test" +os::cmd::expect_success_and_text "oc get -o jsonpath='{.image.dockerImageManifestMediaType}' istag hello-world:pullthrough" 'application/vnd\.docker\.distribution\.manifest\.v2\+json' +hello_world_name=$(oc get -o 'jsonpath={.image.metadata.name}' istag hello-world:pullthrough) +os::cmd::expect_success_and_text "echo ${hello_world_name:-}" '.+' +# dockerImageManifest is retrievable only with "images" resource +hello_world_config_name=$(oc get -o 'jsonpath={.dockerImageManifest}' image "$hello_world_name" --context="$CLUSTER_ADMIN_CONTEXT" | jq -r '.config.digest') +hello_world_config_image=$(oc get -o 'jsonpath={.image.dockerImageConfig}' istag hello-world:pullthrough | jq -r '.container_config.Image') +os::cmd::expect_success_and_text "echo ${hello_world_config_name:-}:${hello_world_config_image:-}" '.+:.+' +# verify we can fetch the config +os::cmd::expect_success_and_text "curl -u 'pusher:${pusher_token}' -v -s -o ${ARTIFACT_DIR}/hello-world-config.json ${DOCKER_REGISTRY}/v2/test/hello-world/blobs/${hello_world_config_name} 2>&1" "Docker-Content-Digest:\s*${hello_world_config_name}" +os::cmd::expect_success_and_text "jq -r '.container_config.Image' ${ARTIFACT_DIR}/hello-world-config.json" "${hello_world_config_image}" +hello_world_schema1_digest=$(curl -u pusher:${pusher_token} -s -v -o ${ARTIFACT_DIR}/hello-world-manifest.json ${DOCKER_REGISTRY}/v2/test/hello-world/manifests/pullthrough |& sed -n 's/.*Docker-Content-Digest:\s*\(\S\+\).*/\1/p') +# ensure the manifest was converted to schema 1 +os::cmd::expect_success_and_text "jq -r '.schemaVersion' ${ARTIFACT_DIR}/hello-world-manifest.json" '^1$' +os::cmd::expect_success "[ '${hello_world_schema1_digest:-}' != '${hello_world_name}' ] && [ -n '${hello_world_schema1_digest:-}' ]" +os::cmd::expect_success_and_text "curl -I -u 'pusher:${pusher_token}' '${DOCKER_REGISTRY}/v2/test/hello-world/manifests/${hello_world_schema1_digest}'" "404 Not Found" +echo "[INFO] Manifest V2 schema 2 image fetch successfully with old client" + echo "[INFO] Docker login as pusher to ${DOCKER_REGISTRY}" os::cmd::expect_success "docker login -u e2e-user -p ${pusher_token} -e pusher@openshift.com ${DOCKER_REGISTRY}" echo "[INFO] Docker login successful" @@ -221,9 +242,9 @@ os::cmd::try_until_text 'oc policy who-can get imagestreams/layers -n custom' 's os::cmd::expect_success "docker pull ${DOCKER_REGISTRY}/custom/cross:namespace-pull" os::cmd::expect_success "docker pull ${DOCKER_REGISTRY}/custom/cross:namespace-pull-id" # unauthorized pushes return authorization errors, regardless of backing data -os::cmd::expect_failure_and_text "docker push ${DOCKER_REGISTRY}/missing/image:tag" "authentication required" -os::cmd::expect_failure_and_text "docker push ${DOCKER_REGISTRY}/custom/cross:namespace-pull" "authentication required" -os::cmd::expect_failure_and_text "docker push ${DOCKER_REGISTRY}/custom/cross:namespace-pull-id" "authentication required" +os::cmd::expect_failure_and_text "docker push ${DOCKER_REGISTRY}/missing/image:tag" "authentication required|not authorized" +os::cmd::expect_failure_and_text "docker push ${DOCKER_REGISTRY}/custom/cross:namespace-pull" "authentication required|not authorized" +os::cmd::expect_failure_and_text "docker push ${DOCKER_REGISTRY}/custom/cross:namespace-pull-id" "authentication required|not authorized" # test anonymous pushes os::cmd::expect_success 'oc policy add-role-to-user system:image-pusher system:anonymous -n custom' os::cmd::try_until_text 'oc policy who-can update imagestreams/layers -n custom' 'system:anonymous' @@ -242,9 +263,11 @@ os::cmd::expect_success "oc project ${CLUSTER_ADMIN_CONTEXT}" os::cmd::expect_success_and_text 'oc whoami' 'system:admin' os::cmd::expect_success "oc tag --source docker centos/ruby-22-centos7:latest -n custom ruby-22-centos7:latest" os::cmd::expect_success 'oc policy add-role-to-user registry-viewer pusher -n custom' +os::cmd::expect_success 'oc policy add-role-to-user registry-viewer pusher -n cache' os::cmd::expect_success 'oc policy add-role-to-user system:image-pusher pusher -n crossmount' echo "[INFO] Docker cross-repo mount" +os::cmd::try_until_text "oc policy can-i get imagestreams/layers -n cache '--token=${pusher_token}'" "yes" os::cmd::expect_success_and_text "curl -I -X HEAD -u 'pusher:${pusher_token}' '${DOCKER_REGISTRY}/v2/cache/ruby-22-centos7/blobs/$rubyimageblob'" "200 OK" os::cmd::try_until_text "oc get -n custom is/ruby-22-centos7 -o 'jsonpath={.status.tags[*].tag}'" "latest" $((20*TIME_SEC)) os::cmd::expect_success_and_text "curl -I -X HEAD -u 'pusher:${pusher_token}' '${DOCKER_REGISTRY}/v2/custom/ruby-22-centos7/blobs/$rubyimageblob'" "200 OK" @@ -257,12 +280,45 @@ os::cmd::expect_success_and_text "curl -I -X POST -u 'pusher:${pusher_token}' '$ # check that the blob is linked now os::cmd::expect_success_and_text "curl -I -X HEAD -u 'pusher:${pusher_token}' '${DOCKER_REGISTRY}/v2/crossmount/repo/blobs/$rubyimageblob'" "200 OK" # remove pusher's permissions to read from the source repository -os::cmd::expect_success "oc policy remove-role-from-user system:image-pusher pusher -n cache" +os::cmd::expect_success "oc policy remove-role-from-user registry-viewer pusher -n cache" os::cmd::try_until_text "oc policy can-i get imagestreams/layers -n cache '--token=${pusher_token}'" "no" # cross-repo mount failed because of access denied os::cmd::expect_success_and_text "curl -I -X POST -u 'pusher:${pusher_token}' '${DOCKER_REGISTRY}/v2/crossmount/repo/blobs/uploads/?mount=$rubyimageblob&from=cache/ruby-22-centos7'" "202 Accepted" echo "[INFO] Docker cross-repo mount successful" +echo "[INFO] Configure registry to accept manifest V2 schema 2" +os::cmd::expect_success "oc project ${CLUSTER_ADMIN_CONTEXT}" +os::cmd::expect_success 'oc env -n default dc/docker-registry REGISTRY_MIDDLEWARE_REPOSITORY_OPENSHIFT_ACCEPTSCHEMA2=true' +wait_for_registry +echo "[INFO] Registry configured to accept manifest V2 schema 2" + +echo "[INFO] Accept manifest V2 schema 2" +os::cmd::expect_success "oc project test" +os::cmd::expect_success "docker tag busybox '${DOCKER_REGISTRY}/test/busybox'" +os::cmd::expect_success "docker push '${DOCKER_REGISTRY}/test/busybox'" +# image accepted as schema 2 +os::cmd::expect_success_and_text "oc get -o jsonpath='{.image.dockerImageManifestMediaType}' istag busybox:latest" 'application/vnd\.docker\.distribution\.manifest\.v2\+json' +echo "[INFO] Manifest V2 schema 2 successfully accepted" + +echo "[INFO] Convert manifest V2 schema 2 to schema 1 for older client" +os::cmd::expect_success 'oc login -u pusher -p pass' +os::cmd::expect_success "oc new-project schema2tagged" +os::cmd::expect_success "oc tag --source=istag test/busybox:latest busybox:latest" +busybox_name=$(oc get -o 'jsonpath={.image.metadata.name}' istag busybox:latest) +os::cmd::expect_success_and_text "echo ${busybox_name:-}" '.+' +busybox_schema1_digest=$(curl -u "pusher:${pusher_token}" -s -v -o ${ARTIFACT_DIR}/busybox-manifest.json ${DOCKER_REGISTRY}/v2/schema2tagged/busybox/manifests/latest |& sed -n 's/.*Docker-Content-Digest:\s*\(\S\+\).*/\1/p') +# ensure the manifest was converted to schema 1 +os::cmd::expect_success_and_text "jq -r '.schemaVersion' ${ARTIFACT_DIR}/busybox-manifest.json" '^1$' +os::cmd::expect_success "[ '${busybox_schema1_digest:-}' != '${busybox_name}' ] && [ -n '${busybox_schema1_digest:-}' ]" +os::cmd::expect_success_and_text "curl -I -u 'pusher:${pusher_token}' '${DOCKER_REGISTRY}/v2/schema2tagged/busybox/manifests/${busybox_schema1_digest}'" "404 Not Found" +# ensure we can fetch it back as schema 2 +os::cmd::expect_success_and_text "curl -I -u 'pusher:${pusher_token}' -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' ${DOCKER_REGISTRY}/v2/schema2tagged/busybox/manifests/latest" "Docker-Content-Digest:\s*${busybox_name}" +echo "[INFO] Manifest V2 schema 2 successfully converted to schema 1" + +echo "[INFO] Back to 'default' project with 'admin' user..." +os::cmd::expect_success "oc project ${CLUSTER_ADMIN_CONTEXT}" +os::cmd::expect_success_and_text 'oc whoami' 'system:admin' + # The build requires a dockercfg secret in the builder service account in order # to be able to push to the registry. Make sure it exists first. echo "[INFO] Waiting for dockercfg secrets to be generated in project 'test' before building"