updated helps and README, added pvm2tarball.sh
This commit is contained in:
parent
c7eb38694f
commit
bc0fc70388
14
README
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
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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user