diff --git a/README b/README
index 86afc4e..d5b07b3 100644
--- a/README
+++ b/README
@@ -1,88 +1,34 @@
-parabola-arm-imagebuilder
-=========================
+parabola-imagebuilder
+=====================
+
+This is a collection of scripts creating parabola images for use with qemu.
image creation
--------------
-this is a collection of scripts creating parabola arm images for use with qemu
-with the original goal of building parabola arm packages on these machines.
-Development focus has since shifted towards creating parabola-arm release
-tarballs.
-
-to create a new virtual machine image, run
+To create a new virtual machine image, run
$> sudo ./create.sh
-by default, the creation script will use a ParabolaArm release tarball to
-create the virtual machine. Alternatively, to install an archlinuxarm tarball
-and migrating the installed system to parabola in-place, set the environment
-variable ARCHBOOTSTRAP to 1:
+The creation is influenced by the following environment variables:
- $> sudo ARCHBOOTSTRAP=1 ./create.sh
+ ARCH - the target architecture of the image. default: armv7h
-Optionally, to create a new virtual machine with a packaging environment, set
-the environment variable DEVSETUP to 1:
+ SIZE - the size of the root image. default: 64GiB
- $> sudo DEVSETUP=1 ./create.sh
+ MIRROR - the mirror used to pacstrap the image, anything valid in a `Server =`
+ line can go here.
+ default: https://redirector.parabola.nu/\$repo/os/\$arch}
-The packaging environment setup script makes use of several files and packages
-present on already setup parabola development machines. if your setup is
-different, you might have to modify src/stage3.sh accordingly.
+The created images are stored in the build/ directory.
-Places the scripts check the host machine for configuration files are:
- /etc/makepkg.conf - for PACKAGER and GPGKEY
- ~/.gnupg ~/.ssh ~/.gitconfig - copied verbatim to the VM
-
-The scripts assume that the following programs are available and in $PATH:
- qemu-img, qemu-system-arm
- wget
- parted
- mkfs.vfat, mkfs.ext4, mkswap
- bsdtar
- scp, ssh, ssh-keygen
- pacman
-
-The scripts also assume that you like vim :)
virtual machine start
---------------------
-to open a shell into the created machine, run
- $> ./start.sh [path to created image]
+To boot a created virtual machine, run
+ $> sudo ./boot.sh [path to created image]
-the start.sh script assumes that you want a throwaway session, so it will start
-the virtual machine in snapshot mode and drop you into an ssh session. Once you
-exit that session, the machine is shutdown and changes made to the image are
-discarded. This behavior can be changed using the following environment
-variables:
-
- FOREGROUND : set this to 1 to start a qemu serial connection instead of a ssh
- session. Useful to capture boot output.
-
- PERSISTENT : set this to 1 to make persistent changes to the image that are
- not discarded on shutdown.
-
-The username and password for the created image is parabola:parabola, or
-root:parabola respectively. If a packaging environment is setup, the system is
-configured for passwordless sudo for the parabola user and the package tree and
-a build chroot are prepared. have fun. also check out the .bashrc of the
-parabola user in the created virtual machine, for batch build integration based
-on task-spooler.
-
-tarball creation
-----------------
-
-to create a tarball from the created vm image, run
-
- $> sudo ./make_tarball.sh [path to created image]
-
-the tarball creation script assumes to operate on an image *without* packaging
-environment setup and will not perform additional cleanup operations if used on
-the wrong image. Things that are cleaned up are:
-
- /root/.ssh
- /etc/ssh/ssh_host_*
- /etc/pacman.d/gnupg
- /var/log/*
- /var/cache/*
- /lost+found
+The start.sh script assumes that you want a throwaway session, so it will start
+the virtual machine in snapshot mode, and changes during the session will be
+discarded.
diff --git a/boot.sh b/boot.sh
new file mode 100755
index 0000000..66eb1cf
--- /dev/null
+++ b/boot.sh
@@ -0,0 +1,134 @@
+#!/bin/bash
+ ##############################################################################
+ # parabola-imagebuilder #
+ # #
+ # Copyright (C) 2017 Andreas Grapentin #
+ # #
+ # This program is free software: you can redistribute it and/or modify #
+ # it under the terms of the GNU General Public License as published by #
+ # the Free Software Foundation, either version 3 of the License, or #
+ # (at your option) any later version. #
+ # #
+ # This program is distributed in the hope that it will be useful, #
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+ # GNU General Public License for more details. #
+ # #
+ # You should have received a copy of the GNU General Public License #
+ # along with this program. If not, see . #
+ ##############################################################################
+ # this is a convenience script to start a created VM
+ ##############################################################################
+
+# common directories
+startdir="$(pwd)"
+export TOPBUILDDIR="$startdir"/build
+export TOPSRCDIR="$startdir"/src
+mkdir -p "$TOPBUILDDIR"
+chown "$SUDO_USER" "$TOPBUILDDIR"
+
+# shellcheck source=src/shared/common.sh
+. "$TOPSRCDIR"/shared/common.sh
+
+# sanity checks
+if [ "$(id -u)" -ne 0 ]; then
+ die -e "$ERROR_INVOCATION" "must be root"
+fi
+
+# shellcheck source=src/qemu.sh
+. "$TOPSRCDIR"/qemu.sh
+
+check_kernel_arch() {
+ echo -n "checking for kernel name ..."
+ local kernel
+ kernel=$(find "$1" -maxdepth 1 -type f -iname '*vmlinu*' | head -n1)
+ [ -n "$kernel" ] || kernel=no
+ echo "$(basename "$kernel")"
+
+ [ "x$kernel" != "xno" ] || return
+
+ # check if the kernel has an elf header and extract arch
+
+ echo -n "checking for kernel elf header ... "
+ set -o pipefail
+ machine=$(readelf -h "$kernel" 2>/dev/null | grep Machine | awk '{print $2}') || machine=no
+ set +o pipefail
+ echo "$machine"
+
+ [ "x$machine" != "xno" ] && return
+
+ # no elf header? maybe arm?
+
+ echo -n "checking for ARM boot executable ... "
+ local is_arm=no
+ file "$kernel" | grep -q 'ARM boot executable' && is_arm=yes
+ echo "$is_arm"
+ [ "x$is_arm" == "xyes" ] && machine=ARM
+
+ [ "x$machine" != "xno" ] && return
+
+ # no idea, just bail.
+
+ error "unable to extract kernel arch from image"
+ return "$ERROR_MISSING"
+}
+
+qemu_setargs_arm() {
+ qemu_args=(
+ -snapshot
+ -nographic
+ -machine vexpress-a9
+ -cpu cortex-a9
+ -m 1G
+ -kernel "$1"/vmlinuz-linux-libre
+ -dtb "$1"/dtbs/linux-libre/vexpress-v2p-ca9.dtb
+ -initrd "$1"/initramfs-linux-libre.img
+ --append "console=ttyAMA0 rw root=/dev/mmcblk0p3"
+ -drive if=sd,driver=raw,cache=writeback,file="$2"
+ )
+}
+
+qemu_setargs_riscv64() {
+ qemu_args=(
+ -snapshot
+ -nographic
+ -machine virt
+ -m 2G
+ -kernel bbl
+ -append "console=ttyS0 rw root=/dev/vda"
+ -drive file="${3}p3",format=raw,id=hd0
+ -device virtio-blk-device,drive=hd0
+ -object rng-random,filename=/dev/urandom,id=rng0
+ -device virtio-rng-device,rng=rng0
+ -device virtio-net-device,netdev=usernet
+ -netdev user,id=usernet
+ )
+}
+
+boot_from_image() {
+ [ -f "$1" ] || die "$1: image does not exist"
+
+ local loopdev
+ qemu_img_losetup "$1" || return
+
+ # mount the boot partition
+ mkdir -p "$TOPBUILDDIR"/mnt
+ mount "${loopdev}p1" "$TOPBUILDDIR"/mnt || return
+ trap_add "umount -R $TOPBUILDDIR/mnt" INT TERM EXIT
+
+ local machine
+ check_kernel_arch "$TOPBUILDDIR"/mnt || return
+
+ case "$machine" in
+ RISC-V) arch=riscv64 ;;
+ ARM) arch=arm ;;
+ *) error "unrecognized machine '$machine'"
+ return "$ERROR_UNSPECIFIED" ;;
+ esac
+
+ qemu_args=()
+ "qemu_setargs_$arch" "$TOPBUILDDIR"/mnt "$1" "$loopdev"
+ QEMU_AUDIO_DRV=none "qemu-system-$arch" "${qemu_args[@]}"
+}
+
+boot_from_image "$1" || die "boot failed"
diff --git a/create.sh b/create.sh
index f3e4e6d..efefe59 100755
--- a/create.sh
+++ b/create.sh
@@ -1,8 +1,8 @@
#!/bin/bash
##############################################################################
- # parabola-arm-imagebuilder #
+ # parabola-imagebuilder #
# #
- # Copyright (C) 2017 Andreas Grapentin #
+ # Copyright (C) 2017, 2018 Andreas Grapentin #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
@@ -18,48 +18,30 @@
# along with this program. If not, see . #
##############################################################################
-set -eu
-
-die() { echo "$*" 1>&2 ; exit 1; }
-
-# this script prepares an armv7h parabola image for use with start.sh
-
-[ $(id -u) -ne 0 ] && die "must be root"
-[ -z "${SUDO_USER:-}" ] && die "SUDO_USER not set"
-
-export OUTFILE="${OUTFILE:-armv7h.img}"
+# target options
+export ARCH="${ARCH:-armv7h}"
export SIZE="${SIZE:-64G}"
-export ARCHTARBALL="${ARCHTARBALL:-ArchLinuxARM-armv7-latest.tar.gz}"
-export PARABOLATARBALL="${PARABOLATARBALL:-ParabolaARM-armv7-LATEST.tar.gz}"
+export MIRROR="${MIRROR:-https://redirector.parabola.nu/\$repo/os/\$arch}"
-export _builddir=build
-mkdir -p "$_builddir"
-chown $SUDO_USER "$_builddir"
+# common directories
+startdir="$(pwd)"
+export TOPBUILDDIR="$startdir"/build
+export TOPSRCDIR="$startdir"/src
+mkdir -p "$TOPBUILDDIR"
+chown "$SUDO_USER" "$TOPBUILDDIR"
-export _outfile="$_builddir/$(basename "$OUTFILE")"
+# shellcheck source=src/shared/common.sh
+. "$TOPSRCDIR"/shared/common.sh
-# prepare the empty image
-./src/stage0.sh
-
-if [ -n "${ARCHBOOTSTRAP:-}" ]; then
- # install a clean archlinux-arm system in the empty image
- wget -nc http://os.archlinuxarm.org/os/$ARCHTARBALL
- TARBALL="$ARCHTARBALL" ./src/stage1.sh
-
- # migrate the installed image to a clean parabola
- ./src/stage2.sh
-else
- # install a clean parabola-arm system in the empty image
- wget -nc https://repo.parabola.nu/iso/arm/LATEST/$PARABOLATARBALL
- TARBALL="$PARABOLATARBALL" ./src/stage1.sh
+# sanity checks
+if [ "$(id -u)" -ne 0 ]; then
+ die -e "$ERROR_INVOCATION" "must be root"
fi
-# setup package development environment
-[ -n "${DEVSETUP:-}" ] && ./src/stage3.sh
+# shellcheck source=src/qemu.sh
+. "$TOPSRCDIR"/qemu.sh
-# cleanup
-chown $SUDO_USER $_outfile
-mv -v "$_outfile" "$OUTFILE"
-rm -rf "$_builddir"
+qemu_make_image "$TOPBUILDDIR/parabola-$ARCH.img" "$SIZE" \
+ || die "failed to prepare qemu base image"
-echo "all done :)"
+msg "all done."
diff --git a/make_tarball.sh b/make_tarball.sh
deleted file mode 100755
index 56f56f4..0000000
--- a/make_tarball.sh
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/bin/bash
- ##############################################################################
- # parabola-arm-imagebuilder #
- # #
- # Copyright (C) 2017 Andreas Grapentin #
- # #
- # This program is free software: you can redistribute it and/or modify #
- # it under the terms of the GNU General Public License as published by #
- # the Free Software Foundation, either version 3 of the License, or #
- # (at your option) any later version. #
- # #
- # This program is distributed in the hope that it will be useful, #
- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
- # GNU General Public License for more details. #
- # #
- # You should have received a copy of the GNU General Public License #
- # along with this program. If not, see . #
- ##############################################################################
-
-set -eu
-
-die() { echo "$*" 1>&2 ; exit 1; }
-
-[ $(id -u) -ne 0 ] && die "must be root"
-
-_builddir=build
-mkdir -p "$_builddir"
-
-_imagefile="$_builddir/$(basename "$1")"
-cp $1 $_imagefile
-_rootdir="$_builddir"/root-$$
-
-_loopdev=$(sudo losetup -f --show "$_imagefile")
-sudo partprobe $_loopdev
-
-# register a cleanup error handler
-function cleanup {
- sudo umount ${_loopdev}p1
- sudo umount ${_loopdev}p3
- sudo losetup -d $_loopdev
- rm -rf "$_rootdir" "$_imagefile"
-}
-trap cleanup ERR
-
-# mount the image
-mkdir -p "$_rootdir"
-sudo mount ${_loopdev}p3 "$_rootdir"
-sudo mount ${_loopdev}p1 "$_rootdir"/boot
-
-# clean the image
-rm -fvr \
- "$_rootdir"/root/.ssh \
- "$_rootdir"/etc/ssh/ssh_host_* \
- "$_rootdir"/var/log/* \
- "$_rootdir"/var/cache/* \
- "$_rootdir"/lost+found
-
-# create the tarball
-tar -czf ParabolaARM-armv7-$(date "+%Y-%m-%d").tar.gz -C "$_rootdir" .
-
-# cleanup
-sudo umount ${_loopdev}p1
-sudo umount ${_loopdev}p3
-sudo losetup -d $_loopdev
-rm -rf "$_rootdir" "$_imagefile"
diff --git a/release_tarball.sh b/release_tarball.sh
deleted file mode 100755
index b879995..0000000
--- a/release_tarball.sh
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/bash
- ##############################################################################
- # parabola-arm-imagebuilder #
- # #
- # Copyright (C) 2017 Andreas Grapentin #
- # #
- # This program is free software: you can redistribute it and/or modify #
- # it under the terms of the GNU General Public License as published by #
- # the Free Software Foundation, either version 3 of the License, or #
- # (at your option) any later version. #
- # #
- # This program is distributed in the hope that it will be useful, #
- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
- # GNU General Public License for more details. #
- # #
- # You should have received a copy of the GNU General Public License #
- # along with this program. If not, see . #
- ##############################################################################
-
-set -eu
-set -x
-
-die() { echo "$*" 1>&2 ; exit 1; }
-
-_tarball=$1
-
-# parse date from tarball
-_date=$(echo "${_tarball%.tar.gz}" | rev | cut -d'-' -f1-3 | rev)
-
-# create checksums
-sha512sum $_tarball > SHA512SUMS
-whirlpool-hash $_tarball > WHIRLPOOLSUMS
-
-# sign tarball and checksum
-gpg --detach-sign $_tarball
-gpg --detach-sign SHA512SUMS
-gpg --detach-sign WHIRLPOOLSUMS
-
-# upload tarball and checksum
-_repopath="/srv/repo/main/iso/arm/$_date"
-ssh repo@repo "mkdir -p $_repopath"
-scp $_tarball{,.sig} SHA512SUMS{,.sig} WHIRLPOOLSUMS{,.sig} repo@repo:$_repopath/
-
-# update LATEST symlinks
-ssh repo@repo "mkdir -p $_repopath/../LATEST"
-for f in $_tarball{,.sig} SHA512SUMS{,.sig} WHIRLPOOLSUMS{,.sig}; do
- ssh repo@repo "ln -fs ../$_date/$f $_repopath/../LATEST/$(echo $f | sed "s/$_date/LATEST/g")"
-done
-
-# cleanup
-rm -rf $_tarball.sig SHA512SUMS{,.sig} WHIRLPOOLSUMS{,.sig}
diff --git a/src/qemu.sh b/src/qemu.sh
new file mode 100644
index 0000000..4d0f6a9
--- /dev/null
+++ b/src/qemu.sh
@@ -0,0 +1,150 @@
+#!/bin/bash
+ ##############################################################################
+ # parabola-arm-imagebuilder #
+ # #
+ # Copyright (C) 2018 Andreas Grapentin #
+ # #
+ # This program is free software: you can redistribute it and/or modify #
+ # it under the terms of the GNU General Public License as published by #
+ # the Free Software Foundation, either version 3 of the License, or #
+ # (at your option) any later version. #
+ # #
+ # This program is distributed in the hope that it will be useful, #
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+ # GNU General Public License for more details. #
+ # #
+ # You should have received a copy of the GNU General Public License #
+ # along with this program. If not, see . #
+ ##############################################################################
+
+qemu_img_partition_and_mount_for_armv7h() {
+ parted -s "$1" \
+ mklabel gpt \
+ mkpart ESP fat32 1MiB 513MiB \
+ set 1 boot on \
+ mkpart primary linux-swap 513MiB 4609MiB \
+ mkpart primary ext4 4609MiB 100% || return
+
+ check_exe -r mkfs.vfat mkfs.ext4
+
+ mkfs.vfat -F 32 "${1}p1"
+ mkswap "${1}p2"
+ mkfs.ext4 "${1}p3"
+
+ mkdir -p "$2"
+ mount "${1}p3" "$2" || return
+ trap_add "umount -R $2" INT TERM EXIT
+ mkdir -p "$2"/boot
+ mount "${1}p1" "$2"/boot || return
+}
+
+qemu_img_partition_and_mount_for_riscv64() {
+ parted -s "$1" \
+ mklabel gpt \
+ mkpart primary ext2 1MiB 513MiB \
+ set 1 boot on \
+ mkpart primary linux-swap 513MiB 4609MiB \
+ mkpart primary ext4 4609MiB 100% || return
+
+ check_exe mkfs.ext2 mkfs.ext4
+
+ mkfs.ext2 "${1}p1"
+ mkswap "${1}p2"
+ mkfs.ext4 "${1}p3"
+
+ mkdir -p "$2"
+ mount "${1}p3" "$2" || return
+ trap_add "umount -R $2" INT TERM EXIT
+ mkdir -p "$2"/boot
+ mount "${1}p1" "$2"/boot || return
+}
+
+qemu_img_losetup() {
+ echo -n "checking for free loop device ... "
+ loopdev=$(losetup -f --show "$1") || loopdev=no
+ echo "$loopdev"
+
+ [ "x$loopdev" == "xno" ] && return "$ERROR_MISSING"
+
+ trap_add "qemu_img_lorelease $loopdev" INT TERM EXIT
+}
+
+qemu_img_lorelease() {
+ losetup -d "$1"
+}
+
+qemu_setup_user_static() {
+ # borrowed from /usr/bin/librechroot
+ local setarch interpreter
+ case "$ARCH" in
+ armv7h) setarch=armv7l; interpreter=/usr/bin/qemu-arm- ;;
+ *) setarch="$ARCH"; interpreter=/usr/bin/qemu-"$ARCH"- ;;
+ esac
+
+ if ! setarch "$setarch" /bin/true 2>/dev/null; then
+ # target arch can't execute natively, pacstrap is going to need help by qemu
+ # Make sure that qemu-static is set up with binfmt_misc
+ if [[ -z $(grep -l -F \
+ -e "interpreter $interpreter" \
+ -r -- /proc/sys/fs/binfmt_misc 2>/dev/null \
+ | xargs -r grep -xF 'enabled') ]]
+ then
+ error "unable to continue - need qemu-user-static for $ARCH"
+ return "$ERROR_MISSING"
+ fi
+
+ mkdir -p "$1"/usr/bin
+ cp -v "$interpreter"* "$1"/usr/bin || return
+ trap_add "qemu_cleanup_user_static $1"
+ fi
+}
+
+qemu_cleanup_user_static() {
+ rm -f "$1"/usr/bin/qemu-*
+}
+
+qemu_make_image() {
+ msg "preparing parabola qemu image for $ARCH"
+
+ # skip, if already exists
+ check_file "$1" && return
+
+ check_exe -r parted
+
+ # write to preliminary file
+ local tmpfile="$1.part"
+ rm -f "$tmpfile"
+
+ # create an empty image
+ qemu-img create -f raw "$tmpfile" "$2" || return
+
+ # create a minimal pacman.conf
+ cat > "$TOPBUILDDIR/pacman.conf.$ARCH" << EOF
+[options]
+Architecture = $ARCH
+[libre]
+Server = $MIRROR
+[core]
+Server = $MIRROR
+[extra]
+Server = $MIRROR
+[community]
+Server = $MIRROR
+EOF
+
+ # setup the image (in a subshell for trap management)
+ (
+ loopdev=''
+ qemu_img_losetup "$tmpfile" || return
+
+ dd if=/dev/zero of="$loopdev" bs=1M count=8 || return
+ "qemu_img_partition_and_mount_for_$ARCH" "$loopdev" "$TOPBUILDDIR"/mnt || return
+
+ qemu_setup_user_static "$TOPBUILDDIR"/mnt || return
+
+ pacstrap -GMcd -C "$TOPBUILDDIR/pacman.conf.$ARCH" "$TOPBUILDDIR"/mnt || return
+ ) || return
+
+ mv "$tmpfile" "$1"
+}
diff --git a/src/shared/checks.sh b/src/shared/checks.sh
new file mode 100644
index 0000000..38a94dc
--- /dev/null
+++ b/src/shared/checks.sh
@@ -0,0 +1,100 @@
+#!/bin/bash
+ ##############################################################################
+ # parabola-imagebuilder #
+ # #
+ # Copyright (C) 2018 Andreas Grapentin #
+ # #
+ # This program is free software: you can redistribute it and/or modify #
+ # it under the terms of the GNU General Public License as published by #
+ # the Free Software Foundation, either version 3 of the License, or #
+ # (at your option) any later version. #
+ # #
+ # This program is distributed in the hope that it will be useful, #
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+ # GNU General Public License for more details. #
+ # #
+ # You should have received a copy of the GNU General Public License #
+ # along with this program. If not, see . #
+ ##############################################################################
+
+check_exe() {
+ local OPTIND o r=
+ while getopts "r" o; do
+ case "$o" in
+ r) r=yes ;;
+ *) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-r] program ..." ;;
+ esac
+ done
+ shift $((OPTIND-1))
+
+ local v res=0
+ for v in "$@"; do
+ echo -n "checking for $v in \$PATH ... "
+
+ local have_exe=yes
+ type -p "$v" >/dev/null || have_exe=no
+ echo $have_exe
+
+ if [ "x$have_exe" != "xyes" ]; then
+ [ "x$r" == "xyes" ] && die -e "$ERROR_MISSING" "missing $v in \$PATH"
+ res="$ERROR_MISSING"
+ fi
+ done
+
+ return "$res"
+}
+
+check_file() {
+ local OPTIND o r=
+ while getopts "r" o; do
+ case "$o" in
+ r) r=yes ;;
+ *) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-r] file ..." ;;
+ esac
+ done
+ shift $((OPTIND-1))
+
+ local v res=0
+ for v in "$@"; do
+ echo -n "checking for $v ... "
+
+ local have_file=yes
+ [ -f "$v" ] || have_file=no
+ echo $have_file
+
+ if [ "x$have_file" != "xyes" ]; then
+ [ "x$r" == "xyes" ] && die -e "$ERROR_MISSING" "missing $v in filesystem"
+ res="$ERROR_MISSING"
+ fi
+ done
+
+ return "$res"
+}
+
+check_gpgkey() {
+ local OPTIND o r=
+ while getopts "r" o; do
+ case "$o" in
+ r) r=yes ;;
+ *) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-r] key" ;;
+ esac
+ done
+ shift $((OPTIND-1))
+
+ local v res=0
+ for v in "$@"; do
+ echo -n "checking for key $v ... "
+
+ local have_key=yes
+ sudo -u "$SUDO_USER" gpg --list-keys "$v" &>/dev/null || have_key=no
+ echo $have_key
+
+ if [ "x$have_key" != "xyes" ]; then
+ [ "x$r" == "xyes" ] && die -e "$ERROR_MISSING" "missing $v in keyring"
+ res="$ERROR_MISSING"
+ fi
+ done
+
+ return "$res"
+}
diff --git a/src/shared/common.sh b/src/shared/common.sh
new file mode 100644
index 0000000..62dfb15
--- /dev/null
+++ b/src/shared/common.sh
@@ -0,0 +1,68 @@
+#!/bin/bash
+ ##############################################################################
+ # parabola-imagebuilder #
+ # #
+ # Copyright (C) 2018 Andreas Grapentin #
+ # #
+ # This program is free software: you can redistribute it and/or modify #
+ # it under the terms of the GNU General Public License as published by #
+ # the Free Software Foundation, either version 3 of the License, or #
+ # (at your option) any later version. #
+ # #
+ # This program is distributed in the hope that it will be useful, #
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+ # GNU General Public License for more details. #
+ # #
+ # You should have received a copy of the GNU General Public License #
+ # along with this program. If not, see . #
+ ##############################################################################
+
+# shellcheck source=src/shared/feedback.sh
+. "$TOPSRCDIR"/shared/feedback.sh
+# shellcheck source=src/shared/checks.sh
+. "$TOPSRCDIR"/shared/checks.sh
+
+retry() {
+ local OPTIND o n=5 s=60
+ while getopts "n:s:" o; do
+ case "$o" in
+ n) n="$OPTARG" ;;
+ s) s="$OPTARG" ;;
+ *) die -e $ERROR_INVOCATION "Usage: ${FUNCNAME[0]} [-n tries] [-s delay] cmd ..." ;;
+ esac
+ done
+ shift $((OPTIND-1))
+
+ for _ in $(seq "$((n - 1))"); do
+ "$@" && return 0
+ sleep "$s"
+ done
+ "$@" || return
+}
+
+# appends a command to a trap
+# source: https://stackoverflow.com/questions/3338030/multiple-bash-traps-for-the-same-signal
+#
+# - 1st arg: code to add
+# - remaining args: names of traps to modify
+#
+trap_add() {
+ trap_add_cmd=$1; shift || fatal "${FUNCNAME[0]} usage error"
+ for trap_add_name in "$@"; do
+ trap -- "$(
+ # helper fn to get existing trap command from output
+ # of trap -p
+ extract_trap_cmd() { printf '%s\n' "$3"; }
+ # print the new trap command
+ printf '%s\n' "${trap_add_cmd}"
+ # print existing trap command with newline
+ eval "extract_trap_cmd $(trap -p "${trap_add_name}")"
+ )" "${trap_add_name}" \
+ || fatal "unable to add to trap ${trap_add_name}"
+ done
+}
+# set the trace attribute for the above function. this is
+# required to modify DEBUG or RETURN traps because functions don't
+# inherit them unless the trace attribute is set
+declare -f -t trap_add
diff --git a/src/stage0.sh b/src/shared/feedback.sh
old mode 100755
new mode 100644
similarity index 63%
rename from src/stage0.sh
rename to src/shared/feedback.sh
index 9994e22..ff050e7
--- a/src/stage0.sh
+++ b/src/shared/feedback.sh
@@ -1,8 +1,8 @@
#!/bin/bash
##############################################################################
- # parabola-arm-imagebuilder #
+ # parabola-imagebuilder #
# #
- # Copyright (C) 2017 Andreas Grapentin #
+ # Copyright (C) 2018 Andreas Grapentin #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
@@ -18,8 +18,34 @@
# along with this program. If not, see . #
##############################################################################
-set -eu
+# error codes
+export ERROR_UNSPECIFIED=1
+export ERROR_INVOCATION=2
+export ERROR_MISSING=3
+export ERROR_BUILDFAIL=4
+export ERROR_KEYFAIL=5
-# create an empty qemu image
-rm -f $_outfile
-qemu-img create -f raw $_outfile $SIZE
+# messaging functions
+msg() {
+ echo "$(tput bold)$(tput setf 2)==>$(tput setf 7) $*$(tput sgr0)";
+}
+
+error() {
+ echo "$(tput bold)$(tput setf 4)==> ERROR:$(tput setf 7) $*$(tput sgr0)" 1>&2
+}
+
+die() {
+ local OPTIND o e="$ERROR_UNSPECIFIED"
+ while getopts "e:" o; do
+ case "$o" in
+ e) e="$OPTARG" ;;
+ *) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-e status] msg ..." ;;
+ esac
+ done
+ shift $((OPTIND-1))
+
+ error "$@"
+ trap - ERR
+ exit "$e"
+}
+trap 'die "unknown error"' ERR
diff --git a/src/stage1.sh b/src/stage1.sh
deleted file mode 100755
index 595ec5a..0000000
--- a/src/stage1.sh
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/bin/bash
- ##############################################################################
- # parabola-arm-imagebuilder #
- # #
- # Copyright (C) 2017 Andreas Grapentin #
- # #
- # This program is free software: you can redistribute it and/or modify #
- # it under the terms of the GNU General Public License as published by #
- # the Free Software Foundation, either version 3 of the License, or #
- # (at your option) any later version. #
- # #
- # This program is distributed in the hope that it will be useful, #
- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
- # GNU General Public License for more details. #
- # #
- # You should have received a copy of the GNU General Public License #
- # along with this program. If not, see . #
- ##############################################################################
-
-set -eu
-
-_bootdir="$_builddir/boot"
-_rootdir="$_builddir/root"
-
-_loopdev=$(losetup -f --show "$_outfile")
-
-# setup an error exit handler for cleanup
-function cleanup {
- echo "exiting due to earlier errors..." >&2
- for part in p1 p3; do
- umount $_loopdev$part || true
- done
- losetup -d $_loopdev || true
- rm -rf "$_bootdir" "$_rootdir"
- rm -f "$_outfile"
-}
-trap cleanup ERR
-
-# the following installation instructions are adapted from
-# https://archlinuxarm.org/platforms/armv7/arm/versatile-express
-
-# partition the image
-dd if=/dev/zero of=$_loopdev bs=1M count=8
-parted -s $_loopdev \
- mklabel gpt \
- mkpart ESP fat32 1MiB 513MiB \
- set 1 boot on \
- mkpart primary linux-swap 513MiB 4609MiB \
- mkpart primary ext4 4609MiB 100%
-
-# create filesystems
-mkfs.vfat -F 32 ${_loopdev}p1
-mkswap ${_loopdev}p2
-mkfs.ext4 ${_loopdev}p3
-
-# install the base image
-mkdir -p "$_bootdir"
-mkdir -p "$_rootdir"
-mount ${_loopdev}p1 "$_bootdir"
-mount ${_loopdev}p3 "$_rootdir"
-bsdtar -vxpf $TARBALL -C "$_rootdir"
-sync
-
-# fill the boot partition and create fstab
-mv -v "$_rootdir"/boot/* "$_bootdir"
-cat >> "$_rootdir"/etc/fstab << EOF
-/dev/mmcblk0p1 /boot vfat defaults 0 0
-/dev/mmcblk0p2 none swap defaults 0 0
-EOF
-
-# create and install root ssh keys for access
-mkdir -p keys
-test -f keys/id_rsa || ssh-keygen -N '' -f keys/id_rsa
-chown $SUDO_USER keys/id_rsa*
-mkdir -m 700 "$_rootdir"/root/.ssh
-install -m 600 -o 0 -g 0 keys/id_rsa.pub "$_rootdir"/root/.ssh/authorized_keys
-
-# create and install ssh host keys
-for cipher in dsa ecdsa ed25519 rsa; do
- if [ ! -f keys/ssh_host_${cipher}_key ]; then
- ssh-keygen -N '' -t ${cipher} -f keys/ssh_host_${cipher}_key
- fi
- install -m 600 -o 0 -g 0 keys/ssh_host_${cipher}_key "$_rootdir"/etc/ssh
- install -m 644 -o 0 -g 0 keys/ssh_host_${cipher}_key.pub "$_rootdir"/etc/ssh
-done
-
-# tie up any loose ends
-for part in p1 p3; do
- umount $_loopdev$part
-done
-losetup -d $_loopdev
-rm -rf "$_bootdir" "$_rootdir"
diff --git a/src/stage2.sh b/src/stage2.sh
deleted file mode 100755
index ec8a721..0000000
--- a/src/stage2.sh
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/bin/bash
- ##############################################################################
- # parabola-arm-imagebuilder #
- # #
- # Copyright (C) 2017 Andreas Grapentin #
- # #
- # This program is free software: you can redistribute it and/or modify #
- # it under the terms of the GNU General Public License as published by #
- # the Free Software Foundation, either version 3 of the License, or #
- # (at your option) any later version. #
- # #
- # This program is distributed in the hope that it will be useful, #
- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
- # GNU General Public License for more details. #
- # #
- # You should have received a copy of the GNU General Public License #
- # along with this program. If not, see . #
- ##############################################################################
-
-set -eu
-
-_scriptfile="$_builddir"/migrate.sh
-_pidfile="$_builddir"/qemu-$$.pid
-_bootdir="$_builddir"/boot-$$
-
-_loopdev=$(sudo losetup -f --show $_outfile)
-
-# register cleanup handler to stop the started VM
-function cleanup {
- test -f "$_pidfile" && (kill -9 $(cat "$_pidfile") || true)
- rm -f "$_pidfile"
- umount ${_loopdev}p1
- losetup -d $_loopdev
- rm -rf "$_bootdir"
- rm -f "$_scriptfile"
-}
-trap cleanup ERR
-
-# create the migration script, adapted from
-# https://wiki.parabola.nu/Migration_from_Arch_ARM
-cat > "$_scriptfile" << 'EOF'
-#!/bin/bash
-
-set -eu
-
-# install the keyrings and mirrorlist
-sed -i 's/^SigLevel.*/SigLevel = Never/' /etc/pacman.conf
-pacman --noconfirm -U https://www.parabola.nu/packages/libre/any/parabola-keyring/download/
-pacman --noconfirm -U https://www.parabola.nu/packages/libre/any/archlinux32-keyring/download/
-pacman --noconfirm -U https://www.parabola.nu/packages/core/any/archlinux-keyring/download/
-pacman --noconfirm -U https://www.parabola.nu/packages/libre/any/pacman-mirrorlist/download/
-pacman --noconfirm -S archlinuxarm-keyring
-sed -i 's/^SigLevel.*/SigLevel = Required DatabaseOptional/' /etc/pacman.conf
-
-# update the keyring
-pacman-key --init
-pacman-key --populate archlinuxarm archlinux archlinux32 parabola
-pacman-key --refresh-keys
-
-# install the mirrorlist
-[ -f /etc/pacman.d/mirrorlist.pacnew ] && mv /etc/pacman.d/mirrorlist{.pacnew,}
-
-# enable the [libre] and disable [alarm] in pacman.conf
-sed -i '/^\[core\]/i \
-[libre] \
-Include = /etc/pacman.d/mirrorlist \
-' /etc/pacman.conf
-sed -Ei '/^\[alarm\]|\[aur\]/,+2d' /etc/pacman.conf
-
-# clear the pacman cache. all of it.
-yes | pacman -Scc
-
-# fix the architecture in /etc/pacman.conf
-sed -i 's/^Architecture.*/Architecture = armv7h/' /etc/pacman.conf
-
-# update the system to parabola
-pacman --noconfirm -Syy
-pacman --noconfirm -S pacman
-mv /etc/pacman.conf{.pacnew,}
-pacman --noconfirm -Syyuu
-pacman --noconfirm -S your-freedom
-yes | pacman -S linux-libre
-
-# cleanup users
-userdel -r alarm
-useradd -mU parabola
-echo 'parabola:parabola' | chpasswd
-echo 'root:parabola' | chpasswd
-
-# cleanup hostname
-echo "parabola-arm" > /etc/hostname
-
-# enable UTF-8 locale
-sed -i 's/#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
-locale-gen
-sed -i 's/LANG.*/LANG=en_US.UTF-8/' /etc/locale.conf
-EOF
-chmod +x "$_scriptfile"
-
-# start the VM
-mkdir -p "$_bootdir"
-mount ${_loopdev}p1 $_bootdir
-QEMU_AUDIO_DRV=none qemu-system-arm \
- -M vexpress-a9 \
- -m 1G \
- -dtb "$_bootdir"/dtbs/vexpress-v2p-ca9.dtb \
- -kernel "$_bootdir"/zImage \
- --append "root=/dev/mmcblk0p3 rw roottype=ext4 console=ttyAMA0" \
- -drive if=sd,driver=raw,cache=writeback,file="$_outfile" \
- -display none \
- -net user,hostfwd=tcp::2022-:22 \
- -net nic \
- -daemonize \
- -pidfile "$_pidfile"
-
-# wait for ssh to be up
-while ! ssh -p 2022 -i keys/id_rsa root@localhost -o StrictHostKeyChecking=no true 2>/dev/null; do
- echo -n . && sleep 5
-done && echo
-
-# copy and execute the migration script
-scp -P 2022 -i keys/id_rsa "$_scriptfile" root@localhost:
-ssh -p 2022 -i keys/id_rsa root@localhost "./$(basename "$_scriptfile")"
-
-# stop the VM
-ssh -p 2022 -i keys/id_rsa root@localhost "nohup shutdown -h now &>/dev/null & exit"
-while kill -0 $(cat "$_pidfile") 2> /dev/null; do echo -n . && sleep 5; done && echo
-
-# cleanup
-umount ${_loopdev}p1
-losetup -d $_loopdev
-rm -rf "$_bootdir" "$_scriptfile" "$_pidfile"
diff --git a/src/stage3.sh b/src/stage3.sh
deleted file mode 100755
index a9efaea..0000000
--- a/src/stage3.sh
+++ /dev/null
@@ -1,167 +0,0 @@
-#!/bin/bash
- ##############################################################################
- # parabola-arm-imagebuilder #
- # #
- # Copyright (C) 2017 Andreas Grapentin #
- # #
- # This program is free software: you can redistribute it and/or modify #
- # it under the terms of the GNU General Public License as published by #
- # the Free Software Foundation, either version 3 of the License, or #
- # (at your option) any later version. #
- # #
- # This program is distributed in the hope that it will be useful, #
- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
- # GNU General Public License for more details. #
- # #
- # You should have received a copy of the GNU General Public License #
- # along with this program. If not, see . #
- ##############################################################################
-
-set -eu
-
-_scriptfile="$_builddir"/migrate.sh
-_pidfile="$_builddir"/qemu-$$.pid
-_bootdir="$_builddir"/boot-$$
-
-_loopdev=$(sudo losetup -f --show "$_outfile")
-
-# register cleanup handler to stop the started VM
-function cleanup {
- test -f "$_pidfile" && (kill -9 $(cat "$_pidfile") || true)
- rm -f "$_pidfile"
- umount ${_loopdev}p1
- losetup -d $_loopdev
- rm -rf "$_bootdir"
- rm -f "$_scriptfile"
-}
-trap cleanup ERR
-
-# create the package build preparation script, adapted from
-# https://wiki.parabola.nu/Package_maintainer_guide
-(source /etc/makepkg.conf && cat > "$_scriptfile" << EOF
-#!/bin/bash
-
-set -eu
-
-# setup parabola login keys
-cat /root/.ssh/authorized_keys >> /home/parabola/.ssh/authorized_keys
-
-# fix key permissions and ownership
-chown -R parabola:parabola /home/parabola/{.gnupg,.ssh,.gitconfig}
-chmod 600 /home/parabola/.ssh/authorized_keys
-
-# install needed packages
-pacman --noconfirm -S libretools base-devel vim sudo \
- rxvt-unicode-terminfo bash-completion htop
-
-# update configuration
-sed -i \
- -e 's_^#PKGDEST.*_PKGDEST="/home/parabola/output/packages"_' \
- -e 's_^#SRCDEST.*_SRCDEST="/home/parabola/output/sources"_' \
- -e 's_^#SRCPKGDEST.*_SRCPKGDEST="/home/parabola/output/srcpackages"_' \
- -e 's_^#LOGDEST.*_LOGDEST="/home/parabola/output/makepkglogs"_' \
- -e 's_^#PACKAGER.*_PACKAGER="$PACKAGER"_' \
- -e 's_^#GPGKEY.*_GPGKEY="$GPGKEY"_' \
- /etc/makepkg.conf
-
-sed -i \
- -e 's_^CHROOTDIR.*_CHROOTDIR="/home/parabola/build"_' \
- -e 's_^CHROOTEXTRAPKG.*_CHROOTEXTRAPKG=(vim)_' \
- /etc/libretools.d/chroot.conf
-
-sed -i \
- -e 's_^HOOKPOSTRELEASE.*_HOOKPOSTRELEASE=""_' \
- /etc/libretools.conf
-
-# create directories
-mkdir -p /home/parabola/output/{packages,sources,srcpackages,makepkglogs}
-chown -R parabola:parabola /home/parabola/output
-
-# disable systemd-stdin hack...
-sed -i '/XXX: SYSTEMD-STDIN HACK/,+9d' /usr/bin/librechroot
-
-# setup sudo
-cat > /etc/sudoers.d/parabola << IEOF
-# grant full permissions to user parabola
-parabola ALL=(ALL) NOPASSWD: ALL
-IEOF
-
-# setup work directories
-su - parabola -c createworkdir
-su - parabola -c "sudo librechroot make"
-
-# setup batch building
-pacman --noconfirm -S task-spooler
-
-cat >> /home/parabola/.bashrc << 'IEOF'
-
-alias sudo='sudo '
-
-function librespool() {
- local cmd
- printf -v cmd '%q ' "\$@"
- tsp -d script --return --quiet --command "\$cmd" /dev/null
-}
-
-alias librechroot-spool='librespool sudo /usr/bin/librechroot'
-alias libremakepkg-spool='librespool sudo /usr/bin/libremakepkg'
-
-alias qbuild='if tsp | grep " \$(pwd)\\$" >/dev/null; then tspr; fi && tsp echo \$(pwd) && librechroot-spool update && libremakepkg-spool && tsp -d librestage'
-
-alias tspr='d=\$(tsp | grep " \$(pwd)\\$" | head -n1 | cut -d" " -f1) && for i in \$(seq \$d \$((\$d+3))); do tsp -r \$i; done'
-alias tspl='watch -n5 tsp'
-alias tspc='while tsp | grep -q running; do tsp -c; done'
-
-alias librecommit='if tsp | grep " \$(pwd)\\$" >/dev/null; then tspr; fi && git commit -m "\$(pwd | rev | cut -d"/" -f1-2 | rev): updated to \$(bash -c "source PKGBUILD && echo \\\$pkgver")"'
-IEOF
-EOF
-)
-chmod +x "$_scriptfile"
-
-# start the VM
-mkdir -p "$_bootdir"
-mount ${_loopdev}p1 "$_bootdir"
-_board="vexpress-a9"
-_cpu="cortex-a9"
-_memory="1G"
-_kernel="$_bootdir"/vmlinuz-linux-libre
-_dtb="$_bootdir"/dtbs/linux-libre/vexpress-v2p-ca9.dtb
-_initrd="$_bootdir"/initramfs-linux-libre.img
-QEMU_AUDIO_DRV=none qemu-system-arm \
- -M $_board \
- -cpu $_cpu \
- -m $_memory \
- -kernel "$_kernel" \
- -dtb "$_dtb" \
- -initrd "$_initrd" \
- --append "root=/dev/mmcblk0p3 rw roottype=ext4 console=ttyAMA0" \
- -drive if=sd,driver=raw,cache=writeback,file="$_outfile" \
- -display none \
- -net user,hostfwd=tcp::2022-:22 \
- -net nic \
- -daemonize \
- -pidfile "$_pidfile"
-
-# wait for ssh to be up
-while ! ssh -p 2022 -i keys/id_rsa root@localhost -o StrictHostKeyChecking=no true 2>/dev/null; do
- echo -n . && sleep 5
-done && echo
-
-# copy the current users keys to the VM
-scp -rP 2022 -i keys/id_rsa "$(sudo -iu $SUDO_USER pwd)"/.gnupg root@localhost:/home/parabola/
-scp -rP 2022 -i keys/id_rsa "$(sudo -iu $SUDO_USER pwd)"/.ssh root@localhost:/home/parabola/
-scp -rP 2022 -i keys/id_rsa "$(sudo -iu $SUDO_USER pwd)"/.gitconfig root@localhost:/home/parabola/
-
-# copy and execute the migration script
-scp -P 2022 -i keys/id_rsa "$_scriptfile" root@localhost:
-ssh -p 2022 -i keys/id_rsa root@localhost "./$(basename "$_scriptfile")"
-
-# stop the VM
-ssh -p 2022 -i keys/id_rsa root@localhost "nohup shutdown -h now &>/dev/null & exit"
-while kill -0 $(cat "$_pidfile") 2> /dev/null; do echo -n . && sleep 5; done && echo
-
-# cleanup
-umount ${_loopdev}p1
-losetup -d $_loopdev
-rm -rf "$_bootdir" "$_scriptfile" "$_pidfile"
diff --git a/start.sh b/start.sh
deleted file mode 100755
index 5430b41..0000000
--- a/start.sh
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/bin/bash
- ##############################################################################
- # parabola-arm-imagebuilder #
- # #
- # Copyright (C) 2017 Andreas Grapentin #
- # #
- # This program is free software: you can redistribute it and/or modify #
- # it under the terms of the GNU General Public License as published by #
- # the Free Software Foundation, either version 3 of the License, or #
- # (at your option) any later version. #
- # #
- # This program is distributed in the hope that it will be useful, #
- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
- # GNU General Public License for more details. #
- # #
- # You should have received a copy of the GNU General Public License #
- # along with this program. If not, see . #
- ##############################################################################
-
-set -eu
-
-_builddir=build
-mkdir -p "$_builddir"
-
-_imagefile=$1
-_pidfile="$_builddir"/qemu-$$.pid
-_bootdir="$_builddir"/boot-$$
-
-_loopdev=$(sudo losetup -f --show "$_imagefile")
-sudo partprobe $_loopdev
-touch "$_pidfile"
-
-# register a cleanup error handler
-function cleanup {
- test -f "$_pidfile" && (sudo kill -9 $(cat "$_pidfile") || true)
- rm -f "$_pidfile"
- sudo umount ${_loopdev}p1
- sudo losetup -d $_loopdev
- rm -rf "$_bootdir"
-}
-trap cleanup ERR
-
-# start the VM
-mkdir -p "$_bootdir"
-sudo mount ${_loopdev}p1 "$_bootdir"
-_board="vexpress-a9"
-# FIXME: archlinuxarm rust SIGILLs on cortex-a9 cpus, using cortex-a15 for now
-_cpu="cortex-a15"
-_memory="1G"
-_snapshot=""
-[ -z "${PERSISTENT:-}" ] && _snapshot="-snapshot"
-_daemonize="-nographic -serial mon:stdio"
-[ -z "${FOREGROUND:-}" ] && _daemonize="-daemonize -pidfile $_pidfile -net user,hostfwd=tcp::2022-:22 -net nic -display none"
-if [ -f "$_bootdir"/zImage ]; then
- _kernel="$_bootdir"/zImage
- _dtb="$_bootdir"/dtbs/vexpress-v2p-ca9.dtb
- _initrd="$_bootdir"/initramfs-linux.img
-else
- _kernel="$_bootdir"/vmlinuz-linux-libre
- _dtb="$_bootdir"/dtbs/linux-libre/vexpress-v2p-ca9.dtb
- _initrd="$_bootdir"/initramfs-linux-libre.img
-fi
-QEMU_AUDIO_DRV=none qemu-system-arm \
- -M $_board \
- -cpu $_cpu \
- -m $_memory \
- -kernel "$_kernel" \
- -dtb "$_dtb" \
- -initrd "$_initrd" \
- --append "root=/dev/mmcblk0p3 rw roottype=ext4 console=ttyAMA0" \
- -drive if=sd,driver=raw,cache=writeback,file="$_imagefile" \
- $_daemonize \
- $_snapshot
-
-if [ -z "${FOREGROUND:-}" ]; then
- # wait for ssh to be up
- _sshopts="-o StrictHostKeyChecking=no -o ConnectTimeout=5"
- while ! ssh -p 2022 -i keys/id_rsa root@localhost $_sshopts true 2>/dev/null; do
- echo -n . && sleep 5
- done && echo
-
- # open a session
- ssh -p 2022 -i keys/id_rsa parabola@localhost
-
- # shutdown the VM
- ssh -p 2022 -i keys/id_rsa root@localhost "nohup shutdown -h now &>/dev/null & exit"
- while sudo kill -0 $(cat "$_pidfile") 2> /dev/null; do echo -n . && sleep 5; done && echo
-fi
-
-# cleanup
-sudo umount ${_loopdev}p1
-sudo losetup -d $_loopdev
-rm -rf "$_bootdir" "$_pidfile"