update 2025-05-15 20:44:23

This commit is contained in:
kenzok8 2025-05-15 20:44:23 +08:00
parent bbb3464a1d
commit fc1910ae82
4 changed files with 210 additions and 16 deletions

View File

@ -11,13 +11,13 @@ LUCI_DEPENDS:=+curl +opkg +luci-base +tar +libuci-lua +mount-utils +luci-lib-tas
LUCI_EXTRA_DEPENDS:=luci-lib-taskd (>=1.0.19)
LUCI_PKGARCH:=all
PKG_VERSION:=0.1.27-4
PKG_VERSION:=0.1.28-2
# PKG_RELEASE MUST be empty for luci.mk
PKG_RELEASE:=
ISTORE_UI_VERSION:=0.1.27
ISTORE_UI_RELEASE:=2
PKG_HASH:=7fb8e9983dd33b14c43de3caf6a6121df0727e0adac6c666354e0d8a0cffa0b8
ISTORE_UI_VERSION:=0.1.28
ISTORE_UI_RELEASE:=1
PKG_HASH:=c45d7552a4c52fdd2f5a2a9bbc94d14a66c5af187ef8a117a3e08b6a9a4b7dbf
PKG_SOURCE_URL_FILE:=v$(ISTORE_UI_VERSION)-$(ISTORE_UI_RELEASE).tar.gz
PKG_SOURCE:=istore-ui-$(PKG_SOURCE_URL_FILE)

View File

