Refine backup validation and manifest details
This commit is contained in:
@@ -355,6 +355,7 @@ if [[ "$LND_AVAILABLE" -eq 1 ]]; then
|
||||
fi
|
||||
|
||||
ESTIMATED_BYTES=$(( ETC_NIXOS_BYTES + HOME_BYTES + SECRETS_BYTES + VAR_LIB_BYTES + LND_BYTES ))
|
||||
# Require 20% growth headroom plus an additional fixed 1 GiB safety margin.
|
||||
REQUIRED_BYTES=$(( ESTIMATED_BYTES + (ESTIMATED_BYTES / 5) + SAFETY_MARGIN_BYTES ))
|
||||
|
||||
FREE_BYTES=$(df -B1 --output=avail "$TARGET" | tail -1 | tr -d ' ')
|
||||
@@ -716,8 +717,6 @@ CHECKSUM_FILE="$BACKUP_DIR/SHA256SUMS.txt"
|
||||
find "$BACKUP_DIR" -mindepth 1 -maxdepth 2 -type f | sort
|
||||
} > "$MANIFEST_FILE"
|
||||
|
||||
ARCHIVE_FILES+=("BACKUP_MANIFEST.txt")
|
||||
|
||||
# ── Generate checksums for all backup artifacts ─────────────────
|
||||
|
||||
log "Generating SHA-256 checksums …"
|
||||
|
||||
@@ -1493,6 +1493,41 @@ def _is_internal_mount(mnt: str) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def _is_supported_backup_fstype(path: str, fstype: str) -> bool:
|
||||
"""Return whether the target filesystem type is supported for manual backup."""
|
||||
fstype = (fstype or "").lower()
|
||||
if fstype == "exfat":
|
||||
return True
|
||||
if fstype != "fuseblk":
|
||||
return False
|
||||
|
||||
src_dev = ""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["findmnt", "-n", "-o", "SOURCE", "-T", path],
|
||||
capture_output=True, text=True, timeout=5,
|
||||
)
|
||||
if result.returncode == 0:
|
||||
src_dev = result.stdout.strip()
|
||||
except Exception:
|
||||
src_dev = ""
|
||||
|
||||
if not src_dev:
|
||||
return False
|
||||
|
||||
for cmd in (
|
||||
["lsblk", "-no", "FSTYPE", src_dev],
|
||||
["blkid", "-o", "value", "-s", "TYPE", src_dev],
|
||||
):
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=5)
|
||||
if result.returncode == 0 and result.stdout.strip().lower() in {"exfat", "fuseblk"}:
|
||||
return True
|
||||
except Exception:
|
||||
continue
|
||||
return False
|
||||
|
||||
|
||||
def _detect_external_drives() -> list[dict]:
|
||||
"""Scan for mounted external USB drives.
|
||||
|
||||
@@ -3746,7 +3781,7 @@ async def api_backup_run(target: str = ""):
|
||||
|
||||
selected_target = selected.get("path", "")
|
||||
selected_fstype = (selected.get("fstype") or "").lower()
|
||||
if selected_fstype and selected_fstype not in {"exfat", "fuseblk"}:
|
||||
if selected_fstype and not _is_supported_backup_fstype(selected_target, selected_fstype):
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"Selected drive filesystem '{selected_fstype}' is not supported for manual backup.",
|
||||
|
||||
Reference in New Issue
Block a user