source: trunk/cereal/src/cereal-admin @ 1190

Last change on this file since 1190 was 1190, checked in by jrollins, 10 years ago

fixed some lingering bashism that were causing things to fail with
dash/sh.

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