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.
This commit is contained in:
parent
981e49c6f8
commit
d1f08269c6
48
package/diy/maple-restore/Makefile
Normal file
48
package/diy/maple-restore/Makefile
Normal file
@ -0,0 +1,48 @@
|
||||
#
|
||||
# Copyright (C) 2026 xiexiaobao
|
||||
#
|
||||
# This is free software, licensed under the GPL 2.0 license.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=maple-restore
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_MAINTAINER:=xiexiaobao
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/maple-restore
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=Auto-restore configs from p4 after MapleOS sysupgrade
|
||||
PKGARCH:=all
|
||||
DEPENDS:=
|
||||
endef
|
||||
|
||||
define Package/maple-restore/description
|
||||
UCI defaults script that auto-restores backed-up configs from
|
||||
/mnt/mmc2-4/.maple-backup/ on first boot after a maple-upgrade.
|
||||
|
||||
Restores: shadow, frpc, openclash, firewall, network, dhcp, fstab,
|
||||
dropbear, luci, system, uhttpd, transmission, aria2, tinyproxy,
|
||||
tailscale, dockerd, crontab, and more.
|
||||
|
||||
Runs exactly once via uci-defaults, then self-deletes.
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/maple-restore/install
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(INSTALL_BIN) ./files/99-maple-restore.sh $(1)/etc/uci-defaults/99-maple-restore
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,maple-restore))
|
||||
52
package/diy/maple-restore/files/99-maple-restore.sh
Normal file
52
package/diy/maple-restore/files/99-maple-restore.sh
Normal file
@ -0,0 +1,52 @@
|
||||
#!/bin/sh
|
||||
# /etc/uci-defaults/99-maple-restore
|
||||
# Auto-restore configs from p4 after MapleOS sysupgrade.
|
||||
# Runs once on first boot, then deleted by uci-defaults.
|
||||
|
||||
BACKUP_DIR="/mnt/mmc2-4/.maple-backup"
|
||||
DONE_FILE="/etc/maple-restore.done"
|
||||
|
||||
# Guard: only run once
|
||||
[ -f "$DONE_FILE" ] && exit 0
|
||||
|
||||
# Guard: backup must exist
|
||||
if [ ! -d "$BACKUP_DIR" ]; then
|
||||
logger -t "maple-restore" "No backup found at $BACKUP_DIR, skipping"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Count files to restore
|
||||
RESTORED=0
|
||||
for f in $(cd "$BACKUP_DIR" && find . -type f 2>/dev/null); do
|
||||
src="${BACKUP_DIR}/${f}"
|
||||
dst="/${f}"
|
||||
|
||||
# Skip if destination exists and is identical
|
||||
[ -f "$dst" ] && cmp -s "$src" "$dst" && continue
|
||||
|
||||
dst_dir=$(dirname "$dst")
|
||||
mkdir -p "$dst_dir" 2>/dev/null
|
||||
|
||||
# For shadow, preserve original permissions
|
||||
if [ "$dst" = "/etc/shadow" ]; then
|
||||
cp -a "$src" "$dst" 2>/dev/null && chmod 0640 "$dst" 2>/dev/null
|
||||
else
|
||||
cp -a "$src" "$dst" 2>/dev/null
|
||||
fi
|
||||
|
||||
RESTORED=$((RESTORED + 1))
|
||||
done
|
||||
|
||||
logger -t "maple-restore" "Restored $RESTORED config files from p4 backup"
|
||||
|
||||
# Restart services to pick up restored configs
|
||||
for svc in frpc openclash cron dropbear; do
|
||||
if [ -x "/etc/init.d/$svc" ]; then
|
||||
/etc/init.d/$svc restart 2>/dev/null
|
||||
logger -t "maple-restore" "Restarted $svc"
|
||||
fi
|
||||
done
|
||||
|
||||
# Mark done
|
||||
touch "$DONE_FILE"
|
||||
exit 0
|
||||
50
package/diy/maple-upgrade/Makefile
Normal file
50
package/diy/maple-upgrade/Makefile
Normal file
@ -0,0 +1,50 @@
|
||||
#
|
||||
# Copyright (C) 2026 xiexiaobao
|
||||
#
|
||||
# This is free software, licensed under the GPL 2.0 license.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=maple-upgrade
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_MAINTAINER:=xiexiaobao
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/maple-upgrade
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=MapleOS firmware upgrade with auto-config backup
|
||||
PKGARCH:=all
|
||||
DEPENDS:=
|
||||
endef
|
||||
|
||||
define Package/maple-upgrade/description
|
||||
Safely upgrade MapleOS firmware with automatic config backup to p4.
|
||||
|
||||
Usage:
|
||||
maple-upgrade <firmware.img.gz> Back up 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
|
||||
|
||||
Backups go to /mnt/mmc2-4/.maple-backup/ and are auto-restored
|
||||
by maple-restore on next boot.
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/maple-upgrade/install
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(INSTALL_BIN) ./files/maple-upgrade.sh $(1)/sbin/maple-upgrade
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,maple-upgrade))
|
||||
122
package/diy/maple-upgrade/files/maple-upgrade.sh
Normal file
122
package/diy/maple-upgrade/files/maple-upgrade.sh
Normal file
@ -0,0 +1,122 @@
|
||||
#!/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
|
||||
@ -208,6 +208,10 @@ CONFIG_PACKAGE_openssh-sftp-server=y
|
||||
# Custom branding
|
||||
CONFIG_PACKAGE_branding=y
|
||||
|
||||
# MapleOS auto-config backup/restore (sysupgrade)
|
||||
CONFIG_PACKAGE_maple-upgrade=y
|
||||
CONFIG_PACKAGE_maple-restore=y
|
||||
|
||||
# Rockchip hardware acceleration
|
||||
CONFIG_PACKAGE_kmod-rk_vcodec=y
|
||||
CONFIG_PACKAGE_kmod-rga3=y
|
||||
|
||||
Loading…
Reference in New Issue
Block a user