@ -2,6 +2,7 @@ module("luci.controller.store", package.seeall)
local myopkg = "is-opkg"
local is_backup = "/usr/libexec/istore/backup"
local is_overlay_backup = "/usr/libexec/istore/overlay-backup"
local page_index = {"admin", "store", "pages"}
function index()
@ -44,16 +45,18 @@ function index()
store_api(action, false)
end
-- backup
-- istore backup
if nixio.fs.access("/usr/libexec/istore/backup") then
entry({"admin", "store", "get_support_backup_features"}, call("get_support_backup_features"))
entry({"admin", "store", "light_backup"}, post("light_backup"))
entry({"admin", "store", "get_light_backup_file"}, call("get_light_backup_file"))
entry({"admin", "store", "local_backup"}, post("local_backup"))
entry({"admin", "store", "light_restore"}, post("light_restore"))
entry({"admin", "store", "local_restore"}, post("local_restore"))
entry({"admin", "store", "get_backup_app_list_file_path"}, call("get_backup_app_list_file_path"))
entry({"admin", "store", "get_backup_app_list"}, call("get_backup_app_list"))
end
if nixio.fs.access("/usr/libexec/istore/backup") or nixio.fs.access("/usr/libexec/istore/overlay-backup") then
entry({"admin", "store", "local_backup"}, post("local_backup"))
entry({"admin", "store", "local_restore"}, post("local_restore"))
entry({"admin", "store", "get_available_backup_file_list"}, call("get_available_backup_file_list"))
entry({"admin", "store", "set_local_backup_dir_path"}, post("set_local_backup_dir_path"))
entry({"admin", "store", "get_local_backup_dir_path"}, call("get_local_backup_dir_path"))
@ -160,6 +163,9 @@ function store_index()
if fs.access("/usr/libexec/istore/backup") then
features[#features+1] = "backup"
end
if luci.sys.call(is_overlay_backup .. " supports_overlay_backup >/dev/null 2>&1") == 0 then
features[#features+1] = "overlay"
end
if luci.sys.call("which docker >/dev/null 2>&1") == 0 then
features[#features+1] = "docker"
end
@ -682,18 +688,27 @@ function local_backup()
local code, out, err, ret
local error_ret
local path = luci.http.formvalue("path")
local type = luci.http.formvalue("type") or "istore"
if path ~= "" then
-- judge path
local fs = require "nixio.fs"
fs.mkdirr(path)
code,out,err = is_exec("findmnt -T " .. path .. " -o TARGET|sed -n 2p")
if out:gsub("[\r\n]", "") == "/" or out:gsub("[\r\n]", "") == "/tmp" then
local mp = out:gsub("[\r\n]", "")
if mp == "/" or mp == "/tmp" then
-- error
error_ret = {code = 500, stderr = "Path Error,Can not be / or tmp."}
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
luci.http.write_json(error_ret)
elseif type == "overlay" and ( mp == "/overlay" or mp == "/ext_overlay" ) then
-- error
error_ret = {code = 500, stderr = "Path Error,Can not be /overlay or /ext_overlay."}
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
else
-- update local backup path
update_local_backup_path(path)
code,out,err = _action(is_backup, "backup", path)
code,out,err = _action(type == "overlay" and is_overlay_backup or is_backup, "backup", path)
ret = {
code = code,
stdout = out,
@ -761,9 +776,10 @@ end
-- post local_restore
function local_restore()
local path = luci.http.formvalue("path")
local type = luci.http.formvalue("type") or "istore"
local code, out, err, ret
if path ~= "" then
code,out,err = _action(is_backup, "restore", path)
code,out,err = _action(type == "overlay" and is_overlay_backup or is_backup, "restore", path)
ret = {
code = code,
stdout = out,
@ -821,12 +837,13 @@ function get_available_backup_file_list()
local error_ret = {code = 500, msg = "Unknown"}
local success_ret = {code = 200,msg = "Unknown"}
local path = luci.http.formvalue("path")
local type = luci.http.formvalue("type") or "istore"
local r,o,e
if path ~= "" then
-- update local backup path
update_local_backup_path(path)
r,o,e = is_exec(is_backup .. " get_available_backup_file_list " .. luci.util.shellquote(path))
r,o,e = is_exec((type == "overlay" and is_overlay_backup or is_backup) .. " get_available_backup_file_list " .. luci.util.shellquote(path))
if r ~= 0 then
error_ret.msg = e
luci.http.prepare_content("application/json")

View File

@ -170,7 +170,7 @@ backup() {
ipk_build ${pkg_name} $BACKUP_PATH/backup_istore_$date
done
# 5. create tar.gz file,and remove fir
# 5. create tar.gz file,and remove dir
cd $BACKUP_PATH
echo "write backup file to $BACKUP_PATH/backup_istore_$date.backup.tar.gz"
tar -czf $BACKUP_PATH/backup_istore_$date.backup.tar.gz backup_istore_$date
@ -246,10 +246,10 @@ get_backup_app_list() {
}
get_available_backup_file_list() {
local backup_file
if [ -n "$1" ]; then
for backup_file in `ls $1/*.backup.tar.gz`; do
filename=${backup_file##*/}
echo "${filename}"
for backup_file in `cd $1 && ls backup_istore_*.backup.tar.gz`; do
echo "${backup_file}"
done
else
echo "input backup path is null"

View File

@ -0,0 +1,177 @@
#!/bin/sh
TMP_SELF_COPY=/var/run/cloned-overlay-backup
action=${1}
shift
has_overlay() {
[ -d "/overlay/upper" ] || return 1
[ "overlay" = "$(/bin/mount | awk '($3 ~ /^\/$/) && ($5 !~ /rootfs/) { print $5 }')" ] || return 1
return 0
}
has_ext_overlay() {
[ -d "/ext_overlay/upper" ] || return 1
grep '^overlayfs:/overlay / ' /proc/mounts | grep -Fq 'upperdir=/ext_overlay/upper' || return 1
return 0
}
backup() {
if ! has_overlay; then
echo "only supports squashfs firmware"
exit 1
fi
if [ -z "$1" ]; then
echo "input backup path is null"
exit 1
fi
local BACKUP_PATH="$1"
if echo "$BACKUP_PATH" | grep -q -e '^/overlay/upper' -e '^/ext_overlay/upper' ; then
echo "can not backup to /overlay/upper, /ext_overlay/upper"
exit 1
fi
if [ ! -d "${BACKUP_PATH}" ] && ! mkdir -p "${BACKUP_PATH}" ; then
echo "backup path does not exist and can not be create"
exit 1
fi
local realpath="$(cd "${BACKUP_PATH}"; pwd -P)"
if [ -z "$realpath" ]; then
echo "cannot get absolute path of ${BACKUP_PATH}"
exit 1
fi
local mountpoint=$(findmnt -T $realpath -o TARGET | sed -n 2p)
# while read -r; do
# if [[ "x$realpath" == "x$REPLY" || "x${realpath#$REPLY/}" != "x$realpath" ]]; then
# mountpoint="$REPLY"
# break
# fi
# done < <(
# cat /proc/mounts | grep -v '^overlay ' | awk 'NR>1 {print $2}' | grep -v '^/$' | \
# sort -u | \
# while read -r; do printf "%b\n" "$REPLY" ; done | \
# awk '{print length, $0}' | sort -nr | cut -d' ' -f2-
# )
if [ "/" = "$mountpoint" ]; then
echo "can not backup to /"
exit 1
else
echo "found mount point $mountpoint"
fi
local tar_extra_args=
if has_ext_overlay; then
tar_extra_args="$tar_extra_args ext_overlay/upper"
fi
local hostname=$(cat /proc/sys/kernel/hostname)
local fwver=$(. /etc/openwrt_release; echo $DISTRIB_ID-$DISTRIB_RELEASE)
local date=$(date +%Y-%m%d-%H%M)
local backup_name="backup_overlay_${hostname}_${fwver}_${date}.overlay.tar.gz"
local backup_full_path="$BACKUP_PATH/$backup_name"
echo "writing backup to $backup_full_path"
if tar -C / -cz overlay/upper $tar_extra_args > "$backup_full_path" ; then
sync "$BACKUP_PATH"
echo "backup success"
return 0
else
rm -f "$backup_full_path"
echo "backup failed"
exit 1
fi
}
restore() {
if ! has_overlay; then
echo "only supports squashfs firmware"
exit 1
fi
if [ -z "$1" ]; then
echo "input backup path is null"
exit 1
fi
local BACKUP_PATH_FILE="$1"
if [ ! -f "${BACKUP_PATH_FILE}" ]; then
echo "invalid backup file, can not restore"
exit 1
fi
local tar_extra_args=
if has_ext_overlay; then
tar_extra_args="$tar_extra_args ext_overlay/upper"
fi
sync /
echo "restoring from ${BACKUP_PATH_FILE}"
if tar -C / -xz overlay/upper $tar_extra_args < "${BACKUP_PATH_FILE}" ; then
sync /overlay /ext_overlay
echo "restore success"
echo "schedule to restart after 5 seconds!"
/etc/init.d/tasks task_add reboot 'reboot -d 5'
return 0
else
echo "restore failed"
exit 1
fi
}
supports_overlay_backup() {
has_overlay || return 1
echo "overlay"
has_ext_overlay && echo "ext_overlay"
return 0
}
get_backup_file_list() {
local backup_file
if [ -n "$1" ]; then
for backup_file in `cd $1 && ls backup_overlay_*.overlay.tar.gz`; do
echo "${backup_file}"
done
else
echo "input backup path is null"
exit 1
fi
}
usage() {
echo "usage: overlay-backup sub-command [arguments...]"
echo "where sub-command is one of:"
echo " backup [dir] Backup all installed package(s) to [directory]"
echo " restore [dir] Restore package(s) by [directory]"
echo " supports_overlay_backup check system supports overlay backup"
echo " get_backup_file_list [dir] get local available backup file list in [dir]"
}
case $action in
"supports_overlay_backup")
supports_overlay_backup
;;
"backup")
backup "$@"
;;
"restore")
if [ "$0" = "$TMP_SELF_COPY" ]; then
restore "$@"
else
echo "copy self $0 to $TMP_SELF_COPY when restore"
cp -af "$0" "$TMP_SELF_COPY"
exec "$TMP_SELF_COPY" restore "$@"
fi
;;
"get_available_backup_file_list")
get_backup_file_list "$@"
;;
*)
usage
;;
esac