]> git.treefish.org Git - backmeupscotty.git/blob - backmeupscotty
Added placeholder cleanup function.
[backmeupscotty.git] / backmeupscotty
1 #!/bin/bash
2
3 REMOTE_HOST=localhost
4 REMOTE_DIR=/tmp/backmeupscotty/test
5 ARCHIVE_KEEPNBACKUPS=30
6 ARCHIVE_KEEPNDAYS=30
7 BACKUP_RUNEVERYNTHDAY=1
8
9 function upperme {
10     echo $(basename $0) | tr '[:lower:]' '[:upper:]'
11 }
12
13 function scottyinfo {
14     echo $(upperme): $@ 
15 }
16
17 function scottyerror {
18     echo $(upperme): $@ >&2 
19 }
20
21 function grepbackups {
22     ssh $REMOTE_HOST "ls $REMOTE_DIR" | grep -E '[0-9]+-[0-9]+'
23 }
24
25 function isIncomplete {
26     if ( ssh $REMOTE_HOST '[ -d '$REMOTE_DIR/incomplete' ]' ); then
27         return 0
28     else
29         return 1
30     fi
31 }
32
33 function isIncompleteOrNthDay {
34     if isIncomplete || \
35         [ $(( ( $(date +%s) / (60*60*24) ) % $BACKUP_RUNEVERYNTHDAY )) -eq 0 ]; 
36     then
37         return 0
38     else
39         return 1
40     fi  
41 }
42
43 function scottysync {
44     timestamp=$(date +%s)
45
46     scottyinfo Syncing $SYNC_SRC to $REMOTE_HOST:$REMOTE_DIR @$timestamp
47
48     if [ ! -d "$SYNC_SRC" ]; then
49         scottyerror Source dir $SYNC_SRC does not exist. Not syncing!
50         return 1
51     fi
52
53     if [ $(ls -A "$SYNC_SRC" | wc -l) -eq 0 ]; then
54         scottyerror Source dir $SYNC_SRC is empty. Not syncing!
55         return 1
56     fi
57
58     dir_current=$REMOTE_DIR/current
59     dir_incomplete=$REMOTE_DIR/incomplete
60     dir_timestamped=$REMOTE_DIR/$timestamp-$(date -d @$timestamp +%Y%m%d%H%M%S)
61
62     if [ -z $SYNC_EXC ]; then
63         rsync_exclude=""
64     else
65         rsync_exclude=$(eval echo --exclude={$SYNC_EXC} | tr -d {})
66     fi
67
68     if (ssh $REMOTE_HOST '[ ! -d '$REMOTE_DIR' ]'); then
69         scottyinfo Creating destination directory $REMOTE_HOST:$REMOTE_DIR
70         ssh $REMOTE_HOST "mkdir $REMOTE_DIR"
71     fi
72
73     if isIncomplete; then
74         scottyerror Continuing old incomplete backup
75     fi
76
77     scottyinfo Starting rsync
78     rsync -e ssh \
79         -v -aHAX --numeric-ids --delete --delete-excluded \
80         --link-dest=$dir_current \
81         $rsync_exclude \
82         $SYNC_SRC/ $REMOTE_HOST:$dir_incomplete/
83     
84     if [ $? -eq 0 ]; then
85         scottyinfo Timestamping completed backup and linking to current backup
86         ssh $REMOTE_HOST \
87             "mv $dir_incomplete $dir_timestamped && rm -f $dir_current && ln -s $(basename $dir_timestamped) $dir_current"
88     fi
89
90     while [ $(grepbackups | wc -l) -gt $ARCHIVE_KEEPNBACKUPS ]; do
91         oldestbackup=$(grepbackups | head -1)
92         oldestbackuptstamp=$(echo $oldestbackup | cut -d'-' -f1)
93
94         if [ $oldestbackuptstamp -lt $(( $(date +%s) - $ARCHIVE_KEEPNDAYS*60*60*24 )) ]; then
95             scottyinfo Removing old backup $oldestbackup
96             ssh $REMOTE_HOST rm -r "$REMOTE_DIR/$oldestbackup"
97         else
98             break
99         fi
100     done
101 }
102
103 function deleteLock {
104     if ! rmdir /tmp/$(basename $0).lock; then
105         scottyerror "Could not delete lockfile /tmp/$(basename $0).lock!"
106     fi
107 }
108
109 function prepare {
110     scottyinfo "Preparing for sync"
111 }
112
113 function cleanup_abort {
114     scottyerror "Caught exit signal! Cleaning up..."
115
116     cleanup ABORT
117
118     if [ $(jobs -p) ]; then
119         scottyerror TERMinating remaining child processes...
120         kill $(jobs -p)
121     fi
122
123     deleteLock
124
125     exit
126 }
127
128 function cleanup {
129     scottyinfo "No cleanup function was defined."
130 }
131
132 function prepare {
133     scottyinfo "No prepare function was defined."
134 }
135
136 function cleanup_normal {
137     cleanup
138     deleteLock
139 }
140
141 function printhelp {
142     cat <<EOF
143 Usage: $(basename $0) [OPTION]...
144
145 Recognized options:
146   -q   Only output errors
147   -n   Run only on nth day
148   -h   Print out this help
149 EOF
150 }
151
152 function backmeupscotty {
153     while getopts "qn:h" opt; do
154         case $opt in
155             q)
156                 exec > /dev/null
157                 ;;
158             n)
159                 BACKUP_RUNEVERYNTHDAY=$OPTARG
160                 ;;
161             h)
162                 printhelp
163                 exit 0
164                 ;;
165         esac
166     done
167     
168     if ! isIncompleteOrNthDay; then
169         scottyinfo "This is not the nth day and no incomplete backup exists."
170         exit 0
171     fi
172
173     trap cleanup_abort EXIT
174
175     prepare
176     scottysync
177
178     trap cleanup_normal EXIT
179
180     exit 0
181 }
182
183 if ! mkdir /tmp/$(basename $0).lock; then
184     scottyerror "Another instance of $(basename $0) is still running!"
185     exit 1
186 else
187     trap deleteLock EXIT
188 fi