refactor(de-sudo): backup subsystem data ops via runFileOp/runFileWrite
The backup engine already drops to the backup user (sudo -E -u $docker_install_user) and backupLocationOwner == $docker_install_user, which is exactly what runFileOp/runFileWrite resolve to in both modes. So convert the raw-sudo data ops (mkdir/chmod/rm/find/cat/grep/mv/chown/tee on backup repos, location configs, keys, manifests) to runFileOp/runFileWrite — creating files as the owner directly, no root chown. backup_verify creates its scratch as the backup user (runFileOp mktemp) instead of chown-after. Binary installs (kopia tar/install, borg dnf) -> runSystem. The 44 sudo -u engine drops stay (already least-privilege; the scoped sudoers will grant them). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
This commit is contained in:
parent
bace502044
commit
7acfdabbac
@ -12,8 +12,8 @@ borgInitLocation()
|
|||||||
borgEnvExport "$idx" || return 1
|
borgEnvExport "$idx" || return 1
|
||||||
|
|
||||||
if [[ "$(resticLocationType "$idx")" == "local" ]]; then
|
if [[ "$(resticLocationType "$idx")" == "local" ]]; then
|
||||||
sudo mkdir -p "$BORG_REPO"
|
runFileOp mkdir -p "$BORG_REPO"
|
||||||
sudo chown -R "$docker_install_user":"$docker_install_user" "$BORG_REPO"
|
runFileOp chown -R "$docker_install_user":"$docker_install_user" "$BORG_REPO"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if sudo -E -u "$docker_install_user" borg info "$BORG_REPO" >/dev/null 2>&1; then
|
if sudo -E -u "$docker_install_user" borg info "$BORG_REPO" >/dev/null 2>&1; then
|
||||||
|
|||||||
@ -13,7 +13,7 @@ borgInstall()
|
|||||||
if command -v apt-get >/dev/null 2>&1; then
|
if command -v apt-get >/dev/null 2>&1; then
|
||||||
runSystem apt-get install -y borgbackup && return 0
|
runSystem apt-get install -y borgbackup && return 0
|
||||||
elif command -v dnf >/dev/null 2>&1; then
|
elif command -v dnf >/dev/null 2>&1; then
|
||||||
sudo dnf install -y borgbackup && return 0
|
runSystem dnf install -y borgbackup && return 0
|
||||||
elif command -v pacman >/dev/null 2>&1; then
|
elif command -v pacman >/dev/null 2>&1; then
|
||||||
runSystem pacman -S --noconfirm borg && return 0
|
runSystem pacman -S --noconfirm borg && return 0
|
||||||
fi
|
fi
|
||||||
|
|||||||
@ -27,8 +27,8 @@ kopiaInitLocation()
|
|||||||
local)
|
local)
|
||||||
local path
|
local path
|
||||||
path=$(backupLocationResolvedPath "$idx")
|
path=$(backupLocationResolvedPath "$idx")
|
||||||
sudo mkdir -p "$path"
|
runFileOp mkdir -p "$path"
|
||||||
sudo chown -R "$docker_install_user":"$docker_install_user" "$path"
|
runFileOp chown -R "$docker_install_user":"$docker_install_user" "$path"
|
||||||
args=(repository create filesystem --path="$path")
|
args=(repository create filesystem --path="$path")
|
||||||
;;
|
;;
|
||||||
sftp)
|
sftp)
|
||||||
|
|||||||
@ -36,7 +36,7 @@ kopiaInstall()
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sudo tar xzf "$tmp/kopia.tgz" -C "$tmp"
|
runSystem tar xzf "$tmp/kopia.tgz" -C "$tmp"
|
||||||
local bin
|
local bin
|
||||||
bin=$(find "$tmp" -name kopia -type f -executable | head -1)
|
bin=$(find "$tmp" -name kopia -type f -executable | head -1)
|
||||||
if [[ -z "$bin" ]]; then
|
if [[ -z "$bin" ]]; then
|
||||||
@ -44,7 +44,7 @@ kopiaInstall()
|
|||||||
isError "Kopia binary not found in archive"
|
isError "Kopia binary not found in archive"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
sudo install -m 0755 "$bin" /usr/local/bin/kopia
|
runSystem install -m 0755 "$bin" /usr/local/bin/kopia
|
||||||
rm -rf "$tmp"
|
rm -rf "$tmp"
|
||||||
checkSuccess "Kopia v${version} installed to /usr/local/bin/kopia"
|
checkSuccess "Kopia v${version} installed to /usr/local/bin/kopia"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ kopiaRestoreSnapshot()
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
kopiaEnvExport "$idx" || return 1
|
kopiaEnvExport "$idx" || return 1
|
||||||
sudo mkdir -p "$target_dir"
|
runFileOp mkdir -p "$target_dir"
|
||||||
|
|
||||||
isNotice "Restoring ${snapshot_id:0:12} from $(resticLocationName "$idx") → $target_dir"
|
isNotice "Restoring ${snapshot_id:0:12} from $(resticLocationName "$idx") → $target_dir"
|
||||||
# Kopia's restore lays down the snapshot's source tree relative to target.
|
# Kopia's restore lays down the snapshot's source tree relative to target.
|
||||||
@ -22,7 +22,7 @@ kopiaRestoreSnapshot()
|
|||||||
local final_target="$target_dir"
|
local final_target="$target_dir"
|
||||||
if [[ -n "$include_path" ]]; then
|
if [[ -n "$include_path" ]]; then
|
||||||
final_target="$target_dir/${include_path#/}"
|
final_target="$target_dir/${include_path#/}"
|
||||||
sudo mkdir -p "$final_target"
|
runFileOp mkdir -p "$final_target"
|
||||||
fi
|
fi
|
||||||
sudo -E -u "$docker_install_user" kopia snapshot restore "$snapshot_id" "$final_target"
|
sudo -E -u "$docker_install_user" kopia snapshot restore "$snapshot_id" "$final_target"
|
||||||
local rc=$?
|
local rc=$?
|
||||||
|
|||||||
@ -9,7 +9,7 @@ resticAllLocationIndices()
|
|||||||
compgen -v 2>/dev/null | grep -oE '^CFG_BACKUP_LOC_[0-9]+_NAME$' | grep -oE '[0-9]+' | sort -n -u
|
compgen -v 2>/dev/null | grep -oE '^CFG_BACKUP_LOC_[0-9]+_NAME$' | grep -oE '[0-9]+' | sort -n -u
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
sudo find "$dir" -mindepth 2 -maxdepth 2 -name location.config -type f 2>/dev/null \
|
runFileOp find "$dir" -mindepth 2 -maxdepth 2 -name location.config -type f 2>/dev/null \
|
||||||
| awk -F/ '{print $(NF-1)}' \
|
| awk -F/ '{print $(NF-1)}' \
|
||||||
| grep -E '^[0-9]+$' \
|
| grep -E '^[0-9]+$' \
|
||||||
| sort -n -u
|
| sort -n -u
|
||||||
|
|||||||
@ -12,8 +12,8 @@ resticInitLocation()
|
|||||||
resticEnvExport "$idx" || return 1
|
resticEnvExport "$idx" || return 1
|
||||||
|
|
||||||
if [[ "$(resticLocationType "$idx")" == "local" ]]; then
|
if [[ "$(resticLocationType "$idx")" == "local" ]]; then
|
||||||
sudo mkdir -p "$RESTIC_REPOSITORY"
|
runFileOp mkdir -p "$RESTIC_REPOSITORY"
|
||||||
sudo chown -R "$docker_install_user":"$docker_install_user" "$RESTIC_REPOSITORY"
|
runFileOp chown -R "$docker_install_user":"$docker_install_user" "$RESTIC_REPOSITORY"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if sudo -E -u "$docker_install_user" restic snapshots --json --no-lock >/dev/null 2>&1; then
|
if sudo -E -u "$docker_install_user" restic snapshots --json --no-lock >/dev/null 2>&1; then
|
||||||
|
|||||||
@ -14,7 +14,7 @@ resticRestoreSnapshot()
|
|||||||
|
|
||||||
resticEnvExport "$idx" || return 1
|
resticEnvExport "$idx" || return 1
|
||||||
|
|
||||||
sudo mkdir -p "$target_dir"
|
runFileOp mkdir -p "$target_dir"
|
||||||
|
|
||||||
local args=(restore "$snapshot_id" --target "$target_dir")
|
local args=(restore "$snapshot_id" --target "$target_dir")
|
||||||
[[ -n "$include_path" ]] && args+=(--include "$include_path")
|
[[ -n "$include_path" ]] && args+=(--include "$include_path")
|
||||||
|
|||||||
@ -55,9 +55,9 @@ locationAdd()
|
|||||||
echo "CFG_BACKUP_LOC_${idx}_KEEP_WEEKLY="
|
echo "CFG_BACKUP_LOC_${idx}_KEEP_WEEKLY="
|
||||||
echo "CFG_BACKUP_LOC_${idx}_KEEP_MONTHLY="
|
echo "CFG_BACKUP_LOC_${idx}_KEEP_MONTHLY="
|
||||||
echo "CFG_BACKUP_LOC_${idx}_KEEP_YEARLY="
|
echo "CFG_BACKUP_LOC_${idx}_KEEP_YEARLY="
|
||||||
} | sudo tee "$cfg_file" >/dev/null
|
} | runFileWrite "$cfg_file" >/dev/null
|
||||||
sudo chown "$owner":"$owner" "$cfg_file"
|
runFileOp chown "$owner":"$owner" "$cfg_file"
|
||||||
sudo chmod 0640 "$cfg_file"
|
runFileOp chmod 0640 "$cfg_file"
|
||||||
|
|
||||||
if declare -f replacePlainPasswords >/dev/null 2>&1; then
|
if declare -f replacePlainPasswords >/dev/null 2>&1; then
|
||||||
replacePlainPasswords "$cfg_file"
|
replacePlainPasswords "$cfg_file"
|
||||||
|
|||||||
@ -14,5 +14,5 @@ sourceBackupLocations()
|
|||||||
local cfg
|
local cfg
|
||||||
while IFS= read -r -d '' cfg; do
|
while IFS= read -r -d '' cfg; do
|
||||||
[[ -f "$cfg" ]] && source "$cfg"
|
[[ -f "$cfg" ]] && source "$cfg"
|
||||||
done < <(sudo find "$dir" -mindepth 2 -maxdepth 2 -name location.config -type f -print0 2>/dev/null)
|
done < <(runFileOp find "$dir" -mindepth 2 -maxdepth 2 -name location.config -type f -print0 2>/dev/null)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ backupLocationsMigrate()
|
|||||||
# Already migrated? Detect by presence of at least one location.config.
|
# Already migrated? Detect by presence of at least one location.config.
|
||||||
if [[ -d "$new_dir" ]]; then
|
if [[ -d "$new_dir" ]]; then
|
||||||
local existing
|
local existing
|
||||||
existing=$(sudo find "$new_dir" -mindepth 2 -maxdepth 2 -name location.config -type f 2>/dev/null | head -1)
|
existing=$(runFileOp find "$new_dir" -mindepth 2 -maxdepth 2 -name location.config -type f 2>/dev/null | head -1)
|
||||||
if [[ -n "$existing" ]]; then
|
if [[ -n "$existing" ]]; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@ -32,12 +32,12 @@ backupLocationsMigrate()
|
|||||||
|
|
||||||
local owner
|
local owner
|
||||||
owner=$(backupLocationOwner)
|
owner=$(backupLocationOwner)
|
||||||
sudo mkdir -p "$new_dir"
|
runFileOp mkdir -p "$new_dir"
|
||||||
sudo chown "$owner":"$owner" "$new_dir"
|
runFileOp chown "$owner":"$owner" "$new_dir"
|
||||||
sudo chmod 0755 "$new_dir"
|
runFileOp chmod 0755 "$new_dir"
|
||||||
|
|
||||||
local indices
|
local indices
|
||||||
indices=$(sudo grep -oE '^CFG_BACKUP_LOC_[0-9]+_' "$old_file" 2>/dev/null | grep -oE '[0-9]+' | sort -nu)
|
indices=$(runFileOp grep -oE '^CFG_BACKUP_LOC_[0-9]+_' "$old_file" 2>/dev/null | grep -oE '[0-9]+' | sort -nu)
|
||||||
if [[ -z "$indices" ]]; then
|
if [[ -z "$indices" ]]; then
|
||||||
isNotice "No locations found in legacy file — archiving without migration"
|
isNotice "No locations found in legacy file — archiving without migration"
|
||||||
fi
|
fi
|
||||||
@ -48,14 +48,14 @@ backupLocationsMigrate()
|
|||||||
loc_dir=$(backupLocationDir "$idx")
|
loc_dir=$(backupLocationDir "$idx")
|
||||||
cfg_file=$(backupLocationConfig "$idx")
|
cfg_file=$(backupLocationConfig "$idx")
|
||||||
|
|
||||||
sudo mkdir -p "$loc_dir"
|
runFileOp mkdir -p "$loc_dir"
|
||||||
sudo chown "$owner":"$owner" "$loc_dir"
|
runFileOp chown "$owner":"$owner" "$loc_dir"
|
||||||
sudo chmod 0700 "$loc_dir"
|
runFileOp chmod 0700 "$loc_dir"
|
||||||
|
|
||||||
local old_pass="/docker/configs/security/restic/loc_${idx}.pass"
|
local old_pass="/docker/configs/security/restic/loc_${idx}.pass"
|
||||||
local pass_value=""
|
local pass_value=""
|
||||||
if [[ -f "$old_pass" ]]; then
|
if [[ -f "$old_pass" ]]; then
|
||||||
pass_value=$(sudo cat "$old_pass" | tr -d '\n\r')
|
pass_value=$(runFileOp cat "$old_pass" | tr -d '\n\r')
|
||||||
fi
|
fi
|
||||||
[[ -z "$pass_value" ]] && pass_value="RANDOMIZEDPASSWORD1"
|
[[ -z "$pass_value" ]] && pass_value="RANDOMIZEDPASSWORD1"
|
||||||
|
|
||||||
@ -63,13 +63,13 @@ backupLocationsMigrate()
|
|||||||
echo "# Backup location $idx — migrated $(date -Iseconds) from $old_file."
|
echo "# Backup location $idx — migrated $(date -Iseconds) from $old_file."
|
||||||
echo "# Edit via the Locations page on /backup, or directly here."
|
echo "# Edit via the Locations page on /backup, or directly here."
|
||||||
echo "CFG_BACKUP_LOC_${idx}_PASSWORD=${pass_value} # Repository Password - Used to encrypt/decrypt snapshots — back up offline!"
|
echo "CFG_BACKUP_LOC_${idx}_PASSWORD=${pass_value} # Repository Password - Used to encrypt/decrypt snapshots — back up offline!"
|
||||||
sudo grep "^CFG_BACKUP_LOC_${idx}_" "$old_file" | grep -v "^CFG_BACKUP_LOC_${idx}_PASSWORD="
|
runFileOp grep "^CFG_BACKUP_LOC_${idx}_" "$old_file" | grep -v "^CFG_BACKUP_LOC_${idx}_PASSWORD="
|
||||||
} | sudo tee "$cfg_file" >/dev/null
|
} | runFileWrite "$cfg_file" >/dev/null
|
||||||
sudo chown "$owner":"$owner" "$cfg_file"
|
runFileOp chown "$owner":"$owner" "$cfg_file"
|
||||||
sudo chmod 0640 "$cfg_file"
|
runFileOp chmod 0640 "$cfg_file"
|
||||||
|
|
||||||
if [[ -f "$old_pass" ]]; then
|
if [[ -f "$old_pass" ]]; then
|
||||||
sudo rm -f "$old_pass"
|
runFileOp rm -f "$old_pass"
|
||||||
isNotice "Inlined password for location $idx into $cfg_file (old .pass removed)"
|
isNotice "Inlined password for location $idx into $cfg_file (old .pass removed)"
|
||||||
elif declare -f replacePlainPasswords >/dev/null 2>&1; then
|
elif declare -f replacePlainPasswords >/dev/null 2>&1; then
|
||||||
replacePlainPasswords "$cfg_file"
|
replacePlainPasswords "$cfg_file"
|
||||||
@ -79,9 +79,9 @@ backupLocationsMigrate()
|
|||||||
local new_kopia
|
local new_kopia
|
||||||
new_kopia=$(backupLocationKopiaConfig "$idx")
|
new_kopia=$(backupLocationKopiaConfig "$idx")
|
||||||
if [[ -f "$old_kopia" ]]; then
|
if [[ -f "$old_kopia" ]]; then
|
||||||
sudo mv "$old_kopia" "$new_kopia"
|
runFileOp mv "$old_kopia" "$new_kopia"
|
||||||
sudo chown "$owner":"$owner" "$new_kopia"
|
runFileOp chown "$owner":"$owner" "$new_kopia"
|
||||||
sudo chmod 0600 "$new_kopia"
|
runFileOp chmod 0600 "$new_kopia"
|
||||||
isNotice "Moved kopia state for location $idx → $new_kopia"
|
isNotice "Moved kopia state for location $idx → $new_kopia"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -89,16 +89,16 @@ backupLocationsMigrate()
|
|||||||
local new_ssh
|
local new_ssh
|
||||||
new_ssh=$(backupLocationSshKey "$idx")
|
new_ssh=$(backupLocationSshKey "$idx")
|
||||||
if [[ -f "$old_ssh" ]]; then
|
if [[ -f "$old_ssh" ]]; then
|
||||||
sudo mv "$old_ssh" "$new_ssh"
|
runFileOp mv "$old_ssh" "$new_ssh"
|
||||||
sudo chown "$owner":"$owner" "$new_ssh"
|
runFileOp chown "$owner":"$owner" "$new_ssh"
|
||||||
sudo chmod 0600 "$new_ssh"
|
runFileOp chmod 0600 "$new_ssh"
|
||||||
isNotice "Moved SSH key for location $idx → $new_ssh"
|
isNotice "Moved SSH key for location $idx → $new_ssh"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
isSuccessful "Location $idx migrated"
|
isSuccessful "Location $idx migrated"
|
||||||
done
|
done
|
||||||
|
|
||||||
sudo mv "$old_file" "${old_file}.migrated"
|
runFileOp mv "$old_file" "${old_file}.migrated"
|
||||||
isSuccessful "Migration complete — old file archived as ${old_file}.migrated"
|
isSuccessful "Migration complete — old file archived as ${old_file}.migrated"
|
||||||
|
|
||||||
# Re-source the new per-location configs so CFG vars reflect new state.
|
# Re-source the new per-location configs so CFG vars reflect new state.
|
||||||
|
|||||||
@ -56,9 +56,9 @@ backupLocationEnsureDir()
|
|||||||
dir=$(backupLocationDir "$idx")
|
dir=$(backupLocationDir "$idx")
|
||||||
local owner
|
local owner
|
||||||
owner=$(backupLocationOwner)
|
owner=$(backupLocationOwner)
|
||||||
sudo mkdir -p "$dir"
|
runFileOp mkdir -p "$dir"
|
||||||
sudo chown "$owner":"$owner" "$dir"
|
runFileOp chown "$owner":"$owner" "$dir"
|
||||||
sudo chmod 0700 "$dir"
|
runFileOp chmod 0700 "$dir"
|
||||||
}
|
}
|
||||||
|
|
||||||
backupLocationResolvedPath()
|
backupLocationResolvedPath()
|
||||||
|
|||||||
@ -20,7 +20,7 @@ locationRemove()
|
|||||||
local name_var="CFG_BACKUP_LOC_${idx}_NAME"
|
local name_var="CFG_BACKUP_LOC_${idx}_NAME"
|
||||||
local label="${!name_var:-Location $idx}"
|
local label="${!name_var:-Location $idx}"
|
||||||
|
|
||||||
sudo rm -rf "$dir"
|
runFileOp rm -rf "$dir"
|
||||||
|
|
||||||
# Best-effort unset of the now-orphaned env vars so other code in this
|
# Best-effort unset of the now-orphaned env vars so other code in this
|
||||||
# process doesn't see stale values.
|
# process doesn't see stale values.
|
||||||
|
|||||||
@ -52,9 +52,9 @@ backupSshKeySet()
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "$decoded" | sudo tee "$key_file" >/dev/null
|
echo "$decoded" | runFileWrite "$key_file" >/dev/null
|
||||||
sudo chown "$owner":"$owner" "$key_file"
|
runFileOp chown "$owner":"$owner" "$key_file"
|
||||||
sudo chmod 0600 "$key_file"
|
runFileOp chmod 0600 "$key_file"
|
||||||
|
|
||||||
if ! sudo -u "$owner" ssh-keygen -y -f "$key_file" >/dev/null 2>&1; then
|
if ! sudo -u "$owner" ssh-keygen -y -f "$key_file" >/dev/null 2>&1; then
|
||||||
isError "Key written but ssh-keygen can't read it — check the format (OpenSSH PEM: ed25519, rsa, ecdsa)"
|
isError "Key written but ssh-keygen can't read it — check the format (OpenSSH PEM: ed25519, rsa, ecdsa)"
|
||||||
@ -80,12 +80,12 @@ backupSshKeyGenerate()
|
|||||||
key_file=$(backupSshKeyFile "$idx")
|
key_file=$(backupSshKeyFile "$idx")
|
||||||
|
|
||||||
if [[ -f "$key_file" ]]; then
|
if [[ -f "$key_file" ]]; then
|
||||||
sudo rm -f "$key_file" "${key_file}.pub"
|
runFileOp rm -f "$key_file" "${key_file}.pub"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sudo -u "$owner" ssh-keygen -t ed25519 -f "$key_file" -N "" -C "libreportal-loc-${idx}" -q
|
sudo -u "$owner" ssh-keygen -t ed25519 -f "$key_file" -N "" -C "libreportal-loc-${idx}" -q
|
||||||
sudo chmod 0600 "$key_file"
|
runFileOp chmod 0600 "$key_file"
|
||||||
[[ -f "${key_file}.pub" ]] && sudo rm -f "${key_file}.pub" # we re-derive when needed
|
[[ -f "${key_file}.pub" ]] && runFileOp rm -f "${key_file}.pub" # we re-derive when needed
|
||||||
|
|
||||||
isSuccessful "Generated ed25519 keypair for location $idx"
|
isSuccessful "Generated ed25519 keypair for location $idx"
|
||||||
isNotice "Public key (paste into the remote host's ~/.ssh/authorized_keys):"
|
isNotice "Public key (paste into the remote host's ~/.ssh/authorized_keys):"
|
||||||
@ -107,7 +107,7 @@ backupSshKeyDelete()
|
|||||||
local idx="$1"
|
local idx="$1"
|
||||||
local key_file
|
local key_file
|
||||||
key_file=$(backupSshKeyFile "$idx")
|
key_file=$(backupSshKeyFile "$idx")
|
||||||
[[ -f "$key_file" ]] && sudo rm -f "$key_file" "${key_file}.pub"
|
[[ -f "$key_file" ]] && runFileOp rm -f "$key_file" "${key_file}.pub"
|
||||||
isSuccessful "SSH key removed for location $idx"
|
isSuccessful "SSH key removed for location $idx"
|
||||||
backupSshKeyRefreshUi
|
backupSshKeyRefreshUi
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,11 +41,11 @@ manifestCollect()
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
local size_bytes
|
local size_bytes
|
||||||
size_bytes=$(sudo du -sb "$app_dir" 2>/dev/null | awk '{print $1}')
|
size_bytes=$(runFileOp du -sb "$app_dir" 2>/dev/null | awk '{print $1}')
|
||||||
[[ -z "$size_bytes" ]] && size_bytes=0
|
[[ -z "$size_bytes" ]] && size_bytes=0
|
||||||
|
|
||||||
local file_count
|
local file_count
|
||||||
file_count=$(sudo find "$app_dir" -type f 2>/dev/null | wc -l | tr -d ' ')
|
file_count=$(runFileOp find "$app_dir" -type f 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
|
||||||
local strategy="${CFG_BACKUP_STRATEGY:-auto}"
|
local strategy="${CFG_BACKUP_STRATEGY:-auto}"
|
||||||
declare -f backupResolveStrategy >/dev/null 2>&1 && strategy=$(backupResolveStrategy "$app_name")
|
declare -f backupResolveStrategy >/dev/null 2>&1 && strategy=$(backupResolveStrategy "$app_name")
|
||||||
|
|||||||
@ -13,9 +13,9 @@ manifestWrite()
|
|||||||
|
|
||||||
local manifest
|
local manifest
|
||||||
manifest=$(manifestCollect "$app_name")
|
manifest=$(manifestCollect "$app_name")
|
||||||
echo "$manifest" | sudo tee "$manifest_path" >/dev/null
|
echo "$manifest" | runFileWrite "$manifest_path" >/dev/null
|
||||||
sudo chown "$docker_install_user":"$docker_install_user" "$manifest_path"
|
runFileOp chown "$docker_install_user":"$docker_install_user" "$manifest_path"
|
||||||
sudo chmod 0644 "$manifest_path"
|
runFileOp chmod 0644 "$manifest_path"
|
||||||
|
|
||||||
local sha
|
local sha
|
||||||
sha=$(echo "$manifest" | sha256sum | cut -c1-12)
|
sha=$(echo "$manifest" | sha256sum | cut -c1-12)
|
||||||
@ -26,5 +26,5 @@ manifestRemove()
|
|||||||
{
|
{
|
||||||
local app_name="$1"
|
local app_name="$1"
|
||||||
local manifest_path="$containers_dir$app_name/.libreportal-manifest.json"
|
local manifest_path="$containers_dir$app_name/.libreportal-manifest.json"
|
||||||
[[ -f "$manifest_path" ]] && sudo rm -f "$manifest_path"
|
[[ -f "$manifest_path" ]] && runFileOp rm -f "$manifest_path"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,14 +12,15 @@ backupVerifySnapshot()
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
local scratch
|
local scratch
|
||||||
scratch=$(mktemp -d -t libreportal-verify-XXXXXX)
|
# Create the scratch dir AS the backup/install user so the engine (which runs
|
||||||
sudo chown "$docker_install_user":"$docker_install_user" "$scratch"
|
# as that user) can restore into it and we can read it back — no root chown.
|
||||||
|
scratch=$(runFileOp mktemp -d -t libreportal-verify-XXXXXX)
|
||||||
|
|
||||||
isNotice "Verifying ${snapshot_id:0:8} via scratch restore at $scratch"
|
isNotice "Verifying ${snapshot_id:0:8} via scratch restore at $scratch"
|
||||||
|
|
||||||
if ! engineRestoreSnapshot "$idx" "$snapshot_id" "$scratch" "$containers_dir$app_name"; then
|
if ! engineRestoreSnapshot "$idx" "$snapshot_id" "$scratch" "$containers_dir$app_name"; then
|
||||||
isError "Verify restore FAILED for $app_name on $(resticLocationName "$idx")"
|
isError "Verify restore FAILED for $app_name on $(resticLocationName "$idx")"
|
||||||
sudo rm -rf "$scratch"
|
runFileOp rm -rf "$scratch"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -30,9 +31,9 @@ backupVerifySnapshot()
|
|||||||
# and replaced by dumps/captures under .lp-backup) — so just sanity-check the
|
# and replaced by dumps/captures under .lp-backup) — so just sanity-check the
|
||||||
# restore produced a non-empty tree.
|
# restore produced a non-empty tree.
|
||||||
local restored_count
|
local restored_count
|
||||||
restored_count=$(sudo find "$scratch$containers_dir$app_name" -type f 2>/dev/null | wc -l)
|
restored_count=$(runFileOp find "$scratch$containers_dir$app_name" -type f 2>/dev/null | wc -l)
|
||||||
|
|
||||||
sudo rm -rf "$scratch"
|
runFileOp rm -rf "$scratch"
|
||||||
|
|
||||||
if [[ "$restored_count" -lt 1 ]]; then
|
if [[ "$restored_count" -lt 1 ]]; then
|
||||||
isError "Verify FAILED for $app_name — restored snapshot is empty"
|
isError "Verify FAILED for $app_name — restored snapshot is empty"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user