Initial setup
=============

Run on client:

    sudo git clone https://git.jim.sh/jim/borg-setup.git /opt/borg
    sudo /opt/borg/initial-setup.sh

Customize `/opt/borg/config.yaml` as desired.



Cheat sheet
===========

*After setup, the copy of this file on the client will have the
variables in this section filled in automatically*

## Configuration

    Hostname: ${HOSTNAME}
    Base directory: ${BORG_DIR}
    Destination: ${BACKUP_USER}@${BACKUP_HOST}
    Repository: ${BACKUP_REPO}

## Commands

See when next backup is scheduled:

    systemctl list-timers borg-backup.timer

See status of most recent backup:

    systemctl status --full --lines 999999 --no-pager --all borg-backup

Watch log:

    journalctl --all --follow --unit borg-backup

Start backup now:

    sudo systemctl start borg-backup

Interrupt backup in progress:

    sudo systemctl stop borg-backup

Show backups and related info:

    sudo ${BORG_DIR}/borg.sh info
    sudo ${BORG_DIR}/borg.sh list

Run Borg using the read-write SSH key:

    sudo ${BORG_DIR}/borg.sh --rw list

Mount and look at files:

    mkdir mnt
    sudo ${BORG_DIR}/borg.sh mount :: mnt
    sudo -s # to explore as root
    sudo umount mnt


## Compaction and remote access

Old backups are "pruned" automatically, but because the SSH key is
append-only, no space is actually recovered on the server, it's just
marked for deletion.  If you are sure that the client system was not
compromised, then you can run compaction manually directly on the
backup host by logging in via SSH (bitwarden `ssh ${BACKUP_HOST} /
${BACKUP_USER}`) and compacting there:

    ssh ${BACKUP_USER}@${BACKUP_HOST} borg/borg compact --verbose --progress ${BACKUP_REPO}

This doesn't require the repo key.  It shouldn't be entered on the untrusted
backup host, so for operations that need it, use a trusted host and run borg
remotely instead, e.g.:

    ${BORG_DIR}/Borg.bin --remote-path borg/borg info ${BACKUP_USER}@${BACKUP_HOST}:borg/${HOSTNAME}

The repo passphrase is in bitwarden `borg ${HOSTNAME}/ repo key`.


Design
======

- On server, we have a separate user account "jim-backups".  Password
  for this account is in bitwarden in the "Backups" folder, under `ssh
  backup.jim.sh`.

- Repository keys are repokeys, which get stored on the server, inside
  the repo.  Passphrases are stored:
  - on clients (in `/opt/borg/passphrase`, for making backups)
  - in bitwarden (under `borg <hostname>`, user `repo key`)

- Each client has two passwordless SSH keys for connecting to the server:
  - `/opt/borg/ssh/id_ecdsa_appendonly`
    - configured on server for append-only operation
    - used for making backups
  - `/opt/borg/ssh/id_ecdsa_notify`
    - configured on server for running `borg/notify.sh` only
    - used for sending email notifications on errors

- Systemd timers start daily backups:

      /etc/systemd/system/borg-backup.service -> /opt/borg/borg-backup.service
      /etc/systemd/system/borg-backup.timer -> /opt/borg/borg-backup.timer

- 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 or newer.


Notes
=====

# Building Borg.bin binary from git

    git clone https://github.com/borgbackup/borg.git
    cd borg
    virtualenv --python=python3 borg-env
    source borg-env/bin/activate
    pip install -r requirements.d/development.txt
    pip install pyinstaller
    pip install llfuse
    pip install -e .[llfuse]
    pyinstaller --clean --noconfirm scripts/borg.exe.spec
    pip install staticx
    staticx -l /lib/x86_64-linux-gnu/libm.so.6 dist/borg.exe Borg.bin

Then see `dist/borg.exe`.  Confirm the version with `dist/borg.exe --version`.

*Note:* This uses the deprecated `llfuse` instead of the newer `pyfuse3`.
`pyfuse3` doesn't work because, at minimum, it pulls in `trio` which
requires `ssl` which is explicitly excluded by
`scripts/borg.exe.spec`.
