1 |
9800
|
aaronmk
|
#!/bin/bash -e
|
2 |
|
|
. "$(dirname "${BASH_SOURCE[0]}")"/util.sh
|
3 |
|
|
|
4 |
|
|
if self_not_included; then
|
5 |
|
|
|
6 |
|
|
alias use_sync='declare prefix=sync_; import_vars; unset prefix'
|
7 |
|
|
|
8 |
10030
|
aaronmk
|
upload() # usage: local_dir=... remote_url=serv:dir [swap=1] [subpath=...] \
|
9 |
|
|
# upload [opt|path]...
|
10 |
10009
|
aaronmk
|
# swap: downloads instead of uploads
|
11 |
10030
|
aaronmk
|
# subpath: relative to *currdir*, not $local_dir as in `put`
|
12 |
10015
|
aaronmk
|
# path: relative to *currdir*, not $local_dir. when invoking from a script, use
|
13 |
|
|
# an absolute path (e.g. "$(dirname "${BASH_SOURCE[0]}")"/...).
|
14 |
9800
|
aaronmk
|
# requires put from https://uutils.googlecode.com/svn/trunk/bin/put
|
15 |
|
|
{
|
16 |
9893
|
aaronmk
|
echo_func; kw_params local_dir remote_url; echo_vars swap
|
17 |
9800
|
aaronmk
|
|
18 |
10030
|
aaronmk
|
# make subpath relative to currdir
|
19 |
|
|
if test "$subpath"; then
|
20 |
|
|
local subpath="$(base_dir="$local_dir" canon_rel_path "$subpath")"
|
21 |
|
|
if test "$subpath" = .; then unset subpath; fi
|
22 |
|
|
fi
|
23 |
|
|
|
24 |
9889
|
aaronmk
|
# change path args to --includes
|
25 |
12955
|
aaronmk
|
local has_includes= only_explicit_files=1 args=()
|
26 |
9889
|
aaronmk
|
local a; for a in "$@"; do
|
27 |
|
|
if starts_with -- "$a"; then args+=("$a") # option, so leave as is
|
28 |
|
|
else # path
|
29 |
|
|
# also need to --include parent dirs for each --include path
|
30 |
10144
|
aaronmk
|
path_parents "$(base_dir="$local_dir" canon_dir_rel_path "$a")"
|
31 |
9889
|
aaronmk
|
args+=("${dirs[@]/#/--include=/}") # prepend each with --include=/
|
32 |
9890
|
aaronmk
|
has_includes=1
|
33 |
12955
|
aaronmk
|
if ! could_be_file "$a"; then only_explicit_files=; fi
|
34 |
9889
|
aaronmk
|
fi
|
35 |
|
|
done
|
36 |
12955
|
aaronmk
|
if test ! "$has_includes"; then only_explicit_files=; fi #root dir->not file
|
37 |
9890
|
aaronmk
|
set -- "${args[@]}" ${has_includes:+--exclude="**"}
|
38 |
9811
|
aaronmk
|
|
39 |
12955
|
aaronmk
|
if test ! "$only_explicit_files"; then # don't rsync-ignore explicit files
|
40 |
|
|
# use .rsync_ignore
|
41 |
|
|
set -- --filter="dir-merge,- .rsync_ignore" "$@"
|
42 |
|
|
|
43 |
|
|
# use directional .rsync_filter
|
44 |
|
|
local filter_type=upload; if test "$swap"; then filter_type=download; fi
|
45 |
|
|
set -- --filter="dir-merge .rsync_filter.$(hostname -s).$filter_type" \
|
46 |
|
|
--filter="dir-merge .rsync_filter.$filter_type" "$@"
|
47 |
|
|
fi
|
48 |
10000
|
aaronmk
|
|
49 |
9890
|
aaronmk
|
src="$local_dir" dest="$remote_url" command put "$@"
|
50 |
9800
|
aaronmk
|
}
|
51 |
|
|
|
52 |
13260
|
aaronmk
|
db_copy() # usage: [live=] from=... [to=...] db_copy
|
53 |
|
|
# **IMPORTANT**: to produce a consistent snapshot, DB must be shut down
|
54 |
13258
|
aaronmk
|
{
|
55 |
13260
|
aaronmk
|
echo_func; kw_params live from to; : "${from:?}"
|
56 |
13258
|
aaronmk
|
local_export live="${live-1}"; local to="${to:-$from.bak}"
|
57 |
|
|
sudo mkdir "$to"
|
58 |
|
|
|
59 |
13263
|
aaronmk
|
local_dir="$from" remote_url="$to" inplace=1 sudo upload --delete-excluded \
|
60 |
|
|
--exclude=.DO_NOT_BACKUP # allow tape backup
|
61 |
13260
|
aaronmk
|
# inplace: for large files, don't re-copy entire file
|
62 |
|
|
}
|
63 |
|
|
|
64 |
|
|
db_snapshot() # usage: [live=] ctl=... from=... [to=...] db_snapshot
|
65 |
|
|
# ctl(cmd:{start|stop}): daemon controller that takes command param
|
66 |
|
|
{
|
67 |
|
|
echo_func; kw_params ctl from to; : "${ctl:?}"
|
68 |
|
|
|
69 |
13261
|
aaronmk
|
# copy changes before stopping DB to minimize the time that it's shut down
|
70 |
|
|
db_copy # copy changes since last backup
|
71 |
|
|
db_copy # copy changes that occurred during the copy operation
|
72 |
|
|
|
73 |
|
|
# make copy a consistent snapshot
|
74 |
13258
|
aaronmk
|
sudo "$ctl" stop
|
75 |
13260
|
aaronmk
|
try db_copy
|
76 |
13258
|
aaronmk
|
sudo "$ctl" start
|
77 |
|
|
rethrow
|
78 |
|
|
}
|
79 |
|
|
|
80 |
9800
|
aaronmk
|
fi
|