[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Monotone-commits-diffs] net.venge.monotone.contrib.usher: 200716ad68df
From: |
code |
Subject: |
[Monotone-commits-diffs] net.venge.monotone.contrib.usher: 200716ad68df60ea4de9b92bf20d8acd1cf20283 |
Date: |
Wed, 19 Jan 2011 13:57:01 GMT |
revision: 200716ad68df60ea4de9b92bf20d8acd1cf20283
date: 2011-01-18T13:41:58
author: Timothy Brownawell <address@hidden>
branch: net.venge.monotone.contrib.usher
changelog:
merge of 'b16eb174a9d756580969379e1bf9db896e555373'
and 'e2a50b5003a2d6a87380c1343d01e1d32a5c3395'
manifest:
format_version "1"
new_manifest [16e7c0040863c26c4671bc137142d6a1eeac5419]
old_revision [b16eb174a9d756580969379e1bf9db896e555373]
add_file "doc/usherctl.html"
content [fffd09c2ad2cb1724f7f602d5a9910c49fc896fa]
patch "doc/documentation.html"
from [a83704fce2015f082c1268099432353a6bf60f56]
to [428368437a2f078716e183d140dd58c2532cf147]
patch "utils/usherctl"
from [af585016af49ef0233e6df6210b6bf1e513dfb39]
to [f6f4d53eb56bdec130b464c53a5c14060c248dec]
old_revision [e2a50b5003a2d6a87380c1343d01e1d32a5c3395]
add_file "release-checklist.txt"
content [305136c17d554f0b16fdab39873c5814cc64691a]
patch "NEWS"
from [a9b8cb5b3dc0ec686519bbb81dc1058d30fb1099]
to [41f6acc0681f23e164e7d8dc6be0738de13a8bf1]
patch "README"
from [b968eb93f8b8ce88d822e9ddc52b563f1742a147]
to [84610efd11606729230d94fb905e5e4695328c7b]
patch "src/channel.cc"
from [7e6b6bbae6a84041ec840bedf5816bd6e116e5ea]
to [28d584b7185308aeab9297b3c9ceae03718a9e65]
patch "src/channel.hh"
from [3a97687c17a68c983872de2792defd9e48028168]
to [21231cc383b16935ac33a349718e5aa775341c45]
patch "src/server.hh"
from [dd153b5671f0b9560be8b817849731419e5b8fe4]
to [6a57214c24d5c35c705276dcae8415dfcabf6c6e]
patch "src/server_manager.cc"
from [0abe47e13dd931c522aa1a7fb828502d63531a6e]
to [f4a5b6fe2d917f24ce56c133ee347b9b3e91e50b]
patch "src/server_manager.hh"
from [fc8ad29b28f82cae3b26955995afdad8f1276a5a]
to [1d1f3a16329bdf11b69fb7593d048d95c65edc8d]
patch "src/sock.hh"
from [0917e736d673fa6d15fcefea8f1f0e16a63b9bc2]
to [b077f32cc61674e13b9c3bc138c924c41b23ceb1]
============================================================
--- doc/documentation.html a83704fce2015f082c1268099432353a6bf60f56
+++ doc/documentation.html 428368437a2f078716e183d140dd58c2532cf147
@@ -108,8 +108,8 @@ connections on the specified address:por
If the <span style="font-family: monospace;">adminaddr</span> directive
is given in the config file, the usher will listen for administrative
connections on the specified address:port. The connecting client can
-give commands of the form<br>
-<div style="margin-left: 40px;">COMMAND [arg] ... <newline><br>
+give commands of the following form, ending with a newline:<br>
+<div style="margin-left: 40px;">COMMAND [arg] ...<br>
</div>
After any command except USERPASS the usher will send a reply and close the connection. The reply will end with a newline.<br>
<h3>Administrative commands</h3>
@@ -238,12 +238,12 @@ the named server doesn't exist.<br>
file and giving the "RELOAD" command. Returns "ok", or "not found" if
the named server doesn't exist.<br>
</dd>
- <dt>ADD_SERVER name { remote | local } args<br>
+ <dt>ADD_SERVER name { remote | local } arg ...<br>
</dt>
<dd>Add a server with the given name and startup arguments (or name and address for remote servers).
-"args" is either "hostname port" for remote servers, or "arg 'arg' ..."
-for local servers. Quotes are treated the same as for RUN. Returns
-"ok", or an error message.<br>
+"arg ..." is either "hostname port" for remote servers, or arguments
+to the underlying monotone server for local servers. Quotes are
+treated the same as for RUN. Returns "ok", or an error message.<br>
</dd>
</dl>
============================================================
--- utils/usherctl af585016af49ef0233e6df6210b6bf1e513dfb39
+++ utils/usherctl f6f4d53eb56bdec130b464c53a5c14060c248dec
@@ -27,13 +27,28 @@ MTN=/usr/bin/mtn
# (default: /var/log/usher)
# USHER_PROJECTDIR Usher projects directory.
# (default: /var/lib/usher/projects)
+#
+# The following variables are only useful for the system administrator
+# that wants to set up a system wide usher.
+# USHER_SYSTEM_STARTUP a non-empty string if usher should be started
+# and stopped with the script /etc/init.d/usher.
+# (default: (unset))
+# USHER_USER User to run usher as. Only useful if
+# usher is started with /etc/init.d/usher.
+# MUST match the user usher is started as!
+# USHER_GROUP Group to run usher as. Only useful if
+# usher is started with /etc/init.d/usher.
+# MUST match the group usher is started as!
+
+config_file="/etc/usher/usherctl.conf"
+
TEMP=`POSIXLY_CORRECT=yes getopt -o c: -n usherctl -- "$@"`
eval set -- "$TEMP"
while true; do
case "$1" in
-c )
if [ -r "$2" ]; then
- . "$2"
+ config_file="$2"
fi
shift 2
;;
@@ -44,11 +59,13 @@ done
esac
done
+. "$config_file"
+
# Apply default where nothing is set.
USHER_CONFDIR=${USHER_CONFDIR:-/etc/usher}
-USHER_CONF=${USHER_CONF:-$USHER_CONFDIR/usher.conf}
-USHER_GLOBALCONF=${USHER_GLOBALCONF:-$USHER_CONFDIR/global.conf}
-USHER_CONFD=${USHER_CONFD:-$USHER_CONFDIR/conf.d}
+USHER_CONF=${USHER_CONF:-"$USHER_CONFDIR/usher.conf"}
+USHER_GLOBALCONF=${USHER_GLOBALCONF:-"$USHER_CONFDIR/global.conf"}
+USHER_CONFD=${USHER_CONFD:-"$USHER_CONFDIR/conf.d"}
USHER_PIDFILE=${USHER_PIDFILE:-/var/run/usher.pid}
USHER_LOGDIR=${USHER_LOGDIR:-/var/log/usher}
USHER_PROJECTDIR=${USHER_PROJECTDIR:-/var/lib/usher/projects}
@@ -56,9 +73,9 @@ _read_pid_file () {
THIS="$0"
_read_pid_file () {
- if [ -r $USHER_PIDFILE ]; then
- cat $USHER_PIDFILE
- elif [ -f $USHER_PIDFILE ]; then
+ if [ -r "$USHER_PIDFILE" ]; then
+ cat "$USHER_PIDFILE"
+ elif [ -f "$USHER_PIDFILE" ]; then
echo >&2 "There is a pid file you aren't allowed to read: $USHER_PIDFILE"
echo >&2 "This means there may be a usher process running, and that"
echo >&2 "you don't have permission to change that."
@@ -69,63 +86,116 @@ status () {
}
status () {
- pid=`_read_pid_file`
- if [ -n "$pid" ]; then
- if kill -0 $pid 2>/dev/null; then
- echo "The usher process is up and running: $pid"
+ if [ -z $USHER_SYSTEM_STARTUP ]; then
+ pid=`_read_pid_file`
+ if [ -n "$pid" ]; then
+ if kill -0 $pid 2>/dev/null; then
+ echo "The usher process is up and running: $pid"
+ return 0
+ else
+ echo "The usher process is down, but there's a PID file."
+ return 1
+ fi
else
- echo "The usher process is down, but there's a PID file."
+ echo "The usher process is down."
+ return 2
fi
else
- echo "The usher process is down."
+ /etc/init.d/usher status
fi
}
start () {
- pid=`_read_pid_file`
- if [ -n "$pid" ]; then
- if kill -0 $pid 2>/dev/null; then
- echo >&2 "Usher process already up: $pid"
- exit 1
+ if [ -z $USHER_SYSTEM_STARTUP ]; then
+ pid=`_read_pid_file`
+ if [ -n "$pid" ]; then
+ if kill -0 $pid 2>/dev/null; then
+ echo >&2 "Usher process already up: $pid"
+ exit 1
+ fi
fi
+ rm -f "$USHER_PIDFILE"
+ $USHER -p "$USHER_PIDFILE" "$USHER_CONF" \
+ < /dev/null > /dev/null 2> /dev/null &
+ else
+ /etc/init.d/usher start
fi
- rm -f $USHER_PIDFILE
- $USHER -p $USHER_PIDFILE $USHER_CONF < /dev/null > /dev/null 2> /dev/null &
}
stop () {
- pid=`_read_pid_file`
- if [ -n "$pid" ]; then
- kill $pid
+ if [ -z $USHER_SYSTEM_STARTUP ]; then
+ pid=`_read_pid_file`
+ if [ -n "$pid" ]; then
+ kill $pid
+ fi
+ else
+ /etc/init.d/usher stop
fi
}
reload () {
- pid=`_read_pid_file`
- if [ -z "$pid" ]; then
- echo >&2 No usher process present.
- exit 1
+ if [ -z $USHER_SYSTEM_STARTUP ]; then
+ pid=`_read_pid_file`
+ if [ -z "$pid" ]; then
+ echo >&2 "No usher process present."
+ exit 1
+ else
+ kill -1 $pid
+ fi
else
- kill -1 $pid
+ /etc/init.d/usher reload
fi
}
restart () {
- stop && start
+ if [ -z $USHER_SYSTEM_STARTUP ]; then
+ stop && start
+ else
+ /etc/init.d/usher restart
+ fi
}
+restart_if_started () {
+ if [ -z $USHER_SYSTEM_STARTUP ]; then
+ pid=`_read_pid_file`
+ if [ -n "$pid" ]; then
+ restart
+ fi
+ elif /etc/init.c/usher status >/dev/null 2>/dev/null; then
+ /etc/init.d/usher restart
+ fi
+}
-_mkconf () {
- if [ -f $USHER_CONF ]; then
- cp $USHER_CONF $USHER_CONF~ || exit 1
+
+_maybe_set_file_owner() {
+ for file in "$@"; do
+ if [ -n "$USHER_USER" -a -n "$USHER_GROUP" ]; then
+ chown ${USHER_USER}:${USHER_GROUP} "$file"
+ fi
+ done
+}
+
+_maybe_set_directory_owner() {
+ for dir in "$@"; do
+ if [ -n "$USHER_USER" -a -n "$USHER_GROUP" ]; then
+ chown -R ${USHER_USER}:${USHER_GROUP} "$dir"
+ fi
+ done
+}
+
+rebuild () {
+ if [ -f "$USHER_CONF" ]; then
+ cp "$USHER_CONF" "$USHER_CONF~" || exit 1
fi
(
- cat $USHER_GLOBALCONF
- for x in $USHER_CONFD/*.conf; do
+ if [ -f "$USHER_GLOBALCONF" ]; then cat "$USHER_GLOBALCONF"; fi
+ ls "$USHER_CONFD"/*.conf 2>/dev/null | while read x; do
echo
cat $x
done
- ) > $USHER_CONF 2>/dev/null
+ ) > "$USHER_CONF"
+ _maybe_set_file_owner "$USHER_CONF"
+ chmod 640 "$USHER_CONF"
}
# $1 operation
@@ -142,14 +212,20 @@ writesrv () {
type="$1"; shift
if [ -z "$name" ]; then
- echo >&2 Server must have a name.
+ echo >&2 "Server must have a name."
exit 1
fi
- ( set -x
+ (
echo "server \"$name\""
- [ -n "$host" ] && echo "host \"$host\""
- [ -n "$pattern" ] && echo "pattern \"$pattern\""
+ if [ -n "$host" ]; then echo "host \"$host\""; fi
+ if [ -n "$pattern" ]; then
+ if [ "$pattern" = ";" ]; then
+ echo "pattern \"\""
+ else
+ echo "pattern \"$pattern\""
+ fi
+ fi
case "$type" in
local )
argslist=
@@ -162,13 +238,15 @@ writesrv () {
echo "remote \"$1\""
;;
* )
- echo >&2 Unknown type \'$type\'.
+ echo >&2 "Unknown type '$type'."
exit 1
;;
esac
- ) > $USHER_CONFD/$name.conf
- _mkconf
- echo >&2 Server $name $op, please reload usher to activate.
+ ) > "$USHER_CONFD/$name.conf"
+ _maybe_set_file_owner "$USHER_CONFD/$name.conf"
+ chmod 640 "$USHER_CONFD/$name.conf"
+ rebuild
+ echo >&2 "Server '$name' $op, please reload usher to activate."
}
# $1 server name
@@ -177,8 +255,8 @@ addsrv () {
# $4 type (remote local)
# $5- args
addsrv () {
- if [ -f $USHER_CONFD/$1.conf ]; then
- echo >&2 There is already a server named $1, not changing.
+ if [ -f "$USHER_CONFD/$1.conf" ]; then
+ echo >&2 "There is already a server named '$1', not changing."
exit 1
fi
@@ -196,8 +274,8 @@ modsrv () {
opattern="$1"; pattern="$1"; shift
otype="$1"
- if [ ! -f $USHER_CONFD/$name.conf ]; then
- echo >&2 There is no server configuration named $name, nothing to modify.
+ if [ ! -f "$USHER_CONFD/$name.conf" ]; then
+ echo >&2 "There is no server configuration named '$name', nothing to modify."
exit 1
fi
@@ -207,7 +285,14 @@ modsrv () {
if [ -z "$ohost" ]; then eval "host=$A"; fi
;;
pattern )
- if [ -z "$opattern" ]; then eval "pattern=$A"; fi
+ if [ -z "$opattern" ]; then
+ eval "pattern=$A";
+ # Because a pattern prefix can be empty, but there's
+ # no way to distinguish that from an unset value, let's
+ # use a forbidden branch character as an internal marker
+ # for the empty pattern.
+ if [ -z "$pattern" ]; then pattern=";"; fi
+ fi
;;
remote | local )
if [ -z "$otype" ]; then eval "set -- $K $A"; fi
@@ -215,8 +300,8 @@ modsrv () {
* )
;;
esac
- done < $USHER_CONFD/$name.conf
- mv $USHER_CONFD/$name.conf $USHER_CONFD/$name.conf~
+ done < "$USHER_CONFD/$name.conf"
+ mv "$USHER_CONFD/$name.conf" "$USHER_CONFD/$name.conf~"
writesrv modified "$name" "$host" "$pattern" "$@"
}
@@ -224,14 +309,14 @@ delsrv () {
delsrv () {
name="$1"
- if [ ! -f $USHER_CONFD/$name.conf ]; then
- echo >&2 There is no server configuration named $name, nothing to delete.
+ if [ ! -f "$USHER_CONFD/$name.conf" ]; then
+ echo >&2 "There is no server configuration named '$name', nothing to delete."
exit 1
fi
- rm -f $USHER_CONFD/$name.conf $USHER_CONFD/$name.conf~
- _mkconf
- echo >&2 Server $name deleted, please reload usher to activate.
+ rm -f "$USHER_CONFD/$name.conf" "$USHER_CONFD/$name.conf~"
+ rebuild
+ echo >&2 "Server '$name' deleted, please reload usher to activate."
}
# $1 type
@@ -241,7 +326,7 @@ mkproject () {
name="$1"; shift
if [ -e "$USHER_PROJECTDIR/$name" ]; then
- echo >&2 There already is a project named "$name".
+ echo >&2 "There already is a project named '$name'."
exit 1
fi
@@ -251,6 +336,7 @@ mkproject () {
mkdir "$confdir/hooks.d"
set +e
+ _maybe_set_directory_owner "$confdir"
chmod 0750 "$confdir"
# Generate name and password for the server key
@@ -258,31 +344,43 @@ mkproject () {
skp=`dd if=/dev/random ibs=8 count=1 2>/dev/null | \
perl -e 'my $string=""; while (<STDIN>) { $string .= $_; } print unpack("H*",$string),"\n";'`
echo "$skn \"$skp\"" > $confdir/passphrases
+ _maybe_set_file_owner "$confdir/passphrases"
chmod 400 $confdir/passphrases
+ # Generate database
mtn="$MTN -d \"$confdir/database.mtn\" --confdir \"$confdir\" --no-standard-rcfiles --ticker=dot"
eval $mtn db init
+ _maybe_set_file_owner "$confdir/database.mtn"
+ chmod 0600 "$confdir/database.mtn"
+
+ # Generate key
(echo "$skp"; echo "$skp") | \
eval $mtn genkey "$skn" > /dev/null 2> /dev/null
skid=`eval $mtn ls keys | grep "$skn\$" | tail -1 | cut -f1 -d' '`
- chmod 0600 "$confdir/database.mtn"
+ _maybe_set_directory_owner "$confdir/keys"
sed -e '1,/^# -----BEGIN monotonerc-----$/d' \
-e '/^# -----END monotonerc-----$/,$d' \
-e 's/^# //' \
< "$THIS" > "$confdir/monotonerc"
+ _maybe_set_file_owner "$confdir/monotonerc"
chmod 0640 "$confdir/monotonerc"
aconfdir="$confdir/admin"
mkdir "$aconfdir"
+ _maybe_set_directory_owner "$aconfdir"
chmod 700 "$aconfdir"
amtn="$MTN -d \"$aconfdir/database.mtn\" --confdir \"$aconfdir\" --no-standard-rcfiles --ticker=dot"
eval $amtn db init
- (echo; echo) | eval $amtn genkey ".$name-admin" > /dev/null 2> /dev/null
+ _maybe_set_file_owner "$aconfdir/database.mtn"
+ chmod 0600 "$aconfdir/database.mtn"
+
+ (echo; echo) | eval $amtn genkey "$name-admin" > /dev/null 2> /dev/null
akid=`eval $amtn ls keys | grep "$akn\$" | tail -1 | cut -f1 -d' '`
+ _maybe_set_directory_owner "$aconfdir/keys"
- listenport=`cat $USHER_CONF | grep '^ *listenaddr' | tail -1 | \
+ listenport=`cat "$USHER_CONF" | grep '^ *listenaddr' | tail -1 | \
cut -f2 -d'"' | cut -f2 -d:`
case $type in
@@ -298,6 +396,8 @@ mkproject () {
-e "s|%confdir%|$confdir|g" \
-e "s|%listenport%|$listenport|g" \
-e "s|%name%|$name|g" \
+ -e "s|%user%|$USHER_USER|g" \
+ -e "s|%group%|$USHER_GROUP|g" \
-e 's/^# //' \
< "$THIS" > "$confdir/addclientkeys"
;;
@@ -312,64 +412,90 @@ mkproject () {
-e "s|%confdir%|$confdir|g" \
-e "s|%listenport%|$listenport|g" \
-e "s|%name%|$name|g" \
+ -e "s|%user%|$USHER_USER|g" \
+ -e "s|%group%|$USHER_GROUP|g" \
-e 's/^# //' \
< "$THIS" > "$confdir/addclientkeys"
;;
esac
+ _maybe_set_file_owner "$confdir/read-permissions"
+ _maybe_set_file_owner "$confdir/write-permissions"
+ _maybe_set_file_owner "$confdir/addclientkeys"
chmod 0640 $confdir/read-permissions
chmod 0640 $confdir/write-permissions
chmod 0600 $confdir/addclientkeys
# We need a quick bootstrap, otherwise addclientkeys won't work
- eval $amtn pubkey ".$name-admin" | eval $mtn read 2> /dev/null
+ eval $amtn pubkey "$name-admin" | eval $mtn read 2> /dev/null
addsrv "$name" "" "" \
local "--confdir" "$confdir" "-d" "$confdir/database.mtn" \
"--no-standard-rcfiles" "--rcfile" "$confdir/monotonerc" \
"--timestamps" "--ticker=dot" 2>/dev/null
- restart
+ restart_if_started
+ _maybe_set_file_owner "$confdir/addclientkeys"
chmod 700 "$confdir/addclientkeys"
- eval $amtn pubkey ".$name-admin" | "$confdir/addclientkeys"
+ eval $amtn pubkey "$name-admin" | "$confdir/addclientkeys"
- echo >&2 $type project $name created
+ echo >&2 "$type project '$name' created."
}
rmproject () {
name="$1"; shift
if [ ! -e "$USHER_PROJECTDIR/$name" ]; then
- echo >&2 There is no project named "$name".
+ echo >&2 "There is no project named '$name'."
exit 1
fi
- delsrv $name 2>/dev/null
- restart
- rm -rf $USHER_PROJECTDIR/$name
- echo >&2 project $name removed
-}
+ delsrv "$name" 2>/dev/null
+ restart_if_started
+ rm -rf "$USHER_PROJECTDIR/$name"
+ echo >&2 "project '$name' removed."
+}
+list () {
+ grep '^ *server *"' "$USHER_CONF" | cut -f2 -d'"' | while read name; do
+ text="$name"
+ extratext=" (WARNING: seems manually added, might get overwritten)"
+ if [ -f "$USHER_CONFD/$name.conf" ]; then
+ extratext=" (managed with usherctl)"
+ fi
+ if [ -d "$USHER_PROJECTDIR/$name" ]; then
+ extratext=" (project managed with usherctl)"
+ fi
+ echo "$text$extratext"
+ done
+}
+
#----------------------------------------------------------------------
case $1 in
init )
shift
- if [ -f $USHER_GLOBALCONF ]; then
- echo >&2 Usher is already initialised.
+ if [ -f "$USHER_GLOBALCONF" ]; then
+ echo >&2 "Usher is already initialised."
exit 1
fi
- mkdir $USHER_CONFDIR $USHER_CONFD $USHER_LOGDIR
- mkdir -p $USHER_PROJECTDIR
+ mkdir "$USHER_CONFDIR" "$USHER_CONFD" "$USHER_LOGDIR"
+ mkdir -p "$USHER_PROJECTDIR"
sed -e '1,/^# -----BEGIN globalconf-----$/d' \
-e '/^# -----END globalconf-----$/,$d' \
-e "s|%MTN%|$MTN|g" \
-e "s|%USHER_LOGDIR%|$USHER_LOGDIR|g" \
-e 's/^# //' \
- < "$THIS" > $USHER_GLOBALCONF
- _mkconf
- echo >&2 Global configuration file $USHER_GLOBALCONF generated.
- echo >&2 You should probably edit it.
+ < "$THIS" > "$USHER_GLOBALCONF"
+ _maybe_set_directory_owner "$USHER_CONFDIR" "$USHER_CONFD" \
+ "$USHER_LOGDIR" "$USHER_PROJECTDIR"
+ rebuild
+ echo >&2 "Global configuration file $USHER_GLOBALCONF generated."
+ echo >&2 "You should probably edit it."
;;
+ rebuild )
+ shift
+ rebuild
+ ;;
add | mod )
op="$1"
@@ -385,6 +511,11 @@ case $1 in
;;
-p )
pattern="$2"; shift 2
+ # Because a pattern prefix can be empty, but there's
+ # no way to distinguish that from an unset value, let's
+ # use a forbidden branch character as an internal marker
+ # for the empty pattern.
+ if [ -z "$pattern" ]; then pattern=";"; fi
;;
--)
shift
@@ -394,7 +525,7 @@ case $1 in
done
name="$1"; shift
if [ -z "$name" ]; then
- echo >&2 No name given.
+ echo >&2 "No name given."
exit 1
fi
case $1 in
@@ -402,7 +533,7 @@ case $1 in
${op}srv "$name" "$host" "$pattern" "$@"
;;
* )
- echo >&2 Unknown server type $1.
+ echo >&2 "Unknown server type $1."
exit 1
;;
esac
@@ -411,7 +542,7 @@ case $1 in
shift
name="$1"; shift
if [ -z "$name" ]; then
- echo >&2 No name given.
+ echo >&2 "No name given."
exit 1
fi
delsrv "$name"
@@ -422,7 +553,7 @@ case $1 in
shift
name="$1"
if [ -z "$name" ]; then
- echo >&2 You have to give your project a name.
+ echo >&2 "You have to give your project a name."
exit 1
fi
@@ -432,19 +563,19 @@ case $1 in
shift
name="$1"
if [ -z "$name" ]; then
- echo >&2 You have to give your project a name.
+ echo >&2 "You have to give your project a name."
exit 1
fi
rmproject "$1"
;;
- start | stop | restart | reload | status )
+ start | stop | restart | reload | status | list )
$1
;;
* )
- echo >&2 Unknown command $1.
+ echo >&2 "Unknown command $1."
;;
esac
@@ -535,7 +666,12 @@ exit
# confdir='%confdir%'
# listenport='%listenport%'
# name='%name%'
+# user='%user%'
+# group='%group%'
#
+# set -e
+# cd "$confdir"
+#
# eval $mtn read 2> /dev/null
# rm -f "$confdir/write-permissions"
# touch "$confdir/write-permissions"
@@ -546,9 +682,18 @@ exit
# while read K; do
# echo $K >> "$confdir/write-permissions"
# echo " allow \"$K\"" >> "$confdir/read-permissions"
-# eval $mtn push mtn://127.0.0.1:$listenport/$name '"*"' \
-# --key-to-push $K 2> /dev/null
+# if /etc/init.c/usher status >/dev/null 2>/dev/null; then
+# eval $mtn push mtn://127.0.0.1:$listenport/$name '"*"' \
+# --key-to-push $K 2> /dev/null
+# else
+# eval $mtn push file://$confdir/database.mtn '"*"' \
+# --key-to-push $K 2> /dev/null
+# fi
# done
+# if [ -n "$user" -a -n "$group" ]; then
+# chown ${user}:${group} "$confdir/write-permissions"
+# chown ${user}:${group} "$confdir/read-permissions"
+# fi
# -----END priv:addclientkeys-----
# -----BEGIN pub:addclientkeys-----
@@ -558,6 +703,11 @@ exit
# confdir='%confdir%'
# listenport='%listenport%'
# name='%name%'
+# user='%user%'
+# group='%group%'
+#
+# set -e
+# cd "$confdir"
#
# eval $mtn read 2> /dev/null
# rm -f "$confdir/write-permissions"
@@ -566,7 +716,15 @@ exit
# eval $mtn ls keys | grep '^[0-9a-f]' | cut -f1 -d' ' | sort | uniq | \
# while read K; do
# echo $K >> "$confdir/write-permissions"
-# eval $mtn push mtn://127.0.0.1:$listenport/$name '"*"' \
-# --key-to-push $K 2> /dev/null
+# if /etc/init.c/usher status >/dev/null 2>/dev/null; then
+# eval $mtn push mtn://127.0.0.1:$listenport/$name '"*"' \
+# --key-to-push $K 2> /dev/null
+# else
+# eval $mtn push file://$confdir/database.mtn '"*"' \
+# --key-to-push $K 2> /dev/null
+# fi
# done
+# if [ -n "$user" -a -n "$group" ]; then
+# chown ${user}:${group} "$confdir/write-permissions"
+# fi
# -----END pub:addclientkeys-----
============================================================
--- /dev/null
+++ doc/usherctl.html fffd09c2ad2cb1724f7f602d5a9910c49fc896fa
@@ -0,0 +1,147 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+ <title>Usherctl Documentation</title>
+ </head>
+
+ <body>
+ <h1>Synopsis</h1>
+
+ <p><tt>usherctl [ -c <i>configfile</i> ] <i>command</i>
+ [ <i>commandoptions</i> ... ] [ <i>subcommand</i> ]
+ [ <i>args</i> ... ]</tt></p>
+
+ <h1>Description</h1>
+
+ <p><tt>usherctl</tt> is a program to control usher and manipulate
+ its configuration, as well as creating and removing entire
+ projects, through a simple command set.</p>
+
+ <p><tt>usherctl</tt> can be used to control the system usher
+ daemon, or a private daemon. The difference is that when
+ controling the system usher daemon, it will make sure that
+ everything is owned by the daemon user. This, as well as other
+ aspects of <tt>usherctl</tt>, is controlled with the
+ configuration file, either the default one or the one given with
+ <tt>-c</tt>.</p>
+
+ <p><tt>usherctl</tt> keeps track of two directory trees, one for
+ the configuration of usher, the other for the configuration and
+ data of the projects created. They are refered to as "the usher
+ configuration" and "the project configuration".</p>
+
+ <h1>Commands</h1>
+
+ <dl>
+ <dt><tt>init</tt></dt>
+ <dd>This will simply initialise the usher configuration.</dd>
+ <dt><tt>rebuild</tt></dt>
+ <dd>This will rebuild the usher configuration from the global
+ configuration file and the configuration files for each
+ project. This should be run at any time when the
+ configuration has been changed manually.</dd>
+ <dt><tt>add <i>name</i>
+ [ -h <i>hostprefix</i> ] [ -p <i>patternprefix</i> ]
+ <i>type</i> <i>args ..</i></tt></dt>
+ <dd>This adds a usher server named <tt><i>name</i></tt>, with a
+ possible host prefix or branch prefix, either of the
+ <tt>local</tt> or <tt>remote</tt> type. The rest of the
+ arguments are according to the type, please read the
+ <a href="">usher documentation</a> for
+ further information on these.</dd>
+ <dt><tt>mod <i>name</i>
+ [ -h <i>hostprefix</i> ] [ -p <i>patternprefix</i> ]
+ <i>type</i> <i>args ..</i></tt></dt>
+ <dd>Like <tt>add</tt>, but modifies an already existing usher
+ server instead of adding it.</dd>
+ <dt><tt>del <i>name</i></tt></dt>
+ <dd>Removes the usher server <tt><i>name</i></tt></dd>
+ <dt><tt>mkpubproject <i>name</i></tt></dt>
+ <dd>Creates a project set up so anyone can read from it,
+ anonymously. This also creates the usher server
+ <tt><i>name</i></tt>, of type <tt>local</tt>.</dd>
+ <dt><tt>mkprivproject <i>name</i></tt></dt>
+ <dd>Creates a project set up so only registered key owners can
+ read from it. This also creates the usher server
+ <tt><i>name</i></tt>, of type <tt>local</tt>.</dd>
+ <dt><tt>rmproject <i>name</i></tt></dt>
+ <dd>Removes the project <tt><i>name</i></tt>. This destroys
+ everything associated with that project, including the usher
+ server and server database.</dd>
+ <dt><tt>start</tt></dt>
+ <dd>Starts the usher daemon if it's not already started.</dd>
+ <dt><tt>stop</tt></dt>
+ <dd>Stops the usher daemon if it's started.</dd>
+ <dt><tt>restart</tt></dt>
+ <dd>Restarts a running usher daemon.</dd>
+ <dt><tt>reload</tt></dt>
+ <dd>Has the usher daemon reload its configuration.</dd>
+ <dt><tt>status</tt></dt>
+ <dd>Checks if the usher daemon is up or not.</dd>
+ <dt><tt>list</tt></dt>
+ <dd>Lists the configured usher servers, and says if they are a
+ project controlled by <tt>usherctl</tt>.</dd>
+ </dl>
+
+ <h1>Configuration</h1>
+
+ <p>Configuration is done with simple shell variable assignments
+ in a configuration file. The variables to be used are:</p>
+
+ <dl>
+ <dt><tt>USHER</tt></dt>
+ <dd>Usher binary.<br />
+ (default: /usr/bin/usher)</dd>
+ <dt><tt>MTN</tt></dt>
+ <dd>Monotone binary.<br />
+ (default: /usr/bin/mtn)</dd>
+ <dt><tt>USHER_CONFDIR</tt></dt>
+ <dd>Configuration directory.<br />
+ (default: /etc/usher)</dd>
+ <dt><tt>USHER_CONF</tt></dt>
+ <dd>Actual configuration file.<br />
+ (default: $USHER_CONFDIR/usher.conf)</dd>
+ <dt><tt>USHER_GLOBALCONF</tt></dt>
+ <dd>Global configuration template.<br />
+ (default: $USHER_CONFDIR/global.conf)</dd>
+ <dt><tt>USHER_CONFD</tt></dt>
+ <dd>Directory for project specific configuration files.<br />
+ (default: $USHER_CONFDIR/conf.d)</dd>
+ <dt><tt>USHER_PIDFILE</tt></dt>
+ <dd>Usher PID file.<br />
+ (default: /var/run/usher.pid)</dd>
+ <dt><tt>USHER_LOGDIR</tt></dt>
+ <dd>Usher log directory.<br />
+ (default: /var/log/usher)</dd>
+ <dt><tt>USHER_PROJECTDIR</tt></dt>
+ <dd>Usher projects directory.<br />
+ (default: /var/lib/usher/projects)</dd>
+ </dl>
+
+ <p>The following variables are only useful for the system
+ administrator that wants to set up a system wide usher:</p>
+
+ <dl>
+ <dt><tt>USHER_SYSTEM_STARTUP</tt></dt>
+ <dd>a non-empty string if usher should be started and stopped with the
+ script /etc/init.d/usher.<br />
+ (default: (unset))</dd>
+ <dt><tt>USHER_USER</tt></dt>
+ <dd>User to run usher as. Only useful if usher is started with
+ /etc/init.d/usher.<br />
+ MUST match the user usher is started as!</dd>
+ <dt><tt>USHER_GROUP</tt></dt>
+ <dd>Group to run usher as. Only useful if usher is started with
+ /etc/init.d/usher.<br />
+ MUST match the group usher is started as!</dd>
+ </dl>
+
+ <hr>
+ <address><a href="">Richard Levitte</a></address>
+<!-- Created: Wed Dec 1 09:50:50 CET 2010 -->
+<!-- hhmts start -->
+Last modified: Tue Jan 18 13:00:06 CET 2011
+<!-- hhmts end -->
+ </body>
+</html>
============================================================
--- src/channel.cc 7e6b6bbae6a84041ec840bedf5816bd6e116e5ea
+++ src/channel.cc 28d584b7185308aeab9297b3c9ceae03718a9e65
@@ -24,7 +24,7 @@ channel::channel(sock & c, server_manage
channel::channel(sock & c, server_manager &sm)
: num(++counter),
- cli(c), srv(-1),
+ cli(c),
have_routed(false), no_server(false),
manager(sm)
{
@@ -45,7 +45,7 @@ channel::~channel()
channel::~channel()
{
- if (srv && !no_server)
+ if (srv != -1 && !no_server)
manager.disconnect_from_server(srv, name);
}
============================================================
--- src/channel.hh 3a97687c17a68c983872de2792defd9e48028168
+++ src/channel.hh 21231cc383b16935ac33a349718e5aa775341c45
@@ -17,7 +17,7 @@ using boost::shared_ptr;
#include <boost/shared_ptr.hpp>
using boost::shared_ptr;
-struct server_manager;
+class server_manager;
struct channel
{
============================================================
--- src/server.hh dd153b5671f0b9560be8b817849731419e5b8fe4
+++ src/server.hh 6a57214c24d5c35c705276dcae8415dfcabf6c6e
@@ -24,7 +24,7 @@ using boost::weak_ptr;
#include <boost/weak_ptr.hpp>
using boost::weak_ptr;
-struct server_manager;
+class server_manager;
struct serverstate
{
@@ -38,8 +38,9 @@ std::ostream & operator<<(std::ostream &
};
std::ostream & operator<<(std::ostream & os, serverstate const & ss);
-struct server
+class server
{
+ friend class server_manager;
bool enabled;
bool local;
int pid;
@@ -51,6 +52,7 @@ struct server
int last_conn_time;
server_manager &manager;
weak_ptr<server> me;
+public:
server(server_manager &sm);
~server();
serverstate get_state();
============================================================
--- src/server_manager.cc 0abe47e13dd931c522aa1a7fb828502d63531a6e
+++ src/server_manager.cc f4a5b6fe2d917f24ce56c133ee347b9b3e91e50b
@@ -20,8 +20,9 @@ using std::make_pair;
#include <boost/lexical_cast.hpp>
//#include <iostream>
-serversock::serversock(sock const &o)
- : sock(o)
+serversock::serversock() : sock(-1) { }
+serversock::serversock(sock const &o, string s)
+ : sock(o), srv(s)
{
}
@@ -309,11 +310,10 @@ server_manager::connect_to_server(string
if (!srv)
throw std::logic_error("usher internal error");
sock s = srv->connect(name);
- serversock ss(s);
map<shared_ptr<server>, serverdata>::iterator i = servers.find(srv);
if (i == servers.end())
throw std::logic_error("server_manager is inconsistent");
- ss.srv = i->second.name;
+ serversock ss(s, i->second.name);
++total_connections;
if (srv->local && srv->connection_count == 1)
{
@@ -325,7 +325,7 @@ server_manager::disconnect_from_server(s
server_manager::disconnect_from_server(serversock const &s,
string const &name)
{
- map<string, shared_ptr<server> >::iterator i = by_name.find(s.srv);
+ map<string, shared_ptr<server> >::iterator i = by_name.find(s.servername());
if (i == by_name.end())
return;
i->second->disconnect(name);
============================================================
--- src/server_manager.hh fc8ad29b28f82cae3b26955995afdad8f1276a5a
+++ src/server_manager.hh 1d1f3a16329bdf11b69fb7593d048d95c65edc8d
@@ -27,11 +27,13 @@ struct serverlist_reader;
struct serverlist_reader;
-struct serversock : public sock
+class serversock : public sock
{
string srv;
- serversock(sock const &o);
- operator bool() {return !srv.empty();}
+public:
+ serversock();
+ serversock(sock const &o, string s);
+ string const & servername() const { return srv; }
};
class server_manager
============================================================
--- src/sock.hh 0917e736d673fa6d15fcefea8f1f0e16a63b9bc2
+++ src/sock.hh b077f32cc61674e13b9c3bc138c924c41b23ceb1
@@ -15,10 +15,11 @@ struct buffer;
struct buffer;
-struct sock
+class sock
{
int *s;
static std::set<int*> all_socks;
+public:
operator int();
sock(int ss);
sock(sock const & ss);
============================================================
--- README b968eb93f8b8ce88d822e9ddc52b563f1742a147
+++ README 84610efd11606729230d94fb905e5e4695328c7b
@@ -13,4 +13,4 @@
use your new subclass instead of basic_io_serverlist_reader.
The tests use 'socat', and assume the monotone in your $PATH is at least
-version 0.45.
\ No newline at end of file
+version 0.45.
============================================================
--- NEWS a9b8cb5b3dc0ec686519bbb81dc1058d30fb1099
+++ NEWS 41f6acc0681f23e164e7d8dc6be0738de13a8bf1
@@ -1,5 +1,13 @@
-Xxx Xxx 99 99:99:99 UTC 2010
+Xxx Xxx 99 99:99:99 UTC 2011
+ 1.0 release.
+
+ General
+
+ - [put stuff here]
+
+Sat Nov 06 03:04:58 UTC 2010
+
0.99 release.
General
============================================================
--- /dev/null
+++ release-checklist.txt 305136c17d554f0b16fdab39873c5814cc64691a
@@ -0,0 +1,16 @@
+* test 'make check' or 'make distcheck' on a couple different systems
+
+* look at what's changed since the last release, and make sure there are documentation
+ updates where appropriate
+
+* make sure NEWS is filled out and presentable
+
+* make sure the date at the top of NEWS is filled out
+
+* take the "~dev" out of the version in configure.in
+
+* commit; run autoreconf -i, configure, and "make distcheck" in a clean checkout
+
+* add a tag, post the tarball, and email monotone-devel
+
+* add a new blank release date at the top of NEWS, increment the version number and add "~dev"
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Monotone-commits-diffs] net.venge.monotone.contrib.usher: 200716ad68df60ea4de9b92bf20d8acd1cf20283,
code <=