#!/bin/bash set -euo pipefail CONFIG_FILE="${AUTONAS_CONFIG_FILE:-/etc/pve/autonas/disks.conf}" STORAGE_CFG="${AUTONAS_STORAGE_CFG:-/etc/pve/storage.cfg}" DROPIN_DIR="/etc/systemd/system/nfs-server.service.d" DROPIN_FILE="${DROPIN_DIR}/50-autonas-self-hosted-proxmox.conf" require_root() { if [[ "${EUID}" -ne 0 ]]; then echo "ERROR: this action must be run as root" >&2 exit 1 fi } collect_local_autonas_ips() { [[ -f "${CONFIG_FILE}" ]] || return 0 local -A current_ip_map=() local current_ip="" while IFS= read -r current_ip; do [[ -n "${current_ip}" ]] && current_ip_map["${current_ip}"]=1 done < <(ip -o -4 addr show up scope global | awk '{print $4}' | cut -d/ -f1 | sort -u) [[ "${#current_ip_map[@]}" -gt 0 ]] || return 0 local cfg_ip="" while IFS=: read -r _ _ cfg_ip _ _ _; do [[ -z "${cfg_ip}" || "${cfg_ip}" == "LOCAL" || "${cfg_ip}" == "IMPORT" ]] && continue [[ -n "${current_ip_map[${cfg_ip}]:-}" ]] && echo "${cfg_ip}" done < <(grep -v '^[[:space:]]*#' "${CONFIG_FILE}" || true) } collect_self_hosted_mount_units() { [[ -f "${STORAGE_CFG}" ]] || return 0 local -A local_ip_map=() local ip="" while IFS= read -r ip; do [[ -n "${ip}" ]] && local_ip_map["${ip}"]=1 done < <(collect_local_autonas_ips) [[ "${#local_ip_map[@]}" -gt 0 ]] || return 0 local -A mount_unit_map=() local server="" local path="" local type="" local line="" emit_candidate() { if [[ "${type}" == "nfs" && -n "${server}" && -n "${path}" && -n "${local_ip_map[${server}]:-}" ]]; then mount_unit_map["$(systemd-escape --path --suffix=mount "${path}")"]=1 fi } while IFS= read -r line || [[ -n "${line}" ]]; do if [[ "${line}" =~ ^[[:space:]]*# ]]; then continue fi if [[ "${line}" =~ ^[[:space:]]*$ ]]; then emit_candidate type="" server="" path="" continue fi if [[ ! "${line}" =~ ^[[:space:]] ]]; then emit_candidate type="${line%%:*}" server="" path="" continue fi if [[ "${line}" =~ ^[[:space:]]*server[[:space:]]+(.+)$ ]]; then server="${BASH_REMATCH[1]}" continue fi if [[ "${line}" =~ ^[[:space:]]*path[[:space:]]+(.+)$ ]]; then path="${BASH_REMATCH[1]}" continue fi done < "${STORAGE_CFG}" emit_candidate printf '%s\n' "${!mount_unit_map[@]}" | sort } write_dropin() { local units=("$@") if [[ "${#units[@]}" -eq 0 ]]; then rm -f "${DROPIN_FILE}" rmdir "${DROPIN_DIR}" 2>/dev/null || true return 0 fi mkdir -p "${DROPIN_DIR}" { echo "# Managed by AutoNAS." echo "# Keep self-hosted Proxmox NFS client mounts ordered before nfs-server shutdown." echo "[Unit]" printf 'Before=' printf '%s ' "${units[@]}" printf '\n' } > "${DROPIN_FILE}" } main() { require_root local units=() local unit="" while IFS= read -r unit; do [[ -n "${unit}" ]] && units+=("${unit}") done < <(collect_self_hosted_mount_units) write_dropin "${units[@]}" systemctl daemon-reload } main "$@"