Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
151 changes: 151 additions & 0 deletions images/archlinux/common.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#!/bin/bash
# Common functions for ArchLinux images

DISTRO="archlinux"
IMAGE_NAME="${DISTRO}-base.qcow2"
BASE_IMAGE="${BASE_DIR}/${IMAGE_NAME}"
DISK_SIZE="15G"

# Download the ArchLinux cloud image
# ${1} - Base directory to store the image
# ${2} - Distribution (should be "archlinux")
# ${3} - Flavor (server, minimal, etc.)
function download_source() {
# Skip if the image already exists
if [ -f "${BASE_IMAGE}" ]; then
echo "Base image already exists at ${BASE_IMAGE}, skipping download."
return 0
fi

echo "Downloading ArchLinux cloud image..."

# Get the latest ArchLinux cloud image
local arch_image_url="https://mirrors.pku.edu.cn/archlinux/images/latest/Arch-Linux-x86_64-cloudimg.qcow2"

wget -q -O "${BASE_IMAGE}" "${arch_image_url}"

echo "Download complete: ${BASE_IMAGE}"
return 0
}

# Function to resize ArchLinux cloud image
function resize_image() {
local image_path="${1}"
local new_size="${2}"

# ArchLinux cloud images typically have this partition layout:
# /dev/nbd0p1 2048 4095 2048 1M BIOS boot
# /dev/nbd0p2 4096 618495 614400 300M EFI System
# /dev/nbd0p3 618496 4194270 3575775 1.7G Linux root (x86-64)

# Resize the image to the new size
echo "Resizing image to ${new_size}..."
qemu-img resize "${image_path}" "${new_size}"

# Use qemu-nbd to access the partitions
echo "Connecting image to NBD device..."
# Find an unused nbd device
modprobe nbd max_part=16

# Find the first available nbd device
NBD_DEV=$(find_free_nbd)

# Connect the image to the NBD device
qemu-nbd --connect="${NBD_DEV}" "${image_path}"

# Wait for partitions to be recognized
sleep 2
partprobe "${NBD_DEV}"

# Fix GPT and resize the root partition
echo "Resizing filesystem on root partition..."
sgdisk -e "${NBD_DEV}"

# Resize the last partition (root) to fill available space
parted -s "${NBD_DEV}" resizepart 3 100%
fdisk -l "${NBD_DEV}"

# Resize the ext4 filesystem
e2fsck -f "${NBD_DEV}p3"
resize2fs "${NBD_DEV}p3"
fdisk -l "${NBD_DEV}"

# Disconnect the NBD device
echo "Disconnecting NBD device..."
qemu-nbd --disconnect "${NBD_DEV}"

echo "Resize complete."
}

# Change package mirrors to PKU mirrors
function os_change_source() {
# Backup original mirrorlist
cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.bak

# Use PKU mirrors for faster downloads
echo '##' > /etc/pacman.d/mirrorlist
echo '## PKU Mirror' >> /etc/pacman.d/mirrorlist
echo '##' >> /etc/pacman.d/mirrorlist
echo 'Server = https://mirrors.pku.edu.cn/archlinux/$repo/os/$arch' >> /etc/pacman.d/mirrorlist
echo '' >> /etc/pacman.d/mirrorlist
echo '##' >> /etc/pacman.d/mirrorlist
echo '## Tsinghua Mirror (Fallback)' >> /etc/pacman.d/mirrorlist
echo '##' >> /etc/pacman.d/mirrorlist
echo 'Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch' >> /etc/pacman.d/mirrorlist

# Initialize pacman keyring if needed
pacman-key --init
pacman-key --populate archlinux

# Add archlinuxcn repository
echo '' >> /etc/pacman.conf
echo '[archlinuxcn]' >> /etc/pacman.conf
echo 'Server = https://mirrors.pku.edu.cn/archlinuxcn/$arch' >> /etc/pacman.conf

# Refresh package database and install archlinuxcn-keyring
pacman -Sy --noconfirm archlinuxcn-keyring

# Force refresh package lists
pacman -Syyu --noconfirm
}

function os_update() {
echo "pacman -Syu --noconfirm"
}

# Function to install packages on ArchLinux
function os_install() {
echo "pacman -S --noconfirm"
}

function os_cleanup() {
echo "pacman -Scc --noconfirm && paccache -r"
}

function mount_image() {
NBD_DEV=$(find_free_nbd)
qemu-nbd --connect="${NBD_DEV}" "${1:-${IMAGE}}"
sleep 2

# Mount partitions
# Root partition
mount "${NBD_DEV}p3" "${MOUNT}"

# EFI partition (if it exists)
if [ -b "${NBD_DEV}p2" ]; then
mkdir -p "${MOUNT}/boot/efi"
mount "${NBD_DEV}p2" "${MOUNT}/boot/efi"
fi
}

function unmount_image() {
sync "${MOUNT}"

# Unmount EFI partition if mounted
if mountpoint -q "${MOUNT}/boot/efi" 2>/dev/null; then
umount "${MOUNT}/boot/efi"
fi

umount "${MOUNT}"
qemu-nbd --disconnect "${NBD_DEV}"
}
55 changes: 55 additions & 0 deletions images/archlinux/pku/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/bash
# shellcheck disable=SC2034,SC2154

# Image configuration
IMAGE_NAME="archlinux-server-pku-${build_version}.qcow2"
DISK_SIZE="10G"
PACKAGES=(qemu-guest-agent)
SERVICES=(qemu-guest-agent.service)

function pre() {
echo "Preparing to build ${IMAGE_NAME} with disk size ${DISK_SIZE}"
}

function inchroot() {
echo "Setting up the image environment for ${IMAGE_NAME}..."

# Install required tools for handling RPM packages
pacman -S --noconfirm --needed rpmextract wget curl

# Get the latest clab-guest-tools version from rpm repository
echo "Fetching latest clab-guest-tools version..."
latest_rpm=$(curl -s "https://git.pku.edu.cn/api/packages/lcpu/rpm/el9/repodata/primary.xml.gz" | \
gunzip | grep -o 'package/clab-guest-tools/[^"]*\.rpm' | \
sort -V | tail -1)

if [ -z "$latest_rpm" ]; then
echo "Failed to get latest clab-guest-tools version, falling back to known version"
latest_rpm="package/clab-guest-tools/0.0.20250930-1.el9/noarch/clab-guest-tools-0.0.20250930-1.el9.noarch.rpm"
fi

rpm_url="https://git.pku.edu.cn/api/packages/lcpu/rpm/el9/${latest_rpm}"
echo "Downloading clab-guest-tools from: ${rpm_url}"

# Download and extract clab-guest-tools RPM
cd /tmp
wget -O clab-guest-tools.rpm "${rpm_url}" || {
echo "Failed to download clab-guest-tools RPM"
exit 1
}

# Extract RPM directly to root filesystem
cd /
rpmextract.sh /tmp/clab-guest-tools.rpm

# Clean up
rm -f /tmp/clab-guest-tools.rpm

echo "clab-guest-tools installation completed"
}

function post() {
# compress the image, which is qcow2 format
qemu-img convert -f qcow2 -O qcow2 -o compression_type=zstd -m 8 "${1}" "${2}"
rm "${1}"
}