coreos-home-server/host/base/service/coreos-home-server-update
Alex Palaistras 84a17f6df3 Support same-name directories in CoreOS update
This commit extends our `coreos-home-server-update` script with support
for updating host directories with configuration collected across
multiple remote directories of the same name. This will, essentially,
allow for extending systemd services with custom configuration, as
sometimes required of base systemd service files.
2022-09-19 13:02:29 +01:00

90 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Hook for updating local configuration on each pull. This will automatically put files in their
# right places, but will not enable or start any services automatically; this is left to the user.
#
# Move this to '.git/hooks/post-merge' to have to run automatically after every 'git pull' operation.
# The script assumes write access to host directories, and a CoreOS host. Don't run on other systems!
set -euo pipefail
shopt -s globstar
# Global configuration variables.
TEMP_CONFIG_PATH="$(git -C "$(dirname "$0")" rev-parse --show-toplevel)"
HOST_CONFIG_PATH="/etc/coreos-home-server"
SYSTEMD_CONFIG_PATH="/etc/systemd/system"
# Synchronize CoreOS home-server configuration for specific path.
function sync-coreos-config() {
local hostdir="$1"
local dirname="$(basename "$hostdir")"
# Check if any remote configuration exists for the name given.
if ! compgen -G "$TEMP_CONFIG_PATH"/*/"$dirname" > /dev/null; then
printf "configuration not found, skipping.\n"
return
fi
# Collect remote configuration files across base directories.
for tmpdir in "$TEMP_CONFIG_PATH"/*/"$dirname"; do
# Update timestamp for temporary file to match last commit time, in order to ensure correct partial updates.
for f in "$tmpdir/"**; do
# Skip directories, as updating their commit times will have all files within be synchronized.
if test -d "$f"; then
continue
fi
touch -t "$(cd "$tmpdir" && git log -n 1 --pretty=format:%cd --date=format-local:%Y%m%d%H%M.%S --date-order -- "$f")" -- "$f"
done
# Link source files into temporary destination directory.
mkdir --parents "$TEMP_CONFIG_PATH/.tmp/$dirname"
cp --archive --force --target-directory "$TEMP_CONFIG_PATH/.tmp/$dirname" "$tmpdir"/.
done
# Remove files that only exist in local configuration.
for f in $(comm -23 <(cd "$hostdir"; find . | sort) <(cd "$TEMP_CONFIG_PATH/.tmp/$dirname"; find . | sort)); do
# Don't delete environment files, as these are required for active services.
if test "$(basename --suffix=.env "$f")" != "$(basename "$f")"; then
continue
fi
rm --verbose --recursive --force "$(realpath --quiet "$hostdir/$f")"
done
# Copy files from temporary directory to host configuration directory.
cp --verbose --recursive --update --target-directory "$hostdir" "$TEMP_CONFIG_PATH/.tmp/$dirname"/*
printf "done.\n"
}
# Synchronize systemd service files from CoreOS home-server configuration.
function sync-systemd-services() {
local buffer="" tmp
# Copy service files if newer than destination.
for src in "$HOST_CONFIG_PATH"/*/systemd/*; do
tmp="$(cp --verbose --recursive --update --target-directory "$SYSTEMD_CONFIG_PATH" "$src")"
if test -n "$tmp"; then buffer="${buffer}"$'\n'"${tmp}"; fi
done
printf "%s\ndone.\n" "$buffer"
if test -n "$buffer"; then return 0; else return 1; fi
}
# Synchronize all existing CoreOS home-server configuration.
for hostdir in "$HOST_CONFIG_PATH"/*; do
if test ! -d "$hostdir"; then
continue
fi
printf "Synchronizing host configuration for '%s'... " "$hostdir"
sync-coreos-config "$hostdir"
done
# Synchronize systemd services from local CoreOS home-server configuration.
printf "Synchronizing systemd service files... "
if sync-systemd-services; then
printf "Reloading systemd daemon after service updates...\n"
systemctl daemon-reload
fi