tOverhaul the entire library. - libdevuansdk - common library for devuan's simple distro kits
git clone https://git.parazyd.org/libdevuansdk
Log
Files
Refs
Submodules
README
LICENSE
---
commit aedf124832b7643ab3f215395cb6083a9cf2db7f
parent 881efdf1ba1b4ed09ec42258403281a95b9cf2b3
Author: parazyd 
Date:   Fri, 13 Nov 2020 10:04:52 +0100

Overhaul the entire library.

This commit is a "complete" overhaul of libdevuansdk and is a likely
breaking change for all the sdks. They will be updated accordingly.

Notable changes:
    * Bootstrap tarballs are now cpio archives.
    * Error handling is improved a lot.
    * rsync is avoided and cpio is used where necessary.
    * debootstrap submodule is removed and system-wide debootstrap is
      used instead.
    * VMs aren't being built inside an nbd device anymore. They are now
      built normally on the filesystem, and copied into a raw image
      which is then converted to requested formats (qcow and/or vdi).
    * Vagrant build support is completely dropped.
    * apt-cache functionality is completely dropped.
    * The full-build helper functions are renamed and and separated into
      more internal functions/steps.
    * Obsolete and unused code is removed.

Diffstat:
  M config                              |      18 +++++-------------
  M libdevuansdk                        |      29 +++++++++++++----------------
  M zlibs/bootstrap                     |     306 ++++++++++++++++---------------
  D zlibs/cache                         |      83 -------------------------------
  M zlibs/helpers                       |     452 ++++++++++++-------------------
  M zlibs/imaging                       |     487 +++++++++++++++++--------------
  M zlibs/iso                           |     119 ++++++++++++++++---------------
  D zlibs/kernel                        |      40 -------------------------------
  D zlibs/rsync                         |      44 -------------------------------
  M zlibs/sysconf                       |      14 +++-----------
  M zlibs/vm                            |     238 +++++++------------------------

11 files changed, 719 insertions(+), 1111 deletions(-)
---
diff --git a/config b/config
t@@ -1,4 +1,5 @@
 #!/usr/bin/env zsh
+# shellcheck shell=bash
 # Copyright (c) 2016-2020 Dyne.org Foundation
 # libdevuansdk is maintained by Ivan J. 
 #
t@@ -17,21 +18,13 @@
 # You should have received a copy of the GNU General Public License
 # along with this source code. If not, see .
 
-## libdevuansdk configuration
-
 vars+=(release version mirror section blend_name image_name vm_name)
 vars+=(arch earch)
-vars+=(aptcachedir APT_CACHE aptcachegpg)
 vars+=(usercredentials rootcredentials)
-vars+=(nocompressimage)
+vars+=(COMPRESS_IMAGE CPIO_STAGE4 MKEFI)
 
 arrs+=(core_packages base_packages purge_packages blend_packages)
-
-## enable local apt cache
-APT_CACHE=${APT_CACHE:-0}
-aptcachedir="$LIBPATH/apt-cache"
-## key used to sign the cache's Release
-aptcachegpg="0xdeadbeefdeadbeef"
+arrs+=(core_packages_option base_packages_option purge_packages_option blend_packages_option)
 
 os="devuan"
 release="beowulf"
t@@ -43,11 +36,10 @@ image_name="${os}_${release}_${version}_${arch}"
 [[ -n "$blend_name"  ]] && image_name="${image_name}_${blend_name}"
 [[ -n "$device_name" ]] && image_name="${image_name}_${device_name}"
 
-vm_name="${os}_${release}_${version}_${arch}_vagrant"
-[[ -n $blend_name  ]] && vm_name="${image_name}_${blend_name}"
+vm_name="${os}_${release}_${version}_${arch}_virtual"
+[[ -n "$blend_name" ]] && vm_name="${vm_name}_${blend_name}"
 
 rootcredentials="root:toor"
