arkdep/arkanium-build
2023-08-14 06:53:30 +02:00

174 lines
5.8 KiB
Bash
Executable file

#!/usr/bin/env bash
# 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.
# Print manual if no parameters provided or invalid amount of parameters is provided
if [[ ! -n $1 || -n $2 ]]; then
cat <<- END
Usage: arkanium-build [variant]
Variants:
archlinux Plain Arch Linux TTY image
arkanelinux Arkane Linux GNOME image
debian Plain Debian TTY image
Variants are loaded based on their directory names, the ones listed here
are included by default. For information on the exact configuration of
these variants or to create your own see /etc/arkanium/variants.
END
exit 0
fi
## Set common variables
#
declare -r workdir='/var/tmp/rootfs'
declare -r configs_dir="./arkanium-build.d/"
declare -r variant="$1"
declare -r type="$(cat $(readlink -m $configs_dir/$variant/type))"
declare -r output_target="$(pwd)/target/"
## Common functions
#
# Cleanup and quit if error
cleanup_and_quit () {
# If any paramters are passed we will assume it to be an error
[[ -n $1 ]] && printf "\e[1;31m<#>\e[0m $*\e[0m\n" >&2
btrfs property set -ts $workdir ro false
btrfs property set -ts $workdir/etc ro false
btrfs property set -ts $workdir/var ro false
# Remove temporary btrfs volumes
rm -rf $workdir/etc \
$workdir/var \
$workdir
# Quit program if argument provided to function
[[ -n $1 ]] && exit 1
# Otherwise just quit, there is no error
exit 0
}
# Generate a 42 character long random string, used for generating psuedo-random
# image names
gen_random_string () {
random=$(openssl rand -hex 100 | head -c 42)
printf "${random}\n"
}
## Error checking
#
# Quit if not root
[[ ! $EUID -eq 0 ]] &&
printf '\e[1;31m<#>\e[0m\e[1m This program has to be run as root\n\e[0m' &&
exit 1
# Check if all dependencies are installed, quit if not
for prog in btrfs pacstrap; do
if ! command -v $prog > /dev/null; then
printf "\e[1;31m<#>\e[0m\e[1m Failed to locate $prog, ensure it is installed\e[0m\n"
exit 1
fi
done
# Check if requested variant exists
[[ ! -d arkanium-build.d/$variant ]] &&
printf '\e[1;31m<#>\e[0m\e[1m The requested variant does not exist\e[0m\n' &&
exit 1
## Variants
#
# Build archlinux type image
if [[ $type == 'archlinux' ]]; then
# Ensure base.list exists, if not error and quit
if [[ ! -e arkanium-build.d/$variant/base.list ]]; then
printf "\e[1;31m<#>\e[0m\e[1m The required file 'base.list' is not preset in $(readlink -m $configs_dir/$variant)\e[0m\n" &&
exit 1
fi
printf '\e[1;34m-->\e[0m\e[1m Started Arch linux image build\e[0m\n'
# Create temporary Btrfs subvolume
printf "\e[1;34m-->\e[0m\e[1m Creating temporary Btrfs subvolumes at $(readlink -m $workdir)\e[0m\n"
btrfs subvolume create $workdir || cleanup_and_quit "Failed to create btrfs subvolume $(readlink -m $workdir)"
btrfs subvolume create $workdir/etc || cleanup_and_quit "Failed to create btrfs subvolume $(readlink -m $workdir/etc)"
btrfs subvolume create $workdir/var || cleanup_and_quit "Failed to create btrfs subvolume $(readlink -m $workdir/var)"
# Read base package list and install base system
readarray base_packages < arkanium-build.d/$variant/base.list
printf "\e[1;34m-->\e[0m\e[1m Installing base packages\e[0m\n"
pacstrap $workdir ${base_packages[*]} || cleanup_and_quit 'Failed to install secondary package list'
# If overlay directory exists in variant copy it's contents to the temporary subvolume
if [[ -d arkanium-build.d/$variant/overlay ]]; then
cp -rv arkanium-build.d/$variant/overlay/* $workdir/
fi
# Read package list and install secondary system components, skip if not used
if [[ -e arkanium-build.d/$variant/package.list ]]; then
printf '\e[1;34m-->\e[0m\e[1m Installing secondary packages...\e[0m\n'
readarray packages < arkanium-build.d/$variant/package.list
arch-chroot $workdir pacman -S --noconfirm ${packages[*]} || cleanup_and_quit 'Failed to install base packages'
fi
# Enable systemd services if requested
if [[ -e arkanium-build.d/$variant/systemd.services ]]; then
printf '\e[1;34m-->\e[0m\e[1m Enabling systemd services...\e[0m\n'
readarray services < arkanium-build.d/$variant/systemd.services
for service in services; do
arch-chroot $workdir systemctl enable $service
done
fi
# Clear pacman cache
arch-chroot $workdir pacman --noconfirm -Scc
# Remove subvolumes created by systemd
[[ -d $workdir/var/lib/portables ]] &&
printf "\e[1;34m-->\e[0m\e[1m Removing systemd subvolume var/lib/portables\e[0m\n" &&
btrfs subvolume delete $workdir/var/lib/portables
[[ -d $workdir/var/lib/machines ]] &&
printf "\e[1;34m-->\e[0m\e[1m Removing systemd subvolume var/lib/machines\e[0m\n" &&
btrfs subvolume delete $workdir/var/lib/machines
# Clear pacman cache
rm -rf $workdir/var/cache/pacman/pkg/*
rm -rf $workdir/var/lib/pacman/local/*
# Make subvolume read-only
printf "\e[1;34m-->\e[0m\e[1m Adding read-only property to subvolumes\e[0m\n"
btrfs property set -ts $workdir ro true
btrfs property set -ts $workdir/etc ro true
btrfs property set -ts $workdir/var ro true
# Generate random name for new image
declare -r image_name=$(gen_random_string)
# Create dir for storing the images
mkdir -vp $(readlink -m $output_target/$image_name)
# Write subvolume to image
printf "\e[1;34m-->\e[0m\e[1m Creating images...\e[0m\n"
btrfs send -f $output_target/$image_name/$image_name-rootfs.img $workdir
btrfs send -f $output_target/$image_name/$image_name-etc.img $workdir/etc
btrfs send -f $output_target/$image_name/$image_name-var.img $workdir/var
printf "\e[1;34m-->\e[0m\e[1m Compressing images...\e[0m\n"
tar -cv -I 'zstd -12 -T0 ' -f $output_target/$image_name.tar.zst $output_target/$image_name
cleanup_and_quit
fi