diff --git a/.github/workflows/knative-style.yaml b/.github/workflows/knative-style.yaml new file mode 100644 index 00000000..55bb1537 --- /dev/null +++ b/.github/workflows/knative-style.yaml @@ -0,0 +1,15 @@ +# Copyright 2020 The Knative Authors. +# SPDX-License-Identifier: Apache-2.0 + +# This file is automagically synced here from github.com/knative-extensions/knobots + +name: Code Style + +on: + pull_request: + branches: [ 'main', 'release-*' ] + +jobs: + + style: + uses: knative/actions/.github/workflows/reusable-style.yaml@main diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES index 83fbbbb2..6b7e972e 100644 --- a/OWNERS_ALIASES +++ b/OWNERS_ALIASES @@ -2,8 +2,6 @@ # Do not modify this file, instead modify peribolos/knative.yaml aliases: - api-core-wg-leads: - - dprotaso client-reviewers: - itsmurugappan client-wg-leads: @@ -17,58 +15,59 @@ aliases: - rhuss - vyasgun conformance-task-force-leads: - - omerbensaadon - salaboy conformance-writers: - - omerbensaadon - salaboy docs-reviewers: - nainaz - - omerbensaadon + - nak3 - pmbanugo + - retocode + - skonto - snneji docs-wg-leads: - - abrennan89 - snneji docs-writers: - - abrennan89 - csantanapr + - nak3 - psschwei + - retocode + - skonto - snneji eventing-reviewers: - aslom - - tayarani - - tommyreddad + - creydr eventing-triage: - - akashrv - lberk eventing-wg-leads: - pierDipi eventing-writers: - - akashrv - aliok + - creydr - lberk + - lionelvillard - matzew - odacremolbap - pierDipi func-reviewers: + - gauron99 - jrangelramos - nainaz func-writers: + - jrangelramos - lance - lkingland - matejvasek - salaboy - - zroubalik functions-wg-leads: - - lance + - lkingland - salaboy knative-admin: + - Vishal-Chdhry + - creydr - csantanapr - dprotaso - dsimansk - - evankanderson - - itsmurugappan - knative-automation - knative-prow-releaser-robot - knative-prow-robot @@ -76,143 +75,99 @@ aliases: - knative-test-reporter-robot - kvmware - lance - - lionelvillard - mchmarny - - nak3 - - pmorie + - nainaz + - pierDipi - psschwei + - puerco + - salaboy + - skonto - smoser-ibm - - thisisnotapril - upodroid - - vaikas - - zroubalik + - xtreme-sameer-vohra knative-release-leads: - - lionelvillard - - nak3 + - Vishal-Chdhry + - creydr + - dsimansk + - pierDipi + - skonto knative-robots: - knative-automation - knative-prow-releaser-robot - knative-prow-robot - knative-prow-updater-robot - knative-test-reporter-robot - networking-reviewers: - - JRBANCEL - - ZhiminXiang - - andrew-su - - arturenault - - carlisia - - nak3 - - shashwathi - - tcnghia - - vagababov - - yanweiguo - networking-wg-leads: [] - networking-writers: - - JRBANCEL - - vagababov operations-reviewers: - - Cynocracy - aliok - houshengbo - - jcrossley3 - matzew - maximilien - - trshafer operations-wg-leads: - houshengbo operations-writers: - - Cynocracy - aliok - houshengbo - - jcrossley3 - matzew - maximilien - - trshafer - pkg-configmap-reviewers: - - dprotaso - - mattmoor - - vagababov - pkg-configmap-writers: - - dprotaso - - mattmoor - - vagababov - pkg-controller-reviewers: - - dprotaso - - mattmoor - - tcnghia - - vagababov - - whaught - pkg-controller-writers: - - dprotaso - - mattmoor - - tcnghia - - vagababov productivity-leads: - kvmware - upodroid productivity-reviewers: - - albertomilan - evankanderson - mgencur - - shinigambit productivity-wg-leads: - kvmware - upodroid productivity-writers: - cardil - - chaodaiG - - coryrc - kvmware - psschwei - upodroid security-wg-leads: + - davidhadas - evankanderson - - julz security-writers: + - davidhadas - evankanderson - - julz - serving-observability-reviewers: + serving-approvers: + - nak3 + - psschwei - skonto - - yanweiguo - serving-observability-writers: - - yanweiguo serving-reviewers: - - carlisia - - julz - - nader-ziada - - nealhu - - psschwei + - KauzClay + - jsanin-vmw + - kauana + - kvmware + - retocode + - skonto + - xtreme-vikram-yadav + serving-triage: + - KauzClay + - retocode - skonto - - whaught serving-wg-leads: - dprotaso - - psschwei serving-writers: - dprotaso - - julz + - nak3 - psschwei - - tcnghia - - vagababov + - skonto steering-committee: - csantanapr - - itsmurugappan - lance - - pmorie - - thisisnotapril - - vaikas + - nainaz + - puerco + - salaboy technical-oversight-committee: - dprotaso - dsimansk - - evankanderson + - kvmware - psschwei - - zroubalik trademark-committee: - - evankanderson - mchmarny - smoser-ibm + - xtreme-sameer-vohra ux-wg-leads: - - abrennan89 - snneji ux-writers: - - abrennan89 - snneji diff --git a/README.md b/README.md index 607bc897..5dc34c8e 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ main "$@" This is a helper script for Knative E2E test scripts. To use it: 1. [optional] Customize the test cluster. Pass the flags as described - [here](../tools/kntest/pkg/kubetest2/gke/README.md) to the `initialize` function + [here](https://github.com/knative/toolbox/blob/main/kntest/pkg/kubetest2/gke/README.md) to the `initialize` function call if the default values don't fit your needs. 1. Source the script. @@ -123,6 +123,10 @@ This is a helper script for Knative E2E test scripts. To use it: when a test fails, and can dump extra information about the current state of the cluster (typically using `kubectl`). +1. [optional] Write the `on_success` function. It will be called when a test succeeds + +1. [optional] Write the `on_failure` function. It will be called when a test fails + 1. [optional] Write the `parse_flags()` function. It will be called whenever an unrecognized flag is passed to the script, allowing you to define your own flags. The function must return 0 if the flag is unrecognized, or the number diff --git a/e2e-tests.sh b/e2e-tests.sh index cb186a4e..331511cc 100755 --- a/e2e-tests.sh +++ b/e2e-tests.sh @@ -19,15 +19,8 @@ source "$(dirname "${BASH_SOURCE[0]:-$0}")/infra-library.sh" -readonly TEST_RESULT_FILE=/tmp/${REPO_NAME}-e2e-result - -# Flag whether test is using a boskos GCP project -IS_BOSKOS=0 - # Tear down the test resources. function teardown_test_resources() { - # On boskos, save time and don't teardown as the cluster will be destroyed anyway. - (( IS_BOSKOS )) && return header "Tearing down test environment" if function_exists test_teardown; then test_teardown @@ -89,10 +82,9 @@ function setup_test_cluster() { kubectl config set-context "${k8s_cluster}" --namespace=default echo "- Cluster is ${k8s_cluster}" - echo "- Docker is ${KO_DOCKER_REPO}" + echo "- KO_DOCKER_REPO is ${KO_DOCKER_REPO}" - # Do not run teardowns if we explicitly want to skip them. - (( ! SKIP_TEARDOWNS )) && add_trap teardown_test_resources EXIT + (( TEARDOWN )) && add_trap teardown_test_resources EXIT # Handle failures ourselves, so we can dump useful info. set +o errexit @@ -111,7 +103,7 @@ function success() { echo "**************************************" echo "*** E2E TESTS PASSED ***" echo "**************************************" - dump_metrics + function_exists on_success && on_success exit 0 } @@ -122,18 +114,24 @@ function fail_test() { if [[ "X${message:-}X" == "XX" ]]; then message='test failed' fi - add_trap "dump_cluster_state;dump_metrics" EXIT + function_exists on_failure && on_failure + (( ! SKIP_DUMP_ON_FAILURE )) && dump_cluster_state abort "${message}" } -SKIP_TEARDOWNS=0 +# Since create_test_cluster invokes the test script +# recursively we don't want to override these on the second +# invocation +TEARDOWN=${TEARDOWN:-0} +CLOUD_PROVIDER=${CLOUD_PROVIDER:-"gke"} +SKIP_DUMP_ON_FAILURE=${SKIP_DUMP_ON_FAILURE:-0} E2E_SCRIPT="" -CLOUD_PROVIDER="gke" # Parse flags and initialize the test cluster. function initialize() { local run_tests=0 local custom_flags=() + local extra_gcloud_flags=() local parse_script_flags=0 E2E_SCRIPT="$(get_canonical_path "$0")" local e2e_script_command=( "${E2E_SCRIPT}" "--run-tests" ) @@ -153,7 +151,7 @@ function initialize() { # Skip parsed flag (and possibly argument) and continue # Also save it to it's passed through to the test script for ((i=1;i<=skip;i++)); do - # Avoid double-parsing + # Avoid double-parsing if (( parse_script_flags )); then e2e_script_command+=("$1") fi @@ -165,9 +163,10 @@ function initialize() { # Try parsing flag as a standard one. case ${parameter} in --run-tests) run_tests=1 ;; - --skip-teardowns) SKIP_TEARDOWNS=1 ;; - --skip-istio-addon) echo "--skip-istio-addon is no longer supported" - ;; # This flag is a noop + --teardown) TEARDOWN=1 ;; + --skip-teardowns) echo "--skip-teardowns is no longer supported - opt in with --teardown" ;; + --skip-dump-on-failure) SKIP_DUMP_ON_FAILURE=1 ;; + --skip-istio-addon) echo "--skip-istio-addon is no longer supported" ;; *) case ${parameter} in --cloud-provider) shift; CLOUD_PROVIDER="$1" ;; @@ -177,17 +176,12 @@ function initialize() { shift done - (( IS_PROW )) && [[ -z "${GCP_PROJECT_ID:-}" ]] && IS_BOSKOS=1 - - if [[ "${CLOUD_PROVIDER}" == "gke" ]]; then - custom_flags+=("--addons=NodeLocalDNS") - fi - - readonly IS_BOSKOS - readonly SKIP_TEARDOWNS + readonly SKIP_DUMP_ON_FAILURE + readonly TEARDOWN + readonly CLOUD_PROVIDER if (( ! run_tests )); then - create_test_cluster "${CLOUD_PROVIDER}" custom_flags e2e_script_command + create_test_cluster "${CLOUD_PROVIDER}" custom_flags extra_gcloud_flags e2e_script_command else setup_test_cluster fi diff --git a/infra-library.sh b/infra-library.sh index 662adfec..4782d09a 100644 --- a/infra-library.sh +++ b/infra-library.sh @@ -91,7 +91,7 @@ function create_test_cluster() { fi case "$1" in - gke) create_gke_test_cluster "$2" "$3" "${4:-}" ;; + gke) create_gke_test_cluster "$2" "$3" "$4" "${5:-}" ;; kind) create_kind_test_cluster "$2" "$3" "${4:-}" ;; *) echo "unsupported provider: $1"; exit 1 ;; esac @@ -117,23 +117,50 @@ function create_kind_test_cluster() { } # Create a GKE test cluster with kubetest2 and run the test command. -# Parameters: $1 - custom flags defined in kntest -# $2 - test command to run after the cluster is created (optional) +# Parameters: $1 - custom flags defined in kubetest2 +# $2 - custom flags to pass directly to gcloud +# $3 - test command to run after the cluster is created (optional) function create_gke_test_cluster() { local -n _custom_flags=$1 - local -n _test_command=$2 + local -n _extra_gcloud_flags=$2 + local -n _test_command=$3 # We are disabling logs and metrics on Boskos Clusters by default as they are not used. Manually set ENABLE_GKE_TELEMETRY to true to enable telemetry # and ENABLE_PREEMPTIBLE_NODES to true to create preemptible/spot VMs. VM Preemption is a rare event and shouldn't be distruptive given the fault tolerant nature of our tests. - local extra_gcloud_flags="" if [[ "${ENABLE_GKE_TELEMETRY:-}" != "true" ]]; then - extra_gcloud_flags="${extra_gcloud_flags} --logging=NONE --monitoring=NONE" + _extra_gcloud_flags+=("--logging=NONE --monitoring=NONE") + fi + + if [[ "${CLOUD_PROVIDER}" == "gke" ]]; then + extra_gcloud_flags+=("--addons=NodeLocalDNS") fi if [[ "${ENABLE_PREEMPTIBLE_NODES:-}" == "true" ]]; then - extra_gcloud_flags="${extra_gcloud_flags} --preemptible" + _extra_gcloud_flags+=("--preemptible") + fi + + _extra_gcloud_flags+=("--quiet") + if ! command -v kubetest2 >/dev/null; then + tmpbin="$(mktemp -d)" + echo "kubetest2 not found, installing in temp path: ${tmpbin}" + GOBIN="$tmpbin" go install sigs.k8s.io/kubetest2/...@latest + export PATH="${tmpbin}:${PATH}" + fi + if [[ ! " ${_custom_flags[*]} " =~ "--machine-type=" ]]; then + _custom_flags+=("--machine-type=e2-standard-4") fi - run_kntest kubetest2 gke "${_custom_flags[@]}" \ - --test-command="${_test_command[*]}" \ - --extra-gcloud-flags="${extra_gcloud_flags}" + kubetest2 gke "${_custom_flags[@]}" \ + --rundir-in-artifacts \ + --up \ + --down \ + --boskos-heartbeat-interval-seconds=20 \ + --v=1 \ + --network=e2e-network \ + --boskos-acquire-timeout-seconds=1200 \ + --region="${E2E_CLUSTER_REGION},us-east1,us-west1" \ + --gcloud-extra-flags="${_extra_gcloud_flags[*]}" \ + --retryable-error-patterns='.*does not have enough resources available to fulfill.*,.*only \\d+ nodes out of \\d+ have registered; this is likely due to Nodes failing to start correctly.*,.*All cluster resources were brought up.+ but: component .+ from endpoint .+ is unhealthy.*' \ + --test=exec \ + -- \ + "${_test_command[@]}" } diff --git a/library.sh b/library.sh index faac80df..5eab6a8d 100755 --- a/library.sh +++ b/library.sh @@ -46,7 +46,7 @@ readonly REPO_ROOT_DIR function __resolveRepoName() { local repoName repoName="$(basename "${1:-$(git rev-parse --show-toplevel)}")" - repoName="${repoName#knative-sandbox-}" # Remove knative-sandbox- prefix if any + repoName="${repoName#knative-extensions-}" # Remove knative-extensions- prefix if any repoName="${repoName#knative-}" # Remove knative- prefix if any echo "${repoName}" } @@ -586,17 +586,6 @@ function start_knative_eventing_extension() { wait_until_pods_running "$2" || return 1 } -# Install the stable release of eventing extension sugar controller in the current cluster. -# Parameters: $1 - Knative Eventing release version, e.g. 0.16.0 -function start_release_eventing_sugar_controller() { - start_knative_eventing_extension "https://storage.googleapis.com/knative-releases/eventing/previous/v$1/eventing-sugar-controller.yaml" "knative-eventing" -} - -# Install the sugar cotroller eventing extension -function start_latest_eventing_sugar_controller() { - start_knative_eventing_extension "${KNATIVE_EVENTING_SUGAR_CONTROLLER_RELEASE}" "knative-eventing" -} - # Run a go utility without installing it. # Parameters: $1 - tool package for go run. # $2..$n - parameters passed to the tool. @@ -647,7 +636,7 @@ function add_trap { local current_trap current_trap="$(trap -p "$trap_signal" | cut -d\' -f2)" local new_cmd="($cmd)" - [[ -n "${current_trap}" ]] && new_cmd="${current_trap};${new_cmd}" + [[ -n "${current_trap}" ]] && new_cmd="${new_cmd};${current_trap}" trap -- "${new_cmd}" "$trap_signal" done } @@ -668,7 +657,7 @@ function foreach_go_module() { echo "Command '${cmd}' failed in module $gomod_dir: $failed" >&2 return $failed fi - done < <(go_run knative.dev/test-infra/tools/modscope@latest ls -p) + done < <(go_run knative.dev/toolbox/modscope@latest ls -p) } # Update go deps. @@ -720,7 +709,7 @@ function __go_update_deps_for_module() { else group "Upgrading to release ${RELEASE}" fi - FLOATING_DEPS+=( $(go_run knative.dev/test-infra/buoy@latest float ./go.mod "${buoyArgs[@]}") ) + FLOATING_DEPS+=( $(go_run knative.dev/toolbox/buoy@latest float ./go.mod "${buoyArgs[@]}") ) if [[ ${#FLOATING_DEPS[@]} > 0 ]]; then echo "Floating deps to ${FLOATING_DEPS[@]}" go get -d ${FLOATING_DEPS[@]} @@ -765,7 +754,7 @@ function __go_update_deps_for_module() { # Intended to be used like: # export MODULE_NAME=$(go_mod_module_name) function go_mod_module_name() { - go_run knative.dev/test-infra/tools/modscope@latest current + go_run knative.dev/toolbox/modscope@latest current } # Return a GOPATH to a temp directory. Works around the out-of-GOPATH issues @@ -1018,4 +1007,3 @@ readonly KNATIVE_SERVING_RELEASE_CRDS="$(get_latest_knative_yaml_source "serving readonly KNATIVE_SERVING_RELEASE_CORE="$(get_latest_knative_yaml_source "serving" "serving-core")" readonly KNATIVE_NET_ISTIO_RELEASE="$(get_latest_knative_yaml_source "net-istio" "net-istio")" readonly KNATIVE_EVENTING_RELEASE="$(get_latest_knative_yaml_source "eventing" "eventing")" -readonly KNATIVE_EVENTING_SUGAR_CONTROLLER_RELEASE="$(get_latest_knative_yaml_source "eventing" "eventing-sugar-controller")" diff --git a/performance-tests.sh b/performance-tests.sh index 440668de..23e17e5b 100755 --- a/performance-tests.sh +++ b/performance-tests.sh @@ -17,7 +17,7 @@ # This is a helper script for Knative performance test scripts. # See README.md for instructions on how to use it. -source $(dirname "${BASH_SOURCE[0]}")/library.sh +source "$(dirname "${BASH_SOURCE[0]}")"/library.sh # Configurable parameters. # If not provided, they will fall back to the default values. @@ -76,7 +76,8 @@ EOF update_knative || abort "failed to update knative" fi # get benchmark name from the cluster name - local benchmark_name=$(get_benchmark_name "$1") + local benchmark_name + benchmark_name=$(get_benchmark_name "$1") if function_exists update_benchmark; then update_benchmark "${benchmark_name}" || abort "failed to update benchmark" fi @@ -92,13 +93,16 @@ function get_benchmark_name() { # Update the clusters related to the current repo. function update_clusters() { header "Updating all clusters for ${REPO_NAME}" - local all_clusters=$(gcloud container clusters list --project="${PROJECT_NAME}" --format="csv[no-heading](name,zone)") + local all_clusters + all_clusters=$(gcloud container clusters list --project="${PROJECT_NAME}" --format="csv[no-heading](name,zone)") echo ">> Project contains clusters:" "${all_clusters}" for cluster in ${all_clusters}; do - local name=$(echo "${cluster}" | cut -f1 -d",") + local name + name=$(echo "${cluster}" | cut -f1 -d",") # the cluster name is prefixed with "${REPO_NAME}--", here we should only handle clusters belonged to the current repo [[ ! ${name} =~ ^${REPO_NAME}-- ]] && continue - local zone=$(echo "${cluster}" | cut -f2 -d",") + local zone + zone=$(echo "${cluster}" | cut -f2 -d",") # Update all resources installed on the cluster update_cluster "${name}" "${zone}" @@ -109,7 +113,7 @@ function update_clusters() { # Run the perf-tests tool # Parameters: $1..$n - parameters passed to the tool function run_perf_cluster_tool() { - perf-tests $@ + perf-tests "$@" } # Delete the old clusters belonged to the current repo, and recreate them with the same configuration. diff --git a/presubmit-tests.sh b/presubmit-tests.sh index fd2a2c06..d210dc70 100755 --- a/presubmit-tests.sh +++ b/presubmit-tests.sh @@ -17,7 +17,7 @@ # This is a helper script for Knative presubmit test scripts. # See README.md for instructions on how to use it. -source $(dirname "${BASH_SOURCE[0]}")/library.sh +source "$(dirname "${BASH_SOURCE[0]}")"/library.sh # Custom configuration of presubmit tests readonly PRESUBMIT_TEST_FAIL_FAST=${PRESUBMIT_TEST_FAIL_FAST:-0} @@ -139,7 +139,7 @@ function __build_test_runner_for_module() { # Don't merge these two lines, or return code will always be 0. # Get all build tags in go code (ignore /vendor, /hack and /third_party) local tags - tags="$(go run knative.dev/test-infra/tools/go-ls-tags@latest --joiner=,)" + tags="$(go run knative.dev/toolbox/go-ls-tags@latest --joiner=,)" local go_pkg_dirs go_pkg_dirs="$(go list -tags "${tags}" ./...)" || return $? if [[ -z "${go_pkg_dirs}" ]]; then @@ -289,6 +289,10 @@ function main() { echo ">> maven version" mvn --version fi + if command -v cosign > /dev/null; then + echo ">> cosign version" + cosign version + fi echo ">> prow-tests image version" [[ -f /commit_hash ]] && echo "Prow test image was built from $(cat /commit_hash) commit which is viewable at https://github.com/knative/test-infra/tree/$(cat /commit_hash) " || echo "unknown" fi diff --git a/release.sh b/release.sh index edce2006..5d4f09a8 100755 --- a/release.sh +++ b/release.sh @@ -51,6 +51,7 @@ function tag_images_in_yamls() { local DOCKER_BASE="${KO_DOCKER_REPO}/${REPO_ROOT_DIR/$SRC_DIR}" local GEO_REGIONS="${GEO_REPLICATION[@]} " echo "Tagging any images under '${DOCKER_BASE}' with ${TAG}" + # shellcheck disable=SC2068 for file in $@; do [[ "${file##*.}" != "yaml" ]] && continue echo "Inspecting ${file}" @@ -98,7 +99,7 @@ RELEASE_NOTES="" RELEASE_BRANCH="" RELEASE_GCS_BUCKET="knative-nightly/${REPO_NAME}" RELEASE_DIR="" -KO_FLAGS="-P --platform=all --image-refs=imagerefs.txt" +KO_FLAGS="-P --platform=all" VALIDATION_TESTS="./test/presubmit-tests.sh" ARTIFACTS_TO_PUBLISH="" FROM_NIGHTLY_RELEASE="" @@ -111,6 +112,7 @@ export KO_DOCKER_REPO="gcr.io/knative-nightly" # Build stripped binary to reduce size export GOFLAGS="-ldflags=-s -ldflags=-w" export GITHUB_TOKEN="" +readonly IMAGES_REFS_FILE="${IMAGES_REFS_FILE:-$(mktemp -d)/images_refs.txt}" # Convenience function to run the hub tool. # Parameters: $1..$n - arguments to hub. @@ -312,27 +314,91 @@ function build_from_source() { sign_release || abort "error signing the release" } +function get_images_in_yamls() { + rm -rf "$IMAGES_REFS_FILE" + echo "Assembling a list of image refences to sign" + # shellcheck disable=SC2068 + for file in $@; do + [[ "${file##*.}" != "yaml" ]] && continue + echo "Inspecting ${file}" + while read -r image; do + echo "$image" >> "$IMAGES_REFS_FILE" + done < <(grep -oh "\S*${KO_DOCKER_REPO}\S*" "${file}") + done + if [[ -f "$IMAGES_REFS_FILE" ]]; then + sort -uo "$IMAGES_REFS_FILE" "$IMAGES_REFS_FILE" # Remove duplicate entries + fi +} + +# Finds a checksums file within the given list of artifacts (space delimited) +# Parameters: $n - artifact files +function find_checksums_file() { + for arg in "$@"; do + # kinda dirty hack needed as we pass $ARTIFACTS_TO_PUBLISH in space + # delimiter variable, which is vulnerable to all sorts of argument quoting + while read -r file; do + if [[ "${file}" == *"checksums.txt" ]]; then + echo "${file}" + return 0 + fi + done < <(echo "$arg" | tr ' ' '\n') + done + warning "cannot find checksums file" +} + # Build a release from source. function sign_release() { if (( ! IS_PROW )); then # This function can't be run by devs on their laptops return 0 fi + get_images_in_yamls "${ARTIFACTS_TO_PUBLISH}" + local checksums_file + checksums_file="$(find_checksums_file "${ARTIFACTS_TO_PUBLISH}")" + + if ! [[ -f "${checksums_file}" ]]; then + echo '>> No checksums file found, generating one' + checksums_file="$(mktemp -d)/checksums.txt" + for file in ${ARTIFACTS_TO_PUBLISH}; do + pushd "$(dirname "$file")" >/dev/null + sha256sum "$(basename "$file")" >> "${checksums_file}" + popd >/dev/null + done + ARTIFACTS_TO_PUBLISH="${ARTIFACTS_TO_PUBLISH} ${checksums_file}" + fi # Notarizing mac binaries needs to be done before cosign as it changes the checksum values # of the darwin binaries if [ -n "${APPLE_CODESIGN_KEY}" ] && [ -n "${APPLE_CODESIGN_PASSWORD_FILE}" ] && [ -n "${APPLE_NOTARY_API_KEY}" ]; then banner "Notarizing macOS Binaries for the release" - FILES=$(find -- * -type f -name "*darwin*") - for file in $FILES; do - rcodesign sign "${file}" --p12-file="${APPLE_CODESIGN_KEY}" \ - --code-signature-flags=runtime \ - --p12-password-file="${APPLE_CODESIGN_PASSWORD_FILE}" - done - zip files.zip ${FILES} - rcodesign notary-submit files.zip --api-key-path="${APPLE_NOTARY_API_KEY}" --wait - sha256sum ${ARTIFACTS_TO_PUBLISH//checksums.txt/} > checksums.txt - echo "🧮 Post Notarization Checksum:" - cat checksums.txt + local macos_artifacts + declare -a macos_artifacts=() + while read -r file; do + if echo "$file" | grep -q "darwin"; then + macos_artifacts+=("${file}") + rcodesign sign "${file}" --p12-file="${APPLE_CODESIGN_KEY}" \ + --code-signature-flags=runtime \ + --p12-password-file="${APPLE_CODESIGN_PASSWORD_FILE}" + fi + done < <(echo "${ARTIFACTS_TO_PUBLISH}" | tr ' ' '\n') + if [[ -z "${macos_artifacts[*]}" ]]; then + warning "No macOS binaries found, skipping notarization" + else + local zip_file + zip_file="$(mktemp -d)/files.zip" + zip "$zip_file" -@ < <(printf "%s\n" "${macos_artifacts[@]}") + rcodesign notary-submit "$zip_file" --api-key-path="${APPLE_NOTARY_API_KEY}" --wait + true > "${checksums_file}" # Clear the checksums file + for file in ${ARTIFACTS_TO_PUBLISH}; do + if echo "$file" | grep -q "checksums.txt"; then + continue # Don't checksum the checksums file + fi + pushd "$(dirname "$file")" >/dev/null + sha256sum "$(basename "$file")" >> "${checksums_file}" + popd >/dev/null + done + echo "🧮 Post Notarization Checksum:" + cat "$checksums_file" + fi fi ID_TOKEN=$(gcloud auth print-identity-token --audiences=sigstore \ @@ -340,22 +406,26 @@ function sign_release() { --impersonate-service-account="${SIGNING_IDENTITY}") echo "Signing Images with the identity ${SIGNING_IDENTITY}" ## Sign the images with cosign - if [[ -f "imagerefs.txt" ]]; then - COSIGN_EXPERIMENTAL=1 cosign sign $(cat imagerefs.txt) --recursive --identity-token="${ID_TOKEN}" - if [ -n "${ATTEST_IMAGES:-}" ]; then # Temporary Feature Gate - provenance-generator --clone-log=/logs/clone.json \ - --image-refs=imagerefs.txt --output=attestation.json - COSIGN_EXPERIMENTAL=1 cosign attest $(cat imagerefs.txt) --recursive --identity-token="${ID_TOKEN}" \ - --predicate=attestation.json --type=slsaprovenance - fi + if [[ -f "$IMAGES_REFS_FILE" ]]; then + COSIGN_EXPERIMENTAL=1 cosign sign $(cat "$IMAGES_REFS_FILE") \ + --recursive --identity-token="${ID_TOKEN}" + cp "${IMAGES_REFS_FILE}" "${ARTIFACTS}" + if [ -n "${ATTEST_IMAGES:-}" ]; then # Temporary Feature Gate + provenance-generator --clone-log=/logs/clone.json \ + --image-refs="$IMAGES_REFS_FILE" --output=attestation.json + mkdir -p "${ARTIFACTS}" && cp attestation.json "${ARTIFACTS}" + COSIGN_EXPERIMENTAL=1 cosign attest $(cat "$IMAGES_REFS_FILE") \ + --recursive --identity-token="${ID_TOKEN}" \ + --predicate=attestation.json --type=slsaprovenance + fi fi - ## Check if there is checksums.txt file. If so, sign the checksum file - if [[ -f "checksums.txt" ]]; then - echo "Signing Images with the identity ${SIGNING_IDENTITY}" - COSIGN_EXPERIMENTAL=1 cosign sign-blob checksums.txt --output-signature=checksums.txt.sig --output-certificate=checksums.txt.pem --identity-token="${ID_TOKEN}" - ARTIFACTS_TO_PUBLISH="${ARTIFACTS_TO_PUBLISH} checksums.txt.sig checksums.txt.pem" - fi + echo "Signing checksums with the identity ${SIGNING_IDENTITY}" + COSIGN_EXPERIMENTAL=1 cosign sign-blob "$checksums_file" \ + --output-signature="${checksums_file}.sig" \ + --output-certificate="${checksums_file}.pem" \ + --identity-token="${ID_TOKEN}" + ARTIFACTS_TO_PUBLISH="${ARTIFACTS_TO_PUBLISH} ${checksums_file}.sig ${checksums_file}.pem" } # Copy tagged images from the nightly GCR to the release GCR, tagging them 'latest'. @@ -663,7 +733,7 @@ function main() { # Parameters: $1..$n - files to add to the release. function publish_to_github() { (( PUBLISH_TO_GITHUB )) || return 0 - local title="${REPO_NAME_FORMATTED} release ${TAG}" + local title="${TAG}" local attachments=() local description="$(mktemp)" local attachments_dir="$(mktemp -d)" diff --git a/shell/executor.go b/shell/executor.go index e6308a07..059631dd 100644 --- a/shell/executor.go +++ b/shell/executor.go @@ -19,7 +19,6 @@ package shell import ( "errors" "fmt" - "io/ioutil" "os" "os/exec" "strings" @@ -134,7 +133,7 @@ func defaultPrefixFunc(st StreamType, label string, cfg ExecutorConfig) string { } func withTempScript(contents string, fn func(bin string) error) error { - tmpfile, err := ioutil.TempFile("", "shellout-*.sh") + tmpfile, err := os.CreateTemp("", "shellout-*.sh") if err != nil { return err } diff --git a/shell/project_test.go b/shell/project_test.go index 719f511d..c9533fdb 100644 --- a/shell/project_test.go +++ b/shell/project_test.go @@ -17,7 +17,7 @@ limitations under the License. package shell_test import ( - "io/ioutil" + "os" "path" "testing" @@ -29,7 +29,7 @@ func TestNewProjectLocation(t *testing.T) { loc, err := shell.NewProjectLocation("..") assert.NoError(err) goModPath := path.Join(loc.RootPath(), "go.mod") - bytes, err := ioutil.ReadFile(goModPath) + bytes, err := os.ReadFile(goModPath) assert.NoError(err) assert.Contains(string(bytes), "module knative.dev/hack") } diff --git a/test/e2e-kind.sh b/test/e2e-kind.sh index f5d0be4c..1aab1a0e 100755 --- a/test/e2e-kind.sh +++ b/test/e2e-kind.sh @@ -21,7 +21,49 @@ pushd "$(dirname "${BASH_SOURCE[0]:-$0}")/.." > /dev/null source "$(go run ./cmd/script e2e-tests.sh)" popd > /dev/null +export INGRESS_CLASS=${INGRESS_CLASS:-istio.ingress.networking.knative.dev} + +function is_ingress_class() { + [[ "${INGRESS_CLASS}" == *"${1}"* ]] +} + +# Copied from https://github.com/knative/client/blob/main/test/common.sh#L32 +function install_istio() { + if [[ -z "${ISTIO_VERSION:-}" ]]; then + readonly ISTIO_VERSION="latest" + fi + + header "Installing Istio ${ISTIO_VERSION}" + local LATEST_NET_ISTIO_RELEASE_VERSION=$(curl -L --silent "https://api.github.com/repos/knative/net-istio/releases" | \ + jq -r '[.[].tag_name] | sort_by( sub("knative-";"") | sub("v";"") | split(".") | map(tonumber) ) | reverse[0]') + # And checkout the setup script based on that release + local NET_ISTIO_DIR=$(mktemp -d) + ( + cd $NET_ISTIO_DIR \ + && git init \ + && git remote add origin https://github.com/knative-extensions/net-istio.git \ + && git fetch --depth 1 origin $LATEST_NET_ISTIO_RELEASE_VERSION \ + && git checkout FETCH_HEAD + ) + + if [[ -z "${ISTIO_PROFILE:-}" ]]; then + readonly ISTIO_PROFILE="istio-ci-no-mesh.yaml" + fi + + if [[ -n "${CLUSTER_DOMAIN:-}" ]]; then + sed -ie "s/cluster\.local/${CLUSTER_DOMAIN}/g" ${NET_ISTIO_DIR}/third_party/istio-${ISTIO_VERSION}/${ISTIO_PROFILE} + fi + + echo ">> Installing Istio" + echo "Istio version: ${ISTIO_VERSION}" + echo "Istio profile: ${ISTIO_PROFILE}" + ${NET_ISTIO_DIR}/third_party/istio-${ISTIO_VERSION}/install-istio.sh ${ISTIO_PROFILE} +} + function knative_setup() { + if is_ingress_class istio; then + install_istio + fi start_latest_knative_serving } diff --git a/test/e2e-tests.sh b/test/e2e-tests.sh index f643172f..c4ccbfb2 100755 --- a/test/e2e-tests.sh +++ b/test/e2e-tests.sh @@ -45,9 +45,9 @@ function dump_metrics() { } # Script entry point. -initialize "$@" --max-nodes=1 --machine=e2-standard-2 \ +initialize "$@" --num-nodes=1 --machine-type=e2-standard-4 \ --enable-workload-identity --cluster-version=latest \ - --extra-gcloud-flags "--enable-stackdriver-kubernetes --no-enable-ip-alias --no-enable-autoupgrade" + --gcloud-extra-flags "--logging=NONE --monitoring=NONE" [[ ${KNATIVE_SETUP_DONE:-0} == 1 ]] || fail_test 'Knative setup not persisted' [[ ${TEST_SETUP_DONE:-0} == 1 ]] || fail_test 'Test setup not persisted' diff --git a/test/unit/e2e_helpers_test.go b/test/unit/e2e_helpers_test.go index 049d713d..e6fa1146 100644 --- a/test/unit/e2e_helpers_test.go +++ b/test/unit/e2e_helpers_test.go @@ -27,8 +27,6 @@ func TestE2eHelpers(t *testing.T) { retcode: retcode(111), stdout: []check{ contains(">> DUMPING THE CLUSTER STATE"), - contains(">> STARTING KUBE PROXY"), - contains(">> GRABBING K8S METRICS"), }, }} for _, tc := range tcs { diff --git a/test/unit/presubmit_test.go b/test/unit/presubmit_test.go index f69c6aeb..5e4d4ac9 100644 --- a/test/unit/presubmit_test.go +++ b/test/unit/presubmit_test.go @@ -2,7 +2,6 @@ package unit_test import ( "fmt" - "path" "strings" "testing" @@ -11,7 +10,6 @@ import ( func TestMainFunc(t *testing.T) { t.Parallel() - rootDir := path.Dir(path.Dir(currentDir())) sc := newShellScript( fakeProwJob(), loadFile("source-presubmit-tests.bash"), @@ -44,23 +42,8 @@ func TestMainFunc(t *testing.T) { contains("-- -short -race -count 1 ./..."), contains("UNIT TESTS PASSED"), }, - }, { - name: `main --integration-tests`, - stdout: []check{ - contains("RUNNING INTEGRATION TESTS"), - contains("Running integration test test/e2e-tests.sh"), - contains(fmt.Sprintf("go run knative.dev/test-infra/tools/kntest/cmd/kntest@latest"+ - " kubetest2 gke --max-nodes=1 --machine=e2-standard-2 "+ - "--enable-workload-identity --cluster-version=latest "+ - "--extra-gcloud-flags --enable-stackdriver-kubernetes "+ - "--no-enable-ip-alias --no-enable-autoupgrade "+ - "--addons=NodeLocalDNS "+ - "--test-command=%s/test/e2e-tests.sh "+ - "--run-tests --extra-gcloud-flags= --logging=NONE "+ - "--monitoring=NONE", rootDir)), - contains("INTEGRATION TESTS PASSED"), - }, - }} + }, + } for _, tc := range tcs { tc := tc t.Run(tc.name, tc.test(sc)) diff --git a/test/unit/release_test.go b/test/unit/release_test.go index bce8d6ed..bf420699 100644 --- a/test/unit/release_test.go +++ b/test/unit/release_test.go @@ -2,13 +2,111 @@ package unit_test import ( "fmt" + "io/ioutil" "os" + "path" "testing" "github.com/stretchr/testify/require" "github.com/thanhpk/randstr" ) +var CantFindChecksums = warned("cannot find checksums file") + +func TestBuildFromSource(t *testing.T) { + t.Parallel() + + outChecks := []check{ + contains("Signing Images with the identity signer@knative-releases.test"), + contains("Signing checksums with the identity signer@knative-releases.test"), + contains("Notarizing macOS Binaries for the release"), + } + checksumsContent := `🧮 Post Notarization Checksum: +4d410c6611b89b21215e06046dc8104aa668c8e93a5b73062e45bd43c6c422cc foo-linux-amd64 +6fedd2d0b79cbd3faf11f159f6b229707e191a5bcc5f727fd33b916d517c8ed4 foo-linux-arm64 +58eaa00b44cb836d09f009791bdb2c521afc18f7a2dac80422a6204774d6a677 foo-linux-ppc64le +7b33c5e58372290a7addc5e9b95a1fef33bb1ce38660dd4fdc65b9862e466a59 foo-linux-s390x +9ee0670b6715542ef64a336ae68342fde32d3045273dcfe67d97c22f72f4c039 foo-darwin-amd64 +74da512cfed7a90713a7161f34a2339fe2e9c9cec8bd3cb30566c464bf2c18f1 foo-darwin-arm64 +73517e997b68696b1a6be4957519b800e26c9bc44c1b7f46fe90be0834d1af07 foo-windows-amd64.exe +9ac630646ca5b77fbf716f9a780d33f26357bbd8b242c14e0863cdde72aacbf0 foo.yaml +` + tcs := []testCase{{ + name: "build_from_source", + retcode: retcode(0), + stderr: CantFindChecksums, + stdout: outChecks, + }, { + name: "build_from_source (with_checksums)", + commands: []string{ + `export CALCULATE_CHECKSUMS=1`, + `build_from_source`, + }, + stdout: append(outChecks, contains(checksumsContent)), + }} + for _, tc := range tcs { + tc := tc + t.Run(tc.name, func(t *testing.T) { + tmp := t.TempDir() + sc := testReleaseShellScript( + envs(map[string]string{ + "BUILD_DIR": tmp, + "APPLE_CODESIGN_KEY": randomFile(t, tmp, "codesign.key"), + "APPLE_CODESIGN_PASSWORD_FILE": randomFile(t, tmp, "codesign.pass"), + "APPLE_NOTARY_API_KEY": randomFile(t, tmp, "notary.key"), + "SIGNING_IDENTITY": "signer@knative-releases.test", + }), + loadFile("fake-build-release.bash"), + ) + tc.test(sc)(t) + }) + } +} + +func TestFindChecksumsFile(t *testing.T) { + t.Parallel() + + foundChecksums := lines("/tmp/other/checksums.txt") + + tcs := []testCase{{ + name: "find_checksums_file /tmp/file1.out /tmp/file2.out", + retcode: retcode(0), + stderr: CantFindChecksums, + stdout: empty(), + }, { + name: "find_checksums_file /tmp/file1.out /tmp/other/checksums.txt /tmp/file2.out", + stdout: foundChecksums, + }, { + name: `find_checksums_file "$ARTIFACTS_TO_PUBLISH"`, + commands: []string{ + `export ARTIFACTS_TO_PUBLISH="/tmp/file1.out /tmp/other/checksums.txt /tmp/file2.out"`, + `find_checksums_file "$ARTIFACTS_TO_PUBLISH"`, + }, + stdout: foundChecksums, + }, { + name: `find_checksums_file "$ARTIFACTS_TO_PUBLISH" # without checksums in artifacts`, + retcode: retcode(0), + commands: []string{ + `export ARTIFACTS_TO_PUBLISH="/tmp/file1.out /tmp/file2.out"`, + `find_checksums_file "$ARTIFACTS_TO_PUBLISH"`, + }, + stderr: CantFindChecksums, + stdout: empty(), + }, { + name: `find_checksums_file "$ARTIFACTS_TO_PUBLISH" # with double spaces`, + commands: []string{ + `export ARTIFACTS_TO_PUBLISH="/tmp/file1.out /tmp/other/checksums.txt /tmp/file2.out"`, + `find_checksums_file "$ARTIFACTS_TO_PUBLISH"`, + }, + stdout: foundChecksums, + }} + sc := testReleaseShellScript(loadFile("fake-build-release.bash")) + for _, tc := range tcs { + tc := tc + t.Run(tc.name, tc.test(sc)) + } +} + func TestReleaseHelperFunctions(t *testing.T) { t.Parallel() sc := testReleaseShellScript() @@ -257,9 +355,22 @@ func TestReleaseFlagParsingDefaults(t *testing.T) { } } -func testReleaseShellScript() shellScript { - return newShellScript( +func testReleaseShellScript(scrps ...scriptlet) shellScript { + aargs := make([]scriptlet, 0, len(scrps)+3) + aargs = append(aargs, fakeProwJob(), loadFile("source-release.bash"), + loadFile("fake-presubmit-tests.bash"), ) + aargs = append(aargs, scrps...) + return newShellScript(aargs...) +} + +func randomFile(tb testing.TB, tmpdir string, filename string) string { + r := randString(24) + fp := path.Join(tmpdir, filename) + if err := ioutil.WriteFile(fp, []byte(r), 0o600); err != nil { + tb.Fatal(err) + } + return fp } diff --git a/test/unit/scripts/fake-build-release.bash b/test/unit/scripts/fake-build-release.bash new file mode 100644 index 00000000..58f7aca4 --- /dev/null +++ b/test/unit/scripts/fake-build-release.bash @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +# Copyright 2022 The Knative Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -Eeuo pipefail + +build_dir="${BUILD_DIR:-$(mktemp -d)}" +export ARTIFACTS_TO_PUBLISH + +function build_release() { + local artifact_names + declare -a artifact_names + artifact_names=( + foo-linux-amd64 + foo-linux-arm64 + foo-linux-ppc64le + foo-linux-s390x + foo-darwin-amd64 + foo-darwin-arm64 + foo-windows-amd64.exe + foo.yaml + ) + for artifact_name in "${artifact_names[@]}"; do + hashCode "$artifact_name" > "${build_dir}/${artifact_name}" + echo "${build_dir}/${artifact_name}" >> "${build_dir}/artifacts.list" + done + ARTIFACTS_TO_PUBLISH="$(tr '\r\n' ' ' < "${build_dir}/artifacts.list")" + if [[ -n "${CALCULATE_CHECKSUMS:-}" ]]; then + calculate_checksums + fi +} + +function calculate_checksums { + local checksums file + checksums="${build_dir}/checksums.txt" + rm -vf "${checksums}" + while read -r file; do + pushd "$(dirname "$file")" >/dev/null + sha256sum "$(basename "$file")" >> "${checksums}" + popd >/dev/null + done < "${build_dir}/artifacts.list" + ARTIFACTS_TO_PUBLISH="${ARTIFACTS_TO_PUBLISH} ${checksums}" +} diff --git a/test/unit/scripts/fake-presubmit-tests.bash b/test/unit/scripts/fake-presubmit-tests.bash new file mode 100644 index 00000000..73227f72 --- /dev/null +++ b/test/unit/scripts/fake-presubmit-tests.bash @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +# Copyright 2022 The Knative Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +add_trap teardown_fake_presubmit EXIT + +VALIDATION_TESTS="$(mktemp -d)/presubmit-tests.sh" + +cat < "${VALIDATION_TESTS}" +#!/usr/bin/env bash + +echo ">> Running fake presubmit tests" +echo "UNIT TESTS PASSED" +echo "INTEGRATION TESTS PASSED" +EOF + +chmod +x "${VALIDATION_TESTS}" + +function teardown_fake_presubmit() { + rm -rf "${VALIDATION_TESTS}" +} diff --git a/test/unit/sharedlib_test.go b/test/unit/sharedlib_test.go index c182be52..b314863a 100644 --- a/test/unit/sharedlib_test.go +++ b/test/unit/sharedlib_test.go @@ -30,6 +30,11 @@ func aborted(msg string) []check { return equal(makeBanner('*', fmsg)) } +func warned(msg string) []check { + fmsg := fmt.Sprintf("WARN: %s", msg) + return equal(makeBanner('!', fmsg)) +} + func makeBanner(ch rune, msg string) string { const span = 4 border := strings.Repeat(string(ch), len(msg)+span*2+2) @@ -169,6 +174,14 @@ func loadFile(names ...string) scriptlet { }) } +func envs(envs map[string]string) scriptlet { + instr := make([]string, 0, len(envs)) + for k, v := range envs { + instr = append(instr, fmt.Sprintf(`export %s="%s"`, k, v)) + } + return instructions(instr...) +} + func instructions(inst ...string) scriptlet { return fnScriptlet(func(t TestingT) string { return strings.Join(inst, "\n") @@ -248,8 +261,8 @@ func (a anyArgs) String() string { } func mockGo(responses ...response) scriptlet { - lstags := "knative.dev/test-infra/tools/go-ls-tags@latest" - modscope := "knative.dev/test-infra/tools/modscope@latest" + lstags := "knative.dev/toolbox/go-ls-tags@latest" + modscope := "knative.dev/toolbox/modscope@latest" callOriginals := []args{ startsWith{"run " + lstags}, startsWith{"run " + modscope}, @@ -283,10 +296,17 @@ func mockKubectl(responses ...response) scriptlet { func fakeProwJob() scriptlet { return union( loadFile("fake-prow-job.bash"), - mockBinary("gcloud"), + mockBinary("gcloud", response{ + startsWith{"auth print-identity-token"}, + simply("F4KE-T0K3N-3B49"), + }), mockBinary("java"), mockBinary("mvn"), mockBinary("ko"), + mockBinary("cosign"), + mockBinary("rcodesign"), + mockBinary("gsutil"), + mockBinary("kubetest2"), ) } diff --git a/test/unit/update_deps_test.go b/test/unit/update_deps_test.go index 4bf56a42..4fa1cd66 100644 --- a/test/unit/update_deps_test.go +++ b/test/unit/update_deps_test.go @@ -32,13 +32,13 @@ func TestUpdateDeps(t *testing.T) { }, { name: "go_update_deps --upgrade", stdout: []check{ - contains("go run knative.dev/test-infra/buoy@latest float ./go.mod " + + contains("go run knative.dev/toolbox/buoy@latest float ./go.mod " + "--release v9000.1 --domain knative.dev"), }, }, { name: "go_update_deps --upgrade --release 1.25 --module-release 0.28", stdout: []check{ - contains("go run knative.dev/test-infra/buoy@latest float ./go.mod " + + contains("go run knative.dev/toolbox/buoy@latest float ./go.mod " + "--release 1.25 --domain knative.dev --module-release 0.28"), }, }}