89e3affa22
Among other things this commit refactors mknet.sh to use the lib.sh functions for executing code in the chroot and generally handling the potential for future builds to generate netboot tarballs for ARM platforms. ARM tarballs will require syslinux to be built for the target architecture, but it should largely just be a drop in option.
225 lines
9.4 KiB
Bash
225 lines
9.4 KiB
Bash
#!/bin/sh
|
|
#
|
|
# vim: set ts=4 sw=4 et:
|
|
#
|
|
#-
|
|
# Copyright (c) 2009-2015 Juan Romero Pardines.
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
#-
|
|
|
|
readonly PROGNAME=$(basename "$0")
|
|
readonly REQTOOLS="xbps-install tar"
|
|
|
|
# This script needs to jump around, so we'll remember where we started
|
|
# so that we can get back here
|
|
readonly CURDIR="$(pwd)"
|
|
|
|
# This source pulls in all the functions from lib.sh. This set of
|
|
# functions makes it much easier to work with chroots and abstracts
|
|
# away all the problems with running binaries with QEMU.
|
|
# shellcheck source=./lib.sh
|
|
. ./lib.sh
|
|
|
|
# Die is a function provided in lib.sh which handles the cleanup of
|
|
# the mounts and removal of temporary directories if the running
|
|
# program exists unexpectedly.
|
|
trap 'die "An unchecked exception has occured!"' INT TERM
|
|
|
|
usage() {
|
|
cat <<_EOF
|
|
Usage: $PROGNAME [options] <rootfs>
|
|
|
|
Options:
|
|
-r <repo-url> Use this XBPS repository (may be specified multiple times).
|
|
-c <cachedir> Use this XBPS cache directory.
|
|
-i <lz4|gzip|bzip2|xz> Compression type for the initramfs image (lz4 if unset).
|
|
-o <file> Output file name for the netboot tarball (auto if unset).
|
|
|
|
-C "cmdline args" Add additional kernel command line arguments.
|
|
-T "title" Modify the bootloader title.
|
|
-S "splash image" Set a custom splash image for the bootloader
|
|
|
|
The $PROGNAME script generates a network-bootable tarball of Void Linux
|
|
_EOF
|
|
exit 1
|
|
}
|
|
|
|
# ########################################
|
|
# SCRIPT EXECUTION STARTS HERE
|
|
# ########################################
|
|
|
|
while getopts "r:c:C:T:i:o:h" opt; do
|
|
case $opt in
|
|
r) XBPS_REPOSITORY="--repository=$OPTARG $XBPS_REPOSITORY";;
|
|
c) XBPS_CACHEDIR="--cachedir=$OPTARG";;
|
|
i) INITRAMFS_COMPRESSION="$OPTARG";;
|
|
o) OUTPUT_FILE="$OPTARG";;
|
|
C) BOOT_CMDLINE="$OPTARG";;
|
|
T) BOOT_TITLE="$OPTARG";;
|
|
S) SPLASH_IMAGE="OPTARG";;
|
|
h) usage;;
|
|
esac
|
|
done
|
|
shift $((OPTIND - 1))
|
|
|
|
BASE_TARBALL="$1"
|
|
|
|
# We need to infer the target architecture from the filename. All
|
|
# other scripts are able to get this from the platforms map because a
|
|
# platform is manually specified. Since the netboot tarballs target
|
|
# only architectures, its necessary to pull this information from the
|
|
# filename.
|
|
XBPS_TARGET_ARCH=${BASE_TARBALL%%-ROOTFS*}
|
|
XBPS_TARGET_ARCH=${XBPS_TARGET_ARCH##void-}
|
|
|
|
# Knowing the target arch, we can set the cache up if it hasn't
|
|
# already been set
|
|
set_cachedir
|
|
|
|
# This is an aweful hack since the script isn't using privesc
|
|
# mechanisms selectively. This is a TODO item.
|
|
if [ "$(id -u)" -ne 0 ]; then
|
|
die "need root perms to continue, exiting."
|
|
fi
|
|
|
|
# Before going any further, check that the tools that are needed are
|
|
# present. If we delayed this we could check for the QEMU binary, but
|
|
# its a reasonable tradeoff to just bail out now.
|
|
check_tools
|
|
|
|
# We need to operate on a tempdir, if this fails to create, it is
|
|
# absolutely crucial to bail out so that we don't hose the system that
|
|
# is running the script.
|
|
ROOTFS=$(mktemp -d) || die "failed to create ROOTFS tempdir, exiting..."
|
|
BOOT_DIR=$(mktemp -d) || die "failed to create BOOT_DIR tempdir, exiting..."
|
|
PXELINUX_DIR="$BOOT_DIR/pxelinux.cfg"
|
|
|
|
# Now that we have a directory for the ROOTFS, we can expand the
|
|
# existing base filesystem into the directory
|
|
info_msg "Expanding base tarball $BASE_TARBALL into $ROOTFS for $PLATFORM build."
|
|
tar xf "$BASE_TARBALL" -C "$ROOTFS"
|
|
|
|
info_msg "Install additional dracut modules"
|
|
# This section sets up the dracut modules that need to be present on
|
|
# the ROOTFS to build the PXE tarball. This includes the netmenu
|
|
# module and the autoinstaller
|
|
mkdir -p "$ROOTFS/usr/lib/dracut/modules.d/05netmenu"
|
|
cp dracut/netmenu/* "$ROOTFS/usr/lib/dracut/modules.d/05netmenu/"
|
|
|
|
# The netmenu can directly launch the manual installer from the
|
|
# initrd. This is the same installer that's on the live media with
|
|
# all its quirks, oddities, and wierdness. It's included here for
|
|
# places where you might have a lab network and need to run manual
|
|
# installs from the network.
|
|
cp installer.sh "$ROOTFS/usr/lib/dracut/modules.d/05netmenu/"
|
|
|
|
# Of course with a PXE environment unattended installs are the norm.
|
|
# The autoinstaller is loaded as a very high priority dracut module
|
|
# and will fail the build if it can't be installed.
|
|
mkdir -p "$ROOTFS/usr/lib/dracut/modules.d/01autoinstaller"
|
|
cp dracut/autoinstaller/* "$ROOTFS/usr/lib/dracut/modules.d/01autoinstaller/"
|
|
|
|
info_msg "Install kernel and additional required netboot packages"
|
|
# The rootfs has no kernel in it, so it needs to have at the very
|
|
# least dracut, syslinux, and linux installed. binutils provides
|
|
# /usr/bin/strip which lets us shrink down the size of the initrd
|
|
# dracut-network provides the in-initrd network stack
|
|
# dialog is needed by the install environment
|
|
# ${INITRAMFS_COMPRESSION} is the name of the compressor we want to use (lz4 by default)
|
|
run_cmd_target "xbps-install $XBPS_CONFFILE $XBPS_CACHEDIR $XBPS_REPOSITORY -r $ROOTFS -Sy linux dracut syslinux binutils dracut-network dialog ${INITRAMFS_COMPRESSION-lz4}"
|
|
run_cmd_chroot "$ROOTFS" "xbps-reconfigure -a"
|
|
|
|
# Dracut needs to know the kernel version that will be using this
|
|
# initrd so that it can install the kernel drivers in it. Normally
|
|
# this check is quite complex, but since this is a clean rootfs and we
|
|
# just installed exactly one kernel, this check can get by with a
|
|
# really niave command to figure out the kernel version
|
|
KERNELVERSION=$(ls "$ROOTFS/usr/lib/modules/")
|
|
|
|
# Now that things are setup, we can call dracut and build the initrd.
|
|
# This will pretty much step through the normal process to build
|
|
# initrd with the exception that the autoinstaller and netmenu are
|
|
# force added since no module depends on them.
|
|
info_msg "Building initrd for kernel version $KERNELVERSION"
|
|
run_cmd_chroot "$ROOTFS" "env -i /usr/bin/dracut \
|
|
-N \
|
|
--${INITRAMFS_COMPRESSION-lz4} \
|
|
--add-drivers ahci \
|
|
--force-add 'autoinstaller netmenu' \
|
|
--omit systemd \
|
|
/boot/initrd \
|
|
$KERNELVERSION"
|
|
[ $? -ne 0 ] && die "Failed to generate the initramfs"
|
|
|
|
info_msg "Collect netboot components"
|
|
# The whole point of this endeavor is to get the files needed for PXE.
|
|
# Now that they have been generated, we copy them out of the doomed
|
|
# ROOTFS and into the $BOOT_DIR where we're staging the rest of the
|
|
# tarball
|
|
mv -v "$ROOTFS/boot/initrd" "$BOOT_DIR"
|
|
cp -v "$ROOTFS/boot/vmlinuz-$KERNELVERSION" "$BOOT_DIR/vmlinuz"
|
|
|
|
# The initrd has *very* restrictive permissions by default. To
|
|
# prevent some SysAdmin down the road having a very frustrating time
|
|
# debugging this, we just fix this here and now.
|
|
chmod 0644 "$BOOT_DIR/initrd"
|
|
|
|
# Now we need to grab the rest of the files that go in the tarball.
|
|
# Some of these are always required, some of these are canonical, and
|
|
# some of this list is from trial and error. Either way, this is the
|
|
# minimum needed to get Void up and booting on metal from the network.
|
|
for prog in pxelinux.0 ldlinux.c32 libcom32.c32 vesamenu.c32 libutil.c32 chain.c32 ; do
|
|
cp -v "$ROOTFS/usr/share/syslinux/$prog" "$BOOT_DIR"
|
|
done
|
|
|
|
# Lastly we need the default pxelinux config and the splash image.
|
|
# This is user configurable, but if that isn't set then we'll use the
|
|
# one from data/splash.png instead
|
|
mkdir -p "$PXELINUX_DIR"
|
|
cp -f pxelinux.cfg/pxelinux.cfg.in "$PXELINUX_DIR/default"
|
|
cp -f "${SPLASH_IMAGE-data/splash.png}" "$BOOT_DIR"
|
|
|
|
# This sets all the variables in the default config file
|
|
info_msg "Configuring pxelinux.0 default boot menu"
|
|
sed -i -e "s|@@SPLASHIMAGE@@|$(basename "${SPLASH_IMAGE}")|" \
|
|
-e "s|@@KERNVER@@|${KERNELVERSION}|" \
|
|
-e "s|@@KEYMAP@@|${KEYMAP}|" \
|
|
-e "s|@@ARCH@@|$BASE_ARCH|" \
|
|
-e "s|@@LOCALE@@|${LOCALE}|" \
|
|
-e "s|@@BOOT_TITLE@@|${BOOT_TITLE}|" \
|
|
-e "s|@@BOOT_CMDLINE@@|${BOOT_CMDLINE}|" \
|
|
"$PXELINUX_DIR/default"
|
|
|
|
# Default output file format
|
|
OUTPUT_FILE="void-netboot-${XBPS_TARGET_ARCH}-${KERNELVERSION}-$(date +%Y%m%d)"
|
|
info_msg "Compressing results to $OUTPUT_FILE.tar.gz"
|
|
cd "$BOOT_DIR" || die "Could not enter image dir"
|
|
tar -zcvf "$CURDIR/$OUTPUT_FILE.tar.gz" .
|
|
cd "$CURDIR" || die "Could not return to working directory"
|
|
|
|
# As a final cleanup step, remove the ROOTFS and the expanded BOOT_DIR
|
|
info_msg "Cleaning up and removing build directories"
|
|
cleanup_chroot
|
|
[ -d "$ROOTFS" ] && rm -rf "$ROOTFS"
|
|
[ -d "$BOOT_DIR" ] && rm -rf "$BOOT_DIR"
|