From e4413396eba201ab102f82e36558fb38bef874c8 Mon Sep 17 00:00:00 2001 From: Adriano Cunha Date: Tue, 27 Nov 2018 14:15:56 -0800 Subject: [PATCH] Publish nightly knative/build releases to knative-nightly Part of https://github.com/knative/serving/issues/2555. Bonus: updates `test-infra` to include the latest fixes and features, while also updating the Gopkg files so the cleanup workaround in `update-deps.sh` is not necessary anymore. --- Gopkg.lock | 10 +-- Gopkg.toml | 3 +- hack/release.md | 4 +- hack/release.sh | 4 +- hack/update-deps.sh | 3 - .../knative/test-infra/scripts/e2e-tests.sh | 86 +++++++++++++------ .../knative/test-infra/scripts/library.sh | 30 ++++--- .../test-infra/scripts/presubmit-tests.sh | 81 +++++++++++------ .../knative/test-infra/scripts/release.sh | 7 +- 9 files changed, 142 insertions(+), 86 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 7e0370b8..857ab663 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -234,11 +234,11 @@ [[projects]] branch = "master" - digest = "1:74cb96c67ebca1a00240a23e7a6a33b7a9b3336f621e223666eff9550acae1a8" + digest = "1:0cabae2c3a124c49ed5e862866e1228f08a1a6e49d0daf971e5a72e5e56095a4" name = "github.com/knative/test-infra" - packages = ["."] - pruneopts = "T" - revision = "9303db13a4bcf216af14aa7ab65802c0672e01f6" + packages = ["scripts"] + pruneopts = "UT" + revision = "2a11b760d21b3a969d80d9ccf18323e1d5ed03a6" [[projects]] digest = "1:56dbf15e091bf7926cb33a57cb6bdfc658fc6d3498d2f76f10a97ce7856f1fde" @@ -811,7 +811,7 @@ "github.com/knative/pkg/test", "github.com/knative/pkg/test/logging", "github.com/knative/pkg/webhook", - "github.com/knative/test-infra", + "github.com/knative/test-infra/scripts", "go.opencensus.io/trace", "go.uber.org/zap", "golang.org/x/sync/errgroup", diff --git a/Gopkg.toml b/Gopkg.toml index 60b98030..980fabe4 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -9,7 +9,7 @@ required = [ "k8s.io/code-generator/cmd/lister-gen", "k8s.io/code-generator/cmd/informer-gen", "github.com/knative/caching/pkg/apis/caching", - "github.com/knative/test-infra", + "github.com/knative/test-infra/scripts", ] [[override]] @@ -66,5 +66,4 @@ required = [ [[prune.project]] name = "github.com/knative/test-infra" - unused-packages = false non-go = false diff --git a/hack/release.md b/hack/release.md index e72a4ba6..900f5fc4 100644 --- a/hack/release.md +++ b/hack/release.md @@ -20,9 +20,9 @@ added.* * `--publish`, `--nopublish` Whether the generated images should be published to a GCR, and the generated manifests written to a GCS bucket or not. If yes, the destination GCR is defined by the environment variable -`$BUILD_RELEASE_GCR` (defaults to `gcr.io/knative-releases`) and the +`$BUILD_RELEASE_GCR` (defaults to `gcr.io/knative-nightly`) and the destination GCS bucket is defined by the environment variable -`$BUILD_RELEASE_GCS` (defaults to `knative-releases/build`). If no, the +`$BUILD_RELEASE_GCS` (defaults to `knative-nightly/build`). If no, the images will be pushed to the `ko.local` registry, and the manifests written to the local disk only (in the repository root directory). diff --git a/hack/release.sh b/hack/release.sh index 1031d273..b145c729 100755 --- a/hack/release.sh +++ b/hack/release.sh @@ -17,8 +17,8 @@ source $(dirname $0)/../vendor/github.com/knative/test-infra/scripts/release.sh # Set default GCS/GCR -: ${BUILD_RELEASE_GCS:="knative-releases/build"} -: ${BUILD_RELEASE_GCR:="gcr.io/knative-releases"} +: ${BUILD_RELEASE_GCS:="knative-nightly/build"} +: ${BUILD_RELEASE_GCR:="gcr.io/knative-nightly"} readonly BUILD_RELEASE_GCS readonly BUILD_RELEASE_GCR diff --git a/hack/update-deps.sh b/hack/update-deps.sh index 17404d5f..83585706 100755 --- a/hack/update-deps.sh +++ b/hack/update-deps.sh @@ -25,7 +25,4 @@ cd ${REPO_ROOT_DIR} # Ensure we have everything we need under vendor/ dep ensure -# Keep the only dir in knative/test-infra we're interested in -find vendor/github.com/knative/test-infra -mindepth 1 -maxdepth 1 ! -name scripts -exec rm -fr {} \; - update_licenses third_party/VENDOR-LICENSE "./cmd/*" diff --git a/vendor/github.com/knative/test-infra/scripts/e2e-tests.sh b/vendor/github.com/knative/test-infra/scripts/e2e-tests.sh index edad530e..b1dd6644 100755 --- a/vendor/github.com/knative/test-infra/scripts/e2e-tests.sh +++ b/vendor/github.com/knative/test-infra/scripts/e2e-tests.sh @@ -45,6 +45,9 @@ readonly E2E_CLUSTER_NODES=3 readonly E2E_CLUSTER_MACHINE=n1-standard-4 readonly TEST_RESULT_FILE=/tmp/${E2E_BASE_NAME}-e2e-result +# Flag whether test is using a boskos GCP project +IS_BOSKOS=0 + # Tear down the test resources. function teardown_test_resources() { header "Tearing down test environment" @@ -53,15 +56,8 @@ function teardown_test_resources() { teardown fi - # Delete Knative Serving images when using prow. - if (( IS_PROW )); then - echo "Images in ${DOCKER_REPO_OVERRIDE}:" - gcloud container images list --repository=${DOCKER_REPO_OVERRIDE} - delete_gcr_images ${DOCKER_REPO_OVERRIDE} - else - # Delete the kubernetes source downloaded by kubetest - rm -fr kubernetes kubernetes.tar.gz - fi + # Delete the kubernetes source downloaded by kubetest + rm -fr kubernetes kubernetes.tar.gz } # Exit test, dumping current state info. @@ -83,11 +79,12 @@ function go_test_e2e() { } # Download the k8s binaries required by kubetest. +# Parameters: $1 - GCP project that will host the test cluster. function download_k8s() { local version=${E2E_CLUSTER_VERSION} # Fetch valid versions local versions="$(gcloud container get-server-config \ - --project=${GCP_PROJECT} \ + --project=$1 \ --format='value(validMasterVersions)' \ --region=${E2E_CLUSTER_REGION})" local gke_versions=(`echo -n ${versions//;/ /}`) @@ -118,6 +115,7 @@ function download_k8s() { mv kubernetes/client/kubernetes-client-*.tar.gz . rm -fr kubernetes # Create an empty kubernetes test tarball; we don't use it but kubetest will fetch it + # As of August 21 2018 this means avoiding a useless 1.2GB download tar -czf kubernetes-test.tar.gz -T /dev/null fi popd @@ -128,7 +126,7 @@ function download_k8s() { # This is intended to be called when a test fails to provide debugging information. function dump_cluster_state() { echo "***************************************" - echo "*** TEST FAILED ***" + echo "*** E2E TEST FAILED ***" echo "*** Start of information dump ***" echo "***************************************" echo ">>> All resources:" @@ -139,7 +137,7 @@ function dump_cluster_state() { kubectl get events --all-namespaces function_exists dump_extra_cluster_state && dump_extra_cluster_state echo "***************************************" - echo "*** TEST FAILED ***" + echo "*** E2E TEST FAILED ***" echo "*** End of information dump ***" echo "***************************************" } @@ -162,10 +160,10 @@ function create_test_cluster() { --gcp-network="${E2E_NETWORK_NAME}" --gke-environment=prod ) - if (( ! IS_PROW )); then - CLUSTER_CREATION_ARGS+=(--gcp-project=${PROJECT_ID:?"PROJECT_ID must be set to the GCP project where the tests are run."}) - else + if (( IS_BOSKOS )); then CLUSTER_CREATION_ARGS+=(--gcp-service-account=/etc/service-account/service-account.json) + else + CLUSTER_CREATION_ARGS+=(--gcp-project=${GCP_PROJECT}) fi # SSH keys are not used, but kubetest checks for their existence. # Touch them so if they don't exist, empty files are create to satisfy the check. @@ -177,15 +175,19 @@ function create_test_cluster() { # be a writeable docker repo. export K8S_USER_OVERRIDE= export K8S_CLUSTER_OVERRIDE= - # Get the current GCP project - export GCP_PROJECT=${PROJECT_ID} - [[ -z ${GCP_PROJECT} ]] && export GCP_PROJECT=$(gcloud config get-value project) # Assume test failed (see more details at the end of this script). echo -n "1"> ${TEST_RESULT_FILE} local test_cmd_args="--run-tests" (( EMIT_METRICS )) && test_cmd_args+=" --emit-metrics" + [[ -n "${GCP_PROJECT}" ]] && test_cmd_args+=" --gcp-project ${GCP_PROJECT}" + # Get the current GCP project for downloading kubernetes + local gcloud_project="${GCP_PROJECT}" + [[ -z "${gcloud_project}" ]] && gcloud_project="$(gcloud config get-value project)" + echo "gcloud project is ${gcloud_project}" + (( IS_BOSKOS )) && echo "Using boskos for the test cluster" + [[ -n "${GCP_PROJECT}" ]] && echo "GCP project for test cluster is ${GCP_PROJECT}" echo "Test script is ${E2E_SCRIPT}" - download_k8s || return 1 + download_k8s ${gcloud_project} || return 1 # Don't fail test for kubetest, as it might incorrectly report test failure # if teardown fails (for details, see success() below) set +o errexit @@ -194,29 +196,31 @@ function create_test_cluster() { --up \ --down \ --extract local \ - --gcp-node-image ${SERVING_GKE_IMAGE} \ + --gcp-node-image "${SERVING_GKE_IMAGE}" \ --test-cmd "${E2E_SCRIPT}" \ --test-cmd-args "${test_cmd_args}" echo "Test subprocess exited with code $?" # Ignore any errors below, this is a best-effort cleanup and shouldn't affect the test result. set +o errexit + # Ensure we're using the GCP project used by kubetest + gcloud_project="$(gcloud config get-value project)" # Delete target pools and health checks that might have leaked. # See https://github.com/knative/serving/issues/959 for details. # TODO(adrcunha): Remove once the leak issue is resolved. local http_health_checks="$(gcloud compute target-pools list \ - --project=${GCP_PROJECT} --format='value(healthChecks)' --filter="instances~-${E2E_CLUSTER_NAME}-" | \ + --project=${gcloud_project} --format='value(healthChecks)' --filter="instances~-${E2E_CLUSTER_NAME}-" | \ grep httpHealthChecks | tr '\n' ' ')" local target_pools="$(gcloud compute target-pools list \ - --project=${GCP_PROJECT} --format='value(name)' --filter="instances~-${E2E_CLUSTER_NAME}-" | \ + --project=${gcloud_project} --format='value(name)' --filter="instances~-${E2E_CLUSTER_NAME}-" | \ tr '\n' ' ')" if [[ -n "${target_pools}" ]]; then echo "Found leaked target pools, deleting" - gcloud compute forwarding-rules delete -q --project=${GCP_PROJECT} --region=${E2E_CLUSTER_REGION} ${target_pools} - gcloud compute target-pools delete -q --project=${GCP_PROJECT} --region=${E2E_CLUSTER_REGION} ${target_pools} + gcloud compute forwarding-rules delete -q --project=${gcloud_project} --region=${E2E_CLUSTER_REGION} ${target_pools} + gcloud compute target-pools delete -q --project=${gcloud_project} --region=${E2E_CLUSTER_REGION} ${target_pools} fi if [[ -n "${http_health_checks}" ]]; then echo "Found leaked health checks, deleting" - gcloud compute http-health-checks delete -q --project=${GCP_PROJECT} ${http_health_checks} + gcloud compute http-health-checks delete -q --project=${gcloud_project} ${http_health_checks} fi local result="$(cat ${TEST_RESULT_FILE})" echo "Test result code is $result" @@ -252,6 +256,8 @@ function setup_test_cluster() { echo "- User is ${K8S_USER_OVERRIDE}" echo "- Docker is ${DOCKER_REPO_OVERRIDE}" + export KO_DOCKER_REPO="${DOCKER_REPO_OVERRIDE}" + trap teardown_test_resources EXIT if (( USING_EXISTING_CLUSTER )) && function_exists teardown; then @@ -276,7 +282,7 @@ function success() { # TODO(adrcunha): Get rid of this workaround. echo -n "0"> ${TEST_RESULT_FILE} echo "**************************************" - echo "*** ALL TESTS PASSED ***" + echo "*** E2E TESTS PASSED ***" echo "**************************************" exit 0 } @@ -284,6 +290,7 @@ function success() { RUN_TESTS=0 EMIT_METRICS=0 USING_EXISTING_CLUSTER=1 +GCP_PROJECT="" E2E_SCRIPT="" E2E_CLUSTER_VERSION="" @@ -319,6 +326,11 @@ function initialize() { case $parameter in --run-tests) RUN_TESTS=1 ;; --emit-metrics) EMIT_METRICS=1 ;; + --gcp-project) + shift + [[ $# -ge 1 ]] || abort "missing project name after --gcp-project" + GCP_PROJECT=$1 + ;; --cluster-version) shift [[ $# -ge 1 ]] || abort "missing version after --cluster-version" @@ -326,15 +338,35 @@ function initialize() { E2E_CLUSTER_VERSION=$1 ;; *) - echo "usage: $0 [--run-tests][--emit-metrics][--cluster-version X.Y.Z]" + echo "usage: $0 [--run-tests][--emit-metrics][--cluster-version X.Y.Z][--gcp-project name]" abort "unknown option ${parameter}" ;; esac shift done + + # Use PROJECT_ID if set, unless --gcp-project was used. + if [[ -n "${PROJECT_ID:-}" && -z "${GCP_PROJECT}" ]]; then + echo "\$PROJECT_ID is set to '${PROJECT_ID}', using it to run the tests" + GCP_PROJECT="${PROJECT_ID}" + fi + if (( ! IS_PROW )) && [[ -z "${GCP_PROJECT}" ]]; then + abort "set \$PROJECT_ID or use --gcp-project to select the GCP project where the tests are run" + fi + + (( IS_PROW )) && [[ -z "${GCP_PROJECT}" ]] && IS_BOSKOS=1 + + # Safety checks + + if [[ "${DOCKER_REPO_OVERRIDE}" =~ ^gcr.io/knative-(releases|nightly)/?$ ]]; then + abort "\$DOCKER_REPO_OVERRIDE is set to ${DOCKER_REPO_OVERRIDE}, which is forbidden" + fi + readonly RUN_TESTS readonly EMIT_METRICS readonly E2E_CLUSTER_VERSION + readonly GCP_PROJECT + readonly IS_BOSKOS if (( ! RUN_TESTS )); then create_test_cluster diff --git a/vendor/github.com/knative/test-infra/scripts/library.sh b/vendor/github.com/knative/test-infra/scripts/library.sh index 6d374f07..ba267d97 100755 --- a/vendor/github.com/knative/test-infra/scripts/library.sh +++ b/vendor/github.com/knative/test-infra/scripts/library.sh @@ -22,12 +22,12 @@ readonly SERVING_GKE_VERSION=latest readonly SERVING_GKE_IMAGE=cos -# Public images and yaml files. -readonly KNATIVE_ISTIO_CRD_YAML=https://storage.googleapis.com/knative-releases/serving/latest/istio-crds.yaml -readonly KNATIVE_ISTIO_YAML=https://storage.googleapis.com/knative-releases/serving/latest/istio.yaml -readonly KNATIVE_SERVING_RELEASE=https://storage.googleapis.com/knative-releases/serving/latest/release.yaml -readonly KNATIVE_BUILD_RELEASE=https://storage.googleapis.com/knative-releases/build/latest/release.yaml -readonly KNATIVE_EVENTING_RELEASE=https://storage.googleapis.com/knative-releases/eventing/latest/release.yaml +# Public latest stable nightly images and yaml files. +readonly KNATIVE_ISTIO_CRD_YAML=https://storage.googleapis.com/knative-nightly/serving/latest/istio-crds.yaml +readonly KNATIVE_ISTIO_YAML=https://storage.googleapis.com/knative-nightly/serving/latest/istio.yaml +readonly KNATIVE_SERVING_RELEASE=https://storage.googleapis.com/knative-nightly/serving/latest/release.yaml +readonly KNATIVE_BUILD_RELEASE=https://storage.googleapis.com/knative-nightly/build/latest/release.yaml +readonly KNATIVE_EVENTING_RELEASE=https://storage.googleapis.com/knative-nightly/eventing/latest/release.yaml # Conveniently set GOPATH if unset if [[ -z "${GOPATH:-}" ]]; then @@ -47,7 +47,7 @@ readonly REPO_ROOT_DIR="$(git rev-parse --show-toplevel)" # $2 - banner message. function make_banner() { local msg="$1$1$1$1 $2 $1$1$1$1" - local border="${msg//[-0-9A-Za-z _.,]/$1}" + local border="${msg//[-0-9A-Za-z _.,\/]/$1}" echo -e "${border}\n${msg}\n${border}" } @@ -100,7 +100,10 @@ function wait_until_object_does_not_exist() { fi echo -n "Waiting until ${DESCRIPTION} does not exist" for i in {1..150}; do # timeout after 5 minutes - kubectl ${KUBECTL_ARGS} > /dev/null 2>&1 || return 0 + if kubectl ${KUBECTL_ARGS} > /dev/null 2>&1; then + echo "\n${DESCRIPTION} does not exist" + return 0 + fi echo -n "." sleep 2 done @@ -182,9 +185,8 @@ function wait_until_routable() { # Parameters: $1 - app name. # $2 - namespace (optional). function get_app_pod() { - local namespace="" - [[ -n $2 ]] && namespace="-n $2" - kubectl get pods ${namespace} --selector=app=$1 --output=jsonpath="{.items[0].metadata.name}" + local pods=($(get_app_pods $1 $2)) + echo "${pods[0]}" } # Returns the name of all pods of the given app. @@ -246,6 +248,7 @@ function report_go_test() { local report=$(mktemp) local failed=0 local test_count=0 + local tests_failed=0 ${go_test} > ${report} || failed=$? echo "Finished run, return code is ${failed}" # Tests didn't run. @@ -298,6 +301,7 @@ function report_go_test() { local src="${name}.sh" echo "exit 0" > ${src} if [[ "${field1}" == "FAIL:" ]]; then + tests_failed=$(( tests_failed + 1 )) [[ -z "${error}" ]] && read error echo "cat < ${src} echo "${error}" >> ${src} @@ -324,13 +328,13 @@ function report_go_test() { fi fi done < ${report} - echo "Done parsing ${test_count} tests" + echo "Done parsing ${test_count} tests, ${tests_failed} tests failed" # If any test failed, show the detailed report. # Otherwise, we already shown the summary. # Exception: when emitting metrics, dump the full report. if (( failed )) || [[ "$@" == *" -emitmetrics"* ]]; then if (( failed )); then - echo "At least one test failed, full log:" + echo "There were ${tests_failed} test failures, full log:" else echo "Dumping full log as metrics were requested:" fi diff --git a/vendor/github.com/knative/test-infra/scripts/presubmit-tests.sh b/vendor/github.com/knative/test-infra/scripts/presubmit-tests.sh index db78f3d0..5818fab9 100755 --- a/vendor/github.com/knative/test-infra/scripts/presubmit-tests.sh +++ b/vendor/github.com/knative/test-infra/scripts/presubmit-tests.sh @@ -20,7 +20,7 @@ source $(dirname ${BASH_SOURCE})/library.sh # Extensions or file patterns that don't require presubmit tests. -readonly NO_PRESUBMIT_FILES=(\.md \.png ^OWNERS) +readonly NO_PRESUBMIT_FILES=(\.md \.png ^OWNERS ^OWNERS_ALIASES) # Options set by command-line flags. RUN_BUILD_TESTS=0 @@ -48,6 +48,11 @@ function exit_if_presubmit_not_required() { fi } +function abort() { + echo "error: $@" + exit 1 +} + # Process flags and run tests accordingly. function main() { exit_if_presubmit_not_required @@ -63,52 +68,55 @@ function main() { kubectl version echo ">> go version" go version + echo ">> git version" + git version fi - local all_parameters=$@ - [[ -z $1 ]] && all_parameters="--all-tests" + [[ -z $1 ]] && set -- "--all-tests" + + local TEST_TO_RUN="" - for parameter in ${all_parameters}; do + while [[ $# -ne 0 ]]; do + local parameter=$1 case ${parameter} in + --build-tests) RUN_BUILD_TESTS=1 ;; + --unit-tests) RUN_UNIT_TESTS=1 ;; + --integration-tests) RUN_INTEGRATION_TESTS=1 ;; + --emit-metrics) EMIT_METRICS=1 ;; --all-tests) RUN_BUILD_TESTS=1 RUN_UNIT_TESTS=1 RUN_INTEGRATION_TESTS=1 - shift - ;; - --build-tests) - RUN_BUILD_TESTS=1 - shift - ;; - --unit-tests) - RUN_UNIT_TESTS=1 - shift - ;; - --integration-tests) - RUN_INTEGRATION_TESTS=1 - shift ;; - --emit-metrics) - EMIT_METRICS=1 + --run-test) shift + [[ $# -ge 1 ]] || abort "missing executable after --run-test" + TEST_TO_RUN=$1 ;; - *) - echo "error: unknown option ${parameter}" - exit 1 - ;; + *) abort "error: unknown option ${parameter}" ;; esac + shift done readonly RUN_BUILD_TESTS readonly RUN_UNIT_TESTS readonly RUN_INTEGRATION_TESTS readonly EMIT_METRICS + readonly TEST_TO_RUN cd ${REPO_ROOT_DIR} # Tests to be performed, in the right order if --all-tests is passed. local failed=0 + + if [[ -n "${TEST_TO_RUN}" ]]; then + if (( RUN_BUILD_TESTS || RUN_UNIT_TESTS || RUN_INTEGRATION_TESTS )); then + abort "--run-test must be used alone" + fi + ${TEST_TO_RUN} || failed=1 + fi + if (( RUN_BUILD_TESTS )); then build_tests || failed=1 fi @@ -116,21 +124,38 @@ function main() { unit_tests || failed=1 fi if (( RUN_INTEGRATION_TESTS )); then + local e2e_failed=0 + # Run pre-integration tests, if any if function_exists pre_integration_tests; then - pre_integration_tests || failed=1 + if ! pre_integration_tests; then + failed=1 + e2e_failed=1 + fi fi - if (( ! failed )); then + # Don't run integration tests if pre-integration tests failed + if (( ! e2e_failed )); then if function_exists integration_tests; then - integration_tests || failed=1 + if ! integration_tests; then + failed=1 + e2e_failed=1 + fi else local options="" (( EMIT_METRICS )) && options="--emit-metrics" - ./test/e2e-tests.sh ${options} || failed=1 + for e2e_test in ./test/e2e-*tests.sh; do + echo "Running integration test ${e2e_test}" + if ! ${e2e_test} ${options}; then + failed=1 + e2e_failed=1 + fi + done fi fi - if (( ! failed )) && function_exists post_integration_tests; then + # Don't run post-integration + if (( ! e2e_failed )) && function_exists post_integration_tests; then post_integration_tests || failed=1 fi fi + exit ${failed} } diff --git a/vendor/github.com/knative/test-infra/scripts/release.sh b/vendor/github.com/knative/test-infra/scripts/release.sh index 31e8619a..cbde3c64 100755 --- a/vendor/github.com/knative/test-infra/scripts/release.sh +++ b/vendor/github.com/knative/test-infra/scripts/release.sh @@ -110,10 +110,9 @@ function parse_flags() { fi if (( TAG_RELEASE )); then - local commit="$(git rev-parse --short HEAD)" - if [[ "$(git describe --dirty)" == *-dirty ]]; then - commit+="-dirty" - fi + # Get the commit, excluding any tags but keeping the "dirty" flag + local commit="$(git describe --always --dirty --match '^$')" + [[ -n "${commit}" ]] || abort "Error getting the current commit" # Like kubernetes, image tag is vYYYYMMDD-commit TAG="v$(date +%Y%m%d)-${commit}" fi