-usercredentials="devuan:devuan"
 
 core_packages_option=()
 core_packages=(
diff --git a/libdevuansdk b/libdevuansdk
t@@ -1,6 +1,7 @@
 #!/usr/bin/env zsh
-# Copyright (c) 2016-2017 Dyne.org Foundation
-# libdevuansdk maintained by Ivan J. 
+# shellcheck shell=bash
+# Copyright (c) 2016-2020 Dyne.org Foundation
+# libdevuansdk is maintained by Ivan J. 
 #
 # This file is part of libdevuansdk
 #
t@@ -17,22 +18,18 @@
 # You should have received a copy of the GNU General Public License
 # along with this source code. If not, see .
 
-libdevuansdk_version="1.0"
-LIBPATH=${LIBPATH:-$(dirname $0)}
+vars+=(libdevuansdk_version LIBPATH)
 
-source $LIBPATH/config
-source $LIBPATH/zlibs/bootstrap
-source $LIBPATH/zlibs/cache
-source $LIBPATH/zlibs/helpers
-source $LIBPATH/zlibs/imaging
-source $LIBPATH/zlibs/iso
-source $LIBPATH/zlibs/kernel
-source $LIBPATH/zlibs/rsync
-source $LIBPATH/zlibs/sysconf
-source $LIBPATH/zlibs/vm
+libdevuansdk_version="2.0"
+LIBPATH="${LIBPATH:-$(dirname $0)}"
 
-vars+=(libdevuansdk_version)
-vars+=(LIBPATH)
+source "$LIBPATH/config"
+source "$LIBPATH/zlibs/bootstrap"
+source "$LIBPATH/zlibs/helpers"
+source "$LIBPATH/zlibs/imaging"
+source "$LIBPATH/zlibs/iso"
+source "$LIBPATH/zlibs/vm"
+source "$LIBPATH/zlibs/sysconf"
 
 setopt pushdsilent
 
diff --git a/zlibs/bootstrap b/zlibs/bootstrap
t@@ -1,6 +1,7 @@
 #!/usr/bin/env zsh
+# shellcheck shell=bash
 # Copyright (c) 2016-2020 Dyne.org Foundation
-# libdevuansdk maintained by Ivan J. 
+# libdevuansdk is maintained by Ivan J. 
 #
 # This file is part of libdevuansdk
 #
t@@ -17,222 +18,227 @@
 # You should have received a copy of the GNU General Public License
 # along with this source code. If not, see .
 
-vars+=(bootstrap_tgz_stage3 bootstrap_tgz_stage4 TAR_STAGE4)
-arrs+=(base_packages_option core_packages_option extra_packages_option)
-arrs+=(purge_packages_option)
+vars+=(bootstrap_cpio_stage3 bootstrap_cpio_stage4 CPIO_STAGE4)
 
-bootstrap_complete_base() {
-        fn bootstrap_complete_base "$@"
-        req=(arch)
+bootstrap_complete_base()
+{
+        fn bootstrap_complete_base "$*"
+        req=(R os arch strapdir LIBPATH release mirror)
         ckreq || return 1
 
-        notice "bootstrapping $os $arch base"
+        notice "Bootstrapping: ${os}:${arch} base"
 
         export LANG=C
         export LC_ALL=C
         export DEBIAN_FRONTEND=noninteractive
 
-        bootstrap_tgz_stage3="$R/tmp/bootstrap-${os}-${arch}-stage3.tgz"
-        bootstrap_tgz_stage4="$R/tmp/bootstrap-${os}-${arch}-stage4.tgz"
+        bootstrap_cpio_stage3="$R/tmp/bootstrap-${os}-${arch}-stage3.cpio.gz"
+        bootstrap_cpio_stage4="$R/tmp/bootstrap-${os}-${arch}-stage4.cpio.gz"
 
-        if [[ -n "$TAR_STAGE4" && -f "$bootstrap_tgz_stage4" ]]; then
-                notice "using the existing stage4 bootstrap tarball found in $R/tmp"
-                bootstrap_tar_unpack "$bootstrap_tgz_stage4" "$strapdir" || {
-                        die "failed to extract tarball"
-                        zerr
+        if [[ -n "$CPIO_STAGE4" && -f "$bootstrap_cpio_stage4" ]]; then
+                act "Using the existing stage4 bootstrap cpio archive..."
+                bootstrap_cpio_unpack "$bootstrap_cpio_stage4" "$strapdir" || {
+                        die "Failed to extract cpio archive"
+                        return 1
                 }
                 return
-        elif [[ -f "$bootstrap_tgz_stage3" ]]; then
-                notice "using the existing stage3 bootstrap tarball found in $R/tmp"
-                bootstrap_tar_unpack "$bootstrap_tgz_stage3" "$strapdir" || {
-                        die "failed to extract tarball"
-                        zerr
+        elif [[ -f "$bootstrap_cpio_stage3" ]]; then
+                act "Using the existing stage3 bootstrap cpio archive..."
+                bootstrap_cpio_unpack "$bootstrap_cpio_stage3" "$strapdir" || {
+                        die "Failed to extract cpio archive"
+                        return 1
                 }
+                bootstrap_stage4 || { zerr; return 1; }
+                if [[ -n "$CPIO_STAGE4" ]]; then
+                        bootstrap_cpio_pack "$bootstrap_cpio_stage4" || { zerr; return 1; }
+                fi
                 return
         fi
 
-        notice "running debootstrap stage 1"
+        notice "Running stage1 debootstrap"
 
-        sudo DEBOOTSTRAP_DIR="$LIBPATH/extra/debootstrap" "$LIBPATH/extra/debootstrap/debootstrap" \
+        sudo debootstrap \
                 --keyring="$LIBPATH/extra/devuan-keyring/keyrings/devuan-archive-keyring.gpg" \
-                --include=wget,ca-certificates \
+                --include=devuan-keyring,wget,ca-certificates \
                 --foreign \
-                --arch $arch $release $strapdir $mirror || zerr
+                --arch "$arch" "$release" "$strapdir" "$mirror" || { zerr; return 1; }
 
-        [[ $arch =~ "^arm.." ]] && { qemu_install_user || zerr }
-
-        sudo mkdir -p $strapdir/tmp
-        sudo chmod 1777 $strapdir/tmp
-
-        ## debootstrap stage 2
-        notice "running debootstrap stage 2"
-        sudo chroot $strapdir \
-                /debootstrap/debootstrap --second-stage || zerr
-
-        blend_bootstrap_setup || zerr
-
-        ## write all system configuration
-        notice "writing system configuration"
-        conf_print_debconf     | sudo tee $strapdir/debconf.set              >/dev/null
-        conf_print_fstab       | sudo tee $strapdir/etc/fstab                >/dev/null
-        conf_print_hostname    | sudo tee $strapdir/etc/hostname             >/dev/null
-        conf_print_hosts       | sudo tee $strapdir/etc/hosts                >/dev/null
-        conf_print_netifaces   | sudo tee $strapdir/etc/network/interfaces   >/dev/null
-        conf_print_resolvconf  | sudo tee $strapdir/etc/resolv.conf          >/dev/null
-        conf_print_sourceslist | sudo tee $strapdir/etc/apt/sources.list     >/dev/null
-        #conf_print_locales     | sudo tee $strapdir/etc/profile.d/locales.sh >/dev/null
+        if [[ "$arch" =~ "^arm.." ]]; then
+                qemu_install_user "$strapdir" || { zerr; return 1; }
+        fi
 
-        ## write third-stage for chroot
-        bootstrap_config_thirdstage | sudo tee $strapdir/thirdstage >/dev/null
+        notice "Running stage2 debootstrap"
 
-        ## chroot into it and configure further
-        ## debootstrap stage 3
-        notice "running debootstrap stage 3"
+        sudo chroot "$strapdir" /debootstrap/debootstrap --second-stage || { zerr; return 1; }
 
+        # TODO: sys config as function
+        conf_print_fstab       | sudo tee "$strapdir/etc/fstab" >/dev/null
+        conf_print_hostname    | sudo tee "$strapdir/etc/hostname" >/dev/null
+        conf_print_hosts       | sudo tee "$strapdir/etc/hosts" >/dev/null
+        conf_print_netifaces   | sudo tee "$strapdir/etc/network/interfaces" >/dev/null
+        conf_print_resolvconf  | sudo tee "$strapdir/etc/resolv.conf" >/dev/null
+        conf_print_sourceslist | sudo tee "$strapdir/etc/apt/sources.list" >/dev/null
 
-        chroot-script -d thirdstage || zerr
+        blend_bootstrap_setup || { zerr; return 1; }
 
-        [[ $APT_CACHE = 1 ]] && {
-                notice "adding apt cache gpg pubkey"
-                cat </dev/null
-#!/bin/sh
-gpgkey="$(gpg --export -a $aptcachegpg)"
-printf "%s" "\$gpgkey" | apt-key add -
-EOF
-                chroot-script addcachepubkey || zerr
-        }
+        bootstrap_stage3 || { zerr; return 1; }
+        bootstrap_cpio_pack "$bootstrap_cpio_stage3" || { zerr; return 1; }
 
-        if [[ -n "$TAR_STAGE4" ]]; then
-                bootstrap_tar_pack   "$bootstrap_tgz_stage3"             || zerr
-                bootstrap_tar_unpack "$bootstrap_tgz_stage4" "$strapdir" || zerr
-        else
-                bootstrap_tar_pack   "$bootstrap_tgz_stage3"             || zerr
-                bootstrap_tar_unpack "$bootstrap_tgz_stage3" "$strapdir" || zerr
+        bootstrap_stage4 || { zerr; return 1; }
+        if [[ -n "$CPIO_STAGE4" ]]; then
+                bootstrap_cpio_pack "$bootstrap_cpio_stage4" || { zerr; return 1; }
         fi
+
+        return
 }
 
-bootstrap_config_thirdstage() {
-        fn bootstrap_config_thirdstage
-        req=(core_packages base_packages)
+bootstrap_stage3()
+{
+        fn bootstrap_stage3
+        req=(core_packages base_packages rootcredentials)
         ckreq || return 1
 
-        cat << EOF
+        cat </dev/null
 #!/bin/sh
 apt-get update
-debconf-set-selections /debconf.set
-
-echo "${rootcredentials}" | chpasswd
-sed -i -e 's/KERNEL\!=\"eth\*|/KERNEL\!=\"/' \
-        /lib/udev/rules.d/75-persistent-net-generator.rules
-rm -f /etc/udev/rules.d/70-persistent-net.rules
-export DEBIAN_FRONTEND=noninteractive
-
-apt-get --yes --force-yes install ${core_packages_option} ${core_packages}
-apt-get --yes --force-yes install ${base_packages_option} ${base_packages}
-apt-get --yes --force-yes purge  ${purge_packages_option} ${purge_packages}
-apt-get --yes --force-yes autoremove
-
+apt-get --yes --force-yes install ${core_packages_option} ${core_packages} || exit 1
+apt-get --yes --force-yes install ${base_packages_option} ${base_packages} || exit 1
+apt-get --yes --force-yes purge ${purge_packages_option} ${purge_packages} || exit 1
+apt-get --yes --force-yes --purge autoremove || exit 1
 apt-get clean
 
-sed -e 's/# en_US.UTF-8/en_US.UTF-8/' -i /etc/locale.gen
-locale-gen
+echo "${rootcredentials}" | chpasswd
 
-rm -f /debconf.set
 rm -f /etc/ssh/ssh_host_*
 rm -f /root/.bash_history
-#echo "1" > .keep
 EOF
-}
 
-bootstrap_tar_pack() {
-        fn bootstrap_tar_pack
-        req=(bootstrap_tgz)
-        bootstrap_tgz="$1"
-        ckreq || return 1
-
-        local _dest="$(dirname $bootstrap_tgz)"
-
-        if [[ -f "$bootstrap_tgz" ]]; then
-                notice "tarball found already in $_dest"
-        else
-                notice "Creating boostrap tarball in $bootstrap_tgz"
-                silly
-
-                pushd ${strapdir}
-                mkdir -p ${_dest}
-                silly
-                sudo tar czfp "$bootstrap_tgz" \
-                        --acls \
-                        --selinux \
-                        --xattrs \
-                        --xattrs-include=security.capability \
-                        --xattrs-include=user.pax.flags \
-                        --exclude={./dev,./sys,./proc} . || zerr
-                popd
-        fi
+        chroot-script -d thirdstage || { zerr; return 1; }
 }
 
-bootstrap_tar_unpack() {
-        fn bootstrap_tar_unpack $@
-        local bootstrap_tgz="$1"
-        req=(strapdir bootstrap_tgz)
+bootstrap_stage4()
+{
+        fn bootstrap_stage4
+        req=(strapdir extra_packages)
         ckreq || return 1
 
-        [[ -n "$TAR_STAGE4" ]] && {
-                [[ -f "$bootstrap_tgz" ]] || bootstrap_tgz="$bootstrap_tgz_stage3"
-        }
-        sudo rm -rf "${strapdir}"/*
-        silly
-        sudo tar xpf "$bootstrap_tgz" -C "$strapdir" --xattrs-include='*.*' --numeric-owner \
-                --acls --selinux --xattrs
-        sudo mkdir -p ${strapdir}/{boot,dev,sys,proc}
+        sudo mkdir -p "$strapdir"/{boot,dev,proc,sys}
 
-        conf_print_sourceslist | sudo tee $strapdir/etc/apt/sources.list >/dev/null
-
-        cat </dev/null
+        cat </dev/null
 #!/bin/sh
 apt-get update
 
-## check if all our extra_packages exist
+# check if all our extra_packages exist
 allpkgs="\$(apt-cache search '.' | cut -d' ' -f1)"
-for i in ${extra_packages} ; do
+for i in ${extra_packages}; do
         printf "%s" "\$allpkgs" | grep -q "^\$i$" || {
                 case "\$i" in
-                        --*) continue ;;
-                        *)   missing="\$missing \$i" ;;
+                --*) continue;;
+                *)   missing="\$missing \$i" ;;
                 esac
         }
 done
 
-[ -n "\$missing" ] && {
-        printf "\033[1;31m[!!] some extra packages don't exist\033[0m\n"
+if [ -n "\$missing" ]; then
+        printf "\033[1;31m[!!] Some extra packages don't exist:\033[0m\n"
         printf "%s\n" "\$missing"
         exit 1
-}
-
-apt-get --yes --force-yes upgrade
-apt-get --yes --force-yes install ${extra_packages_option} ${extra_packages}
-apt-get --yes --force-yes autoremove
+fi
 
+apt-get --yes --force-yes upgrade || exit 1
+apt-get --yes --force-yes install ${extra_packages_option} ${extra_packages} || exit 1
+apt-get --yes --force-yes --purge autoremove || exit 1
 apt-get clean
 EOF
 
-        chroot-script -d postunpack || zerr
+        chroot-script -d fourthstage || { zerr; return 1; }
 
         for i in $inittab; do
-                grep -q "^$i" $strapdir/etc/inittab && continue
-                print "$i" | sudo tee -a $strapdir/etc/inittab >/dev/null
+                grep -q "$^i" "$strapdir/etc/inittab" && continue
+                echo "$i" | sudo tee -a "$strapdir/etc/inittab" >/dev/null
         done || true
 
         for i in $custmodules; do
-                grep -q "^$i" $strapdir/etc/modules && continue
-                print "$i" | sudo tee -a $strapdir/etc/modules >/dev/null
+                grep -q "^$i" "$strapdir/etc/modules" && continue
+                echo "$i" | sudo tee -a "$strapdir/etc/modules" >/dev/null
         done || true
+}
+
+qemu_install_user()
+{
+        fn qemu_install_user "$*"
+        req=(arch _target)
+        local _target="$1"
+        ckreq || return 1
+
+        case "$(uname -m)" in
+        arm*|aarch*)
+                return
+                ;;
+        esac
+
+        notice "Installing qemu-user-static"
+        case "$arch" in
+        armel)
+                sudo cp -a "$armel_qemu_bin" "$_target/usr/bin/" || { zerr; return 1; }
+                ;;
+        armhf)
+                sudo cp -a "$armhf_qemu_bin" "$_target/usr/bin/" || { zerr; return 1; }
+                ;;
+        arm64)
+                sudo cp -a "$arm64_qemu_bin" "$_target/usr/bin/" || { zerr; return 1; }
+                ;;
+        esac
+}
+
+bootstrap_cpio_pack()
+{
+        fn bootstrap_cpio_pack "$*"
+        req=(_bootstrap_cpio strapdir)
+        local _bootstrap_cpio="$1"
+        ckreq || return 1
+
+        local _dest="$(dirname "$_bootstrap_cpio")"
+        if [[ -f "$_bootstrap_cpio" ]]; then
+                notice "cpio archive already found in $_dest"
+                return
+        fi
+
+        notice "Creating bootstrap cpio archive: $_bootstrap_cpio"
+        silly
+
+        pushd "$strapdir"
+        mkdir -p "$_dest"
+        sudo find . \
+                -not -path "./dev/*" \
+                -a -not -path "./proc/*" \
+                -a -not -path "./sys/*" \
+                | sudo cpio -o --format=newc \
+                | gzip - > "$_bootstrap_cpio" || { zerr; return 1; }
+        popd
+}
+
+bootstrap_cpio_unpack()
+{
+        fn bootstrap_cpio_unpack "$*"
+        req=(_bootstrap_cpio strapdir)
+        local _bootstrap_cpio="$1"
+        ckreq || return 1
+
+        notice "Unpacking bootstrap cpio archive: $_bootstrap_cpio"
+        silly
+
+        sudo rm -rf "${strapdir}"/*
+
+        pushd "$strapdir" || { zerr; return 1; }
+        zcat "$_bootstrap_cpio" | sudo cpio -id || { zerr; return 1; }
+        popd
 
-        [[ -n "$TAR_STAGE4" ]] && bootstrap_tar_pack "$bootstrap_tgz_stage4" || true
+        sudo mkdir -p "$strapdir"/{boot,dev,proc,sys}
 }
 
-blend_bootstrap_setup() {
-        fn blend_bootstrap_setup "noop"
-        return 0
+blend_bootstrap_setup()
+{
+        fn blend_bootstrap_setup "(noop)"
+        return
 }
diff --git a/zlibs/cache b/zlibs/cache
t@@ -1,83 +0,0 @@
-#!/usr/bin/env zsh
-# Copyright (c) 2017 Dyne.org Foundation
-# libdevuansdk is maintained by Ivan J. 
-#
-# This file is part of libdevuansdk
-#
-# This source code 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 software 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 source code. If not, see .
-
-aptcache() {
-    fn aptcache "$*"
-    req=(aptcachedir watdo werdo APT_CACHE)
-    local watdo="$1"
-    local werdo="$2"
-    ckreq || return 1
-
-    [[ $APT_CACHE = 1 ]] || return 0
-
-    case "$watdo" in
-        on)
-            act "mounting local apt cache"
-            sudo mount -o bind "$aptcachedir" "$werdo" || zerr
-            ;;
-        off)
-            act "umounting local apt cache"
-            sudo umount "$werdo" || zerr
-            ;;
-    esac
-}
-
-fill_apt_cache() {
-    fn fill_apt_cache
-    req=(strapdir APT_CACHE aptcachedir)
-    ckreq || return 1
-
-    [[ $APT_CACHE = 1 ]] || return 0
-
-    notice "filling local apt cache"
-
-        cp -fv $strapdir/var/cache/apt/archives/*.deb $aptcachedir
-
-        pushd "$aptcachedir"
-                dpkg-scanpackages . /dev/null > Packages
-                gzip -c Packages > Packages.gz
-                cat < Release
-Origin: ${os}
-Suite: ${release}
-Version: ${version}
-Architectures: alpha amd64 arm64 armel armhf hppa i386 ia64 mips mipsel powerpc ppc64el s390x sparc
-MD5sum:
- $(md5sum Packages    | cut -d' ' -f1)    $(du -b Packages)
- $(md5sum Packages.gz | cut -d' ' -f1)    $(du -b Packages.gz)
-SHA1:
- $(sha1sum Packages    | cut -d' ' -f1)    $(du -b Packages)
- $(sha1sum Packages.gz | cut -d' ' -f1)    $(du -b Packages.gz)
-SHA256:
- $(sha256sum Packages    | cut -d' ' -f1)    $(du -b Packages)
- $(sha256sum Packages.gz | cut -d' ' -f1)    $(du -b Packages.gz)
-EOF
-                rm -f Packages
-                gpg --sign --detach-sign -a --sign-with $aptcachegpg Release || zerr
-                mv Release.asc Release.gpg
-        popd
-
-
-        sudo sed -i '/deb file:\/mnt/d' "$strapdir/etc/apt/sources.list"
-        notice "removing apt cache gpg pubkey"
-        cat </dev/null
-#!/bin/sh
-apt-key del ${aptcachegpg}
-EOF
-        chroot-script delcachepubkey || zerr
-}
diff --git a/zlibs/helpers b/zlibs/helpers
t@@ -1,5 +1,6 @@
 #!/usr/bin/env zsh
-# Copyright (c) 2016-2017 Dyne.org Foundation
+# shellcheck shell=bash
+# Copyright (c) 2016-2020 Dyne.org Foundation
 # libdevuansdk is maintained by Ivan J. 
 #
 # This file is part of libdevuansdk
t@@ -17,101 +18,109 @@
 # You should have received a copy of the GNU General Public License
 # along with this source code. If not, see .
 
-## helper functions that make my life easier
-
-vars+=(loopdevice)
-
-build_image_dist() {
-        fn build_image_dist
-        req=(arch size parted_type)
-        if [[ $parted_type = gpt ]]; then
-                req+=(gpt_boot gpt_root)
-        elif [[ $parted_type = dos ]]; then
-                req+=(parted_root parted_boot)
-        fi
-        req+=(workdir strapdir image_name)
+build_arm_dist()
+{
+        fn build_arm_dist
+        req=(workdir strapdir os arch size parted_type)
+        case "$parted_type" in
+        gpt) req+=(gpt_boot gpt_root) ;;
+        dos) req+=(dos_boot dos_root) ;;
+        *) die "Unknown parted_type: $parted_type. Supported is gpt|dos."
+                zerr; return 1
+                ;;
+        esac
         ckreq || return 1
 
-        notice "building complete dist image"
-        act "$image_name"
-
-        bootstrap_complete_base            || { zerr; wrapup }
-        blend_preinst                      || { zerr; wrapup }
-        image_prepare_raw                  || { zerr; wrapup }
-        image_partition_raw_${parted_type} || { zerr; wrapup }
-        build_kernel_${arch}               || { zerr; wrapup }
-        blend_postinst                     || { zerr; wrapup }
-        rsync_to_raw_image                 || { zerr; wrapup }
-        image_pack_dist                    || { zerr; wrapup }
+        notice "Building complete Arm image(s)"
+
+        bootstrap_complete_base        || { zerr; return 1; }
+        blend_preinst                  || { zerr; return 1; }
+        image_prepare_raw              || { zerr; return 1; }
+        image_connect_raw              || { zerr; return 1; }
+        image_partition_${parted_type} || { zerr; return 1; }
+        image_format_partitions        || { zerr; return 1; }
+        build_kernel_${arch}           || { zerr; return 1; }
+        image_mount                    || { zerr; return 1; }
+        strapdir_to_image              || { zerr; return 1; }
+        blend_postinst                 || { zerr; return 1; }
+        image_umount                   || { zerr; return 1; }
+        image_disconnect_raw           || { zerr; return 1; }
+        image_pack_dist                || { zerr; return 1; }
+        clean_strapdir                 || { zerr; return 1; }
 }
 
-build_iso_dist() {
+build_iso_dist()
+{
         fn build_iso_dist
         req=(workdir strapdir os arch)
         ckreq || return 1
 
-        notice "building complete iso image"
-
-        bootstrap_complete_base || { zerr; wrapup }
-        blend_preinst           || { zerr; wrapup }
-        iso_prepare_strap       || { zerr; wrapup }
-        build_kernel_${arch}    || { zerr; wrapup }
-        iso_setup_isolinux      || { zerr; wrapup }
-        iso_write_isolinux_cfg  || { zerr; wrapup }
-        #[[ $INSTALLER = 1 ]] && iso_setup_installer || zerr
-        blend_postinst          || { zerr; wrapup }
-        fill_apt_cache          || { zerr; wrapup }
-        iso_squash_strap        || { zerr; wrapup }
-        iso_xorriso_build       || { zerr; wrapup }
+        notice "Building complete iso image(s)"
+
+        bootstrap_complete_base || { zerr; return 1; }
+        blend_preinst           || { zerr; return 1; }
+        iso_prepare_strap       || { zerr; return 1; }
+        iso_setup_isolinux      || { zerr; return 1; }
+        iso_write_isolinux_cfg  || { zerr; return 1; }
+        blend_postinst          || { zerr; return 1; }
+        iso_squash_strap        || { zerr; return 1; }
+        iso_xorriso_build       || { zerr; return 1; }
 }
 
-build_vagrant_dist() {
-        fn build_vagrant_dist
-        req=(workdir strapdir os arch imageformat)
+build_vm_dist()
+{
+        fn build_vm_dist
+        req=(workdir strapdir os arch size imageformat parted_type)
+        case "$parted_type" in
+        gpt) req+=(gpt_boot gpt_root) ;;
+        dos) req+=(dos_boot dos_root) ;;
+        *) die "Unknown parted_type: $parted_type. Supported is gpt|dos."
+                zerr; return 1
+                ;;
+        esac
         ckreq || return 1
 
-        notice "building complete vagrant image"
-
-        image_${imageformat}_as_strapdir   || { zerr; wrapup }
-        bootstrap_complete_base            || { zerr; wrapup }
-        vm_inject_overrides                || { zerr; wrapup }
-        blend_preinst                      || { zerr; wrapup }
-        vm_setup_grub                      || { zerr; wrapup }
-        blend_postinst                     || { zerr; wrapup }
-        vm_umount_${imageformat}           || { zerr; wrapup }
-        vm_vbox_setup                      || { zerr; wrapup }
-        vm_vagrant_package                 || { zerr; wrapup }
-        vm_init_cloud                      || { zerr; wrapup }
-        vm_pack_dist                       || { zerr; wrapup }
-}
-
-getfield() {
-        fn getfield $*
-        print "$1" | \
-                grep "^$2=" | \
-                sed -e 's:.*=\(.*\)$:\1:g' | \
-                sed -e 's:^"\(.*\)"$:\1:g'
+        notice "Building complete VM image(s)"
+
+        bootstrap_complete_base        || { zerr; return 1; }
+        vm_inject_overrides            || { zerr; return 1; }
+        blend_preinst                  || { zerr; return 1; }
+        image_prepare_raw              || { zerr; return 1; }
+        image_connect_raw              || { zerr; return 1; }
+        image_partition_${parted_type} || { zerr; return 1; }
+        image_format_partitions        || { zerr; return 1; }
+        image_mount                    || { zerr; return 1; }
+        strapdir_to_image              || { zerr; return 1; }
+        vm_setup_grub                  || { zerr; return 1; }
+        blend_postinst                 || { zerr; return 1; }
+        image_umount                   || { zerr; return 1; }
+        image_disconnect_raw           || { zerr; return 1; }
+        if [[ "$imageformat" = qcow2 ]]; then
+                image_raw_to_qcow2         || { zerr; return 1; }
+        fi
+        image_raw_to_vdi               || { zerr; return 1; }
+        vm_pack_dist                   || { zerr; return 1; }
+        clean_strapdir                 || { zerr; return 1; }
 }
 
-add-user() {
-        fn add-user $*
-        local user="$1"
-        local pass="$2"
-        req=(strapdir user pass)
+clean_strapdir()
+{
+        fn clean_strapdir
+        req=(strapdir)
         ckreq || return 1
 
-        notice "adding user $user:$pass"
+        if [[ "$DEBUG" = 1 ]]; then
+                return
+        fi
 
-        cat </dev/null || {
-                        print "/dev/nbd${i}"
-                        break
-                }
-        done
-}
-
-qemu_install_user() {
-        fn qemu_install_user
-        req=(arch strapdir)
-        ckreq || return 1
-
-        [[ "$(uname -m)" =~ "arm" ]]   && return
-        [[ "$(uname -m)" =~ "aarch" ]] && return
-
-        notice "installing qemu-user-static"
-        case "$arch" in
-                armel)
-                        sudo cp -a "$armel_qemu_bin" "$strapdir/usr/bin"
-                        ;;
-                armhf)
-                        sudo cp -a "$armhf_qemu_bin" "$strapdir/usr/bin"
-                        ;;
-                arm64)
-                        sudo cp -a "$arm64_qemu_bin" "$strapdir/usr/bin"
-                        ;;
-        esac
-}
-
-dpkgdivert() {
+dpkgdivert()
+{
         fn dpkgdivert "$@"
         req=(watdo werdo)
         local watdo="$1"
t@@ -207,8 +154,8 @@ dpkgdivert() {
                 cat </dev/null
 #!/bin/sh
 dpkg-divert --add --local \
-        --divert /usr/sbin/invoke-rc.d.chroot \
-        --rename /usr/sbin/invoke-rc.d
+--divert /usr/sbin/invoke-rc.d.chroot \
+--rename /usr/sbin/invoke-rc.d
 cp /bin/true /usr/sbin/invoke-rc.d
 echo -e "#!/bin/sh\nexit 101" > /usr/sbin/policy-rc.d
 chmod +x /usr/sbin/policy-rc.d
t@@ -222,163 +169,98 @@ dpkg-divert --remove --rename /usr/sbin/invoke-rc.d
 EOF
         fi
 
-        chroot-script dpkgdivert || zerr
+        chroot-script "$werdo/dpkgdivert" || { zerr; return 1; }
 }
 
-enableserv() {
-        fn enableserv "$@"
-        local service="$1"
-        req=(service strapdir)
+chroot-script()
+{
+        fn chroot-script "$*"
+        req=(R workdir strapdir)
         ckreq || return 1
 
-        cat </dev/null
-#!/bin/sh
-update-rc.d ${service} enable
-EOF
-
-        notice "enabling $service service"
-        chroot-script enserv
-}
-
-disableserv() {
-        fn disableserv "$@"
-        local service="$1"
-        req=(service strapdir)
-        ckreq || return 1
+        mkdir -p "$R/log"
 
-        cat </dev/null
-#!/bin/sh
-update-rc.d ${service} disable
-EOF
+        local _divert=""
+        local _path=""
+        local _script=""
 
-        notice "disabling $service service"
-        chroot-script disserv
-}
+        case "x$1" in
+        x-d)
+                _divert=1
+                shift
+                ;;
+        esac
 
-install-custdebs() {
-        fn install-custdebs
-        req=(R strapdir custom_deb_packages)
-        ckreq || return 1
+        if [[ "$(dirname "$1")" = "." ]]; then
+                _path="$strapdir"
+        else
+                _path="$(dirname "$1")"
+        fi
 
-        sudo mkdir -p $strapdir/debs
-        sudo cp $R/extra/custom-packages/*.deb $strapdir/debs/
+        _script="$(basename "$1")"
 
-        cat </dev/null
-#!/bin/sh
-cd /debs
-for deb in ${custom_deb_packages}; do
-        dpkg -i \$deb
-        apt-get --yes --force-yes -f install
-done
-cd /
-apt-get --yes --force-yes autoremove
-rm -rf /debs
-EOF
-        chroot-script -d install-debs
-}
+        if [[ -n "$_divert" ]]; then
+                devprocsys mount "$_path" || { zerr; return 1; }
+                dpkgdivert on "$_path"    || { zerr; return 1; }
+        fi
 
-chroot-script() {
-        fn chroot-script "$@"
-        req=(strapdir)
-        ckreq || return 1
+        sudo sed -i "$_path/$_script" \
+                -e 's@^#!/bin/sh@&\nexport DEBIAN_FRONTEND=noninteractive@' \
+                -e 's@^#!/bin/sh@&\nexport LC_ALL=C@' \
+                -e 's@^#!/bin/sh@&\nexport LANG=C@' \
+                -e 's@^#!/bin/sh@&\nset -x ; exec 2>/'$_script'.log@'
 
-        mkdir -p "$R/log"
+        notice "Chrooting to execute '$_script' ..."
+        sudo chmod +x "$_path/$_script"  || { zerr; return 1; }
+        sudo chroot "$_path" "/$_script" || { zerr; return 1; }
+        sudo mv -f "$_path/${_script}.log" "$R/log/"
 
-        case "x$1" in
-                x-d)
-                        local script="$2"
-                        devprocsys mount "$strapdir" || zerr
-                        dpkgdivert on "$strapdir"    || zerr
-                        [[ "$APT_CACHE" = 1 ]] && { aptcache on "$strapdir/mnt"  || zerr }
-
-                        ## logging
-                        sudo sed -i "$strapdir/$script" \
-                                -e 's@#!/bin/sh@#!/bin/sh\'$'\nset -x ; exec 2>/'$script'.log ; export DEBIAN_FRONTEND=noninteractive@'
-
-                        notice "chrooting to execute $script..."
-                        sudo chmod +x  "$strapdir/$script"    || zerr
-                        sudo chroot "$strapdir" "/$script" || zerr
-                        sudo mv -f "$strapdir/${script}.log" "$R/log/"
-
-                        [[ "$APT_CACHE" = 1 ]] && { aptcache off "$strapdir/mnt" || zerr }
-                        dpkgdivert off "$strapdir"    || zerr
-                        devprocsys umount "$strapdir" || zerr
-                        ;;
-                *)
-                        local script="$1"
-                        [[ "$APT_CACHE" = 1 ]] && { aptcache on "$strapdir/mnt"  || zerr }
-
-                        ## logging
-                        sudo sed -i "$strapdir/$script" \
-                                -e 's@#!/bin/sh@#!/bin/sh\'$'\nset -x ; exec 2>/'$script'.log@'
-
-                        notice "chrooting to execute $script..."
-                        sudo chmod +x  "$strapdir/$script"    || zerr
-                        sudo chroot "$strapdir" "/$script" || zerr
-                        sudo mv -f "$strapdir/${script}.log" "$R/log/"
-
-                        [[ "$APT_CACHE" = 1 ]] && { aptcache off "$strapdir/mnt" || zerr }
-                        ;;
-        esac
+        if [[ -n "$_divert" ]]; then
+                dpkgdivert off "$_path"    || { zerr; return 1; }
+                devprocsys umount "$_path" || { zerr; return 1; }
+        fi
 
-        sudo rm -f $strapdir/$script
+        sudo rm -f "$_path/$_script"
 }
 
-install_fake_package() {
-        fn install_fake_package "$@"
-        req=(strapdir pkgname pkgver section)
-        local pkgname="$1"
-        local pkgver="$2"
-        local section="$3"
+findloopdev()
+{
+        fn findloopdev
+        req=(workdir image_name)
         ckreq || return 1
 
-        local _tmp="$strapdir/tmp"
-        sudo mkdir -p "$_tmp/$pkgname"
-
-        cat </dev/null
-Section: ${section}
-Priority: optional
-Homepage: https://devuan.org/
-Standards-Version: 3.9.6
-
-Package: ${pkgname}
-Version: ${pkgver}
-Maintainer: Devuan developers 
-Architecture: all
-Description: (Fake) ${pkgname}
-  Dummy package used to meet some dependencies without installing the
-  real ${pkgname} package.
-EOF
+        local _l="$(sudo losetup -f --show "$workdir/${image_name}.img")"
+        if [[ -z "$_l" ]]; then
+                zerr; return 1
+        fi
 
-        cat </dev/null
-#!/bin/sh
-cd /tmp/${pkgname}
-equivs-build ${pkgname}_${pkgver}.control \
-        && dpkg -i ${pkgname}_${pkgver}_all.deb || exit 1
-cd /tmp
-rm -rf ${pkgname}
-EOF
-        chroot-script install-fake-package || zerr
+        echo "$_l"
 }
 
-blend_preinst() {
-        fn blend_preinst
-        func "not overriden"
-        return 0
-}
+findnbddev()
+{
+        fn findnbddev
 
-blend_postinst() {
-        fn blend_postinst
-        func "not overriden"
-        return 0
+        notice "Finding a free /dev/nbd device"
+
+        for i in $(seq 0 8); do
+                grep -q "^/dev/nbd${i}" /proc/mounts || {
+                        echo "/dev/nbd${i}"
+                        return
+                }
+        done
+
+        zerr; return 1
 }
 
-silly() {
+silly()
+{
         fn silly "$@"
         local arg1="$1"
         local arg2="$2"
-        ## cheers mailpile!
-        funneh=("do not think of purple hippos"
+        # Cheers Mailpile!
+        funneh=(
+                "do not think of purple hippos"
                 "increasing entropy & scrambling bits"
                 "indexing kittens..."
                 "patching bugs..."
t@@ -406,10 +288,20 @@ silly() {
                 "Supplying monkeys with typewriters"
                 "Swapping time and space"
                 "Self potato"
-                "god is porco"
+                "God is porco"
                 "A million hamsters are spinning their wheels right now"
         )
         local rnd=$(shuf -i1-$#funneh -n 1)
         act "${funneh[$rnd]}"
         [[ $arg1 = sleep ]] && sleep $arg2 || true
 }
+
+blend_preinst()
+{
+        fn blend_preinst "(noop)"
+}
+
+blend_postinst()
+{
+        fn blend_postinst "(noop)"
+}
diff --git a/zlibs/imaging b/zlibs/imaging
t@@ -1,4 +1,5 @@
 #!/usr/bin/env zsh
+# shellcheck shell=bash
 # Copyright (c) 2016-2020 Dyne.org Foundation
 # libdevuansdk is maintained by Ivan J. 
 #
t@@ -17,305 +18,337 @@
 # You should have received a copy of the GNU General Public License
 # along with this source code. If not, see .
 
-## imagine images
+vars+=(bootpart rootpart loopdevice)
 
-vars+=(image_name bootpart rootpart loopdevice filesystem)
-arrs+=(fsargs)
+strapdir_to_image()
+{
+        fn strapdir_to_image
+        req=(workdir strapdir bootpart rootpart loopdevice)
+        ckreq || return 1
+
+        notice "Copying strapdir to image ..."
+
+        if [[ ! -d "$workdir/mnt" ]]; then
+                die "$workdir/mnt doesn't exist. Did you run image_mount?"
+                zerr; return 1
+        fi
 
-image_prepare_raw() {
+        pushd "$strapdir"
+        sudo find . \
+                -not -path "./dev/*" \
+                -a -not -path "./proc/*" \
+                -a -not -path "./sys/*" \
+                | sudo cpio -p "$workdir/mnt" || { zerr; return 1; }
+        popd
+}
+
+image_prepare_raw()
+{
         fn image_prepare_raw
         req=(workdir size image_name)
         ckreq || return 1
 
-        notice "creating raw image file from zeroes..."
+        notice "Creating raw image of $size MB"
+        touch "$workdir/${image_name}.img"
+        chattr +C "$workdir/${image_name}.img"
+        dd if=/dev/zero of="$workdir/${image_name}.img" bs=1M count="$size" || { zerr; return 1; }
+}
 
-        dd if=/dev/zero \
-                of=$workdir/${image_name}.img \
-                bs=1M \
-                count=$size
+image_prepare_qcow2()
+{
+        fn image_prepare_qcow2
+        req=(workdir size image_name)
+        ckreq || return 1
+
+        notice "Creating qcow2 image of $size MB"
+        touch "$workdir/${image_name}.qcow2"
+        chattr +C "$workdir/${image_name}.qcow2"
+        qemu-img create -f qcow2 "${workdir}/${image_name}.qcow2" "${size}M" || { zerr; return 1; }
 }
 
-image_format_partitions() {
+image_format_partitions()
+{
         fn image_format_partitions
         req=(bootfs bootpart rootpart)
         ckreq || return 1
 
-        notice "formatting partitions..."
+        notice "Formatting image partitions"
+
         case "$bootfs" in
-                none)
-                        act "skipping boot partition"
-                        ;;
-                vfat|fat|dos)
-                        act "formatting boot as vfat"
-                        sudo mkfs.vfat ${=bootopts} ${bootpart}
-                        ;;
-                ext4)
-                        act "formatting boot as ext4"
-                        sudo mkfs.ext4 ${=bootopts} ${bootpart}
-                        ;;
-                ext2)
-                        act "formating boot as ext2"
-                        sudo mkfs.ext2 ${=bootopts} ${bootpart}
-                        ;;
-                *)
-                        error "unknown parted_bootfs type '$bootfs'"
-                        zerr
-                        ;;
+        none)
+                act "Skipping boot partition"
+                ;;
+        vfat|fat|dos)
+                act "Formatting boot as VFAT"
+                sudo mkfs.vfat ${=bootopts} "${bootpart}" || { zerr; return 1; }
+                ;;
+        ext?)
+                act "Formatting boot as $bootfs"
+                sudo mkfs.${bootfs} ${=bootopts} "${bootpart}" || { zerr; return 1; }
+                ;;
+        btrfs)
+                act "Formatting boot as btrfs"
+                sudo mkfs.btrfs ${=bootopts} "${bootpart}" || { zerr; return 1; }
+                ;;
+        "")
+                die "No bootfs filesystem set!"
+                zerr; return 1
+                ;;
+        *)
+                die "Unimplemented filesystem: $bootfs"
+                die "Please report it for inclusion."
+                zerr; return 1
+                ;;
         esac
 
-        # default to ext4
-        [[ -z "$rootfs" ]] && rootfs=ext4
-
         case "$rootfs" in
-                none)
-                        act "skipping root partition"
-                        ;;
-                vfat|fat|dos)
-                        act "formatting root as vfat"
-                        sudo mkfs.vfat ${=rootopts} ${rootpart}
-                        ;;
-                ext4)
-                        act "formatting root as ext4"
-                        sudo mkfs.ext4 ${=rootopts} ${rootpart}
-                        ;;
-                ext2)
-                        act "formating root as ext2"
-                        sudo mkfs.ext2 ${=rootopts} ${rootpart}
-                        ;;
-                btrfs)
-                        act "formatting root as btrfs"
-                        sudo mfks.btrfs ${=rootopts} ${rootpart}
-                        ;;
-                *)
-                        error "unknown parted_rootfs type '$rootfs'"
-                        zerr
-                        ;;
+        none)
+                act "Skipping root partition"
+                ;;
+        vfat|fat|dos)
+                act "Formatting root as VFAT"
+                sudo mkfs.vfat ${=rootopts} "${rootpart}" || { zerr; return 1; }
+                ;;
+        ext?)
+                act "Formatting root as $rootfs"
+                sudo mkfs.${rootfs} ${=rootopts} "${rootpart}" || { zerr; return 1; }
+                ;;
+        btrfs)
+                act "Formatting root as btrfs"
+                sudo mkfs.btrfs ${=rootopts} "${rootpart}" || { zerr; return 1; }
+                ;;
+        "")
+                die "No rootfs filesystem set!"
+                zerr; return 1
+                ;;
+        *)
+                die "Unimplemented filesystem: $rootfs"
+                die "Please report it for inclusion."
+                zerr; return 1
+                ;;
         esac
 }
 
-image_partition_raw_dos() {
-        fn image_partition_raw_dos
-        req=(workdir image_name parted_boot parted_root)
+image_connect_raw()
+{
+        fn image_connect_raw
+        req=(workdir image_name)
         ckreq || return 1
 
-        notice "partitioning raw dos image..."
-
-        parted $workdir/${image_name}.img --script -- mklabel msdos
-        parted $workdir/${image_name}.img --script -- mkpart primary ${parted_boot}
-        parted $workdir/${image_name}.img --script -- mkpart primary ${parted_root}
-        [ -n "$bootable_part" ] && \
-                parted "$workdir/${image_name}.img" --script -- set "$bootable_part" boot on
-
-        ## get loopdevice (see ./helpers)
-        findloopdev
+        notice "Connecting raw image to loop device"
 
-        bootpart=${loopdevice}p1
-        rootpart=${loopdevice}p2
+        loopdevice="$(findloopdev)"
+        if [[ -z "$loopdevice" ]]; then
+                die "Didn't find a free loop device"
+                zerr; return 1
+        fi
 
-        image_format_partitions
+        bootpart="${loopdevice}p1"
+        rootpart="${loopdevice}p2"
 }
 
-image_partition_raw_gpt() {
-        fn image_partition_raw_gpt
-        req=(workdir image_name gpt_boot gpt_root)
+image_connect_qcow2()
+{
+        fn image_connect_qcow2
+        req=(workdir image_name)
         ckreq || return 1
 
-        notice "partitioning raw gpt image..."
+        notice "Connecting qcow2 image to nbd device"
 
-        parted $workdir/${image_name}.img --script -- mklabel gpt || zerr
-        cgpt create -z $workdir/${image_name}.img || zerr
-        cgpt create    $workdir/${image_name}.img || zerr
+        sudo modprobe nbd max_part=8 || { zerr; return 1; }
+        loopdevice="$(findnbddev)"
+        if [[ -z "$loopdevice" ]]; then
+                die "Didn't find a free nbd device"
+                zerr; return 1
+        fi
 
-        cgpt add -i 1 -t kernel -b ${gpt_boot[1]} \
-                -s ${gpt_boot[2]} \
-                -l kernel -S 1 -T 5 -P 10 $workdir/${image_name}.img
+        sudo qemu-nbd --connect="${loopdevice}" "$workdir/${image_name}.qcow2" || { zerr; return 1; }
+}
 
-        cgpt add -i 2 -t data -b ${gpt_root[1]} \
-                -s $(expr $(cgpt show $workdir/${image_name}.img | \
-                awk '/Sec GPT table/ {print $1}') - ${gpt_root[1]}) \
-                -l Root $workdir/${image_name}.img
+image_partition_dos()
+{
+        fn image_partition_dos
+        req=(loopdevice bootpart rootpart dos_boot dos_root)
+        ckreq || return 1
 
-        findloopdev
+        notice "Partitioning dos image"
 
-        bootpart="${loopdevice}p1"
-        rootpart="${loopdevice}p2"
+        sudo parted "$loopdevice" --script -- mklabel msdos || { zerr; return 1; }
+        sudo parted "$loopdevice" --script -- mkpart primary "$dos_boot" || { zerr; return 1; }
+        sudo parted "$loopdevice" --script -- mkpart primary "$dos_root" || { zerr; return 1; }
+        if [[ -n "$bootable_part" ]]; then
+                sudo parted "$loopdevice" --script -- set "$bootable_part" boot on
+        fi
 
-        image_format_partitions
+        sudo partprobe "$loopdevice" || { zerr; return 1; }
 }
 
-image_pack_dist() {
-        fn image_pack_dist
-        req=(loopdevice image_name strapdir workdir)
+image_mount()
+{
+        fn image_mount
+        req=(workdir bootpart rootpart bootfs)
         ckreq || return 1
 
-        notice "packaging image for dist"
+        notice "Mounting image to $workdir/mnt"
 
-        act "rechecking filesystem"
-        sudo e2fsck -fy ${loopdevice}p2
-        sudo resize2fs ${loopdevice}p2
+        mkdir -p "$workdir/mnt"
+        sudo mount "$rootpart" "$workdir/mnt" || { zerr; return 1; }
+        act "Mounted root partition"
 
-        sleep 2
-
-        [[ $parted_type = gpt ]] && {
-                sudo cgpt repair $loopdevice
-                sleep 1
-        }
-
-        case "$device_name" in
-                pinephone-dontbeevil)
-                        notice "dd-ing u-boot bootloader to image"
-                        sudo dd if="$R/dist/u-boot-sunxi-with-spl-sopine.bin" \
-                                of="$loopdevice" bs=1024 seek=8 || zerr
-                        ;;
-        esac
+        if [[ "$bootfs" = none ]]; then
+                return
+        fi
 
-        sudo partx -dv $loopdevice || {
-                die "partx failed to remove $loopdevice"
-                zerr
-        }
-        sudo losetup -d $loopdevice || {
-                die "losetup failed to remove $loopdevice"
-                zerr
-        }
+        sudo mkdir -p "$workdir/mnt/boot"
+        sudo mount "$bootpart" "$workdir/mnt/boot" || { zerr; return 1; }
+        act "Mounted boot partition"
+}
 
-        if [[ -n "$nocompressimage" ]]; then
-                _suffix="img"
-        else
-                _suffix="img.xz"
-        fi
+image_umount()
+{
+        fn image_umount
+        req=(workdir bootpart rootpart)
+        ckreq || return 1
 
-        pushd $workdir
+        notice "Umounting image from $workdir/mnt"
 
-        [[ -n "$nocompressimage" ]] || {
-                if which pixz > /dev/null ; then
-                        xzcomp=$(which pixz)
-                else
-                        xzcomp=$(which xz)
-                fi
+        sudo umount -R "$workdir/mnt" || { zerr; return 1; }
+        act "Umounted"
 
-                notice "compressing image with $xzcomp"
-                silly
+        act "Flushing bytes and buffers"
+        sudo blockdev --flushbufs "$loopdevice" || { zerr; return 1; }
+        sudo python -c 'import os; os.fsync(open("'$loopdevice'", "r+b"))' || { zerr; return 1; }
+}
 
-                $xzcomp "${image_name}.img"
-        }
+image_disconnect_raw()
+{
+        fn image_disconnect_raw
+        req=(loopdevice bootfs rootfs bootpart rootpart)
+        ckreq || return 1
 
-        mkdir -p "$R/dist"
-        mv -v ${image_name}.${_suffix} $R/dist/
+        notice "Disconnecting image from $loopdevice"
 
-        pushd "$R/dist"
-        notice "generating sha256 for ${image_name}.${_suffix}"
-        sha256sum ${image_name}.${_suffix} > ${image_name}.${_suffix}.sha
-        notice "generating sha256 for ${image_name}.tar.gz"
-        sha256sum ${image_name}.tar.gz > ${image_name}.tar.gz.sha
-        popd
+        act "Rechecking filesystems"
+        case "$bootfs" in
+        ext?)
+                sudo e2fsck -fy "$bootpart"
+                sudo resize2fs "$bootpart"
+                ;;
+        esac
 
-        popd
+        case "$rootfs" in
+        ext?)
+                sudo e2fsck -fy "$rootpart"
+                sudo resize2fs "$rootpart"
+                ;;
+        esac
 
-        [[ $DEBUG = 1 ]] || sudo rm -r $workdir
+        act "Disconnecting"
+        sudo partx -dv "$loopdevice" || {
+                die "partx failed to remove $loopdevice"
+                zerr; return 1
+        }
 
-        notice "finished packing $image_name"
-        act "find it in $R/dist/"
-        act "thanks for being patient!"
+        sudo losetup -d "$loopdevice" || {
+                die "losetup failed to remove $loopdevice"
+                zerr; return 1
+        }
 }
 
-image_raw_mount() {
-        fn image_raw_mount
-        req=(workdir bootpart rootpart bootfs)
+image_disconnect_qcow2()
+{
+        fn image_disconnect_qcow2
+        req=(loopdevice bootfs rootfs bootpart rootpart)
         ckreq || return 1
 
-        mkdir -p $workdir/mnt
-        sudo mount $rootpart $workdir/mnt && \
-                act "mounted root partition" || zerr
+        notice "Disconnecting image from $loopdevice"
 
-        [[ "$bootfs" == none ]] || {
-                sudo mkdir -p $workdir/mnt/boot
-                sudo mount $bootpart $workdir/mnt/boot && \
-                        act "mounted boot partition" || zerr
-        }
-}
+        act "Rechecking filesystems"
+        case "$bootfs" in
+        ext?)
+                sudo e2fsck -fy "$bootpart"
+                sudo resize2fs "$bootpart"
+                ;;
+        esac
 
-image_raw_umount() {
-        fn image_raw_umount
-        req=(workdir bootpart rootpart)
-        ckreq || return 1
+        case "$rootfs" in
+        ext?)
+                sudo e2fsck -fy "$rootpart"
+                sudo resize2fs "$rootpart"
+                ;;
+        esac
 
-        [[ "$bootfs" == none ]] || {
-                sudo umount $workdir/mnt/boot && act "unmounted boot partition" || zerr
-                sleep 1
-        }
-        sudo umount $workdir/mnt      && act "unmounted root partition" || zerr
+        act "Disconnecting"
+
+        sudo qemu-nbd --disconnect "$loopdevice" || { zerr; return 1; }
 }
 
-image_raw_as_strapdir() {
-        fn image_raw_as_strapdir
-        req=(workdir strapdir size)
+image_raw_to_qcow2()
+{
+        fn image_raw_to_qcow2
+        req=(image_name workdir)
         ckreq || return 1
 
-        pushd "$workdir"
-
-        notice "creating raw image of $size MB"
-        sudo rm -f base.raw
-        sudo qemu-img create -f raw base.raw ${size}M   || zerr
-        notice "partitioning"
-        sudo parted base.raw mktable msdos              || zerr
-        sudo parted base.raw mkpart primary '0%' '100%' || zerr
-        loopdevice=$(losetup --find)
-        sudo losetup -P $loopdevice base.raw || zerr
-        sudo mkfs.ext4 ${loopdevice}p1       || zerr
-
-        notice "mounting raw image to strapdir"
-        sudo mount ${loopdevice}p1 $strapdir
-        echo 1 | sudo tee ${strapdir}/.keep >/dev/null
+        notice "Converting raw image to qcow2"
+        pushd "$workdir" || { zerr; return 1; }
+        touch "${image_name}.qcow2"
+        chattr +C "${image_name}.qcow2"
+        qemu-img convert -f raw -O qcow2 "${image_name}.img" "${image_name}.qcow2" || { zerr; return 1; }
         popd
 }
 
-image_qcow2_as_strapdir() {
-        fn image_qcow2_as_strapdir
-        req=(workdir strapdir size)
+image_raw_to_vdi()
+{
+        fn image_raw_to_vdi
+        req=(image_name workdir)
         ckreq || return 1
 
-        pushd "$workdir"
-
-        # default filesystem fallback to ext4
-        filesystem=${filesystem:-ext4}
-
-        notice "creating qcow2 image of $size MB formatted with $filesystem"
-        rm -f base.qcow2
-        qemu-img create -f qcow2 base.qcow2 ${size}M     || zerr
-        sudo modprobe nbd max_part=8                     || zerr
-        loopdevice="$(findfreenbd)"
-        [ -n "$loopdevice" ]                             || zerr
-        act "$loopdevice"
-        sudo qemu-nbd --connect=${loopdevice} base.qcow2 || zerr
-
-        notice "partitioning"
-        sudo parted ${loopdevice} mktable msdos              || zerr
-        sudo parted ${loopdevice} mkpart primary '0%' '100%' || zerr
-
-        notice "formatting with $filesystem"
-        command -v mkfs.${filesystem} >/dev/null || {
-                error "filesystem tools not found in path: mkfs.${filesystem}"
-                zerr }
-        sudo mkfs.${filesystem} ${=fsargs} ${loopdevice}p1 || zerr
-
-        notice "mounting qcow2 image to strapdir"
-        sudo mount ${loopdevice}p1 $strapdir || zerr
-        echo 1 | sudo tee ${strapdir}/.keep >/dev/null
+        notice "Converting raw image to vdi"
+        pushd "$workdir" || { zerr; return 1; }
+        touch "${image_name}.vdi"
+        chattr +C "${image_name}.vdi"
+        qemu-img convert -f raw -O vdi "${image_name}.img" "${image_name}.vdi" || { zerr; return 1; }
+        #VBoxManage modifyhd "${image_name}.vdi" --type immutable --compact || { zerr; return 1; }
         popd
 }
 
-tar_strapdir() {
-        fn tar_strapdir
-        req=(strapdir)
+image_pack_dist()
+{
+        fn image_pack_dist
+        req=(R image_name workdir)
         ckreq || return 1
 
-        notice "creating a tarbomb of the rootfs..."
-        mkdir -p "$R/dist"
+        notice "Packing up built images"
+
+        local _xzcomp=""
+        local _rsuffix="img"
+
+        if [[ -n "$COMPRESS_IMAGE" ]]; then
+                if command -v pixz >/dev/null; then
+                        _xzcomp="$(command -v pixz)"
+                else
+                        _xzcomp="$(command -v xz)"
+                fi
+                _rsuffix="img.xz"
+        fi
+
+        pushd "$workdir" || { zerr; return 1; }
+
+        if [[ -n "$COMPRESS_IMAGE" ]]; then
+                act "Compressing images with $_xzcomp"
+                silly
+                $_xzcomp "${image_name}.img" || { zerr; return 1; }
+                # TODO: cpio image?
+        fi
+
+        act "Calculating sha256 checksums"
         silly
-        pushd "$strapdir"
-        sudo tar czf "$R/dist/${image_name}.tar.gz" . \
-                --acls --selinux --xattrs \
-                --xattrs-include=security.capability \
-                --xattrs-include=user.pax.flags || zerr
+        sha256sum "${image_name}.${_rsuffix}" > "${image_name}.${_rsuffix}.sha256"
+        # TODO: cpio image?
+        mkdir -p "$R/dist"
+        mv -v "${image_name}".* "$R/dist" || { zerr; return 1; }
+
+        notice "Done! Thanks for being patient!"
+
         popd
 }
diff --git a/zlibs/iso b/zlibs/iso
t@@ -1,5 +1,6 @@
 #!/usr/bin/env zsh
-# Copyright (c) 2016-2017 Dyne.org Foundation
+# shellcheck shell=bash
+# Copyright (c) 2016-2020 Dyne.org Foundation
 # libdevuansdk is maintained by Ivan J. 
 #
 # This file is part of libdevuansdk
t@@ -17,54 +18,55 @@
 # You should have received a copy of the GNU General Public License
 # along with this source code. If not, see .
 
-## burn baby
+vars+=(MKEFI)
 
-#[[ $INSTALLER = 1 ]] && base_packages+=(grub-pc)
-
-iso_prepare_strap() {
+iso_prepare_strap()
+{
         fn iso_prepare_strap
         req=(strapdir)
         ckreq || return 1
 
-        notice "preparing strapdir for livecd"
+        notice "Preparing strapdir for Live CD"
 
-        cat </dev/null
+        cat </dev/null
 #!/bin/sh
 apt-get update
-apt-get --yes --force-yes install dialog live-boot live-boot-initramfs-tools
-apt-get --yes --force-yes autoremove
+apt-get --yes --force-yes install dialog live-boot live-boot-initramfs-tools || exit 1
+apt-get --yes --force-yes --purge autoremove || exit 1
 EOF
 
-        chroot-script -d isoprep    || zerr
+        chroot-script -d isoprep || { zerr; return 1; }
 }
 
-iso_setup_isolinux() {
+iso_setup_isolinux()
+{
         fn iso_setup_isolinux
         req=(workdir strapdir)
         ckreq || return 1
 
-        notice "setting up isolinux"
+        notice "Setting up isolinux"
 
-        pushd $workdir
+        pushd "$workdir" || { zerr; return 1; }
         sudo mkdir -p binary/{live,isolinux}
-        act "copying kernel and initrd"
-        sudo cp $strapdir/boot/vmlinuz* binary/live/vmlinuz
-        sudo cp $strapdir/boot/initrd*  binary/live/initrd.img
-        #sudo cp $strapdir/boot/memtest86+.bin binary/live/memtest
-
-        sudo cp "$R"/extra/syslinux/isolinux.bin binary/isolinux || zerr
-        sudo cp "$R"/extra/syslinux/*.c32 binary/isolinux || zerr
+        act "Copyring kernel and initrd"
+        sudo cp "$strapdir/boot/"vmlinuz* binary/live/vmlinuz || { zerr; return 1; }
+        sudo cp "$strapdir/boot/"initrd*  binary/live/initrd.img || { zerr; return 1; }
+        #sudo cp "$strapdir/boot/memtest86+.bin binary/live/memtest || { zerr; return 1; }
 
+        sudo cp "$R/extra/syslinux/isolinux.bin" binary/isolinux || { zerr; return 1; }
+        sudo cp "$R"/extra/syslinux/*.c32 binary/isolinux || { zerr; return 1; }
         popd
 }
 
-iso_write_isolinux_cfg() {
+iso_write_isolinux_cfg()
+{
         fn iso_write_isolinux_cfg
         req=(workdir arch os)
         ckreq || return 1
 
-        notice "writing isolinux configuration"
-        cat </dev/null
+        notice "Writing isolinux configuration"
+
+        cat </dev/null
 ui vesamenu.c32
 prompt 0
 menu title ${os} boot menu
t@@ -80,49 +82,51 @@ endtext
 EOF
 }
 
-iso_squash_strap() {
+iso_squash_strap()
+{
         fn iso_squash_strap
         req=(workdir strapdir)
         ckreq || return 1
 
-        notice "creating squashfs out of strapdir"
+        notice "Creating squashfs out of strapdir"
 
         case "$arch" in
-                amd64|i386)
-                        _compfilt="-Xbcj x86"
-                        ;;
-                arm*)
-                        _compfilt="-Xbcj arm"
-                        ;;
-                *)
-                        _compfilt=""
-                        ;;
+        amd64|i386)
+                _compfilt="-Xbcj x86"
+                ;;
+        arm*)
+                _compfilt="-Xbcj arm"
+                ;;
+        *)
+                _compfilt=""
+                ;;
         esac
-        pushd $workdir
-        sudo mksquashfs $strapdir binary/live/filesystem.squashfs \
-                -comp xz ${=_compfilt} -noappend || zerr
 
+        pushd "$workdir" || { zerr; return 1; }
+        sudo mksquashfs "$strapdir" binary/live/filesystem.squashfs \
+                -comp xz ${=_compfilt} -noappend || { zerr; return 1; }
         popd
 }
 
-iso_xorriso_build() {
+iso_xorriso_build()
+{
         fn iso_xorriso_build
         req=(workdir image_name)
         ckreq || return 1
 
-        notice "building iso..."
+        notice "Building iso..."
         isoname="${image_name}-live.iso"
 
-        [[ -n "$mkefi" ]] && {
-        uefi_opt="-eltorito-alt-boot -e boot/grub/efiboot.img -isohybrid-gpt-basdat -no-emul-boot"
-        }
+        if [[ -n "$MKEFI" ]]; then
+                uefi_opt="-eltorito-alt-boot -e boot/grub/efiboot.img -isohybrid-gpt-basdat -no-emul-boot"
+        fi
 
-        isohybrid="$R"/extra/syslinux/isohdpfx.bin
+        isohybrid="$R/extra/syslinux/isohdpfx.bin"
 
-        mkdir -p $R/dist
-        pushd $workdir
+        mkdir -p "$R/dist"
+        pushd "$workdir"
         sudo xorriso -as mkisofs -r -J -joliet-long -l \
-                -isohybrid-mbr $isohybrid \
+                -isohybrid-mbr "$isohybrid" \
                 -partition_offset 16 \
                 -A "${os} Live - ${arch}" \
                 -b isolinux/isolinux.bin \
t@@ -131,21 +135,20 @@ iso_xorriso_build() {
                 -boot-load-size 4 \
                 -boot-info-table \
                 ${=uefi_opt} \
-                -o $R/dist/$isoname \
-                binary || zerr
+                -o "$R/dist/$isoname" \
+                binary || { zerr; return 1; }
         popd
-        unset uefi_opt
 
-        [[ "$DEBUG" = 1 ]] || {
-                [[ -n "$workdir" ]] && sudo rm -rf "$workdir"
-        }
-}
+        act "Calculating sha256 checksums"
+        pushd "$R/dist" || { zerr; return 1; }
+        sha256sum "$isoname" > "${isoname}.sha256"
+        popd
 
-iso_setup_installer() {
-        fn iso_setup_installer
+        if [[ "$DEBUG" = 1 ]]; then
+                return
+        fi
 
-        notice "setting up devuan-installer"
-        sudo cp $R/extra/installer/* $strapdir/
+        sudo rm -rf "$workdir"
 
-        ## TODO: init to script
+        notice "Done! Thanks for being patient!"
 }
diff --git a/zlibs/kernel b/zlibs/kernel
t@@ -1,40 +0,0 @@
-#!/usr/bin/env zsh
-# Copyright (c) 2016-2017 Dyne.org Foundation
-# libdevuansdk is maintained by Ivan J. 
-#
-# This file is part of libdevuansdk
-#
-# This source code 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 software 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 source code. If not, see .
-
-## all windows users are suckers
-
-build_kernel_${arch}() {
-        fn build_kernel_${arch}
-        req=(strapdir arch)
-        ckreq || return 1
-
-        local kernel_base="linux-image"
-        case "$arch" in
-                amd64) local kernel="${kernel_base}-amd64";;
-                i386)  local kernel="${kernel_base}-586";;
-        esac
-
-        notice "installing stock kernel for $arch"
-
-        cat <
diff --git a/zlibs/rsync b/zlibs/rsync
t@@ -1,44 +0,0 @@
-#!/usr/bin/env zsh
-# Copyright (c) 2016-2020 Dyne.org Foundation
-# libdevuansdk is maintained by Ivan J. 
-#
-# This file is part of libdevuansdk
-#
-# This source code 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 software 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 source code. If not, see .
-
-## ilpd
-
-rsync_to_raw_image() {
-        fn rsync_to_raw_image
-        req=(workdir strapdir bootpart rootpart)
-        ckreq || return 1
-
-        notice "Preparing to rsync and tar the rootfs..."
-        image_raw_mount
-        silly sleep 1
-
-        mkdir -p $R/dist
-        pushd $strapdir
-                tar_strapdir || zerr
-
-                notice "rsyncing strapdir to raw image..."
-                sudo rsync -HPaq ./* $workdir/mnt || {
-                        image_raw_umount
-                        die "not enough space, please report a bug"
-                        zerr
-                }
-        popd
-
-        image_raw_umount
-}
diff --git a/zlibs/sysconf b/zlibs/sysconf
t@@ -1,5 +1,5 @@
 #!/usr/bin/env zsh
-# Copyright (c) 2016-2019 Dyne.org Foundation
+# Copyright (c) 2016-2020 Dyne.org Foundation
 # libdevuansdk is maintained by Ivan J. 
 #
 # This file is part of libdevuansdk
t@@ -95,7 +95,6 @@ conf_print_resolvconf() {
         fn conf_print_resolvconf
 
         cat <
diff --git a/zlibs/vm b/zlibs/vm
t@@ -1,5 +1,6 @@
 #!/usr/bin/env zsh
-# Copyright (c) 2016-2018 Dyne.org Foundation
+# shellcheck shell=bash
+# Copyright (c) 2016-2020 Dyne.org Foundation
 # libdevuansdk is maintained by Ivan J. 
 #
 # This file is part of libdevuansdk
t@@ -17,17 +18,17 @@
 # You should have received a copy of the GNU General Public License
 # along with this source code. If not, see .
 
-## ma baker
-
 vars+=(vmname)
 
-vm_inject_overrides() {
+vm_inject_overrides()
+{
         fn vm_inject_overrides
         req=(strapdir)
         ckreq || return 1
 
-        notice "injecting rootfs overrides"
-        cat </dev/null
+        notice "Injecting rootfs overrides"
+
+        cat </dev/null
 #!/bin/sh
 # rc.local for base images
 
t@@ -35,210 +36,69 @@ vm_inject_overrides() {
 
 exit 0
 EOF
-        sudo chmod +x $strapdir/etc/rc.local
+        sudo chmod +x "$strapdir/etc/rc.local"
 
-        print "rootfs / rootfs rw 0 0" | sudo tee ${strapdir}/etc/fstab >/dev/null
-
-        sudo sed -i ${strapdir}/etc/ssh/sshd_config \
+        sudo sed -i "$strapdir/etc/ssh/sshd_config" \
                 -e 's/#PermitRootLogin .*/PermitRootLogin yes/' \
-                -e 's/PermitRootLogin .*/PermitRootLogin yes/'|| zerr
+                -e 's/PermitRootLogin .*/PermitRootLogin yes/' || { zerr; return 1; }
 }
 
-vm_setup_grub() {
+vm_setup_grub()
+{
         fn vm_setup_grub
-        req=(strapdir loopdevice)
+        req=(workdir loopdevice bootfs)
         ckreq || return 1
 
-        notice "setting up grub"
-        cat </dev/null
+        notice "Setting up grub"
+
+        cat </dev/null
 #!/bin/sh
-export DEBIAN_FRONTEND=noninteractive
-apt-get --yes --force-yes install linux-image-amd64 grub-pc
-sed -e 's:GRUB_TIMEOUT=5:GRUB_TIMEOUT=1:' -i /etc/default/grub
-sed -e 's:GRUB_CMDLINE_LINUX_DEFAULT=".*":GRUB_CMDLINE_LINUX_DEFAULT="net.ifnames=0":' \
-        -i /etc/default/grub
-update-grub
-grub-install --no-floppy --recheck --modules="biosdisk part_msdos" \
-        ${loopdevice}
-sed -e 's:${loopdevice}p1:/dev/sda1:g' -i /boot/grub/grub.cfg
-sync; sync; sync
+grub-install "${loopdevice}" || exit 1
+grub-mkconfig -o /boot/grub/grub.cfg || exit 1
 EOF
-        chroot-script -d setupgrub  || zerr
-}
-
-vm_umount_${imageformat}() {
-        fn vm_umount_${imageformat}
-        req=(strapdir loopdevice imageformat)
-        ckreq || return 1
-
-        notice "remounting ${imageformat} image"
-        sudo mount -o remount,ro $strapdir || zerr
-
-        notice "flushing bytes and buffers"
-        sudo blockdev --flushbufs $loopdevice || zerr
-        sudo python -c 'import os;os.fsync(open("'${loopdevice}'", "r+b"))' || zerr
-
-        notice "unmounting ${imageformat} image from strapdir"
-        sudo umount $strapdir || zerr
-        silly sleep 1
-        sudo rmdir $strapdir  || zerr
-
-        notice "cleaning up"
-        case "$imageformat" in
-                raw)
-                        sudo losetup -d ${loopdevice} || zerr
-                        ;;
-                qcow2)
-                        sudo qemu-nbd --disconnect ${loopdevice} || zerr
-                        ;;
-                *)
-                        zerr
-                        ;;
-        esac
-        silly sleep 1
-}
-
-vm_vbox_setup() {
-        fn vm_vbox_setup
-        req=(workdir imageformat)
-        ckreq || return 1
-
-        notice "converting ${imageformat} image to vdi"
-        pushd $workdir
-        qemu-img convert \
-                -f ${imageformat} \
-                -O vdi \
-                base.${imageformat} \
-                base.vdi || zerr
-        VBoxManage modifyhd base.vdi --type immutable --compact || zerr
-
-        vmname="${os}-${release}-prevagrant-${RANDOM}"
-        notice "importing base.vdi to a VBox"
-        act "creating vm"
-        VBoxManage createvm --name "$vmname" --ostype Debian_64 --register || zerr
-
-        act "setting up ram and group"
-        VBoxManage modifyvm "$vmname" --memory 256 --groups /vmsdk || zerr
-
-        act "setting up storage"
-        VBoxManage storagectl "$vmname" --name "IDE Controller" --add ide || zerr
-
-        act "attaching storage"
-        VBoxManage storageattach "$vmname" --storagectl "IDE Controller" --port 0 \
-                --device 0 --type hdd --medium base.vdi || zerr
-
-        vminfo="$(VBoxManage showvminfo "$vmname" --machinereadable)"
-        diskuuid="$(getfield "$vminfo" '"IDE Controller-ImageUUID-0-0"')"
-
-        act "autoreset off on storage"
-        VBoxManage modifyhd "$diskuuid" --autoreset off || zerr
-
-        act "setting up nat network"
-        VBoxManage modifyvm "$vmname" --nic1 nat || zerr
-        popd
+        chroot-script -d "$workdir/mnt/setupgrub" || { zerr; return 1; }
 }
 
-vm_vagrant_package() {
-        fn vm_vagrant_package
-        req=(workdir vmname)
-        ckreq || return 1
-
-        notice "packaging a vagrant box"
-
-        pushd $workdir
-        act "creating vagrantfile"
-        cat < Vagrantfile
-Vagrant.configure("2") do |config|
-        config.vm.box = "devuanbox.box"
-        config.ssh.username = "root"
-        config.ssh.password = "toor"
-        config.vm.guest = :debian
-        config.vm.synced_folder ".", "/vagrant", disabled: true
-        # https://github.com/dotless-de/vagrant-vbguest
-end
-EOF
-        act "creating metadata.json"
-        cat < metadata.json
+vm_pack_dist()
 {
-        "provider": "virtualbox"
-}
-EOF
-        notice "actually packaging..."
-        vagrant package --base "$vmname" --output ${vm_name}.box \
-                --include metadata.json --vagrantfile Vagrantfile || zerr
-        popd
-}
-
-vm_init_cloud() {
-        fn vm_init_cloud
-        req=(workdir strapdir imageformat loopdevice)
+        fn vm_pack_dist
+        req=(R workdir image_name imageformat)
         ckreq || return 1
 
-        [[ -n "$makecloud" ]] || return
-        [[ "$imageformat" = qcow2 ]] || {
-                die "imageformat is not qcow2"
-                zerr
-        }
+        notice "Packing up built images"
 
-        notice "Creating a cloud-based image"
-        pushd "$workdir"
-        cp -v "base.qcow2" "base-cloud.qcow2"
+        local _xzcomp=""
+        local _rsuffix="${imageformat}"
+        local _vsuffix="vdi"
 
-        notice "Connecting qemu-nbd and mounting"
-        sudo mkdir -p "$strapdir"
-        sudo qemu-nbd --connect=${loopdevice} base-cloud.qcow2 || zerr
-        silly sleep 1
-        sudo mount ${loopdevice}p1 $strapdir || zerr
+        if [[ -n "$COMPRESS_IMAGE" ]]; then
+                if command -v pixz >/dev/null; then
+                        _xzcomp="$(command -v pixz)"
+                else
+                        _xzcomp="$(command -v xz)"
+                fi
+                _rsuffix="${imageformat}.xz"
+                _vsuffix="vdi.xz"
+        fi
 
-        notice "Installing cloud-init"
-        cat </dev/null
-#!/bin/sh
+        pushd "$workdir" || { zerr; return 1; }
 
-apt-get update
-apt-get --yes --force-yes install cloud-init
-apt-get clean
-EOF
-        chroot-script -d initcloud || zerr
-        vm_umount_${imageformat} || zerr
-        popd
-}
+        if [[ -n "$COMPRESS_IMAGE" ]]; then
+                act "Compressing images with $_xzcomp"
+                silly
+                $_xzcomp "${image_name}.${imageformat}" || { zerr; return 1; }
+                $_xzcomp "${image_name}.vdi" || { zerr; return 1; }
+        fi
 
-vm_pack_dist() {
-        fn vm_pack_dist
-        req=(workdir imageformat)
-        ckreq || return 1
+        act "Calculating sha256 checksums"
+        silly
+        sha256sum "${image_name}.${_rsuffix}" > "${image_name}.${_rsuffix}.sha256"
+        sha256sum "${image_name}.${_vsuffix}" > "${image_name}.${_vsuffix}.sha256"
 
-        notice "packing up dist"
-        mkdir -p $R/dist
-        mv $workdir/${vm_name}.box $R/dist
-        mv $workdir/base.${imageformat} $R/dist/${vm_name}.${imageformat}
-        cp $workdir/base.vdi $R/dist/${vm_name}.vdi
+        mkdir -p "$R/dist"
+        mv -v "${image_name}".* "$R/dist" || { zerr; return 1; }
 
-        [[ -n "$makecloud" ]] && \
-                mv $workdir/base-cloud.${imageformat} \
-                        $R/dist/${vm_name}-cloud.${imageformat}
+        notice "Done! Thanks for being patient!"
 
-        act "calculating sha256 sums..."
-        silly
-        sha256sum $R/dist/${vm_name}.box > \
-                $R/dist/${vm_name}.box.sha
-        sha256sum $R/dist/${vm_name}.${imageformat} > \
-                $R/dist/${vm_name}.${imageformat}.sha
-        sha256sum $R/dist/${vm_name}.vdi > \
-                $R/dist/${vm_name}.vdi.sha
-        [[ -n "$makecloud" ]] && \
-                sha256sum $R/dist/${vm_name}-cloud.${imageformat} > \
-                        $R/dist/${vm_name}-cloud.${imageformat}.sha
-
-        notice "cleaning up virtualbox leftovers"
-        pushd "$workdir"
-                VBoxManage unregistervm "$vmname" --delete
-                rm -f metadata.json Vagrantfile
-                rm -rf .vagrant
         popd
-        rm -rf "$workdir"
-        rm -rf "$HOME/VirtualBox VMs/vmsdk"
-
-        notice "done!"
-        ls -1 $R/dist
 }