Skip to content

Commit

Permalink
Try building KVM qcow2 with GH Actions
Browse files Browse the repository at this point in the history
  • Loading branch information
iBug committed Sep 4, 2024
1 parent f499a39 commit 28e4b18
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 9 deletions.
45 changes: 45 additions & 0 deletions .github/workflows/kvm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: KVM Image Build CI

on:
workflow_dispatch: {}

permissions:
contents: write

jobs:
build:
runs-on: ubuntu-latest
env:
filename: build-${{ github.run_number }}
APT_SOURCE: http://azure.archive.ubuntu.com
steps:
- name: Install dependencies
run: |
sudo apt update
sudo apt -y install qemu-utils
sudo modprobe nbd
- uses: actions/checkout@v4
- name: Get base image
run: |
wget --progress=dot:giga \
-O ~/input.qcow2 \
https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
- name: Mount image
run: |
qemu-img resize ~/input.qcow2 4096M
sudo qemu-nbd -c /dev/nbd0 ~/input.qcow2
- name: Build it!
run: |
sudo ./kvmstrap /dev/nbd0p1
- name: Pack it!
run: |
sudo qemu-nbd -d /dev/nbd0
qemu-img convert -c -m 2 -O qcow2 -p ~/input.qcow2 ${{ env.filename }}.qcow2
./infostrap ${{ env.filename }}.qcow2 > ${{ env.filename }}-buildinfo.txt
- name: Upload it!
uses: softprops/action-gh-release@v1
with:
tag_name: auto-build
files: |
${{ env.filename }}.qcow2
${{ env.filename }}-buildinfo.txt
93 changes: 87 additions & 6 deletions kvmstrap
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,92 @@ BASE="$(dirname "$0")"
SRC="$BASE/rootfs"
DST=/tmp/target
INPUT="${1:-input.qcow2}"
APT_SOURCE="${APT_SOURCE:-https://mirrors.ustc.edu.cn}"
cd "$BASE"
. ./variables

qemu-img resize "$INPUT" 4096M
run() {
chroot "$DST" "$@"
}

add_file() {
while [ "$#" -ne 0 ]; do
rsync -rlp "$SRC/$1" "$DST/$1"
shift
done
}

add_package() {
DEBIAN_FRONTEND=noninteractive run apt-get install -y --no-install-recommends "$@"
}

remove_package() {
DEBIAN_FRONTEND=noninteractive run apt-get purge -y --autoremove "$@"
}

mount_all() {
mount -t tmpfs none "$DST/dev"
chmod 755 "$DST/dev"
mknod -m0666 "$DST/dev/null" c 1 3
mknod -m0666 "$DST/dev/random" c 1 8
mknod -m0666 "$DST/dev/urandom" c 1 9
mknod -m0666 "$DST/dev/zero" c 1 5
ln -sf /proc/self/fd/0 "$DST/dev/stdin"
ln -sf /proc/self/fd/1 "$DST/dev/stdout"
ln -sf /proc/self/fd/2 "$DST/dev/stderr"
mkdir -p "$DST/dev/pts"
mount -t devpts none "$DST/dev/pts"
mount -t proc proc "$DST/proc"
mount -t tmpfs none "$DST/run"
mount -t sysfs sys "$DST/sys"
mount -t tmpfs none "$DST/tmp"
}

umount_all() {
umount "$DST/dev/pts"
umount "$DST/dev"
umount "$DST/proc"
umount "$DST/run"
umount "$DST/sys"
umount "$DST/tmp"
umount "$DST"
}

mkdir -p "$DST"
guestmount -a "$INPUT" -m /dev/sda1 "$DST"
trap 'fusermount -u "$DST"' EXIT
if [ -b "$INPUT" ]; then
mount "$INPUT" "$DST"
else
qemu-img resize "$INPUT" 4096M
guestmount -a "$INPUT" -m /dev/sda1 "$DST"
fi

mount_all
trap umount_all EXIT

