From ced9aa0de94a9e8eeb0502b03bf29bedab126c8b Mon Sep 17 00:00:00 2001 From: Andreas Grapentin Date: Thu, 28 Dec 2017 16:09:01 +0100 Subject: [PATCH] producing parabola images now --- .gitignore | 7 ++++ create.sh | 66 +++++++++------------------------- src/stage0.sh | 7 ++++ src/stage1.sh | 65 ++++++++++++++++++++++++++++++++++ src/stage2.sh | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++ start.sh | 50 +++++++++++++++++++++----- 6 files changed, 235 insertions(+), 58 deletions(-) create mode 100755 src/stage0.sh create mode 100755 src/stage1.sh create mode 100755 src/stage2.sh diff --git a/.gitignore b/.gitignore index ef6b600..13cd0d6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,13 @@ # image files *.qcow2 *.raw +*.img # tarballs *.tar.* + +# build dirs +build/ + +# generated ssh keys +keys/* diff --git a/create.sh b/create.sh index e509b86..d1f811b 100755 --- a/create.sh +++ b/create.sh @@ -2,63 +2,29 @@ set -eu -# this script prepares an archlinuxarm image for use with start.sh +# this script prepares an armv7h parabola image for use with start.sh -OUTFILE=${OUTFILE:-armv7h.raw} -SIZE=${SIZE:-64G} - -_builddir=build -_outfile=$_builddir/$(basename $OUTFILE) +export OUTFILE=${OUTFILE:-armv7h.img} +export SIZE=${SIZE:-64G} +export ARCHTARBALL=${ARCHTARBALL:-ArchLinuxARM-armv7-latest.tar.gz} +export _builddir=build mkdir -p $_builddir -# create an empty image -rm -f $_outfile -qemu-img create -f raw $_outfile $SIZE +export _outfile=$_builddir/$(basename $OUTFILE) -# setup an available loop device -_loopdev=$(losetup -f --show $_outfile) +# prepare the empty image +./src/stage0.sh -# setup an error exit handler for cleanup -function cleanup { - echo "exiting due to earlier errors..." >&2 - for part in p1 p2; do - umount $_loopdev$part || true - done - losetup -d $_loopdev || true - rm -rf $_builddir/boot $_builddir/root - rm -f $_outfile -} -trap cleanup ERR +# install archlinuxarm in the empty image +./src/stage1.sh -# fetch latest archlinuxarm tarball -wget -nc http://os.archlinuxarm.org/os/ArchLinuxARM-armv7-latest.tar.gz +# migrate the installed image to parabola +./src/stage2.sh -# following are the installation instructions provided on -# https://archlinuxarm.org/platforms/armv7/arm/versatile-express -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 ext4 513MiB 100% -mkfs.vfat -F 32 ${_loopdev}p1 -mkdir -p $_builddir/boot -mount ${_loopdev}p1 $_builddir/boot -mkfs.ext4 ${_loopdev}p2 -mkdir $_builddir/root -mount ${_loopdev}p2 $_builddir/root -bsdtar -vxpf ArchLinuxARM-armv7-latest.tar.gz -C $_builddir/root -sync -mv -v $_builddir/root/boot/* $_builddir/boot -cat >> $_builddir/root/etc/fstab << EOF -/dev/mmcblk0p1 /boot vfat defaults 0 0 -EOF - -# tie up any loose ends -for part in p1 p2; do - umount $_loopdev$part -done -losetup -d $_loopdev +# cleanup +chown $(logname) $_outfile mv -v $_outfile $OUTFILE rm -rf $_builddir + +echo "all done :)" diff --git a/src/stage0.sh b/src/stage0.sh new file mode 100755 index 0000000..970e4a6 --- /dev/null +++ b/src/stage0.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -eu + +# create an empty qemu image +rm -f $_outfile +qemu-img create -f raw $_outfile $SIZE diff --git a/src/stage1.sh b/src/stage1.sh new file mode 100755 index 0000000..e106288 --- /dev/null +++ b/src/stage1.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +set -eu + +# setup an available loop device +_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 p2; do + umount $_loopdev$part || true + done + losetup -d $_loopdev || true + rm -rf $_builddir/boot $_builddir/root + rm -f $_outfile +} +trap cleanup ERR + +# fetch latest archlinuxarm tarball +wget -nc http://os.archlinuxarm.org/os/$ARCHTARBALL + +# the following installation instructions are taken from +# https://archlinuxarm.org/platforms/armv7/arm/versatile-express +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 ext4 513MiB 100% +mkfs.vfat -F 32 ${_loopdev}p1 +mkdir -p $_builddir/boot +mount ${_loopdev}p1 $_builddir/boot +mkfs.ext4 ${_loopdev}p2 +mkdir $_builddir/root +mount ${_loopdev}p2 $_builddir/root +bsdtar -vxpf $ARCHTARBALL -C $_builddir/root +sync +mv -v $_builddir/root/boot/* $_builddir/boot +cat >> $_builddir/root/etc/fstab << EOF +/dev/mmcblk0p1 /boot vfat 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 $(logname) keys/id_rsa* +mkdir -m 700 $_builddir/root/root/.ssh +install -m 600 -o 0 -g 0 keys/id_rsa.pub $_builddir/root/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 $_builddir/root/etc/ssh + install -m 644 -o 0 -g 0 keys/ssh_host_${cipher}_key.pub $_builddir/root/etc/ssh +done + +# tie up any loose ends +for part in p1 p2; do + umount $_loopdev$part +done +losetup -d $_loopdev +rm -rf $_builddir/boot $_builddir/root diff --git a/src/stage2.sh b/src/stage2.sh new file mode 100755 index 0000000..ddc01b4 --- /dev/null +++ b/src/stage2.sh @@ -0,0 +1,98 @@ +#!/bin/bash + +set -eu + +_scriptfile=$_builddir/migrate.sh +_pidfile=$_builddir/qemu.pid + +_loopdev=$(sudo losetup -f --show $_outfile) +_bootdir=.boot + +# 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 + +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 + +pacman-key --init +pacman-key --populate archlinuxarm archlinux archlinux32 parabola + +test -f /etc/pacman.d/mirrorlist.pacnew && mv /etc/pacman.d/mirrorlist{.pacnew,} + +sed -i '/^\[core\]/i \ +[libre] \ +Include = /etc/pacman.d/mirrorlist \ +' /etc/pacman.conf +sed -Ei '/^\[alarm\]|\[aur\]/,+2d' /etc/pacman.conf + +yes | pacman -Scc + +sed -i 's/^Architecture.*/Architecture = armv7h/' /etc/pacman.conf + +pacman --noconfirm -Syy + +pacman --noconfirm -S pacman +mv /etc/pacman.conf{.pacnew,} +pacman --noconfirm -Syuu + +pacman --noconfirm -S your-freedom +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/mmcblk0p2 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 +rm -f $_pidfile + +# cleanup +umount ${_loopdev}p1 +losetup -d $_loopdev +rm -rf $_bootdir +rm $_scriptfile diff --git a/start.sh b/start.sh index 8e1bcfb..1d967e1 100755 --- a/start.sh +++ b/start.sh @@ -1,25 +1,59 @@ #!/bin/bash -IMAGE=${IMAGE:-armv7h.raw} +set -eu -_loopdev=$(sudo losetup -f --show $IMAGE) + +_builddir=build +mkdir -p $_builddir + +_imagefile=$1 +_pidfile=$_builddir/qemu.pid + +_loopdev=$(sudo losetup -f --show $_imagefile) _bootdir=.boot +# 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 EXIT +trap cleanup ERR +# start the VM mkdir -p $_bootdir sudo mount ${_loopdev}p1 $_bootdir - -qemu-system-arm \ +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/mmcblk0p2 rw roottype=ext4 console=ttyAMA0" \ - -drive if=sd,driver=raw,cache=writeback,file=$IMAGE \ - --nographic \ - -snapshot + -drive if=sd,driver=raw,cache=writeback,file=$_imagefile \ + -display none \ + -net user,hostfwd=tcp::2022-:22 \ + -net nic \ + -daemonize \ + -snapshot \ + -pidfile $_pidfile + +# 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 root@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 +rm -f $_pidfile + +# cleanup +sudo umount ${_loopdev}p1 +sudo losetup -d $_loopdev +rm -rf $_bootdir