updated helps and README, added pvm2tarball.sh

This commit is contained in:
Andreas Grapentin 2019-03-18 21:07:36 +01:00
parent c7eb38694f
commit bc0fc70388
No known key found for this signature in database
GPG Key ID: 7171986E4B745536
5 changed files with 250 additions and 40 deletions

14
README

@ -35,8 +35,8 @@ The creation hooks currently supported are:
ethernet-dhcp: ethernet-dhcp:
this hook will setup ethernet in the VM by enabling systemd-resolved and this hook will setup ethernet in the VM by enabling systemd-resolved and
symlinking /etc/resolv.conf properly, as well as creating and enabling a openresolv properly, as well as creating and enabling a systemd-networkd
netctl configuration based on the ethernet-dhcp example. configuration.
virtual machine boot virtual machine boot
-------------------- --------------------
@ -62,3 +62,13 @@ memory to the machine, by specifying additional qemu parameters on the command
line following the virtual machine image name: line following the virtual machine image name:
$> DISPLAY= ./pvmboot [path to image] -m 2G $> DISPLAY= ./pvmboot [path to image] -m 2G
release tarball creation
------------------------
To convert a virtual machine image into a parabola release tarball, run:
$> ./pvm2tarball.sh [path to image]
This will attempt to mount the rootfs and the /boot partition, and tar the
contents to an output file, filtering out all unneeded files.

@ -2,16 +2,19 @@
set -e set -e
# setup systemd-resolved
systemctl start systemd-resolved.service || return
systemctl enable systemd-resolved.service
ln -sf /var/run/systemd/resolve/resolv.conf /etc/resolv.conf
# determine first ethernet device # determine first ethernet device
eth="$(basename "$(find /sys/class/net/ -mindepth 1 -maxdepth 1 -iname 'e*' | head -n1)")" eth="$(basename "$(find /sys/class/net/ -mindepth 1 -maxdepth 1 -iname 'e*' | head -n1)")"
[ -n "$eth" ] || eth="eth0" [ -n "$eth" ] || eth="eth0"
# setup netctl for ethernet-dhcp # create a network configuration
sed "s/eth0/$eth/" /etc/netctl/examples/ethernet-dhcp > /etc/netctl/ethernet-dhcp cat > /etc/systemd/network/$eth.network << EOF
netctl start ethernet-dhcp || return [Match]
netctl enable ethernet-dhcp Name=$eth
[Network]
DHCP=yes
EOF
# enable said network configuration
systemctl enable systemd-networkd.service
systemctl enable systemd-resolved.service

165
src/pvm2tarball.sh Normal file

