summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbill-auger <mr.j.spam.me@gmail.com>2023-08-16 13:58:08 -0400
committerbill-auger <mr.j.spam.me@gmail.com>2023-08-17 21:20:52 -0400
commit32078c3bfac9cb7d46dafb814a385efbd993da3e (patch)
treed839fd571c1ac92b5080049a0e092bbd8ed52865
parent8bc826fb0d662204c98517a4b2968447c3af44bd (diff)
validations, refactoring, housekeepingHEADv20230816master
-rw-r--r--src/pvm-common.sh.inc57
-rwxr-xr-xsrc/pvmbootstrap.sh277
2 files changed, 195 insertions, 139 deletions
diff --git a/src/pvm-common.sh.inc b/src/pvm-common.sh.inc
index 6da7685..1e37408 100644
--- a/src/pvm-common.sh.inc
+++ b/src/pvm-common.sh.inc
@@ -1,23 +1,24 @@
#!/bin/bash
-###############################################################################
-# parabola-vmbootstrap -- create and start parabola virtual machines #
-# #
-# Copyright (C) 2017 - 2019 Andreas Grapentin #
-# Copyright (C) 2019 - 2020 bill-auger #
-# #
-# This program 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 program 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 program. If not, see <http://www.gnu.org/licenses/>. #
-###############################################################################
+
+###########################################################################
+# parabola-vmbootstrap -- create and start parabola virtual machines #
+# #
+# Copyright (C) 2017-2019 Andreas Grapentin #
+# Copyright (C) 2019-2020,2023 bill-auger #
+# #
+# This program 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 program 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 program. If not, see <http://www.gnu.org/licenses/>. #
+###########################################################################
# readonly DATA_IMG=./pvmdata.img # optional large qemu disk
@@ -34,7 +35,7 @@ source "$(librelib messages)"
pvm_get_script() # (script_name)
{
local script_name=$1
- local intree_script=$THIS_DIR/$script_name.sh
+ local intree_script="$THIS_DIR"/$script_name.sh
local installed_script=$script_name
[[ -f "$intree_script" ]] && echo "$intree_script" && return "$EXIT_SUCCESS"
@@ -44,16 +45,18 @@ pvm_get_script() # (script_name)
pvm_get_hook() # ( hook_name )
{
- local hook_name=$1
- local intree_dir=$THIS_DIR/hooks
+ local hook_name="$1"
+ local intree_dir="$THIS_DIR"/hooks
local installed_dir=/usr/lib/parabola-vmbootstrap
local hook_filename=hook-$hook_name.sh
- local locations=( "$intree_dir/$hook_filename" "$installed_dir/$hook_filename" "$hook_name" '' )
- local location
+ local paths=( "$intree_dir/$hook_filename" "$installed_dir/$hook_filename" "$hook_name" '' )
+ local filename_warning="hook filenames must not contain spaces"
+ local hook path
+
+ (( $# == 1 )) && [[ ! "$1" =~ ' ' ]] || ! warning "$filename_warning" || paths=()
- for location in "${locations[@]}" ; do [[ -f "$location" ]] && break ; done ;
- [[ "$location" ]] && echo "$location" || warning "no such hook: '%s'" "$hook_name"
- [[ "$location" ]] && return "$EXIT_SUCCESS" || return "$EXIT_FAILURE"
+ hook="$(for path in "${paths[@]}" ; do ls "$hook" ; done | head -n 1 ;)"
+ [[ -f "$hook" ]] && echo "$hook" || ! warning "no such hook: '%s'" "$hook_name"
}
pvm_find_part_n() # ( imagefile fs_types ) , sets: $part_n
diff --git a/src/pvmbootstrap.sh b/src/pvmbootstrap.sh
index 16ce955..8ca2ad8 100755
--- a/src/pvmbootstrap.sh
+++ b/src/pvmbootstrap.sh
@@ -1,58 +1,65 @@
#!/bin/bash
-###############################################################################
-# parabola-vmbootstrap -- create and start parabola virtual machines #
-# #
-# Copyright (C) 2017 - 2019 Andreas Grapentin #
-# Copyright (C) 2019 - 2020 bill-auger #
-# #
-# This program 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 program 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 program. If not, see <http://www.gnu.org/licenses/>. #
-###############################################################################
+
+###########################################################################
+# parabola-vmbootstrap -- create and start parabola virtual machines #
+# #
+# Copyright (C) 2017-2020 Andreas Grapentin #
+# Copyright (C) 2019-2020,2023 bill-auger #
+# #
+# This program 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 program 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 program. If not, see <http://www.gnu.org/licenses/>. #
+###########################################################################
# defaults
-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=1125 ; # 841 (pacstrap)
-readonly STD_PKGS=('base' 'parabola-base' ) ; readonly ROOT_MB_STD=1250 ; # 898 (pacstrap)
-readonly DEV_PKGS=('base' 'parabola-base' 'base-devel') ; readonly ROOT_MB_DEV=1500 ; # 1163 (pacstrap)
-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 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=1125 ; # 841 (pacstrap)
+readonly STD_PKGS=( base parabola-base ) ; readonly ROOT_MB_STD=1250 ; # 898 (pacstrap)
+readonly DEV_PKGS=( base parabola-base base-devel ) ; readonly ROOT_MB_DEV=1500 ; # 1163 (pacstrap)
+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_MIRROR=https://repo.parabola.nu
readonly DEF_ROOT_MB=32000
readonly DEF_BOOT_MB=150
readonly DEF_SWAP_MB=0
-readonly PKGS_MANDATORY_ALL=( )
-readonly PKGS_MANDATORY_armv7h=( haveged net-tools )
-readonly PKGS_MANDATORY_i686=( haveged net-tools grub )
-readonly PKGS_MANDATORY_ppc64le=( haveged net-tools )
-readonly PKGS_MANDATORY_riscv64=( )
-readonly PKGS_MANDATORY_x86_64=( haveged net-tools grub )
-
-# misc
-readonly PKGS_GUEST_CACHED=('ca-certificates-utils')
+readonly PKGS_ALL=( haveged net-tools )
+readonly PKGS_armv7h=( )
+readonly PKGS_i686=( grub )
+readonly PKGS_ppc64le=( )
+readonly PKGS_riscv64=( )
+readonly PKGS_x86_64=( grub )
+
+# misc constants
+readonly PKGS_NETWORKING=( dhcpcd )
+readonly PKGS_NONSYSTEMD=( libelogind ) # resolve conflicts in 'nonsystemd/base'
+readonly PKGS_GUEST_CACHED=( ca-certificates-utils )
+readonly REPOS_STANDARD=( libre core extra )
+readonly REPOS_NONSYSTEMD=( nonsystemd )
+readonly CACHE_DIR=/var/cache/pacman/pkg # in-chroot
readonly PVM_HOOKS_SUCCESS_MSG="[hooks.sh] pre-init hooks successful"
-# options
+
+# options (over-ride defaults per CLI args)
BasePkgSet=$DEF_PKG_SET
MinRootMb=$DEF_MIN_MB
Hooks=()
-Kernels=($DEF_KERNEL)
+Kernels=( $DEF_KERNEL )
Mirror=$DEF_MIRROR
IsNonsystemd=0
-Pkgs=(${DEF_PKGS[@]})
-PkgsCached=(${PKGS_GUEST_CACHED[@]})
+Pkgs=( ${DEF_PKGS[*]} )
+PkgsCached=( ${PKGS_GUEST_CACHED[*]} )
PkgsOptional=()
RootSizeMb=$DEF_ROOT_MB
BootSizeMb=$DEF_BOOT_MB
@@ -93,7 +100,7 @@ usage()
echo " (default: $DEF_MIRROR)"
echo " -O Bootstrap an openrc system instead of a systemd one"
echo " NOTE: This option is currently ignored; because"
- echo " the 'preinit' hook is implemented as a systemd service."
+ echo " the 'pre-init' hook is implemented as a systemd service."
echo " -p <package> Specify an additional package to be installed in the image."
echo " This option can be specified multiple times;"
echo " but note that these will be ignored if -s <root_size> is 0."
@@ -177,6 +184,7 @@ pvm_bootstrap() # assumes: $arch $imagefile $loopdev $workdir , traps: INT TERM
i686|x86_64 ) boot_mkfs_cmd='mkfs.ext2' ;;
ppc64le|riscv64) boot_mkfs_cmd='mkfs.ext2' ;;
esac
+
msg "creating target filesystems"
sudo $boot_mkfs_cmd "$boot_loopdev" || return "$EXIT_FAILURE"
! (( $HasSwap )) || \
@@ -213,19 +221,24 @@ pvm_bootstrap() # assumes: $arch $imagefile $loopdev $workdir , traps: INT TERM
# prepare pacstrap config
local pacconf="$(mktemp -t pvm-pacconf-XXXXXXXXXX)" || return "$EXIT_FAILURE"
- local repos=(libre core extra community pcr)
- (( $IsNonsystemd )) && repos=('nonsystemd' ${repos[@]})
- echo -e "[options]\nArchitecture = $arch" > "$pacconf"
- for repo in ${repos[@]}; do echo "[$repo]" >> "$pacconf";
- for mirror_n in {1..5}; do echo "Server = $Mirror/\$repo/os/\$arch" >> "$pacconf"; done;
+ local repos=( ${REPOS_STANDARD[*]} $((( $IsNonsystemd )) && echo ${REPOS_NONSYSTEMD[*]}) )
+ echo -e "[options]\nArchitecture = $arch" > "$pacconf"
+ for repo in ${repos[*]} ; do echo "[$repo]" >> "$pacconf" ;
+ for n in {1..5} ; do echo "Server = $Mirror/\$repo/os/\$arch" >> "$pacconf" ; done ;
done
# pacstrap! :)
- msg "installing packages into the work chroot"
- sudo pacstrap -GMc -C "$pacconf" "$workdir" "${Pkgs[@]}" || return "$EXIT_FAILURE"
- sudo pacman -Sw --config "$pacconf" --root "$workdir" \
- --cachedir "$workdir"/var/cache/pacman/pkg --noconfirm \
- "${PkgsCached[@]}" || return "$EXIT_FAILURE"
+ local pacstrap_msg="installing (${#Pkgs[*]}) packages into the work chroot:"
+ local cache_msg="caching (${#PkgsCached[*]}) packages into the work chroot:"
+ local cachedir="$workdir/$CACHE_DIR"
+ msg "$pacstrap_msg" ; prose "${Pkgs[*]}" ;
+ sudo pacstrap -GMc -C "$pacconf" "$workdir" ${Pkgs[*]} || return "$EXIT_FAILURE"
+ if (( ${#PkgsCached[*]} ))
+ then msg2 "${cache_msg}" ; prose "${PkgsCached[*]}" ;
+ sudo pacman -S --config "$pacconf" --downloadonly \
+ --root "$workdir" --cachedir "$cachedir" \
+ --noconfirm ${PkgsCached[*]} || return "$EXIT_FAILURE"
+ fi
# generate list of installed packages
msg2 "generating a list of installed packages"
@@ -288,7 +301,7 @@ pvm_bootstrap() # assumes: $arch $imagefile $loopdev $workdir , traps: INT TERM
esac
# regenerate the initcpio(s), to skip the 'autodetect' hook
- for kernel in ${Kernels[@]}
+ for kernel in ${Kernels[*]}
do
local preset_file="$workdir"/etc/mkinitcpio.d/${kernel}.preset
local default_options="default_options=\"-S autodetect\""
@@ -304,15 +317,17 @@ pvm_bootstrap() # assumes: $arch $imagefile $loopdev $workdir , traps: INT TERM
done
# initialize the pacman keyring
+ local keyrings=( $(for pkg in ${Pkgs[*]} ;
+ do [[ "$pkg" =~ -keyring$ ]] && echo ${pkg%-keyring} ;
+ done) )
msg "initializing the pacman keyring"
sudo arch-chroot "$workdir" pacman-key --init
- sudo arch-chroot "$workdir" pacman-key --populate archlinux archlinux32 archlinuxarm parabola
+ sudo arch-chroot "$workdir" pacman-key --populate ${keyrings[*]}
# push hooks into the image
msg "preparing hooks"
sudo mkdir -p "$workdir"/root/hooks
- [ "${#Hooks[@]}" -eq 0 ] || sudo cp -v "${Hooks[@]}" "$workdir"/root/hooks/
- (( $IsNonsystemd )) && sudo rm "$workdir"/root/hooks/hook-ethernet-dhcp.sh # systemd-only hook
+ for hook in ${Hooks[@]} ; do sudo cp -v "$hook" "$workdir"/root/hooks/ ; done ;
# create a master hook script
msg2 "hooks.sh:"
@@ -324,10 +339,17 @@ echo "[hooks.sh] boot successful - configuring ...."
locale-gen
# fix the mkinitcpio
-for kernel in ${Kernels[@]} ; do mkinitcpio -p \$kernel ; done ;
+for kernel in ${Kernels[*]} ; do mkinitcpio -p \$kernel ; done ;
# fix ca-certificates
-pacman -U --noconfirm /var/cache/pacman/pkg/ca-certificates-utils-*.pkg.tar.zst
+certs_pkg=\$(ls ${CACHE_DIR}/ca-certificates-utils-*.pkg.tar.zst)
+if [[ -f \$certs_pkg ]]
+then pacman -U --noconfirm \$certs_pkg ||
+ ! echo "[hooks.sh] ERROR: 'ca-certificates-utils' install failed" ||
+ exit "$EXIT_FAILURE"
+else echo "[hooks.sh] ERROR: could not find 'ca-certificates-utils' package"
+ exit "$EXIT_FAILURE"
+fi
# run the hooks
shopt -s nullglob
@@ -339,22 +361,25 @@ done
shopt -u nullglob
# clean up after yourself
-systemctl disable preinit.service
+systemctl disable pre-init.service
+#rm -f /etc/init.d/pre-init # TODO: non-systemd hooks NYI
rm -f /root/.bash_history
rm -rf /root/hooks
-rm -f /root/hooks.sh
-rm -f /usr/lib/systemd/system/preinit.service
-rm -f /var/cache/pacman/pkg/*
+rm -f /root/hooks.sh # this file
+rm -f /usr/lib/systemd/system/pre-init.service
+rm -f $CACHE_DIR/*
# report success :)
echo "$PVM_HOOKS_SUCCESS_MSG - powering off"
EOF
# create a pre-init service to run the hooks
- msg2 "preinit.service:"
- sudo tee "$workdir"/usr/lib/systemd/system/preinit.service << 'EOF'
+ msg2 "pre-init.service:"
+ if (( IsNonsystemd ))
+ then ;
+ else sudo tee "$workdir"/usr/lib/systemd/system/pre-init.service << 'EOF'
[Unit]
-Description=Oneshot VM Preinit
+Description=Oneshot VM Pre-init
After=multi-user.target
[Service]
@@ -367,15 +392,19 @@ ExecStopPost=shutdown -r now
[Install]
WantedBy=multi-user.target
EOF
+ fi
# configure services
msg "configuring services"
- # disable audit
- sudo arch-chroot "$workdir" systemctl mask systemd-journald-audit.socket
- # enable the entropy daemon, to avoid stalling https
- sudo arch-chroot "$workdir" systemctl enable haveged.service
- # enable the pre-init service
- sudo arch-chroot "$workdir" systemctl enable preinit.service || return "$EXIT_FAILURE"
+ if (( IsNonsystemd ))
+ then ;
+ else # disable audit
+ sudo arch-chroot "$workdir" systemctl mask systemd-journald-audit.socket
+ # enable the entropy daemon, to avoid stalling https
+ sudo arch-chroot "$workdir" systemctl enable haveged.service
+ # enable the pre-init service
+ sudo arch-chroot "$workdir" systemctl enable pre-init.service || return "$EXIT_FAILURE"
+ fi
# unmount everything
pvm_bootstrap_cleanup
@@ -392,7 +421,7 @@ pvm_bootstrap_preinit() # assumes: $imagefile
pvm_boot "$imagefile" | tee /dev/fd/3 | grep -q -F "$PVM_HOOKS_SUCCESS_MSG"
local res=$?
exec 3>&-
- ! (( $res )) || error "%s: failed to complete preinit hooks" "$imagefile"
+ ! (( $res )) || error "%s: failed to complete pre-init hooks" "$imagefile"
return $res
}
@@ -412,15 +441,20 @@ pvm_bootstrap_cleanup() # unsets: $pacconf , untraps: INT TERM RETURN
main() # ( [cli_options] imagefile arch )
{
+ msg "validating build parameters"
+
pvm_check_unprivileged # exits on failure
+
+ ## parse CLI args ##
+
# parse options
while getopts 'b:hH:k:M:Op:s:S:' arg; do
case "$arg" in
b) case $OPTARG in
- $PKG_SET_MIN) BasePkgSet=$OPTARG ; Pkgs=(${MIN_PKGS[@]}) ; MinRootMb=$ROOT_MB_MIN ;;
- $PKG_SET_STD) BasePkgSet=$OPTARG ; Pkgs=(${STD_PKGS[@]}) ; MinRootMb=$ROOT_MB_STD ;;
- $PKG_SET_DEV) BasePkgSet=$OPTARG ; Pkgs=(${DEV_PKGS[@]}) ; MinRootMb=$ROOT_MB_DEV ;;
+ $PKG_SET_MIN) BasePkgSet=$OPTARG ; Pkgs=(${MIN_PKGS[*]}) ; MinRootMb=$ROOT_MB_MIN ;;
+ $PKG_SET_STD) BasePkgSet=$OPTARG ; Pkgs=(${STD_PKGS[*]}) ; MinRootMb=$ROOT_MB_STD ;;
+ $PKG_SET_DEV) BasePkgSet=$OPTARG ; Pkgs=(${DEV_PKGS[*]}) ; MinRootMb=$ROOT_MB_DEV ;;
* ) warning "invalid base set: %s" "$OPTARG" ;;
esac ;;
c) PkgsCached+=($OPTARG) ;;
@@ -428,7 +462,7 @@ main() # ( [cli_options] imagefile arch )
H) Hooks+=( "$(pvm_get_hook $OPTARG)" ) ;;
k) Kernels+=($OPTARG) ;;
M) Mirror="$OPTARG" ;;
- O) IsNonsystemd=0 ;; # TODO:
+ O) IsNonsystemd=0 ;; # TODO: non-systemd hooks NYI
p) PkgsOptional+=($OPTARG) ;;
s) RootSizeMb="$(sed 's|[^0-9]||g' <<<$OPTARG)" ;;
S) SwapSizeMb="$(sed 's|[^0-9]||g' <<<$OPTARG)" ;;
@@ -437,65 +471,84 @@ main() # ( [cli_options] imagefile arch )
done
local shiftlen=$(( OPTIND - 1 ))
shift $shiftlen
+
+ # validate CLI args
local imagefile="$1"
local arch="$2"
- (( $# < 2 )) && error "insufficient arguments" && usage >&2 && exit "$EXIT_INVALIDARGUMENT"
+ (( $# != 2 )) && error "insufficient arguments" && usage >&2 && exit "$EXIT_INVALIDARGUMENT"
+ case "$arch" in
+ i686|x86_64|armv7h) ;;
+ ppc64le|riscv64 ) warning "arch is experimental: %s" "$arch" ;;
+ * ) error "arch is unsupported: %s" "$arch"
+ exit "$EXIT_INVALIDARGUMENT" ;;
+ esac
+
+
+ ## calculate options-dependent config vars ##
- # vaidate options and calculate options-dependent vars
- (( $RootSizeMb > 0 )) && \
- (( $RootSizeMb < $MinRootMb )) && warning "specified root FS size too small - ignoring -c and -p packages"
- (( $RootSizeMb < $MinRootMb )) && RootSizeMb=$MinRootMb PkgsCached=() PkgsOptional=()
- RootSizeMb=$(( $RootSizeMb + (${#Kernels[@]} * 75) ))
- ImgSizeMb=$(( $BootSizeMb + $SwapSizeMb + $RootSizeMb ))
- HasSwap=$( (( $SwapSizeMb > 0 )) && echo 1 || echo 0 )
+ # normalize target image filename
+ [[ -d "$imagefile" ]] && imagefile="$imagefile/parabola-$(date -I).img"
+ [[ "$imagefile" =~ \.img$ ]] || imagefile="$imagefile.img"
+
+ # calculate target filesystem sizes
+ local n_extra_kernels=$((( ${#Kernels[*]} )) && echo ${#Kernels[*]} - 1 || echo 0)
+ MinBootMb=$(( MinBootMb + (n_extra_kernels * 75) ))
+ MinRootMb=$(( MinRootMb + (n_extra_kernels * 75) ))
+ local opt_msg="optimizing root FS size - ignoring -c and -p packages"
+ local warn_msg="specified root FS size too small - ignoring -c and -p packages"
+ (( RootSizeMb == 0 )) && msg2 "$opt_msg" || warning "$warn_msg"
+ (( BootSizeMb < MinBootMb )) && BootSizeMb=$MinBootMb
+ (( RootSizeMb < MinRootMb )) && RootSizeMb=$MinRootMb PkgsOptional=() &&
+ PkgsCached=( ${PKGS_GUEST_CACHED[*]} )
+ ImgSizeMb=$(( BootSizeMb + SwapSizeMb + RootSizeMb ))
+ HasSwap=$( echo $(( SwapSizeMb > 0 )) )
# prepare package lists
- local kernels=( ${Kernels[@]} )
- local pkgs=( ${Pkgs[@]} ${Kernels[@]} ${PkgsOptional[@]} ${PKGS_MANDATORY_ALL[@]} )
- local pkgs_cached=( ${PkgsCached[@]} )
+ local kernels=( ${Kernels[*]} )
+ local pkgs=( ${Kernels[*]} ${Pkgs[*]} ${PkgsOptional[*]} \
+ ${PKGS_ALL[*]} $(eval "echo \${PKGS_$arch[*]}") )
+ local pkgs_cached=( ${PkgsCached[*]} )
+ pkgs+=( archlinux-keyring parabola-keyring )
case "$arch" in
- armv7h ) pkgs+=( ${PKGS_MANDATORY_armv7h[@]} ) ;;
- i686 ) pkgs+=( ${PKGS_MANDATORY_i686[@]} ) ;;
- ppc64le) pkgs+=( ${PKGS_MANDATORY_ppc64le[@]} ) ;;
- riscv64) pkgs+=( ${PKGS_MANDATORY_riscv64[@]} ) ;;
- x86_64 ) pkgs+=( ${PKGS_MANDATORY_x86_64[@]} ) ;;
+ armv7h) pkgs+=( archlinuxarm-keyring ) ;;
+ i686 ) pkgs+=( archlinux32-keyring ) ;;
esac
- (( $IsNonsystemd )) && [[ "$BasePkgSet" == "$PKG_SET_MIN" ]] && pkgs+=(libelogind)
- (( ! $IsNonsystemd )) && [[ "${Hooks[@]}" =~ hook-ethernet-dhcp.sh ]] && pkgs+=(dhcpcd )
+ (( IsNonsystemd )) && Hooks=( ${Hooks[*]/*ethernet-dhcp*/} ) # TODO: non-systemd hooks NYI
+ (( IsNonsystemd )) && pkgs+=( ${PKGS_NONSYSTEMD[*]} )
+ [[ "${Hooks[@]}" =~ ethernet-dhcp ]] && pkgs+=( ${PKGS_NETWORKING[*]} )
# minimize package lists
- local kernel ; local pkg ; Kernels=() ; Pkgs=() ; PkgsCached=() ;
- for kernel in $(printf "%s\n" "${kernels[@]}" | sort -u) ; do Kernels+=($kernel) ; done ;
- for pkg in $(printf "%s\n" "${pkgs[@]}" | sort -u) ; do Pkgs+=($pkg) ; done ;
- for pkg in $(printf "%s\n" "${pkgs_cached[@]}" | sort -u) ; do PkgsCached+=($pkg) ; done ;
+ local kernel pkg ; Kernels=() ; Pkgs=() ; PkgsCached=() ;
+ for kernel in $(printf "%s\n" "${kernels[*]}" | sort -u) ; do Kernels+=($kernel) ; done ;
+ for pkg in $(printf "%s\n" "${pkgs[*]}" | sort -u) ; do Pkgs+=($pkg) ; done ;
+ for pkg in $(printf "%s\n" "${pkgs_cached[*]}" | sort -u) ; do PkgsCached+=($pkg) ; done ;
- msg "making $arch image: $imagefile"
- # determine if the target arch is supported
- case "$arch" in
- i686|x86_64|armv7h) ;;
- ppc64le|riscv64 ) warning "arch is experimental: %s" "$arch" ;;
- * ) error "arch is unsupported: %s" "$arch"
- exit "$EXIT_INVALIDARGUMENT" ;;
- esac
+ ## build ##
+
+ msg "making $arch image (${ImgSizeMb}MB): $imagefile"
# create the virtual machine
+ declare -i was_err=0
+ local err_msg=" - renaming to $imagefile-failed.img"
if pvm_bootstrap; then
if pvm_bootstrap_preinit; then
- msg "bootstrap complete for image: %s" "$imagefile"
- exit "$EXIT_SUCCESS"
+ was_err="$EXIT_SUCCESS" ; msg "bootstrap complete" ;
else
- error "bootstrap complete, but preinit failed for image: %s" "$imagefile"
- exit "$EXIT_FAILURE"
+ was_err="$EXIT_FAILURE" ; error "bootstrap complete, but pre-init failed$err_msg" ;
fi
else
- error "bootstrap failed for image: %s" "$imagefile"
- exit "$EXIT_FAILURE"
+ was_err="$EXIT_FAILURE" ; error "bootstrap failed$err_msg" ;
fi
+
+ # cleanup
+ (( ! was_err )) || mv "$imagefile" "$imagefile"-failed.img &> /dev/null
+
+ return $was_err
}
-if source "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"/pvm-common.sh.inc 2> /dev/null || \
+if source "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"/pvm-common.sh.inc 2> /dev/null ||
source /usr/lib/parabola-vmbootstrap/pvm-common.sh.inc 2> /dev/null
then main "$@"
else echo "can not find pvm-common.sh.inc" && exit 1