linux-qubasis

linux oasis port as a qubes template

git clone https://9o.is/git/linux-qubasis.git

commit a247ec7d8de977a356ff4df6869c7982607ecc41
parent 97f6f1b923f8538eec9d0e438a233bb31a879aa0
Author: Jul <jul@9o.is>
Date:   Sat, 13 Sep 2025 17:29:46 +0800

add qubes-install ninja script

Diffstat:
Dninja/fspec-img.sh | 29-----------------------------
Mninja/functions.sh | 29+++++++++++++++++++----------
Aninja/qubes-install.sh | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mninja/rules.ninja | 12++++++++----
Mtpl/example/gen.sh | 2+-
5 files changed, 117 insertions(+), 44 deletions(-)

diff --git a/ninja/fspec-img.sh b/ninja/fspec-img.sh @@ -1,29 +0,0 @@ -set -eu - -hostdir=out/host - -fspec=$1 -img_file=$2 -img_size=${3%M} -mnt=${img_file%/*}/mnt - -trap cleanup EXIT - -cleanup() { - sudo umount $mnt - sudo losetup --detach $loop - rmdir $mnt - fsck.ext4 -vf $img_file -} - -rm -rf $img_file $mnt -mkdir $mnt - -dd if=/dev/zero of=$img_file bs=1M count=$img_size >/dev/null 2>&1 -mke2fs -t ext4 $img_file >/dev/null 2>&1 - -loop=$(losetup --find) -sudo losetup $loop $img_file -sudo mount $loop $mnt - -$hostdir/fspec-tar <$fspec | sudo $hostdir/pax -r -s ",^[^/]*,$mnt," diff --git a/ninja/functions.sh b/ninja/functions.sh @@ -196,8 +196,11 @@ headers_exist() { return 1 } -build_img() { - _ninja_img_size="$1" +template() { + case $3 in + *M) _ninja_template="$1 $2 $(( ${3%M} * 1048576 ))";; + *) error image size "'$3'" must be suffixed by "'M'";; + esac } ## @@ -269,7 +272,7 @@ _ninja_initglobals() { _ninja_buffer_build= _ninja_buffer_fspec= _ninja_buffer_fspec_files= - _ninja_img_size= + _ninja_template= } _ninja_setv_init() { @@ -572,13 +575,19 @@ _ninja_flush_build() { fi ;; tpl) - if [ "$_ninja_img_size" ]; then - build fspec-img $outdir/root.img '|' $basedir/ninja/fspec-img.sh $hostdir/fspec-tar $hostdir/pax '||' $outdir/_fspec/ALL - bind img_size $_ninja_img_size - build phony $tgtdir/build $outdir/root.img - else - build touch $outdir/_fetch/build - build phony $tgtdir/build $outdir/_fetch/build + build fspec-tar $outdir/root.tar.zstd '|' $hostdir/fspec-tar '||' $outdir/_fspec/ALL + build phony $tgtdir/build $outdir/root.tar.zstd + + if [ "$_ninja_template" ]; then + set -- $_ninja_template + + build qubes-install $outdir/qubes-installed '|' $basedir/ninja/qubes-install.sh $hostdir/pax '||' $outdir/root.tar.zstd + bind template $1 + bind label $2 + bind size $3 + bind tar $outdir/root.tar.zstd + + build phony $tgtdir/install $outdir/qubes-installed fi ;; esac diff --git a/ninja/qubes-install.sh b/ninja/qubes-install.sh @@ -0,0 +1,89 @@ +set -eu + +hostdir=out/host + +template=$1 +label=$2 +size=$3 +tar=$4 +outdir=$5 + +tmpdir=$(mktemp -d) +mnt=$tmpdir/mnt +img=$tmpdir/root.img +loop= + +# Don't forget to add the following policies to dom0. Replace "{vm}" with the +# name of the this vm. +# +# admin.vm.Create.TemplateVM * {vm} dom0 allow target=dom0 +# admin.vm.volume.ImportWithSize +root {vm} @tag:created-by-{vm} allow target=dom0 + +trap cleanup EXIT + +cleanup() { + set +e + sudo umount $mnt 2>/dev/null + rm -rf $tmpdir + + if [ $loop ]; then + sudo losetup -d $loop 2>/dev/null + fi +} + +error() { + printf "Failed installing qubes template '%s': %s\n" "$template" "$*" + exit 1 +} + +create_image() { + count=$(( $size / (128 * 1024) )) + dd if=/dev/zero of=$img bs=128k count=$count >/dev/null 2>&1 + mke2fs -t ext4 $img #>/dev/null 2>&1 + + loop=$(losetup --find) + sudo losetup $loop $img + mkdir -p $mnt + sudo mount $loop $mnt + + zstd -d --stdout $tar | sudo $hostdir/pax -r -s ",^[^/]*,$mnt," + + sudo umount $mnt + sudo losetup -d $loop + fsck.ext4 -vf $img +} + +create_template() { + set -- $(printf "name=$template label=$label" | + qrexec-client-vm dom0 admin.vm.Create.TemplateVM | xargs -0) + + status=${1-1} + shift 2 + errmsg="${*-}" + + if [ $status -eq 0 ]; then + return + fi + + case "$errmsg" in + *'already exists') return;; + *) error "create template: $errmsg";; + esac +} + +import_volume() { + set -- $({ + printf '%s\n' "$(stat -c%s $img)" + cat $img + } | qrexec-client-vm $template admin.vm.volume.ImportWithSize+root | xargs -0) + + status=${1-1} + + if [ $status -ne 0 ]; then + error "volume import: $*" + fi +} + +create_template +create_image +import_volume diff --git a/ninja/rules.ninja b/ninja/rules.ninja @@ -57,10 +57,9 @@ rule fspec command = sh $basedir/ninja/fspec.sh $out $path $type $mode $in $target >/dev/null description = FSPEC $out -rule fspec-img - command = sh $basedir/ninja/fspec-img.sh $outdir/_fspec/ALL $out $img_size - description = FSPEC-IMG $out - pool = console +rule fspec-tar + command = $hostdir/fspec-tar <$outdir/_fspec/ALL | zstd >$out + description = FSPEC-TAR $out rule yacc command = $hostdir/yacc $yaccflags $in >/dev/null @@ -97,3 +96,8 @@ rule patch rule sed command = sed $expr $in >$out description = SED $out + +rule qubes-install + command = sh $basedir/ninja/qubes-install.sh $template $label $size $tar $outdir && touch $out + description = QUBES-INSTALL $template + pool = console diff --git a/tpl/example/gen.sh b/tpl/example/gen.sh @@ -1,4 +1,4 @@ -build_img 10M +template oasis-example black 12M dir /dev dir /tmp