source: branches/cereal/0.22/fs/usr/sbin/cereal-admin @ 1203

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

cereal/0.22: fixing maintainer addresses, updating changelog, removing set -e since it is not associated with the bug at hand.

  • 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 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##################################################
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            read -p "Really stop and destroy session? [Y|n]: " OK; OK=${OK:=Y}
243            if [ "$OK" = 'y' -o "$OK" = 'Y' ] ; then
244                if stop_session "$SESSION" ; then
245                    if destroy_session "$SESSION" ; then
246                        echo "Session '$SESSION' stopped and destroyed."
247                    else
248                        error "Session '$SESSION' could not be destroyed." 2
249                    fi
250                else
251                    error "Session '$SESSION' could not be stopped." 2
252                fi
253            else
254                error "Session '$SESSION' not stopped." 1
255            fi
256        else
257            read -p "Really destroy session '$SESSION'? [Y|n]: " OK; OK=${OK:=Y}
258            if [ "$OK" = 'y' -o "$OK" = 'Y' ] ; then
259                if destroy_session "$SESSION" ; then
260                    echo "Session '$SESSION' destroyed."
261                else
262                    error "Session '$SESSION' could not be destroyed." 2
263                fi
264            else
265                error "Session '$SESSION' not destroyed." 1
266            fi
267        fi
268    done
269}
270
271###############################################################
272### MAIN
273
274COMMAND="$1"
275[ "$COMMAND" ] || failure "Type 'cereal-admin help' for usage."
276shift
277
278case $COMMAND in
279    'create'|'c')
280        create "$@"
281        ;;
282    'start'|'s')
283        start "$@"
284        ;;
285    'restart'|'r')
286        restart "$@"
287        ;;
288    'stop'|'k')
289        stop "$@"
290        ;;
291    'destroy'|'d')
292        destroy "$@"
293        ;;
294    'list'|'l')
295        list "$@" || failure "There are no sessions." 1
296        ;;
297    'help'|'h'|'?')
298        usage
299        ;;
300    *)
301        failure "Unknown command: '$COMMAND'
302Type 'cereal-admin help' for usage."
303        ;;
304esac
305
306exit "$ERR"
Note: See TracBrowser for help on using the repository browser.