Merge commit '300babff46ad5a1dd593a9a7962cd28cd9349563' into update-release-tools3

This commit is contained in:
andyzhangx 2023-08-11 14:39:24 +00:00
commit 8fae414d14
5 changed files with 196 additions and 16 deletions

View File

@ -102,9 +102,9 @@ naming convention `<hostpath-deployment-version>-on-<kubernetes-version>`.
1. If release was a new major/minor version, create a new `release-<minor>` 1. If release was a new major/minor version, create a new `release-<minor>`
branch at that commit. branch at that commit.
1. Check [image build status](https://k8s-testgrid.appspot.com/sig-storage-image-build). 1. Check [image build status](https://k8s-testgrid.appspot.com/sig-storage-image-build).
1. Promote images from k8s-staging-sig-storage to k8s.gcr.io/sig-storage. From 1. Promote images from k8s-staging-sig-storage to registry.k8s.io/sig-storage. From
the [k8s image the [k8s image
repo](https://github.com/kubernetes/k8s.io/tree/HEAD/k8s.gcr.io/images/k8s-staging-sig-storage), repo](https://github.com/kubernetes/k8s.io/tree/HEAD/registry.k8s.io/images/k8s-staging-sig-storage),
run `./generate.sh > images.yaml`, and send a PR with the updated images. run `./generate.sh > images.yaml`, and send a PR with the updated images.
Once merged, the image promoter will copy the images from staging to prod. Once merged, the image promoter will copy the images from staging to prod.
1. Update [kubernetes-csi/docs](https://github.com/kubernetes-csi/docs) sidecar 1. Update [kubernetes-csi/docs](https://github.com/kubernetes-csi/docs) sidecar

View File

@ -148,7 +148,7 @@ DOCKER_BUILDX_CREATE_ARGS ?=
$(CMDS:%=push-multiarch-%): push-multiarch-%: check-pull-base-ref build-% $(CMDS:%=push-multiarch-%): push-multiarch-%: check-pull-base-ref build-%
set -ex; \ set -ex; \
export DOCKER_CLI_EXPERIMENTAL=enabled; \ export DOCKER_CLI_EXPERIMENTAL=enabled; \
docker buildx create $(DOCKER_BUILDX_CREATE_ARGS) --use --name multiarchimage-buildertest; \ docker buildx create $(DOCKER_BUILDX_CREATE_ARGS) --use --name multiarchimage-buildertest --driver-opt image=moby/buildkit:v0.10.6; \
trap "docker buildx rm multiarchimage-buildertest" EXIT; \ trap "docker buildx rm multiarchimage-buildertest" EXIT; \
dockerfile_linux=$$(if [ -e ./$(CMDS_DIR)/$*/Dockerfile ]; then echo ./$(CMDS_DIR)/$*/Dockerfile; else echo Dockerfile; fi); \ dockerfile_linux=$$(if [ -e ./$(CMDS_DIR)/$*/Dockerfile ]; then echo ./$(CMDS_DIR)/$*/Dockerfile; else echo Dockerfile; fi); \
dockerfile_windows=$$(if [ -e ./$(CMDS_DIR)/$*/Dockerfile.Windows ]; then echo ./$(CMDS_DIR)/$*/Dockerfile.Windows; else echo Dockerfile.Windows; fi); \ dockerfile_windows=$$(if [ -e ./$(CMDS_DIR)/$*/Dockerfile.Windows ]; then echo ./$(CMDS_DIR)/$*/Dockerfile.Windows; else echo Dockerfile.Windows; fi); \

View File

@ -13,7 +13,7 @@
# See https://github.com/kubernetes/test-infra/blob/HEAD/config/jobs/image-pushing/README.md # See https://github.com/kubernetes/test-infra/blob/HEAD/config/jobs/image-pushing/README.md
# for more details on image pushing process in Kubernetes. # for more details on image pushing process in Kubernetes.
# #
# To promote release images, see https://github.com/kubernetes/k8s.io/tree/HEAD/k8s.gcr.io/images/k8s-staging-sig-storage. # To promote release images, see https://github.com/kubernetes/k8s.io/tree/HEAD/registry.k8s.io/images/k8s-staging-sig-storage.
# This must be specified in seconds. If omitted, defaults to 600s (10 mins). # This must be specified in seconds. If omitted, defaults to 600s (10 mins).
# Building three images in external-snapshotter takes more than an hour. # Building three images in external-snapshotter takes more than an hour.
@ -26,7 +26,7 @@ steps:
# The image must contain bash and curl. Ideally it should also contain # The image must contain bash and curl. Ideally it should also contain
# the desired version of Go (currently defined in release-tools/prow.sh), # the desired version of Go (currently defined in release-tools/prow.sh),
# but that just speeds up the build and is not required. # but that just speeds up the build and is not required.
- name: 'gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20210917-12df099d55' - name: 'gcr.io/k8s-testimages/gcb-docker-gcloud:v20230623-56e06d7c18'
entrypoint: ./.cloudbuild.sh entrypoint: ./.cloudbuild.sh
env: env:
- GIT_TAG=${_GIT_TAG} - GIT_TAG=${_GIT_TAG}

View File

@ -0,0 +1,170 @@
# Copyright 2023 The Kubernetes 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.
import argparse
import datetime
import re
from collections import defaultdict
import subprocess
import shutil
from dateutil.relativedelta import relativedelta
def check_gh_command():
"""
Pretty much everything is processed from `gh`
Check that the `gh` command is in the path before anything else
"""
if not shutil.which('gh'):
print("Error: The `gh` command is not available in the PATH.")
print("Please install the GitHub CLI (https://cli.github.com/) and try again.")
exit(1)
def duration_ago(dt):
"""
Humanize duration outputs
"""
delta = relativedelta(datetime.datetime.now(), dt)
if delta.years > 0:
return f"{delta.years} year{'s' if delta.years > 1 else ''} ago"
elif delta.months > 0:
return f"{delta.months} month{'s' if delta.months > 1 else ''} ago"
elif delta.days > 0:
return f"{delta.days} day{'s' if delta.days > 1 else ''} ago"
elif delta.hours > 0:
return f"{delta.hours} hour{'s' if delta.hours > 1 else ''} ago"
elif delta.minutes > 0:
return f"{delta.minutes} minute{'s' if delta.minutes > 1 else ''} ago"
else:
return "just now"
def parse_version(version):
"""
Parse version assuming it is in the form of v1.2.3
"""
pattern = r"v(\d+)\.(\d+)\.(\d+)"
match = re.match(pattern, version)
if match:
major, minor, patch = map(int, match.groups())
return (major, minor, patch)
def end_of_life_grouped_versions(versions):
"""
Calculate the end of life date for a minor release version according to : https://kubernetes-csi.github.io/docs/project-policies.html#support
The input is an array of tuples of:
* grouped versions (e.g. 1.0, 1.1)
* array of that contains all versions and their release date (e.g. 1.0.0, 01-01-2013)
versions structure example :
[((3, 5), [('v3.5.0', datetime.datetime(2023, 4, 27, 22, 28, 6))]),
((3, 4),
[('v3.4.1', datetime.datetime(2023, 4, 5, 17, 41, 15)),
('v3.4.0', datetime.datetime(2022, 12, 27, 23, 43, 41))])]
"""
supported_versions = []
# Prepare dates for later calculation
now = datetime.datetime.now()
one_year = datetime.timedelta(days=365)
three_months = datetime.timedelta(days=90)
# get the newer versions on top
sorted_versions_list = sorted(versions.items(), key=lambda x: x[0], reverse=True)
# the latest version is always supported no matter the release date
latest = sorted_versions_list.pop(0)
supported_versions.append(latest[1][-1])
for v in sorted_versions_list:
first_release = v[1][-1]
last_release = v[1][0]
# if the release is less than a year old we support the latest patch version
if now - first_release[1] < one_year:
supported_versions.append(last_release)
# if the main release is older than a year and has a recent path, this is supported
elif now - last_release[1] < three_months:
supported_versions.append(last_release)
return supported_versions
def get_release_docker_image(repo, version):
"""
Extract docker image name from the release page documentation
"""
output = subprocess.check_output(['gh', 'release', '-R', repo, 'view', version], text=True)
#Extract matching image name excluding `
match = re.search(r"docker pull ([\.\/\-\:\w\d]*)", output)
docker_image = match.group(1) if match else ''
return((version, docker_image))
def get_versions_from_releases(repo):
"""
Using `gh` cli get the github releases page details then
create a list of grouped version on major.minor
and for each give all major.minor.patch with release dates
"""
# Run the `gh release` command to get the release list
output = subprocess.check_output(['gh', 'release', '-R', repo, 'list'], text=True)
# Parse the output and group by major and minor version numbers
versions = defaultdict(lambda: [])
for line in output.strip().split('\n'):
parts = line.split('\t')
# pprint.pprint(parts)
version = parts[0]
parsed_version = parse_version(version)
if parsed_version is None:
continue
major, minor, patch = parsed_version
published = datetime.datetime.strptime(parts[3], '%Y-%m-%dT%H:%M:%SZ')
versions[(major, minor)].append((version, published))
return(versions)
def main():
manual = """
This script lists the supported versions Github releases according to https://kubernetes-csi.github.io/docs/project-policies.html#support
It has been designed to help to update the tables from : https://kubernetes-csi.github.io/docs/sidecar-containers.html\n\n
It can take multiple repos as argument, for all CSI sidecars details you can run:
./get_supported_version_csi-sidecar.py -R kubernetes-csi/external-attacher -R kubernetes-csi/external-provisioner -R kubernetes-csi/external-resizer -R kubernetes-csi/external-snapshotter -R kubernetes-csi/livenessprobe -R kubernetes-csi/node-driver-registrar -R kubernetes-csi/external-health-monitor\n
With the output you can then update the documentation manually.
"""
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, description=manual)
parser.add_argument('--repo', '-R', required=True, action='append', dest='repos', help='The name of the repository in the format owner/repo.')
parser.add_argument('--display', '-d', action='store_true', help='(default) Display EOL versions with their dates', default=True)
parser.add_argument('--doc', '-D', action='store_true', help='Helper to https://kubernetes-csi.github.io/docs/ that prints Docker image for each EOL version')
args = parser.parse_args()
# Verify pre-reqs
check_gh_command()
# Process all repos
for repo in args.repos:
versions = get_versions_from_releases(repo)
eol_versions = end_of_life_grouped_versions(versions)
if args.display:
print(f"Supported versions with release date and age of `{repo}`:\n")
for version in eol_versions:
print(f"{version[0]}\t{version[1].strftime('%Y-%m-%d')}\t{duration_ago(version[1])}")
# TODO : generate proper doc output for the tables of: https://kubernetes-csi.github.io/docs/sidecar-containers.html
if args.doc:
print("\nSupported Versions with docker images for each end of life version:\n")
for version in eol_versions:
_, image = get_release_docker_image(repo, version[0])
print(f"{version[0]}\t{image}")
print()
if __name__ == '__main__':
main()

View File

@ -86,7 +86,7 @@ configvar CSI_PROW_BUILD_PLATFORMS "linux amd64 amd64; linux ppc64le ppc64le -pp
# which is disabled with GOFLAGS=-mod=vendor). # which is disabled with GOFLAGS=-mod=vendor).
configvar GOFLAGS_VENDOR "$( [ -d vendor ] && echo '-mod=vendor' )" "Go flags for using the vendor directory" configvar GOFLAGS_VENDOR "$( [ -d vendor ] && echo '-mod=vendor' )" "Go flags for using the vendor directory"
configvar CSI_PROW_GO_VERSION_BUILD "1.19" "Go version for building the component" # depends on component's source code configvar CSI_PROW_GO_VERSION_BUILD "1.20" "Go version for building the component" # depends on component's source code
configvar CSI_PROW_GO_VERSION_E2E "" "override Go version for building the Kubernetes E2E test suite" # normally doesn't need to be set, see install_e2e configvar CSI_PROW_GO_VERSION_E2E "" "override Go version for building the Kubernetes E2E test suite" # normally doesn't need to be set, see install_e2e
configvar CSI_PROW_GO_VERSION_SANITY "${CSI_PROW_GO_VERSION_BUILD}" "Go version for building the csi-sanity test suite" # depends on CSI_PROW_SANITY settings below configvar CSI_PROW_GO_VERSION_SANITY "${CSI_PROW_GO_VERSION_BUILD}" "Go version for building the csi-sanity test suite" # depends on CSI_PROW_SANITY settings below
configvar CSI_PROW_GO_VERSION_KIND "${CSI_PROW_GO_VERSION_BUILD}" "Go version for building 'kind'" # depends on CSI_PROW_KIND_VERSION below configvar CSI_PROW_GO_VERSION_KIND "${CSI_PROW_GO_VERSION_BUILD}" "Go version for building 'kind'" # depends on CSI_PROW_KIND_VERSION below
@ -101,7 +101,10 @@ configvar CSI_PROW_GINKGO_VERSION v1.7.0 "Ginkgo"
# Ginkgo runs the E2E test in parallel. The default is based on the number # Ginkgo runs the E2E test in parallel. The default is based on the number
# of CPUs, but typically this can be set to something higher in the job. # of CPUs, but typically this can be set to something higher in the job.
configvar CSI_PROW_GINKO_PARALLEL "-p" "Ginko parallelism parameter(s)" configvar CSI_PROW_GINKGO_PARALLEL "-p" "Ginkgo parallelism parameter(s)"
# Timeout value for the overall ginkgo test suite.
configvar CSI_PROW_GINKGO_TIMEOUT "1h" "Ginkgo timeout"
# Enables building the code in the repository. On by default, can be # Enables building the code in the repository. On by default, can be
# disabled in jobs which only use pre-built components. # disabled in jobs which only use pre-built components.
@ -245,7 +248,7 @@ configvar CSI_PROW_SANITY_CONTAINER "hostpath" "Kubernetes container with CSI dr
# The version of dep to use for 'make test-vendor'. Ignored if the project doesn't # The version of dep to use for 'make test-vendor'. Ignored if the project doesn't
# use dep. Only binary releases of dep are supported (https://github.com/golang/dep/releases). # use dep. Only binary releases of dep are supported (https://github.com/golang/dep/releases).
configvar CSI_PROW_DEP_VERSION v0.5.1 "golang dep version to be used for vendor checking" configvar CSI_PROW_DEP_VERSION v0.5.4 "golang dep version to be used for vendor checking"
# Each job can run one or more of the following tests, identified by # Each job can run one or more of the following tests, identified by
# a single word: # a single word:
@ -469,7 +472,7 @@ install_dep () {
if dep version 2>/dev/null | grep -q "version:.*${CSI_PROW_DEP_VERSION}$"; then if dep version 2>/dev/null | grep -q "version:.*${CSI_PROW_DEP_VERSION}$"; then
return return
fi fi
run curl --fail --location -o "${CSI_PROW_WORK}/bin/dep" "https://github.com/golang/dep/releases/download/v0.5.4/dep-linux-amd64" && run curl --fail --location -o "${CSI_PROW_WORK}/bin/dep" "https://github.com/golang/dep/releases/download/${CSI_PROW_DEP_VERSION}/dep-linux-amd64" &&
chmod u+x "${CSI_PROW_WORK}/bin/dep" chmod u+x "${CSI_PROW_WORK}/bin/dep"
} }
@ -872,10 +875,17 @@ install_snapshot_controller() {
cnt=0 cnt=0
expected_running_pods=$(kubectl apply --dry-run=client -o "jsonpath={.spec.replicas}" -f "$SNAPSHOT_CONTROLLER_YAML") expected_running_pods=$(kubectl apply --dry-run=client -o "jsonpath={.spec.replicas}" -f "$SNAPSHOT_CONTROLLER_YAML")
expected_namespace=$(kubectl apply --dry-run=client -o "jsonpath={.metadata.namespace}" -f "$SNAPSHOT_CONTROLLER_YAML") expected_namespace=$(kubectl apply --dry-run=client -o "jsonpath={.metadata.namespace}" -f "$SNAPSHOT_CONTROLLER_YAML")
while [ "$(kubectl get pods -n "$expected_namespace" -l app=snapshot-controller | grep 'Running' -c)" -lt "$expected_running_pods" ]; do expect_key='app\.kubernetes\.io/name'
expected_label=$(kubectl apply --dry-run=client -o "jsonpath={.spec.template.metadata.labels['$expect_key']}" -f "$SNAPSHOT_CONTROLLER_YAML")
if [ -z "${expected_label}" ]; then
expect_key='app'
expected_label=$(kubectl apply --dry-run=client -o "jsonpath={.spec.template.metadata.labels['$expect_key']}" -f "$SNAPSHOT_CONTROLLER_YAML")
fi
expect_key=${expect_key//\\/}
while [ "$(kubectl get pods -n "$expected_namespace" -l "$expect_key"="$expected_label" | grep 'Running' -c)" -lt "$expected_running_pods" ]; do
if [ $cnt -gt 30 ]; then if [ $cnt -gt 30 ]; then
echo "snapshot-controller pod status:" echo "snapshot-controller pod status:"
kubectl describe pods -n "$expected_namespace" -l app=snapshot-controller kubectl describe pods -n "$expected_namespace" -l "$expect_key"="$expected_label"
echo >&2 "ERROR: snapshot controller not ready after over 5 min" echo >&2 "ERROR: snapshot controller not ready after over 5 min"
exit 1 exit 1
fi fi
@ -1018,10 +1028,10 @@ run_e2e () (
if [ "${name}" == "local" ]; then if [ "${name}" == "local" ]; then
cd "${GOPATH}/src/${CSI_PROW_SIDECAR_E2E_IMPORT_PATH}" && cd "${GOPATH}/src/${CSI_PROW_SIDECAR_E2E_IMPORT_PATH}" &&
run_with_loggers env KUBECONFIG="$KUBECONFIG" KUBE_TEST_REPO_LIST="$(if [ -e "${CSI_PROW_WORK}/e2e-repo-list" ]; then echo "${CSI_PROW_WORK}/e2e-repo-list"; fi)" ginkgo -v "$@" "${CSI_PROW_WORK}/e2e-local.test" -- -report-dir "${ARTIFACTS}" -report-prefix local run_with_loggers env KUBECONFIG="$KUBECONFIG" KUBE_TEST_REPO_LIST="$(if [ -e "${CSI_PROW_WORK}/e2e-repo-list" ]; then echo "${CSI_PROW_WORK}/e2e-repo-list"; fi)" ginkgo --timeout="${CSI_PROW_GINKGO_TIMEOUT}" -v "$@" "${CSI_PROW_WORK}/e2e-local.test" -- -report-dir "${ARTIFACTS}" -report-prefix local
else else
cd "${GOPATH}/src/${CSI_PROW_E2E_IMPORT_PATH}" && cd "${GOPATH}/src/${CSI_PROW_E2E_IMPORT_PATH}" &&
run_with_loggers env KUBECONFIG="$KUBECONFIG" KUBE_TEST_REPO_LIST="$(if [ -e "${CSI_PROW_WORK}/e2e-repo-list" ]; then echo "${CSI_PROW_WORK}/e2e-repo-list"; fi)" ginkgo -v "$@" "${CSI_PROW_WORK}/e2e.test" -- -report-dir "${ARTIFACTS}" -storage.testdriver="${CSI_PROW_WORK}/test-driver.yaml" run_with_loggers env KUBECONFIG="$KUBECONFIG" KUBE_TEST_REPO_LIST="$(if [ -e "${CSI_PROW_WORK}/e2e-repo-list" ]; then echo "${CSI_PROW_WORK}/e2e-repo-list"; fi)" ginkgo --timeout="${CSI_PROW_GINKGO_TIMEOUT}" -v "$@" "${CSI_PROW_WORK}/e2e.test" -- -report-dir "${ARTIFACTS}" -storage.testdriver="${CSI_PROW_WORK}/test-driver.yaml"
fi fi
) )
@ -1310,7 +1320,7 @@ main () {
if tests_enabled "parallel"; then if tests_enabled "parallel"; then
# Ignore: Double quote to prevent globbing and word splitting. # Ignore: Double quote to prevent globbing and word splitting.
# shellcheck disable=SC2086 # shellcheck disable=SC2086
if ! run_e2e parallel ${CSI_PROW_GINKO_PARALLEL} \ if ! run_e2e parallel ${CSI_PROW_GINKGO_PARALLEL} \
-focus="$focus" \ -focus="$focus" \
-skip="$(regex_join "${CSI_PROW_E2E_SERIAL}" "${CSI_PROW_E2E_ALPHA}" "${CSI_PROW_E2E_SKIP}")"; then -skip="$(regex_join "${CSI_PROW_E2E_SERIAL}" "${CSI_PROW_E2E_ALPHA}" "${CSI_PROW_E2E_SKIP}")"; then
warn "E2E parallel failed" warn "E2E parallel failed"
@ -1320,7 +1330,7 @@ main () {
# Run tests that are feature tagged, but non-alpha # Run tests that are feature tagged, but non-alpha
# Ignore: Double quote to prevent globbing and word splitting. # Ignore: Double quote to prevent globbing and word splitting.
# shellcheck disable=SC2086 # shellcheck disable=SC2086
if ! run_e2e parallel-features ${CSI_PROW_GINKO_PARALLEL} \ if ! run_e2e parallel-features ${CSI_PROW_GINKGO_PARALLEL} \
-focus="$focus.*($(regex_join "${CSI_PROW_E2E_FOCUS}"))" \ -focus="$focus.*($(regex_join "${CSI_PROW_E2E_FOCUS}"))" \
-skip="$(regex_join "${CSI_PROW_E2E_SERIAL}")"; then -skip="$(regex_join "${CSI_PROW_E2E_SERIAL}")"; then
warn "E2E parallel features failed" warn "E2E parallel features failed"
@ -1368,7 +1378,7 @@ main () {
if tests_enabled "parallel-alpha"; then if tests_enabled "parallel-alpha"; then
# Ignore: Double quote to prevent globbing and word splitting. # Ignore: Double quote to prevent globbing and word splitting.
# shellcheck disable=SC2086 # shellcheck disable=SC2086
if ! run_e2e parallel-alpha ${CSI_PROW_GINKO_PARALLEL} \ if ! run_e2e parallel-alpha ${CSI_PROW_GINKGO_PARALLEL} \
-focus="$focus.*($(regex_join "${CSI_PROW_E2E_ALPHA}"))" \ -focus="$focus.*($(regex_join "${CSI_PROW_E2E_ALPHA}"))" \
-skip="$(regex_join "${CSI_PROW_E2E_SERIAL}" "${CSI_PROW_E2E_SKIP}")"; then -skip="$(regex_join "${CSI_PROW_E2E_SERIAL}" "${CSI_PROW_E2E_SKIP}")"; then
warn "E2E parallel alpha failed" warn "E2E parallel alpha failed"