diff --git a/.forgejo/patches/linux-template-builder_use-fuse.patch b/.forgejo/patches/linux-template-builder_use-fuse.patch new file mode 100644 index 0000000..4fa02af --- /dev/null +++ b/.forgejo/patches/linux-template-builder_use-fuse.patch @@ -0,0 +1,184 @@ +diff --git a/cleanup_image b/cleanup_image +index 224c04a..911b238 100755 +--- a/cleanup_image ++++ b/cleanup_image +@@ -1,6 +1,7 @@ + #!/bin/sh + + export INSTALLDIR=$1 ++export TEMPLATE_USE_FUSE=1 + + . ./builder_setup + +@@ -20,5 +21,8 @@ fi + echo "--> Cleaning up image file..." + $SCRIPTSDIR/09_cleanup.sh + +-echo "--> Compacting image file..." +-/sbin/fstrim -v "$INSTALLDIR" ++# fstrim not supported in userspace ++if [ "$TEMPLATE_USE_FUSE" -ne 1 ]; then ++ echo "--> Compacting image file..." ++ /sbin/fstrim -v "$INSTALLDIR" ++fi +diff --git a/prepare_image b/prepare_image +index 6334879..de1a2af 100755 +--- a/prepare_image ++++ b/prepare_image +@@ -19,6 +19,8 @@ RETCODE=0 + . ./builder_setup >/dev/null + . ./umount_kill.sh >/dev/null + ++export TEMPLATE_USE_FUSE=1 ++ + if ! [ $# -eq 1 ]; then + echo "usage ${0} " + exit +@@ -55,11 +57,20 @@ echo "-> Preparing instalation of ${DIST} template..." + if [ -f "${IMG}" ]; then + echo "-> Image file already exists, assuming *update*..." + if [ "0$TEMPLATE_ROOT_WITH_PARTITIONS" -eq 1 ]; then +- IMG_LOOP=$(/sbin/losetup -P -f --show "$IMG") +- IMG_DEV=${IMG_LOOP}p3 ++ if [ "$TEMPLATE_USE_FUSE" -eq 1 ]; then ++ echo "Fuse mode not implemented when TEMPLATE_ROOT_WITH_PARTITIONS is true" ++ exit ++ else ++ IMG_LOOP=$(/sbin/losetup -P -f --show "$IMG") ++ IMG_DEV=${IMG_LOOP}p3 ++ fi + else +- IMG_LOOP=$(/sbin/losetup -f --show "$IMG") +- IMG_DEV=${IMG_LOOP} ++ if [ "$TEMPLATE_USE_FUSE" -eq 1 ]; then ++ IMG_DEV=$IMG ++ else ++ IMG_LOOP=$(/sbin/losetup -f --show "$IMG") ++ IMG_DEV=${IMG_LOOP} ++ fi + fi + udevadm settle --exit-if-exists="$IMG_DEV" + else +@@ -78,11 +89,20 @@ size=2MiB, type=21686148-6449-6E6F-744E-656564454649, uuid=1e6c9db4-1e91-46c4-84 + type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=693244e6-3e07-47bf-ad79-acade4293fe7, name="Root filesystem" + EOF + +- IMG_LOOP=$(/sbin/losetup -P -f --show "$IMG") +- IMG_DEV=${IMG_LOOP}p3 ++ if [ "$TEMPLATE_USE_FUSE" -eq 1 ]; then ++ echo "Fuse mode not implemented when TEMPLATE_ROOT_WITH_PARTITIONS is true" ++ exit ++ else ++ IMG_LOOP=$(/sbin/losetup -P -f --show "$IMG") ++ IMG_DEV=${IMG_LOOP}p3 ++ fi + else +- IMG_LOOP=$(/sbin/losetup -f --show "$IMG") +- IMG_DEV=${IMG_LOOP} ++ if [ "$TEMPLATE_USE_FUSE" -eq 1 ]; then ++ IMG_DEV=$IMG ++ else ++ IMG_LOOP=$(/sbin/losetup -f --show "$IMG") ++ IMG_DEV=${IMG_LOOP} ++ fi + fi + udevadm settle --exit-if-exists="$IMG_DEV" + +@@ -90,7 +110,9 @@ EOF + /sbin/mkfs.ext4 -q -F "${IMG_DEV}" || exit 1 + fi + +-mount "${IMG_DEV}" "${INSTALLDIR}" || exit 1 ++if [ "$TEMPLATE_USE_FUSE" -eq 1 ]; then ++ fuse2fs "${IMG_DEV}" "${INSTALLDIR}" || exit 1 ++fi + trap "umount_kill $(readlink -m ${INSTALLDIR})" EXIT + "${SCRIPTSDIR}/01_install_core.sh" + +@@ -107,6 +129,8 @@ trap - EXIT + + echo "-> Unmounting prepared_image..." + umount_kill "$(readlink -m ${INSTALLDIR})" || true +-/sbin/losetup -d ${IMG_LOOP} ++if [ "$TEMPLATE_USE_FUSE" -ne 1 ]; then ++ /sbin/losetup -d ${IMG_LOOP} ++fi + + exit ${RETCODE} +diff --git a/qubeize_image b/qubeize_image +index 19c37cb..9e5179d 100755 +--- a/qubeize_image ++++ b/qubeize_image +@@ -13,6 +13,8 @@ export CLEANIMG="$1" + export NAME="$2" + export LC_ALL=POSIX + ++export TEMPLATE_USE_FUSE=1 ++ + . ./builder_setup >/dev/null + . ./umount_kill.sh >/dev/null + +@@ -50,7 +52,9 @@ function cleanup() { + trap - ERR + trap + umount_kill "$PWD/mnt" || true +- /sbin/losetup -d ${IMG_LOOP} ++ if [ "$TEMPLATE_USE_FUSE" -ne 1 ]; then ++ /sbin/losetup -d ${IMG_LOOP} ++ fi + exit $errval + } + trap cleanup ERR +@@ -72,14 +76,27 @@ fi + echo "--> Mounting $IMG" + mkdir -p mnt + if [ "0$TEMPLATE_ROOT_WITH_PARTITIONS" -eq 1 ]; then +- IMG_LOOP=$(/sbin/losetup -P -f --show "$IMG") +- IMG_DEV=${IMG_LOOP}p3 ++ if [ "$TEMPLATE_USE_FUSE" -eq 1 ]; then ++ echo "Fuse mode not implemented when TEMPLATE_ROOT_WITH_PARTITIONS is true" ++ exit ++ else ++ IMG_LOOP=$(/sbin/losetup -P -f --show "$IMG") ++ IMG_DEV=${IMG_LOOP}p3 ++ fi + else +- IMG_LOOP=$(/sbin/losetup -f --show "$IMG") +- IMG_DEV=${IMG_LOOP} ++ if [ "$TEMPLATE_USE_FUSE" -eq 1 ]; then ++ IMG_DEV=$IMG ++ else ++ IMG_LOOP=$(/sbin/losetup -f --show "$IMG") ++ IMG_DEV=${IMG_LOOP} ++ fi + fi + udevadm settle --exit-if-exists="$IMG_DEV" +-mount "$IMG_DEV" mnt || exit 1 ++if [ "$TEMPLATE_USE_FUSE" -eq 1 ]; then ++ fuse2fs "$IMG_DEV" mnt ++else ++ mount "$IMG_DEV" mnt || exit 1 ++fi + export INSTALLDIR=mnt + + # prepare for template.conf, so the qubeize script may generate it dynamically +@@ -159,7 +176,9 @@ ls -als $IMG + # ------------------------------------------------------------------------------ + echo "--> Unmounting $IMG" + umount_kill "$PWD/mnt" || true +-/sbin/losetup -d ${IMG_LOOP} ++if [ "$TEMPLATE_USE_FUSE" -ne 1 ]; then ++ /sbin/losetup -d ${IMG_LOOP} ++fi + + echo "Qubeized image stored at: $IMG" + +diff --git a/templates.spec b/templates.spec +index e1a82e9..210ef57 100644 +--- a/templates.spec ++++ b/templates.spec +@@ -193,3 +193,4 @@ rm -rf $RPM_BUILD_ROOT + %attr (664,root,qubes) %{dest_dir}/vm-whitelisted-appmenus.list + %attr (664,root,qubes) %{dest_dir}/netvm-whitelisted-appmenus.list + %attr (664,root,qubes) %{dest_dir}/template.conf ++%define _arch x86_64 diff --git a/.forgejo/workflows/test-build.yaml b/.forgejo/workflows/test-build.yaml new file mode 100644 index 0000000..b33aefb --- /dev/null +++ b/.forgejo/workflows/test-build.yaml @@ -0,0 +1,36 @@ +on: + pull_request: + types: [ assigned, opened, synchronize, reopened ] + +jobs: + build-test: + runs-on: x86_64 + container: + image: alpine:3.20 + steps: + - name: Environment setup + run: | + apk add rpm wget coreutils eudev e2fsprogs xen doas sudo curl nodejs git alpine-sdk fuse2fs patch findutils grep + cd /etc/apk/keys + curl -JO https://ayakael.net/api/packages/forge/alpine/key + - name: Repo pull + uses: actions/checkout@v4 + with: + fetch-depth: 500 + - name: RPM build + run: | + git clone https://github.com/QubesOS/qubes-builder + mkdir qubes-builder/qubes-src + ln -s $GITHUB_WORKSPACE qubes-builder/qubes-src/builder-alpine + cp builder.conf qubes-builder/. + git clone https://github.com/QubesOS/qubes-linux-template-builder qubes-builder/qubes-src/linux-template-builder + patch -d qubes-builder/qubes-src/linux-template-builder -p1 -i $GITHUB_WORKSPACE/.forgejo/patches/linux-template-builder_use-fuse.patch + echo "%define _arch x86_64" >> qubes-builder/qubes-src/linux-template-builder/templates.spec + cd qubes-builder + make linux-template-builder + cp qubes-src/linux-template-builder/rpm/noarch/qubes-template-*.rpm $GITHUB_WORKSPACE/. + - name: Package upload + uses: forgejo/upload-artifact@v3 + with: + name: package + path: qubes-template-*.rpm diff --git a/scripts/04_install_qubes.sh b/scripts/04_install_qubes.sh index f0e6bac..cf3438d 100755 --- a/scripts/04_install_qubes.sh +++ b/scripts/04_install_qubes.sh @@ -17,8 +17,8 @@ fi APKTOOLS_CACHE_DIR="${CACHEDIR}/apk_cache" ALPINELINUX_VERSION=${DIST_VER:-latest-stable} -QUBESALPINE_MIRROR="${QUBESALPINE_MIRROR:-https://lab.ilot.io/ayakael/repo-apk/-/raw}" -QUBESALPINE_KEYFILE="${QUBESALPINE_KEYFILE:-antoine.martin@protonmail.com-5b3109ad.rsa.pub}" +QUBESALPINE_MIRROR="${QUBESALPINE_MIRROR:-https://ayakael.net/api/packages/forge/alpine}" +QUBESALPINE_KEYFILE="${QUBESALPINE_KEYFILE:-https://ayakael.net/api/packages/forge/alpine/key}" QUBES_REL="${QUBES_REL:-r4.2}" export APK_CACHE_DIR @@ -28,8 +28,10 @@ if [ "$VERBOSE" -ge 2 ] || [ "$DEBUG" -gt 0 ]; then fi echo " --> Adding Qubes custom repository..." -su -c "echo '$QUBESALPINE_MIRROR/$ALPINELINUX_VERSION/qubes/$QUBES_REL' >> $INSTALLDIR/etc/apk/repositories" -wget "$QUBESALPINE_MIRROR/$ALPINELINUX_VERSION/$QUBESALPINE_KEYFILE" -P "$INSTALLDIR"/etc/apk/keys +su -c "echo '$QUBESALPINE_MIRROR/$ALPINELINUX_VERSION/qubes-$QUBES_REL' >> $INSTALLDIR/etc/apk/repositories" +pushd "$INSTALLDIR"/etc/apk/keys +curl -JO "$QUBESALPINE_KEYFILE" +popd echo " --> Synchronize resolv.conf..." cp /etc/resolv.conf "${INSTALLDIR}/etc/resolv.conf" diff --git a/scripts/alpine-chroot b/scripts/alpine-chroot index 0728f32..ca2cc2f 100755 --- a/scripts/alpine-chroot +++ b/scripts/alpine-chroot @@ -31,7 +31,7 @@ chroot_setup() { chroot_add_mount sys "$1/sys" -t sysfs -o nosuid,noexec,nodev,ro && # alpine-chroot will never have occasion to use efivars, so don't bother # mounting efivarfs here - chroot_add_mount udev "$1/dev" -t devtmpfs -o mode=0755,nosuid && + chroot_add_mount /dev "$1/dev" -o bind && chroot_add_mount devpts "$1/dev/pts" -t devpts -o mode=0620,gid=5,nosuid,noexec && chroot_add_mount shm "$1/dev/shm" -t tmpfs -o mode=1777,nosuid,nodev && chroot_add_mount run "$1/run" -t tmpfs -o nosuid,nodev,mode=0755 &&