-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathborg_backup
executable file
·184 lines (143 loc) · 5.32 KB
/
borg_backup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#!/bin/bash
# borg_backup
# Taken from the QuickStart guide and modified.
# https://borgbackup.readthedocs.io/en/stable/quickstart.html#automating-backups
# Should be ran as a launchd process hourly.
# Checks to see if it can connect to our internal server
# before attempting a backup.
# Set this
# repo_server_address
repo_server_address=example.org
# Determine logged in user
loggedInUser=$(/usr/bin/python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "\n");')
# Get the hostname of the client
localhostname=$(/bin/hostname)
# Determine 'now' via date
# "2018-01-04-085601"
now=$(/bin/date "+%Y-%m-%d-%H%M%S")
# Setting this, so the repo does not need to be given on the commandline:
export BORG_REPO=${loggedInUser}@${repo_server_address}:backups
# and this to ask an external program to supply the passphrase:
# https://borgbackup.readthedocs.io/en/stable/faq.html#how-can-i-specify-the-encryption-passphrase-programmatically
# must have done security add-generic-password -D secret -U -a $USER -s borg-passphrase -w $(head -c 32 /dev/urandom | base64)
# or similar before hand.
export BORG_PASSCOMMAND="security find-generic-password -a ${loggedInUser} -s borg-passphrase -w"
# some helpers and error handling:
info() { printf '%s %s\n' "$(/bin/date)" "$*" >&2; }
trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM
# define borg for launchd to find it
borg=/usr/local/bin/borg
# Check to see if we can backup
# Stolen from https://github.com/rtrouton/CasperCheck/blob/master/script/caspercheck.sh
# Thanks, Rich.
CheckForNetwork(){
# Determine if the network is up by looking for any non-loopback network interfaces.
local test
if [[ -z "${NETWORKUP:=}" ]]; then
test=$(/sbin/ifconfig -a inet 2>/dev/null | sed -n -e '/127.0.0.1/d' -e '/0.0.0.0/d' -e '/inet/p' | wc -l)
if [[ "${test}" -gt 0 ]]; then
NETWORKUP="-YES-"
else
NETWORKUP="-NO-"
fi
fi
}
CheckSiteNetwork (){
site_network="False"
ssh_check=$(ssh ${repo_server_address} "hostname")
if [[ "${ssh_check}" == "${repo_server_address}" ]]; then
site_network="True"
else
site_network="False"
fi
}
borgCreate(){
# https://borgbackup.readthedocs.io/en/stable/usage/create.html
# Backup the most important directories into an archive named after
# the machine this script is currently running on:
$borg create \
--one-file-system \
--verbose \
--filter AME \
--list \
--stats \
--show-rc \
--compression lz4 \
--exclude-caches \
--exclude ~/Library/Caches \
--exclude ~/Downloads \
--exclude ~/.Trash \
--exclude-from ~/.borgignore \
\
::"${localhostname}"-"${now}" \
/Users/"${loggedInUser}" \
backup_exit=$?
}
borgPrune(){
info "Pruning repository"
# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly
# archives of THIS machine. The '{hostname}-' prefix is very important to
# limit prune's operation to this machine's archives and not apply to
# other machines' archives also:
$borg prune \
--list \
--prefix "${localhostname}"- \
--show-rc \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6 \
prune_exit=$?
}
# Wait up to 30 minutes for a network connection to become
# available which doesn't use a loopback address. This
# is a condition which may occur if this script is run by
# a LaunchDaemon at boot time.
#
# The network connection check will occur every 5 seconds
# until the 30 minute limit is reached.
info "Checking for active network connection."
CheckForNetwork
i=1
while [[ "${NETWORKUP}" != "-YES-" ]] && [[ $i -ne 360 ]]
do
sleep 5
NETWORKUP=
CheckForNetwork
echo $i
i=$(( $i + 1 ))0
done
# If no network connection is found within 30 minutes,
# the script will exit.
if [[ "${NETWORKUP}" != "-YES-" ]]; then
echo "Error: Network connection check failed."
exit 1
fi
if [[ "${NETWORKUP}" == "-YES-" ]]; then
info "Network connection appears to be live."
# Sleeping for 60 seconds to give WiFi time to come online.
info "Pausing for 1 minute to give WiFi and DNS time to come online."
sleep 60
CheckSiteNetwork
if [[ "$site_network" == "False" ]]; then
echo "Error: Site network verification failed."
exit 1
fi
if [[ "$site_network" == "True" ]]; then
info "Access to site network verified"
info "Starting backup"
borgCreate
borgPrune
info "Backup Complete"
fi
fi
# use highest exit code as global exit code
global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit ))
if [ ${global_exit} -eq 1 ];
then
info "Backup and/or Prune finished with a warning"
fi
if [ ${global_exit} -gt 1 ];
then
info "Backup and/or Prune finished with an error"
fi
exit ${global_exit}