istoreos/package/diy/maple-upgrade/files/maple-upgrade.sh
xiexiaobao d1f08269c6 feat: add maple-upgrade + maple-restore for sysupgrade auto-config save/restore
maple-upgrade (/sbin/maple-upgrade):
  - Backup 21 critical configs to p4 (/mnt/mmc2-4/.maple-backup/)
  - Then sysupgrade -n (skip broken backup/restore flow)
  - Supports -b (backup-only), --no-backup (direct flash), -h

maple-restore (/etc/uci-defaults/99-maple-restore):
  - Auto-restores configs from p4 on first boot after upgrade
  - Restores: shadow, openclash, frpc, firewall, network, dhcp,
    fstab, dropbear, transmission, aria2, tailscale, dockerd, etc.
  - Restarts services (frpc, openclash, cron, dropbear)
  - Runs once via uci-defaults, then self-deletes

Fixes the long-standing issue: sysupgrade without -n hangs due to
0-byte tgz backup + stage2 ubus deadlock. With maple-upgrade:
config is safely backed up to p4 (survives reflash), then -n flash
works perfectly, and config is restored automatically.
2026-07-08 10:19:03 +08:00

123 lines
2.8 KiB
Bash

#!/bin/sh
# /sbin/maple-upgrade - MapleOS firmware upgrade with auto-config backup
#
# Usage:
# maple-upgrade <firmware.img.gz> Backup configs then sysupgrade -n
# maple-upgrade -b Backup-only mode (no flash)
# maple-upgrade --no-backup <file> Direct sysupgrade -n (skip backup)
# maple-upgrade -h Show help
BACKUP_DIR="/mnt/mmc2-4/.maple-backup"
BACKUP_LIST="
/etc/shadow
/etc/config/dropbear
/etc/config/openclash
/etc/config/firewall
/etc/config/frpc
/etc/config/dhcp
/etc/config/fstab
/etc/config/network
/etc/config/luci
/etc/config/system
/etc/config/uhttpd
/etc/config/tinyproxy
/etc/config/nlbwmon
/etc/config/aria2
/etc/config/hd-idle
/etc/config/transmission
/etc/config/ttyd
/etc/config/tailscale
/etc/config/dockerd
/etc/config/upnpd
/etc/crontabs/root
"
SERVICES_RESTORE="frpc openclash cron dropbear"
log() {
echo "[maple-upgrade] $*"
}
die() {
echo "[maple-upgrade] ERROR: $*" >&2
exit 1
}
show_help() {
cat <<'EOF'
MapleOS firmware upgrade with auto-config backup to p4
Usage:
maple-upgrade <firmware.img.gz> Back up configs, then sysupgrade -n
maple-upgrade -b Backup only, do not flash
maple-upgrade --no-backup <file> Skip backup, direct sysupgrade -n
maple-upgrade -h Show this help
Backups stored in /mnt/mmc2-4/.maple-backup/
Auto-restored by maple-restore (uci-defaults) on first boot after upgrade.
EOF
}
backup_configs() {
local count=0
# Ensure backup directory on p4
if ! mountpoint -q /mnt/mmc2-4 2>/dev/null; then
# p4 might not be mounted yet; try to mount it
mkdir -p /mnt/mmc2-4 2>/dev/null
mount /dev/mmcblk2p4 /mnt/mmc2-4 2>/dev/null || {
die "Cannot mount p4 (/dev/mmcblk2p4) for backup. Is the partition table set up?"
}
fi
mkdir -p "$BACKUP_DIR" || die "Cannot create $BACKUP_DIR"
# Remove old backup
rm -rf "${BACKUP_DIR:?}"/*
log "Backing up configs to $BACKUP_DIR ..."
for f in $BACKUP_LIST; do
if [ -f "$f" ]; then
dir="$BACKUP_DIR$(dirname "$f")"
mkdir -p "$dir" 2>/dev/null
cp -a "$f" "${BACKUP_DIR}${f}" 2>/dev/null && count=$((count + 1))
fi
done
log "Backed up $count files."
[ "$count" -gt 0 ] || die "No config files were backed up!"
}
# ---- Main ----
case "${1:-}" in
-h|--help)
show_help
exit 0
;;
-b|--backup)
backup_configs
log "Backup complete. Run 'maple-upgrade <firmware>' to upgrade."
exit 0
;;
--no-backup)
[ -n "$2" ] || die "Missing firmware file. Usage: maple-upgrade --no-backup <firmware.img.gz>"
shift
log "Skipping backup, running sysupgrade -n on $1 ..."
sysupgrade -n "$1"
;;
"")
show_help
exit 1
;;
*)
FIRMWARE="$1"
[ -f "$FIRMWARE" ] || die "Firmware file not found: $FIRMWARE"
backup_configs
log "Backup done. Running sysupgrade -n ..."
sysupgrade -n "$FIRMWARE"
;;
esac