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 <parazyd@dyne.org>
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:
Mconfig | 18+++++-------------
Mlibdevuansdk | 29+++++++++++++----------------
Mzlibs/bootstrap | 306++++++++++++++++++++++++++++++++++++++++---------------------------------------
Dzlibs/cache | 83-------------------------------------------------------------------------------
Mzlibs/helpers | 452++++++++++++++++++++++++++++++-------------------------------------------------
Mzlibs/imaging | 487++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mzlibs/iso | 119++++++++++++++++++++++++++++++++++++++++---------------------------------------
Dzlibs/kernel | 40----------------------------------------
Dzlibs/rsync | 44--------------------------------------------
Mzlibs/sysconf | 14+++-----------
Mzlibs/vm | 238+++++++++++++++++--------------------------------------------------------------
11 files changed, 719 insertions(+), 1111 deletions(-)

diff --git a/config b/config @@ -1,4 +1,5 @@ #!/usr/bin/env zsh +# shellcheck shell=bash # Copyright (c) 2016-2020 Dyne.org Foundation # libdevuansdk is maintained by Ivan J. <parazyd@dyne.org> # @@ -17,21 +18,13 @@ # You should have received a copy of the GNU General Public License # along with this source code. If not, see <http://www.gnu.org/licenses/>. -## 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" @@ -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 @@ -1,6 +1,7 @@ #!/usr/bin/env zsh -# Copyright (c) 2016-2017 Dyne.org Foundation -# libdevuansdk maintained by Ivan J. <parazyd@dyne.org> +# shellcheck shell=bash +# Copyright (c) 2016-2020 Dyne.org Foundation +# libdevuansdk is maintained by Ivan J. <parazyd@dyne.org> # # This file is part of libdevuansdk # @@ -17,22 +18,18 @@ # You should have received a copy of the GNU General Public License # along with this source code. If not, see <http://www.gnu.org/licenses/>. -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 @@ -1,6 +1,7 @@ #!/usr/bin/env zsh +# shellcheck shell=bash # Copyright (c) 2016-2020 Dyne.org Foundation -# libdevuansdk maintained by Ivan J. <parazyd@dyne.org> +# libdevuansdk is maintained by Ivan J. <parazyd@dyne.org> # # This file is part of libdevuansdk # @@ -17,222 +18,227 @@ # You should have received a copy of the GNU General Public License # along with this source code. If not, see <http://www.gnu.org/licenses/>. -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 <<EOF | sudo tee ${strapdir}/addcachepubkey >/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 <<EOF | sudo tee "$strapdir/thirdstage" >/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 <<EOF | sudo tee ${strapdir}/postunpack >/dev/null + cat <<EOF | sudo tee "$strapdir/fourthstage" >/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 @@ -1,83 +0,0 @@ -#!/usr/bin/env zsh -# Copyright (c) 2017 Dyne.org Foundation -# libdevuansdk is maintained by Ivan J. <parazyd@dyne.org> -# -# 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 <http://www.gnu.org/licenses/>. - -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 <<EOF > 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 <<EOF | sudo tee ${strapdir}/delcachepubkey >/dev/null -#!/bin/sh -apt-key del ${aptcachegpg} -EOF - chroot-script delcachepubkey || zerr -} diff --git a/zlibs/helpers b/zlibs/helpers @@ -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. <parazyd@dyne.org> # # This file is part of libdevuansdk @@ -17,101 +18,109 @@ # You should have received a copy of the GNU General Public License # along with this source code. If not, see <http://www.gnu.org/licenses/>. -## 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 <<EOF | sudo tee ${strapdir}/adduser -#!/bin/sh -useradd -m ${user} -echo "${user}:${pass}" | chpasswd -EOF - chroot-script adduser || zerr + notice "Cleaning strapdir" + + sudo rm -rf "$strapdir" } -devprocsys() { - fn devprocsys "$@" +devprocsys() +{ + fn devprocsys "$*" local watdo="$1" local werdo="$2" req=(watdo werdo) @@ -124,79 +133,17 @@ devprocsys() { sudo mount -o bind /dev/pts $werdo/dev/pts && act "mounted devpts" && \ return 0 elif [[ $watdo = umount ]]; then - sudo umount $werdo/dev/pts && act "umounted devpts" && sleep 1 - sudo umount $werdo/dev && act "umounted dev" && sleep 1 - sudo umount $werdo/proc && act "umounted proc" && sleep 1 - sudo umount $werdo/sys && act "umounted sys" && sleep 1 + sudo umount $werdo/dev/pts && act "umounted devpts" + sudo umount $werdo/dev && act "umounted dev" + sudo umount $werdo/proc && act "umounted proc" + sudo umount $werdo/sys && act "umounted sys" return 0 fi - return 1 -} - -wrapup() { - # a hopefully clean exit - fn wrapup - req=(strapdir) - ckreq || { - die "something is very wrong" - die "cleanup yourself, sorry" - exit 1 - } - - devprocsys umount $strapdir - exit 1 + zerr; return 1 } -findloopdev() { - fn findloopdev - req=(workdir image_name) - ckreq || return 1 - - notice "finding a free loopdevice" - - loopdevice=$(sudo losetup -f --show $workdir/${image_name}.img) - sudo partx -av $loopdevice || zerr - - func "loopdevice: $loopdevice" - silly sleep 2 -} - -findfreenbd() { - fn findfreenbd - - notice "looking for a free /dev/nbd" - - for i in $(seq 0 8); do - grep "^/dev/nbd${i}" /proc/mounts >/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" @@ -207,8 +154,8 @@ dpkgdivert() { cat <<EOF | sudo tee ${werdo}/dpkgdivert >/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 @@ -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 <<EOF | sudo tee -a ${strapdir}/enserv >/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 <<EOF | sudo tee -a ${strapdir}/disserv >/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 <<EOF | sudo tee ${strapdir}/install-debs >/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 <<EOF | sudo tee ${_tmp}/${pkgname}/${pkgname}_${pkgver}.control >/dev/null -Section: ${section} -Priority: optional -Homepage: https://devuan.org/ -Standards-Version: 3.9.6 - -Package: ${pkgname} -Version: ${pkgver} -Maintainer: Devuan developers <onelove@devuan.org> -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 <<EOF | sudo tee ${strapdir}/install-fake-package >/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..." @@ -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 @@ -1,4 +1,5 @@ #!/usr/bin/env zsh +# shellcheck shell=bash # Copyright (c) 2016-2020 Dyne.org Foundation # libdevuansdk is maintained by Ivan J. <parazyd@dyne.org> # @@ -17,305 +18,337 @@ # You should have received a copy of the GNU General Public License # along with this source code. If not, see <http://www.gnu.org/licenses/>. -## 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 @@ -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. <parazyd@dyne.org> # # This file is part of libdevuansdk @@ -17,54 +18,55 @@ # You should have received a copy of the GNU General Public License # along with this source code. If not, see <http://www.gnu.org/licenses/>. -## 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 <<EOF | sudo tee ${strapdir}/isoprep >/dev/null + cat <<EOF | sudo tee "$strapdir/isoprep" >/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 <<EOF | sudo tee ${workdir}/binary/isolinux/isolinux.cfg >/dev/null + notice "Writing isolinux configuration" + + cat <<EOF | sudo tee "$workdir/binary/isolinux/isolinux.cfg" >/dev/null ui vesamenu.c32 prompt 0 menu title ${os} boot menu @@ -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 \ @@ -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 @@ -1,40 +0,0 @@ -#!/usr/bin/env zsh -# Copyright (c) 2016-2017 Dyne.org Foundation -# libdevuansdk is maintained by Ivan J. <parazyd@dyne.org> -# -# 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 <http://www.gnu.org/licenses/>. - -## 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 <<EOF | sudo tee ${strapdir}/install-linux -#!/bin/sh -apt-get --yes --force-yes install ${kernel} -EOF - chroot-script -d install-linux || zerr -} diff --git a/zlibs/rsync b/zlibs/rsync @@ -1,44 +0,0 @@ -#!/usr/bin/env zsh -# Copyright (c) 2016-2020 Dyne.org Foundation -# libdevuansdk is maintained by Ivan J. <parazyd@dyne.org> -# -# 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 <http://www.gnu.org/licenses/>. - -## 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 @@ -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. <parazyd@dyne.org> # # This file is part of libdevuansdk @@ -95,7 +95,6 @@ conf_print_resolvconf() { fn conf_print_resolvconf cat <<EOF -## google's nameservers nameserver 8.8.8.8 nameserver 8.8.4.4 EOF @@ -106,21 +105,14 @@ conf_print_sourceslist() { req=(mirror release section) ckreq || return 1 - [[ $APT_CACHE = 1 ]] && { - cat <<EOF -deb file:/mnt ./ - -EOF - } - cat <<EOF -## package repositories +# Package repositories deb ${mirror} ${release} ${section} deb ${mirror} ${release}-updates ${section} deb ${mirror} ${release}-security ${section} #deb ${mirror} ${release}-backports ${section} -## source repositories +# Source repositories #deb-src ${mirror} ${release} ${section} #deb-src ${mirror} ${release}-updates ${section} #deb-src ${mirror} ${release}-security ${section} diff --git a/zlibs/vm b/zlibs/vm @@ -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. <parazyd@dyne.org> # # This file is part of libdevuansdk @@ -17,17 +18,17 @@ # You should have received a copy of the GNU General Public License # along with this source code. If not, see <http://www.gnu.org/licenses/>. -## ma baker - vars+=(vmname) -vm_inject_overrides() { +vm_inject_overrides() +{ fn vm_inject_overrides req=(strapdir) ckreq || return 1 - notice "injecting rootfs overrides" - cat <<EOF | sudo tee ${strapdir}/etc/rc.local >/dev/null + notice "Injecting rootfs overrides" + + cat <<EOF | sudo tee "$strapdir/etc/rc.local" >/dev/null #!/bin/sh # rc.local for base images @@ -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 <<EOF | sudo tee ${strapdir}/setupgrub >/dev/null + notice "Setting up grub" + + cat <<EOF | sudo tee "$workdir/mnt/setupgrub" >/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 <<EOF > 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 <<EOF > 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 <<EOF | sudo tee ${strapdir}/initcloud >/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 }