Files
reterminal-dm4/emmc-provisioning/host/run-shrink-on-host.sh

78 lines
2.6 KiB
Bash

#!/usr/bin/env bash
# Run on the Proxmox host when shrink_request.json appears in the provisioning dir.
# Runs PiShrink on the requested backup image (shrink or shrink+compress).
# Requires PiShrink on host (scripts/install-pishrink-on-host.sh). Triggered by cm4-shrink.path.
set -e
PROV_DIR="${CM4_PROVISIONING_DIR:-/var/lib/cm4-provisioning}"
REQUEST_FILE="$PROV_DIR/shrink_request.json"
STATUS_FILE="$PROV_DIR/shrink_status.json"
[[ -f /opt/cm4-provisioning/env ]] && source /opt/cm4-provisioning/env
BACKUPS_DIR="${BACKUPS_DIR:-$PROV_DIR/backups}"
PISHRINK="${PISHRINK_SCRIPT:-/usr/local/bin/pishrink.sh}"
SHRINK_TIMEOUT="${SHRINK_TIMEOUT:-2100}"
write_status() {
local phase="$1" name="$2" message="$3" error="$4"
printf '{"phase":"%s","name":"%s","message":"%s","error":%s,"updated":%s}\n' \
"$phase" "$name" "$message" \
"$([ -n "$error" ] && echo "\"${error//\"/\\\"}\"" || echo "null")" \
"$(date +%s)" > "$STATUS_FILE"
}
[[ -f "$REQUEST_FILE" ]] || { echo "No request file"; exit 0; }
# Parse request
NAME=$(python3 -c "import json; print(json.load(open('$REQUEST_FILE')).get('name',''))")
ACTION=$(python3 -c "import json; print(json.load(open('$REQUEST_FILE')).get('action','shrink'))")
FORMAT=$(python3 -c "import json; print(json.load(open('$REQUEST_FILE')).get('format','xz'))")
rm -f "$REQUEST_FILE"
# Validate
if [[ -z "$NAME" ]]; then
write_status "error" "" "" "Missing name in request"
exit 0
fi
if [[ "$NAME" != "${NAME##*/}" ]] || [[ "$NAME" == *..* ]]; then
write_status "error" "$NAME" "" "Invalid name"
exit 0
fi
if [[ ! "$NAME" =~ \.img$ ]]; then
write_status "error" "$NAME" "" "Only .img files can be shrunk"
exit 0
fi
PATH_FILE="$BACKUPS_DIR/$NAME"
if [[ ! -f "$PATH_FILE" ]]; then
write_status "error" "$NAME" "" "File not found"
exit 0
fi
if [[ ! -x "$PISHRINK" ]]; then
write_status "error" "$NAME" "" "PiShrink not installed on host. Run scripts/install-pishrink-on-host.sh"
exit 0
fi
write_status "running" "$NAME" "Shrinking…" ""
OPTS=(-n)
if [[ "$ACTION" == "compress" ]]; then
if [[ "$FORMAT" == "gz" ]] || [[ "$FORMAT" == "gzip" ]]; then
OPTS+=(-z -a)
else
OPTS+=(-Z -a)
fi
fi
cd "$BACKUPS_DIR" || exit 1
if timeout "$SHRINK_TIMEOUT" "$PISHRINK" "${OPTS[@]}" "$NAME" 2>&1; then
if [[ "$ACTION" == "compress" ]]; then
ext=".xz"
[[ "$FORMAT" == "gz" ]] || [[ "$FORMAT" == "gzip" ]] && ext=".gz"
write_status "done" "$NAME" "Compressed to ${NAME}${ext}" ""
else
write_status "done" "$NAME" "Shrunk $NAME" ""
fi
else
rc=$?
write_status "error" "$NAME" "" "PiShrink failed (exit $rc)"
fi