# Preliminary cleanup
rm -f "$DST/etc/resolv.conf"
cp -f /etc/resolv.conf "$DST/etc/resolv.conf"
add_file /etc/apt/
run sed -i "s,%APT_SOURCE%,$APT_SOURCE,g" /etc/apt/sources.list.d/ubuntu.sources
run apt-mark auto '~i!~M'
run apt-get update
run apt-get -y dist-upgrade

add_package linux-virtual ubuntu-minimal ubuntu-server ubuntu-standard

# Add files
rsync -rlpt "$SRC"/etc/{apt,cloud,default,locale.gen,profile.d,skel,ssh,systemd} "$DST"/etc/
add_file /etc/{apt,cloud,default,profile.d,skel,ssh,systemd}/ /etc/locale.gen

# Remove "pass" from fstab
sed -Ei 's/\b[0-9]+$/0/g' "$DST"/etc/fstab

# Remove root password
sed -Ei 's/^(root:)[^:]*(:.*$)/\1\2/' "$DST"/etc/shadow
#sed -Ei 's/^(root:)[^:]*(:.*$)/\1\2/' "$DST"/etc/shadow
run passwd -d root

# Simulate systemctl enable
ln -sfn /etc/systemd/system/vlab-startup.service "$DST"/etc/systemd/system/multi-user.target.wants/vlab-startup.service
#ln -sfn /etc/systemd/system/vlab-startup.service "$DST"/etc/systemd/system/multi-user.target.wants/vlab-startup.service
run systemctl enable vlab-startup.service

# Write version info
VLAB_VERSION="$VERSION:$(date +%y%m%d)"
Expand All @@ -39,3 +106,17 @@ FILE="$DST"/etc/vlab_version
echo "VLAB_DISTRO=ubuntu" > "$FILE"
echo "VLAB_VERSION=$VLAB_VERSION" >> "$FILE"
chmod 444 "$FILE"

# Set the apt source of the resulting image to USTC mirrors
add_file /etc/apt/sources.list.d/ubuntu.sources
run sed -i "s,%APT_SOURCE%,https://mirrors.ustc.edu.cn,g" /etc/apt/sources.list.d/ubuntu.sources
run apt clean

# Final cleanup
set +e
rm -rf "$DST/var/lib/apt/lists"/* "$DST/var/lib/dpkg"/*-old
rm -rf "$DST/var/cache"/*
rm -f "$DST/etc/resolv.conf"
ln -sfn ../run/systemd/resolve/stub-resolv.conf "$DST/etc/resolv.conf"
rm -rf "$DST/etc/ssh"/ssh_host_*_key{,.pub}
rmdir "$DST"/*.usr-is-merged || true
7 changes: 4 additions & 3 deletions labstrap
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ BASE="$(dirname "$0")"
SRC="$BASE/rootfs"
DST=/target
INPUT=/input.tar.zst
APT_SOURCE=${APT_SOURCE:-https://mirrors.ustc.edu.cn}
cd "$BASE"
. ./variables

Expand Down Expand Up @@ -66,12 +67,12 @@ mount_all
trap umount_all EXIT

# Preliminary cleanup
run sh -c 'dpkg --get-selections | cut -f1 | xargs apt-mark auto'
run apt-mark auto '~i!~M'

rm -f "$DST/etc/resolv.conf"
cp -f /etc/resolv.conf "$DST/etc/resolv.conf"
add_file /etc/apt/
run sed -i "s,%APT_SOURCE%,${APT_SOURCE:=https://mirrors.ustc.edu.cn},g" /etc/apt/sources.list.d/ubuntu.sources
run sed -i "s,%APT_SOURCE%,$APT_SOURCE,g" /etc/apt/sources.list.d/ubuntu.sources
run apt-get update
run apt-get -y dist-upgrade

Expand Down Expand Up @@ -184,4 +185,4 @@ rm -rf "$DST/var/lib/apt/lists"/* "$DST/var/lib/dpkg"/*-old
rm -rf "$DST/var/cache"/*
rm "$DST/etc/resolv.conf"
rm -rf "$DST/etc/ssh"/ssh_host_*_key{,.pub}
rmdir "$DST"/*.usr-is-merged
rmdir "$DST"/*.usr-is-merged || true

0 comments on commit 28e4b18

Please sign in to comment.