From 6935a6398f56b820faa76ed718f484fe15dc9a97 Mon Sep 17 00:00:00 2001 From: Gyokhan Kochmarla Date: Sun, 14 Dec 2025 12:05:56 +0100 Subject: [PATCH] feat(templates): add amazonlinux-2023 distro This commit adds a simple template for the Amazon Linux 2023 operating system's 2025-12-08 version. The OS is scheduled to release every two weeks, therefore, a new script called hack/update-template-amazonlinux.sh is added next to the other template updater scripts. Find the latest images here: cdn.amazonlinux.com/al2023/os-images/latest/ This patch: - Adds amazonlinux-2023 template with 2025-12-08 release by default (fallback). - Resolves mount issues on AL2023 with host OS. - Introduces a script on VM init where it updates the system to latest release. - Adds update-template-amazonlinux.sh script to help maintainers automatically update the verison. Signed-off-by: Gyokhan Kochmarla --- hack/update-template-amazonlinux.sh | 190 ++++++++++++++++++ hack/update-template.sh | 2 + .../boot/04-amazonlinux-virtiofs.sh | 29 +++ templates/_images/amazonlinux-2023.yaml | 7 + templates/amazonlinux-2023.yaml | 15 ++ templates/amazonlinux.yaml | 1 + 6 files changed, 244 insertions(+) create mode 100755 hack/update-template-amazonlinux.sh create mode 100644 pkg/cidata/cidata.TEMPLATE.d/boot/04-amazonlinux-virtiofs.sh create mode 100644 templates/_images/amazonlinux-2023.yaml create mode 100644 templates/amazonlinux-2023.yaml create mode 120000 templates/amazonlinux.yaml diff --git a/hack/update-template-amazonlinux.sh b/hack/update-template-amazonlinux.sh new file mode 100755 index 00000000000..486e62fca80 --- /dev/null +++ b/hack/update-template-amazonlinux.sh @@ -0,0 +1,190 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: Copyright The Lima Authors +# SPDX-License-Identifier: Apache-2.0 + +set -eu -o pipefail + +# Functions in this script assume error handling with 'set -e'. +# To ensure 'set -e' works correctly: +# - Use 'set +e' before assignments and '$(set -e; )' to capture output without exiting on errors. +# - Avoid calling functions directly in conditions to prevent disabling 'set -e'. +# - Use 'shopt -s inherit_errexit' (Bash 4.4+) to avoid repeated 'set -e' in all '$(...)'. +shopt -s inherit_errexit || error_exit "inherit_errexit not supported. Please use bash 4.4 or later." + +function amazonlinux_print_help() { + cat <... + +Description: + This script updates the Amazon Linux 2023 image location in the specified templates. + Image location format: + https://cdn.amazonlinux.com/al2023/os-images/// + + Latest version information is fetched from: + https://cdn.amazonlinux.com/al2023/os-images/latest/ + +Examples: + Update the Amazon Linux 2023 image location in templates/**.yaml: + $ $(basename "${BASH_SOURCE[0]}") templates/**.yaml + +Flags: + -h, --help Print this help message +HELP +} + +function amazonlinux_cache_key_for_image_kernel() { + local location=$1 + case "${location}" in + https://cdn.amazonlinux.com/al2023/os-images/*) ;; + *) return 1 ;; + esac + # Cache key based on architecture and variant derived from location + # We use a simple heuristic: file path components. + # The URL structure is .../os-images///... + # We want a key that represents "amazonlinux:al2023:" + local folder + if [[ "${location}" == *"/kvm-arm64/"* ]]; then + folder="kvm-arm64" + elif [[ "${location}" == *"/kvm/"* ]]; then + folder="kvm" + else + return 1 + fi + echo "amazonlinux:al2023:${folder}" +} + +function amazonlinux_image_entry_for_image_kernel() { + local location=$1 + case "${location}" in + https://cdn.amazonlinux.com/al2023/os-images/*) ;; + *) return 1 ;; + esac + + local latest_url + # Get the redirect URL to find the latest version + latest_url=$(curl -Ls -o /dev/null -w '%{url_effective}' https://cdn.amazonlinux.com/al2023/os-images/latest/) + local version + version=$(basename "${latest_url}") + + local arch folder + if [[ "${location}" == *"x86_64"* ]]; then + # shellcheck disable=SC2034 + arch="x86_64" + folder="kvm" + elif [[ "${location}" == *"arm64"* ]] || [[ "${location}" == *"aarch64"* ]]; then + # shellcheck disable=SC2034 + arch="aarch64" + folder="kvm-arm64" + else + error_exit "Unknown arch for amazonlinux location: ${location}" + fi + + local base_url="https://cdn.amazonlinux.com/al2023/os-images/${version}/${folder}" + local checksums + checksums=$(download_to_cache "${base_url}/SHA256SUMS") + + local filename digest line + # Find the qcow2 file in SHA256SUMS + line=$(grep "\.qcow2$" "${checksums}" | head -n 1) + [[ -n ${line} ]] || error_exit "No qcow2 image found in ${base_url}/SHA256SUMS" + + # shellcheck disable=SC2034 + digest=$(echo "${line}" | awk '{print "sha256:"$1}') + filename=$(echo "${line}" | awk '{print $2}') + + # shellcheck disable=SC2034 + local location="${base_url}/${filename}" + + json_vars location arch digest +} + +# check if the script is executed or sourced +# shellcheck disable=SC1091 +if [[ ${BASH_SOURCE[0]} == "${0}" ]]; then + scriptdir=$(dirname "${BASH_SOURCE[0]}") + # shellcheck source=./cache-common-inc.sh + . "${scriptdir}/cache-common-inc.sh" + + # shellcheck source=/dev/null # avoid shellcheck hangs on source looping + . "${scriptdir}/update-template.sh" +else + # this script is sourced + if [[ -v SUPPORTED_DISTRIBUTIONS ]]; then + SUPPORTED_DISTRIBUTIONS+=("amazonlinux") + else + declare -a SUPPORTED_DISTRIBUTIONS=("amazonlinux") + fi + return 0 +fi + +declare -a templates=() +while [[ $# -gt 0 ]]; do + case "$1" in + -h | --help) + amazonlinux_print_help + exit 0 + ;; + -d | --debug) set -x ;; + *.yaml) templates+=("$1") ;; + *) + error_exit "Unknown argument: $1" + ;; + esac + shift +done + +if [[ ${#templates[@]} -eq 0 ]]; then + amazonlinux_print_help + exit 0 +fi + +declare -A image_entry_cache=() + +for template in "${templates[@]}"; do + echo "Processing ${template}" + # 1. extract location by parsing template + yq_filter=" + .images[] | [.location, .kernel.location, .kernel.cmdline] | @tsv + " + parsed=$(yq eval "${yq_filter}" "${template}") + + # 2. get the image location + arr=() + while IFS= read -r line; do arr+=("${line}"); done <<<"${parsed}" + locations=("${arr[@]}") + for ((index = 0; index < ${#locations[@]}; index++)); do + [[ ${locations[index]} != "null" ]] || continue + set -e + IFS=$'\t' read -r location _kernel_location _kernel_cmdline <<<"${locations[index]}" + set +e # Disable 'set -e' to avoid exiting on error for the next assignment. + cache_key=$( + set -e # Enable 'set -e' for the next command. + amazonlinux_cache_key_for_image_kernel "${location}" + ) # Check exit status separately to prevent disabling 'set -e' by using the function call in the condition. + # shellcheck disable=2181 + [[ $? -eq 0 ]] || continue + image_entry=$( + set -e # Enable 'set -e' for the next command. + if [[ -v image_entry_cache[${cache_key}] ]]; then + echo "${image_entry_cache[${cache_key}]}" + else + amazonlinux_image_entry_for_image_kernel "${location}" + fi + ) # Check exit status separately to prevent disabling 'set -e' by using the function call in the condition. + # shellcheck disable=2181 + [[ $? -eq 0 ]] || continue + set -e + image_entry_cache[${cache_key}]="${image_entry}" + if [[ -n ${image_entry} ]]; then + echo "${image_entry}" | jq + limactl edit --log-level error --set " + .images[${index}] = ${image_entry}| + (.images[${index}] | ..) style = \"double\" + " "${template}" + fi + done +done diff --git a/hack/update-template.sh b/hack/update-template.sh index 2828e60657d..87fba5341d0 100755 --- a/hack/update-template.sh +++ b/hack/update-template.sh @@ -170,6 +170,8 @@ if [[ ${BASH_SOURCE[0]} == "${0}" ]]; then . "${scriptdir}/update-template-fedora.sh" # shellcheck source=./update-template-opensuse.sh . "${scriptdir}/update-template-opensuse.sh" + # shellcheck source=./update-template-amazonlinux.sh + . "${scriptdir}/update-template-amazonlinux.sh" else # this script is sourced return 0 diff --git a/pkg/cidata/cidata.TEMPLATE.d/boot/04-amazonlinux-virtiofs.sh b/pkg/cidata/cidata.TEMPLATE.d/boot/04-amazonlinux-virtiofs.sh new file mode 100644 index 00000000000..cc06e6dc29e --- /dev/null +++ b/pkg/cidata/cidata.TEMPLATE.d/boot/04-amazonlinux-virtiofs.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# SPDX-FileCopyrightText: Copyright The Lima Authors +# SPDX-License-Identifier: Apache-2.0 + +set -eux -o pipefail + +# Workaround for Amazon Linux 2023 +if [ -f /etc/os-release ] && grep -q "Amazon Linux" /etc/os-release; then + # 1. Create missing mount.virtiofs helper + if [ ! -e /sbin/mount.virtiofs ]; then + cat >/sbin/mount.virtiofs <<'EOF' +#!/bin/sh +exec mount -i -t virtiofs "$@" +EOF + chmod +x /sbin/mount.virtiofs + fi + + # Cloud-init fails to mount 'mount0' because it doesn't recognize it as a device, + # so we extract the intended path from user-data and mount it manually. + USER_DATA="/var/lib/cloud/instance/user-data.txt" + if [ -f "${USER_DATA}" ]; then + MOUNT_POINT=$(grep "mount0" "${USER_DATA}" | awk -F, '{print $2}' | tr -d '[:space:]') + if [ -n "${MOUNT_POINT}" ] && ! mountpoint -q "${MOUNT_POINT}"; then + mkdir -p "${MOUNT_POINT}" + mount -t virtiofs mount0 "${MOUNT_POINT}" || true + fi + fi +fi diff --git a/templates/_images/amazonlinux-2023.yaml b/templates/_images/amazonlinux-2023.yaml new file mode 100644 index 00000000000..8562d7639a1 --- /dev/null +++ b/templates/_images/amazonlinux-2023.yaml @@ -0,0 +1,7 @@ +images: +- location: "https://cdn.amazonlinux.com/al2023/os-images/2023.9.20251208.0/kvm/al2023-kvm-2023.9.20251208.0-kernel-6.1-x86_64.xfs.gpt.qcow2" + arch: "x86_64" + digest: "sha256:c91f244483d9a460869738f7fcfb5e37eb402aec8582d10456cf0c108e1a4d4c" +- location: "https://cdn.amazonlinux.com/al2023/os-images/2023.9.20251208.0/kvm-arm64/al2023-kvm-2023.9.20251208.0-kernel-6.1-arm64.xfs.gpt.qcow2" + arch: "aarch64" + digest: "sha256:7aef1f189076a0416cd16062bbf7e0928d81061e68411cab8904447e1bd5eafd" diff --git a/templates/amazonlinux-2023.yaml b/templates/amazonlinux-2023.yaml new file mode 100644 index 00000000000..c17ba377210 --- /dev/null +++ b/templates/amazonlinux-2023.yaml @@ -0,0 +1,15 @@ +minimumLimaVersion: 2.0.0 + +base: +- template:_images/amazonlinux-2023 +- template:_default/mounts + +provision: +- mode: system + script: | + #!/bin/bash + set -eux -o pipefail + # Update to the latest release on the first boot + if [ ! -f /etc/lima-al2023-updated ]; then + dnf upgrade -y --releasever=latest + fi diff --git a/templates/amazonlinux.yaml b/templates/amazonlinux.yaml new file mode 120000 index 00000000000..bfa2d7b735d --- /dev/null +++ b/templates/amazonlinux.yaml @@ -0,0 +1 @@ +amazonlinux-2023.yaml \ No newline at end of file