|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +set -e |
| 4 | +set -o pipefail |
| 5 | + |
| 6 | +# https://github.com/Azure/login?tab=readme-ov-file#azure-login-action |
| 7 | +export AZURE_CORE_OUTPUT=none |
| 8 | + |
| 9 | +checkArguments() { |
| 10 | + if [ $# -lt 2 ]; then |
| 11 | + echo "Error: You need to specify the cloud image to upload and the Kairos version (to tag resources)." |
| 12 | + echo "Usage: $0 <cloud-image> <kairos-version>" |
| 13 | + exit 1 |
| 14 | + fi |
| 15 | + |
| 16 | + local file="$1" |
| 17 | + |
| 18 | + if [ ! -f "$file" ]; then |
| 19 | + echo "Error: File '$file' does not exist." |
| 20 | + exit 1 |
| 21 | + fi |
| 22 | +} |
| 23 | + |
| 24 | +checkEnvVars() { |
| 25 | + if [ -z "$AZURE_RESOURCE_GROUP" ] || [ -z "$AZURE_STORAGE_ACCOUNT" ] || [ -z "$AZURE_CONTAINER_NAME" ]; then |
| 26 | + echo "Error: AZURE_RESOURCE_GROUP, AZURE_STORAGE_ACCOUNT and AZURE_CONTAINER_NAME environment variables must be set." |
| 27 | + exit 1 |
| 28 | + fi |
| 29 | +} |
| 30 | + |
| 31 | +LOCAL_VHD_PATH=$(readlink -f "$1") |
| 32 | +NAME=$(basename "$LOCAL_VHD_PATH" | sed 's/\.raw\.vhd$//') # just the file name without extension or path |
| 33 | +VERSION=$2 |
| 34 | + |
| 35 | +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| 36 | +# shellcheck source=/dev/null |
| 37 | +source "$SCRIPT_DIR/cleanup-old-images-azure.sh" |
| 38 | + |
| 39 | +checkArguments "$@" |
| 40 | +checkEnvVars |
| 41 | + |
| 42 | +# === CHECK AZURE LOGIN === |
| 43 | +az account show >/dev/null 2>&1 || { echo "Please run 'az login' first."; exit 1; } |
| 44 | + |
| 45 | +# === GET STORAGE ACCOUNT REGION === |
| 46 | +echo "Fetching storage account region..." |
| 47 | +STORAGE_REGION=$(az storage account show --name "$AZURE_STORAGE_ACCOUNT" --query "primaryLocation" --output tsv) |
| 48 | +echo "Storage account is in region: $STORAGE_REGION" |
| 49 | + |
| 50 | +# === GET STORAGE ACCOUNT KEY === |
| 51 | +echo "Fetching storage account key..." |
| 52 | +STORAGE_KEY=$(az storage account keys list --account-name "$AZURE_STORAGE_ACCOUNT" --query "[0].value" --output tsv) |
| 53 | + |
| 54 | +echo "Uploading VHD file ($LOCAL_VHD_PATH) to Azure Storage..." |
| 55 | +az storage blob upload --account-name "$AZURE_STORAGE_ACCOUNT" --container-name "$AZURE_CONTAINER_NAME" --type page \ |
| 56 | + --name "$NAME" --file "$LOCAL_VHD_PATH" --auth-mode key --account-key "$STORAGE_KEY" --overwrite true |
| 57 | + |
| 58 | +echo "Retrieving uploaded VHD URL..." |
| 59 | +VHD_URL=$(az storage blob url --account-name "$AZURE_STORAGE_ACCOUNT" --container-name "$AZURE_CONTAINER_NAME" --name "$NAME" --output tsv) |
| 60 | +echo "VHD uploaded successfully: $VHD_URL" |
| 61 | + |
| 62 | +# === Get file size in bytes === |
| 63 | +VHD_SIZE_BYTES=$(stat -c %s "$LOCAL_VHD_PATH") |
| 64 | + |
| 65 | +# === Convert to GB and round up === |
| 66 | +VHD_SIZE_GB=$(( (VHD_SIZE_BYTES + 1073741823) / 1073741824 )) |
| 67 | +echo "Calculated disk size: $VHD_SIZE_GB GB" |
| 68 | + |
| 69 | +echo "Creating a managed disk" |
| 70 | +az disk create \ |
| 71 | + --resource-group "$AZURE_RESOURCE_GROUP" \ |
| 72 | + --name "$NAME" \ |
| 73 | + --source "$VHD_URL" \ |
| 74 | + --os-type Linux \ |
| 75 | + --sku Premium_LRS \ |
| 76 | + --size-gb "$VHD_SIZE_GB" \ |
| 77 | + --hyper-v-generation V2 |
| 78 | + |
| 79 | +echo "Getting the ID of the managed disk" |
| 80 | +DISK_ID=$(az disk show \ |
| 81 | + --resource-group "$AZURE_RESOURCE_GROUP" \ |
| 82 | + --name "$NAME" \ |
| 83 | + --query "id" \ |
| 84 | + --output tsv) |
| 85 | + |
| 86 | +# === CREATE AZURE IMAGE IN SAME REGION AS STORAGE ACCOUNT === |
| 87 | +echo "Creating Azure image ($NAME) from VHD in region: $STORAGE_REGION..." |
| 88 | +az image create \ |
| 89 | + --resource-group "$AZURE_RESOURCE_GROUP" \ |
| 90 | + --name "$NAME" \ |
| 91 | + --os-type "Linux" \ |
| 92 | + --source "$DISK_ID" \ |
| 93 | + --hyper-v-generation "V2" \ |
| 94 | + --location "$STORAGE_REGION" |
| 95 | +echo "Image created successfully: $NAME" |
| 96 | + |
| 97 | +echo "Getting the image ID" |
| 98 | +IMAGE_ID=$(az image show \ |
| 99 | + --resource-group "$AZURE_RESOURCE_GROUP" \ |
| 100 | + --name "$NAME" \ |
| 101 | + --query "id" \ |
| 102 | + --output tsv) |
| 103 | + |
| 104 | +# echo "Creating a Shared Image Gallery (one-off)" |
| 105 | +# # https://learn.microsoft.com/en-us/azure/virtual-machines/create-gallery?tabs=portal%2Cportaldirect%2Ccli2 |
| 106 | +# # TODO: Link to some EULA? |
| 107 | +# az sig create \ |
| 108 | +# --gallery-name kairos.io \ |
| 109 | +# --permissions community \ |
| 110 | +# --resource-group "$AZURE_RESOURCE_GROUP" \ |
| 111 | +# --location "$STORAGE_REGION" \ |
| 112 | +# --publisher-uri kairos.io \ |
| 113 | +# --publisher-email [email protected] \ |
| 114 | +# --eula https://github.com/kairos-io/kairos/?tab=Apache-2.0-1-ov-file#readme \ |
| 115 | +# --public-name-prefix kairos |
| 116 | + |
| 117 | +# echo "Creating an image definition (one-off)" |
| 118 | +# az sig image-definition create --resource-group "$AZURE_RESOURCE_GROUP" --gallery-name kairos.io \ |
| 119 | +# --gallery-image-definition kairos --publisher kairos.io --offer kairos --sku kairos \ |
| 120 | +# --hyper-v-generation "V2" --os-type Linux |
| 121 | +# |
| 122 | +# echo "Making the gallery public (one-off)" |
| 123 | +# az sig share enable-community --resource-group "$AZURE_RESOURCE_GROUP" --gallery-name kairos.io |
| 124 | + |
| 125 | +echo "Creating a Shared image version" |
| 126 | +az sig image-version create --resource-group "$AZURE_RESOURCE_GROUP" --gallery-name kairos.io \ |
| 127 | + --gallery-image-definition "kairos" --gallery-image-version "${VERSION#v}" \ |
| 128 | + --managed-image "$IMAGE_ID" --location "$STORAGE_REGION" |
| 129 | + |
| 130 | +echo "Deleting the managed disk" |
| 131 | +az disk delete \ |
| 132 | + --resource-group "$AZURE_RESOURCE_GROUP" \ |
| 133 | + --name "$NAME" \ |
| 134 | + --yes |
| 135 | + |
| 136 | +echo "Deleting managed image (no longer needed)" |
| 137 | +az image delete \ |
| 138 | + --resource-group "$AZURE_RESOURCE_GROUP" \ |
| 139 | + --name "$NAME" |
| 140 | + |
| 141 | +echo "Deleting uploaded VHD blob from Azure Storage..." |
| 142 | +az storage blob delete \ |
| 143 | + --account-name "$AZURE_STORAGE_ACCOUNT" \ |
| 144 | + --container-name "$AZURE_CONTAINER_NAME" \ |
| 145 | + --name "$NAME" \ |
| 146 | + --auth-mode key \ |
| 147 | + --account-key "$STORAGE_KEY" |
0 commit comments