Initial commit

This commit is contained in:
Antoine Martin 2023-05-01 14:46:00 -04:00
commit 969e19e14a
Signed by: forge
GPG key ID: D62A472A4AA7D541
2 changed files with 76 additions and 0 deletions

20
README.md Normal file
View file

@ -0,0 +1,20 @@
# bacoid
## Purpose
Sends incremental backups using syncoid and zfs config variables
## How to use
* Set target machine with `zfs set syncoid:target_a=user@backup.com:22 rpool`
* Set target pool with `zfs set syncoid:pool_a=bkppool rpool`
* Set current machine with `zfs set syncoid:machine=hal rpool`
Due to zfs setting these values recursively, bacoid will then go down the
pool and send whatever matches using the configured settings. In the last
example, this means that syncoid will send `rpool` and all of its children
to `user@backup.com:bkppool/user/hal/rpool`
If you want to certain children to be skipped, you can do the following:
* `zfs set syncoid:pool_a='' rpool/skip-me`
## Dependencies
* bash

56
bacoid.sh Normal file
View file

@ -0,0 +1,56 @@
#!/bin/bash
subvolArray=($(zfs get syncoid:pool_a -H -o name,value | grep -v '@' | awk '{if($2 != "-" && $2 != "") print $1}'))
COUNT=1
for subvol in ${subvolArray[@]}; do
targetArray[$COUNT]="$(zfs get syncoid:target_a ${subvol} | grep -v 'NAME' | awk '{print $3}')"
COUNT=$(( ${COUNT} + 1 ))
done
targetArray=($(printf '%s\n' ${targetArray[@]} | awk '!a[$0]++'))
for target in ${targetArray[@]}; do
[[ ${target} != *@* ]] && continue
echo "Testing SSH connection to ${target}"
USERHOST="$(sed 's|:.*||' <<< ${target})"
HOST="$(sed 's|.*@||' <<< ${USERHOST})"
USER="$(sed 's|@.*||' <<< ${USERHOST})"
PORT="$(sed 's|.*:||' <<< ${target})"
if [[ ! -f "${HOME}/.ssh/bkp_rsa" ]]; then
echo "Generating bkp_rsa key"
ssh-keygen -N "" -f "${HOME}/.ssh/bkp_rsa"
fi
ssh -i "${HOME}/.ssh/bkp_rsa" \
-p ${PORT} \
-o ControlPath=none \
-o LogLevel=INFO \
-o PreferredAuthentications=publickey \
-o IdentitiesOnly=yes ${USERHOST} exit
[[ $? -ne 0 ]] && ssh-copy-id -p ${PORT} -i "${HOME}/.ssh/bkp_rsa" ${USERHOST}
done
for subvol in ${subvolArray[@]}; do
TARGET="$(zfs get syncoid:target_a ${subvol} | grep -v NAME | awk '{print $3}')"
if [[ ${target} != "-" ]]; then
USERHOST="$(sed 's|:.*||' <<< ${TARGET})"
HOST="$(sed 's|.*@||' <<< ${USERHOST})"
USER="$(sed 's|@.*||' <<< ${USERHOST})"
PORT="$(sed 's|.*:||' <<< ${TARGET})"
MACHINE="$(zfs get syncoid:machine ${subvol} | grep -v NAME | awk '{print $3}')"
[[ ${MACHINE} == '-' ]] && { echo "syncoid:machine not set for ${subvol}"; continue; }
POOL="$(zfs get syncoid:pool_a ${subvol} | grep -v NAME | awk '{print $3}')"
[[ ${POOL} == '-' ]] && { echo "syncoid:pool_a not set for ${subvol}"; continue; }
echo "Sending ${subvol} to ${USERHOST}:${POOL}/$USER/$MACHINE/$subvol"
syncoid --sendoptions="w" --recvoptions="u" --sshport=${PORT} --sshkey="${HOME}/.ssh/bkp_rsa" --no-sync-snap --no-privilege-elevation ${subvol} ${USERHOST}:${POOL}/${USER}/${MACHINE}/${subvol}
else
MACHINE="$(zfs get syncoid:machine ${subvol} | grep -v NAME | awk '{print $3}')"
[[ ${MACHINE} == '-' ]] && { echo "syncoid:machine not set for ${subvol}"; continue; }
POOL="$(zfs get syncoid:pool_a ${subvol} | grep -v NAME | awk '{print $3}')"
[[ ${POOL} == '-' ]] && { echo "syncoid:pool_a not set for ${subvol}"; continue; }
echo "Sending ${subvol} to ${POOL}/$MACHINE/$subvol"
syncoid --sendoptions="w" --recvoptions="u" --no-sync-snap ${subvol} ${POOL}/${MACHINE}/${subvol}
fi
done