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.
123 lines
2.8 KiB
Bash
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
|