for reference of those interested.
my bashly based bash cli for restic which can use a yaml file for a “job”
run
BACKUP_PASSWORD=xxx backup -s /opt/backup/jobs/gate/opt.yml
generates restic commands
RESTIC_PASSWORD=xxx /opt/bin/restic -r rest:https://backup.mynetwork.net/gateway/opt -H router.mynetwork.net --set-path /opt backup /mnt/238/gate/opt --iexclude-file /mnt/238/gate/opt/exclude.bac
/opt/backup/jobs/gate/opt.yml
# actual network hostname
host: router.mynetwork.net
# alternate to host for use in snaphsot
hostname: gateway
# target:
# source path by default
# path:
# <hostname>/ by default
# mount:
source:
mount: /mnt/238/gate
path: /opt
server:
# user: sysadmin
host: backup.mynetwork.net
#port: 9500
secure: true
bashly yaml
name: dbackup
help: differential backup using restic
version: 0.1.0
environment_variables:
- name: BACKUP_EXCLUDE
help: path to file of excludes
- name: BACKUP_INCLUDE
help: path to directory of includes
- name: BACKUP_SETTINGS
help: path to default settings file
- name: BACKUP_PASSWORD
help: path to default settings file
- name: BACKUP_SERVER
help: URL of Restic rest server
- name: BACKUP_DIR
help: Backup Directory
- name: BACKUP_MOUNT_POINT
help: mount point of source if mounted external to host
args:
- name: source
help: source directory to be backed up, default is $PWD
- name: target
help: "target directory for backup"
flags:
- long: --password
short: -p
arg: password
help: repo password (or file path) for backup repository
- long: --remote
short: -r
help: backup to a remote machine
- long: --server
arg: url
help: url of restic rest server
- long: --init
help: initialize repo (default is backup)
- long: --snap
help: list repo snapshots
- long: --view
short: -v
help: mount snapshot for viewing (default is BACKUP_MOUNT or /opt/backup/view)
- long: --view-path
help: set custom mount point path for viewing of snapshot, --view not required if set
arg: path
- long: --prune
arg: prune
help: prune repo (default is backup). true for default prune or path to prune settings
- long: --password
short: -p
arg: password
help: repo password (or file path) for backup repository
- long: --settings
short: -s
arg: syaml
help: path to settings file (yaml). Keys are same as long
- long: --host
short: -h
arg: thost
help: host on remote to target to receive backup
- long: --shost
arg: shost
help: remote to host of source
- long: --user
short: -u
arg: tuser
help: user on remote host
- long: --suser
arg: suser
help: remote user on source host
- long: --sshcfg
arg: sshcfg
help: path to sshcfg file
- long: --options
short: -o
arg: options
help: additional options (restic or rsync)
- long: --include_file
short: -i
arg: include
help: include file
- long: --exclude_file
short: -e
arg: exclude
help: exclude file
- long: --dir
short: -d
help: append source directory path to target directory
examples:
- backup -p password . /target/dir
- backup -s /path/to/settings/yaml/file
bash for backup bashly generate
#!/bin/bash
echo "running root command"
inspect_args
# module_load ssh
module_load confirm
module_load path
local settings=${args[--settings]}
if [[ -f $settings ]]; then
echo loading settings file $settings
module_load yaml
eval $(parse_yaml $settings "s_")
echo $s_source
echo $s_target
echo $s_host
fi
if [[ $s_server_host ]]; then
s_server="http$([[ $s_server_secure ]] && echo "s")://${s_server_host}$([[ $s_server_port ]] && echo :${s_server_port} || echo "")"
fi
local password=${args[--password]:-$BACKUP_PASSWORD}
password=${password:-$s_password}
[[ ! $password ]] && echo restic requires a backup repository password, exiting && return 2
password="RESTIC_PASSWORD=${password}"
local server=${args[--server]:-$BACKUP_SERVER}
server=${server:-$s_server}
local hostname=${args[--hostname]:-$s_hostname}
hostname=${hostname:-$s_host}
hostname=${hostname:-$HOSTNAME}
local backup_dir=${args[--backup_dir]:-$BACKUP_DIR}
backup_dir=${backup_dir:-$s_backup_dir}
backup_dir=${backup_dir:-"/backup"}
local smount=${args[--source_mount]:-$BACKUP_SOURCE_MOUNT}
smount=${smount:-$s_source_mount}
echo smount: $smount $s_source_mount
local tmount=${args[--target_mount]:-$BACKUP_TARGET_MOUNT}
tmount=${tmount:-$s_target_mount}
echo tmount: $tmount $s_target_mount
local source="${args[source]:-$s_source}"
source="${source:-$s_source_path}"
source=$(echo "${source:-$PWD}" | tr -s /)
echo yaml source $s_source_path $s_source_mount
echo source $source
echo target $s_target
echo target path $s_target_path
local target=${args[target]:-$s_target}
target=${target:-$s_target_path}
target=${target:-$(echo "${source}" | tr -s / | sed -e "s#^[.]##")}
target="$(echo "${target}" | tr -s /)"
echo "target> $target"
if [[ ${tmount} ]]; then
target="${tmount}${target}"
else
target="/${hostname}${target}"
fi
if [[ $server ]]; then
target="rest:${server}${target}"
fi
if [[ $smount ]]; then
setpath="--set-path ${source}"
source=${smount}${source}
fi
local exclude=${args[--exclude_file]:-$BACKUP_EXCLUDE}
exclude=${exclude:-$s_exclude}
exclude=${exclude:-"$source/exclude.bac"}
local shost=$([[ ${args[--shost]} ]] && echo ${args[--shost]}::)
local suser=$([[ ${args[--suser]} ]] && echo ${args[--suser]}@)
local thost=$([[ ${args[--host]} ]] && echo ${args[--host]}::)
local tuser=$([[ ${args[--user]} ]] && echo ${args[--user]}@)
local options=$(echo ${args[--options]} | awk '{gsub(/\\/," ")}1')
local bin=$(command -v restic)
local cmd=${args[cmd]:-"backup"}
echo before exists exclude: $exclude
exclude=$([[ -f $exclude ]] && echo "--iexclude-file $exclude" || echo "")
echo source: $source
echo target $target
echo exclude: $exclude
# local ssh="--remote-schema \"ssh -C %s /home/sysadmin/.local/bin/rdiff-backup --server\""
#cmd="$sudo rdiff-backup $options $exclude $ssh ${suser}${shost}$source ${tuser}${thost}$target"
local sudo=""
local pcmd="${sudo} ${password} ${bin} -r ${target}"
local cmd="${pcmd} -H ${hostname} ${setpath} backup ${source} ${exclude}"
if [[ ${args[--init]} ]]; then cmd="${pcmd} init"; fi
if [[ ${args[--snap]} ]]; then cmd="${pcmd} snapshots"; fi
if [[ ${args[--prune]} ]]; then cmd="${pcmd} prune"; fi
if [[ ${args[--view]} || ${args[--view-path]} ]]; then
mount=${args[--view-path]:-$BACKUP_MOUNT}
mount=${mount:-"/opt/backup/view/"}
echo view mount point $mount
if [[ -e ${mount} ]]; then
cmd="${pcmd} mount $mount";
echo browse files at $mount/snapshots/latest${source}
else
echo $mount: directory for mounting snapshot for viewing does not exist. Create and try again
return 3
fi
fi
echo $cmd
confirm run this command? || return 1
eval $cmd
# sudo chown -R $USER:$USER $target
# sudo chown -R $USER:$USER /home/$USER/.cache/restic
# sudo chmod -R g+rwX /home/$USER/.cache/restic