Compare commits
3 Commits
6066188ef1
...
ad4de2994a
Author | SHA1 | Date | |
---|---|---|---|
ad4de2994a | |||
6876a63250 | |||
d1d561cb70 |
8
Makefile
8
Makefile
|
@ -31,6 +31,14 @@ test-setup:
|
|||
#git ls-files -z | tar --null -T - -cf - | tar -C /tmp/test-borg -xvf -
|
||||
/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
|
||||
clean:
|
||||
rm -f README.html
|
||||
|
|
|
@ -89,7 +89,7 @@ Design
|
|||
- `/opt/borg/ssh/id_ecdsa`
|
||||
- configured on server for read-write operation
|
||||
- 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
|
||||
be run when the client has not been compromised.
|
||||
|
@ -104,7 +104,7 @@ Design
|
|||
- Backup script `/opt/borg/backup.py` uses configuration in
|
||||
`/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
|
||||
or newer, which is why the setup scripts download a specific version.
|
||||
or newer.
|
||||
|
||||
|
||||
|
||||
|
|
29
backup.py
29
backup.py
|
@ -241,10 +241,8 @@ def main(argv: list[str]):
|
|||
base = pathlib.Path(__file__).parent
|
||||
parser.add_argument('-c', '--config',
|
||||
help="Config file", default=str(base / "config.yaml"))
|
||||
parser.add_argument('-b', '--borg',
|
||||
help="Borg command", default=str(base / "borg.sh"))
|
||||
parser.add_argument('-N', '--notify',
|
||||
help="Notify command", default=str(base / "notify.sh"))
|
||||
parser.add_argument('-v', '--vars',
|
||||
help="Variables file", default=str(base / "vars.sh"))
|
||||
parser.add_argument('-n', '--dry-run', action="store_true",
|
||||
help="Just print log output, don't run borg")
|
||||
parser.add_argument('-d', '--debug', action="store_true",
|
||||
|
@ -253,6 +251,27 @@ def main(argv: list[str]):
|
|||
args = parser.parse_args()
|
||||
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
|
||||
backup = Backup(config, args.dry_run)
|
||||
captured_output: list[bytes] = []
|
||||
|
@ -275,7 +294,7 @@ def main(argv: list[str]):
|
|||
"--compression", "zstd,3",
|
||||
"--paths-from-stdin",
|
||||
"--paths-delimiter", "\\0",
|
||||
"::{hostname}-{now:%Y%m%d-%H%M%S}"],
|
||||
"::" + hostname + "-{now:%Y%m%d-%H%M%S}"],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
# These can be overridden when running this script
|
||||
HOSTNAME=${HOSTNAME:-$(hostname)}
|
||||
BACKUP_HOST=${BACKUP_HOST:-backup.jim.sh}
|
||||
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
|
||||
BORG_DIR="$(realpath "$(dirname "$0")")"
|
||||
|
@ -14,7 +15,7 @@ cd "${BORG_DIR}"
|
|||
BORG_BIN="${BORG_DIR}/Borg.bin"
|
||||
|
||||
# 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() {
|
||||
echo "Error at $1 line $2:"
|
||||
|
@ -86,7 +87,7 @@ create_borg_vars()
|
|||
export BACKUP_USER=${BACKUP_USER}
|
||||
export BACKUP_HOST=${BACKUP_HOST}
|
||||
export BACKUP_REPO=${BACKUP_REPO}
|
||||
export HOSTNAME=$(hostname)
|
||||
export HOSTNAME=${HOSTNAME}
|
||||
export BORG_REPO=${BORG_REPO}
|
||||
export BORG_HOST_ID=${HOSTID}
|
||||
export BORG_PASSCOMMAND="cat ${BORG_DIR}/passphrase"
|
||||
|
@ -273,7 +274,7 @@ EOF
|
|||
update_paths()
|
||||
{
|
||||
sed -i \
|
||||
-e "s!\${HOSTNAME}!$(hostname)!g" \
|
||||
-e "s!\${HOSTNAME}!${HOSTNAME}!g" \
|
||||
-e "s!\${BORG_DIR}!${BORG_DIR}!g" \
|
||||
-e "s!\${BACKUP_USER}!${BACKUP_USER}!g" \
|
||||
-e "s!\${BACKUP_HOST}!${BACKUP_HOST}!g" \
|
||||
|
@ -287,14 +288,14 @@ update_paths()
|
|||
|
||||
git_setup()
|
||||
{
|
||||
if ! git checkout -b "setup-$(hostname)" ; then
|
||||
if ! git checkout -b "setup-${HOSTNAME}" ; then
|
||||
warn "Git setup failed; ignoring"
|
||||
return
|
||||
fi
|
||||
|
||||
log "Committing local changes to git"
|
||||
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:"
|
||||
|
@ -315,11 +316,11 @@ git_setup
|
|||
echo
|
||||
notice "Add these two passwords to Bitwarden:"
|
||||
notice ""
|
||||
notice " Name: borg $(hostname)"
|
||||
notice " Name: borg ${HOSTNAME}"
|
||||
notice " Username: read-write ssh key"
|
||||
notice " Password: $PASS_SSH"
|
||||
notice ""
|
||||
notice " Name: borg $(hostname)"
|
||||
notice " Name: borg ${HOSTNAME}"
|
||||
notice " Username: repo key"
|
||||
notice " Password: $PASS_REPOKEY"
|
||||
notice ""
|
||||
|
|
Loading…
Reference in New Issue
Block a user