@ -0,0 +1,165 @@
#!/bin/bash
###############################################################################
# parabola-vmbootstrap -- create and start parabola virtual machines #
# #
# Copyright (C) 2017 - 2019 Andreas Grapentin #
# #
# 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/>. #
###############################################################################
# shellcheck source=/usr/lib/libretools/messages.sh
. "$(librelib messages)"
usage() {
print "usage: %s [-h] [-o FILE] IMG" "${0##*/}"
prose "Produce a parabola release tarball from IMG."
echo
prose "IMG is expected to be a valid parabola image, ideally freshly bootstrapped
using pvmbootstrap. If FILE is not specifed, generate an archive name
from IMG and place it in the current working directory"
echo
echo "Supported options:"
echo " -o FILE Write the generated tar archive to FILE instead of"
echo " generating a name for the archive from IMG"
echo " -h Display this help and exit"
echo
echo "This script is part of parabola-vmbootstrap. source code available at:"
echo " <https://git.parabola.nu/~oaken-source/parabola-vmbootstrap.git>"
}
pvm_mount() {
if ! file "$1" | grep -q ' DOS/MBR '; then
error "%s: does not seem to be a raw qemu image." "$1"
return "$EXIT_FAILURE"
fi
trap 'pvm_umount' INT TERM EXIT
workdir="$(mktemp -d -t pvm-XXXXXXXXXX)" || return
loopdev="$(sudo losetup -fLP --show "$1")" || return
# find the root partition
local part rootpart
for part in "$loopdev"p*; do
sudo mount "$part" "$workdir" || continue
if [ -f "$workdir"/etc/fstab ]; then
rootpart="$part"
break
fi
sudo umount "$workdir"
done
if [ -z "$rootpart" ]; then
error "%s: unable to determine root partition." "$1"
return "$EXIT_FAILURE"
fi
# find the boot partition
bootpart="$(findmnt -senF "$workdir"/etc/fstab /boot | awk '{print $2}')"
if [ -z "$bootpart" ]; then
error "%s: unable to determine boot partition." "$1"
return "$EXIT_FAILURE"
fi
# mount and be happy
sudo mount "$bootpart" "$workdir"/boot || return
}
pvm_umount() {
trap - INT TERM EXIT
[ -n "$workdir" ] && (sudo umount -R "$workdir"; rmdir "$workdir")
unset workdir
[ -n "$loopdev" ] && sudo losetup -d "$loopdev"
unset loopdev
}
main() {
if [ "$(id -u)" -eq 0 ]; then
error "This program must be run as a regular user"
exit "$EXIT_NOPERMISSION"
fi
# parse options
local output
while getopts 'ho:' arg; do
case "$arg" in
h) usage; return "$EXIT_SUCCESS";;
o) output="$OPTARG";;
*) usage >&2; exit "$EXIT_INVALIDARGUMENT";;
esac
done
local shiftlen=$(( OPTIND - 1 ))
shift $shiftlen
if [ "$#" -ne 1 ]; then usage >&2; exit "$EXIT_INVALIDARGUMENT"; fi
local imagebase imagefile="$1"
imagebase="$(basename "$imagefile")"
shift
# check for input file presence
if [ ! -e "$imagefile" ]; then
error "%s: file not found" "$imagefile"
exit "$EXIT_FAILURE"
fi
# determine output file
[ -n "$output" ] || output="${imagebase%.*}.tar.gz"
# check for output file presence
if [ -e "$output" ]; then
warning "%s: file exists. Continue? [y/N]" "$output"
read -p " " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit "$EXIT_FAILURE"
fi
rm -f "$output" || exit
fi
# mount the root filesystem
local workdir loopdev
pvm_mount "$imagefile" || exit
# tar the root filesystem, excluding unneeded things
sudo tar -c -f "$output" -C "$workdir" -X - . << EOF
./boot/lost+found
./etc/.updated
./etc/pacman.d/empty.conf
./etc/pacman.d/gnupg
./lost+found
./root/.bash_history
./var/.updated
./var/log/journal/*
./var/log/pacman.log
./var/log/tallylog
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
sudo chown "$(id -u)":"$(id -g)" "$output"
# cleanup
pvm_umount
}
main "$@"

@ -22,22 +22,32 @@
. "$(librelib messages)" . "$(librelib messages)"
usage() { usage() {
print "usage: %s [-h] filename [args...]" "${0##*/}" print "usage: %s [-h] IMG [ARG]..." "${0##*/}"
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
created using pvmbootstrap. The started instances are assigned 1GiB of
RAM and one SMP core."
echo echo
prose " this script is designed to smartly boot a parabola GNU/Linux-libre prose "When a graphical desktop environment is available, start the machine
virtual machine with qemu. It takes the path to a virtual machine image normally, otherwise append -nographic to the qemu options. This behavior
as parameter, and determines the architecture of that image. It sets can be forced by unsetting DISPLAY manually, for example through:"
default qemu parameters for the target architecture, and determines
whether kvm acceleration is available."
echo echo
prose " the script also determines whether a graphical desktop environment echo " DISPLAY= ${0##*/} IMG ..."
is available by evaluating the DISPLAY environment variable, and sets
default options accordingly."
echo echo
prose " the default qemu parameters can be overwritten and extended by adding prose "When the architecture of IMG is compatible with the host architecture,
custom arguments after the image file name." append -enable-kvm to the qemu arguments."
echo echo
echo "this script is developed as part of parabola-vmbootstrap." 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
machine, for example:"
echo
echo " ${0##*/} IMG -m 2G -smp 2"
echo
echo "Supported options:"
echo " -h Display this help and exit"
echo
echo "This script is part of parabola-vmbootstrap. source code available at:"
echo " <https://git.parabola.nu/~oaken-source/parabola-vmbootstrap.git>"
} }
pvm_mount() { pvm_mount() {

@ -22,26 +22,31 @@
. "$(librelib messages)" . "$(librelib messages)"
usage() { usage() {
print "usage: %s [-h] [-s size] [-M mirror] [-H hook...] filename arch" "${0##*/}" print "usage: %s [-h] [-s SIZE] [-M MIRROR] [-H HOOK]... IMG ARCH" "${0##*/}"
prose "Produce preconfigured parabola GNU/Linux-libre virtual machine instances."
echo echo
prose " this script produces preconfigured parabola GNU/Linux-libre virtual prose "The produced image file is written to IMG, and is configured and
machine images, to be started using the accompanying pvmboot.sh bootstrapped for the achitecture specified in ARCH. ARCH can ether be
script. The created image is placed at the specified path." one of the officially supported architectures x86_64, i686 or armv7h,
or one of the unofficial arches ppc64le and riscv64 (refer to -M for
custom package mirrors)"
echo echo
prose " the target architecture of the virtual machine image can be one of the echo "Supported options:"
officially supported i686, x86_64 and armv7h, as well as one of the echo " -s SIZE Set the size of the VM image (default: 64GiB)"
unofficial ports for ppc64le and riscv64." echo " -M MIRROR Choose a different mirror to pacstrap from"
echo " default: <https://repo.parabola.nu/\$repo/os/\$arch>"
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 running VM, or one of the predefined hooks described"
echo " below. This option can be specified multiple times."
echo " -h Display this help and exit"
echo echo
prose " the creation of the virtual machine is configurable in three ways. First, echo "Predefined hooks:"
the size of the image can be configured with the -s switch, whose echo " ethernet-dhcp: configure and enable an ethernet device in the virtual"
value is passed verbatim to qemu-img create (default 64G). Second, echo " machine, using openresolv, dhcp and systemd-networkd"
the mirror to load packages from can be configured with the -M switch,
wich is necessary for the unofficial ports, whose packages are not on
the main mirrors. Lastly, the -H switch can be passed multiple times to
specify post-install hooks to be run in the virtual machine for
install finalization. See src/hooks/ for examples."
echo echo
echo "this script is developed as part of parabola-vmbootstrap." echo "This script is part of parabola-vmbootstrap. source code available at:"
echo " <https://git.parabola.nu/~oaken-source/parabola-vmbootstrap.git>"
} }
pvm_native_arch() { pvm_native_arch() {
@ -170,10 +175,12 @@ Server = $mirror
Server = $mirror Server = $mirror
[community] [community]
Server = $mirror Server = $mirror
[pcr]
Server = $mirror
EOF EOF
# prepare lists of packages # prepare lists of packages
local pkg=(base haveged) local pkg=(base haveged openssh openresolv ldns net-tools)
case "$arch" in case "$arch" in
i686|x86_64) pkg+=(grub) ;; i686|x86_64) pkg+=(grub) ;;
esac esac
@ -190,6 +197,13 @@ EOF
sudo swapoff "$swapdev" sudo swapoff "$swapdev"
sudo swapon --all sudo swapon --all
# produce a hostname
echo "parabola" | sudo tee "$workdir"/etc/hostname
# produce an /etc/locale.conf
echo "LANG=en_US.UTF-8" | sudo tee "$workdir"/etc/locale.conf
sudo sed -i 's/#en_US.UTF-8/en_US.UTF-8/' "$workdir"/etc/locale.gen
# install a boot loader # install a boot loader
case "$arch" in case "$arch" in
i686|x86_64) i686|x86_64)
@ -242,21 +256,29 @@ EOF
#!/bin/bash #!/bin/bash
systemctl disable preinit.service systemctl disable preinit.service
# generate the locale
locale-gen
# fix the mkinitcpio # fix the mkinitcpio
mkinitcpio -p linux-libre mkinitcpio -p linux-libre
# fix ca-certificates # fix ca-certificates
pacman -U --noconfirm /var/cache/pacman/pkg/ca-certificates-utils-*.pkg.tar.xz pacman -U --noconfirm /var/cache/pacman/pkg/ca-certificates-utils-*.pkg.tar.xz
# 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 . "$hook" || return
done done
# clean up after yourself
rm -rf /root/hooks rm -rf /root/hooks
rm -f /root/hooks.sh rm -f /root/hooks.sh
rm -f /usr/lib/systemd/system/preinit.service rm -f /usr/lib/systemd/system/preinit.service
rm -f /var/cache/pacman/pkg/*
rm -f /root/.bash_history
# report success :)
echo "preinit hooks successful" echo "preinit hooks successful"
EOF EOF