mirror of https://github.com/k3s-io/k3s
Use kube::release::gcs::publish_latest_official logic in mark-stable-release.sh and add quote fixups, fixes #14785; implement major- and minor-pinned version releases, fixes #14920
parent
7c5b8f6a58
commit
9e61f8d632
229
build/common.sh
229
build/common.sh
|
@ -41,8 +41,7 @@ readonly KUBE_GCS_MAKE_PUBLIC="${KUBE_GCS_MAKE_PUBLIC:-y}"
|
|||
# KUBE_GCS_RELEASE_BUCKET default: kubernetes-releases-${project_hash}
|
||||
readonly KUBE_GCS_RELEASE_PREFIX=${KUBE_GCS_RELEASE_PREFIX-devel}/
|
||||
readonly KUBE_GCS_DOCKER_REG_PREFIX=${KUBE_GCS_DOCKER_REG_PREFIX-docker-reg}/
|
||||
readonly KUBE_GCS_LATEST_FILE=${KUBE_GCS_LATEST_FILE:-}
|
||||
readonly KUBE_GCS_LATEST_CONTENTS=${KUBE_GCS_LATEST_CONTENTS:-}
|
||||
readonly KUBE_GCS_PUBLISH_VERSION=${KUBE_GCS_PUBLISH_VERSION:-}
|
||||
readonly KUBE_GCS_DELETE_EXISTING="${KUBE_GCS_DELETE_EXISTING:-n}"
|
||||
|
||||
# Constants
|
||||
|
@ -339,6 +338,28 @@ function kube::build::destroy_container() {
|
|||
"${DOCKER[@]}" rm -f -v "$1" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
# Validate a release version
|
||||
#
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# version
|
||||
# Returns:
|
||||
# If version is a valid release version
|
||||
# Sets:
|
||||
# BASH_REMATCH, so you can do something like:
|
||||
# local -r version_major="${BASH_REMATCH[1]}"
|
||||
# local -r version_minor="${BASH_REMATCH[2]}"
|
||||
# local -r version_patch="${BASH_REMATCH[3]}"
|
||||
function kube::release::parse_and_validate_release_version() {
|
||||
local -r version_regex="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$"
|
||||
local -r version="${1-}"
|
||||
[[ "${version}" =~ ${version_regex} ]] || {
|
||||
kube::log::error "Invalid release version: '${version}'"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Building
|
||||
|
@ -975,14 +996,15 @@ function kube::release::gcs::copy_release_artifacts() {
|
|||
kube::log::error "${gcs_destination} not empty."
|
||||
[[ ${KUBE_GCS_DELETE_EXISTING} =~ ^[yY]$ ]] || {
|
||||
read -p "Delete everything under ${gcs_destination}? [y/n] " -r || {
|
||||
echo "EOF on prompt. Skipping upload"
|
||||
kube::log::status "EOF on prompt. Skipping upload"
|
||||
return
|
||||
}
|
||||
[[ $REPLY =~ ^[yY]$ ]] || {
|
||||
echo "Skipping upload"
|
||||
kube::log::status "Skipping upload"
|
||||
return
|
||||
}
|
||||
}
|
||||
kube::log::status "Deleting everything under ${gcs_destination}"
|
||||
gsutil -q -m rm -f -R "${gcs_destination}" || return 1
|
||||
fi
|
||||
|
||||
|
@ -1006,68 +1028,169 @@ function kube::release::gcs::copy_release_artifacts() {
|
|||
gsutil ls -lhr "${gcs_destination}" || return 1
|
||||
}
|
||||
|
||||
function kube::release::gcs::publish_latest() {
|
||||
local latest_file_dst="gs://${KUBE_GCS_RELEASE_BUCKET}/${KUBE_GCS_LATEST_FILE}"
|
||||
|
||||
mkdir -p "${RELEASE_STAGE}/upload" || return 1
|
||||
echo ${KUBE_GCS_LATEST_CONTENTS} > "${RELEASE_STAGE}/upload/latest" || return 1
|
||||
|
||||
gsutil -m cp "${RELEASE_STAGE}/upload/latest" "${latest_file_dst}" || return 1
|
||||
|
||||
if [[ ${KUBE_GCS_MAKE_PUBLIC} =~ ^[yY]$ ]]; then
|
||||
gsutil acl ch -R -g all:R "${latest_file_dst}" >/dev/null 2>&1 || return 1
|
||||
fi
|
||||
|
||||
kube::log::status "gsutil cat ${latest_file_dst}:"
|
||||
gsutil cat ${latest_file_dst} || return 1
|
||||
# Publish a new ci version, (latest,) but only if the release files actually
|
||||
# exist on GCS.
|
||||
#
|
||||
# Globals:
|
||||
# See callees
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# Success
|
||||
function kube::release::gcs::publish_ci() {
|
||||
kube::release::gcs::verify_release_files || return 1
|
||||
kube::release::gcs::publish 'ci/latest.txt' || return 1
|
||||
}
|
||||
|
||||
# Publish a new latest.txt, but only if the release we're dealing with
|
||||
# is newer than the contents in GCS.
|
||||
function kube::release::gcs::publish_latest_official() {
|
||||
local -r new_version=${KUBE_GCS_LATEST_CONTENTS}
|
||||
local -r latest_file_dst="gs://${KUBE_GCS_RELEASE_BUCKET}/${KUBE_GCS_LATEST_FILE}"
|
||||
# Publish a new official version, (latest or stable,) but only if the release
|
||||
# files actually exist on GCS and the release we're dealing with is newer than
|
||||
# the contents in GCS.
|
||||
#
|
||||
# Globals:
|
||||
# KUBE_GCS_PUBLISH_VERSION
|
||||
# See callees
|
||||
# Arguments:
|
||||
# release_kind: either 'latest' or 'stable'
|
||||
# Returns:
|
||||
# Success
|
||||
function kube::release::gcs::publish_official() {
|
||||
local -r release_kind="${1-}"
|
||||
|
||||
local -r version_regex="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$"
|
||||
[[ ${new_version} =~ ${version_regex} ]] || {
|
||||
kube::log::error "publish_latest_official passed bogus value: '${new_version}'"
|
||||
kube::release::gcs::verify_release_files || return 1
|
||||
|
||||
kube::release::parse_and_validate_release_version "${KUBE_GCS_PUBLISH_VERSION}" || return 1
|
||||
local -r version_major="${BASH_REMATCH[1]}"
|
||||
local -r version_minor="${BASH_REMATCH[2]}"
|
||||
|
||||
local publish_files
|
||||
if [[ "${release_kind}" == 'latest' ]]; then
|
||||
publish_files=(release/latest.txt release/latest-${version_major}.txt release/latest-${version_major}.${version_minor}.txt)
|
||||
elif [[ "${release_kind}" == 'stable' ]]; then
|
||||
publish_files=(release/stable.txt release/stable-${version_major}.txt release/stable-${version_major}.${version_minor}.txt)
|
||||
else
|
||||
kube::log::error "Wrong release_kind: must be 'latest' or 'stable'."
|
||||
return 1
|
||||
}
|
||||
fi
|
||||
|
||||
for publish_file in ${publish_files[*]}; do
|
||||
# If there's a version that's above the one we're trying to release, don't
|
||||
# do anything, and just try the next one.
|
||||
kube::release::gcs::verify_release_gt "${publish_file}" || continue
|
||||
kube::release::gcs::publish "${publish_file}" || return 1
|
||||
done
|
||||
}
|
||||
|
||||
# Verify that the release files we expect actually exist.
|
||||
#
|
||||
# Globals:
|
||||
# KUBE_GCS_RELEASE_BUCKET
|
||||
# KUBE_GCS_RELEASE_PREFIX
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# If release files exist
|
||||
function kube::release::gcs::verify_release_files() {
|
||||
local -r release_dir="gs://${KUBE_GCS_RELEASE_BUCKET}/${KUBE_GCS_RELEASE_PREFIX}"
|
||||
if ! gsutil ls "${release_dir}" >/dev/null 2>&1 ; then
|
||||
kube::log::error "Release files don't exist at '${release_dir}'"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if the new version is greater than the version currently published on
|
||||
# GCS.
|
||||
#
|
||||
# Globals:
|
||||
# KUBE_GCS_PUBLISH_VERSION
|
||||
# KUBE_GCS_RELEASE_BUCKET
|
||||
# Arguments:
|
||||
# publish_file: the GCS location to look in
|
||||
# Returns:
|
||||
# If new version is greater than the GCS version
|
||||
function kube::release::gcs::verify_release_gt() {
|
||||
local -r publish_file="${1-}"
|
||||
local -r new_version=${KUBE_GCS_PUBLISH_VERSION}
|
||||
local -r publish_file_dst="gs://${KUBE_GCS_RELEASE_BUCKET}/${publish_file}"
|
||||
|
||||
kube::release::parse_and_validate_release_version "${new_version}" || return 1
|
||||
|
||||
local -r version_major="${BASH_REMATCH[1]}"
|
||||
local -r version_minor="${BASH_REMATCH[2]}"
|
||||
local -r version_patch="${BASH_REMATCH[3]}"
|
||||
|
||||
local gcs_version
|
||||
gcs_version=$(gsutil cat "${latest_file_dst}")
|
||||
if gcs_version="$(gsutil cat "${publish_file_dst}")"; then
|
||||
kube::release::parse_and_validate_release_version "${gcs_version}" || {
|
||||
kube::log::error "${publish_file_dst} contains invalid release version, can't compare: '${gcs_version}'"
|
||||
return 1
|
||||
}
|
||||
|
||||
[[ ${gcs_version} =~ ${version_regex} ]] || {
|
||||
kube::log::error "${latest_file_dst} contains invalid release version, can't compare: '${gcs_version}'"
|
||||
return 1
|
||||
}
|
||||
local -r gcs_version_major="${BASH_REMATCH[1]}"
|
||||
local -r gcs_version_minor="${BASH_REMATCH[2]}"
|
||||
local -r gcs_version_patch="${BASH_REMATCH[3]}"
|
||||
|
||||
local -r gcs_version_major="${BASH_REMATCH[1]}"
|
||||
local -r gcs_version_minor="${BASH_REMATCH[2]}"
|
||||
local -r gcs_version_patch="${BASH_REMATCH[3]}"
|
||||
local greater=true
|
||||
if [[ "${gcs_version_major}" -gt "${version_major}" ]]; then
|
||||
greater=false
|
||||
elif [[ "${gcs_version_major}" -lt "${version_major}" ]]; then
|
||||
: # fall out
|
||||
elif [[ "${gcs_version_minor}" -gt "${version_minor}" ]]; then
|
||||
greater=false
|
||||
elif [[ "${gcs_version_minor}" -lt "${version_minor}" ]]; then
|
||||
: # fall out
|
||||
elif [[ "${gcs_version_patch}" -ge "${version_patch}" ]]; then
|
||||
greater=false
|
||||
fi
|
||||
|
||||
local greater=true
|
||||
if [[ "${gcs_version_major}" -gt "${version_major}" ]]; then
|
||||
greater=false
|
||||
elif [[ "${gcs_version_major}" -lt "${version_major}" ]]; then
|
||||
: # fall out
|
||||
elif [[ "${gcs_version_minor}" -gt "${version_minor}" ]]; then
|
||||
greater=false
|
||||
elif [[ "${gcs_version_minor}" -lt "${version_minor}" ]]; then
|
||||
: # fall out
|
||||
elif [[ "${gcs_version_patch}" -ge "${version_patch}" ]]; then
|
||||
greater=false
|
||||
fi
|
||||
|
||||
if [[ "${greater}" != "true" ]]; then
|
||||
kube::log::status "${gcs_version} (latest on GCS) >= ${new_version} (just uploaded), not updating ${latest_file_dst}"
|
||||
if [[ "${greater}" != "true" ]]; then
|
||||
kube::log::status "${new_version} (just uploaded) <= ${gcs_version} (latest on GCS), not updating ${publish_file_dst}"
|
||||
return 1
|
||||
else
|
||||
kube::log::status "${new_version} (just uploaded) > ${gcs_version} (latest on GCS), updating ${publish_file_dst}"
|
||||
fi
|
||||
else # gsutil cat failed; file does not exist
|
||||
kube::log::error "Release file '${publish_file_dst}' does not exist. Continuing."
|
||||
return 0
|
||||
fi
|
||||
|
||||
kube::log::status "${new_version} (just uploaded) > ${gcs_version} (latest on GCS), updating ${latest_file_dst}"
|
||||
kube::release::gcs::publish_latest || return 1
|
||||
}
|
||||
|
||||
# Publish a release to GCS: upload a version file, if KUBE_GCS_MAKE_PUBLIC,
|
||||
# make it public, and verify the result.
|
||||
#
|
||||
# Globals:
|
||||
# KUBE_GCS_RELEASE_BUCKET
|
||||
# RELEASE_STAGE
|
||||
# KUBE_GCS_PUBLISH_VERSION
|
||||
# KUBE_GCS_MAKE_PUBLIC
|
||||
# Arguments:
|
||||
# publish_file: the GCS location to look in
|
||||
# Returns:
|
||||
# If new version is greater than the GCS version
|
||||
function kube::release::gcs::publish() {
|
||||
local -r publish_file="${1-}"
|
||||
local -r publish_file_dst="gs://${KUBE_GCS_RELEASE_BUCKET}/${publish_file}"
|
||||
|
||||
mkdir -p "${RELEASE_STAGE}/upload" || return 1
|
||||
echo "${KUBE_GCS_PUBLISH_VERSION}" > "${RELEASE_STAGE}/upload/latest" || return 1
|
||||
|
||||
gsutil -m cp "${RELEASE_STAGE}/upload/latest" "${publish_file_dst}" || return 1
|
||||
|
||||
local contents
|
||||
if [[ ${KUBE_GCS_MAKE_PUBLIC} =~ ^[yY]$ ]]; then
|
||||
gsutil acl ch -R -g all:R "${publish_file_dst}" >/dev/null 2>&1 || return 1
|
||||
# If public, validate public link
|
||||
local -r public_link="https://storage.googleapis.com/${KUBE_GCS_RELEASE_BUCKET}/${publish_file}"
|
||||
kube::log::status "Validating uploaded version file at ${public_link}"
|
||||
contents="$(curl -s "${public_link}")"
|
||||
else
|
||||
# If not public, validate using gsutil
|
||||
kube::log::status "Validating uploaded version file at ${publish_file_dst}"
|
||||
contents="$(gsutil cat "${publish_file_dst}")"
|
||||
fi
|
||||
if [[ "${contents}" == "${KUBE_GCS_PUBLISH_VERSION}" ]]; then
|
||||
kube::log::status "Contents as expected: ${contents}"
|
||||
else
|
||||
kube::log::error "Expected contents of file to be ${KUBE_GCS_PUBLISH_VERSION}, but got ${contents}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -20,31 +20,24 @@ set -o errexit
|
|||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
if [[ -z "$1" ]]; then
|
||||
echo "Usage: $0 <version>"
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: ${0} <version>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! gsutil ls gs://kubernetes-release/release/${1}/kubernetes.tar.gz; then
|
||||
echo "Release files don't exist, aborting."
|
||||
exit 2
|
||||
fi
|
||||
KUBE_RELEASE_VERSION="${1-}"
|
||||
|
||||
STABLE_FILE_LOCATION="kubernetes-release/release/stable.txt"
|
||||
KUBE_GCS_MAKE_PUBLIC='y'
|
||||
KUBE_GCS_RELEASE_BUCKET='kubernetes-release'
|
||||
KUBE_GCS_RELEASE_PREFIX="release/${KUBE_RELEASE_VERSION}"
|
||||
KUBE_GCS_PUBLISH_VERSION="${KUBE_RELEASE_VERSION}"
|
||||
|
||||
version_file=$(mktemp -t stable.XXXXXX)
|
||||
KUBE_ROOT="$(dirname "${BASH_SOURCE}")/.."
|
||||
source "${KUBE_ROOT}/build/common.sh"
|
||||
|
||||
echo $1 >> ${version_file}
|
||||
echo "Uploading stable version $1 to google storage"
|
||||
gsutil cp ${version_file} "gs://${STABLE_FILE_LOCATION}"
|
||||
echo "Making it world readable"
|
||||
gsutil acl ch -R -g all:R "gs://${STABLE_FILE_LOCATION}"
|
||||
|
||||
rm ${version_file}
|
||||
|
||||
value=$(curl -s https://storage.googleapis.com/${STABLE_FILE_LOCATION})
|
||||
echo "Validating version file"
|
||||
if [[ "${value}" != "${1}" ]]; then
|
||||
echo "Error validating upload, :${value}: vs expected :${1}:"
|
||||
if "${KUBE_ROOT}/cluster/kubectl.sh" 'version' | grep 'Client' | grep 'dirty'; then
|
||||
echo "!!! Tag at invalid point, or something else is bad. Build is dirty. Don't push this build." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kube::release::gcs::publish_official 'stable'
|
||||
|
|
|
@ -36,21 +36,20 @@ function kube::release::semantic_version() {
|
|||
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
|
||||
LATEST=$(kube::release::semantic_version)
|
||||
|
||||
KUBE_GCS_NO_CACHING=n
|
||||
KUBE_GCS_MAKE_PUBLIC=y
|
||||
KUBE_GCS_UPLOAD_RELEASE=y
|
||||
KUBE_GCS_DELETE_EXISTING=y
|
||||
KUBE_GCS_RELEASE_BUCKET=kubernetes-release
|
||||
KUBE_GCS_NO_CACHING='n'
|
||||
KUBE_GCS_MAKE_PUBLIC='y'
|
||||
KUBE_GCS_UPLOAD_RELEASE='y'
|
||||
KUBE_GCS_DELETE_EXISTING='y'
|
||||
KUBE_GCS_RELEASE_BUCKET='kubernetes-release'
|
||||
KUBE_GCS_RELEASE_PREFIX="ci/${LATEST}"
|
||||
KUBE_GCS_LATEST_FILE="ci/latest.txt"
|
||||
KUBE_GCS_LATEST_CONTENTS=${LATEST}
|
||||
KUBE_GCS_PUBLISH_VERSION="${LATEST}"
|
||||
|
||||
source "$KUBE_ROOT/build/common.sh"
|
||||
|
||||
MAX_ATTEMPTS=3
|
||||
attempt=0
|
||||
while [[ ${attempt} -lt ${MAX_ATTEMPTS} ]]; do
|
||||
kube::release::gcs::release && kube::release::gcs::publish_latest && break || true
|
||||
kube::release::gcs::release && kube::release::gcs::publish_ci && break || true
|
||||
attempt=$((attempt + 1))
|
||||
sleep 5
|
||||
done
|
||||
|
|
|
@ -20,29 +20,28 @@ set -o errexit
|
|||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
KUBE_RELEASE_VERSION=${1-}
|
||||
|
||||
VERSION_REGEX="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$"
|
||||
[[ ${KUBE_RELEASE_VERSION} =~ $VERSION_REGEX ]] || {
|
||||
echo "!!! You must specify the version you are releasing in the form of '$VERSION_REGEX'" >&2
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: ${0} <version>"
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
||||
KUBE_GCS_NO_CACHING=n
|
||||
KUBE_GCS_MAKE_PUBLIC=y
|
||||
KUBE_GCS_UPLOAD_RELEASE=y
|
||||
KUBE_GCS_RELEASE_BUCKET=kubernetes-release
|
||||
KUBE_GCS_RELEASE_PREFIX=release/${KUBE_RELEASE_VERSION}
|
||||
KUBE_GCS_LATEST_FILE="release/latest.txt"
|
||||
KUBE_GCS_LATEST_CONTENTS=${KUBE_RELEASE_VERSION}
|
||||
KUBE_RELEASE_VERSION="${1-}"
|
||||
|
||||
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
|
||||
source "$KUBE_ROOT/build/common.sh"
|
||||
KUBE_GCS_NO_CACHING='n'
|
||||
KUBE_GCS_MAKE_PUBLIC='y'
|
||||
KUBE_GCS_UPLOAD_RELEASE='y'
|
||||
KUBE_GCS_RELEASE_BUCKET='kubernetes-release'
|
||||
KUBE_GCS_RELEASE_PREFIX="release/${KUBE_RELEASE_VERSION}"
|
||||
KUBE_GCS_PUBLISH_VERSION="${KUBE_RELEASE_VERSION}"
|
||||
|
||||
if ${KUBE_ROOT}/cluster/kubectl.sh version | grep Client | grep dirty; then
|
||||
KUBE_ROOT="$(dirname "${BASH_SOURCE}")/.."
|
||||
source "${KUBE_ROOT}/build/common.sh"
|
||||
|
||||
if "${KUBE_ROOT}/cluster/kubectl.sh" 'version' | grep 'Client' | grep 'dirty'; then
|
||||
echo "!!! Tag at invalid point, or something else is bad. Build is dirty. Don't push this build." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kube::release::parse_and_validate_release_version "${KUBE_RELEASE_VERSION}"
|
||||
kube::release::gcs::release
|
||||
kube::release::gcs::publish_latest_official
|
||||
kube::release::gcs::publish_official 'latest'
|
||||
|
|
Loading…
Reference in New Issue