-
Notifications
You must be signed in to change notification settings - Fork 4
/
WeeklyBackup.sh
307 lines (243 loc) · 7.75 KB
/
WeeklyBackup.sh
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
#!/bin/bash
#
# *EXAMPLE* Script for daily backup
#
# Before the backup takes place a snapshot of the current backupfile is taken.
# This is done by calling a script $snapscript.
# Using a snapshot supporting filesystem (btrfs,xfs...) is recommended
# for the backupdestination. If BTRFS is used you may have a look to
# https://github.com/dolorosus/btrfs-snapshot-rotation
#
# After the snapshot is taken, the system will be isolated to rescue mode.
# Thus results in:
# - you will be no longer able to login from ssh
# - existing login sessions remain unchanged.
#
# Recommendation: use 'screen' or 'tmux' so that the backup will be finished
# even if the connection fails.
#
#
# Also you should take a closer look to *setup()*. Change the variables according
# your filesystem structure.
#
exec &> >(tee "${0%%.sh}.out")
setup() {
IDENT=" "
TICK="[✓]"
CROSS="[✗]"
INFO="[i]"
WARN="[w]"
msg() {
echo "${IDENT} ${1}"
}
msgok() {
echo "${TICK} ${1}"
}
}
errexit() {
[ ${DEBUG} ] && msg "${FUNCNAME[*]} parameter_: ${*}"
case "${1}" in
1)
echo "${CROSS} You have to be root to run this script${NOATT}">&2
;;
5)
echo "${CROSS} snapfunc.sh (${snapfunc}) not found${NOATT}">&2
;;
7)
echo "${CROSS} BTRFS at least one error counter for ${destvol} is greater 0${NOATT}">&2
;;
10)
echo "${CROSS} More than one backupfile according to ${destpath}/${destpatt} found.">&2
echo "Can't decide which one to use.${NOATT}">&2
;;
11)
echo "${CROSS} backupfile according to ${destpath}/${destpatt} is no flatfile.${NOATT}">&2
;;
12)
echo "${CROSS} backupfile according to ${destpath}/${destpatt} is empty.${NOATT}">&2
;;
20)
echo "${CROSS} No executable file $bckscript found.${NOATT}">&2
;;
21)
echo "${CROSS} Snapshot functions $snapscript not found.${NOATT}">&2
;;
25)
echo "${TICK} ${YELLOW}${action} $prog failed${NOATT}">&2
;;
30)
echo "${CROSS} something went wrong...">&2
echo "the incomplete backupfile is named: ${destpath}/${tmppre}${bcknewname}">&2
echo "Resolve the issue, rename the the backupfile and restart">&2
echo "Good luck!${NOATT}">&2
;;
*)
echo "${CROSS} An unknown error occured${NOATT}">&2
echo " Write down what you did, open an Issue and append all logfiles${NOATT}">&2
set -- 99
;;
esac
systemctl default
exit ${1}
}
progs() {
[ "${DEBUG}" ] && msg "${FUNCNAME[*]} parameter_: ${*}"
local action=${1:=start}
#local grace=20
local line=""
[ "${action}" == "stop" ] && {
msg "System is put to rescue mode."
systemctl rescue
}
[ "${action}" == "start" ] && {
msg "System is put to default mode."
systemctl default
}
msg "waiting for 20s"
#progress "waiting for ${grace}s"
for i in {1..20}; do
line="*${line}"
echo -en "[${line:1:20}]\r"
sleep 1s
done
echo ''
msgok "done."
return 0
}
do_backup() {
[ ${DEBUG} ] && msg "${FUNCNAME[*]} parameter_: ${*}"
local creopt="${1}"
# move the destination to a temporary filename while
# the backup is working
[ -z "${creopt}" ] && {
msg "Moving ${bckfile} to ${destpath}/${tmppre}${bcknewname}"
mv "${bckfile}" "${destpath}/${tmppre}${bcknewname}"
}
sync
msg "Starting backup_: ${bckscript} start ${creopt} ${destpath}/${tmppre}${bcknewname}"
backup="ko"
${bckscript} start ${creopt} "${destpath}/${tmppre}${bcknewname}" && {
backup="ok"
msg "Moving ${destpath}/${tmppre}${bcknewname} to ${destpath}/${bcknewname}"
mv "${destpath}/${tmppre}${bcknewname}" "${destpath}/${bcknewname}"
msgok "Backup successful"
msg "Backupfile is_: ${destpath}/${bcknewname}"
}
[ "${SKIPISO}" == "noskip" ] && progs start
[ "${backup}" == "ok" ] && return 0
errexit 30
}
# ===============================================================================================================
# Main
# ===============================================================================================================
declare -gx SKIPCHECK="noskip"
declare -gx SKIPISO="noskip"
opt=$(getopt --long skipcheck skipiso -- "$@")
eval set -- "$opt"
while shift; do
case "${1}" in
--skipcheck) SKIPCHECK="skip" ;;
--skipiso) SKIPISO="skip" ;;
esac
done
declare -r SKIPCHECK
declare -r SKIPISO
hostname
[ ${EUID} -eq 0 ] || errexit 1
declare -xr stamp=$(date +%y%m%d_%H%M%S)
declare -xr destvol="/x6/"
declare -xr destpath="${destvol}/BACKUPS/system"
declare -xr snappath="${destvol}/BACKUPS/.snapshots/system"
declare -xr rempath="/media/usbSyncth/.snapshots/Raspi4Images"
declare -xr bckprefix="MyRaspi4"
declare -xr destpatt="${bckprefix}-2*_[0-9]*.img"
declare -xr bcknewname="${bckprefix}-${stamp}.img"
declare -xr tmppre="#"
declare -xr bckscript="/home/pi/scripts/RaspiBackup.sh"
declare -xr versions=7
declare -xr remusr="[email protected]"
declare -xr MYNAME=${0##*/}
declare -xr ORGNAME=$(realpath "${0}")
declare -xr scriptbase="${ORGNAME%%${ORGNAME##*/}}"
declare -xr colors="${scriptbase}/COLORS.sh"
declare -xr snapfunc="${scriptbase}/snapFunc.sh"
declare -xr BTRFS="/usr/local/bin/btrfs"
[ -f "${snapfunc}" ] || errexit 5
source "${snapfunc}"
[ -f "${colors}" ] && {
source "${colors}"
msgheader "${MYNAME}"
}
mark=$(echo ${0} | sed 's/\(.*cron.\)\(.*\)\(\/.*\)/\2/')
case "${mark}" in
"daily") keep=7 ;;
"weekly") keep=3 ;;
"monthly") keep=3 ;;
*)
mark="manual"
keep=7
;;
esac
readonly mark
readonly keep
setup
#
# Please, do not disturb
#
trap "progs start" SIGTERM SIGINT
#
# Bailout in case of uncaught error
#
set +e
msg "using ${BTRFS} $(${BTRFS} --version)"
$BTRFS device stat --check ${destvol} || {
msg "PreCheck for errors btrfs device stat found error(s)"
msg "use btrfs device stat --reset ${destvol} to reset counter."
errexit 7
}
[ "${SKIPISO}" == "noskip" ] && {
msg "System will be isolated."
progs stop
}
[ "$(ls -1 ${destpath}/${destpatt} | wc -l)" == "0" ] && {
msg "No backupfile found."
msg "creating a new one"
do_backup "-c"
progs start
exit 0
}
[ "${SKIPCHECK}" == "noskip" ] && {
msg "some checks"
msg "get devicename for ${destvol}"
destdev=$(findmnt -o SOURCE --uniq --noheadings "${destvol}")
msg "checking mounted filesystem readonly on ${destdev} "
$BTRFS check --readonly --force --progress "${destdev}"
msg "scrub filesystem on ${destdev} "
$BTRFS scrub start -B "${destpath}"
}
$BTRFS device stat --check ${destvol} || {
msg "PostCheck btrfs device stat found error(s)"
msg "use btrfs device stat --reset ${destvol} to reset counter."
errexit 7
}
[ "$(ls -1 ${destpath}/${destpatt} | wc -l)" == "1" ] || errexit 10
bckfile="$(ls -1 ${destpath}/${destpatt})"
[ -f "${bckfile}" ] || errexit 11
[ -s "${bckfile}" ] || errexit 12
#
msg "some more checks..."
[ -x "${bckscript}" ] || errexit 20
msgok "All preflight checks successful"
msg "Rotate the logfiles"
logrotate -f /etc/logrotate.conf
msg "Finally start the backup"
do_backup
msg "Creating a snapshot of current backupfile and deleting the oldest snapshot"
snap "${destpath}" "${snappath}" "${mark}" ${keep} "${stamp}"
msg "sending the snapshot to ${remusr}"
snapremote "${remusr}" "${snappath}" "${rempath}" "${mark}" ${keep} "${stamp}"
msgok "All's Well That Ends Well"
exit 0
# ===============================================================================================================
# End of WeeklyBackup.sh
# ===============================================================================================================