#!/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 . ## imagine images vars+=(image_name bootpart rootpart loopdevice filesystem) arrs+=(fsargs) image_prepare_raw() { fn image_prepare_raw req=(workdir size image_name) ckreq || return 1 notice "creating raw image file from zeroes..." dd if=/dev/zero \ of=$workdir/${image_name}.img \ bs=1M \ count=$size } image_format_partitions() { fn image_format_partitions req=(bootfs bootpart rootpart) ckreq || return 1 notice "formatting 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 ;; 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 ;; esac } image_partition_raw_dos() { fn image_partition_raw_dos req=(workdir image_name parted_boot parted_root) 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 bootpart=${loopdevice}p1 rootpart=${loopdevice}p2 image_format_partitions } image_partition_raw_gpt() { fn image_partition_raw_gpt req=(workdir image_name gpt_boot gpt_root) ckreq || return 1 notice "partitioning raw gpt image..." parted $workdir/${image_name}.img --script -- mklabel gpt || zerr cgpt create -z $workdir/${image_name}.img || zerr cgpt create $workdir/${image_name}.img || zerr 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 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 findloopdev bootpart="${loopdevice}p1" rootpart="${loopdevice}p2" image_format_partitions } image_pack_dist() { fn image_pack_dist req=(loopdevice image_name strapdir workdir) ckreq || return 1 notice "packaging image for dist" act "rechecking filesystem" sudo e2fsck -fy ${loopdevice}p2 sudo resize2fs ${loopdevice}p2 sleep 2 [[ $parted_type = gpt ]] && { sudo cgpt repair $loopdevice sleep 1 } sudo partx -dv $loopdevice || { die "partx failed to remove $loopdevice" zerr } sudo losetup -d $loopdevice || { die "losetup failed to remove $loopdevice" zerr } if [[ -n "$nocompressimage" ]]; then _suffix="img" else _suffix="img.xz" fi pushd $workdir [[ -n "$nocompressimage" ]] || { notice "compressing image with xz" silly xz -zv "${image_name}.img" } mkdir -p "$R/dist" mv -v ${image_name}.${_suffix} $R/dist/ 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 popd [[ $DEBUG = 1 ]] || sudo rm -r $workdir notice "finished packing $image_name" act "find it in $R/dist/" act "thanks for being patient!" } image_raw_mount() { fn image_raw_mount req=(workdir bootpart rootpart bootfs) ckreq || return 1 mkdir -p $workdir/mnt sudo mount $rootpart $workdir/mnt && \ act "mounted root partition" || zerr [[ "$bootfs" == none ]] || { sudo mkdir -p $workdir/mnt/boot sudo mount $bootpart $workdir/mnt/boot && \ act "mounted boot partition" || zerr } } image_raw_umount() { fn image_raw_umount req=(workdir bootpart rootpart) ckreq || return 1 [[ "$bootfs" == none ]] || { sudo umount $workdir/mnt/boot && act "unmounted boot partition" || zerr sleep 1 } sudo umount $workdir/mnt && act "unmounted root partition" || zerr } image_raw_as_strapdir() { fn image_raw_as_strapdir req=(workdir strapdir size) 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 popd } image_qcow2_as_strapdir() { fn image_qcow2_as_strapdir req=(workdir strapdir size) 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 popd } tar_strapdir() { fn tar_strapdir req=(strapdir) ckreq || return 1 notice "creating a tarbomb of the rootfs..." mkdir -p "$R/dist" silly pushd "$strapdir" sudo tar czf "$R/dist/${image_name}.tar.gz" . || zerr popd }