diff --git a/az_sig_publish b/az_sig_publish new file mode 100755 index 00000000000..46a71437fb3 --- /dev/null +++ b/az_sig_publish @@ -0,0 +1,194 @@ +#!/bin/bash + +# Copyright (c) 2024-2025 The Flatcar Maintainers. +# Use of this source code is governed by the Apache 2.0 license. + +# Script to publish Flatcar images to Azure Shared Galley Images + +# Set defaults for environment variables (allow override via --env or directly in script) +AZURE_SUBSCRIPTION_ID="${AZURE_SUBSCRIPTION_ID:-3be1ff13-7eef-458c-b1ef-97a01af1b2f4}" +IMAGE_PUBLISHER_NAME="${IMAGE_PUBLISHER_NAME:-flatcar}" +AZURE_LOCATION="${AZURE_LOCATION:-westeurope}" +SIG_RESOURCE_GROUP="${STAGING_SIG_RESOURCE_GROUP:-sayan-flatcar-image-gallery-staging}" + +FLATCAR_GALLERY_NAME="${FLATCAR_STAGING_GALLERY_NAME:-sayan_flatcar_staging}" +FLATCAR_IMAGE_NAME="${FLATCAR_IMAGE_NAME:-"flatcar-${FLATCAR_CHANNEL}-${FLATCAR_ARCH}"}" +FLATCAR_CHANNEL="${FLATCAR_CHANNEL:-developer}" +FLATCAR_VERSION="${FLATCAR_VERSION:-3374.2.1}" +FLATCAR_ARCH="${FLATCAR_ARCH:-amd64}" +FLATCAR_LOCAL_FILE_NAME="${FLATCAR_LOCAL_FILE_NAME:-flatcar_production_azure_image.vhd}" +FLATCAR_LOCAL_FILE_URL="${FLATCAR_LOCAL_FILE_URL:-}" +FLATCAR_IMAGE_OFFER="${FLATCAR_IMAGE_OFFER:-${FLATCAR_CHANNEL}}" + +FLATCAR_GALLERY_IMAGE_NAME="${FLATCAR_GALLERY_IMAGE_NAME:-"flatcar-${FLATCAR_CHANNEL}-${FLATCAR_ARCH}"}" +FLATCAR_GALLERY_VERSION="${FLATCAR_GALLERY_VERSION:-3374.2.9999}" + +VHD_STORAGE_ACCOUNT_NAME="${VHD_STORAGE_ACCOUNT_NAME:-flatcar}" +VHD_STORAGE_RESOURCE_GROUP_NAME="${VHD_STORAGE_RESOURCE_GROUP_NAME:-flatcar}" +VHD_STORAGE_CONTAINER_NAME="${VHD_STORAGE_CONTAINER_NAME:-developer}" +BLACKLISTED_TARGET_REGIONS="${BLACKLISTED_TARGET_REGIONS:-polandcentral australiacentral2 brazilsoutheast centraluseuap eastus2euap eastusstg francesouth germanynorth jioindiacentral norwaywest southafricawest switzerlandwest uaecentral brazilus southcentralusstg}" +TARGET_REGIONS="${TARGET_REGIONS:-}" + +function publish-flatcar-sig-image-version-from-vhd() { + login + + get-target-regions + ensure-vhd-uri-exists + ensure-resource-group + ensure-sig + IMAGE_OFFER="${FLATCAR_IMAGE_OFFER}" IMAGE_PUBLISHER="${IMAGE_PUBLISHER_NAME}" ensure-image-definition + + STORAGE_ACCOUNT_ID="/subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${VHD_STORAGE_RESOURCE_GROUP_NAME}/providers/Microsoft.Storage/storageAccounts/${VHD_STORAGE_ACCOUNT_NAME}" + VHD_URI="https://${VHD_STORAGE_ACCOUNT_NAME}.blob.core.windows.net/${VHD_STORAGE_CONTAINER_NAME}/flatcar-linux-${FLATCAR_GALLERY_VERSION}-${FLATCAR_CHANNEL}-${FLATCAR_ARCH}.vhd" + + if ! sig-image-version-exists; then + echo "Creating SIG image version ${FLATCAR_GALLERY_VERSION}" + az sig image-version create \ + --resource-group "${SIG_RESOURCE_GROUP}" \ + --gallery-name "${FLATCAR_GALLERY_NAME}" \ + --gallery-image-definition "${FLATCAR_GALLERY_IMAGE_NAME}" \ + --gallery-image-version "${FLATCAR_GALLERY_VERSION}" \ + --os-vhd-storage-account "${STORAGE_ACCOUNT_ID}" \ + --os-vhd-uri "${VHD_URI}" + else + echo "SIG image version ${FLATCAR_GALLERY_VERSION} already exists, skipping creation" + fi + + sig-image-version-update-regions +} + +function get-target-regions() { + if [[ -n "${TARGET_REGIONS:-}" ]]; then + return 0 + fi + + echo "Fetching target regions" + TARGET_REGIONS=$(az account list-locations -o json | jq -r '.[] | select( .metadata.regionType != "Logical" ) | .name' | sort | grep -v -E "(${BLACKLISTED_TARGET_REGIONS// /|})" | tr '\n' ' ') +} + +function ensure-vhd-uri-exists() { + EXISTS=$(az storage blob exists \ + --account-name "${VHD_STORAGE_ACCOUNT_NAME}" \ + --container-name "${VHD_STORAGE_CONTAINER_NAME}" \ + --auth-mode login \ + --name "flatcar-linux-${FLATCAR_GALLERY_VERSION}-${FLATCAR_CHANNEL}-${FLATCAR_ARCH}.vhd" \ + --query "exists" -o tsv) + + if [[ "${EXISTS}" = "true" ]]; then + echo "flatcar-linux-${FLATCAR_GALLERY_VERSION}-${FLATCAR_CHANNEL}-${FLATCAR_ARCH} Blob already exists. Skipping upload." + return 0 + fi + + if [[ -z "${FLATCAR_LOCAL_FILE_URL:-}" ]]; then + echo "FLATCAR_LOCAL_FILE_URL variable is empty. Please set." + exit 1 + fi + + echo "Blob doesn't exist. Downloading flatcar-linux-${FLATCAR_GALLERY_VERSION}-${FLATCAR_CHANNEL}-${FLATCAR_ARCH}" + # Download the VHD file (only if blob doesn't exist) + echo "Downloading ${FLATCAR_LOCAL_FILE_URL}..." + if ! curl -L -o "/data/${FLATCAR_LOCAL_FILE_NAME}.bz2" "${FLATCAR_LOCAL_FILE_URL}"; then + echo "ERROR: Download failed. Exiting" + exit 1 + fi + + # Decompress the file + echo "Decompressing ${FLATCAR_LOCAL_FILE_NAME}.bz2" + if ! bzip2 -d "/data/${FLATCAR_LOCAL_FILE_NAME}.bz2"; then + echo "ERROR: Decompression failed. Exiting" + exit 1 + fi + + echo "Uploading blob - flatcar-linux-${FLATCAR_GALLERY_VERSION}-${FLATCAR_CHANNEL}-${FLATCAR_ARCH}" + if ! az storage blob upload \ + --account-name "${VHD_STORAGE_ACCOUNT_NAME}" \ + --auth-mode login \ + --container "${VHD_STORAGE_CONTAINER_NAME}" \ + --name "flatcar-linux-${FLATCAR_GALLERY_VERSION}-${FLATCAR_CHANNEL}-${FLATCAR_ARCH}.vhd" \ + --file "/data/${FLATCAR_LOCAL_FILE_NAME}"; then + echo "ERROR: Blob upload failed. Exiting" + exit 1 + fi +} + +function sig-image-version-exists() { + if ! az sig image-version show \ + --gallery-image-definition "${FLATCAR_GALLERY_IMAGE_NAME}" \ + --gallery-image-version "${FLATCAR_GALLERY_VERSION}" \ + --gallery-name "${FLATCAR_GALLERY_NAME}" \ + --resource-group "${SIG_RESOURCE_GROUP}" \ + --output none \ + --only-show-errors; then + echo "SIG image ${SIG_RESOURCE_GROUP}/${FLATCAR_GALLERY_NAME}/${FLATCAR_GALLERY_VERSION}/${FLATCAR_GALLERY_IMAGE_NAME} does not exist" + return 1 + fi + + echo "SIG image ${SIG_RESOURCE_GROUP}/${FLATCAR_GALLERY_NAME}/${FLATCAR_GALLERY_VERSION}/${FLATCAR_GALLERY_IMAGE_NAME} already exists" + return 0 +} + +function sig-image-version-update-regions() { + echo "DEBUG: Source location: ${AZURE_LOCATION}" + echo "DEBUG: Target regions: ${TARGET_REGIONS}" + az sig image-version update \ + --resource-group "${SIG_RESOURCE_GROUP}" \ + --gallery-name "${FLATCAR_GALLERY_NAME}" \ + --gallery-image-definition "${FLATCAR_GALLERY_IMAGE_NAME}" \ + --gallery-image-version "${FLATCAR_GALLERY_VERSION}" \ + --target-regions ${TARGET_REGIONS} +} + +function ensure-image-definition() { + local architecture + case "${FLATCAR_ARCH}" in + amd64) architecture=x64 ;; + arm64) architecture=Arm64 ;; + *) echo "Unsupported architecture: '${FLATCAR_ARCH}'"; exit 1 ;; + esac + + az sig image-definition create \ + --gallery-image-definition "${FLATCAR_GALLERY_IMAGE_NAME}" \ + --gallery-name "${FLATCAR_GALLERY_NAME}" \ + --offer "${FLATCAR_IMAGE_OFFER}" \ + --os-type Linux \ + --publisher "${IMAGE_PUBLISHER_NAME}" \ + --resource-group "${SIG_RESOURCE_GROUP}" \ + --sku "${FLATCAR_GALLERY_IMAGE_NAME}" \ + --architecture "${architecture}" \ + --hyper-v-generation V2 +} + +function ensure-sig() { + az sig create \ + --gallery-name "${FLATCAR_GALLERY_NAME}" \ + --resource-group "${SIG_RESOURCE_GROUP}" +} + +function ensure-resource-group() { + if ! az group show -n "${SIG_RESOURCE_GROUP}" -o none 2>/dev/null; then + az group create -n "${SIG_RESOURCE_GROUP}" -l "${AZURE_LOCATION}" + fi +} + +function login() { + echo "Authenticating to Azure using managed identity" + AZURE_LOGIN_ERR_FILE=$(mktemp) + trap 'rm -f "$AZURE_LOGIN_ERR_FILE"' EXIT + + if ! az login --identity >/dev/null 2>"$AZURE_LOGIN_ERR_FILE"; then + echo "Azure login failed. Error:" >&2 + cat "$AZURE_LOGIN_ERR_FILE" >&2 + exit 1 + fi + + echo "Azure login successful." + echo "Setting active subscription to ${AZURE_SUBSCRIPTION_ID}" + if ! az account set -s "${AZURE_SUBSCRIPTION_ID}" >/dev/null 2>&1; then + echo "Failed to set Azure subscription." + exit 1 + fi + echo "Subscription set." +} + +# Entrypoint +publish-flatcar-sig-image-version-from-vhd diff --git a/ci-automation/az_sig_publish.sh b/ci-automation/az_sig_publish.sh new file mode 100644 index 00000000000..5f8a0fb6eec --- /dev/null +++ b/ci-automation/az_sig_publish.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +function az_sig_publish() { + # Run a subshell, so the traps, environment changes and global + # variables are not spilled into the caller. + ( + set -euo pipefail + + _az_sig_publish_impl "${@}" + ) +} + +# -- +function _az_sig_publish_impl() { + local arch="$1" + local push_non_nightly_builds="${PUSH_NON_NIGHTLY_BUILDS:-}" + + source sdk_container/.repo/manifests/version.txt + source sdk_lib/sdk_container_common.sh + local vernum="$(get_git_version)" + local channel="$(get_git_channel)" + + source ci-automation/ci_automation_common.sh + source ci-automation/gpg_setup.sh + + if { [[ "$vernum" != *"nightly"* ]] || [[ "$channel" != "developer" ]] } && [[ "$push_non_nightly_builds" != "true" ]]; then + echo "INFO: Version '$vernum' is not a nightly build, or channel is not developer and PUSH_NON_NIGHTLY_BUILDS is not enabled. Skipping publish step." + exit 0 + fi + + FLATCAR_GALLERY_IMAGE_NAME="flatcar-${channel}-${arch}" + version=$(echo "${vernum}" | cut -d '-' -f2) + + local date="" + if [[ "$vernum" == *nightly* ]]; then + date=$(echo "${vernum}" | cut -d '-' -f4) + FLATCAR_GALLERY_VERSION="${version%.*}.${date:2}" + else + date=$(date +'%y%m%d') + FLATCAR_GALLERY_VERSION="${version%.*}.${date}" + fi + + TMP_DIR=$(mktemp -d /var/tmp/flatcar.XXXXXX) + # Cleanup on exit (success or failure) + trap 'echo "Cleaning up..."; rm -rf "${TMP_DIR}"' EXIT + + FLATCAR_LOCAL_FILE_URL="https://bincache.flatcar-linux.net/images/amd64/${FLATCAR_VERSION}/flatcar_production_azure_image.vhd.bz2" + + # -- Clean up -- + echo "FLATCAR_GALLERY_IMAGE_NAME ${FLATCAR_GALLERY_IMAGE_NAME}" + echo "FLATCAR_GALLERY_VERSION ${FLATCAR_GALLERY_VERSION}" + echo "Channel ${channel}" + export VHD_STORAGE_ACCOUNT_NAME="sayantestsbwesteurope" + export VHD_STORAGE_CONTAINER_NAME="vhd" + # -- end clean up -- + + docker run --pull always --rm --net host \ + --env VHD_STORAGE_ACCOUNT_NAME="${VHD_STORAGE_ACCOUNT_NAME}" \ + --env VHD_STORAGE_CONTAINER_NAME="${VHD_STORAGE_CONTAINER_NAME}" \ + --env FLATCAR_ARCH="${arch}" \ + --env FLATCAR_CHANNEL="${channel}" \ + --env FLATCAR_GALLERY_VERSION="${FLATCAR_GALLERY_VERSION}" \ + --env FLATCAR_GALLERY_IMAGE_NAME="${FLATCAR_GALLERY_IMAGE_NAME}" \ + --env FLATCAR_LOCAL_FILE_URL="${FLATCAR_LOCAL_FILE_URL}" \ + -v "$PWD":/work \ + -v "${TMP_DIR}":/data/ \ + -w /work \ + mcr.microsoft.com/azure-cli \ + /work/az_sig_publish +} +# -- diff --git a/sdk_container/.repo/manifests/version.txt b/sdk_container/.repo/manifests/version.txt index fa984ccd4fa..c691c79e1b2 100644 --- a/sdk_container/.repo/manifests/version.txt +++ b/sdk_container/.repo/manifests/version.txt @@ -1,4 +1,4 @@ -FLATCAR_VERSION=4379.0.0+nightly-20250627-2100 -FLATCAR_VERSION_ID=4379.0.0 -FLATCAR_BUILD_ID="nightly-20250627-2100" +FLATCAR_VERSION=9999.9.9+sayan-publish-nighlies-sig +FLATCAR_VERSION_ID=9999.9.9 +FLATCAR_BUILD_ID="sayan-publish-nighlies-sig" FLATCAR_SDK_VERSION=4379.0.0+nightly-20250627-2100