#!/usr/bin/env bash set -euo pipefail readonly expected_context="kubernetes-admin@kubernetes" readonly node="arschrock" readonly library_path="/mnt/Bilder" readonly ready_label="immich.brunner.ninja/library-ready" readonly selector='app.kubernetes.io/instance=immich,app.kubernetes.io/name in (server,machine-learning)' current_context="$(kubectl config current-context)" if [[ "${current_context}" != "${expected_context}" ]]; then echo "Refusing to modify ${node}: context is ${current_context}, expected ${expected_context}." >&2 exit 1 fi if ! mountpoint -q /mnt; then echo "/mnt is not mounted; Immich remains storage-offline." >&2 exit 1 fi if [[ "$(findmnt -T "${library_path}" -n -o FSTYPE)" != bcachefs ]]; then echo "${library_path} is not backed by bcachefs; Immich remains storage-offline." >&2 exit 1 fi if [[ "$(stat -f -c '%t' "${library_path}")" != ca451a4e ]]; then echo "${library_path} has an unexpected filesystem; Immich remains storage-offline." >&2 exit 1 fi if [[ ! -d "${library_path}/upload" ]]; then echo "${library_path}/upload is missing; Immich remains storage-offline." >&2 exit 1 fi kubectl get node "${node}" >/dev/null if ! kubectl label node "${node}" "${ready_label}-" 2>/dev/null; then labels="$(kubectl get node "${node}" --output=jsonpath='{.metadata.labels}')" if [[ "${labels}" == *"${ready_label}"* ]]; then echo "Could not clear a stale Immich readiness label on ${node}." >&2 exit 1 fi fi # Force a fresh hostPath/local-PV mount after a mount cycle or reboot. mapfile -t pods < <( kubectl --namespace immich get pods \ --selector="${selector}" \ --field-selector="spec.nodeName=${node}" \ --output=name 2>/dev/null || true ) if ((${#pods[@]})); then kubectl --namespace immich delete "${pods[@]}" --wait=false for pod in "${pods[@]}"; do kubectl --namespace immich wait --for=delete "${pod}" --timeout=5m done fi kubectl label node "${node}" "${ready_label}=true" --overwrite echo "${node} is Immich-library-ready; its Immich workloads may now start."