source: trunk/cereal/fs/usr/sbin/cereal-admin @ 989

Last change on this file since 989 was 989, checked in by Daniel Kahn Gillmor, 11 years ago

cereal: reclosing #24 (session startup and logging was out of order)

  • Property svn:executable set to *
File size: 8.6 KB
Line 
1#!/bin/bash
2
3# cereal-admin: manage cereal sessions (runit service directory structure
4# and runit run directory).
5#
6# The cereal scripts were written by
7# Jameson Rollins <jrollins@fifthhorseman.net>
8# and
9# Daniel Kahn Gillmor <dkg-debian.org@fifthhorseman.net>.
10#
11# They are Copyright 2007, and are all released under the GPL, version 3
12# or later.
13
14##################################################
15CMD=$(basename $0)
16
17SHAREDIR=${SHAREDIR:-"/usr/share/cereal"}
18export SHAREDIR
19source "$SHAREDIR/common"
20[ -r "$ETC/cereal-admin.conf" ] && source "$ETC/cereal-admin.conf"
21##################################################
22
23usage() {
24cat <<EOF
25Usage: $CMD <subcommand> [options] [args]
26Cereal session management program.
27
28subcommands:
29  create (c) SESSION TTY BAUD USER LOGGROUP    create cereal session
30  start (s) [options] SESSION [SESSION]...     start cereal session(s)
31    -a (--all)                                   start all sessions
32  stop (k) [options] SESSION [SESSION]...      stop cereal session(s)
33    -a (--all)                                   stop all sessions
34  restart (r) [options] SESSION [SESSION]...   restart cereal session(s)
35    -a (--all)                                   restart all sessions
36    -r (--running)                               restart only running sessions
37  destroy (d) [options] SESSION [SESSION]...   destroy cereal session(s)
38    -a (--all)                                   destroy all sessions
39  list (l) [options] [SESSION]...              list session(s)
40    -n (--names)                                 list just session names
41  help (h,?)                                   this help
42
43EOF
44}
45
46# create session
47create() {
48    if (( $# < 5 )) ; then
49        failure "Not enough input arguments.
50Type '$CMD help' for more info."
51    fi
52
53    SESSION="$1"
54    TTY="$2"
55    BAUD="$3"
56    SUSER="$4"
57    SGROUP=$(ls -l "$TTY" | awk '{ print $4 }')
58    LOGUSER='cereal'
59    LOGGROUP="$5"
60
61    is_session "$SESSION" && failure "A session named '$SESSION' already exists."
62    check_tty "$TTY"
63    check_session_tty "$TTY"
64    check_user "$SUSER"
65    check_group "$SGROUP"
66    check_user "$LOGUSER"
67    check_group "$LOGGROUP"
68    check_tty_rw "$SUSER" "$SGROUP" "$TTY"
69
70    mkdir -p "$SESSIONDIR/$SESSION"
71
72    # create run script
73    ln -s "$SHAREDIR/mainrun" "$SESSIONDIR/$SESSION/run"
74
75    # store environment variables
76    mkdir -p "$SESSIONDIR/$SESSION/env"
77    echo "$SESSION" > "$SESSIONDIR/$SESSION/env/SESSION"
78    echo "$TTY" > "$SESSIONDIR/$SESSION/env/TTY"
79    echo "$BAUD" > "$SESSIONDIR/$SESSION/env/BAUD" 
80    echo "$SUSER" > "$SESSIONDIR/$SESSION/env/USER"
81    echo "$SGROUP" > "$SESSIONDIR/$SESSION/env/GROUP"
82    echo "$LOGUSER" > "$SESSIONDIR/$SESSION/env/LOGUSER"
83    echo "$LOGGROUP" > "$SESSIONDIR/$SESSION/env/LOGGROUP"
84
85    # create logging script
86    mkdir -p -m 0750 "$SESSIONDIR/$SESSION/log/main"
87    touch "$SESSIONDIR/$SESSION/log/main/current"
88    chmod 0640 "$SESSIONDIR/$SESSION/log/main/current"
89    chown -R "$LOGUSER" "$SESSIONDIR/$SESSION/log/main"
90    chgrp -R "$LOGGROUP" "$SESSIONDIR/$SESSION/log"
91
92    # create socket for screen, since it can't log to stdout
93    mkfifo "$SESSIONDIR/$SESSION/socket"
94    chown "$SUSER:$LOGGROUP" "$SESSIONDIR/$SESSION/socket"
95    chmod 0640 "$SESSIONDIR/$SESSION/socket"
96    ln -s "$SHAREDIR/logrun" "$SESSIONDIR/$SESSION/log/run" 
97
98    echo "Created session '$SESSION':"
99    display_session "$SESSION"
100}
101
102# start_check
103start_check() {
104    is_tty_rw "$USER" "$GROUP" "$TTY"
105}
106export -f start_check
107
108# start_session SESSION
109start_session() {
110    local SESSION="$1"
111
112    if chpst -e "$SESSIONDIR/$SESSION/env/" bash -c start_check ; then
113        update-service --add "$SESSIONDIR/$SESSION" "cereal.$SESSION"
114        log_write "$SESSION" "session '$SESSION' started..."
115       
116        # make supervise directory world accessible if requested
117        if [ "$SUPERVISE_WORLD_ACCESSIBLE" = 'yes' ] ; then
118            chmod 0755 "$SESSIONDIR/$SESSION/supervise"
119            chmod 0755 "$SESSIONDIR/$SESSION/log/supervise"
120        fi
121    else
122        return 1
123    fi
124}
125export -f start_session
126
127# start session
128start() {
129    if [ -z "$1" ] ; then
130        failure "Not enough input arguments.
131Type '$CMD help' for more info."
132    elif [ "$1" = '--all' -o "$1" = '-a' ] ; then
133        SESSIONS=$(list -n) || failure "There are no sessions." 1
134    else
135        SESSIONS="$@"
136    fi
137
138    for SESSION in $SESSIONS ; do
139        if ! is_session "$SESSION" ; then
140            error "Session '$SESSION' not found." 1
141        elif update-service --check "cereal.$SESSION" ; then
142            echo "Session '$SESSION' is already running."
143        elif start_session "$SESSION" ; then
144            echo "Session '$SESSION' started."
145        else
146            error "Session '$SESSION' could not be started." 2
147        fi
148    done
149}
150
151# restart_session SESSION
152restart_session(){
153    local SESSION="$1"
154    if sv restart "cereal.$SESSION" ; then
155        log_write "$SESSION" "session '$SESSION' restarted."
156    fi
157}
158export -f restart_session
159
160# restart session
161restart() {
162    if [ -z "$1" ] ; then
163        failure "Not enough input arguments.
164Type '$CMD help' for more info."
165    elif [ "$1" = '--all' -o "$1" = '-a' ] ; then
166        SESSIONS=$(list -n) || failure "There are no sessions." 1
167    elif [ "$1" = '--running' -o "$1" = '-r' ] ; then
168        SESSIONS=$(list | grep '^+' | cut -d ' ' -f 2)
169        [ "$SESSIONS" ] || failure "There are no running sessions." 0
170    else
171        SESSIONS="$@"
172    fi
173   
174    for SESSION in $SESSIONS ; do
175        if ! is_session "$SESSION" ; then
176            error "Session '$SESSION' not found." 1
177        elif ! update-service --check "cereal.$SESSION" ; then
178            if start_session "$SESSION" ; then
179                echo "Session '$SESSION' started."
180            else
181                error "Session '$SESSION' could not be started." 2
182            fi
183        elif restart_session "$SESSION" ; then
184            echo "Session '$SESSION' restarted."
185        else
186            error "Session could not be restart." 2
187        fi
188    done
189}
190
191# stop_session SESSION
192stop_session() {
193    local SESSION="$1"
194    if sv exit "cereal.$SESSION" ; then
195        log_write "$SESSION" "stopping session '$SESSION'..."
196        update-service --remove "$SESSIONDIR/$SESSION" "cereal.$SESSION"
197    else
198        return 1
199    fi
200}
201export -f stop_session
202
203# stop session
204stop() {
205    if [ -z "$1" ] ; then
206        failure "Not enough input arguments.
207Type '$CMD help' for more info."
208    elif [ "$1" = '--all' -o "$1" = '-a' ] ; then
209        SESSIONS=$(list -n) || failure "There are no sessions." 1
210    else
211        SESSIONS="$@"
212    fi
213   
214    for SESSION in $SESSIONS ; do
215        if ! is_session "$SESSION" ; then
216            error "Session '$SESSION' not found." 1
217        elif ! update-service --check "cereal.$SESSION" ; then
218            error "Session '$SESSION' not registered." 1
219        elif stop_session "$SESSION" ; then
220            echo "Session '$SESSION' stopped."
221        else
222            error "Session '$SESSION' could not be stopped." 2
223        fi
224    done
225}
226
227# destroy_session SESSION
228destroy_session() {
229    local SESSION="$1"
230    rm -rf "$SESSIONDIR/$SESSION"
231}
232export -f destroy_session
233
234# destroy session
235destroy() {
236    if [ -z "$1" ] ; then
237        failure "Not enough input arguments.
238Type '$CMD help' for more info."
239    elif [ "$1" = '--all' -o "$1" = '-a' ] ; then
240        SESSIONS=$(list -n) || failure "There are no sessions." 1
241    else
242        SESSIONS="$@"
243    fi
244
245    for SESSION in $SESSIONS ; do
246        if ! is_session "$SESSION" ; then
247            error "Session '$SESSION' not found." 1
248        elif [ ! -w "$SESSIONDIR/$SESSION" ] ; then
249            error "You do not have permission to destroy session '$SESSION'." 2
250        elif update-service --check "cereal.$SESSION" ; then
251            echo "Session '$SESSION' is currently registered."
252            read -p "Really stop and destroy session? [Y|n]: " OK; OK=${OK:=Y}
253            if [ "${OK/y/Y}" = 'Y' ] ; then
254                if stop_session "$SESSION" ; then
255                    if destroy_session "$SESSION" ; then
256                        echo "Session '$SESSION' stopped and destroyed."
257                    else
258                        error "Session '$SESSION' could not be destroyed." 2
259                    fi
260                else
261                    error "Session '$SESSION' could not be stopped." 2
262                fi
263            else
264                error "Session '$SESSION' not stopped." 1
265            fi
266        else
267            read -p "Really destroy session '$SESSION'? [Y|n]: " OK; OK=${OK:=Y}
268            if [ "${OK/y/Y}" = 'Y' ] ; then
269                if destroy_session "$SESSION" ; then
270                    echo "Session '$SESSION' destroyed."
271                else
272                    error "Session '$SESSION' could not be destroyed." 2
273                fi
274            else
275                error "Session '$SESSION' not destroyed." 1
276            fi
277        fi
278    done
279}
280
281###############################################################
282### MAIN
283
284COMMAND="$1"
285[ "$COMMAND" ] || failure "Type '$CMD help' for usage."
286shift
287
288case $COMMAND in
289    'create'|'c')
290        create "$@"
291        ;;
292    'start'|'s')
293        start "$@"
294        ;;
295    'restart'|'r')
296        restart "$@"
297        ;;
298    'stop'|'k')
299        stop "$@"
300        ;;
301    'destroy'|'d')
302        destroy "$@"
303        ;;
304    'list'|'l')
305        list "$@" || failure "There are no sessions." 1
306        ;;
307    'help'|'h'|'?')
308        usage
309        ;;
310    *)
311        failure "Unknown command: '$COMMAND'
312Type '$CMD help' for usage."
313        ;;
314esac
315
316exit "$ERR"
Note: See TracBrowser for help on using the repository browser.