Compare commits

...

3 Commits

4 changed files with 43 additions and 15 deletions

View File

@ -31,6 +31,14 @@ test-setup:
#git ls-files -z | tar --null -T - -cf - | tar -C /tmp/test-borg -xvf - #git ls-files -z | tar --null -T - -cf - | tar -C /tmp/test-borg -xvf -
/tmp/test-borg/initial-setup.sh /tmp/test-borg/initial-setup.sh
# Pull master and rebase "setup-$HOSTNAME" branch onto it
.PHONY: rebase
rebase:
git checkout master
git pull
git checkout -
git rebase master
.PHONY: clean .PHONY: clean
clean: clean:
rm -f README.html rm -f README.html

View File

@ -89,7 +89,7 @@ Design
- `/opt/borg/ssh/id_ecdsa` - `/opt/borg/ssh/id_ecdsa`
- configured on server for read-write operation - configured on server for read-write operation
- used for manual recovery, management, pruning - used for manual recovery, management, pruning
- password in bitwarden (under `borg [hostname]`, user `read-write ssh key`) - password in bitwarden (under `borg <hostname>`, user `read-write ssh key`)
- Pruning requires the password and is a manual operation, and should only - Pruning requires the password and is a manual operation, and should only
be run when the client has not been compromised. be run when the client has not been compromised.
@ -104,7 +104,7 @@ Design
- Backup script `/opt/borg/backup.py` uses configuration in - Backup script `/opt/borg/backup.py` uses configuration in
`/opt/borg/config.yaml` to generate our own list of files, excluding `/opt/borg/config.yaml` to generate our own list of files, excluding
anything that's too large by default. This requires borg 1.2.0b1 anything that's too large by default. This requires borg 1.2.0b1
or newer, which is why the setup scripts download a specific version. or newer.

View File

@ -241,10 +241,8 @@ def main(argv: list[str]):
base = pathlib.Path(__file__).parent base = pathlib.Path(__file__).parent
parser.add_argument('-c', '--config', parser.add_argument('-c', '--config',
help="Config file", default=str(base / "config.yaml")) help="Config file", default=str(base / "config.yaml"))
parser.add_argument('-b', '--borg', parser.add_argument('-v', '--vars',
help="Borg command", default=str(base / "borg.sh")) help="Variables file", default=str(base / "vars.sh"))
parser.add_argument('-N', '--notify',
help="Notify command", default=str(base / "notify.sh"))
parser.add_argument('-n', '--dry-run', action="store_true", parser.add_argument('-n', '--dry-run', action="store_true",
help="Just print log output, don't run borg") help="Just print log output, don't run borg")
parser.add_argument('-d', '--debug', action="store_true", parser.add_argument('-d', '--debug', action="store_true",
@ -253,6 +251,27 @@ def main(argv: list[str]):
args = parser.parse_args() args = parser.parse_args()
config = Config(args.config) config = Config(args.config)
# Parse variables from vars.sh
hostname = os.uname().nodename
borg = str(base / "borg.sh")
notify = str(base / "notify.sh")
try:
with open(args.vars) as f:
for line in f:
m = re.match(r"\s*export\s*([A-Z_]+)=(.*)", line)
if not m:
continue
var = m.group(1)
value = m.group(2)
if var == "HOSTNAME":
hostname = value
if var == "BORG":
borg = value
if var == "BORG_DIR":
notify = pathlib.Path(value) / "notify.sh"
except Exception as e:
self.log('W', f"failed to parse variables from {args.vars}: {str(e)}")
# Run backup # Run backup
backup = Backup(config, args.dry_run) backup = Backup(config, args.dry_run)
captured_output: list[bytes] = [] captured_output: list[bytes] = []
@ -275,7 +294,7 @@ def main(argv: list[str]):
"--compression", "zstd,3", "--compression", "zstd,3",
"--paths-from-stdin", "--paths-from-stdin",
"--paths-delimiter", "\\0", "--paths-delimiter", "\\0",
"::{hostname}-{now:%Y%m%d-%H%M%S}"], "::" + hostname + "-{now:%Y%m%d-%H%M%S}"],
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT) stderr=subprocess.STDOUT)

View File

