Add cloud image downloader script (#11918)

This commit is contained in:
Manoj Kumar 2026-01-29 16:06:19 +05:30 committed by GitHub
parent a55f85af50
commit 0b62fb5e20
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 259 additions and 0 deletions

View File

@ -0,0 +1,259 @@
#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#-------------------------------------------------------------------------------
# Configuration
#-------------------------------------------------------------------------------
# This section contains the variables you might want to change.
# The temporary directory where files will be downloaded.
# It's a good practice to create a unique temporary directory for each script run.
TEMP_DIR=$(mktemp -d)
# The BASE destination directory for the downloaded image files.
# Subdirectories for each distro will be created inside this one.
# Make sure this directory exists before running the script.
# Must be executed by the cloudstack user on machine hosting the public download site.
# It will be publicly available at https://download.cloudstack.org/templates/cloud-images/
DEST_DIR="${HOME}/repository/templates/cloud-images"
# The directory where log files will be stored.
# Make sure this directory exists.
LOG_DIR="${HOME}/log/cloud-image-downloader"
LOG_FILE="${LOG_DIR}/cloud-image-downloader_$(date +%Y%m%d_%H%M%S).log"
LOG_RETENTION_DAYS=30
LOGGER_TAG="cloud-image-downloader"
LOGGER_FACILITY="user"
LOGGER_AVAILABLE=false
log_message() {
local priority=$1
shift
local message="$*"
local timestamp=$(date +'%Y-%m-%d %H:%M:%S')
# Log to file
echo "${timestamp} [${priority}] ${message}" | tee -a "${LOG_FILE}"
# Log to syslog using logger utility
if [ "${LOGGER_AVAILABLE}" = true ]; then
logger -t "${LOGGER_TAG}" -p "${LOGGER_FACILITY}.${priority}" -- "${message}"
fi
}
log_info() {
log_message "info" "$@"
}
log_warn() {
log_message "warning" "$@"
}
log_error() {
log_message "err" "$@"
}
cleanup_old_logs() {
log_info "Cleaning up log files older than ${LOG_RETENTION_DAYS} days..."
if [ ! -d "$LOG_DIR" ]; then
log_warn "Log directory does not exist: $LOG_DIR"
return
fi
local deleted_count=0
# Find and delete log files older than retention period
while IFS= read -r -d '' log_file; do
rm -f "$log_file"
deleted_count=$((deleted_count + 1))
done < <(find "$LOG_DIR" -name "*.log" -type f -mtime +${LOG_RETENTION_DAYS} -print0 2>/dev/null)
if [ $deleted_count -gt 0 ]; then
log_info "Deleted $deleted_count old log file(s)"
else
log_info "No old log files to delete"
fi
}
#-------------------------------------------------------------------------------
# Image Definitions
#-------------------------------------------------------------------------------
# To add a new image, you must add an entry to BOTH arrays below.
# 1. Add the destination filename and the download URL.
declare -A IMAGE_URLS=(
["Rocky-9-GenericCloud.latest.x86_64.qcow2"]="https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2"
["Rocky-9-GenericCloud.latest.aarch64.qcow2"]="https://dl.rockylinux.org/pub/rocky/9/images/aarch64/Rocky-9-GenericCloud.latest.aarch64.qcow2"
["Rocky-8-GenericCloud.latest.x86_64.qcow2"]="https://dl.rockylinux.org/pub/rocky/8/images/x86_64/Rocky-8-GenericCloud.latest.x86_64.qcow2"
["Rocky-8-GenericCloud.latest.aarch64.qcow2"]="https://dl.rockylinux.org/pub/rocky/8/images/aarch64/Rocky-8-GenericCloud.latest.aarch64.qcow2"
["openSUSE-Leap-15.5-Minimal-VM.x86_64-Cloud.qcow2"]="https://download.opensuse.org/distribution/leap/15.5/appliances/openSUSE-Leap-15.5-Minimal-VM.x86_64-Cloud.qcow2"
["openSUSE-Leap-15.5-Minimal-VM.aarch64-Cloud.qcow2"]="https://download.opensuse.org/distribution/leap/15.5/appliances/openSUSE-Leap-15.5-Minimal-VM.aarch64-Cloud.qcow2"
["debian-12-genericcloud-amd64.qcow2"]="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2"
["debian-12-genericcloud-arm64.qcow2"]="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-arm64.qcow2"
["ubuntu-24.04-server-cloudimg-amd64.img"]="https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img"
["ubuntu-24.04-server-cloudimg-arm64.img"]="https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-arm64.img"
["ubuntu-22.04-server-cloudimg-amd64.img"]="https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img"
["ubuntu-22.04-server-cloudimg-arm64.img"]="https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-arm64.img"
["ubuntu-20.04-server-cloudimg-amd64.img"]="https://cloud-images.ubuntu.com/releases/20.04/release/ubuntu-20.04-server-cloudimg-amd64.img"
["ubuntu-20.04-server-cloudimg-arm64.img"]="https://cloud-images.ubuntu.com/releases/20.04/release/ubuntu-20.04-server-cloudimg-arm64.img"
["OL9U5_x86_64-kvm-b259.qcow2"]="https://yum.oracle.com/templates/OracleLinux/OL9/u5/x86_64/OL9U5_x86_64-kvm-b259.qcow2"
["OL9U5_aarch64-kvm-b126.qcow2"]="https://yum.oracle.com/templates/OracleLinux/OL9/u5/aarch64/OL9U5_aarch64-kvm-b126.qcow2"
["OL8U10_x86_64-kvm-b258.qcow2"]="https://yum.oracle.com/templates/OracleLinux/OL8/u10/x86_64/OL8U10_x86_64-kvm-b258.qcow2"
["OL8U10_aarch64-kvm-b122.qcow2"]="https://yum.oracle.com/templates/OracleLinux/OL8/u10/aarch64/OL8U10_aarch64-kvm-b122.qcow2"
)
# 2. Add the destination filename and its corresponding distribution subdirectory name.
declare -A IMAGE_DISTROS=(
["Rocky-9-GenericCloud.latest.x86_64.qcow2"]="rockylinux"
["Rocky-9-GenericCloud.latest.aarch64.qcow2"]="rockylinux"
["Rocky-8-GenericCloud.latest.x86_64.qcow2"]="rockylinux"
["Rocky-8-GenericCloud.latest.aarch64.qcow2"]="rockylinux"
["openSUSE-Leap-15.5-Minimal-VM.x86_64-Cloud.qcow2"]="opensuse"
["openSUSE-Leap-15.5-Minimal-VM.aarch64-Cloud.qcow2"]="opensuse"
["debian-12-genericcloud-amd64.qcow2"]="debian"
["debian-12-genericcloud-arm64.qcow2"]="debian"
["ubuntu-24.04-server-cloudimg-amd64.img"]="ubuntu"
["ubuntu-24.04-server-cloudimg-arm64.img"]="ubuntu"
["ubuntu-22.04-server-cloudimg-amd64.img"]="ubuntu"
["ubuntu-22.04-server-cloudimg-arm64.img"]="ubuntu"
["ubuntu-20.04-server-cloudimg-amd64.img"]="ubuntu"
["ubuntu-20.04-server-cloudimg-arm64.img"]="ubuntu"
["OL9U5_x86_64-kvm-b259.qcow2"]="oraclelinux"
["OL9U5_aarch64-kvm-b126.qcow2"]="oraclelinux"
["OL8U10_x86_64-kvm-b258.qcow2"]="oraclelinux"
["OL8U10_aarch64-kvm-b122.qcow2"]="oraclelinux"
)
#-------------------------------------------------------------------------------
# Cleanup Handler
#-------------------------------------------------------------------------------
cleanup_on_exit() {
local exit_code=$?
if [ -d "$TEMP_DIR" ]; then
rm -rf "$TEMP_DIR"
log_info "Temporary directory $TEMP_DIR removed."
fi
if [ $exit_code -ne 0 ]; then
log_error "Script exited with error code: $exit_code"
fi
}
trap cleanup_on_exit EXIT INT TERM
#-------------------------------------------------------------------------------
# Main Script Logic
#-------------------------------------------------------------------------------
if command -v logger &> /dev/null; then
LOGGER_AVAILABLE=true
fi
# Ensure base destination and log directories exist
mkdir -p "$DEST_DIR"
mkdir -p "$LOG_DIR"
# Clean up old logs first
cleanup_old_logs
log_info "Starting image download process."
log_info "Temporary directory: $TEMP_DIR"
log_info "Base destination directory: $DEST_DIR"
log_info "Log file: $LOG_FILE"
# Inform about logger status
if [ "${LOGGER_AVAILABLE}" = true ]; then
log_info "Syslog logging enabled (tag: ${LOGGER_TAG})"
else
log_warn "Syslog logging disabled - logger utility not found"
fi
# Loop through the image URLs
for filename in "${!IMAGE_URLS[@]}"; do
url="${IMAGE_URLS[$filename]}"
distro="${IMAGE_DISTROS[$filename]}"
# Check if a distro is defined for the file
if [ -z "$distro" ]; then
log_error "No distribution directory defined for $filename. Skipping."
continue
fi
distro_dest_dir="${DEST_DIR}/${distro}"
temp_filepath="${TEMP_DIR}/${filename}"
dest_filepath="${distro_dest_dir}/${filename}"
log_info "--------------------------------------------------"
log_info "Starting download for: $filename"
log_info "URL: $url"
# Download the file to the temporary directory
wget --progress=bar:force:noscroll -O "$temp_filepath" "$url"
download_status=$?
if [ $download_status -ne 0 ]; then
# Handle download failure
log_error "Failed to download $filename from $url. wget exit code: $download_status"
else
# Handle download success
log_info "Successfully downloaded $filename to temporary location."
# Ensure the specific distro directory exists
log_info "Ensuring destination directory exists: $distro_dest_dir"
mkdir -p "$distro_dest_dir"
# Move the file to the destination directory, replacing any existing file
log_info "Moving $filename to $dest_filepath"
mv -f "$temp_filepath" "$dest_filepath"
move_status=$?
if [ $move_status -ne 0 ]; then
log_error "Failed to move $filename to $dest_filepath. mv exit code: $move_status"
else
log_info "Successfully moved $filename."
fi
fi
done
log_info "Generate checksum"
# Create md5 checksum
checksum_file="md5sum.txt"
sha512_checksum_file="sha512sum.txt"
cd "$DEST_DIR"
find . -type f ! -iname '*.txt' -exec md5sum {} \; > "$checksum_file"
checksum_status=$?
if [ $checksum_status -ne 0 ]; then
log_error "Failed to create md5 checksum. md5sum exit code: $checksum_status"
else
log_info "Successfully created checksum file: $checksum_file"
fi
find . -type f ! -iname '*.txt' -exec sha512sum {} \; > "$sha512_checksum_file"
sha512_checksum_status=$?
if [ $sha512_checksum_status -ne 0 ]; then
log_error "Failed to create sha512 checksum. sha512sum exit code: $sha512_checksum_status"
else
log_info "Successfully created checksum file: $sha512_checksum_file"
fi
log_info "--------------------------------------------------"
log_info "Image download process finished."