housekeeping
This commit is contained in:
parent
164b5b98b9
commit
68fb5be67a
@ -19,10 +19,10 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
# shellcheck source=/usr/lib/libretools/messages.sh
|
# shellcheck source=/usr/lib/libretools/messages.sh
|
||||||
. "$(librelib messages)"
|
source "$(librelib messages)"
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
print "usage: %s [-h] [-o FILE] IMG" "${0##*/}"
|
print "USAGE: %s [-h] [-o FILE] IMG" "${0##*/}"
|
||||||
prose "Produce a parabola release tarball from IMG."
|
prose "Produce a parabola release tarball from IMG."
|
||||||
echo
|
echo
|
||||||
prose "IMG is expected to be a valid parabola image, ideally freshly bootstrapped
|
prose "IMG is expected to be a valid parabola image, ideally freshly bootstrapped
|
||||||
@ -39,18 +39,18 @@ usage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pvm_mount() {
|
pvm_mount() {
|
||||||
if ! file "$1" | grep -q ' DOS/MBR '; then
|
if ! file "$imagefile" | grep -q ' DOS/MBR '; then
|
||||||
error "%s: does not seem to be a raw qemu image." "$1"
|
error "%s: does not seem to be a raw qemu image." "$imagefile"
|
||||||
return "$EXIT_FAILURE"
|
return "$EXIT_FAILURE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
trap 'pvm_umount' INT TERM EXIT
|
trap 'pvm_umount' INT TERM EXIT
|
||||||
|
|
||||||
workdir="$(mktemp -d -t pvm-XXXXXXXXXX)" || return
|
workdir="$(mktemp -d -t pvm-XXXXXXXXXX)" || return
|
||||||
loopdev="$(sudo losetup -fLP --show "$1")" || return
|
loopdev="$(sudo losetup -fLP --show "$imagefile")" || return
|
||||||
|
|
||||||
# find the root partition
|
# find the root partition
|
||||||
local part rootpart
|
local part rootpart bootpart
|
||||||
for part in "$loopdev"p*; do
|
for part in "$loopdev"p*; do
|
||||||
sudo mount "$part" "$workdir" || continue
|
sudo mount "$part" "$workdir" || continue
|
||||||
if [ -f "$workdir"/etc/fstab ]; then
|
if [ -f "$workdir"/etc/fstab ]; then
|
||||||
@ -61,7 +61,7 @@ pvm_mount() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ -z "$rootpart" ]; then
|
if [ -z "$rootpart" ]; then
|
||||||
error "%s: unable to determine root partition." "$1"
|
error "%s: unable to determine root partition." "$imagefile"
|
||||||
return "$EXIT_FAILURE"
|
return "$EXIT_FAILURE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ pvm_mount() {
|
|||||||
bootpart="$(findmnt -senF "$workdir"/etc/fstab /boot | awk '{print $2}')"
|
bootpart="$(findmnt -senF "$workdir"/etc/fstab /boot | awk '{print $2}')"
|
||||||
|
|
||||||
if [ -z "$bootpart" ]; then
|
if [ -z "$bootpart" ]; then
|
||||||
error "%s: unable to determine boot partition." "$1"
|
error "%s: unable to determine boot partition." "$imagefile"
|
||||||
return "$EXIT_FAILURE"
|
return "$EXIT_FAILURE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -105,8 +105,8 @@ main() {
|
|||||||
shift $shiftlen
|
shift $shiftlen
|
||||||
if [ "$#" -ne 1 ]; then usage >&2; exit "$EXIT_INVALIDARGUMENT"; fi
|
if [ "$#" -ne 1 ]; then usage >&2; exit "$EXIT_INVALIDARGUMENT"; fi
|
||||||
|
|
||||||
local imagebase imagefile="$1"
|
local image_filename imagefile="$1"
|
||||||
imagebase="$(basename "$imagefile")"
|
image_filename="$(basename "$imagefile")"
|
||||||
shift
|
shift
|
||||||
|
|
||||||
# check for input file presence
|
# check for input file presence
|
||||||
@ -116,7 +116,7 @@ main() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# determine output file
|
# determine output file
|
||||||
[ -n "$output" ] || output="${imagebase%.*}.tar.gz"
|
[ -n "$output" ] || output="${image_filename%.img*}.tar.gz"
|
||||||
|
|
||||||
# check for output file presence
|
# check for output file presence
|
||||||
if [ -e "$output" ]; then
|
if [ -e "$output" ]; then
|
||||||
@ -131,9 +131,15 @@ main() {
|
|||||||
|
|
||||||
# mount the root filesystem
|
# mount the root filesystem
|
||||||
local workdir loopdev
|
local workdir loopdev
|
||||||
pvm_mount "$imagefile" || exit
|
pvm_mount || exit
|
||||||
|
|
||||||
# tar the root filesystem, excluding unneeded things
|
# tar the root filesystem, excluding unneeded things
|
||||||
|
# HACKING:
|
||||||
|
# to update the exclude list, one can download the latest archlinuxarm
|
||||||
|
# release tarball, and scroll over the diff generated by running both the
|
||||||
|
# archlinuxarm and the generated parabola tarball through:
|
||||||
|
#
|
||||||
|
# `tar -tf <tarball> | sort`
|
||||||
sudo tar -c -f "$output" -C "$workdir" -X - . << EOF
|
sudo tar -c -f "$output" -C "$workdir" -X - . << EOF
|
||||||
./boot/lost+found
|
./boot/lost+found
|
||||||
./etc/.updated
|
./etc/.updated
|
||||||
@ -146,13 +152,6 @@ main() {
|
|||||||
./var/log/tallylog
|
./var/log/tallylog
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# HACKING:
|
|
||||||
# to update the exclude list above, one can download the latest archlinuxarm
|
|
||||||
# release tarball, and scroll over the diff generated by running both the
|
|
||||||
# archlinuxarm and the generated parabola tarball through:
|
|
||||||
#
|
|
||||||
# `tar -tf <tarball> | sort`
|
|
||||||
|
|
||||||
# give the archive back to the user
|
# give the archive back to the user
|
||||||
sudo chown "$(id -u)":"$(id -g)" "$output"
|
sudo chown "$(id -u)":"$(id -g)" "$output"
|
||||||
|
|
||||||
@ -161,4 +160,3 @@ EOF
|
|||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|
||||||
|
@ -19,29 +19,30 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
# shellcheck source=/usr/lib/libretools/messages.sh
|
# shellcheck source=/usr/lib/libretools/messages.sh
|
||||||
. "$(librelib messages)"
|
source "$(librelib messages)"
|
||||||
|
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
print "usage: %s [-h] IMG [ARG]..." "${0##*/}"
|
print "USAGE: %s [-h] <img> [qemu-args ...]" "${0##*/}"
|
||||||
prose "Determine the architecture of IMG and boot it using qemu. IMG is assumed
|
prose "Determine the architecture of <img> and boot it using qemu. <img> is assumed
|
||||||
to be a valid, raw-formatted parabola virtual machine image, ideally
|
to be a valid, raw-formatted parabola virtual machine image, ideally
|
||||||
created using pvmbootstrap. The started instances are assigned 1GiB of
|
created using pvmbootstrap. The started instance is assigned 1G of
|
||||||
RAM and one SMP core."
|
RAM and one SMP core."
|
||||||
echo
|
echo
|
||||||
prose "When a graphical desktop environment is available, start the machine
|
prose "When a graphical desktop environment is available, start the machine
|
||||||
normally, otherwise append -nographic to the qemu options. This behavior
|
normally, otherwise append -nographic to the qemu options. This behavior
|
||||||
can be forced by unsetting DISPLAY manually, for example through:"
|
can be forced by unsetting DISPLAY manually, for example through:"
|
||||||
echo
|
echo
|
||||||
echo " DISPLAY= ${0##*/} IMG ..."
|
echo " DISPLAY= ${0##*/} ./an.img"
|
||||||
echo
|
echo
|
||||||
prose "When the architecture of IMG is compatible with the host architecture,
|
prose "When the architecture of <img> is compatible with the host architecture,
|
||||||
append -enable-kvm to the qemu arguments."
|
append -enable-kvm to the qemu arguments."
|
||||||
echo
|
echo
|
||||||
prose "Further arguments provided after IMG will be passed unmodified to the
|
prose "Further arguments provided after <img> will be passed unmodified to the
|
||||||
qemu invocation. This can be used to allocate more resources to the virtual
|
qemu invocation. This can be used to allocate more resources to the virtual
|
||||||
machine, for example:"
|
machine, for example:"
|
||||||
echo
|
echo
|
||||||
echo " ${0##*/} IMG -m 2G -smp 2"
|
echo " ${0##*/} ./an.img -m 2G -smp 2"
|
||||||
echo
|
echo
|
||||||
echo "Supported options:"
|
echo "Supported options:"
|
||||||
echo " -h Display this help and exit"
|
echo " -h Display this help and exit"
|
||||||
@ -124,38 +125,36 @@ pvm_guess_qemu_args() {
|
|||||||
# if we're running a supported arch, enable kvm
|
# if we're running a supported arch, enable kvm
|
||||||
if pvm_native_arch "$2"; then qemu_args+=(-enable-kvm); fi
|
if pvm_native_arch "$2"; then qemu_args+=(-enable-kvm); fi
|
||||||
|
|
||||||
# otherwise, decide by target arch
|
# set arch-specific args
|
||||||
|
local kernel_console
|
||||||
case "$2" in
|
case "$2" in
|
||||||
i386|x86_64|ppc64)
|
i386|x86_64|ppc64)
|
||||||
qemu_args+=(-m 2G "$1")
|
qemu_args+=(-m 1G -hda "$1")
|
||||||
# unmount the unneeded virtual drive early
|
# unmount the unneeded virtual drive early
|
||||||
pvm_umount ;;
|
pvm_umount ;;
|
||||||
arm)
|
arm)
|
||||||
qemu_args+=(
|
kernel_console="console=tty0 console=ttyAMA0 "
|
||||||
-machine virt
|
qemu_args+=(-machine virt
|
||||||
-m 2G
|
-m 1G
|
||||||
-kernel "$workdir"/vmlinuz-linux-libre
|
-kernel "$workdir"/vmlinuz-linux-libre
|
||||||
-initrd "$workdir"/initramfs-linux-libre.img
|
-initrd "$workdir"/initramfs-linux-libre.img
|
||||||
-append "console=tty0 console=ttyAMA0 rw root=/dev/vda3"
|
-append "${kernel_console}rw root=/dev/vda3"
|
||||||
-drive "if=none,file=$1,format=raw,id=hd"
|
-drive "if=none,file=$1,format=raw,id=hd"
|
||||||
-device "virtio-blk-device,drive=hd"
|
-device "virtio-blk-device,drive=hd"
|
||||||
-netdev "user,id=mynet"
|
-netdev "user,id=mynet"
|
||||||
-device "virtio-net-device,netdev=mynet") ;;
|
-device "virtio-net-device,netdev=mynet") ;;
|
||||||
riscv64)
|
riscv64)
|
||||||
qemu_args+=(
|
kernel_console=$( [ -z "$DISPLAY" ] && echo "console=ttyS0 " )
|
||||||
-machine virt
|
qemu_args+=(-machine virt
|
||||||
-m 2G
|
-m 1G
|
||||||
-kernel "$workdir"/bbl
|
-kernel "$workdir"/bbl
|
||||||
-append "rw root=/dev/vda"
|
-append "${kernel_console}rw root=/dev/vda"
|
||||||
-drive "file=${loopdev}p3,format=raw,id=hd0"
|
-drive "file=${loopdev}p3,format=raw,id=hd0"
|
||||||
-device "virtio-blk-device,drive=hd0"
|
-device "virtio-blk-device,drive=hd0"
|
||||||
-object "rng-random,filename=/dev/urandom,id=rng0"
|
-object "rng-random,filename=/dev/urandom,id=rng0"
|
||||||
-device "virtio-rng-device,rng=rng0"
|
-device "virtio-rng-device,rng=rng0"
|
||||||
-device "virtio-net-device,netdev=usernet"
|
-netdev "user,id=usernet"
|
||||||
-netdev "user,id=usernet")
|
-device "virtio-net-device,netdev=usernet") ;;
|
||||||
if [ -z "$DISPLAY" ]; then
|
|
||||||
qemu_args+=(-append "console=ttyS0 rw root=/dev/vda");
|
|
||||||
fi ;;
|
|
||||||
*)
|
*)
|
||||||
error "%s: unable to determine default qemu args" "$1"
|
error "%s: unable to determine default qemu args" "$1"
|
||||||
return "$EXIT_FAILURE" ;;
|
return "$EXIT_FAILURE" ;;
|
||||||
@ -177,15 +176,9 @@ main() {
|
|||||||
done
|
done
|
||||||
local shiftlen=$(( OPTIND - 1 ))
|
local shiftlen=$(( OPTIND - 1 ))
|
||||||
shift $shiftlen
|
shift $shiftlen
|
||||||
if [ "$#" -lt 1 ]; then usage >&2; exit "$EXIT_INVALIDARGUMENT"; fi
|
|
||||||
|
|
||||||
local imagefile="$1"
|
local imagefile="$1"
|
||||||
shift
|
shift
|
||||||
|
[ ! -e "$imagefile" ] && error "%s: file not found" "$imagefile" && exit "$EXIT_FAILURE"
|
||||||
if [ ! -e "$imagefile" ]; then
|
|
||||||
error "%s: file not found" "$imagefile"
|
|
||||||
exit "$EXIT_FAILURE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
local workdir loopdev
|
local workdir loopdev
|
||||||
pvm_mount "$imagefile" || exit
|
pvm_mount "$imagefile" || exit
|
||||||
|
@ -18,44 +18,52 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
# shellcheck source=/usr/lib/libretools/messages.sh
|
# shellcheck source=/usr/lib/libretools/messages.sh
|
||||||
. "$(librelib messages)"
|
source "$(librelib messages)"
|
||||||
|
|
||||||
|
|
||||||
|
readonly DEF_MIRROR="https://repo.parabola.nu/\$repo/os/\$arch"
|
||||||
|
readonly DEF_IMG_GB=64
|
||||||
|
|
||||||
|
Hooks=()
|
||||||
|
Mirror=$DEF_MIRROR
|
||||||
|
ImgSizeGb=$DEF_IMG_GB
|
||||||
|
Init=''
|
||||||
|
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
print "usage: %s [-hO] [-s SIZE] [-M MIRROR] [-H HOOK]... IMG ARCH" "${0##*/}"
|
print "USAGE:"
|
||||||
|
print " pvmbootstrap [-h] [-H <hook>] [-M <mirror>] [-O] [-s <img_size>] <img> <arch>"
|
||||||
|
echo
|
||||||
prose "Produce preconfigured parabola GNU/Linux-libre virtual machine instances."
|
prose "Produce preconfigured parabola GNU/Linux-libre virtual machine instances."
|
||||||
echo
|
echo
|
||||||
prose "The produced image file is written to IMG, and is configured and
|
prose "The produced image file is written to <img>, and is configured and
|
||||||
bootstrapped for the achitecture specified in ARCH. ARCH can ether be
|
bootstrapped for the achitecture specified in <arch>. <arch> can be any
|
||||||
one of the officially supported architectures x86_64, i686 or armv7h,
|
one of the supported architectures: 'x86_64', 'i686' or 'armv7h',
|
||||||
or one of the unofficial arches ppc64le and riscv64 (refer to -M for
|
or one of the experimental arches: 'ppc64le' or 'riscv64'."
|
||||||
custom package mirrors)"
|
|
||||||
echo
|
echo
|
||||||
echo "Supported options:"
|
echo "Supported options:"
|
||||||
echo " -O bootstrap an openrc system instead of a systemd one"
|
echo " -h Display this help and exit"
|
||||||
echo " -s SIZE Set the size of the VM image (default: 64GiB)"
|
echo " -H <hook> Enable a hook to customize the created image. This can be"
|
||||||
echo " -M MIRROR Choose a different mirror to pacstrap from"
|
echo " the path to a script, which will be executed once within"
|
||||||
echo " default: <https://repo.parabola.nu/\$repo/os/\$arch>"
|
echo " the running VM, or one of the pre-defined hooks described"
|
||||||
echo " -H HOOK Enable a hook to customize the created image. This can be"
|
echo " below. This option can be specified multiple times."
|
||||||
echo " the path to a script, which will be executed once within"
|
echo " -M <mirror> Specify a different mirror from which to fetch packages"
|
||||||
echo " the running VM, or one of the predefined hooks described"
|
echo " (default: $DEF_MIRROR)"
|
||||||
echo " below. This option can be specified multiple times."
|
echo " -O Bootstrap an openrc system instead of a systemd one"
|
||||||
echo " -h Display this help and exit"
|
echo " -s <img_size> Set the size (in GB) of the VM image (default: $DEF_IMG_GB)"
|
||||||
echo
|
echo
|
||||||
echo "Predefined 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, dhcp and systemd-networkd"
|
echo " machine, using openresolv, dhcpcd, and systemd-networkd"
|
||||||
echo
|
echo
|
||||||
echo "This script is part of parabola-vmbootstrap. source code available at:"
|
echo "This script is part of parabola-vmbootstrap. source code available at:"
|
||||||
echo " <https://git.parabola.nu/~oaken-source/parabola-vmbootstrap.git>"
|
echo " <https://git.parabola.nu/~oaken-source/parabola-vmbootstrap.git>"
|
||||||
}
|
}
|
||||||
|
|
||||||
pvm_native_arch() {
|
pvm_native_arch() {
|
||||||
local arch
|
local arch=$( [[ "$1" =~ arm.* ]] && echo 'armv7l' || echo "$1" )
|
||||||
case "$1" in
|
|
||||||
arm*) arch=armv7l;;
|
|
||||||
*) arch="$1";;
|
|
||||||
esac
|
|
||||||
|
|
||||||
setarch "$arch" /bin/true 2>/dev/null || return
|
setarch "$arch" /bin/true 2>/dev/null || return
|
||||||
}
|
}
|
||||||
@ -64,17 +72,15 @@ pvm_bootstrap() {
|
|||||||
msg "%s: starting image creation for %s" "$file" "$arch"
|
msg "%s: starting image creation for %s" "$file" "$arch"
|
||||||
|
|
||||||
# create the raw image file
|
# create the raw image file
|
||||||
qemu-img create -f raw "$file" "$size" || return
|
qemu-img create -f raw "$file" "${ImgSizeGb}G" || return
|
||||||
|
|
||||||
# prepare for cleanup
|
# prepare for cleanup
|
||||||
trap 'pvm_cleanup' INT TERM RETURN
|
trap 'pvm_cleanup' INT TERM RETURN
|
||||||
|
|
||||||
# mount the virtual disk
|
# mount the virtual disk
|
||||||
local workdir loopdev
|
local workdir loopdev
|
||||||
workdir="$(mktemp -d -t pvm-rootfs-XXXXXXXXXX)" || return
|
workdir="$(mktemp -d -t pvm-rootfs-XXXXXXXXXX)" || return
|
||||||
loopdev="$(sudo losetup -fLP --show "$file")" || return
|
loopdev="$(sudo losetup -fLP --show "$file")" || return
|
||||||
|
|
||||||
# clean out the first 8MiB
|
|
||||||
sudo dd if=/dev/zero of="$loopdev" bs=1M count=8 || return
|
sudo dd if=/dev/zero of="$loopdev" bs=1M count=8 || return
|
||||||
|
|
||||||
# partition
|
# partition
|
||||||
@ -111,17 +117,17 @@ pvm_bootstrap() {
|
|||||||
case "$arch" in
|
case "$arch" in
|
||||||
i686|x86_64)
|
i686|x86_64)
|
||||||
sudo mkfs.ext2 "$loopdev"p2 || return
|
sudo mkfs.ext2 "$loopdev"p2 || return
|
||||||
sudo mkswap "$loopdev"p3 || return
|
sudo mkswap "$loopdev"p3 || return
|
||||||
sudo mkfs.ext4 "$loopdev"p4 || return
|
sudo mkfs.ext4 "$loopdev"p4 || return
|
||||||
swapdev="$loopdev"p3 ;;
|
swapdev="$loopdev"p3 ;;
|
||||||
armv7h)
|
armv7h)
|
||||||
sudo mkfs.vfat -F 32 "$loopdev"p1 || return
|
sudo mkfs.vfat -F 32 "$loopdev"p1 || return
|
||||||
sudo mkswap "$loopdev"p2 || return
|
sudo mkswap "$loopdev"p2 || return
|
||||||
sudo mkfs.ext4 "$loopdev"p3 || return
|
sudo mkfs.ext4 "$loopdev"p3 || return
|
||||||
swapdev="$loopdev"p2 ;;
|
swapdev="$loopdev"p2 ;;
|
||||||
ppc64le|riscv64)
|
ppc64le|riscv64)
|
||||||
sudo mkfs.ext2 "$loopdev"p1 || return
|
sudo mkfs.ext2 "$loopdev"p1 || return
|
||||||
sudo mkswap "$loopdev"p2 || return
|
sudo mkswap "$loopdev"p2 || return
|
||||||
sudo mkfs.ext4 "$loopdev"p3 || return
|
sudo mkfs.ext4 "$loopdev"p3 || return
|
||||||
swapdev="$loopdev"p2 ;;
|
swapdev="$loopdev"p2 ;;
|
||||||
esac
|
esac
|
||||||
@ -129,13 +135,13 @@ pvm_bootstrap() {
|
|||||||
# mount partitions
|
# mount partitions
|
||||||
case "$arch" in
|
case "$arch" in
|
||||||
i686|x86_64)
|
i686|x86_64)
|
||||||
sudo mount "$loopdev"p4 "$workdir" || return
|
sudo mount "$loopdev"p4 "$workdir" || return
|
||||||
sudo mkdir -p "$workdir"/boot || return
|
sudo mkdir -p "$workdir"/boot || return
|
||||||
sudo mount "$loopdev"p2 "$workdir"/boot || return
|
sudo mount "$loopdev"p2 "$workdir"/boot || return
|
||||||
;;
|
;;
|
||||||
armv7h|ppc64le|riscv64)
|
armv7h|ppc64le|riscv64)
|
||||||
sudo mount "$loopdev"p3 "$workdir" || return
|
sudo mount "$loopdev"p3 "$workdir" || return
|
||||||
sudo mkdir -p "$workdir"/boot || return
|
sudo mkdir -p "$workdir"/boot || return
|
||||||
sudo mount "$loopdev"p1 "$workdir"/boot || return
|
sudo mount "$loopdev"p1 "$workdir"/boot || return
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@ -149,66 +155,56 @@ pvm_bootstrap() {
|
|||||||
*) qemu_arch="$arch" ;;
|
*) qemu_arch="$arch" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [[ -z $(sudo grep -l -F \
|
local qemu_user_static=$(sudo grep -l -F -e "interpreter /usr/bin/qemu-$qemu_arch-" \
|
||||||
-e "interpreter /usr/bin/qemu-$qemu_arch-" \
|
-r -- /proc/sys/fs/binfmt_misc 2>/dev/null | \
|
||||||
-r -- /proc/sys/fs/binfmt_misc 2>/dev/null \
|
xargs -r sudo grep -xF 'enabled' )
|
||||||
| xargs -r sudo grep -xF 'enabled') ]]
|
if [[ -z "$qemu_user_static" ]]; then
|
||||||
then
|
|
||||||
error "%s: missing qemu-user-static for %s" "$file" "$arch"
|
error "%s: missing qemu-user-static for %s" "$file" "$arch"
|
||||||
return "$EXIT_FAILURE"
|
return "$EXIT_FAILURE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sudo mkdir -p "$workdir"/usr/bin
|
sudo mkdir -p "$workdir"/usr/bin
|
||||||
sudo cp -v "/usr/bin/qemu-$qemu_arch-"* "$workdir"/usr/bin || return
|
sudo cp -v "/usr/bin/qemu-$qemu_arch-"* "$workdir"/usr/bin || return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# prepare pacstrap config
|
# prepare pacstrap config
|
||||||
local pacconf
|
local pacconf repos
|
||||||
pacconf="$(mktemp -t pvm-pacconf-XXXXXXXXXX)" || return
|
pacconf="$(mktemp -t pvm-pacconf-XXXXXXXXXX)" || return
|
||||||
cat > "$pacconf" << EOF
|
repos=('libre' 'core' 'extra' 'community' 'pcr')
|
||||||
[options]
|
echo -e "[options]\nArchitecture = $arch\n\n" > "$pacconf"
|
||||||
Architecture = $arch
|
for repo in ${repos[@]}; do echo -e "[$repo]\nServer = $Mirror\n" >> "$pacconf"; done;
|
||||||
[libre]
|
|
||||||
Server = $mirror
|
|
||||||
[core]
|
|
||||||
Server = $mirror
|
|
||||||
[extra]
|
|
||||||
Server = $mirror
|
|
||||||
[community]
|
|
||||||
Server = $mirror
|
|
||||||
[pcr]
|
|
||||||
Server = $mirror
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# prepare lists of packages
|
# prepare lists of packages
|
||||||
local pkg=("base$init" "openssh$init" openresolv ldns)
|
# FIXME: [nonsystemd] is in a transitional phase
|
||||||
|
# package name suffices such as '-opernrc' will be removed soon
|
||||||
|
# ideally, the install process will be identical for either systemd or openrc
|
||||||
|
# depending only on which repos are enabled
|
||||||
|
local pkgs=("base$Init" "openssh$Init" openresolv ldns)
|
||||||
case "$arch" in
|
case "$arch" in
|
||||||
i686|x86_64) pkg+=(grub) ;;
|
i686|x86_64) pkgs+=(grub) ;;
|
||||||
esac
|
esac
|
||||||
case "$arch" in
|
case "$arch" in
|
||||||
riscv64) ;;
|
riscv64) ;;
|
||||||
*) pkg+=("haveged$init" net-tools) ;;
|
*) pkgs+=("haveged$Init" net-tools) ;;
|
||||||
esac
|
esac
|
||||||
|
if [[ ! $Init ]]; then
|
||||||
# Add back in base packages that the switch from base group
|
# FIXME: Add back in base packages that the switch from base group
|
||||||
# to base PKG yanked and be specific on OpenRC to avoid conflicts
|
# to base PKG yanked and be specific on OpenRC to avoid conflicts
|
||||||
if [[ ! $init ]]; then
|
# ideally, we will assign these to a new 'base-extras' group
|
||||||
|
pkgs+=(cryptsetup device-mapper dhcpcd e2fsprogs inetutils \
|
||||||
pkg+=(cryptsetup device-mapper dhcpcd e2fsprogs inetutils \
|
jfsutils linux-libre logrotate lvm2 man-db mdadm nano \
|
||||||
jfsutils linux-libre logrotate lvm2 man-db mdadm nano \
|
netctl pacman-mirrorlist perl reiserfsprogs s-nail sysfsutils \
|
||||||
netctl pacman-mirrorlist perl reiserfsprogs s-nail sysfsutils \
|
texinfo usbutils vi xfsprogs your-freedom systemd-udev \
|
||||||
texinfo usbutils vi xfsprogs your-freedom systemd-udev \
|
systemd-libudev )
|
||||||
systemd-libudev)
|
|
||||||
else
|
else
|
||||||
pkg+=(systemd-libs-dummy)
|
pkgs+=(systemd-libs-dummy)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local pkg_guest_cache=(ca-certificates-utils)
|
local pkg_guest_cache=(ca-certificates-utils)
|
||||||
|
|
||||||
# pacstrap! :)
|
# pacstrap! :)
|
||||||
sudo pacstrap -GMc -C "$pacconf" "$workdir" "${pkg[@]}" || return
|
sudo pacstrap -GMc -C "$pacconf" "$workdir" "${pkgs[@]}" || return
|
||||||
sudo pacstrap -GM -C "$pacconf" "$workdir" "${pkg_guest_cache[@]}" || return
|
sudo pacstrap -GM -C "$pacconf" "$workdir" "${pkg_guest_cache[@]}" || return
|
||||||
|
|
||||||
# create an fstab
|
# create an fstab
|
||||||
case "$arch" in
|
case "$arch" in
|
||||||
@ -231,35 +227,35 @@ EOF
|
|||||||
# install a boot loader
|
# install a boot loader
|
||||||
case "$arch" in
|
case "$arch" in
|
||||||
i686|x86_64)
|
i686|x86_64)
|
||||||
|
local grub_def_file="$workdir"/etc/default/grub
|
||||||
|
local grub_cfg_file=/boot/grub/grub.cfg
|
||||||
# enable serial console
|
# enable serial console
|
||||||
local field=GRUB_CMDLINE_LINUX_DEFAULT
|
local field=GRUB_CMDLINE_LINUX_DEFAULT
|
||||||
local value="console=tty0 console=ttyS0"
|
local value="console=tty0 console=ttyS0"
|
||||||
sudo sed -i "s/.*$field=.*/$field=\"$value\"/" \
|
sudo sed -i "s/.*$field=.*/$field=\"$value\"/" "$grub_def_file" || return
|
||||||
"$workdir"/etc/default/grub || return
|
|
||||||
# disable boot menu timeout
|
# disable boot menu timeout
|
||||||
local field=GRUB_TIMEOUT
|
local field=GRUB_TIMEOUT
|
||||||
local value=0
|
local value=0
|
||||||
sudo sed -i "s/.*$field=.*/$field=$value/" \
|
sudo sed -i "s/.*$field=.*/$field=$value/" "$grub_def_file" || return
|
||||||
"$workdir"/etc/default/grub || return
|
|
||||||
# install grub to the VM
|
# install grub to the VM
|
||||||
sudo arch-chroot "$workdir" grub-install --target=i386-pc "$loopdev" || return
|
sudo arch-chroot "$workdir" grub-install "$loopdev" || return
|
||||||
sudo arch-chroot "$workdir" grub-mkconfig -o /boot/grub/grub.cfg || return
|
sudo arch-chroot "$workdir" grub-mkconfig -o $grub_cfg_file || return
|
||||||
;;
|
;;
|
||||||
riscv64)
|
riscv64)
|
||||||
# FIXME: for the time being, use fedora bbl to boot
|
# FIXME: for the time being, use fedora bbl to boot
|
||||||
sudo wget https://fedorapeople.org/groups/risc-v/disk-images/bbl \
|
local bbl_url=https://fedorapeople.org/groups/risc-v/disk-images/bbl
|
||||||
-O "$workdir"/boot/bbl || return
|
sudo wget $bbl_url -O "$workdir"/boot/bbl || return
|
||||||
;;
|
;;
|
||||||
# armv7h has no boot loader.
|
# armv7h has no boot loader.
|
||||||
# FIXME: what about ppc64le
|
# FIXME: what about ppc64le
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# regenerate the initcpio, skipping the autodetect hook
|
# regenerate the initcpio, skipping the autodetect hook
|
||||||
sudo cp "$workdir"/etc/mkinitcpio.d/linux-libre.preset{,.backup} || return
|
local preset_file="$workdir"/etc/mkinitcpio.d/linux-libre.preset
|
||||||
echo "default_options=\"-S autodetect\"" \
|
sudo cp "$preset_file"{,.backup} || return
|
||||||
| sudo tee -a "$workdir"/etc/mkinitcpio.d/linux-libre.preset || return
|
echo "default_options=\"-S autodetect\"" | sudo tee -a "$preset_file" || return
|
||||||
sudo arch-chroot "$workdir" mkinitcpio -p linux-libre || return
|
sudo arch-chroot "$workdir" mkinitcpio -p linux-libre || return
|
||||||
sudo mv "$workdir"/etc/mkinitcpio.d/linux-libre.preset{.backup,} || return
|
sudo mv "$preset_file"{.backup,} || return
|
||||||
|
|
||||||
# disable audit
|
# disable audit
|
||||||
sudo arch-chroot "$workdir" systemctl mask systemd-journald-audit.socket
|
sudo arch-chroot "$workdir" systemctl mask systemd-journald-audit.socket
|
||||||
@ -273,7 +269,7 @@ EOF
|
|||||||
|
|
||||||
# push hooks into the image
|
# push hooks into the image
|
||||||
sudo mkdir -p "$workdir/root/hooks"
|
sudo mkdir -p "$workdir/root/hooks"
|
||||||
[ "${#hooks[@]}" -eq 0 ] || sudo cp -v "${hooks[@]}" "$workdir"/root/hooks/
|
[ "${#Hooks[@]}" -eq 0 ] || sudo cp -v "${Hooks[@]}" "$workdir"/root/hooks/
|
||||||
|
|
||||||
# create a master hook script
|
# create a master hook script
|
||||||
sudo tee "$workdir"/root/hooks.sh << 'EOF'
|
sudo tee "$workdir"/root/hooks.sh << 'EOF'
|
||||||
@ -292,7 +288,7 @@ pacman -U --noconfirm /var/cache/pacman/pkg/ca-certificates-utils-*.pkg.tar.xz
|
|||||||
# run the hooks
|
# run the hooks
|
||||||
for hook in /root/hooks/*; do
|
for hook in /root/hooks/*; do
|
||||||
echo "running hook \"$hook\""
|
echo "running hook \"$hook\""
|
||||||
. "$hook" || return
|
source "$hook" || return
|
||||||
done
|
done
|
||||||
|
|
||||||
# clean up after yourself
|
# clean up after yourself
|
||||||
@ -329,28 +325,26 @@ EOF
|
|||||||
# unmount everything
|
# unmount everything
|
||||||
pvm_cleanup
|
pvm_cleanup
|
||||||
|
|
||||||
# boot the machine, and run the preinit scripts
|
# boot the machine to run the preinit hooks
|
||||||
|
local pvmboot_cmd
|
||||||
local qemu_flags=(-no-reboot)
|
local qemu_flags=(-no-reboot)
|
||||||
local pvmboot
|
|
||||||
if [ -f "./src/pvmboot.sh" ]; then
|
if [ -f "./src/pvmboot.sh" ]; then
|
||||||
pvmboot=(bash ./src/pvmboot.sh)
|
pvmboot_cmd=(bash ./src/pvmboot.sh)
|
||||||
elif type -p pvmboot &>/dev/null; then
|
elif type -p pvmboot &>/dev/null; then
|
||||||
pvmboot=(pvmboot)
|
pvmboot_cmd=('pvmboot')
|
||||||
else
|
else
|
||||||
error "%s: pvmboot not available -- unable to run hooks" "$file"
|
error "%s: pvmboot not available -- unable to run hooks" "$file"
|
||||||
return "$EXIT_FAILURE"
|
return "$EXIT_FAILURE"
|
||||||
fi
|
fi
|
||||||
|
pvmboot_cmd+=("$file" "${qemu_flags[@]}")
|
||||||
exec 3>&1
|
exec 3>&1
|
||||||
DISPLAY='' "${pvmboot[@]}" "$file" "${qemu_flags[@]}" \
|
msg "booting the machine to run the pre-init hooks"
|
||||||
| tee /dev/fd/3 | grep -q "preinit hooks successful"
|
DISPLAY='' "${pvmboot_cmd[@]}" | tee /dev/fd/3 | grep -q "preinit hooks successful"
|
||||||
local res=$?
|
local res=$?
|
||||||
exec 3>&-
|
exec 3>&-
|
||||||
|
! (( $res )) || error "%s: failed to complete preinit hooks" "$file"
|
||||||
|
|
||||||
if [ "$res" -ne 0 ]; then
|
return $res
|
||||||
error "%s: failed to complete preinit hooks" "$file"
|
|
||||||
return "$res"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pvm_cleanup() {
|
pvm_cleanup() {
|
||||||
@ -360,7 +354,7 @@ pvm_cleanup() {
|
|||||||
unset 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-*
|
||||||
sudo umount -R "$workdir"
|
sudo umount -R "$workdir" 2> /dev/null
|
||||||
rmdir "$workdir"
|
rmdir "$workdir"
|
||||||
fi
|
fi
|
||||||
unset workdir
|
unset workdir
|
||||||
@ -374,34 +368,29 @@ main() {
|
|||||||
exit "$EXIT_NOPERMISSION"
|
exit "$EXIT_NOPERMISSION"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local size="64G"
|
|
||||||
local mirror="https://repo.parabola.nu/\$repo/os/\$arch"
|
|
||||||
local hooks=()
|
|
||||||
local init
|
|
||||||
|
|
||||||
# parse options
|
# parse options
|
||||||
while getopts 'hOs:M:H:' arg; do
|
while getopts 'hOs:M:H:' arg; do
|
||||||
case "$arg" in
|
case "$arg" in
|
||||||
O) init="-openrc";;
|
|
||||||
h) usage; return "$EXIT_SUCCESS";;
|
h) usage; return "$EXIT_SUCCESS";;
|
||||||
s) size="$OPTARG";;
|
|
||||||
M) mirror="$OPTARG";;
|
|
||||||
H) if [ -e "/usr/lib/libretools/pvmbootstrap/hook-$OPTARG.sh" ]; then
|
H) if [ -e "/usr/lib/libretools/pvmbootstrap/hook-$OPTARG.sh" ]; then
|
||||||
hooks+=("/usr/lib/libretools/pvmbootstrap/hook-$OPTARG.sh")
|
hooks+=("/usr/lib/libretools/pvmbootstrap/hook-$OPTARG.sh")
|
||||||
elif [ -e "./src/hooks/hook-$OPTARG.sh" ]; then
|
elif [ -e "./src/hooks/hook-$OPTARG.sh" ]; then
|
||||||
hooks+=("./src/hooks/hook-$OPTARG.sh")
|
hooks+=("./src/hooks/hook-$OPTARG.sh")
|
||||||
elif [ -e "$OPTARG" ]; then
|
elif [ -e "$OPTARG" ]; then
|
||||||
hooks+=("$OPTARG")
|
Hooks+=("$OPTARG")
|
||||||
else
|
else
|
||||||
warning "%s: hook does not exist" "$OPTARG"
|
warning "%s: hook does not exist" "$OPTARG"
|
||||||
fi ;;
|
fi ;;
|
||||||
|
M) Mirror="$OPTARG";;
|
||||||
|
O) Init="-openrc";;
|
||||||
|
s) ImgSizeGb="$(sed 's|[^0-9]||g' <<<$OPTARG)";;
|
||||||
*) usage >&2; exit "$EXIT_INVALIDARGUMENT";;
|
*) usage >&2; exit "$EXIT_INVALIDARGUMENT";;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
local shiftlen=$(( OPTIND - 1 ))
|
local shiftlen=$(( OPTIND - 1 ))
|
||||||
shift $shiftlen
|
shift $shiftlen
|
||||||
if [ "$#" -ne 2 ]; then usage >&2; exit "$EXIT_INVALIDARGUMENT"; fi
|
if [ "$#" -ne 2 ]; then usage >&2; exit "$EXIT_INVALIDARGUMENT"; fi
|
||||||
|
|
||||||
local file="$1"
|
local file="$1"
|
||||||
local arch="$2"
|
local arch="$2"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user