Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100755 487 lines (384 sloc) 14.26 kB
68b1571 @falconindy Initial commit: extremely alpha
authored
1 #!/bin/bash
7f897e2 @falconindy Bump to version 1.0
authored
2 VER="1.0"
68b1571 @falconindy Initial commit: extremely alpha
authored
3
5a4021b @falconindy Squish some operational bugs. More to go...
authored
4 CONFIG="/etc/squashfu.conf"
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
5 . "$CONFIG"
63c55ee @falconindy Flesh out action_backup functionality -- commence testing
authored
6
7a830d0 @falconindy Add finish routine, cleanup unneeded code/comments
authored
7 # Informational output w/ happy colors
68b1571 @falconindy Initial commit: extremely alpha
authored
8 debug () {
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
9 [[ "$DEBUG" == "true" ]] && printf '\033[1;33mDEBUG ::\033[1;m %s\n' "$*"
e27598c @falconindy Add further debugging -- stop crashing you turd
authored
10 }
11
480d999 @falconindy Implement warn() function in caution yellow
authored
12 warn () {
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
13 printf '\033[1;33m::\033[1;m %s\n' "$*"
480d999 @falconindy Implement warn() function in caution yellow
authored
14 }
15
e27598c @falconindy Add further debugging -- stop crashing you turd
authored
16 info () {
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
17 printf '\033[1;34m::\033[1;m %s\n' "$*"
68b1571 @falconindy Initial commit: extremely alpha
authored
18 }
19
20 die () {
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
21 printf '\033[1;31m::\033[1;m %s\n' "$*" >&2
22 exit 1
68b1571 @falconindy Initial commit: extremely alpha
authored
23 }
e27598c @falconindy Add further debugging -- stop crashing you turd
authored
24
93a0e29 @falconindy Reorder functions
authored
25 create_new_squash () {
1b2a164 @falconindy Add option to manually resquash down to MIN_BINS
authored
26 # Args: number of bins to be squashed, -1 on initial creation
93a0e29 @falconindy Reorder functions
authored
27 # Returns: 0 on success, non-zero on failure
28
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
29 # If making first seed, create it directly from source
30 if [[ $1 -eq -1 ]]; then
31 info "Creating seed from sources (this may take a while)"
32 mksquashfs "${INCLUDES[@]}" "$SEED" -b 65536 -e "${EXCLUDES[@]}" >/dev/null
33 if [[ $? -eq 0 ]]; then
34 mount_squash
35 info "Seed creation finished. It has been mounted at "$SQUASH_MOUNT" if you would like to make sure the proper files are included"
36 return 0;
37 else
38 die "There was an error creating the initial squash."
93a0e29 @falconindy Reorder functions
authored
39 fi
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
40 fi
93a0e29 @falconindy Reorder functions
authored
41
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
42 # Determine oldest $1 bins and mount them with the current squash
43 local old_bins=($(sort -n -r -t: -k2 "$BINVENTORY" | tail -$1 | cut -d: -f1))
93a0e29 @falconindy Reorder functions
authored
44
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
45 mount_union_with_bins ${old_bins[@]}
93a0e29 @falconindy Reorder functions
authored
46
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
47 info "Merging old incrementals"
48 # Create new squash with temp name, exiting on failure
49 mksquashfs "$UNION_MOUNT" "$SEED.replace" -b 65536 >/dev/null || return 1
93a0e29 @falconindy Reorder functions
authored
50
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
51 unmount_all
93a0e29 @falconindy Reorder functions
authored
52
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
53 # Replace old squash
54 mv "${SEED}.replace" "$SEED"
93a0e29 @falconindy Reorder functions
authored
55
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
56 info "Cleaning up inventory"
57 # Delete old bins, and remove entry from binventory
58 for bin in ${old_bins[@]}; do
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
59 rm -rf "$BINS_DIR/$bin"
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
60 sed -i "/^$bin:/d" "$BINVENTORY"
61 done
93a0e29 @falconindy Reorder functions
authored
62 }
63
ecc1265 @falconindy Reorder and group functions by purpose
authored
64 create_new_bin () {
65 # Arguments: 1, the number of the bin to create
66 # Returns: 0 on success, non-zero on error
67
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
68 debug "Asked to create new bin: $1"
69 # Create new directory, fail if it exists (something's wrong)
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
70 mkdir "$BINS_DIR/$1"
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
71 [[ $? != 0 ]] && return $?
ecc1265 @falconindy Reorder and group functions by purpose
authored
72
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
73 # Update binventory with new bin name and timestamp
74 echo "${1}:$(date +%s)" >> "$BINVENTORY"
ecc1265 @falconindy Reorder and group functions by purpose
authored
75
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
76 # If write to bin list fails, remove diretory and exit
77 if [[ $? -ne 0 ]]; then
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
78 rmdir "$BINS_DIR/${1}"
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
79 die "Error writing to '$BINVENTORY'"
80 fi
ecc1265 @falconindy Reorder and group functions by purpose
authored
81
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
82 return
ecc1265 @falconindy Reorder and group functions by purpose
authored
83 }
84
85 # Mounting functions
985d175 @falconindy Complete rewrite with new structure. Basic framework and backup funct…
authored
86 mount_squash () {
87 # Arguments: none
88 # Returns: return code of mount command
41ed04f @falconindy restore: derp. look in the squash for the restore target as well.
authored
89 mountpoint -q "$SQUASH_MOUNT" || {
90 info "Mounting squash";
91 mount -o loop,ro "$SEED" "$SQUASH_MOUNT";
92 }
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
93 return $?
985d175 @falconindy Complete rewrite with new structure. Basic framework and backup funct…
authored
94 }
95
96 mount_union_with_bins () {
97 # Arguments: numbers of bins to be mounted (variable number)
98 # Returns: 0 on successful mount, non-zero on failure
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
99 info "Mounting union"
100 debug "Requested to mount bins: $*"
101
102 # Mount first as rw, shift, and mount the rest ro
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
103 local branches="br=${BINS_DIR}/$1=rw:"; shift
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
104 if [[ -n $1 ]]; then
105 for bin in $*; do
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
106 branches="$branches$BINS_DIR/$bin=ro:"
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
107 done
108 fi
109 branches="${branches}${SQUASH_MOUNT}=ro"
63f83db @falconindy Split off root priviledge check to its own function -- check for each…
authored
110
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
111 mount -t aufs none "$UNION_MOUNT" -o udba=reval,$branches
97af6e6 @falconindy Split off directory structure creation to its own function
authored
112
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
113 return $?
6f32d3b @falconindy Alphabetize functions
authored
114 }
115
985d175 @falconindy Complete rewrite with new structure. Basic framework and backup funct…
authored
116 # Unmounting functions
117 unmount_union () {
118 # Args: none
119 # Returns: return code from umount
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
120 info "Unmounting union"
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
121 umount "$UNION_MOUNT" 2>/dev/null
70d66ec @falconindy deletion: ensure that the union is unmounted before deleting. fail ha…
authored
122 local ret=$?
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
123 sleep .5
70d66ec @falconindy deletion: ensure that the union is unmounted before deleting. fail ha…
authored
124 return $ret
eef98cf @falconindy Add support for checking custom mounts
authored
125 }
126
5a4021b @falconindy Squish some operational bugs. More to go...
authored
127 unmount_squash () {
985d175 @falconindy Complete rewrite with new structure. Basic framework and backup funct…
authored
128 # Args: none
129 # Returns: return code from umount
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
130 info "Unmounting squash"
e6101ea @falconindy unmount: remove filthy hacks on unmount. aufs seems stable with write…
authored
131 umount "$SQUASH_MOUNT" 2>/dev/null
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
132 return $?
9aab188 @falconindy Split unmount_all into two separate functions, calling both for _all
authored
133 }
134
985d175 @falconindy Complete rewrite with new structure. Basic framework and backup funct…
authored
135 unmount_all () {
136 # Args: none
137 # Returns: none
138
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
139 [[ $UID -ne 0 ]] && die "Must be root to unmount."
955ad5b @falconindy Add checks for root user in rollback, backup, and unmount
authored
140
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
141 # Union MUST be unmounted first
142 mountpoint -q "$UNION_MOUNT" && unmount_union
143 mountpoint -q "$SQUASH_MOUNT" && unmount_squash
7a830d0 @falconindy Add finish routine, cleanup unneeded code/comments
authored
144 }
145
ecc1265 @falconindy Reorder and group functions by purpose
authored
146 check_for_resquash () {
147 # Args: none
148 # Returns: number of bins needing to be merged
bee7a08 @falconindy cleanup grep calls. we don't really need -E
authored
149 local number_of_bins=$(grep -v "^[[:space:]]*$" "$BINVENTORY" | wc -l)
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
150 debug "Found $number_of_bins bins"
151
152 if [[ $number_of_bins -gt $MAX_BINS ]]; then
153 return $(( $number_of_bins - $MIN_BINS ))
154 else
155 return 0
156 fi
ecc1265 @falconindy Reorder and group functions by purpose
authored
157 }
1f96ce1 @falconindy Add usage function and mount checking (and unmounting) in rollback fu…
authored
158
ecc1265 @falconindy Reorder and group functions by purpose
authored
159 get_next_available_bin () {
160 # Arguments: none
161 # Returns: Numeric value of the next unused bin
f75aeb5 @falconindy factor out need for sweep_bins. this introduces a slight breakage to …
authored
162 for (( i=1; i <= MAX_BINS + 1; i++ )); do
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
163 [[ -d "$BINS_DIR/$i" || $(grep "^$i:" "$BINVENTORY") ]] && continue;
f75aeb5 @falconindy factor out need for sweep_bins. this introduces a slight breakage to …
authored
164 debug "Next available bin = $i"
165 return $i
166 done
ecc1265 @falconindy Reorder and group functions by purpose
authored
167 }
1f96ce1 @falconindy Add usage function and mount checking (and unmounting) in rollback fu…
authored
168
20fe278 @falconindy Create skeletons for action handlers
authored
169 action_backup () {
63c55ee @falconindy Flesh out action_backup functionality -- commence testing
authored
170 # Args: options array squashfu was invoked with, shifted 1
171 # Returns: none
172
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
173 [[ $UID -ne 0 ]] && die "Must be root to perform a backup"
63c55ee @falconindy Flesh out action_backup functionality -- commence testing
authored
174
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
175 # Does the binventory exist? If not, prompt to make sure this is an initialization
176 if [[ ! -f "$BINVENTORY" || ! -f "$SEED" ]]; then
5124254 @falconindy pedantic
authored
177 echo -ne "\033[1;33m::\033[0m "
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
178 read -N1 -p "Looks like this is your first time running SquashFu. Is this correct? [y/N] " reply
179 echo
180 [[ ! "$reply" =~ [Yy] ]] && die "Your bin inventory and/or seed seem to be missing. Please fix this before continuing."
ceb3329 @falconindy Refine output, at both info and debug levels
authored
181
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
182 # If we got here, the user answered yes, so initialize a new structure
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
183 mkdir -p "$UNION_MOUNT" "$SQUASH_MOUNT" "$BINS_DIR"
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
184 touch "$BINVENTORY"
185 create_new_squash -1
186 exit 0
187 fi
6ad518d @falconindy Debug action_rollback. Ensure unmount_all runs before we try to do a …
authored
188
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
189 info "Backup requested at $(date --rfc-3339=seconds)"
5570ac4 @falconindy Merge create_new_incremental() into action_backup()
authored
190
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
191 # Cleanup union, in case user was doing a rollback and forgot to unmount (or error on last run)
e7a3987 @falconindy use more mountpoint -q, less &>/dev/null
authored
192 mountpoint -q "$UNION_MOUNT" && unmount_union
5570ac4 @falconindy Merge create_new_incremental() into action_backup()
authored
193
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
194 info "Creating new bin"
195 # Make a new bin for this incremenetal
196 get_next_available_bin
197 local new_bin=$?
198 create_new_bin $new_bin
5570ac4 @falconindy Merge create_new_incremental() into action_backup()
authored
199
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
200 # Determine the mount order via binventory
201 local bin_order=($(sort -n -r -t: -k2 "$BINVENTORY" | cut -d: -f1))
5570ac4 @falconindy Merge create_new_incremental() into action_backup()
authored
202
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
203 mountpoint -q "$SQUASH_MOUNT" || mount_squash
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
204 mount_union_with_bins ${bin_order[@]} || return 1
5570ac4 @falconindy Merge create_new_incremental() into action_backup()
authored
205
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
206 debug "rsync ${RSYNC_OPTS[@]} ${INCLUDES[@]} ${EXCLUDES[@]/#/--exclude } $UNION_MOUNT"
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
207 info "Creating new incremental"
ebbf701 @falconindy don't quote entire exclude with flag
authored
208 /usr/bin/rsync "${RSYNC_OPTS[@]}" "${INCLUDES[@]}" ${EXCLUDES[@]/#/--exclude } "$UNION_MOUNT"
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
209 rsync_ret=$?
647eb3e @falconindy New branch. Goal: optional rollback when rsync fails
authored
210
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
211 for error in ${DEL_BIN_ON_FAIL[@]}; do
212 if [[ $rsync_ret == $error ]]; then
213 warn "Unexpected hangup by rsync ($error). Deleting backup."
214 action_remove_bin $new_bin override
215 break
63c55ee @falconindy Flesh out action_backup functionality -- commence testing
authored
216 fi
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
217 done
20fe278 @falconindy Create skeletons for action handlers
authored
218
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
219 check_for_resquash
ca48c8e @falconindy minor bug fixes
authored
220 [[ val=$? -gt 0 ]] && create_new_squash $val
63c55ee @falconindy Flesh out action_backup functionality -- commence testing
authored
221
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
222 # TODO: Report if requested
ceb3329 @falconindy Refine output, at both info and debug levels
authored
223
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
224 unmount_all
225
226 info "Backup completed at $(date --rfc-3339=seconds)"
20fe278 @falconindy Create skeletons for action handlers
authored
227 }
228
c2ea987 @falconindy Create function to remove a bin, optionally interactive
authored
229 action_remove_bin () {
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
230 # check if the bin exists both in the binventory AND in the bins directory
231 [[ $UID != 0 ]] && die "Must be root to remove a backup"
232 [[ ! -w "$BINVENTORY" ]] && die "Unable to write to ${BINVENTORY}"
233
70d66ec @falconindy deletion: ensure that the union is unmounted before deleting. fail ha…
authored
234
235 if grep -q "^$1:" $BINVENTORY && [[ -d "$BINS_DIR/$1" ]]; then
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
236 if [[ -z $2 ]]; then
237 echo "Are you SURE you want to remove this bin?"
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
238 local timestamp=$(sed -n "/^$1:/s/^[0-9]*:\([0-9]*\)/\1/p" "$BINVENTORY")
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
239 printf "\t%15s %s\n\t%15s %s\n\t%15s %s\n" \
240 "Bin:" "$1" \
241 "Date Created:" "$(date --rfc-3339=seconds --date="@$timestamp")" \
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
242 "Size:" "$(du -sh "$BINS_DIR/$1" 2>/dev/null | awk '{print $1}')"
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
243
70d66ec @falconindy deletion: ensure that the union is unmounted before deleting. fail ha…
authored
244 echo -ne "\033[1;33m::\033[0m "
ca48c8e @falconindy minor bug fixes
authored
245 read -N1 -p "Confirm deletion (y/N) " reply
246 echo
70d66ec @falconindy deletion: ensure that the union is unmounted before deleting. fail ha…
authored
247 [[ ! "$reply" = [Yy] ]] && die "Delete operation aborted"
205426e @falconindy Check UID and that .bin.list is writeable before proceeding with delete
authored
248 fi
249
70d66ec @falconindy deletion: ensure that the union is unmounted before deleting. fail ha…
authored
250 mountpoint -q "$UNION_MOUNT" && { unmount_union || die "Failed to unmount union"; }
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
251 info "Deleting bin $1"
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
252 sed -i "/^$1:[0-9]*/d" "$BINVENTORY"
70d66ec @falconindy deletion: ensure that the union is unmounted before deleting. fail ha…
authored
253 rm -rf "$BINS_DIR/$1"
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
254 else
255 die "Bin $1 not found."
256 fi
c2ea987 @falconindy Create function to remove a bin, optionally interactive
authored
257 }
258
20fe278 @falconindy Create skeletons for action handlers
authored
259 action_rollback () {
955ad5b @falconindy Add checks for root user in rollback, backup, and unmount
authored
260 # Args: number of backups to roll back
261 # Returns: none
262
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
263 [[ $UID -ne 0 ]] && die "Must be root to perform a rollback"
f2958c0 @falconindy rollback: sanitize input. insist that the argument passed is purely n…
authored
264 [[ ! $1 =~ ^[0-9]*$ ]] && die "Invalid argument. Parameter must be a number."
146d12d @falconindy Create rollback action handler. Don't rely on wc -l alone to count bi…
authored
265
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
266 # Form a chronologically ordered list of bins, assuming the user didn't give bogus input
f2958c0 @falconindy rollback: sanitize input. insist that the argument passed is purely n…
authored
267 local bin_list=($(sed -n 's/[\t\ ]*\([0-9]*\):.*/\1/p' "$BINVENTORY"))
146d12d @falconindy Create rollback action handler. Don't rely on wc -l alone to count bi…
authored
268
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
269 [[ $1 -gt ${#bin_list[@]} ]] && die "Cannot rollback more than ${#bin_list[@]} backups"
146d12d @falconindy Create rollback action handler. Don't rely on wc -l alone to count bi…
authored
270
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
271 local num_to_mount=$(( ${#bin_list[@]} - $1 ))
146d12d @falconindy Create rollback action handler. Don't rely on wc -l alone to count bi…
authored
272
f2958c0 @falconindy rollback: sanitize input. insist that the argument passed is purely n…
authored
273 mountpoint -q "$UNION_MOUNT" && unmount_union
274 mountpoint -q "$SQUASH_MOUNT" || mount_squash
146d12d @falconindy Create rollback action handler. Don't rely on wc -l alone to count bi…
authored
275
47295fc @falconindy fix bug with rolling back when number of bins to rollback equals the …
authored
276 if [[ ${#bin_list[@]} -eq $1 ]]; then
277 local rb_timestamp=0 # XXX: What the hell is the timestamp of the seed... ?
278 else
8248834 @falconindy fix mounting order when rolling back
authored
279 # voodoo magic: reverse bin_list and print off the top (#bin_list - $1) bins
280 mount_union_with_bins $(for (( i = ${#bin_list[@]} - $1 - 1; i >= 0; i-- )); do echo ${bin_list[i]}; done)
47295fc @falconindy fix bug with rolling back when number of bins to rollback equals the …
authored
281 local rb_timestamp=$(grep "^${bin_list[@]:(-$num_to_mount):1}:" "$BINVENTORY" | cut -d: -f2)
282 fi
5f75b00 @falconindy Show date of rollback when operation completes
authored
283
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
284 info "You have rolled back to $(date --rfc-3339=seconds --date="@$rb_timestamp")"
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
285 info "Your files can be found at '$UNION_MOUNT'"
20fe278 @falconindy Create skeletons for action handlers
authored
286 }
287
288 action_report () {
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
289 info "SquashFu Usage Report"
290 # Enumerate bins, sort date order, print human readable create date and size
291
20b90d3 @falconindy fix reporting. need more bash, less cut
authored
292 pushd "$BINS_DIR" &>/dev/null
feb9fd4 @falconindy remove unused sweep_bins()
authored
293
635ef83 @falconindy reporting: fix error in calculating grand total
authored
294 declare -a DATA
295
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
296 # Collect all data into an array to 'preload' it. Index 0 is the entire
297 # folder. The following indicies correspond to the bin number of that index
bb96195 @falconindy use PE instead of awk and get rid of some subshells
authored
298 printf "\n%30s\r" ".: Loading :." >&2
299 while read size bin; do
635ef83 @falconindy reporting: fix error in calculating grand total
authored
300 case $bin in
0fbbe1f @falconindy du uses tabs as column separators, not spaces! go go parameter expansion
authored
301 '.') DATA[0]=$size ;;
635ef83 @falconindy reporting: fix error in calculating grand total
authored
302 *) DATA[bin]=$size ;;
977cf79 @falconindy clean up reporting. reduce external calls, use printf properly
authored
303 esac
635ef83 @falconindy reporting: fix error in calculating grand total
authored
304 done < <(du -sh . * 2>/dev/null)
977cf79 @falconindy clean up reporting. reduce external calls, use printf properly
authored
305 printf "%30s\r" "" >&2
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
306
307 printf "%10s\t%25s\t%7s\n" "Bin ID" "Date Created" "Size"
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
308 local OIFS=$IFS;IFS=$IFS$':'
bb96195 @falconindy use PE instead of awk and get rid of some subshells
authored
309 while read bin stamp; do
635ef83 @falconindy reporting: fix error in calculating grand total
authored
310 printf "%10d\t%25s\t%7s\n" "$bin" "$(date --rfc-3339=seconds --date="@$stamp")" "${DATA[bin]}"
bb96195 @falconindy use PE instead of awk and get rid of some subshells
authored
311 done < <(grep -v "^[[:space:]]*$" "$BINVENTORY" | sort -nr -t':' -k2)
f75aeb5 @falconindy factor out need for sweep_bins. this introduces a slight breakage to …
authored
312 IFS=$OIFS
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
313 printf "%10s\t%25s\t%7s\n" "" "Incremental Total" "${DATA[0]}"
314
977cf79 @falconindy clean up reporting. reduce external calls, use printf properly
authored
315 # Print totals
8ccb3b8 @falconindy cleanup: use braces only where necessary, quote more often
authored
316 local grand_total=$(du -csh "$SEED" "$BINS_DIR" 2>/dev/null | awk '/total$/{ print $1 }')
f15b93f @falconindy use PE idioms instead of basename/dirname
authored
317 printf "\n%10s\t%25s\t%7s\n" "" "${SEED##*/}" "$(du -h "$SEED" | awk '{print $1}')"
635ef83 @falconindy reporting: fix error in calculating grand total
authored
318 printf "\n%10s\t%25s\t%7s\n" "" "Grand Total" "$grand_total"
f75aeb5 @falconindy factor out need for sweep_bins. this introduces a slight breakage to …
authored
319
20b90d3 @falconindy fix reporting. need more bash, less cut
authored
320 popd &>/dev/null
20fe278 @falconindy Create skeletons for action handlers
authored
321 }
322
1b2a164 @falconindy Add option to manually resquash down to MIN_BINS
authored
323 action_resquash_now () {
324 # Args: none
325 # Returns: none
326
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
327 [[ $UID != 0 ]] && die "Must be root to perform a resquash"
1b2a164 @falconindy Add option to manually resquash down to MIN_BINS
authored
328
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
329 info "Voluntary resquash requested"
1b2a164 @falconindy Add option to manually resquash down to MIN_BINS
authored
330
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
331 local number_of_bins=$(grep -vE "^[ ]*$" "$BINVENTORY" | wc -l)
332 if [[ $number_of_bins -le $MIN_BINS ]]; then
333 die "Nothing to do. Current backups do not exceed MIN_BINS value."
334 else
335 create_new_squash $(( $number_of_bins - $MIN_BINS ))
336 fi
1b2a164 @falconindy Add option to manually resquash down to MIN_BINS
authored
337
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
338 exit $?
1b2a164 @falconindy Add option to manually resquash down to MIN_BINS
authored
339 }
340
11377a2 @falconindy add interactive restore capability for file and/or directory via -G a…
authored
341 action_restore () {
342 [[ -z $1 ]] && die "Missing parameter from restore. Provide a full path to the restore target."
343 [[ $UID != 0 ]] && die "Must be root to restore."
344
41ed04f @falconindy restore: derp. look in the squash for the restore target as well.
authored
345 mount_squash || die "Failed to mount seed"
346
e8c6ff8 @falconindy refactor display of possible restore bins to sort in ascending order …
authored
347 IFS=$'\n' read -r -d'\0' -a result < <(find "$BINS_DIR"/*/"$1" -maxdepth 0 2>/dev/null)
11377a2 @falconindy add interactive restore capability for file and/or directory via -G a…
authored
348
f7f2723 @falconindy restore: fix glaring error which hid a possible restore and created a…
authored
349 [[ -e "$SQUASH_MOUNT/$1" ]] && snaps[0]=$(stat -c %Z "$SQUASH_MOUNT/$1")
350
351 if [[ -z ${snaps[0]} && ${#results[@]} -eq 0 ]]; then
352 unmount_squash
353 die "Target not found: '$1'"
354 fi
355
e8c6ff8 @falconindy refactor display of possible restore bins to sort in ascending order …
authored
356 # print results, ghetto mapping sort against inventory
09fcf1c @falconindy simply find operation in action_restore
authored
357 info "Found ${1##*/} in the following backups:"
f7f2723 @falconindy restore: fix glaring error which hid a possible restore and created a…
authored
358 [[ -n ${snaps[0]} ]] && printf " 0\t%s\n" "$(date --date=@${snaps[0]})"
11377a2 @falconindy add interactive restore capability for file and/or directory via -G a…
authored
359
e8c6ff8 @falconindy refactor display of possible restore bins to sort in ascending order …
authored
360 declare -a snaps
361 IFS=$'\n' read -r -d'\0' -a mapping < "$BINVENTORY"
362 for line in "${mapping[@]}"; do
363 IFS=':' read bin stamp <<< "$line"
364 for res in "${result[@]}"; do
db51747 @falconindy squashfu: fix missing semi-colon
authored
365 [[ $res =~ $BINS_DIR/$bin$1 ]] && { printf " %d\t%s\n" $bin "$(date --date="@$stamp")"; break; }
e8c6ff8 @falconindy refactor display of possible restore bins to sort in ascending order …
authored
366 done
11377a2 @falconindy add interactive restore capability for file and/or directory via -G a…
authored
367 done
368
41ed04f @falconindy restore: derp. look in the squash for the restore target as well.
authored
369 read -p "Which snapshot to restore from? " reply
e8c6ff8 @falconindy refactor display of possible restore bins to sort in ascending order …
authored
370 [[ -z $reply || -z ${snaps[$reply]} || ${reply//[0-9]/} ]] && die "Invalid bin"
11377a2 @falconindy add interactive restore capability for file and/or directory via -G a…
authored
371
372 local bin_list=($(sed -n 's/[\t\ ]*\([0-9]*\):.*/\1/p' "$BINVENTORY"))
373 local num=$(grep -nh "^$reply:" $BINVENTORY | cut -d: -f1)
374
375 mountpoint -q $UNION_MOUNT && unmount_union
376
41ed04f @falconindy restore: derp. look in the squash for the restore target as well.
authored
377 [[ $reply != 0 ]] &&
378 { mount_union_with_bins ${bin_list[@]:0:$num} || die "Failed to mount union"; } ||
379 mount_union_with_bins || die "Failed to mount union"
11377a2 @falconindy add interactive restore capability for file and/or directory via -G a…
authored
380
0dca065 @falconindy restore: handle directories separately
authored
381 local restore_name="$1.$(date --date=@${snaps[$reply]} +%Y%m%d)"
701d08d @falconindy restore: be nice and actually inform about where the restore was done to
authored
382
0dca065 @falconindy restore: handle directories separately
authored
383 {
384 if [[ -d "$UNION_MOUNT/$1" ]]; then
385 rsync -a $UNION_MOUNT/$1/* "$restore_name" &&
386 chown $(stat -c %u:%g "$UNION_MOUNT/$1") "$restore_name";
387 else
388 rsync -a "$UNION_MOUNT/$1" "$restore_name";
389 fi
754c27a @falconindy remove restore_type. just call it generic 'data'. the user should kno…
authored
390 } && info "Your data has been restored as: '$restore_name'"
11377a2 @falconindy add interactive restore capability for file and/or directory via -G a…
authored
391
392 unmount_all
393
394 }
395
de17d54 @falconindy Conform -U option to set action and not immediately execute
authored
396 action_unmount () {
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
397 unmount_all
de17d54 @falconindy Conform -U option to set action and not immediately execute
authored
398 }
399
ecc1265 @falconindy Reorder and group functions by purpose
authored
400 usage () {
955ad5b @falconindy Add checks for root user in rollback, backup, and unmount
authored
401 info "SquashFu: Super Awesome Backup Express (Professional Edition)"
dd62660 @falconindy Add versioning
authored
402 echo "version: $VER"
ecc1265 @falconindy Reorder and group functions by purpose
authored
403 cat <<HELP
404
405 USAGE
40ca97e @falconindy Add -c option for specifying alternate config
authored
406 squashfu <action> [options]
ecc1265 @falconindy Reorder and group functions by purpose
authored
407
2818589 @falconindy Change 'operations' to 'actions' in usage heredoc
authored
408 ACTIONS
ecc1265 @falconindy Reorder and group functions by purpose
authored
409 -B
a52b1f4 @falconindy Update usage heredoc to actually be accurate for currently supported …
authored
410 Runs a regular backup, using the config file at /etc/squashfu.
ecc1265 @falconindy Reorder and group functions by purpose
authored
411
1b2a164 @falconindy Add option to manually resquash down to MIN_BINS
authored
412 -C
413 Create a new squash by merging old bins. This will still leave you
ddcb110 @falconindy Fix typo in usage
authored
414 with $MIN_BINS backups (as per the MIN_BINS setting in your config).
1b2a164 @falconindy Add option to manually resquash down to MIN_BINS
authored
415
168655f @falconindy Add remove bin option to usage heredoc and options parser
authored
416 -D <bin number>
417 Delete an incremental backup. This is done interactively and you will have
418 a chance to confirm before any files are deleted.
419
4f80e3e @falconindy doc: add -G option to README and usage()
authored
420 -G <path>
421 Directly restore a file or directory. This is an interactive operation and
422 a list of locations where the target is found will be presented.
423
ecc1265 @falconindy Reorder and group functions by purpose
authored
424 -Q
a52b1f4 @falconindy Update usage heredoc to actually be accurate for currently supported …
authored
425 Displays the size of the seed, the incrementals, and totals.
ecc1265 @falconindy Reorder and group functions by purpose
authored
426
427 -R <number of bins>
428 Rollback specified number of backups and mount union for browsing. The rolled
429 back data will be mounted at $UNION_MOUNT.
430
431 -U
432 Unmount squash and union. Although SquashFu will always check and unmount as
433 necessary before an operation, this is provided as a safeguard.
434
1723f51 @falconindy Correct spacing on usage heredoc
authored
435 OPTIONS
40ca97e @falconindy Add -c option for specifying alternate config
authored
436 -c <path_to_config>
437 Specify an alternate config file. Options defined will override options in
438 the default config. If you specify alternate locations via a supplmenetal config,
439 you will need to provide the config for all actions
440
47295fc @falconindy fix bug with rolling back when number of bins to rollback equals the …
authored
441 -v
442 Show debugging output.
443
ecc1265 @falconindy Reorder and group functions by purpose
authored
444 HELP
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
445 exit 1
ecc1265 @falconindy Reorder and group functions by purpose
authored
446 }
447
47295fc @falconindy fix bug with rolling back when number of bins to rollback equals the …
authored
448 while getopts :BG:CD:QR:Uc:v opt; do
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
449 case $opt in
450 B)
451 [[ -n $action ]] && die "only one operation may be used at a time"
452 action=backup ;;
453 C)
454 [[ -n $action ]] && die "only one operation may be used at a time"
455 action=resquash_now ;;
456 D)
457 [[ -n $action ]] && die "only one operation may be used at a time"
458 action="remove_bin $OPTARG" ;;
11377a2 @falconindy add interactive restore capability for file and/or directory via -G a…
authored
459 G)
460 [[ -n $action ]] && die "only one operation may be used at a time"
461 action="restore $OPTARG" ;;
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
462 Q)
463 [[ -n $action ]] && die "only one operation may be used at a time"
464 action=report ;;
465 R)
466 [[ -n $action ]] && die "only one operation may be used at a time"
467 action="rollback $OPTARG" ;;
468 U)
469 [[ -n $action ]] && die "only one operation may be used at a time"
470 action=unmount ;;
471 c)
472 [[ -f $OPTARG ]] && source $OPTARG ;;
47295fc @falconindy fix bug with rolling back when number of bins to rollback equals the …
authored
473 v)
474 DEBUG=true ;;
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
475 \:)
476 die "Argument missing from -$OPTARG"
477 usage ;;
478 \?)
479 die "Unrecognized option -$OPTARG"
480 usage ;;
481 esac >&2
dcff2dd @falconindy Reimplement options using getopts
authored
482 done
483
83c7e76 @falconindy overhaul. redo indents to 2 spaces. use short circuit boolean instead…
authored
484 [[ -z $action ]] && usage
485
486 action_$action
Something went wrong with that request. Please try again.