Skip to content
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 101 additions & 41 deletions .pipelines/scripts/windows_build_vhd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ set +x
# * SKIPVALIDATEREOFFERUPDATE - is always set to True
# * BUILD_DATE


# First we validate the branch. DRY_RUN is only allowed to be false on release branches - which are of the form
# windows/vYYYYMMDD. If we're on the release branch then we also override SIG_FOR_PRODUCTION, because this is a production build.
# for dry runs, we set SIG_FOR_PRODUCTION to false.
Expand All @@ -34,34 +33,34 @@ echo "Checking SourceBranch: ${BRANCH}"

# Check if IS_RELEASE_PIPELINE is already set in the environment
if [ -z "${IS_RELEASE_PIPELINE:-}" ]; then
if echo "${BRANCH}" | grep -E '^refs/heads/windows/v[[:digit:]]{8}$' > /dev/null; then
echo "The branch ${BRANCH} is a release branch. Setting IS_RELEASE_PIPELINE to True."
export IS_RELEASE_PIPELINE="True"
echo "##vso[task.setvariable variable=IS_RELEASE_PIPELINE]True"
else
echo "The branch ${BRANCH} is not a release branch. Setting IS_RELEASE_PIPELINE to False."
export IS_RELEASE_PIPELINE="False"
echo "##vso[task.setvariable variable=IS_RELEASE_PIPELINE]False"
fi
if echo "${BRANCH}" | grep -E '^refs/heads/windows/v[[:digit:]]{8}$' >/dev/null; then
echo "The branch ${BRANCH} is a release branch. Setting IS_RELEASE_PIPELINE to True."
export IS_RELEASE_PIPELINE="True"
echo "##vso[task.setvariable variable=IS_RELEASE_PIPELINE]True"
else
echo "The branch ${BRANCH} is not a release branch. Setting IS_RELEASE_PIPELINE to False."
export IS_RELEASE_PIPELINE="False"
echo "##vso[task.setvariable variable=IS_RELEASE_PIPELINE]False"
fi
fi

if [ "${IS_RELEASE_PIPELINE}" = "True" ]; then
if [ "${DRY_RUN}" = "True" ]; then
echo "This is a test build triggered from the release pipeline"
else
echo "This is a release build triggered from the release pipeline. DRY_RUN=${DRY_RUN}"

if ! (echo "${BRANCH}" | grep -E '^refs/heads/windows/v[[:digit:]]{8}$' > /dev/null); then
echo "The branch ${BRANCH} is not release branch. Please use the release branch. Release branch name format: windows/vYYYYMMDD."
exit 1
if [ "${DRY_RUN}" = "True" ]; then
echo "This is a test build triggered from the release pipeline"
else
echo "This is a release build triggered from the release pipeline. DRY_RUN=${DRY_RUN}"

if ! (echo "${BRANCH}" | grep -E '^refs/heads/windows/v[[:digit:]]{8}$' >/dev/null); then
echo "The branch ${BRANCH} is not release branch. Please use the release branch. Release branch name format: windows/vYYYYMMDD."
exit 1
fi
echo "##vso[task.setvariable variable=SIG_FOR_PRODUCTION]True"
fi
echo "##vso[task.setvariable variable=SIG_FOR_PRODUCTION]True"
fi
else
echo "This is a test build triggered from the test pipeline"
export DRY_RUN=True
echo "##vso[task.setvariable variable=DRY_RUN]$DRY_RUN";
echo "##vso[task.setvariable variable=SIG_FOR_PRODUCTION]False"
echo "This is a test build triggered from the test pipeline"
export DRY_RUN=True
echo "##vso[task.setvariable variable=DRY_RUN]$DRY_RUN"
echo "##vso[task.setvariable variable=SIG_FOR_PRODUCTION]False"
fi

export MODE="windowsVhdMode"
Expand All @@ -74,32 +73,33 @@ echo "Original SIG_IMAGE_VERSION: ${SIG_IMAGE_VERSION:-}"

# -n is "not empty"
if [ -n "${SIG_GALLERY_NAME:-}" ] && [ -n "${SIG_IMAGE_NAME_PREFIX:-}" ] && [ -n "${SIG_IMAGE_VERSION:-}" ]; then
echo "All of Name, Prefix, and Version have been set"
export SIG_IMAGE_NAME="${SIG_IMAGE_NAME_PREFIX}-${WINDOWS_SKU}"
echo "All of Name, Prefix, and Version have been set"
export SIG_IMAGE_NAME="${SIG_IMAGE_NAME_PREFIX}-${WINDOWS_SKU}"
else
echo "At least on of the name, prefix or version are empty. Overwriting all values. "
export SIG_IMAGE_VERSION="$(date +"%y%m%d").$(date +"%H%M%S").$RANDOM"
export SIG_IMAGE_NAME="windows-${WINDOWS_SKU}"
export SIG_GALLERY_NAME="PackerSigGalleryEastUS"
echo "At least on of the name, prefix or version are empty. Overwriting all values. "
export SIG_IMAGE_VERSION="$(date +"%y%m%d").$(date +"%H%M%S").$RANDOM"
export SIG_IMAGE_NAME="windows-${WINDOWS_SKU}"
export SIG_GALLERY_NAME="PackerSigGalleryEastUS"

export WS_SKU=$(echo $WINDOWS_SKU | tr '-' '_')
export WS_SKU=$(echo $WINDOWS_SKU | tr '-' '_')
fi

