move systemd prefixes to software prefixes
This commit is contained in:
12
active/software_borg/backup.service
Normal file
12
active/software_borg/backup.service
Normal file
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Runs backup script for {{ repo_name }}
|
||||
After=network.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Restart=no
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/script/backup-{{ repo_name }}.sh
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
93
active/software_borg/backup.sh.j2
Normal file
93
active/software_borg/backup.sh.j2
Normal file
@@ -0,0 +1,93 @@
|
||||
#!/bin/sh
|
||||
|
||||
{% for service in stop_services %}
|
||||
systemctl stop {{ service }}
|
||||
{% endfor %}
|
||||
|
||||
{% for service in stop_user_services %}
|
||||
systemctl --user --machine={{ systemd_user }}@.host stop {{ service }}
|
||||
{% endfor %}
|
||||
|
||||
# Setting this, so the repo does not need to be given on the commandline:
|
||||
export BORG_REPO={{ borg_user }}@{{ borg_host }}:{{ repo_name }}
|
||||
|
||||
# See the section "Passphrase notes" for more infos.
|
||||
export BORG_PASSPHRASE={{ borg_passphrase }}
|
||||
|
||||
# some helpers and error handling:
|
||||
info() { printf "\n%s %s\n\n" "$( date )" "$*" >&2; }
|
||||
trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM
|
||||
|
||||
info "Starting backup"
|
||||
|
||||
# Backup the most important directories into an archive named after
|
||||
# the machine this script is currently running on:
|
||||
|
||||
borg create \
|
||||
--verbose \
|
||||
--filter AME \
|
||||
--list \
|
||||
--stats \
|
||||
--show-rc \
|
||||
--compression lz4 \
|
||||
--exclude-caches \
|
||||
--exclude 'home/*/.cache/*' \
|
||||
--exclude 'var/tmp/*' \
|
||||
--exclude 'home/*/.snapshots/*' \
|
||||
{% for dir in exclude_dirs %}
|
||||
--exclude '{{ dir }}' \
|
||||
{% endfor %}
|
||||
\
|
||||
::'{hostname}-{now}' \
|
||||
{% for dir in backup_dirs %}
|
||||
{{ dir }} \
|
||||
{% endfor %}
|
||||
|
||||
backup_exit=$?
|
||||
|
||||
{% for service in stop_services %}
|
||||
systemctl start {{ service }}
|
||||
{% endfor %}
|
||||
|
||||
{% for service in stop_user_services %}
|
||||
systemctl --user --machine={{ systemd_user }}@.host start {{ service }}
|
||||
{% endfor %}
|
||||
|
||||
info "Pruning repository"
|
||||
|
||||
# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly
|
||||
# archives of THIS machine. The '{hostname}-*' matching is very important to
|
||||
# limit prune's operation to this machine's archives and not apply to
|
||||
# other machines' archives also:
|
||||
|
||||
borg prune \
|
||||
--list \
|
||||
--glob-archives '{hostname}-*' \
|
||||
--show-rc \
|
||||
--keep-daily {{ keep_daily }} \
|
||||
--keep-weekly {{ keep_weekly }} \
|
||||
--keep-monthly {{ keep_monthly }} \
|
||||
|
||||
prune_exit=$?
|
||||
|
||||
# actually free repo disk space by compacting segments
|
||||
|
||||
info "Compacting repository"
|
||||
|
||||
borg compact
|
||||
|
||||
compact_exit=$?
|
||||
|
||||
# use highest exit code as global exit code
|
||||
global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit ))
|
||||
global_exit=$(( compact_exit > global_exit ? compact_exit : global_exit ))
|
||||
|
||||
if [ ${global_exit} -eq 0 ]; then
|
||||
info "Backup, Prune, and Compact finished successfully"
|
||||
elif [ ${global_exit} -eq 1 ]; then
|
||||
info "Backup, Prune, and/or Compact finished with warnings"
|
||||
else
|
||||
info "Backup, Prune, and/or Compact finished with errors"
|
||||
fi
|
||||
|
||||
exit ${global_exit}
|
||||
11
active/software_borg/backup.timer
Normal file
11
active/software_borg/backup.timer
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Run Backup backup-{{ repo_name }}.service every day
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 2:00:00
|
||||
AccuracySec=10min
|
||||
Persistent=true
|
||||
Unit=backup-{{ repo_name }}.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
255
active/software_borg/borg.md
Normal file
255
active/software_borg/borg.md
Normal file
@@ -0,0 +1,255 @@
|
||||
# Borg Backup
|
||||
|
||||
- [Borg Backup](#borg-backup)
|
||||
- [Install Borg](#install-borg)
|
||||
- [Set up a laptop or workstation client](#set-up-a-laptop-or-workstation-client)
|
||||
- [Set up a new server client](#set-up-a-new-server-client)
|
||||
- [Create a Backup Service](#create-a-backup-service)
|
||||
- [Check backup service logs](#check-backup-service-logs)
|
||||
- [Run a Manual Backup](#run-a-manual-backup)
|
||||
- [Back up and Entire System](#back-up-and-entire-system)
|
||||
- [Upgrade a Borg Repo](#upgrade-a-borg-repo)
|
||||
|
||||
## Install Borg
|
||||
|
||||
<https://borgbackup.readthedocs.io/en/stable/deployment/central-backup-server.html#user-and-group>
|
||||
|
||||
User: backup
|
||||
|
||||
Group: backup
|
||||
|
||||
Shell: /bin/bash (or other capable to run the borg serve command)
|
||||
|
||||
Home: /home/backup
|
||||
|
||||
```bash
|
||||
dnf install borgbackup
|
||||
|
||||
useradd backup
|
||||
mkdir /home/backup/.ssh
|
||||
touch /home/backup/.ssh/authorized_keys
|
||||
chown -R backup:backup /home/backup/.ssh
|
||||
```
|
||||
|
||||
## Set up a laptop or workstation client
|
||||
|
||||
For backing up your laptop or personal account.
|
||||
|
||||
1. On your personal account, set up the borg connection
|
||||
|
||||
```bash
|
||||
export BACKUP_HOST="borg.reeselink.com"
|
||||
|
||||
ssh-keygen -C ${USER}@${HOSTNAME} -f ~/.ssh/id_${BACKUP_HOST}
|
||||
|
||||
cat <<EOF >> ~/.ssh/config
|
||||
Host ${BACKUP_HOST}
|
||||
Hostname ${BACKUP_HOST}
|
||||
IdentityFile ~/.ssh/id_${BACKUP_HOST}
|
||||
User backup
|
||||
Port 22
|
||||
EOF
|
||||
|
||||
echo "export CLIENT_FQDN=${USER}.${HOSTNAME}.reeselink.com"
|
||||
echo "export SSH_PUBKEY=\"$(cat ~/.ssh/id_${BACKUP_HOST}.pub)\""
|
||||
```
|
||||
|
||||
2. On the borg backup server as the backup user:
|
||||
|
||||
```bash
|
||||
# Use echo from above
|
||||
export CLIENT_FQDN=
|
||||
export SSH_PUBKEY=
|
||||
|
||||
# Create the authkey entry to restrict the user's access to the borg repo folder
|
||||
export BORG_COMMAND="cd /home/backup/repos/${CLIENT_FQDN}; borg serve --restrict-to-path /home/backup/repos/${CLIENT_FQDN}"
|
||||
export AUTHKEY_ENTRY="command=\"${BORG_COMMAND}\",restrict ${SSH_PUBKEY}"
|
||||
echo $AUTHKEY_ENTRY >> /home/backup/.ssh/authorized_keys
|
||||
|
||||
# Create the directory
|
||||
mkdir repos/${CLIENT_FQDN}
|
||||
```
|
||||
|
||||
3. On your personal account, create the repo and your first backup
|
||||
|
||||
```bash
|
||||
# Do not include the first / in the path
|
||||
export PATH_TO_BACKUP=home/${USER}
|
||||
export BACKUP_HOST="borg.reeselink.com"
|
||||
export BORG_REPO=${BACKUP_HOST}:home
|
||||
|
||||
# If not initialized, do that now
|
||||
borg init --encryption none $BORG_REPO
|
||||
borg list
|
||||
|
||||
# Run backup and timestamp it
|
||||
borg create \
|
||||
--verbose \
|
||||
--filter AME \
|
||||
--list \
|
||||
--stats \
|
||||
--progress \
|
||||
--show-rc \
|
||||
--compression lz4 \
|
||||
--exclude-caches \
|
||||
${BORG_REPO}::$(date +"%F-%H-%M-%S") \
|
||||
/${PATH_TO_BACKUP}
|
||||
|
||||
# Mount a borg archive
|
||||
borg mount $BORG_REPO::2025-05-14-00-44-05 /mnt/
|
||||
|
||||
# Restore a borg archive to a location (dry run)
|
||||
# First, cd to the location you want to extract to
|
||||
cd ~
|
||||
# Then, extract to that location. --strip-components takes the first n items off a path
|
||||
borg extract --dry-run --list --strip-components 2 $BORG_REPO::my-files home/USERNAME
|
||||
```
|
||||
|
||||
## Set up a new server client
|
||||
|
||||
Backups will be run as the root user. Generate them an SSH key to
|
||||
|
||||
On the server as root:
|
||||
|
||||
```bash
|
||||
export BACKUP_HOST="borg.reeselink.com"
|
||||
|
||||
ssh-keygen -C root@${HOSTNAME} -f ~/.ssh/id_${BACKUP_HOST}
|
||||
|
||||
cat <<EOF >> ~/.ssh/config
|
||||
Host ${BACKUP_HOST}
|
||||
Hostname ${BACKUP_HOST}
|
||||
IdentityFile ~/.ssh/id_${BACKUP_HOST}
|
||||
User backup
|
||||
Port 22
|
||||
EOF
|
||||
```
|
||||
|
||||
Now on borg.reeselink.com as root:
|
||||
|
||||
```bash
|
||||
export CLIENT_FQDN="fqdn.reeseapps.com"
|
||||
export SSH_PUBKEY="ssh-rsa abcd1234 backup@fqdn.something.com"
|
||||
export BORG_COMMAND="cd /home/backup/repos/${CLIENT_FQDN}; borg serve --restrict-to-path /home/backup/repos/${CLIENT_FQDN}"
|
||||
export AUTHKEY_ENTRY="command=\"${BORG_COMMAND}\",restrict ${SSH_PUBKEY}"
|
||||
echo $AUTHKEY_ENTRY >> /home/backup/.ssh/authorized_keys
|
||||
mkdir /home/backup/repos/${CLIENT_FQDN}
|
||||
chown -R backup:backup /home/backup/repos/${CLIENT_FQDN}
|
||||
```
|
||||
|
||||
## Create a Backup Service
|
||||
|
||||
Create your vars file in `secrets/host_vars.yaml`
|
||||
|
||||
```yaml
|
||||
repo_name: my_repo
|
||||
borg_user: backup
|
||||
borg_host: borg.reeselink.com
|
||||
borg_passphrase: ""
|
||||
backup_dirs:
|
||||
- /home/foobar
|
||||
exclude_dirs: []
|
||||
keep_daily: 7
|
||||
keep_weekly: 4
|
||||
keep_monthly: 1
|
||||
stop_services: []
|
||||
stop_user_services:
|
||||
- foobar
|
||||
```
|
||||
|
||||
```bash
|
||||
# Update all existing backup services for podman
|
||||
for var_file in $(ls active/systemd_borg/secrets); do
|
||||
ansible-playbook \
|
||||
-i ansible/inventory.yaml \
|
||||
-l 3dserver \
|
||||
active/systemd_borg/install_backup.yaml \
|
||||
-e "@active/systemd_borg/secrets/$var_file"
|
||||
done
|
||||
```
|
||||
|
||||
## Check backup service logs
|
||||
|
||||
```bash
|
||||
export SERVER_SSH_NAME=
|
||||
ssh $SERVER_SSH_NAME journalctl -u 'backup-*' -f
|
||||
```
|
||||
|
||||
## Run a Manual Backup
|
||||
|
||||
```bash
|
||||
borg list borg.reeselink.com:home
|
||||
|
||||
# Do not include the first / in the path
|
||||
export PATH_TO_BACKUP=home/ducoterra
|
||||
export BORG_REPO=borg.reeselink.com:home
|
||||
|
||||
# If not initialized, do that now
|
||||
borg init --encryption none $BORG_REPO
|
||||
|
||||
# Run backup and timestamp it
|
||||
borg create \
|
||||
--verbose \
|
||||
--filter AME \
|
||||
--list \
|
||||
--stats \
|
||||
--progress \
|
||||
--show-rc \
|
||||
--compression lz4 \
|
||||
--exclude-caches \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.cache" \
|
||||
-e "re:^${PATH_TO_BACKUP}/\.var/app/[^/]+/cache/" \
|
||||
-e "CACHEDIR.TAG" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.local/share/gnome-boxes" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.var/app/org.gnome.Boxes" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.var/app/org.gnome.BoxesDevel" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.local/share/bottles" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.var/app/com.usebottles.bottles" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.local/share/libvirt" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.config/libvirt" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.local/share/containers" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.local/share/docker" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.npm" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.ollama" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/Downloads" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/Nextcloud" \
|
||||
${BORG_REPO}::$(date +"%F-%H-%M-%S") \
|
||||
/${PATH_TO_BACKUP}
|
||||
|
||||
# Mount a borg archive
|
||||
borg mount $BORG_REPO::2025-05-14-00-44-05 /mnt/
|
||||
|
||||
# Restore a borg archive to a location (dry run)
|
||||
borg extract --dry-run --list --strip-components 1 $BORG_REPO::my-files home/USERNAME
|
||||
```
|
||||
|
||||
### Back up and Entire System
|
||||
|
||||
```bash
|
||||
export BORG_REPO=borg.reeselink.com:root
|
||||
|
||||
borg create \
|
||||
--verbose \
|
||||
--filter AME \
|
||||
--list \
|
||||
--stats \
|
||||
--progress \
|
||||
--show-rc \
|
||||
--compression lz4 \
|
||||
--exclude root/.cache \
|
||||
--exclude var/lib/docker \
|
||||
--exclude var/lib/containers \
|
||||
--exclude usr/share/ollama \
|
||||
--exclude home \
|
||||
--exclude proc \
|
||||
--exclude dev \
|
||||
--exclude sys \
|
||||
--exclude tmp \
|
||||
--exclude .snapshots \
|
||||
${BORG_REPO}::$(date +"%F-%H-%M-%S") \
|
||||
/
|
||||
```
|
||||
|
||||
## Upgrade a Borg Repo
|
||||
|
||||
<https://borgbackup.readthedocs.io/en/stable/usage/upgrade.html>
|
||||
39
active/software_borg/install_backup.yaml
Normal file
39
active/software_borg/install_backup.yaml
Normal file
@@ -0,0 +1,39 @@
|
||||
- name: Create Backup Service
|
||||
hosts: all
|
||||
vars_files:
|
||||
- secrets/vars.yaml
|
||||
tasks:
|
||||
- name: Create /usr/local/script dir
|
||||
ansible.builtin.file:
|
||||
path: /usr/local/script
|
||||
state: directory
|
||||
mode: '0755'
|
||||
- name: Copy backup-{{ repo_name }}.service
|
||||
template:
|
||||
src: backup.service
|
||||
dest: /etc/systemd/system/backup-{{ repo_name }}.service
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
- name: Copy backup-{{ repo_name }}.timer
|
||||
template:
|
||||
src: backup.timer
|
||||
dest: /etc/systemd/system/backup-{{ repo_name }}.timer
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
- name: Template backup-{{ repo_name }}.sh
|
||||
template:
|
||||
src: backup.sh.j2
|
||||
dest: /usr/local/script/backup-{{ repo_name }}.sh
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0744'
|
||||
- name: Initialize Repo {{ borg_user }}@{{ borg_host }}:{{ repo_name }}
|
||||
script: /usr/bin/borg init -e none {{ borg_user }}@{{ borg_host }}:{{ repo_name }}
|
||||
ignore_errors: yes
|
||||
- name: Reload backup timer backup-{{ repo_name }}.timer
|
||||
ansible.builtin.systemd_service:
|
||||
name: backup-{{ repo_name }}.timer
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
Reference in New Issue
Block a user