2023-07-05 01:44:37 +02:00
#!/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.
2023-08-15 09:54:08 +02:00
set -o pipefail
2023-07-05 01:44:37 +02:00
## Set common variables
#
2024-02-29 10:33:41 +01:00
declare -r arkdep_dir="$(readlink -m $ARKDEP_ROOT/arkdep)"
2023-07-05 01:44:37 +02:00
2024-02-28 18:44:10 +01:00
# Override arkdep_boot if set, if not assume located inside of root
if [[ -n $ARKDEP_BOOT ]]; then
declare -r arkdep_boot="$(readlink -m $ARKDEP_BOOT)"
else
declare -r arkdep_boot="$(readlink -m $ARKDEP_ROOT/boot)"
fi
# if ARKDEP_BOOT is set also set ARKDEP_NO_BOOTCTL
[[ -n $ARKDEP_BOOT ]] && declare -r ARKDEP_NO_BOOTCTL=1
2024-02-12 02:25:02 +01:00
if [[ ! -d $arkdep_dir ]] && [[ ! $1 == 'init' ]]; then
2024-02-26 16:49:17 +01:00
printf "\e[1;31m<#>\e[0m\e[1m Arkep does not seem to be managing this system or the provided file path is incorrect for $arkdep_dir was not found\e[0m\n"
2024-02-12 02:25:02 +01:00
exit 1
fi
2024-02-27 13:46:35 +01:00
## Load config file, unless we are running init
2023-09-11 19:12:40 +02:00
#
2024-02-27 13:46:35 +01:00
if [[ ! $1 == 'init' ]]; then
2024-02-29 10:33:41 +01:00
source $arkdep_dir/config
2024-02-27 13:46:35 +01:00
# Set default variables if config variables are undefined
[[ -z ${enable_overlay+x} ]] && enable_overlay=1 && printf '\e[1;33m<!>\e[0m\e[1m enable_overlay not defined in config, using default\e[0m\n'
[[ -z ${repo_url+x} ]] && repo_url='https://arkanelinux.org/arkdep' && printf '\e[1;33m<!>\e[0m\e[1m repo_url not defined in config, using default\e[0m\n'
[[ -z ${repo_default_image+x} ]] && repo_default_image='arkanelinux' && printf '\e[1;33m<!>\e[0m\e[1m repo_default_image not defined in config, using default\e[0m\n'
[[ -z ${deploy_keep+x} ]] && deploy_keep=3 && printf '\e[1;33m<!>\e[0m\e[1m deploy_keep not defined in config, using default\e[0m\n'
[[ -z ${clean_cache_on_remove+x} ]] && clean_cache_on_remove=1 && printf '\e[1;33m<!>\e[0m\e[1m clean_cache_on_remove not defined in config, using default\e[0m\n'
[[ -z ${always_healthcheck+x} ]] && always_healthcheck=1 && printf '\e[1;33m<!>\e[0m\e[1m always_healthcheck not defined in config, using default\e[0m\n'
[[ -z ${gpg_signature_check+x} ]] && gpg_signature_check=1 && printf '\e[1;33m<!>\e[0m\e[1m gpg_signature_check not defined in config, using default\e[0m\n'
[[ -z ${minimum_available_boot_storage+x} ]] && minimum_available_boot_storage=153600 && printf '\e[1;33m<!>\e[0m\e[1m minimum_available_boot_storage not defined in config, using default\e[0m\n'
[[ -z ${minimum_available_root_storage+x} ]] && minimum_available_root_storage=12582912 && printf '\e[1;33m<!>\e[0m\e[1m minimum_available_root_storage not defined in config, using default\e[0m\n'
[[ -z ${update_cpu_microcode+x} ]] && update_cpu_microcode=1 && printf '\e[1;33m<!>\e[0m\e[1m update_cpu_microcode not defined in config, using default\e[0m\n'
2024-02-29 21:04:25 +01:00
[[ -z ${backup_user_accounts+x} ]] && backup_user_accounts=0 && printf '\e[1;33m<!>\e[0m\e[1m backup_user_accounts not defined in config, using default\e[0m\n'
2024-03-05 11:12:53 +01:00
[[ -z ${latest_image_always_default+x} ]] && latest_image_always_default=0 && printf '\e[1;33m<!>\e[0m\e[1m latest_image_always_default not defined in config, using default\e[0m\n'
2024-03-30 16:37:18 +01:00
[[ -z ${var_migrate_files+x} ]] && var_migrate_files=('/usrlocal' '/usrliblocale' '/opt' '/srv' '/nm-system-connections' '/lib/AccountsService' '/lib/bluetooth' '/lib/NetworkManager' '/lib/arkane') && printf '\e[1;33m<!>\e[0m\e[1m var_migrate_files not defined in config, using default\e[0m\n'
2024-04-03 21:16:07 +02:00
[[ -z ${load_extensions+x} ]] && load_extensions=0 && printf '\e[1;33m<!>\e[0m\e[1m load_extensions not defined in config, using default\e[0m\n'
2024-04-29 06:59:20 +02:00
[[ -z ${remove_tar_after_deployment+x} ]] && remove_tar_after_deployment=1 && printf '\e[1;33m<!>\e[0m\e[1m remove_tar_after_deployment not defined in config, using default\e[0m\n'
2024-02-27 13:46:35 +01:00
fi
2023-12-10 20:14:42 +01:00
2023-07-05 01:44:37 +02:00
## Common functions
#
# Cleanup and quit if error
cleanup_and_quit () {
2023-10-21 22:06:19 +02:00
# If any paramters are passed we will assume it to be an error message
2023-07-05 01:44:37 +02:00
[[ -n $1 ]] && printf "\e[1;31m<#>\e[0m $*\e[0m\n" >&2
2023-11-12 22:40:17 +00:00
# Ensure we do not try to remove our current deployment
2024-02-24 13:33:57 +01:00
if [[ ! -z ${data[0]+x} ]]; then
if grep -q ${data[0]} /proc/cmdline; then
printf '\e[1;33m<!>\e[0m\e[1m Cleanup target is current active deployment, skipping\e[0m\n'
exit 1
fi
2023-11-12 22:40:17 +00:00
fi
2023-09-14 19:10:20 +02:00
# Remove the subvolume we were working on
# TODO: Make this a generic function and share with the removal of old images?
if [[ -n ${data[0]} ]]; then
2024-02-29 10:33:41 +01:00
btrfs property set -f -ts $arkdep_dir/deployments/${data[0]}/rootfs/etc ro false
2024-03-29 17:40:00 +01:00
btrfs property set -f -ts $arkdep_dir/deployments/${data[0]}/rootfs/var ro false
2024-02-29 10:33:41 +01:00
btrfs property set -f -ts $arkdep_dir/deployments/${data[0]}/rootfs ro false
btrfs subvolume delete $arkdep_dir/deployments/${data[0]}/rootfs/etc
2024-03-29 17:40:00 +01:00
btrfs subvolume delete $arkdep_dir/deployments/${data[0]}/rootfs/var
2024-02-29 10:33:41 +01:00
btrfs subvolume delete $arkdep_dir/deployments/${data[0]}/rootfs
rm -rfv $arkdep_dir/deployments/${data[0]} \
$arkdep_boot/arkdep/${data[0]}
rm -v $arkdep_dir/cache/${data[0]}-*.img \
$arkdep_boot/loader/entries/${data[0]}.conf
2023-09-14 19:10:20 +02:00
fi
2023-07-05 01:44:37 +02:00
2023-11-12 22:40:17 +00:00
exit 1
2023-07-05 01:44:37 +02:00
}
2023-12-31 16:47:53 +01:00
## Healthcheck
#
2024-03-08 22:12:03 +01:00
# Set common variables for healthcheck and cleanup,
# only set all these vars if they will actually be used
if [[ always_healthcheck -eq 1 ]] || [[ $1 =~ ^(healthcheck|cleanup) ]]; then
2023-12-31 16:47:53 +01:00
# Gather tracked deployments
declare -r tracker=($(cat $arkdep_dir/tracker))
declare -r deployed=($(ls $arkdep_dir/deployments/))
declare untracked=${deployed[@]}
# Check for hanging cache files
declare -r cached=($(ls $arkdep_dir/cache/))
declare hanging_cache=()
# Generate grep regex for cache check
declare cache_regex=$(printf "|%s" "${tracker[@]}")
cache_regex=${cache_regex:1}
# Compare items in tracker to actual deployed
for tracked in ${tracker[@]}; do
untracked=("${untracked[@]/$tracked}")
done
for cached_item in ${cached[@]}; do
hanging_cache+=($(echo $cached_item | grep -v -E "$cache_regex"))
done
# Clean whitespaces
2024-03-17 09:24:08 +01:00
untracked=($(echo ${untracked[@]} | xargs))
2024-03-08 22:12:03 +01:00
fi
# Check for and report on any issues such as untracked deployments or hanging files in cache
healthcheck () {
2023-12-31 16:47:53 +01:00
2024-02-28 18:45:04 +01:00
if [[ -n $untracked ]]; then
2023-12-31 16:47:53 +01:00
printf '\e[1;33m<!>\e[0m\e[1m The following deployments were found but are untracked\n\e[0m'
for t in ${untracked[@]}; do
printf "$t\n"
done
fi
2024-02-28 18:45:04 +01:00
if [[ -n $hanging_cache ]]; then
2023-12-31 16:47:53 +01:00
printf '\e[1;33m<!>\e[0m\e[1m The following hanging images were found in cache\n\e[0m'
for t in ${hanging_cache[@]}; do
printf "$t\n"
done
fi
2024-01-19 13:23:04 +01:00
# Warn if gpg check is enabled but no keys are installed
if [[ ! $gpg_signature_check -eq 0 ]] && [[ ! -s $arkdep_dir/keys/trusted-keys ]]; then
2024-02-29 10:33:41 +01:00
printf "\e[1;33m<!>\e[0m\e[1m gpg_signature_check is enabled but $arkdep_dir/keys/trusted-keys does not exist or is empty\n\e[0m"
2024-01-19 13:23:04 +01:00
fi
2023-12-31 16:47:53 +01:00
# If $1 is healthcheck it was manually called by the user
[[ $1 == 'healthcheck' ]] && exit 0
}
2024-03-08 22:12:03 +01:00
cleanup () {
if [[ -n $untracked ]]; then
printf '\e[1;34m-->\e[0m\e[1m Cleaning up untracked deployments\e[0m\n'
for target in ${untracked[@]}; do
2024-03-08 22:18:06 +01:00
if [[ $target == *recovery* ]]; then
2024-03-08 22:12:03 +01:00
printf '\e[1;33m<!>\e[0m\e[1m Detected untracked recovery entry, ignoring\n\e[0m'
2024-03-31 21:50:37 +02:00
continue
2024-03-08 22:12:03 +01:00
fi
# Ensure deployment is not currently active
if grep -q "$arkdep_dir/deployments/$target/rootfs" /proc/cmdline; then
printf '\e[1;33m<!>\e[0m\e[1m Target is currently active deployment\n\e[0m'
2024-03-31 21:50:37 +02:00
continue
2024-03-08 22:12:03 +01:00
fi
# Remove bootloader entry
rm -rfv $arkdep_boot/loader/entries/$target.conf
rm -rfv $arkdep_boot/arkdep/$target
# Ensure the deployment and all sub-volumes are writable
for volume in $(btrfs subvolume list / | grep -oE '[^ ]+$' | grep $target); do
btrfs property set -f -ts $(readlink -m $ARKDEP_ROOT/$volume) ro false || printf "failed to make subvol $volume writable\n"
done
# Remove the deployment
2024-03-29 17:40:00 +01:00
rm -rf $arkdep_dir/deployments/$target
2024-03-08 22:12:03 +01:00
done
fi
if [[ -n $hanging_cache ]]; then
printf '\e[1;34m-->\e[0m\e[1m Cleaning up hanging cache\e[0m\n'
for target in ${hanging_cache[@]}; do
rm -v $arkdep_dir/cache/$target
done
fi
2024-03-31 14:31:58 +02:00
exit 0
2024-03-08 22:12:03 +01:00
}
2023-12-31 16:47:53 +01:00
# Always healthcheck on run if requested in config, unless the user explicitely called it
[[ $always_healthcheck -eq 1 ]] && [[ ! $1 == 'healthcheck' ]] && healthcheck
2023-07-05 01:44:37 +02:00
## Error checking
#
2024-02-20 07:43:25 +01:00
# Quit if not root, only run if required
if [[ ! $1 =~ ^(get-available|healthcheck) ]]; then
if [[ ! $EUID -eq 0 ]]; then
printf '\e[1;31m<#>\e[0m\e[1m This program has to be run as root\n\e[0m' &&
exit 1
fi
fi
2023-07-05 01:44:37 +02:00
# Check if all dependencies are installed, quit if not
2024-01-19 13:23:04 +01:00
for prog in btrfs wget dracut bootctl curl gpg gpgv; do
2024-02-26 17:32:26 +01:00
# If ARKDEP_NO_BOOTCTL defined do not enforce bootctl requirement
2024-02-27 13:48:34 +01:00
if [[ $prog == 'bootctl' ]] && [[ $ARKDEP_NO_BOOTCTL -eq 1 ]]; then
2024-02-26 17:32:26 +01:00
break
fi
2023-07-05 01:44:37 +02:00
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"
2024-02-08 21:35:35 +01:00
# Do not immediately exit to log all missing programs
2023-10-15 08:30:44 +02:00
err=1
2023-07-05 01:44:37 +02:00
fi
2023-10-15 08:30:44 +02:00
[[ $err ]] && exit 1
2023-07-05 01:44:37 +02:00
done
2024-02-08 21:35:35 +01:00
# Ensure minimum required storage is available, only run if new deployment will be made
if [[ $1 == 'deploy' ]]; then
2024-02-29 10:33:41 +01:00
declare boot_storage_available=($(df --output=avail $arkdep_boot))
2024-02-08 21:35:35 +01:00
boot_storage_available=${boot_storage_available[1]}
2024-02-29 10:33:41 +01:00
declare root_storage_available=($(df --output=avail $ARKDEP_ROOT/))
2024-02-08 21:35:35 +01:00
root_storage_available=${root_storage_available[1]}
2024-02-09 17:02:45 +01:00
# Check amount of available boot storage, do not run if set to 0
if [[ $boot_storage_available -lt $minimum_available_boot_storage ]] && [[ $minimum_available_boot_storage -ne 0 ]]; then
2024-02-08 21:35:35 +01:00
printf "\e[1;31m<#>\e[0m\e[1m Less than ${minimum_available_boot_storage}Kib available on boot partition\e[0m\n"
exit 1
fi
2024-02-09 17:02:45 +01:00
# Check amount of available root storage, do not run if set to 0
if [[ $root_storage_available -lt $minimum_available_root_storage ]] && [[ $minimum_available_root_storage -ne 0 ]] ; then
2024-02-08 21:35:35 +01:00
printf "\e[1;31m<#>\e[0m\e[1m Less than ${minimum_available_root_storage}Kib available on root partition\e[0m\n"
exit 1
fi
fi
2023-07-05 01:44:37 +02:00
## Core functions
#
2023-09-21 21:51:57 +02:00
# Initialize the system for arkdep
2023-07-05 01:44:37 +02:00
init () {
2023-07-31 03:07:34 +02:00
# Ensure systemd-boot is installed before continuing, for it is the only thing we support
2024-02-26 17:32:26 +01:00
# Do not run if ARKDEP_NO_BOOTCTL defined
2024-02-27 13:48:34 +01:00
if [[ ! $ARKDEP_NO_BOOTCTL -eq 1 ]]; then
2024-02-27 13:50:25 +01:00
bootctl -q is-installed || cleanup_and_quit 'systemd-boot seems to not be installed'
2024-02-26 17:32:26 +01:00
else
printf '\e[1;33m<!>\e[0m\e[1m Not running bootctl is-installed because overwritten with ARKDEP_NO_BOOTCTL\e[0m\n'
fi
2023-07-31 03:07:34 +02:00
2023-09-21 21:51:57 +02:00
printf '\e[1;34m-->\e[0m\e[1m Initializing arkdep\e[0m\n'
2023-07-05 01:44:37 +02:00
2024-02-26 16:49:17 +01:00
[[ -d $arkdep_dir ]] && cleanup_and_quit "$arkdep_dir already exists"
2023-07-05 01:44:37 +02:00
2023-09-21 21:51:57 +02:00
# Create the /arkdep subvolume
2024-02-26 16:49:17 +01:00
printf "\e[1;34m-->\e[0m\e[1m Creating $arkdep_dir subvolume\e[0m\n"
btrfs subvolume create $arkdep_dir || cleanup_and_quit "Failed to create btrfs subvolume"
2023-07-05 01:44:37 +02:00
# Create directory structure
2023-12-11 22:11:25 +01:00
printf '\e[1;34m-->\e[0m\e[1m Creating directory structure\e[0m\n'
2024-02-29 10:33:41 +01:00
mkdir -pv $arkdep_dir/deployments \
$arkdep_dir/deployments \
$arkdep_dir/cache \
$arkdep_dir/templates \
$arkdep_dir/overlay \
$arkdep_dir/keys \
2024-04-03 21:16:07 +02:00
$arkdep_dir/extensions \
2024-02-29 10:33:41 +01:00
$arkdep_dir/shared ||
2024-02-26 16:49:17 +01:00
cleanup_and_quit "Failed to create $arkdep_dir and related directories"
2023-07-05 01:44:37 +02:00
2023-08-25 00:15:23 +02:00
# Create empty database files
2024-02-29 10:33:41 +01:00
touch $arkdep_dir/tracker
touch $arkdep_dir/keys/trusted-keys
2023-08-25 00:15:23 +02:00
2023-07-31 03:07:34 +02:00
# Add home shared subvolume and make writable
2024-02-29 10:33:41 +01:00
btrfs subvolume create $arkdep_dir/shared/home || cleanup_and_quit "Failed to create home subvolume"
2024-03-29 17:40:00 +01:00
btrfs subvolume create $arkdep_dir/shared/root || cleanup_and_quit "Failed to create root subvolume"
btrfs subvolume create $arkdep_dir/shared/flatpak || cleanup_and_quit "Failed to create flatpak subvolume"
2024-02-29 10:33:41 +01:00
btrfs property set -f -ts $arkdep_dir/shared/home ro false
2024-03-29 17:40:00 +01:00
btrfs property set -f -ts $arkdep_dir/shared/root ro false
btrfs property set -f -ts $arkdep_dir/shared/flatpak ro false
# Ensure permissions on root home directory are set properly
chmod 700 $arkdep_dir/shared/root
2023-07-31 03:07:34 +02:00
2023-07-05 01:44:37 +02:00
# Write default config file
2023-12-11 22:11:25 +01:00
printf '\e[1;34m-->\e[0m\e[1m Adding default config file\e[0m\n'
2024-02-26 16:49:17 +01:00
cat <<- END > $arkdep_dir/config
2024-01-19 13:23:04 +01:00
# Write /arkdep/overlay overlay to new deployments
2023-09-16 11:53:45 +02:00
enable_overlay=1
2023-07-05 01:44:37 +02:00
2023-08-14 18:01:33 +02:00
# URL to image repository, do not add trailing slash
2023-09-21 21:51:57 +02:00
repo_url='https://repo.arkanelinux.org/arkdep'
2023-08-14 18:01:33 +02:00
# Default image pulled from repo if nothing defined
repo_default_image='arkanelinux'
2023-08-25 00:15:23 +02:00
2024-05-03 11:54:26 +02:00
# Keep the latest N deployments, remove anything older
2024-05-03 11:56:28 +02:00
deploy_keep=3
2023-12-09 04:03:33 +01:00
# Remove images from the cache when their deployments are removed
clean_cache_on_remove=1
2023-12-31 16:47:53 +01:00
# Check for untracked deployments and other issues on run
always_healthcheck=1
2024-01-19 13:23:04 +01:00
# Perform a GPG signature check on remote sources
2024-02-08 21:35:35 +01:00
# 1 = enabled but optional, 2 = required
2024-01-19 13:23:04 +01:00
gpg_signature_check=1
2024-02-08 21:35:35 +01:00
2024-02-08 21:41:15 +01:00
# Minimum amount of storage which needs to be available on /boot in Kib
2024-02-08 21:35:35 +01:00
minimum_available_boot_storage=153600
2024-02-08 21:41:15 +01:00
# Minimum amount of storage which needs to be available on / in Kib
2024-02-08 21:35:35 +01:00
minimum_available_root_storage=12582912
2024-02-24 13:33:57 +01:00
# Update CPU firmware if newer version available
update_cpu_microcode=1
2024-02-29 10:05:05 +01:00
# Automatically make a copy of passwd, shadow and group files if they differ from overlay
2024-02-29 21:04:25 +01:00
backup_user_accounts=0
2024-03-04 17:31:18 +01:00
2024-03-05 11:12:53 +01:00
# Ensure latest image as defined in the external database is always the default systemd-boot boot entry
latest_image_always_default=0
2024-03-29 17:40:00 +01:00
2024-03-30 16:37:18 +01:00
# List of files and folders to be recursively copied over from var to new var, path should start with /
var_migrate_files=('/usrlocal' '/usrliblocale' '/opt' '/srv' '/nm-system-connections' '/lib/AccountsService' '/lib/bluetooth' '/lib/NetworkManager' '/lib/arkane')
2024-04-03 21:16:07 +02:00
# Load script extensions from /arkdep/extensions
load_extensions=0
2024-04-29 06:59:20 +02:00
# Remove tarball from cache once deployment is finished
remove_tar_after_deployment=1
2023-07-05 01:44:37 +02:00
END
2023-08-10 06:44:20 +02:00
# Add default bootloader config file
2024-02-26 16:49:17 +01:00
cat <<- END > $arkdep_dir/templates/systemd-boot
2024-02-09 21:09:20 +01:00
title Arkane GNU/Linux - Arkdep
2023-09-21 21:51:57 +02:00
linux /arkdep/%target%/vmlinuz
2023-07-31 03:07:34 +02:00
initrd /amd-ucode.img
initrd /intel-ucode.img
2023-09-21 21:51:57 +02:00
initrd /arkdep/%target%/initramfs-linux.img
options root="LABEL=arkane_root" rootflags=subvol=/arkdep/deployments/%target%/rootfs rw
2023-07-31 03:07:34 +02:00
END
2023-07-05 01:44:37 +02:00
exit 0
2023-07-31 03:07:34 +02:00
2023-07-05 01:44:37 +02:00
}
teardown () {
cat <<- END
2023-09-21 21:51:57 +02:00
WARNING: Removing arkdep may leave your system in an unbootable state and you
2023-07-05 01:44:37 +02:00
may have to manually reconfigure your bootloader etc.. Only proceed if you know
what you are doing!
The following changes will be made to your system;
2023-09-21 21:51:57 +02:00
- All subvolumes under $arkdep_dir will be deleted
2023-12-14 05:36:14 +01:00
- All systemd-boot bootloader entries containing the word "arkdep" will be removed
- Kernel and initramfs storage location /boot/arkdep will be removed
2023-07-05 01:44:37 +02:00
END
2023-12-14 05:36:14 +01:00
# Ensure user knows what they are doing
2023-11-27 08:25:01 +00:00
read -p 'Type "I KNOW WHAT I AM DOING" in uppercase to confirm that you know what you are doing: ' input_confirm
2023-07-05 01:44:37 +02:00
if [[ $input_confirm == 'I KNOW WHAT I AM DOING' ]]; then
2023-09-21 21:51:57 +02:00
printf '\e[1;34m-->\e[0m\e[1m Tearing down arkdep\e[0m\n'
2023-07-05 01:44:37 +02:00
2023-09-21 21:51:57 +02:00
# Quit with error if $arkdep_dir does not exist
if [[ ! -d $arkdep_dir ]]; then
2024-03-31 21:50:37 +02:00
printf "\e[1;31m<#>\e[0m $arkdep_dir does not exist, there is nothing to tear down\n\e[0m"
2023-07-05 01:44:37 +02:00
exit 1
fi
2023-10-20 07:19:44 +02:00
# Remove all bootloader entries
2024-02-29 10:33:41 +01:00
rm -v $(grep -ril arkdep $arkdep_boot/loader/entries)
2023-07-05 01:44:37 +02:00
2023-12-14 05:36:14 +01:00
# Remove kernels and initramfs deployed by Arkdep
2024-02-29 10:33:41 +01:00
rm -rfv $arkdep_boot/arkdep
2023-12-14 05:36:14 +01:00
2023-10-20 07:19:44 +02:00
# Ensure all nested volumes in arkdep are writable and remove
for volume in $(btrfs subvolume list / | grep -oE '[^ ]+$' | grep "^$arkdep_dir" | tac); do
2023-11-12 23:25:42 +00:00
btrfs property set -f -ts $(readlink -m /$volume) ro false
2023-10-20 07:19:44 +02:00
btrfs subvolume delete $volume
done
2023-07-05 01:44:37 +02:00
else
2023-12-14 05:36:14 +01:00
printf '\e[1;33m<!>\e[0m\e[1m Teardown canceled, no changes made to system\e[0m\n'
2023-07-05 01:44:37 +02:00
fi
exit 0
}
2023-10-20 08:22:28 +02:00
remove_deployment () {
# Ensure required vars are set
2024-03-31 21:50:37 +02:00
if [[ -z $1 ]]; then
printf '\e[1;31m<#>\e[0m\e[1m No deployment defined\n\e[0m'
exit 1
fi
2023-10-20 08:22:28 +02:00
2024-03-31 21:50:37 +02:00
for deployment in ${@:2}; do
2023-10-21 22:06:19 +02:00
2024-03-31 21:50:37 +02:00
# Ensure requested deployment is tracked
declare hits=($(grep $deployment $arkdep_dir/tracker))
2023-10-20 08:22:28 +02:00
2024-03-31 21:50:37 +02:00
if [[ ${#hits[@]} -gt 1 ]]; then
2024-02-25 09:31:06 +01:00
2024-03-31 21:50:37 +02:00
# Check if there is an exact match
for hit in ${hits[@]}; do
if [[ $1 == $hit ]]; then
declare -r exact_match_found=1
# Set first hit to exact match
hits[0]=$hit
fi
done
if [[ ! $exact_match_found -eq 1 ]]; then
printf '\e[1;33m<!>\e[0m\e[1m Multiple deployments match target, be more specific or provide an exact match\e[0m\n'
continue
2024-02-25 09:31:06 +01:00
fi
2024-03-31 21:50:37 +02:00
elif [[ ${#hits[@]} -lt 1 ]]; then
printf '\e[1;33m<!>\e[0m\e[1m No deployments match target\e[0m\n'
continue
2024-02-25 09:31:06 +01:00
fi
2023-10-20 08:22:28 +02:00
2024-03-31 21:50:37 +02:00
declare target=${hits[0]}
2023-10-20 08:22:28 +02:00
2024-03-31 21:50:37 +02:00
printf "Removing $target\n"
2024-02-25 10:22:24 +01:00
2024-03-31 21:50:37 +02:00
# Ensure deployment is not currently active
if grep -q "$arkdep_dir/deployments/$target/rootfs" /proc/cmdline; then
printf '\e[1;33m<!>\e[0m\e[1m Target is current active deployment\e[0m\n'
continue
fi
2023-10-20 08:22:28 +02:00
2024-03-31 21:50:37 +02:00
# Remove bootloader entry
rm -rfv $arkdep_boot/loader/entries/$target.conf
rm -rfv $arkdep_boot/arkdep/$target
2023-10-20 08:22:28 +02:00
2024-03-31 21:50:37 +02:00
# Ensure the deployment and all sub-volumes are writable
for volume in $(btrfs subvolume list / | grep -oE '[^ ]+$' | grep $target); do
btrfs property set -f -ts $(readlink -m $ARKDEP_ROOT/$volume) ro false \
|| printf "\e[1;33m<!>\e[0m\e[1m Failed to make subvolume $volume writable\e[0m\n"
done
2023-10-20 08:22:28 +02:00
2024-03-31 21:50:37 +02:00
# Remove the deployment
rm -rf $arkdep_dir/deployments/$target
2024-02-25 05:51:56 +01:00
2024-03-31 21:50:37 +02:00
# Remove from tracker
grep -v $target $arkdep_dir/tracker > $arkdep_dir/tracker_tmp
declare tracker_write_exit_code=$?
# Grep may return a 1 if the file is empty
if [[ $tracker_write_exit_code -eq 1 ]]; then
# No matches, this means file is now empty
truncate -s 0 $arkdep_dir/tracker
elif [[ $tracker_write_exit_code -eq 2 ]]; then
# An error occured in grep
cleanup_and_quit 'Failed to update tracker file'
fi
2024-02-25 05:51:56 +01:00
2024-03-31 21:50:37 +02:00
mv $arkdep_dir/tracker_tmp $arkdep_dir/tracker \
|| cleanup_and_quit 'Failed to move tracker_tmp file to tracker'
2023-10-20 08:22:28 +02:00
2024-03-31 21:50:37 +02:00
# Remove images from cache if requested
if [[ $clean_cache_on_remove -eq 1 ]]; then
# Only attempt remove if file exists
if ls $arkdep_dir/cache/ | grep $target; then
rm -v $arkdep_dir/cache/$target.tar.*
fi
2023-12-09 04:03:33 +01:00
fi
2024-03-31 21:50:37 +02:00
done
if [[ $remove_no_quit -ne 1 ]]; then
exit 0
fi
2023-10-20 08:22:28 +02:00
}
2023-07-22 18:15:44 +02:00
# List all available packages defined in the repo's list file
get_available () {
printf "\e[1;34m-->\e[0m\e[1m Downloading list file from $repo_url\e[0m\n"
2023-12-11 22:11:25 +01:00
curl -sf "${repo_url}/list" || printf '\e[1;33m<!>\e[0m\e[1m Failed to download list file\e[0m\n'
2023-11-15 21:21:16 +00:00
exit 0
2023-07-05 01:44:37 +02:00
}
2023-07-22 18:15:44 +02:00
# Deploy a new or update an existing deployment
deploy () {
2024-04-18 12:15:22 +02:00
# Allow for a clean shutdown, later this is blocked once deployment starts
trap 'echo "User interupt received, interupting download"; exit 4' INT TERM
2023-08-14 20:08:38 +02:00
# target and version are optional, if not defined default to primary as defined in
2023-09-21 21:51:57 +02:00
# /arkdep/config and latest
2024-01-04 18:07:36 +01:00
if [[ -n $1 ]] && [[ $1 != '-' ]]; then
2023-11-18 08:43:35 +00:00
declare -r deploy_target=$1
2023-08-15 10:12:02 +02:00
else
2024-01-04 18:07:36 +01:00
declare -r deploy_target=$repo_default_image
2023-08-15 10:12:02 +02:00
fi
2023-11-18 08:43:35 +00:00
if [[ -n $2 ]]; then
declare -r deploy_version=$2
2023-08-15 10:12:02 +02:00
else
declare -r deploy_version='latest'
fi
2023-07-22 18:15:44 +02:00
2024-01-04 18:07:36 +01:00
# If cache requested version may not be latest
2024-01-04 22:10:23 +01:00
if [[ $1 == 'cache' ]] && [[ $deploy_version == 'latest' ]]; then
2024-01-04 18:07:36 +01:00
cleanup_and_quit '"latest" and undefined are not a valid version definitions for a cache source'
fi
2023-07-22 18:15:44 +02:00
printf "\e[1;34m-->\e[0m\e[1m Deploying $deploy_target $deploy_version\e[0m\n"
2024-01-04 18:07:36 +01:00
# Split latest_version at the delimiter, creating an array with data.0=package ver, data.1=compression method, data.2=sha1 hash
# only run if request target is not cache
if [[ $1 != 'cache' ]]; then
# If latest is requested grab database and get first line
2024-01-31 00:25:03 +01:00
printf '\e[1;34m-->\e[0m\e[1m Downloading database\e[0m\n'
2024-01-04 18:07:36 +01:00
if [[ $deploy_version == 'latest' ]]; then
declare curl_data=$(curl -sf "${repo_url}/${deploy_target}/database" | head -n 1)
elif [[ $deploy_target != 'cache' ]]; then
# Only return first hit
declare curl_data=$(curl -sf "${repo_url}/${deploy_target}/database" | grep -E "^$2" | head -1)
else
declare curl_data='cache'
fi
readarray -d : -t data <<< "$curl_data"
# If target is cache
2023-08-15 09:54:08 +02:00
else
2024-01-20 06:35:34 +01:00
# Find full name in cache, exclude sig files, if no hit quit with error
2024-02-29 10:33:41 +01:00
declare cache_hits=($(ls $arkdep_dir/cache | grep -E "^$deploy_version" | grep -v '.sig$'))
2024-01-04 18:07:36 +01:00
# Temporary var to store the delimited file found in cache
declare data_inter=()
# Check if none or more than a single hit, we only expect a single item to match
[[ ${#cache_hits[@]} -gt 1 ]] && cleanup_and_quit 'More than a single item in cache matched requested version'
[[ ${#cache_hits[@]} -lt 1 ]] && cleanup_and_quit 'No item in cache matched requested version'
# Split filename at delimiter
readarray -d . -t data_inter <<< "$cache_hits"
# Set expected vars for remainder of script
data[0]=${data_inter[0]}
data[1]=${data_inter[2]}
data[2]='-'
fi
2023-11-18 02:44:25 +00:00
# Ensure none of the vars contain whitespaces
data[0]=${data[0]//[$'\t\r\n']}
data[1]=${data[1]//[$'\t\r\n']}
2023-08-15 09:54:08 +02:00
data[2]=${data[2]//[$'\t\r\n']}
2023-11-18 02:44:25 +00:00
# Lets do a bunch of checks to ensure the data is all present
if [[ -z ${data[0]+x} ]] || [[ ! -n ${data[0]} ]]; then
printf '\e[1;31m<#>\e[0m\e[1m No target found\n\e[0m'
exit 1
fi
if [[ -z ${data[1]+x} ]] || [[ ! -n ${data[1]} ]]; then
printf '\e[1;31m<#>\e[0m\e[1m No compression method found\n\e[0m'
exit 1
fi
if [[ -z ${data[2]+x} ]] || [[ ! -n ${data[2]} ]]; then
2024-01-04 18:07:36 +01:00
# Do not trigger if hash is -, is used for cache deployments
if [[ $deploy_target != '-' ]]; then
printf '\e[1;31m<#>\e[0m\e[1m No checksum found\n\e[0m'
exit 1
fi
2023-11-18 02:44:25 +00:00
fi
2023-09-14 19:42:54 +02:00
# Lets ensure the requested image is not already deployed
2023-09-21 21:51:57 +02:00
if [[ -e $arkdep_dir/deployments/${data[0]} ]]; then
2024-03-04 17:31:18 +01:00
# Lets ensure the latest deployment is active, even if it is already deployed
2024-03-05 11:12:53 +01:00
if [[ latest_image_always_default -eq 1 ]] && [[ ! $ARKDEP_NO_BOOTCTL -eq 1 ]]; then
2024-03-04 17:31:18 +01:00
# Allow it to error, it is no big deal if it does
2024-03-05 11:12:53 +01:00
bootctl set-default ${data[0]}.conf || printf '\e[1;33m<!>\e[0m\e[1m Failed to set default bootloader entry on latest_image_always_default\e[0m\n'
2024-03-04 17:31:18 +01:00
fi
2023-09-14 19:42:54 +02:00
printf "\e[1;33m<!>\e[0m\e[1m ${data[0]} is already deployed, canceling deployment\e[0m\n"
2024-03-04 17:17:52 +01:00
exit 0
2023-09-14 19:42:54 +02:00
fi
2023-07-22 18:15:44 +02:00
# Check if requested version is already downloaded
2024-03-04 00:02:24 +01:00
if [[ -e $arkdep_dir/cache/${data[0]}.tar.${data[1]} ]] && [[ ! -e $arkdep_dir/cache/${data[0]}.tar.${data[1]}.run ]]; then
2023-07-22 18:15:44 +02:00
printf "\e[1;34m-->\e[0m\e[1m ${data[0]} already in cache, skipping download\e[0m\n"
else
2024-01-31 00:25:03 +01:00
printf "\e[1;34m-->\e[0m\e[1m Downloading disk image\e[0m\n"
2023-08-14 20:08:38 +02:00
# Download the tarball if not yet downloaded
2024-01-19 13:23:04 +01:00
2024-03-04 00:02:24 +01:00
# Write .run file to indicate process is ongoing and not yet finished, can be used to resume download later
touch $arkdep_dir/cache/${data[0]}.tar.${data[1]}.run
2024-05-09 14:28:46 +02:00
# Start the download
systemd-inhibit --who='arkdep deploy' --what='idle:sleep:shutdown' --why='Arkdep is downloading an image' \
wget -c -q --show-progress -P $arkdep_dir/cache/ "$repo_url/$deploy_target/${data[0]}.tar.${data[1]}" ||
cleanup_and_quit 'Failed to download tarball'
2024-03-04 00:02:24 +01:00
# Download GPG signature, only perform check if not disabled by user and keychain exists
if [[ ! $gpg_signature_check -eq 0 ]] && [[ -s $arkdep_dir/keys/trusted-keys ]]; then
2024-01-19 13:23:04 +01:00
2024-03-04 00:02:24 +01:00
# Download gpg signature if not yet in cache
if [[ ! -s $arkdep_dir/cache/${data[0]}.tar.${data[1]}.sig ]]; then
wget -c -q --show-progress -P $arkdep_dir/cache/ "$repo_url/$deploy_target/${data[0]}.tar.${data[1]}.sig"
sig_exitcode=$?
fi
2024-01-19 13:23:04 +01:00
2024-03-04 00:02:24 +01:00
if [[ ! $sig_exitcode -eq 0 ]] && [[ $gpg_signature_check -eq 1 ]]; then
# Sig download is allowed to fail
printf "\e[1;33m<!>\e[0m\e[1m Failed to download GPG signature, signature check will be skipped\e[0m\n"
elif [[ ! $sig_exitcode -eq 0 ]] && [[ $gpg_signature_check -eq 2 ]]; then
# gpg_signature_check = 2, error and quit the program on fail
cleanup_and_quit 'GPG signature check configured to quit on download failure'
2024-01-19 13:23:04 +01:00
fi
2024-03-04 00:02:24 +01:00
2023-08-14 20:08:38 +02:00
fi
2024-03-04 00:02:24 +01:00
# Remove the .run file
rm $arkdep_dir/cache/${data[0]}.tar.${data[1]}.run
2024-02-21 02:06:45 +01:00
fi
2024-01-25 17:50:43 +01:00
2024-02-21 02:06:45 +01:00
if [[ $gpg_signature_check -eq 2 ]] && [[ ! -s $arkdep_dir/cache/${data[0]}.tar.${data[1]}.sig ]]; then
# if GPG check required but file not present error and quit
cleanup_and_quit 'GPG signature expected but none were provided'
elif [[ ! -s $arkdep_dir/cache/${data[0]}.tar.${data[1]}.sig ]]; then
skip_gpg_check=1
2023-07-22 18:15:44 +02:00
fi
2024-01-20 06:35:34 +01:00
# If not configured to skip by previous error handeling check the signature to the downloaded image
2024-01-25 17:50:43 +01:00
if [[ ! $skip_gpg_check -eq 1 ]]; then
2024-01-20 06:35:34 +01:00
printf '\e[1;34m-->\e[0m\e[1m Checking GPG signature\e[0m\n'
# Perform GPG signature check
gpgv --keyring $arkdep_dir/keys/trusted-keys $arkdep_dir/cache/${data[0]}.tar.${data[1]}.sig $arkdep_dir/cache/${data[0]}.tar.${data[1]} ||
cleanup_and_quit 'gpg check failed'
elif [[ ${data[2]} != '-' ]]; then
# If GPG check not triggered instead check hash, unless defined as -
2024-03-19 07:00:44 +01:00
2024-01-04 18:07:36 +01:00
printf '\e[1;34m-->\e[0m\e[1m Validating integrity\e[0m\n'
2024-03-19 07:00:44 +01:00
# Identify used checksum method
if [[ ${#data[2]} -eq 40 ]]; then
# If it is a sha-1
sha1sum $arkdep_dir/cache/${data[0]}.tar.${data[1]} |
grep "${data[2]}" ||
cleanup_and_quit 'SHA-1 checksum does not match the one defined in database\e[0m\n'
elif [[ ${#data[2]} -eq 56 ]]; then
# If it is sha-224
sha224sum $arkdep_dir/cache/${data[0]}.tar.${data[1]} |
grep "${data[2]}" ||
cleanup_and_quit 'SHA-224 checksum does not match the one defined in database\e[0m\n'
elif [[ ${#data[2]} -eq 64 ]]; then
# If it is sha-256
sha256sum $arkdep_dir/cache/${data[0]}.tar.${data[1]} |
grep "${data[2]}" ||
cleanup_and_quit 'SHA-256 checksum does not match the one defined in database\e[0m\n'
elif [[ ${#data[2]} -eq 96 ]]; then
# If it is sha-384
sha384sum $arkdep_dir/cache/${data[0]}.tar.${data[1]} |
grep "${data[2]}" ||
cleanup_and_quit 'SHA-384 checksum does not match the one defined in database\e[0m\n'
elif [[ ${#data[2]} -eq 128 ]]; then
# If it is a sha-512
sha512sum $arkdep_dir/cache/${data[0]}.tar.${data[1]} |
grep "${data[2]}" ||
cleanup_and_quit 'SHA-512 Checksum does not match the one defined in database\e[0m\n'
else
cleanup_and_quit 'Failed to identify SHA checksum type'
fi
2024-01-04 18:07:36 +01:00
fi
2023-07-22 18:15:44 +02:00
2024-04-18 12:15:22 +02:00
# We will now start writing the images to disk, prevent the user from shutting down the script
trap '' INT TERM
2024-04-27 04:55:47 +02:00
# Check if there is a migration script available
2024-04-27 06:10:03 +02:00
if tar -xf $arkdep_dir/cache/${data[0]}.tar.${data[1]} -C $arkdep_dir/cache/ ./${data[0]}-migration.sh 2> /dev/null; then
2024-04-27 04:55:47 +02:00
printf '\e[1;34m-->\e[0m\e[1m Running migration script\e[0m\n'
# Run the migration script if provided
(source $arkdep_dir/cache/${data[0]}-migration.sh)
# TODO: Evaluate if this is how we would really like to do this
#
# Cancel the update once migration is finished, we are assuming the migration script did all the work for us
exit 0
fi
2023-09-16 18:31:55 +02:00
# Extract the root image if not yet extracted
2023-12-11 22:11:25 +01:00
printf '\e[1;34m-->\e[0m\e[1m Writing root\e[0m\n'
2023-09-16 18:31:55 +02:00
2023-08-14 20:08:38 +02:00
# Create directory using unique deployment name
2024-04-27 03:51:38 +02:00
mkdir -p $arkdep_dir/deployments/${data[0]} || cleanup_and_quit 'Failed to create deployment directory'
2023-08-14 20:08:38 +02:00
2024-04-29 05:27:34 +02:00
# Extra image from tarball to stdin and receive
2024-04-29 05:03:08 +02:00
tar -xOf $arkdep_dir/cache/${data[0]}.tar.${data[1]} "./${data[0]}-rootfs.img" |
btrfs receive $arkdep_dir/deployments/${data[0]} ||
2023-07-31 03:07:34 +02:00
cleanup_and_quit 'Failed to receive root'
# Extract the etc image if not yet extracted
2023-12-11 22:11:25 +01:00
printf '\e[1;34m-->\e[0m\e[1m Writing etc\e[0m\n'
2023-07-31 03:07:34 +02:00
2023-08-14 20:08:38 +02:00
# Write the etc image and create var directory, we have to unlock rootfs temporarily to do this
2024-02-29 10:33:41 +01:00
btrfs property set -f -ts $arkdep_dir/deployments/${data[0]}/rootfs ro false ||
2023-07-31 03:07:34 +02:00
cleanup_and_quit 'Failed to unlock root to write etc'
2023-08-14 20:08:38 +02:00
2024-04-29 05:27:34 +02:00
# Extra image from tarball to stdin and receive
2024-04-29 05:03:08 +02:00
tar -xOf $arkdep_dir/cache/${data[0]}.tar.${data[1]} "./${data[0]}-etc.img" |
btrfs receive $arkdep_dir/deployments/${data[0]}/rootfs/ ||
2023-07-31 03:07:34 +02:00
cleanup_and_quit 'Failed to receive etc'
2023-08-14 20:08:38 +02:00
# Unlock the etc deployment
2024-02-29 10:33:41 +01:00
btrfs property set -f -ts $arkdep_dir/deployments/${data[0]}/rootfs/etc ro false ||
2023-08-14 20:08:38 +02:00
cleanup_and_quit 'Failed to unlock root to write etc'
2023-07-31 03:07:34 +02:00
# Write the var image
2024-03-29 17:40:00 +01:00
printf '\e[1;34m-->\e[0m\e[1m Writing var\e[0m\n'
2023-09-18 23:23:24 +02:00
2024-04-29 05:27:34 +02:00
# Extra image from tarball to stdin and receive
tar -xOf $arkdep_dir/cache/${data[0]}.tar.${data[1]} "./${data[0]}-var.img" |
btrfs receive $arkdep_dir/deployments/${data[0]}/rootfs/ ||
cleanup_and_quit 'Failed to receive var'
2024-03-19 08:12:41 +01:00
2024-03-29 17:40:00 +01:00
# Make var writable
btrfs property set -f -ts $arkdep_dir/deployments/${data[0]}/rootfs/var ro false ||
cleanup_and_quit 'Failed to unlock var'
# Lock the root volume again
btrfs property set -f -ts $arkdep_dir/deployments/${data[0]}/rootfs ro true ||
cleanup_and_quit 'Failed to lock root'
# Cleanup var image
rm $arkdep_dir/cache/${data[0]}-var.img
2024-03-19 08:12:41 +01:00
2023-09-16 11:53:45 +02:00
# Add overlay if enabled
if [[ $enable_overlay -eq 1 ]]; then
2024-02-29 10:05:05 +01:00
2024-02-29 20:19:39 +01:00
# If backup_user_accounts is enabled automatically perform a backup, do not run if custom root is defined
if [[ $backup_user_accounts -eq 1 ]] && [[ ! -n $ARKDEP_ROOT ]]; then
2024-02-29 10:05:05 +01:00
2024-02-29 10:40:46 +01:00
printf '\e[1;34m-->\e[0m\e[1m Copying user account files to overlay if changed\e[0m\n'
2024-02-29 10:18:43 +01:00
2024-02-29 10:05:05 +01:00
for file in passwd shadow group; do
if ! cmp --silent $arkdep_dir/overlay/etc/$file /etc/$file; then
2024-02-29 10:18:43 +01:00
cp -v /etc/$file $arkdep_dir/overlay/etc/$file
2024-02-29 10:05:05 +01:00
fi
done
# Ensure shadow file permissions are set properly
2024-02-29 10:39:39 +01:00
chmod 600 $arkdep_dir/overlay/etc/shadow
2024-02-29 10:05:05 +01:00
fi
2023-12-11 22:11:25 +01:00
printf '\e[1;34m-->\e[0m\e[1m Copying overlay to deployment\e[0m\n'
2023-10-23 20:02:44 +00:00
declare -r overlay_files=($(ls $arkdep_dir/overlay/))
2023-09-16 11:53:45 +02:00
# Check if only /etc is present, if it is we do not have to unlock the root volume
for file in ${overlay_files[*]}; do
2024-03-24 17:19:01 +01:00
if [[ $file != 'etc' ]]; then
2024-04-29 06:10:23 +02:00
printf "\e[1;33m<!>\e[0m\e[1m Non /etc file or directory detected, root will be temporarily unlocked\e[0m\n"
2023-09-16 11:53:45 +02:00
overlay_unlock_root=1
fi
done
# Unlock root if required
if [[ $overlay_unlock_root -eq 1 ]]; then
2024-03-24 17:15:43 +01:00
btrfs property set -f -ts $arkdep_dir/deployments/${data[0]}/rootfs ro false
2023-09-16 11:53:45 +02:00
fi
2024-02-29 10:33:41 +01:00
cp -rv $arkdep_dir/overlay/* $arkdep_dir/deployments/${data[0]}/rootfs/
2023-09-16 11:53:45 +02:00
# Lock root again if required
if [[ $overlay_unlock_root -eq 1 ]]; then
2024-03-24 17:15:43 +01:00
btrfs property set -f -ts $arkdep_dir/deployments/${data[0]}/rootfs ro true
2023-09-16 11:53:45 +02:00
fi
fi
2024-03-29 17:40:00 +01:00
# Migrate specified files and directories
2024-03-29 21:15:50 +01:00
if [[ ${#var_migrate_files[@]} -ge 1 ]] && [[ ! -n $ARKDEP_ROOT ]]; then
2024-03-29 17:40:00 +01:00
printf '\e[1;34m-->\e[0m\e[1m Migrating local files to new deployment\e[0m\n'
for file in ${var_migrate_files[@]}; do
2024-04-29 05:03:08 +02:00
printf "Copying /var$file\n"
2024-03-30 01:49:44 +01:00
cp -r /var/$file $arkdep_dir/deployments/${data[0]}/rootfs/var/${file%/*}
2024-03-29 17:40:00 +01:00
done
fi
2024-04-27 03:51:38 +02:00
printf '\e[1;34m-->\e[0m\e[1m Installing kernel image to boot\e[0m\n'
2023-12-11 21:49:41 +01:00
# Get list of all available kernels
kernels_installed=($(ls $arkdep_dir/deployments/${data[0]}/rootfs/usr/lib/modules/))
2024-04-27 03:51:38 +02:00
mkdir -p $arkdep_boot/arkdep/${data[0]}
2023-12-11 21:49:41 +01:00
# Deploy kernel to /boot, deploy first hit of kernels_installed
2024-04-27 03:51:38 +02:00
printf "Copying ${kernels_installed[0]}/vmlinuz\n"
cp $arkdep_dir/deployments/${data[0]}/rootfs/usr/lib/modules/${kernels_installed[0]}/vmlinuz $arkdep_boot/arkdep/${data[0]}/ ||
2023-09-14 19:31:19 +02:00
cleanup_and_quit 'Failed to copy kernel image'
2024-02-24 13:33:57 +01:00
# Deploy CPU firmware to boot
if [[ $update_cpu_microcode -eq 1 ]]; then
printf '\e[1;34m-->\e[0m\e[1m Checking for CPU microcode updates\e[0m\n'
for ucode in $(ls $arkdep_dir/deployments/${data[0]}/rootfs/usr/lib/ | grep ucode); do
# If CPU firmware present in both image and install
2024-02-29 10:33:41 +01:00
if ! cmp --silent $arkdep_boot/$ucode $arkdep_dir/deployments/${data[0]}/rootfs/usr/lib/$ucode; then
2024-04-27 03:51:38 +02:00
printf "Copying $ucode\n"
cp $arkdep_dir/deployments/${data[0]}/rootfs/usr/lib/$ucode $arkdep_boot/$ucode ||
2024-02-28 19:15:04 +01:00
cleanup_and_quit 'Failed to copy microcode'
2024-02-24 13:33:57 +01:00
fi
done
fi
2023-09-11 18:57:30 +02:00
# Install kernel and generate initramfs
2023-12-11 22:11:25 +01:00
printf '\e[1;34m-->\e[0m\e[1m Generating initramfs\e[0m\n'
2024-02-29 10:33:41 +01:00
dracut -q -k $arkdep_dir/deployments/${data[0]}/rootfs/usr/lib/modules/${kernels_installed[0]} \
2024-02-29 19:09:24 +01:00
-c $arkdep_dir/deployments/${data[0]}/rootfs/etc/dracut.conf \
--confdir $arkdep_dir/deployments/${data[0]}/rootfs/etc/dracut.conf.d \
2024-02-29 10:33:41 +01:00
--kernel-image $arkdep_boot/arkdep/${data[0]}/vmlinuz \
2023-12-11 21:49:41 +01:00
--kver ${kernels_installed[0]} \
2023-09-14 19:10:20 +02:00
--force \
2024-02-29 10:33:41 +01:00
$arkdep_boot/arkdep/${data[0]}/initramfs-linux.img || cleanup_and_quit 'Failed to generate initramfs'
2023-09-11 18:57:30 +02:00
2024-04-03 21:16:07 +02:00
if [[ $load_extensions -eq 1 ]]; then
printf '\e[1;34m-->\e[0m\e[1m Running extensions\e[0m\n'
extensions=($(ls $arkdep_dir/extensions/))
for extension in ${extensions[@]}; do
(source $arkdep_dir/extensions/$extension)
done
fi
2023-08-25 00:15:23 +02:00
# Add to database
2023-12-11 22:11:25 +01:00
printf '\e[1;34m-->\e[0m\e[1m Updating database\e[0m\n'
2023-11-25 02:27:04 +00:00
printf "${data[0]}\n$(cat $(readlink -m $arkdep_dir/tracker))" |
2024-03-31 21:50:37 +02:00
tee $arkdep_dir/tracker_tmp
mv $arkdep_dir/tracker_tmp $arkdep_dir/tracker
2023-08-25 00:15:23 +02:00
2023-08-27 02:07:37 +02:00
# Deploy bootloader configuration
2023-12-09 18:53:22 +01:00
# also insert newline
2023-12-11 22:11:25 +01:00
printf '\n\e[1;34m-->\e[0m\e[1m Adding bootloader entry\e[0m\n'
2024-02-29 10:33:41 +01:00
sed "s/%target%/${data[0]}/" $arkdep_dir/templates/systemd-boot > $arkdep_boot/loader/entries/${data[0]}.conf
2023-08-27 02:07:37 +02:00
2023-12-31 19:10:19 +01:00
# Set new deployment as default bootloader entry
2023-12-11 22:11:25 +01:00
printf '\e[1;34m-->\e[0m\e[1m Setting new bootloader entry as default\e[0m\n'
2024-02-26 17:32:26 +01:00
# Do not set default boot entry if ARKDEP_NO_BOOTCTL is set
if [[ ! $ARKDEP_NO_BOOTCTL -eq 1 ]]; then
bootctl set-default ${data[0]}.conf || cleanup_and_quit "Failed to set default bootloader entry"
else
printf '\e[1;33m<!>\e[0m\e[1m Not running bootctl set-default because overwritten with ARKDEP_NO_BOOTCTL\e[0m\n'
fi
2023-08-27 02:07:37 +02:00
2024-04-18 12:15:22 +02:00
# Image deployment finished, allow for interupts again
trap 'echo "User interupt received, canceling cleanup step"; exit 4' INT TERM
2024-04-29 06:59:20 +02:00
# Remove tarball if configured to remove
if [[ $remove_tar_after_deployment -eq 1 ]]; then
printf '\e[1;34m-->\e[0m\e[1m Removing tarball from cache\e[0m\n'
2024-05-01 00:38:36 +02:00
rm $arkdep_dir/cache/${data[0]}.tar.*
2024-04-29 06:59:20 +02:00
fi
2023-08-25 00:15:23 +02:00
# Remove entries outside of keep
2023-11-02 20:24:23 +00:00
declare -r remove_deployments=($(tail -n +$deploy_keep $arkdep_dir/tracker))
2023-08-25 00:15:23 +02:00
# Remove old deployments
2024-03-31 21:50:37 +02:00
if [[ ${#remove_deployments[@]} -ge 1 ]]; then
printf '\e[1;34m-->\e[0m\e[1m Cleaning up old deployments\e[0m\n'
declare -r remove_no_quit=1
remove_deployment ${remove_deployments[@]}
fi
2023-08-27 02:07:37 +02:00
2023-11-15 21:21:16 +00:00
exit 0
2023-07-05 01:44:37 +02:00
}
2024-02-25 07:22:17 +01:00
[[ $1 == 'init' ]] && init $2
2023-07-05 01:44:37 +02:00
[[ $1 == 'teardown' ]] && teardown
2023-07-22 18:15:44 +02:00
[[ $1 == 'get-available' ]] && get_available
2023-11-18 08:43:35 +00:00
[[ $1 == 'deploy' ]] && deploy $2 $3
2024-03-31 21:50:37 +02:00
[[ $1 == 'remove' ]] && remove_deployment $@
2023-12-31 16:47:53 +01:00
[[ $1 == 'healthcheck' ]] && healthcheck $1
2024-03-08 22:12:03 +01:00
[[ $1 == 'cleanup' ]] && cleanup
2023-12-31 16:47:53 +01:00
# No valid params were provided
2024-03-31 14:31:58 +02:00
printf '\e[1;31m<#>\e[0m\e[1m No valid parameters provided\e[0m\n'
2023-12-31 16:47:53 +01:00
exit 3