@ -1,9 +1,10 @@
#!/bin/bash #!/bin/bash
# These can be overridden when running this script # These can be overridden when running this script
HOSTNAME=${HOSTNAME:-$(hostname)}
BACKUP_HOST=${BACKUP_HOST:-backup.jim.sh} BACKUP_HOST=${BACKUP_HOST:-backup.jim.sh}
BACKUP_USER=${BACKUP_USER:-jim-backups} BACKUP_USER=${BACKUP_USER:-jim-backups}
BACKUP_REPO=${BACKUP_REPO:-borg/$(hostname)} BACKUP_REPO=${BACKUP_REPO:-borg/${HOSTNAME}}
# Main dir is where this repo was checked out # Main dir is where this repo was checked out
BORG_DIR="$(realpath "$(dirname "$0")")" BORG_DIR="$(realpath "$(dirname "$0")")"
@ -14,7 +15,7 @@ cd "${BORG_DIR}"
BORG_BIN="${BORG_DIR}/Borg.bin" BORG_BIN="${BORG_DIR}/Borg.bin"
# Use stable host ID in case MAC address changes # Use stable host ID in case MAC address changes
HOSTID="$(hostname -f)@$(python -c 'import uuid;print(uuid.getnode())')" HOSTID="${HOSTNAME}@$(python -c 'import uuid;print(uuid.getnode())')"
function error_handler() { function error_handler() {
echo "Error at $1 line $2:" echo "Error at $1 line $2:"
@ -86,7 +87,7 @@ create_borg_vars()
export BACKUP_USER=${BACKUP_USER} export BACKUP_USER=${BACKUP_USER}
export BACKUP_HOST=${BACKUP_HOST} export BACKUP_HOST=${BACKUP_HOST}
export BACKUP_REPO=${BACKUP_REPO} export BACKUP_REPO=${BACKUP_REPO}
export HOSTNAME=$(hostname) export HOSTNAME=${HOSTNAME}
export BORG_REPO=${BORG_REPO} export BORG_REPO=${BORG_REPO}
export BORG_HOST_ID=${HOSTID} export BORG_HOST_ID=${HOSTID}
export BORG_PASSCOMMAND="cat ${BORG_DIR}/passphrase" export BORG_PASSCOMMAND="cat ${BORG_DIR}/passphrase"
@ -273,7 +274,7 @@ EOF
update_paths() update_paths()
{ {
sed -i \ sed -i \
-e "s!\${HOSTNAME}!$(hostname)!g" \ -e "s!\${HOSTNAME}!${HOSTNAME}!g" \
-e "s!\${BORG_DIR}!${BORG_DIR}!g" \ -e "s!\${BORG_DIR}!${BORG_DIR}!g" \
-e "s!\${BACKUP_USER}!${BACKUP_USER}!g" \ -e "s!\${BACKUP_USER}!${BACKUP_USER}!g" \
-e "s!\${BACKUP_HOST}!${BACKUP_HOST}!g" \ -e "s!\${BACKUP_HOST}!${BACKUP_HOST}!g" \
@ -287,14 +288,14 @@ update_paths()
git_setup() git_setup()
{ {
if ! git checkout -b "setup-$(hostname)" ; then if ! git checkout -b "setup-${HOSTNAME}" ; then
warn "Git setup failed; ignoring" warn "Git setup failed; ignoring"
return return
fi fi
log "Committing local changes to git" log "Committing local changes to git"
git add README.md borg-backup.service borg-backup.timer vars.sh git add README.md borg-backup.service borg-backup.timer vars.sh
git commit -a -m "autocommit after initial setup on $(hostname)" git commit -a -m "autocommit after initial setup on ${HOSTNAME}"
} }
log "Configuration:" log "Configuration:"
@ -315,11 +316,11 @@ git_setup
echo echo
notice "Add these two passwords to Bitwarden:" notice "Add these two passwords to Bitwarden:"
notice "" notice ""
notice " Name: borg $(hostname)" notice " Name: borg ${HOSTNAME}"
notice " Username: read-write ssh key" notice " Username: read-write ssh key"
notice " Password: $PASS_SSH" notice " Password: $PASS_SSH"
notice "" notice ""
notice " Name: borg $(hostname)" notice " Name: borg ${HOSTNAME}"
notice " Username: repo key" notice " Username: repo key"
notice " Password: $PASS_REPOKEY" notice " Password: $PASS_REPOKEY"
notice "" notice ""