#!/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 path="$1" # Search for configuration in any of the local configuration sub-directories. for dir in "$TEMP_CONFIG_PATH"/config/*/"$(basename "$path")"; do if test ! -d "$dir"; then printf "configuration not found, skipping\n" return fi # Remove files that only exist in local configuration. for f in $(comm -23 <(cd "$path"; find . | sort) <(cd "$dir"; 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 "$path/$f")" done # Update timestamp for temporary file to match last commit time, in order to ensure # correct partial updates. for f in "$dir/"**; 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 "$dir" && git log -n 1 --pretty=format:%cd --date=format-local:%Y%m%d%H%M.%S --date-order -- "$f")" -- "$f" done # Copy files from temporary directory to host configuration directory. cp --verbose --recursive --update --target-directory "$path" "$dir"/* printf "done\n" done } # 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")" buffer="${buffer}${tmp}" done printf "%sdone\n" "$buffer" if test -n "$buffer"; then return 0; else return 1; fi } # Synchronize all existing CoreOS home-server configuration. for dir in "$HOST_CONFIG_PATH"/*; do if test ! -d "$dir"; then continue fi printf "Synchronizing host configuration for '%s'... " "$dir" sync-coreos-config "$dir" 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