Files
platform-core/scripts/bootstrap/prepare-ssd-local-paths.sh

113 lines
4.0 KiB
Bash
Executable File

#!/usr/bin/env bash
set -Eeuo pipefail
readonly SSD_BASE_PATH="/srv/k3s/ssd"
readonly POSTGRES_PATH="${SSD_BASE_PATH}/platform-postgres"
readonly GITEA_PATH="${SSD_BASE_PATH}/gitea"
readonly DECLARED_CAPACITY_BYTES=$((70 * 1024 * 1024 * 1024))
readonly SUDO_BIN="/usr/bin/sudo"
readonly FINDMNT_BIN="/usr/bin/findmnt"
readonly INSTALL_BIN="/usr/bin/install"
readonly TEST_BIN="/usr/bin/test"
fail() {
printf 'ERROR: %s\n' "$*" >&2
exit 1
}
mount_source_for() {
# The Local PV directories are intentionally root:root 0750. An unprivileged
# findmnt cannot canonicalize a child below /srv/k3s/ssd after that directory
# has been created, so perform the mount lookup with the same privilege that
# creates and owns the paths.
"$SUDO_BIN" -- "$FINDMNT_BIN" --kernel --first-only \
--noheadings --output SOURCE --target "$1"
}
mount_target_for() {
"$SUDO_BIN" -- "$FINDMNT_BIN" --kernel --first-only \
--noheadings --output TARGET --target "$1"
}
sudo_test() {
"$SUDO_BIN" -- "$TEST_BIN" "$@"
}
validate_existing_path_kind() {
local target="$1"
if sudo_test -L "$target"; then
fail "refusing symbolic-link target: ${target}"
fi
if sudo_test -e "$target"; then
sudo_test -d "$target" || \
fail "target exists but is not a directory: ${target}"
return 0
fi
return 1
}
ensure_plain_directory() {
local target="$1"
if validate_existing_path_kind "$target"; then
printf 'Already present; left ownership and mode unchanged: %s\n' "$target"
return 0
fi
"$SUDO_BIN" -- "$INSTALL_BIN" -d -o root -g root -m 0750 -- "$target"
validate_existing_path_kind "$target" || \
fail "post-create target is missing: ${target}"
printf 'Created %s\n' "$target"
}
for required_binary in "$SUDO_BIN" "$FINDMNT_BIN" "$INSTALL_BIN" "$TEST_BIN"; do
[[ -x "$required_binary" ]] || \
fail "required executable is missing: ${required_binary}"
done
for command_name in df tail tr; do
command -v "$command_name" >/dev/null 2>&1 || fail "${command_name} is required"
done
[[ -d /srv ]] || fail "/srv does not exist"
# Authenticate before command substitutions call sudo so a failed or cancelled
# prompt cannot be confused with an empty mount-source result.
printf 'Validating sudo access for SSD path checks...\n'
"$SUDO_BIN" -v || fail "sudo authentication failed"
readonly ROOT_SOURCE="$(mount_source_for /)"
readonly SRV_SOURCE="$(mount_source_for /srv)"
readonly SRV_MOUNT_TARGET="$(mount_target_for /srv)"
[[ -n "$ROOT_SOURCE" ]] || fail "could not identify the root filesystem source"
[[ "$SRV_SOURCE" == "$ROOT_SOURCE" ]] || fail "/srv is not on the root filesystem (${SRV_SOURCE} != ${ROOT_SOURCE})"
[[ "$SRV_MOUNT_TARGET" == "/" ]] || fail "/srv is covered by a separate mount (${SRV_MOUNT_TARGET})"
for target in "$SSD_BASE_PATH" "$POSTGRES_PATH" "$GITEA_PATH"; do
if validate_existing_path_kind "$target"; then
[[ "$(mount_source_for "$target")" == "$ROOT_SOURCE" ]] || fail "${target} is not on the root filesystem"
[[ "$(mount_target_for "$target")" == "/" ]] || fail "${target} is covered by a separate mount"
fi
done
readonly ROOT_AVAILABLE_BYTES="$(df --block-size=1 --output=avail / | tail -n 1 | tr -d '[:space:]')"
if [[ "$ROOT_AVAILABLE_BYTES" =~ ^[0-9]+$ ]] && (( ROOT_AVAILABLE_BYTES < DECLARED_CAPACITY_BYTES )); then
printf 'WARNING: root filesystem has less than 70 GiB free; Local PV capacity is not a quota.\n' >&2
fi
ensure_plain_directory "$SSD_BASE_PATH"
ensure_plain_directory "$POSTGRES_PATH"
ensure_plain_directory "$GITEA_PATH"
for target in "$SSD_BASE_PATH" "$POSTGRES_PATH" "$GITEA_PATH"; do
validate_existing_path_kind "$target" || fail "post-create target is missing: ${target}"
[[ "$(mount_source_for "$target")" == "$ROOT_SOURCE" ]] || fail "post-create filesystem check failed for ${target}"
[[ "$(mount_target_for "$target")" == "/" ]] || fail "post-create mount check failed for ${target}"
done
printf 'SSD Local PV paths are ready on root source %s.\n' "$ROOT_SOURCE"
printf 'No Kubernetes resources were applied.\n'