feat: switch to apk
This commit is contained in:
@@ -1,2 +1,157 @@
|
|||||||
# backup-manager
|
# OpenWrt Backup Manager
|
||||||
|
|
||||||
|
Автономный набор скриптов для бэкапа и восстановления конфигурации и пакетов на OpenWrt.
|
||||||
|
|
||||||
|
## Возможности
|
||||||
|
|
||||||
|
#### Бэкап
|
||||||
|
|
||||||
|
- системных конфигов
|
||||||
|
- пользовательских файлов
|
||||||
|
- списка установленных пакетов (apk)
|
||||||
|
|
||||||
|
#### Восстановление
|
||||||
|
|
||||||
|
- конфигурации через sysupgrade
|
||||||
|
- пакетов из сохранённого списка
|
||||||
|
|
||||||
|
#### Поддержка удалённого хранилища
|
||||||
|
|
||||||
|
- NFS
|
||||||
|
- SMB (CIFS)
|
||||||
|
|
||||||
|
#### Очистка старых бэкапов (локально и удалённо)
|
||||||
|
|
||||||
|
## Структура
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.
|
||||||
|
├── backup-manager.sh # основной скрипт
|
||||||
|
├── backup-configs.sh # сбор конфигураций
|
||||||
|
├── backup-apk.sh # работа с пакетами
|
||||||
|
├── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Настройка
|
||||||
|
|
||||||
|
Отредактируйте переменные в backup-manager.sh:
|
||||||
|
|
||||||
|
### Хранилище
|
||||||
|
|
||||||
|
```bash
|
||||||
|
STORAGE_TYPE="nfs" # nfs или smb
|
||||||
|
S_HOST="nfs.lan"
|
||||||
|
S_PATH="/mnt/media1/backup"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Для SMB
|
||||||
|
|
||||||
|
```bash
|
||||||
|
SMB_USER="guest"
|
||||||
|
SMB_PASS="guest"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Политика хранения
|
||||||
|
|
||||||
|
```bash
|
||||||
|
LOCAL_KEEP=10 # сколько хранить локально
|
||||||
|
HOST_KEEP=30 # сколько дней хранить удалённо
|
||||||
|
```
|
||||||
|
|
||||||
|
### Что бэкапить
|
||||||
|
|
||||||
|
```bash
|
||||||
|
C_LIST="
|
||||||
|
/etc/config
|
||||||
|
/etc/xray
|
||||||
|
/root/.ssh
|
||||||
|
...
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Что исключить
|
||||||
|
|
||||||
|
```bash
|
||||||
|
C_EXCLUDE="
|
||||||
|
/opt/.backup-manager/local_backups
|
||||||
|
/etc/xray/ipset
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Конфликтующие пакеты
|
||||||
|
|
||||||
|
Удаляются перед восстановлением:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
H_REPLACE="wpad dnsmasq"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование
|
||||||
|
|
||||||
|
### Создать бэкап
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./backup-manager.sh backup
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Что происходит:
|
||||||
|
|
||||||
|
- создаётся архив .tar.gz
|
||||||
|
- сохраняется список пакетов .lst
|
||||||
|
- копируется на удалённое хранилище (если доступно)
|
||||||
|
|
||||||
|
### Восстановление
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./backup-manager.sh restore
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Далее интерактивно:
|
||||||
|
|
||||||
|
1. Выбор источника (локальный / удалённый)
|
||||||
|
2. Выбор типа:
|
||||||
|
- конфигурация
|
||||||
|
- пакеты
|
||||||
|
|
||||||
|
## Как работает бэкап пакетов
|
||||||
|
|
||||||
|
#### Скрипт:
|
||||||
|
|
||||||
|
- определяет пакеты, установленные пользователем
|
||||||
|
- исключает зависимости
|
||||||
|
|
||||||
|
|
||||||
|
## Зависимости
|
||||||
|
|
||||||
|
#### Для NFS
|
||||||
|
|
||||||
|
```sh
|
||||||
|
opkg install kmod-fs-nfs kmod-fs-nfs-v3 kmod-fs-nfs-v4 nfs-utils
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Для SMB
|
||||||
|
```sh
|
||||||
|
opkg install kmod-fs-cifs cifs-utils
|
||||||
|
```
|
||||||
|
|
||||||
|
## Особенности
|
||||||
|
- Используется временная директория: /tmp
|
||||||
|
- При восстановлении пакетов:
|
||||||
|
- временно правится DNS (Cloudflare)
|
||||||
|
- Для восстановления конфигурации используется:
|
||||||
|
```sh
|
||||||
|
sysupgrade -r backup.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
## Очистка
|
||||||
|
|
||||||
|
#### Автоматически:
|
||||||
|
- старые локальные бэкапы
|
||||||
|
- удалённые файлы старше HOST_KEEP дней
|
||||||
|
|
||||||
|
|
||||||
|
## Пример cron
|
||||||
|
|
||||||
|
```sh
|
||||||
|
0 3 * * * /opt/.backup-manager/backup-manager.sh backup
|
||||||
|
```
|
||||||
@@ -6,8 +6,6 @@ H_REPLACE="$3"
|
|||||||
|
|
||||||
[ -z "$CMD" ] || [ -z "$LOCAL_LST" ] || [ -z "$H_REPLACE" ] && echo "Missing params!" && exit 1
|
[ -z "$CMD" ] || [ -z "$LOCAL_LST" ] || [ -z "$H_REPLACE" ] && echo "Missing params!" && exit 1
|
||||||
|
|
||||||
TMP_DIR="/tmp/opkg_restore"
|
|
||||||
|
|
||||||
fix_dns() {
|
fix_dns() {
|
||||||
local dns1="1.1.1.1"
|
local dns1="1.1.1.1"
|
||||||
local dns2="1.0.0.1"
|
local dns2="1.0.0.1"
|
||||||
@@ -20,28 +18,11 @@ fix_dns() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
list_user_packages() {
|
list_user_packages() {
|
||||||
awk -f - << 'EOF'
|
if [ -f /rom/etc/apk/world ]; then
|
||||||
BEGIN {
|
grep -v -F -x -f /rom/etc/apk/world /etc/apk/world | sed 's/=.*//'
|
||||||
status_file = "/usr/lib/opkg/status"
|
else
|
||||||
cmd="opkg info busybox | grep '^Installed-Time: '"
|
cat /etc/apk/world | sed 's/=.*//'
|
||||||
if ((cmd | getline line) > 0) {
|
fi
|
||||||
FLASH_TIME = substr(line, 17)
|
|
||||||
}
|
|
||||||
close(cmd)
|
|
||||||
while ((getline < status_file) > 0) {
|
|
||||||
if ($1 == "Package:") { pkg = $2 }
|
|
||||||
if ($1 == "Installed-Time:") {
|
|
||||||
installed_time = $2
|
|
||||||
if (installed_time > FLASH_TIME) {
|
|
||||||
check_cmd = "opkg whatdepends " pkg " | wc -l"
|
|
||||||
check_cmd | getline whatdepends
|
|
||||||
close(check_cmd)
|
|
||||||
if (whatdepends == 3) print pkg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case "$CMD" in
|
case "$CMD" in
|
||||||
@@ -61,34 +42,38 @@ case "$CMD" in
|
|||||||
[ ! -f /etc/resolv.conf-backup ] && cp /etc/resolv.conf /etc/resolv.conf-backup
|
[ ! -f /etc/resolv.conf-backup ] && cp /etc/resolv.conf /etc/resolv.conf-backup
|
||||||
fix_dns
|
fix_dns
|
||||||
printf "Updating package lists... "
|
printf "Updating package lists... "
|
||||||
opkg update >/dev/null 2>&1
|
apk update >/dev/null 2>&1
|
||||||
echo "OK"
|
echo "OK"
|
||||||
|
|
||||||
echo "Removing conflicts:"
|
echo "Removing conflicts:"
|
||||||
if [ -n "$H_REPLACE" ]; then
|
if [ -n "$H_REPLACE" ]; then
|
||||||
REMOVABLE=$(opkg list-installed | grep -E $(echo "$H_REPLACE" | tr ' ' '|') | awk '{print $1}')
|
local pattern=$(echo "$H_REPLACE" | sed 's/ /|/g')
|
||||||
|
REMOVABLE=$(apk list --installed | grep -E "$pattern" | awk '{print $1}' | sed 's/-[0-9].*$//')
|
||||||
for p in $REMOVABLE; do
|
for p in $REMOVABLE; do
|
||||||
printf " [-] %s... " "$p"
|
printf " [-] %s... " "$p"
|
||||||
opkg remove "$p" --force-depends >/dev/null 2>&1
|
apk del "$p" >/dev/null 2>&1
|
||||||
echo "OK"
|
echo "OK"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Installing packages:"
|
echo "Installing packages:"
|
||||||
for pkg in $(cat "$LOCAL_LST"); do
|
for pkg in $(cat "$LOCAL_LST"); do
|
||||||
if opkg list-installed | grep -q "^$pkg "; then
|
if apk info -e "$pkg" >/dev/null 2>&1; then
|
||||||
echo " [s] $pkg... is already installed"
|
echo " [s] $pkg... is already installed"
|
||||||
else
|
else
|
||||||
fix_dns
|
fix_dns
|
||||||
printf " [+] $pkg... "
|
printf " [+] $pkg... "
|
||||||
if opkg install "$pkg" >/dev/null 2>&1; then
|
if apk add "$pkg" >/dev/null 2>&1; then
|
||||||
echo "OK"
|
echo "OK"
|
||||||
else
|
else
|
||||||
echo "FAILED"
|
echo "FAILED"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
[ -f /etc/resolv.conf-backup ] && mv /etc/resolv.conf-backup /etc/resolv.conf
|
[ -f /etc/resolv.conf-backup ] && mv /etc/resolv.conf-backup /etc/resolv.conf
|
||||||
echo "Summary:"
|
echo "Summary:"
|
||||||
echo " Restore complete."
|
echo " Restore complete"
|
||||||
echo " Reboot is recommended."
|
echo " Reboot is recommended"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
+2
-2
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
LOCAL_FILE="$1"
|
LOCAL_FILE="$1"
|
||||||
LOCAL_LST="$2"
|
LOCAL_LST="$2"
|
||||||
SCR_OPKG="$3"
|
SCR_APK="$3"
|
||||||
C_LIST="$4"
|
C_LIST="$4"
|
||||||
H_REPLACE="$5"
|
H_REPLACE="$5"
|
||||||
C_EXCLUDE="$6"
|
C_EXCLUDE="$6"
|
||||||
@@ -12,7 +12,7 @@ C_EXCLUDE="$6"
|
|||||||
TMP_DIR="/tmp/backup_stack"
|
TMP_DIR="/tmp/backup_stack"
|
||||||
rm -rf "$TMP_DIR" && mkdir -p "$TMP_DIR"
|
rm -rf "$TMP_DIR" && mkdir -p "$TMP_DIR"
|
||||||
|
|
||||||
$SCR_OPKG write "$LOCAL_LST" "$H_REPLACE"
|
$SCR_APK write "$LOCAL_LST" "$H_REPLACE"
|
||||||
|
|
||||||
echo "Included:"
|
echo "Included:"
|
||||||
for p in $C_LIST; do
|
for p in $C_LIST; do
|
||||||
|
|||||||
+11
-6
@@ -28,17 +28,17 @@ C_LIST="
|
|||||||
/opt/.xray-config
|
/opt/.xray-config
|
||||||
/opt/.backup-manager
|
/opt/.backup-manager
|
||||||
/etc/nftables.d/10-netmap.nft
|
/etc/nftables.d/10-netmap.nft
|
||||||
|
/etc/nftables.d/15-pbr-mark.nft
|
||||||
/etc/hotplug.d/iface/99-xray-restart
|
/etc/hotplug.d/iface/99-xray-restart
|
||||||
/etc/zabbix_agentd.conf
|
/etc/zabbix_agentd.conf
|
||||||
/etc/dropbear
|
/etc/dropbear
|
||||||
/etc/banner
|
/etc/banner
|
||||||
/etc/init.d/xray
|
/etc/init.d/xray
|
||||||
|
/etc/crontabs/root
|
||||||
"
|
"
|
||||||
|
|
||||||
C_EXCLUDE="
|
C_EXCLUDE="
|
||||||
/opt/.backup-manager/local_backups
|
/opt/.backup-manager/local_backups
|
||||||
/etc/xray/ipset
|
|
||||||
/etc/xray/ipnet
|
|
||||||
"
|
"
|
||||||
|
|
||||||
H_REPLACE="wpad dnsmasq"
|
H_REPLACE="wpad dnsmasq"
|
||||||
@@ -47,7 +47,7 @@ DIR=$(cd "$(dirname "$0")" && pwd)
|
|||||||
#DIR="/opt/.backup-manager"
|
#DIR="/opt/.backup-manager"
|
||||||
L_BACKUP_DIR="$DIR/local_backups"
|
L_BACKUP_DIR="$DIR/local_backups"
|
||||||
SCR_BACKUP="$DIR/backup-configs.sh"
|
SCR_BACKUP="$DIR/backup-configs.sh"
|
||||||
SCR_OPKG="$DIR/backup-opkg.sh"
|
SCR_APK="$DIR/backup-apk.sh"
|
||||||
|
|
||||||
mkdir -p "$L_BACKUP_DIR"
|
mkdir -p "$L_BACKUP_DIR"
|
||||||
|
|
||||||
@@ -73,11 +73,16 @@ check_dependencies() {
|
|||||||
local pkgs=""
|
local pkgs=""
|
||||||
[ "$STORAGE_TYPE" = "nfs" ] && pkgs="kmod-fs-nfs kmod-fs-nfs-v3 kmod-fs-nfs-v4 nfs-utils"
|
[ "$STORAGE_TYPE" = "nfs" ] && pkgs="kmod-fs-nfs kmod-fs-nfs-v3 kmod-fs-nfs-v4 nfs-utils"
|
||||||
[ "$STORAGE_TYPE" = "smb" ] && pkgs="kmod-fs-cifs cifs-utils"
|
[ "$STORAGE_TYPE" = "smb" ] && pkgs="kmod-fs-cifs cifs-utils"
|
||||||
|
|
||||||
local missing=""
|
local missing=""
|
||||||
for pkg in $pkgs; do
|
for pkg in $pkgs; do
|
||||||
opkg list-installed | grep -q "^$pkg " || missing="$missing $pkg"
|
if ! apk info -e "$pkg" >/dev/null 2>&1; then
|
||||||
|
missing="$missing $pkg"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ -n "$missing" ]; then
|
if [ -n "$missing" ]; then
|
||||||
|
echo "FAILED"
|
||||||
echo " [!] Missing: $missing. Install them to use remote backup."
|
echo " [!] Missing: $missing. Install them to use remote backup."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@@ -144,7 +149,7 @@ case "$1" in
|
|||||||
LOCAL_FILE="$L_BACKUP_DIR/backup_${HNAME}_${DATE}.tar.gz"
|
LOCAL_FILE="$L_BACKUP_DIR/backup_${HNAME}_${DATE}.tar.gz"
|
||||||
LOCAL_LST="$L_BACKUP_DIR/packages_${HNAME}_${DATE}.lst"
|
LOCAL_LST="$L_BACKUP_DIR/packages_${HNAME}_${DATE}.lst"
|
||||||
REMOTE_STATUS="FAILED"
|
REMOTE_STATUS="FAILED"
|
||||||
$SCR_BACKUP "$LOCAL_FILE" "$LOCAL_LST" "$SCR_OPKG" "$C_LIST" "$H_REPLACE" "$C_EXCLUDE"
|
$SCR_BACKUP "$LOCAL_FILE" "$LOCAL_LST" "$SCR_APK" "$C_LIST" "$H_REPLACE" "$C_EXCLUDE"
|
||||||
manage_local_backups
|
manage_local_backups
|
||||||
if check_network && check_dependencies && mount_share; then
|
if check_network && check_dependencies && mount_share; then
|
||||||
printf "Copying to %s storage... " "$STORAGE_TYPE"
|
printf "Copying to %s storage... " "$STORAGE_TYPE"
|
||||||
@@ -198,7 +203,7 @@ case "$1" in
|
|||||||
2)
|
2)
|
||||||
select_file "$R_DIR" ".lst"
|
select_file "$R_DIR" ".lst"
|
||||||
if [ -n "$SELECTED_PATH" ]; then
|
if [ -n "$SELECTED_PATH" ]; then
|
||||||
$SCR_OPKG restore "$SELECTED_PATH" "$H_REPLACE"
|
$SCR_APK restore "$SELECTED_PATH" "$H_REPLACE"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
|||||||
Reference in New Issue
Block a user