-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdelorean.sh
executable file
·151 lines (118 loc) · 4.14 KB
/
delorean.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
#!/bin/bash
# Klaus Umbach <[email protected]>
# Licensed under the GPLv3
## Configuration
# default - may be overwritten in /etc/default/delorean
REMOTE_USER="delorean"
MAIL="[email protected]"
HOST="backupserver"
DEST_PATH="${HOSTNAME}"
LOCK_FILE="/var/run/delorean.pid"
LOG_FILE="/var/log/delorean.log"
REMOTE_LOCK_FILE="/tmp/delorean.lock.${HOSTNAME}"
REMOTE_LOG_FILE="delorean.log.${HOSTNAME}"
LAST_FILE="/var/lib/delorean.lastrun"
STATUS_FILE="/var/lib/delorean.status"
DISABLE_MOBILE="yes"
# only use real filesystems on real devices, no CDROM/DVDs
PATHS="$(mount | grep '^/dev' | egrep -v '(udf|iso9660|helper=udisks)' | awk '{print $3}' | tr '\n' ' ')"
# Just predefined for user-defined excludes.
EXCLUDE=""
## binaries
FLUXCAPACITOR="/usr/bin/ssh"
rsync="/usr/bin/nice -n 19 /usr/bin/rsync --delete -aHAXxv"
remote_rsync="/usr/bin/rsync"
ionice="/usr/bin/ionice -c3"
date="/bin/date"
# Read external configuration, if available
test -e /etc/default/delorean && source /etc/default/delorean
remote_message_command="/usr/bin/mail -E -s 'Delorean: Remote error on ${HOST}' ${MAIL}"
export RSYNC_RSH="${FLUXCAPACITOR}"
# TODO: CLI-parameters
# Year/Month/Day
today="$(${date} +%Y/%m/%d)"
function loginfo () { # {{{ Do the logging and update statusfile
message="${1}"
while read i; do
echo "[STATUS: INFO] $(${date} +%Y-%M-%d\ %H:%M:%S) ${i}" >> ${LOG_FILE}
done <<< "$message"
if [ "x${2}" != "xNOSTATUS]" ] ; then
echo "${message}" > ${STATUS_FILE}
fi
} # }}}
## MAIN
# minimal check if the host is there
if ! host $HOST > /dev/null 2> /dev/null ; then
loginfo "Backuphost $HOST not reachable, no backup now."
exit 0
fi
# get the currently used network device type
netDeviceType=$(/bin/ip route | \
grep default | \
head | \
cut -d ' ' -f 5 | \
sed -e 's/[0-9]*//g' \
)
# if using a mobile network, stop here.
if [ "x${DISABLE_MOBILE}" == "xyes" ]; then
if [ "x${netDeviceType}" == "xppp" ]; then
loginfo "Currently mobile, no backup now."
exit 0
fi
fi
# These are the files/directories, I find useless to backup on a
# desktop/notebook computer. I'm open to suggestions here!
SYS_EXCLUDE="var/cache/apt/ tmp/ var/run/ var/lib/apt/lists/ var/lib/clamav/ \
var/lib/upower/ var/lib/sudo/ var/spool/exim4/ var/log/ var/mail/ \
$LAST_FILE var/cache/openafs $LOCK_FILE mlocate.db var/cache/samba/ \
.xsession-errors etc/resolv.conf .*.swp etc/mtab var/lib/dhcp/ dev/ \
var/cache/man/ $STATUS_FILE var/cache/system-tools-backends .cache"
ALL_EXCLUDE="$SYS_EXCLUDE $EXCLUDE"
# build the exclude-options
for i in $ALL_EXCLUDE; do
exclude="$exclude --exclude=$i"
done
# If we can use another user than root, we need to take care of the attributes
# and permissions via xattrs, so the destination filesystem needs to be mounted
# with "-o user_xattrs"
if [ "x${REMOTE_USER}" != "xroot" ] ; then
fake_super="--rsync-path=${remote_rsync} --fake-super"
else
fake_super=''
fi
# Assemble the local sync-command
sync_command="${ionice} ${rsync} ${exclude} ${fake_super} ${PATHS} ${REMOTE_USER}@${HOST}:${DEST_PATH}/trunk"
# Assemble the remote command to set the hardlinks.
remote_command="( touch ${REMOTE_LOCK_FILE} && \
cd ${DEST_PATH} && \
mkdir -p ${today} && \
${ionice} nice -19 cp -al trunk ${today}/$(${date} +%H-%M) && \
rm ${REMOTE_LOCK_FILE} )2>&1 "
# local lockfile checking
if [ -e ${LOCK_FILE} ]; then
if [ -d /proc/$(cat ${LOCK_FILE}) ]; then
if grep ${0} /proc/$(cat ${LOCK_FILE}) ; then
loginfo "still running"
exit 0
fi
fi
# and remote lockfile checking
elif ${FLUXCAPACITOR} ${REMOTE_USER}@${HOST} "test -e ${REMOTE_LOCK_FILE}"; then
loginfo "Still running on the remote side."
exit 0
else
echo ${$} > ${LOCK_FILE}
# Now here happens the real backup.
loginfo "Backup started"
if (${sync_command} >> ${LOG_FILE}); then # TODO: sane logging
# if the sync was successful, we drop the command to set the hardlinks
${FLUXCAPACITOR} ${REMOTE_USER}@${HOST} "( ${remote_command} | ${remote_message_command} >/dev/null 2>&1 & disown )"
# write it to syslog.
loginfo "Backup successful"
$date +%s > ${LAST_FILE}
rm -f ${LOCK_FILE}
else
rm ${LOCK_FILE}
loginfo "Something went wrong. Trying again next time."
fi
fi