113 lines
4.0 KiB
Bash
Executable File
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'
|