use predefined package sets

This commit is contained in:
bill-auger 2019-12-25 02:17:25 -05:00
parent 90fcc5fb14
commit 8f102e6742

@ -25,11 +25,16 @@ source "$(librelib messages)"
# defaults # defaults
readonly DEF_PKGS=('base' 'parabola-base' 'openssh') readonly PKG_SET_MIN='minimal'
readonly PKG_SET_STD='standard'
readonly PKG_SET_DEV='devel' ; readonly DEF_PKG_SET=$PKG_SET_STD ;
readonly MIN_PKGS=('base' ) ; readonly ROOT_MB_MIN=800 ;
readonly STD_PKGS=('base' 'parabola-base' ) ; readonly ROOT_MB_STD=1000 ;
readonly DEV_PKGS=('base' 'parabola-base' 'base-devel') ; readonly ROOT_MB_DEV=1250 ;
readonly DEF_PKGS=(${STD_PKGS[@]} ) ; readonly DEF_MIN_MB=$ROOT_MB_STD ;
readonly DEF_KERNEL='linux-libre' # ASSERT: must be 'linux-libre', per 'parabola-base' readonly DEF_KERNEL='linux-libre' # ASSERT: must be 'linux-libre', per 'parabola-base'
readonly DEF_MIRROR=https://repo.parabola.nu readonly DEF_MIRROR=https://repo.parabola.nu
readonly DEF_IMG_GB=64 readonly DEF_ROOT_MB=64000
readonly MIN_GB=1
readonly DEF_BOOT_MB=100 readonly DEF_BOOT_MB=100
readonly DEF_SWAP_MB=0 readonly DEF_SWAP_MB=0
@ -38,12 +43,15 @@ readonly THIS_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
readonly GUEST_CACHED_PKGS=('ca-certificates-utils') readonly GUEST_CACHED_PKGS=('ca-certificates-utils')
# options # options
BasePkgSet=$PKG_SET_STD
MinRootMb=$DEF_MIN_MB
Hooks=() Hooks=()
Kernels=($DEF_KERNEL) Kernels=()
Mirror=$DEF_MIRROR Mirror=$DEF_MIRROR
IsNonsystemd=0 IsNonsystemd=0
Pkgs=() Pkgs=(${DEF_PKGS[@]})
ImgSizeGb=$DEF_IMG_GB OptPkgs=()
RootSizeMb=$DEF_ROOT_MB
BootSizeMb=$DEF_BOOT_MB BootSizeMb=$DEF_BOOT_MB
SwapSizeMb=$DEF_SWAP_MB SwapSizeMb=$DEF_SWAP_MB
HasSwap=0 HasSwap=0
@ -51,8 +59,8 @@ HasSwap=0
usage() { usage() {
print "USAGE:" print "USAGE:"
print " pvmbootstrap [-h] [-H <hook> ] [-k <kernel> ] [-M <mirror> ]" print " pvmbootstrap [-b <base-set>] [-h] [-H <hook>] [-k <kernel>] [-M <mirror>]"
print " [-O] [-p <package>] [-s <img_size>] [-S <swap_size>]" print " [-O] [-p <package>] [-s <root_size>] [-S <swap_size>]"
print " <img> <arch>" print " <img> <arch>"
echo echo
prose "Produce preconfigured parabola GNU/Linux-libre virtual machine instances." prose "Produce preconfigured parabola GNU/Linux-libre virtual machine instances."
@ -63,6 +71,8 @@ usage() {
or one of the experimental arches: 'ppc64le' or 'riscv64'." or one of the experimental arches: 'ppc64le' or 'riscv64'."
echo echo
echo "Supported options:" echo "Supported options:"
echo " -b <base-set> Select one of the pre-defined package-sets described below"
echo " (default: 'standard')"
echo " -h Display this help and exit" echo " -h Display this help and exit"
echo " -H <hook> Enable a hook to customize the created image. This can be" echo " -H <hook> Enable a hook to customize the created image. This can be"
echo " the path to a script, which will be executed once within" echo " the path to a script, which will be executed once within"
@ -70,7 +80,8 @@ usage() {
echo " below. This option can be specified multiple times." echo " below. This option can be specified multiple times."
echo " -k <kernel> Specify an additional kernel package (default: $DEF_KERNEL)." echo " -k <kernel> Specify an additional kernel package (default: $DEF_KERNEL)."
echo " This option can be specified multiple times; but note that" echo " This option can be specified multiple times; but note that"
echo " '$DEF_KERNEL' will be installed, regardless of this option." echo " '$DEF_KERNEL' will be installed as part of the '$PKG_SET_STD' and"
echo " '$PKG_SET_DEV' package sets, regardless of this option."
echo " -M <mirror> Specify a different mirror from which to fetch packages" echo " -M <mirror> Specify a different mirror from which to fetch packages"
echo " (default: $DEF_MIRROR)" echo " (default: $DEF_MIRROR)"
echo " -O Bootstrap an openrc system instead of a systemd one" echo " -O Bootstrap an openrc system instead of a systemd one"
@ -78,9 +89,18 @@ usage() {
echo " the 'preinit' hook is implemented as a systemd service." echo " the 'preinit' hook is implemented as a systemd service."
echo " -p <package> Specify additional packages to be installed in the VM image." echo " -p <package> Specify additional packages to be installed in the VM image."
echo " This option can be specified multiple times." echo " This option can be specified multiple times."
echo " -s <img_size> Set the size (in GB) of the VM image (minimum: $MIN_GB, default: $DEF_IMG_GB)" echo " Note that these will be ignored if -s <root_size> is 0."
echo " -s <root_size> Set the size (in MB) of the root partition (default: $DEF_ROOT_MB)."
echo " If this is 0 (or less than the <base-set> requires),"
echo " the VM image will be the smallest size possible,"
echo " fit to the <base-set>; and any -p <package> will be ignored."
echo " -S <swap_size> Set the size (in MB) of the swap partition (default: $DEF_SWAP_MB)" echo " -S <swap_size> Set the size (in MB) of the swap partition (default: $DEF_SWAP_MB)"
echo echo
echo "Pre-defined package-sets:"
print " $PKG_SET_MIN:%$((15 - ${#PKG_SET_MIN}))s${MIN_PKGS[*]}" ""
print " $PKG_SET_STD:%$((15 - ${#PKG_SET_STD}))s${STD_PKGS[*]}" ""
print " $PKG_SET_DEV:%$((15 - ${#PKG_SET_DEV}))s${DEV_PKGS[*]}" ""
echo
echo "Pre-defined hooks:" echo "Pre-defined hooks:"
echo " ethernet-dhcp: Configure and enable an ethernet device in the virtual" echo " ethernet-dhcp: Configure and enable an ethernet device in the virtual"
echo " machine, using openresolv, dhcpcd, and systemd-networkd" echo " machine, using openresolv, dhcpcd, and systemd-networkd"
@ -100,7 +120,8 @@ pvm_bootstrap() {
msg "starting creation of %s image: %s" "$arch" "$imagefile" msg "starting creation of %s image: %s" "$arch" "$imagefile"
# create the raw image file # create the raw image file
qemu-img create -f raw "$imagefile" "${ImgSizeGb}G" || return "$EXIT_FAILURE" local img_mb=$(( $BootSizeMb + $SwapSizeMb + $RootSizeMb ))
qemu-img create -f raw "$imagefile" "${img_mb}M" || return "$EXIT_FAILURE"
# prepare for cleanup # prepare for cleanup
trap 'pvm_cleanup' INT TERM RETURN trap 'pvm_cleanup' INT TERM RETURN
@ -213,9 +234,9 @@ pvm_bootstrap() {
done done
# prepare package lists # prepare package lists
local kernels=( ${Kernels[@]} ) local kernels=( ${Kernels[@]} )
local pkgs=( ${DEF_PKGS[@]} ${Kernels[@]} ${Pkgs[@]} ) local pkgs=( ${Pkgs[@]} ${Kernels[@]} ${OptPkgs[@]} )
local pkgs_cached=( ${GUEST_CACHED_PKGS[@]} ) local pkgs_cached=( ${GUEST_CACHED_PKGS[@]} )
case "$arch" in case "$arch" in
i686|x86_64) pkgs+=(grub) ;; i686|x86_64) pkgs+=(grub) ;;
riscv64 ) ;; riscv64 ) ;;
@ -341,7 +362,8 @@ rm -f /var/cache/pacman/pkg/*
rm -f /root/.bash_history rm -f /root/.bash_history
# report success :) # report success :)
echo "$hooks_success_msg" echo "$hooks_success_msg - powering off"
[[ -e "/usr/lib/libretools/common.sh" ]] && rm -f /usr/lib/libretools/common.sh
EOF EOF
# create a pre-init service to run the hooks # create a pre-init service to run the hooks
@ -356,7 +378,6 @@ StandardOutput=journal+console
StandardError=journal+console StandardError=journal+console
ExecStart=/usr/bin/bash /root/hooks.sh ExecStart=/usr/bin/bash /root/hooks.sh
Type=oneshot Type=oneshot
ExecStopPost=echo "powering off"
ExecStopPost=shutdown -r now ExecStopPost=shutdown -r now
[Install] [Install]
@ -400,17 +421,18 @@ EOF
pvm_cleanup() { pvm_cleanup() {
trap - INT TERM RETURN trap - INT TERM RETURN
msg "cleaning up" [ -n "${workdir}${loopdev}${pacconf}" ] && msg "cleaning up"
[ -n "$pacconf" ] && rm -f "$pacconf"
unset pacconf
if [ -n "$workdir" ]; then if [ -n "$workdir" ]; then
sudo rm -f "$workdir"/usr/bin/qemu-* sudo rm -f "$workdir"/usr/bin/qemu-*C
sudo umount -R "$workdir" 2> /dev/null sudo umount -R "$workdir" 2> /dev/null
rmdir "$workdir" rmdir "$workdir"
fi fi
if [ -n "$loopdev" ]; then sudo losetup -d "$loopdev"; fi;
if [ -n "$pacconf" ]; then rm -f "$pacconf"; fi;
unset workdir unset workdir
[ -n "$loopdev" ] && sudo losetup -d "$loopdev"
unset loopdev unset loopdev
unset pacconf
} }
main() { main() {
@ -420,8 +442,16 @@ main() {
fi fi
# parse options # parse options
while getopts 'hH:k:M:Op:s:S:' arg; do while getopts 'b:hH:k:M:Op:s:S:' arg; do
case "$arg" in case "$arg" in
b) case $OPTARG in $PKG_SET_MIN) BasePkgSet=$OPTARG ;
Pkgs=(${MIN_PKGS[@]}) ; MinRootMb=$ROOT_MB_MIN ;;
$PKG_SET_STD) BasePkgSet=$OPTARG ; Kernels+=($DEF_KERNEL) ;
Pkgs=(${STD_PKGS[@]}) ; MinRootMb=$ROOT_MB_STD ;;
$PKG_SET_DEV) BasePkgSet=$OPTARG ; Kernels+=($DEF_KERNEL) ;
Pkgs=(${DEV_PKGS[@]}) ; MinRootMb=$ROOT_MB_DEV ;;
* ) warning "%s: invalid base set" "$OPTARG" ;;
esac ;;
h) usage; return "$EXIT_SUCCESS";; h) usage; return "$EXIT_SUCCESS";;
H) if [ -e "$THIS_DIR/hooks/hook-$OPTARG.sh" ]; then # in-tree H) if [ -e "$THIS_DIR/hooks/hook-$OPTARG.sh" ]; then # in-tree
Hooks+=("$THIS_DIR/hooks/hook-$OPTARG.sh") Hooks+=("$THIS_DIR/hooks/hook-$OPTARG.sh")
@ -435,8 +465,8 @@ main() {
k) Kernels+=($OPTARG);; k) Kernels+=($OPTARG);;
M) Mirror="$OPTARG";; M) Mirror="$OPTARG";;
O) IsNonsystemd=0;; # TODO: O) IsNonsystemd=0;; # TODO:
p) Pkgs+=($OPTARG);; p) OptPkgs+=($OPTARG);;
s) ImgSizeGb="$( sed 's|[^0-9]||g' <<<$OPTARG)";; s) RootSizeMb="$(sed 's|[^0-9]||g' <<<$OPTARG)";;
S) SwapSizeMb="$(sed 's|[^0-9]||g' <<<$OPTARG)";; S) SwapSizeMb="$(sed 's|[^0-9]||g' <<<$OPTARG)";;
*) error "invalid argument: %s\n" "$arg"; usage >&2; exit "$EXIT_INVALIDARGUMENT";; *) error "invalid argument: %s\n" "$arg"; usage >&2; exit "$EXIT_INVALIDARGUMENT";;
esac esac
@ -446,11 +476,13 @@ main() {
shift $shiftlen shift $shiftlen
local imagefile="$1" local imagefile="$1"
local arch="$2" local arch="$2"
local has_params=$( (( $# == 2 )) && echo 1 || echo 0 ) (( $# != 2 )) && error "insufficient arguments" && usage >&2 && exit "$EXIT_INVALIDARGUMENT"
local has_space=$( (( ($ImgSizeGb*1000) >= ($MIN_GB*1000) + $SwapSizeMb )) && echo 1 || echo 0 )
HasSwap=$( (( $SwapSizeMb > 0 )) && echo 1 || echo 0 ) (( $RootSizeMb > 0 )) && \
(( ! $has_params )) && error "insufficient arguments" && usage >&2 && exit "$EXIT_INVALIDARGUMENT" (( $RootSizeMb < $MinRootMb )) && warning "specified root FS size too small - ignoring OptPkgs"
(( ! $has_space )) && error "image size too small" && usage >&2 && exit "$EXIT_INVALIDARGUMENT" (( $RootSizeMb < $MinRootMb )) && RootSizeMb=$MinRootMb && OptPkgs=()
RootSizeMb=$(( $RootSizeMb + (${#Kernels[@]} * 75) ))
HasSwap=$( (( $SwapSizeMb > 0 )) && echo 1 || echo 0 )
# determine if the target arch is supported # determine if the target arch is supported
case "$arch" in case "$arch" in