secubox-openwrt/package/secubox/luci-app-backup/root/usr/libexec/rpcd/luci.backup
CyberMind-FR 04d61baa6f fix(rpcd): Remove local keyword from backup/mailserver handlers
POSIX shell doesn't allow 'local' outside functions.
Fixed for busybox/ash compatibility.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 10:48:25 +01:00

236 lines
5.5 KiB
Bash

#!/bin/sh
# SecuBox Backup Manager RPCD Handler
. /usr/share/libubox/jshn.sh
BACKUP_CMD="/usr/sbin/secubox-backup"
case "$1" in
list)
cat <<-EOF
{
"status": {},
"list": { "type": "string" },
"container_list": {},
"create": { "type": "string" },
"restore": { "file": "string", "dry_run": "boolean" },
"cleanup": {},
"container_backup": { "name": "string" },
"container_restore": { "name": "string", "file": "string" }
}
EOF
;;
call)
case "$2" in
status)
json_init
# Get storage info
storage=$($BACKUP_CMD status 2>/dev/null | grep "Storage Path" | cut -d: -f2 | tr -d ' ')
used=$($BACKUP_CMD status 2>/dev/null | grep "Storage Used" | cut -d: -f2 | tr -d ' ')
json_add_string "storage_path" "${storage:-/srv/backups}"
json_add_string "storage_used" "${used:-0}"
# Last backup times
json_add_object "last_backup"
for type in config containers services; do
latest=$(ls -t "${storage:-/srv/backups}/$type/"*.tar* 2>/dev/null | head -1)
if [ -n "$latest" ]; then
bdate=$(stat -c %Y "$latest" 2>/dev/null)
json_add_int "$type" "${bdate:-0}"
else
json_add_int "$type" 0
fi
done
json_close_object
# Container count
containers=$(ls -d /srv/lxc/*/ 2>/dev/null | wc -l)
json_add_int "container_count" "$containers"
json_dump
;;
list)
json_load "$3"
json_get_var type type
type="${type:-all}"
storage=$(uci -q get backup.main.storage_path)
storage="${storage:-/srv/backups}"
json_init
json_add_array "backups"
# List config backups
if [ "$type" = "all" ] || [ "$type" = "config" ]; then
ls "$storage/config/"*.tar* 2>/dev/null | while read f; do
[ -f "$f" ] || continue
json_add_object ""
json_add_string "file" "$(basename "$f")"
json_add_string "type" "config"
json_add_string "size" "$(du -h "$f" 2>/dev/null | cut -f1)"
json_add_int "timestamp" "$(stat -c %Y "$f" 2>/dev/null)"
json_close_object
done
fi
# List container backups
if [ "$type" = "all" ] || [ "$type" = "containers" ]; then
ls "$storage/containers/"*.tar* 2>/dev/null | while read f; do
[ -f "$f" ] || continue
json_add_object ""
json_add_string "file" "$(basename "$f")"
json_add_string "type" "container"
json_add_string "size" "$(du -h "$f" 2>/dev/null | cut -f1)"
json_add_int "timestamp" "$(stat -c %Y "$f" 2>/dev/null)"
json_close_object
done
fi
# List service backups
if [ "$type" = "all" ] || [ "$type" = "services" ]; then
ls "$storage/services/"*.tar* 2>/dev/null | while read f; do
[ -f "$f" ] || continue
json_add_object ""
json_add_string "file" "$(basename "$f")"
json_add_string "type" "service"
json_add_string "size" "$(du -h "$f" 2>/dev/null | cut -f1)"
json_add_int "timestamp" "$(stat -c %Y "$f" 2>/dev/null)"
json_close_object
done
fi
json_close_array
json_dump
;;
container_list)
json_init
json_add_array "containers"
for dir in /srv/lxc/*/; do
[ -d "$dir" ] || continue
name=$(basename "$dir")
[ -f "$dir/config" ] || continue
state="stopped"
lxc-info -n "$name" 2>/dev/null | grep -q "RUNNING" && state="running"
size=$(du -sh "$dir" 2>/dev/null | awk '{print $1}')
# Count backups for this container
storage=$(uci -q get backup.main.storage_path)
storage="${storage:-/srv/backups}"
backup_count=$(ls -1 "$storage/containers/${name}-"*.tar* 2>/dev/null | wc -l)
json_add_object ""
json_add_string "name" "$name"
json_add_string "state" "$state"
json_add_string "size" "$size"
json_add_int "backups" "$backup_count"
json_close_object
done
json_close_array
json_dump
;;
create)
json_load "$3"
json_get_var type type
type="${type:-full}"
result=$($BACKUP_CMD create --$type 2>&1)
rc=$?
json_init
json_add_int "code" "$rc"
json_add_string "output" "$result"
json_dump
;;
restore)
json_load "$3"
json_get_var file file
json_get_var dry_run dry_run
[ -z "$file" ] && {
json_init
json_add_int "code" 1
json_add_string "error" "No file specified"
json_dump
exit 0
}
opts=""
[ "$dry_run" = "1" ] || [ "$dry_run" = "true" ] && opts="--dry-run"
result=$($BACKUP_CMD restore "$file" $opts 2>&1)
rc=$?
json_init
json_add_int "code" "$rc"
json_add_string "output" "$result"
json_dump
;;
cleanup)
result=$($BACKUP_CMD cleanup 2>&1)
rc=$?
json_init
json_add_int "code" "$rc"
json_add_string "output" "$result"
json_dump
;;
container_backup)
json_load "$3"
json_get_var name name
[ -z "$name" ] && {
json_init
json_add_int "code" 1
json_add_string "error" "No container name specified"
json_dump
exit 0
}
result=$($BACKUP_CMD container backup "$name" 2>&1)
rc=$?
json_init
json_add_int "code" "$rc"
json_add_string "output" "$result"
json_dump
;;
container_restore)
json_load "$3"
json_get_var name name
json_get_var file file
[ -z "$name" ] || [ -z "$file" ] && {
json_init
json_add_int "code" 1
json_add_string "error" "Container name and backup file required"
json_dump
exit 0
}
result=$($BACKUP_CMD container restore "$name" "$file" 2>&1)
rc=$?
json_init
json_add_int "code" "$rc"
json_add_string "output" "$result"
json_dump
;;
esac
;;
esac
exit 0