Enterprise-Onion-Toolkit/eotk

630 wiersze
17 KiB
Plaintext
Czysty Zwykły widok Historia

2017-02-04 10:06:42 +00:00
#!/bin/sh
# Enterprise Onion Toolkit
2017-02-22 13:29:31 +00:00
# A NOTE TO CONTRIBUTORS: yes this is a big script, but it's also
# written to be easy to understand (and reason about) what it is
# doing; this is why there are `for` loops around `scp` rather than
# tarballing up a bunch of file and shipping them to remote machines,
# unpacking them there. This is (mostly) why there are some
# long_variable_names. I plan to keep it that way.
2017-02-16 23:02:42 +00:00
#rsync_flags="-n" # testing
2017-02-16 23:02:42 +00:00
# expected by tools and libraries
2017-02-04 10:06:42 +00:00
cd `dirname $0` || exit 1
2017-02-16 23:02:42 +00:00
export EOTK_HOME=`pwd`
2017-02-04 16:28:16 +00:00
2017-02-14 23:58:51 +00:00
# for invoking myself
prog=`basename $0`
self=$EOTK_HOME/$prog
# meta
2017-02-22 13:29:31 +00:00
version=1.2
2017-02-14 23:58:51 +00:00
2017-02-04 16:28:16 +00:00
# set project directory; this path is hard-replicated elsewhere
2017-02-04 10:06:42 +00:00
project_dir=$EOTK_HOME/projects.d
# mirror directory
mirrors_dir=$EOTK_HOME/mirrors.d
2017-02-16 23:02:42 +00:00
# onionbalance directory
ob_dir=$EOTK_HOME/onionbalance.d
2017-02-16 23:35:31 +00:00
ob_conf=$ob_dir/config.yaml
ob_status_sock=$ob_dir/ob-status.sock
ob_tor_conf=$ob_dir/tor.conf
ob_tor_control_sock=$ob_dir/tor-control.sock
2017-02-16 23:02:42 +00:00
# init script name
init=eotk-rc.sh
2017-02-04 16:28:16 +00:00
# set path
2017-02-05 13:14:47 +00:00
export PATH=$EOTK_HOME/opt.d:$EOTK_HOME/lib.d:$PATH
2017-02-04 16:28:16 +00:00
2017-02-16 23:02:42 +00:00
##################################################################
# argument stripping
flag_remote=false
2017-03-01 22:18:07 +00:00
flag_local=false
2017-02-16 23:02:42 +00:00
while : ; do
case "x$1" in
x--remote)
flag_remote=true
shift
;;
2017-03-01 22:18:07 +00:00
x--local)
flag_local=true
shift
;;
2017-02-16 23:02:42 +00:00
x--debug)
set -x
shift
;;
*)
break
;;
esac
done
# what are the hostnames of the remote workers?
2017-02-21 20:14:57 +00:00
host_list=$EOTK_HOME/eotk-workers.conf
2017-02-16 23:02:42 +00:00
CloudHosts() {
# use --remote hack to forcibly stop risk of recursion...
if $flag_remote ; then
echo "localhost" # this will be treated as a magic sentinel
return 0
fi
2017-03-01 22:18:07 +00:00
# perversely, --local, exactly the same
if $flag_local ; then
echo "localhost"
return 0
fi
2017-02-16 23:02:42 +00:00
# todo: if eotk-hosts.conf exists,
# cat it (strip comments?)
# and return
if [ -s $host_list ] ; then
cat $host_list
return 0
fi
# else we are working just on this machine
echo "localhost" # this will be treated as a magic sentinel
}
cloud_hosts=`CloudHosts` # saves multiple invocations
need_to_run_locally=false
for host in $cloud_hosts ; do
test "x$host" = "xlocalhost" && need_to_run_locally=true
done
2017-02-16 23:02:42 +00:00
##################################################################
2017-02-14 21:49:34 +00:00
# print a formatted message to stdout
Print() {
echo "$prog:" "$@"
}
# print a formatted message to stderr
Warn() {
2017-02-14 21:49:34 +00:00
Print "$@" 1>&2
}
2017-02-14 23:00:04 +00:00
# essentially the projects.d folder is a little database
ListProjects() {
(
test -d $project_dir || exit 1
2017-02-14 23:00:04 +00:00
cd $project_dir || exit 1
for d in *.d/ ; do
echo `basename $d .d`
done
)
2017-02-14 21:49:34 +00:00
}
2017-02-16 23:02:42 +00:00
# TODO(alecm) resolve potential clashes between project names and
# various other directory names ending in ".d"; maybe use ".proj"?
2017-02-22 13:29:31 +00:00
SpotPush() {
for filename in "$@" ; do
files=`find $EOTK_HOME/projects.d -type f -name "$filename" | sort`
for host in $cloud_hosts ; do
test "x$host" = "xlocalhost" && continue # skip self
echo :::: push $host ::::
for filepath in $files ; do
Print copying $filepath to $host
scp -p $filepath $host:$filepath || exit 1
done
done
done
}
# push eotk directory to remote
DestructivePush() {
2017-02-16 23:02:42 +00:00
for host in $cloud_hosts ; do
test "x$host" = "xlocalhost" && continue # skip self
2017-02-22 13:29:31 +00:00
echo :::: rnap $host ::::
2017-02-16 23:02:42 +00:00
rsync $rsync_flags \
-av \
--delete \
--delete-excluded \
--exclude="*.log" \
--exclude="*.pid" \
--exclude="*.sock" \
--exclude="*.yaml" \
--exclude="*~" \
--exclude="docs.d/" \
--exclude="mirrors.d/" \
--exclude="onionbalance.d/" \
--exclude="secrets.d/" \
--exclude=".git/" \
--exclude=".gitignore" \
--exclude="cached-certs" \
--exclude="cached-microdesc*" \
--exclude="configure*.log" \
2017-02-21 23:28:52 +00:00
--exclude="eotk-workers.conf" \
2017-02-16 23:02:42 +00:00
--exclude="hostname" \
--exclude="lock" \
--exclude="onion_service_non_anonymous" \
--exclude="private_key" \
--exclude="state" \
${EOTK_HOME}/ \
$host:${EOTK_HOME}/
2017-02-14 23:00:04 +00:00
done
}
# mirror remote back for log review, backup, etc
Mirror() {
2017-02-16 23:02:42 +00:00
for host in $cloud_hosts ; do
test "x$host" = "xlocalhost" && continue # skip self
echo :::: mirror $host ::::
2017-02-15 16:04:58 +00:00
test -d $mirrors_dir || mkdir -p $mirrors_dir || exit 1
2017-02-26 21:11:22 +00:00
chmod 700 $mirrors_dir || exit 1
2017-02-16 23:02:42 +00:00
rsync $rsync_flags -av \
--delete \
--delete-excluded \
2017-02-15 10:56:58 +00:00
--exclude="cached-certs" \
--exclude="cached-microdesc*" \
$host:${EOTK_HOME}/ $mirrors_dir/$host/
2017-02-14 23:00:04 +00:00
done
}
2017-02-14 21:49:34 +00:00
# run a command in the context of the local projects directory
2017-02-16 23:02:42 +00:00
RunLocally() {
2017-02-04 10:06:42 +00:00
action=$1
shift
2017-02-16 23:02:42 +00:00
project=$1
shift
2017-02-16 23:02:42 +00:00
echo :::: $action $project $@ ::::
sh "$project_dir/$project.d/$action.sh" "$@"
}
2017-02-16 23:02:42 +00:00
# $1=action, rest = project names
RunLocallyOverProjects() {
action=$1
shift # remaining arguments are projects
2017-02-14 21:49:34 +00:00
2017-02-16 23:02:42 +00:00
if [ "x$1" = "x" ] ; then # test for no args
2017-02-14 23:00:04 +00:00
Print error: missing project name, try: $prog projects for a list, or -a for all
2017-02-14 21:49:34 +00:00
return 1
2017-02-16 23:02:42 +00:00
elif [ "x$1" = "x-a" ] ; then # test for / expand the "-a" flag
2017-02-14 21:49:34 +00:00
projects=`ListProjects`
2017-02-16 23:02:42 +00:00
else # do what we are told
2017-02-04 10:06:42 +00:00
projects="$*"
fi
2017-02-16 23:02:42 +00:00
# loop
2017-02-04 10:06:42 +00:00
for project in $projects ; do
2017-02-16 23:02:42 +00:00
RunLocally $action $project
done
}
# run a command on remote machines, or possibly locally
InvokeRemotely() {
for host in $cloud_hosts ; do
test "x$host" = "xlocalhost" && continue # skip self
2017-03-06 14:13:19 +00:00
echo :::: remote $host: $* ::::
2017-02-16 23:02:42 +00:00
ssh "$host" "$self --remote $*"
2017-02-04 10:06:42 +00:00
done
}
2017-02-14 23:00:04 +00:00
# implement kludge to insert freshly-generated onions into a "*.tconf"
2017-02-14 21:49:34 +00:00
# template-configuration, so people don't have to type so much...
2017-02-07 13:57:12 +00:00
Populate() {
2017-02-14 21:49:34 +00:00
if [ -t 0 ] ; then # if stdin is a terminal, provide diags
dots=true
else
dots=false
fi
2017-02-07 13:57:12 +00:00
cat "$@" |
while read line ; do
case "$line" in
*%NEW_ONION%*) # legacy / shorter / more common
2017-02-14 23:58:51 +00:00
onion=secrets.d/`$self genkey`
2017-02-07 13:57:12 +00:00
echo "$line" | sed -e "s!%NEW_ONION%!$onion!"
;;
2017-02-16 23:02:42 +00:00
*%NEW_HARD_ONION%*) # same as NEW_ONION
2017-02-14 23:58:51 +00:00
onion=secrets.d/`$self genkey`
echo "$line" | sed -e "s!%NEW_HARD_ONION%!$onion!"
;;
*%NEW_SOFT_ONION%*)
2017-02-14 23:58:51 +00:00
onion=`$self genkey`
onion=`basename $onion .key`
echo "$line" | sed -e "s!%NEW_SOFT_ONION%!$onion!"
;;
2017-02-07 13:57:12 +00:00
*)
echo "$line"
;;
esac
2017-02-14 21:49:34 +00:00
if $dots ; then
echo ".\c" >/dev/tty
fi
2017-02-07 13:57:12 +00:00
done
if $dots ; then
echo "" >/dev/tty
fi
2017-02-07 13:57:12 +00:00
}
2017-02-14 21:49:34 +00:00
# get a config file and re/populate the projects directory with it
2017-02-07 10:05:53 +00:00
Configure() {
log=configure$$.log
for file in "$@" ; do
2017-02-16 23:02:42 +00:00
echo :::: configure $file ::::
2017-02-07 13:57:12 +00:00
case "$file" in
2017-02-14 21:49:34 +00:00
*.conf)
: happy bunnies
;;
2017-02-07 13:57:12 +00:00
*.tconf)
file2=`basename $file .tconf`.conf
if [ -s $file2 ] ; then
2017-02-14 21:49:34 +00:00
Print info: $file: using existing $file2
2017-02-07 13:57:12 +00:00
else
2017-02-14 21:49:34 +00:00
Print info: $file: populating $file2 with onions, please be patient...
Populate $file >$file2
2017-02-07 13:57:12 +00:00
fi
file="$file2"
;;
2017-02-14 21:49:34 +00:00
*)
Print error: bad config file suffix, was expecting: .conf, .tconf
exit 1
;;
esac
2017-02-07 13:57:12 +00:00
2017-02-07 10:05:53 +00:00
if ! $EOTK_HOME/lib.d/do-configure.pl "$file" ; then
2017-02-14 21:49:34 +00:00
Print error: failure processing $file: see $log
2017-02-07 10:05:53 +00:00
exit 1
fi
done 2>$log
2017-02-16 23:02:42 +00:00
Print done. logfile is $log
2017-02-07 10:05:53 +00:00
}
2017-02-14 21:49:34 +00:00
# argument 'parser' - ha!
2017-02-16 23:35:31 +00:00
cmd="$1" # we may need the remaining args
shift
case "$cmd" in
version)
Print $version $EOTK_HOME `uname -a`
test -d .git && git show -s --oneline
;;
projects|proj)
ListProjects
;;
populate|pop)
Populate "$@"
;;
configure|config|conf)
Configure "$@"
;;
genkey|gen)
2017-02-26 21:11:22 +00:00
secrets_dir=secrets.d
test -d $secrets_dir || mkdir -p $secrets_dir || exit 1
chmod 700 $secrets_dir || exit 1
2017-02-16 23:35:31 +00:00
(
2017-02-26 21:11:22 +00:00
cd $secrets_dir
2017-02-16 23:35:31 +00:00
generate-onion-key.sh
)
;;
test)
$self version # recurse!
InvokeRemotely version
;;
## ACTIONS
2017-02-27 09:09:34 +00:00
start) # project ..., or "-a"
2017-02-17 11:44:13 +00:00
$need_to_run_locally && RunLocallyOverProjects start "$@"
2017-02-16 23:35:31 +00:00
InvokeRemotely start "$@"
;;
2017-02-27 09:09:34 +00:00
stop) # project ..., or "-a"
2017-02-17 11:44:13 +00:00
$need_to_run_locally && RunLocallyOverProjects stop "$@"
2017-02-16 23:35:31 +00:00
InvokeRemotely stop "$@"
;;
2017-02-27 09:09:34 +00:00
restart|bounce|reload) # project ..., or "-a"
2017-02-17 11:44:13 +00:00
$need_to_run_locally && RunLocallyOverProjects bounce "$@"
2017-02-16 23:35:31 +00:00
InvokeRemotely bounce "$@"
;;
2017-02-27 09:09:34 +00:00
nxreload|nx-reload) # project ..., or "-a"
2017-02-17 11:44:13 +00:00
$need_to_run_locally && RunLocallyOverProjects nxreload "$@"
2017-02-16 23:35:31 +00:00
InvokeRemotely nxreload "$@"
;;
2017-02-27 09:09:34 +00:00
torreload|tor-reload) # project ..., or "-a"
2017-02-22 11:04:01 +00:00
$need_to_run_locally && RunLocallyOverProjects torreload "$@"
InvokeRemotely torreload "$@"
;;
2017-02-27 09:09:34 +00:00
debugon|debug-on) # project ..., or "-a"
2017-02-17 11:44:13 +00:00
$need_to_run_locally && RunLocallyOverProjects debugon "$@"
2017-02-16 23:35:31 +00:00
InvokeRemotely debugon "$@"
;;
2017-02-27 09:09:34 +00:00
debugoff|debug-off) # project ..., or "-a"
2017-02-17 11:44:13 +00:00
$need_to_run_locally && RunLocallyOverProjects debugoff "$@"
2017-02-16 23:35:31 +00:00
InvokeRemotely debugoff "$@"
;;
2017-02-28 14:24:44 +00:00
syntax) # project ..., or "-a"
$need_to_run_locally && RunLocallyOverProjects syntax "$@"
InvokeRemotely syntax "$@"
;;
2017-02-27 09:09:34 +00:00
harvest|onions) # project ..., or "-a"
2017-02-17 11:44:13 +00:00
$need_to_run_locally && RunLocallyOverProjects harvest "$@"
2017-02-16 23:35:31 +00:00
InvokeRemotely harvest "$@"
;;
2017-02-27 09:09:34 +00:00
status) # project ..., or "-a"
2017-03-06 14:13:19 +00:00
$self ob-ps # because common
2017-02-17 11:44:13 +00:00
$need_to_run_locally && RunLocallyOverProjects status "$@"
2017-02-16 23:35:31 +00:00
InvokeRemotely status "$@"
;;
2017-02-27 09:09:34 +00:00
maps|map) # project ..., or "-a"
2017-02-17 11:44:13 +00:00
$need_to_run_locally && RunLocallyOverProjects maps "$@"
2017-02-16 23:35:31 +00:00
InvokeRemotely maps "$@"
;;
2017-02-27 09:09:34 +00:00
delete) # project ..., or "-a"
2017-02-16 23:38:56 +00:00
Print $cmd not yet implemented, sorry.
2017-02-16 23:35:31 +00:00
;;
## DIAGS
ps)
2017-03-06 14:13:19 +00:00
$flag_remote || echo :::: eotk processes ::::
2017-02-28 14:53:42 +00:00
ps auxww | egrep '\b(eotk|onionbalance|nginx)\b'
2017-03-06 14:13:19 +00:00
# InvokeRemotely prints remote-ness banner diags
2017-02-16 23:35:31 +00:00
InvokeRemotely ps
;;
2017-02-21 20:06:06 +00:00
## ---- ONIONBALANCE ----
2017-02-16 23:35:31 +00:00
push)
Print push is destructive and has been renamed, see the documentation
;;
2017-02-22 18:44:37 +00:00
shutdown)
$self ob-stop
$self stop -a
;;
2017-02-16 23:35:31 +00:00
# this used to be called 'push' but got renamed because oops.
2017-02-21 20:06:06 +00:00
# ---- DO NOT USE THIS CASUALLY, LEARN FROM MY MISTAKES ----
ob-remote-nuke-and-push|rnap)
2017-02-16 23:35:31 +00:00
$self stop -a
DestructivePush
;;
2017-02-21 20:06:06 +00:00
ob-nxpush)
# gently push only the nginx configs to the workers
2017-02-22 13:29:31 +00:00
SpotPush nginx.conf
2017-02-21 20:06:06 +00:00
;;
2017-02-14 23:58:51 +00:00
2017-02-21 20:06:06 +00:00
ob-torpush)
# gently push only the tor configs to the workers
2017-02-22 13:29:31 +00:00
SpotPush tor.conf
;;
ob-spotpush)
# gently push only the tor configs to the workers
SpotPush "$@"
2017-02-21 20:06:06 +00:00
;;
2017-02-16 23:35:31 +00:00
2017-02-21 20:06:06 +00:00
ob-config|obconfig|ob-configure|obconfigure)
2017-02-27 09:09:34 +00:00
Print ob-configure had been rolled into ob-start
Print please skip forward to: $prog ob-start project ...
;;
ob-gather|obgather) # project ..., or "-a"
2017-02-16 23:35:31 +00:00
# ob storage
test -d $ob_dir || mkdir -p $ob_dir || exit 1
2017-02-26 21:05:33 +00:00
chmod 700 $ob_dir # otherwise tor complains
2017-02-21 20:57:05 +00:00
# sanity check that args are provided
2017-02-27 11:51:11 +00:00
if [ "x$1" = "x" ] ; then # test for no args
Print error: missing project name, try: $prog projects for a list, or -a for all "(if applicable)"
2017-02-21 20:57:05 +00:00
exit 1
2017-02-27 11:51:11 +00:00
elif [ "x$1" = "x-a" ] ; then # test for / expand the "-a" flag
projects=`ListProjects`
else # do what we are told
projects="$*"
2017-02-21 20:57:05 +00:00
fi
2017-02-26 20:57:10 +00:00
tor_address=127.0.0.1
tor_port=9055
2017-02-27 09:09:34 +00:00
# get the mappings
2017-02-27 11:51:11 +00:00
Print gathering mappings for OnionBalance for projects: $projects
2017-02-27 09:09:34 +00:00
mappings=__om$$.tmp
2017-02-27 11:51:11 +00:00
$self maps $projects |
2017-02-27 12:14:21 +00:00
awk '/^::::/{next;} $2=="softmap"{print;}' >$mappings
2017-02-27 09:09:34 +00:00
# check the mappings
2017-02-27 11:51:11 +00:00
for p in $projects ; do
2017-02-27 09:09:34 +00:00
n=`awk '$1=="'"$p"'"'<$mappings | wc -l`
if [ $n = 0 ] ; then
Warn no mappings available for project $p, does it exist / is it not a softmap project"?"
rm $mappings
exit 1
else
2017-02-27 09:25:45 +00:00
m=`awk '$1=="'"$p"'"{print $3}'<$mappings | sort -u | wc -l`
w=`awk '$1=="'"$p"'"{print $6}'<$mappings | sort -u | wc -l`
Print project $p contains $n mappings
Print project $p uses $m master onions
Print project $p uses $w worker onions
2017-02-27 09:09:34 +00:00
fi
done
Print building OnionBalance configurations...
2017-02-21 20:57:05 +00:00
(
echo LOG_LEVEL: debug
2017-02-26 20:57:10 +00:00
echo TOR_ADDRESS: $tor_address
echo TOR_PORT: $tor_port
2017-02-21 23:28:52 +00:00
echo REFRESH_INTERVAL: 600
echo PUBLISH_CHECK_INTERVAL: 300 # non-default
echo INITIAL_DELAY: 60 # non-default
echo STATUS_SOCKET_LOCATION: $ob_status_sock
echo DESCRIPTOR_VALIDITY_PERIOD: 86400
echo DESCRIPTOR_OVERLAP_PERIOD: 3600
echo DESCRIPTOR_UPLOAD_PERIOD: 3600
2017-02-27 09:09:34 +00:00
do-obconfig.pl <$mappings
2017-02-21 20:57:05 +00:00
) > $ob_conf
2017-02-27 09:09:34 +00:00
# clean up
rm $mappings
Print building OnionBalance-Tor configurations...
2017-02-16 23:35:31 +00:00
(
echo DataDirectory $ob_dir
echo ControlPort unix:$ob_tor_control_sock
echo PidFile $ob_dir/tor.pid
echo Log info file $ob_dir/tor.log
echo SafeLogging 1
echo HeartbeatPeriod 60 minutes
echo RunAsDaemon 1
echo "#" onionbalance
# echo SocksPort unix:$ob_dir/tor-socks.sock # curl 7.38 does not like this
2017-02-26 20:57:10 +00:00
echo SocksPort $tor_address:$tor_port
2017-02-16 23:35:31 +00:00
echo CookieAuthentication 1
2017-02-28 13:47:56 +00:00
# echo MaxClientCircuitsPending 1024
2017-02-16 23:35:31 +00:00
) > $ob_tor_conf
;;
2017-02-27 09:09:34 +00:00
ob-start|obstart) # project ..., or "-a"
2017-02-27 11:56:26 +00:00
if [ -f $ob_dir/ob.pid ] ; then
2017-03-04 13:33:28 +00:00
Warn file $ob_dir/ob.pid already exists, OnionBalance may already be running, aborting.
2017-02-27 11:56:26 +00:00
exit 1
fi
if [ -f $ob_dir/tor.pid ] ; then
2017-03-04 13:33:28 +00:00
Warn file $ob_dir/tor.pid already exists, OnionBalance-Tor may already be running, aborting.
2017-02-27 11:56:26 +00:00
exit 1
fi
2017-02-27 09:09:34 +00:00
$self ob-gather "$@" || exit 1
Print starting OnionBalance-Tor
2017-02-17 00:07:14 +00:00
tor -f $ob_tor_conf >$ob_dir/tor-startup.log 2>&1
2017-02-27 09:09:34 +00:00
2017-02-16 23:35:31 +00:00
Print starting OnionBalance
2017-02-17 00:07:14 +00:00
onionbalance \
-s $ob_tor_control_sock \
2017-02-17 01:35:12 +00:00
-c $ob_conf </dev/null >$ob_dir/onionbalance.log 2>&1 & # bg
2017-02-17 00:07:14 +00:00
ob_pid=$!
echo $ob_pid >$ob_dir/ob.pid
2017-02-16 23:35:31 +00:00
;;
ob-stop|obstop)
2017-02-17 00:07:14 +00:00
for pidfile in $ob_dir/ob.pid $ob_dir/tor.pid ; do
test -s $pidfile || continue
pid=`cat $pidfile`
Print sending SIGTERM to $pid in $pidfile
kill $pid
done
rm -f $ob_dir/ob.pid
2017-02-16 23:35:31 +00:00
;;
2017-02-27 09:09:34 +00:00
ob-restart) # project ..., or "-a"
2017-02-26 21:17:32 +00:00
$self ob-stop
2017-02-27 09:09:34 +00:00
$self ob-start "$@"
2017-02-26 21:17:32 +00:00
;;
2017-02-28 14:50:41 +00:00
ob-ps)
test -d $ob_dir || exit 0
2017-03-06 14:13:19 +00:00
echo :::: onionbalance processes ::::
2017-02-28 19:13:50 +00:00
pidfiles=`find $ob_dir -name "*.pid"`
2017-02-28 14:50:41 +00:00
if [ "x$pidfiles" != "x" ] ; then
ps -p `cat $pidfiles`
fi
;;
2017-02-17 20:39:14 +00:00
ob-status|obstatus)
2017-02-28 14:50:41 +00:00
$self ob-ps
if [ -S $ob_status_sock ] ; then
2017-02-17 20:39:14 +00:00
echo ""
2017-02-28 14:50:41 +00:00
socat - unix-connect:$ob_status_sock
fi
2017-02-17 20:39:14 +00:00
;;
2017-02-27 12:14:21 +00:00
ob-maps|obmaps) # project ..., or "-a"
2017-02-27 12:18:17 +00:00
if [ "x$1" = "x" ] ; then # test for no args
Print error: missing project name, try: $prog projects for a list, or -a for all "(if applicable)"
exit 1
fi
2017-02-27 12:14:21 +00:00
$self maps "$@" |
awk '/^::::/{next;} $2=="softmap"{print $3, $4}' |
2017-02-27 12:18:17 +00:00
sort -k 2 -u
2017-02-27 12:14:21 +00:00
;;
2017-02-16 23:35:31 +00:00
## FREEZE/BACKUP
mirror|pull)
Mirror
;;
2017-02-22 10:29:26 +00:00
backup|freeze)
2017-02-16 23:35:31 +00:00
Mirror
(
ds=`date "+%Y%m%d%H%M%S"`
cd $mirrors_dir || exit 1
for directory in */ ; do
test -d "$directory" || exit 1 # did */ expand?
dir=`basename $directory` # strip trailing /
2017-02-22 10:29:26 +00:00
echo :::: backup $dir ::::
2017-02-16 23:35:31 +00:00
tar cf - $dir | bzip2 > $dir-$ds.tar.bz2
done
)
;;
make-init-script)
lib.d/expand-template.pl templates.d/init.sh.txt </dev/null >$init
chmod 755 $init
;;
2017-02-16 23:35:31 +00:00
*)
Print usage: see README.md for documentation
exit 1
;;
esac
2017-02-04 10:06:42 +00:00
exit 0