if [ "${USE_RELEASE_DATE:-}" = "False" ]; then
echo "use current date as build date"; BUILD_DATE=$(date +"%y%m%d")
echo "use current date as build date"
BUILD_DATE=$(date +"%y%m%d")
else
echo "use release date as build date"
echo "${RELEASE_DATE:-}" | grep -E '[[:digit:]]{6}'
if (( $? != 0 )); then
echo "The release date ${RELEASE_DATE} is not valid date. Release date format: YYMMDD."
exit 1
fi
export BUILD_DATE=${RELEASE_DATE}
echo "use release date as build date"
echo "${RELEASE_DATE:-}" | grep -E '[[:digit:]]{6}'
if (($? != 0)); then
echo "The release date ${RELEASE_DATE} is not valid date. Release date format: YYMMDD."
exit 1
fi
export BUILD_DATE=${RELEASE_DATE}
Comment on lines +91 to +97
fi
echo "Default BUILD_DATE is $BUILD_DATE"
if [ -n "${CUSTOM_BUILD_DATE:-}" ]; then
echo "set BUILD_DATE to ${CUSTOM_BUILD_DATE}"
export BUILD_DATE=${CUSTOM_BUILD_DATE}
echo "set BUILD_DATE to ${CUSTOM_BUILD_DATE}"
export BUILD_DATE=${CUSTOM_BUILD_DATE}
fi

echo "Modified SIG_IMAGE_VERSION: ${SIG_IMAGE_VERSION}"
Expand All @@ -120,6 +120,66 @@ export MANAGED_SIG_ID="$(cat packer-output | grep -a "ManagedImageSharedImageGal
echo "Found OS_DISK_URI: ${OS_DISK_URI}"
echo "Found MANAGED_SIG_ID: ${MANAGED_SIG_ID}"

# Break gallery lineage if the build was sourced from a shared gallery.
# Sometimes Azure requires AutomaticOSUpgrade on VMSS created from images with gallery lineage.
# Re-creating the SIG image version from a managed disk severs that association.
sig_source_gallery_name=$(jq -r ".WindowsBaseVersions.\"${WINDOWS_SKU}\".sig_source_gallery_name // empty" <vhdbuilder/packer/windows/windows_settings.json)
if [ -n "${sig_source_gallery_name}" ] && [ -n "${MANAGED_SIG_ID}" ]; then
echo "Build sourced from gallery '${sig_source_gallery_name}' — breaking gallery lineage on SIG image version"
LINEAGE_DISK_NAME="lineage-break-${SIG_IMAGE_NAME}-$(date +%s)"
LOCATION="${AZURE_LOCATION}"

echo "Creating managed disk from SIG image version..."
az disk create \
--resource-group "${AZURE_RESOURCE_GROUP_NAME}" \
--name "${LINEAGE_DISK_NAME}" \
--gallery-image-reference "${MANAGED_SIG_ID}" \
--location "${LOCATION}" \
--hyper-v-generation "${HYPERV_GENERATION:-V2}" \
--os-type Windows \
-o none

DISK_ID="/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${AZURE_RESOURCE_GROUP_NAME}/providers/Microsoft.Compute/disks/${LINEAGE_DISK_NAME}"
echo "Created disk: ${DISK_ID}"

echo "Deleting original SIG image version..."
az sig image-version delete \
--resource-group "${AZURE_RESOURCE_GROUP_NAME}" \
--gallery-name "${SIG_GALLERY_NAME}" \
--gallery-image-definition "${SIG_IMAGE_NAME}" \
--gallery-image-version "${SIG_IMAGE_VERSION}"

echo "Waiting for deletion to propagate..."
az sig image-version wait \
--resource-group "${AZURE_RESOURCE_GROUP_NAME}" \
--gallery-name "${SIG_GALLERY_NAME}" \
--gallery-image-definition "${SIG_IMAGE_NAME}" \
--gallery-image-version "${SIG_IMAGE_VERSION}" \
--deleted 2>/dev/null || sleep 30

echo "Re-creating SIG image version from managed disk (no gallery lineage)..."
az sig image-version create \
--resource-group "${AZURE_RESOURCE_GROUP_NAME}" \
--gallery-name "${SIG_GALLERY_NAME}" \
--gallery-image-definition "${SIG_IMAGE_NAME}" \
--gallery-image-version "${SIG_IMAGE_VERSION}" \
--os-snapshot "${DISK_ID}" \
--location "${LOCATION}" \
--replica-count 1 \
-o none

NEW_SIG_ID="/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${AZURE_RESOURCE_GROUP_NAME}/providers/Microsoft.Compute/galleries/${SIG_GALLERY_NAME}/images/${SIG_IMAGE_NAME}/versions/${SIG_IMAGE_VERSION}"
echo "New SIG image version (lineage-free): ${NEW_SIG_ID}"
export MANAGED_SIG_ID="${NEW_SIG_ID}"

echo "Cleaning up temporary disk..."
az disk delete --resource-group "${AZURE_RESOURCE_GROUP_NAME}" --name "${LINEAGE_DISK_NAME}" --yes -o none

echo "Gallery lineage successfully broken"
else
echo "Build was not sourced from a gallery — no lineage breaking needed"
fi

# if bash is echoing the commands, then ADO processes both the echo of the command to set the variable and the command itself.
# This causes super odd behavior in ADO.
set +x
Expand Down
Loading