librelad 7acfdabbac 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>
2026-05-24 17:01:05 +01:00

168 lines
4.0 KiB
Bash

#!/bin/bash
resticAllLocationIndices()
{
local dir
dir=$(backupLocationsDir)
if [[ ! -d "$dir" ]]; then
# Pre-migration / legacy fallback: read indices from CFG vars.
compgen -v 2>/dev/null | grep -oE '^CFG_BACKUP_LOC_[0-9]+_NAME$' | grep -oE '[0-9]+' | sort -n -u
return
fi
runFileOp find "$dir" -mindepth 2 -maxdepth 2 -name location.config -type f 2>/dev/null \
| awk -F/ '{print $(NF-1)}' \
| grep -E '^[0-9]+$' \
| sort -n -u
}
resticEnabledLocations()
{
local idx enabled_var
while IFS= read -r idx; do
[[ -z "$idx" ]] && continue
enabled_var="CFG_BACKUP_LOC_${idx}_ENABLED"
if [[ "${!enabled_var}" == "true" ]]; then
echo "$idx"
fi
done < <(resticAllLocationIndices)
}
resticLocationField()
{
local idx="$1"
local field="$2"
local var="CFG_BACKUP_LOC_${idx}_${field}"
echo "${!var}"
}
resticLocationName()
{
local idx="$1"
local name
name=$(resticLocationField "$idx" NAME)
[[ -z "$name" ]] && name="Location $idx"
echo "$name"
}
resticLocationType()
{
local idx="$1"
local t
t=$(resticLocationField "$idx" TYPE)
[[ -z "$t" ]] && t="local"
echo "$t"
}
resticLocationEnabled()
{
local idx="$1"
[[ "$(resticLocationField "$idx" ENABLED)" == "true" ]]
}
resticLocationAppendOnly()
{
local idx="$1"
[[ "$(resticLocationField "$idx" APPEND_ONLY)" == "true" ]]
}
resticLocationUri()
{
local idx="$1"
local override
override=$(resticLocationField "$idx" URI)
if [[ -n "$override" ]]; then
echo "$override"
return
fi
local t
t=$(resticLocationType "$idx")
case "$t" in
local)
backupLocationResolvedPath "$idx"
;;
sftp)
local user host path port
user=$(resticLocationField "$idx" SSH_USER)
host=$(resticLocationField "$idx" SSH_HOST)
path=$(resticLocationField "$idx" SSH_PATH)
echo "sftp:${user}@${host}:${path}"
;;
rest)
resticLocationField "$idx" URI
;;
s3|b2|gs|azure|rclone)
resticLocationField "$idx" URI
;;
esac
}
resticLocationPassword()
{
local idx="$1"
local var="CFG_BACKUP_LOC_${idx}_PASSWORD"
echo "${!var}"
}
resticEnvExport()
{
local idx="$1"
local repo_uri
repo_uri=$(resticLocationUri "$idx")
if [[ -z "$repo_uri" ]]; then
isError "Location $idx has no URI configured"
return 1
fi
local pass
pass=$(resticLocationPassword "$idx")
if [[ -z "$pass" || "$pass" == RANDOMIZEDPASSWORD* ]]; then
isError "Location $idx has no password set (CFG_BACKUP_LOC_${idx}_PASSWORD). Run the install/scan password pass first."
return 1
fi
export RESTIC_REPOSITORY="$repo_uri"
export RESTIC_PASSWORD="$pass"
local t
t=$(resticLocationType "$idx")
case "$t" in
sftp)
local port auth ssh_cmd
port=$(resticLocationField "$idx" SSH_PORT)
[[ -z "$port" ]] && port=22
auth=$(resticLocationField "$idx" SSH_AUTH)
ssh_cmd=$(backupSshCommand "$idx" "$port" "sftp") || return 1
export RESTIC_SFTP_COMMAND="$ssh_cmd"
;;
s3)
export AWS_ACCESS_KEY_ID="$(resticLocationField "$idx" S3_ACCESS_KEY)"
export AWS_SECRET_ACCESS_KEY="$(resticLocationField "$idx" S3_SECRET_KEY)"
;;
b2)
export B2_ACCOUNT_ID="$(resticLocationField "$idx" B2_ACCOUNT_ID)"
export B2_ACCOUNT_KEY="$(resticLocationField "$idx" B2_ACCOUNT_KEY)"
;;
esac
}
resticEnvUnset()
{
unset RESTIC_REPOSITORY RESTIC_PASSWORD RESTIC_SFTP_COMMAND
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY
unset B2_ACCOUNT_ID B2_ACCOUNT_KEY
unset SSHPASS
}
resticNextFreeIndex()
{
local last
last=$(resticAllLocationIndices | tail -1)
if [[ -z "$last" ]]; then
echo 1
else
echo $((last + 1))
fi
}