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

Last change on this file since 651 was 651, checked in by jrollins, 6 years ago

cereal: a bunch of clean up/simplification of error handling and list
function. added notes on log limits

  • Property svn:executable set to *
File size: 8.3 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) [SESSION]...                        list session(s)
40  help (h,?)                                   this help
41
42EOF
43}
44
45# create session
46create() {
47    if (( $# < 5 )) ; then
48        failure "Not enough input arguments.
49Type '$CMD help' for more info."
50    fi
51
52    SESSION="$1"
53    TTY="$2"
54    BAUD="$3"
55    SUSER="$4"
56    SGROUP=$(ls -l "$TTY" | awk '{ print $4 }')
57    LOGUSER='cereal'
58    LOGGROUP="$5"
59
60    is_session "$SESSION" && failure "A session named '$SESSION' already exists."
61    check_is_tty "$TTY"
62    check_is_session_tty "$TTY"
63    check_user "$SUSER"
64    check_group "$SGROUP"
65    check_user "$LOGUSER"
66    check_group "$LOGGROUP"
67    check_tty_rw "$SUSER" "$SGROUP" "$TTY"
68
69    mkdir -p "$SESSIONDIR/$SESSION"
70
71    # create run script
72    ln -s "$SHAREDIR/mainrun" "$SESSIONDIR/$SESSION/run"
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 script
85    mkdir -p -m 0750 "$SESSIONDIR/$SESSION/log/main"
86    touch "$SESSIONDIR/$SESSION/log/main/current"
87    chmod 0640 "$SESSIONDIR/$SESSION/log/main/current"
88    chown -R "$LOGUSER" "$SESSIONDIR/$SESSION/log/main"
89    chgrp -R "$LOGGROUP" "$SESSIONDIR/$SESSION/log"
90
91    # create socket for screen, since it can't log to stdout
92    mkfifo "$SESSIONDIR/$SESSION/socket"
93    chown "$SUSER:$LOGGROUP" "$SESSIONDIR/$SESSION/socket"
94    chmod 0640 "$SESSIONDIR/$SESSION/socket"
95    ln -s "$SHAREDIR/logrun" "$SESSIONDIR/$SESSION/log/run" 
96
97    # make supervise directory world accessible if requested
98    if [ "$SUPERVISE_WORLD_ACCESSIBLE" = 'yes' ] ; then
99        mkdir -p -m 0755 "$SESSIONDIR/$SESSION/supervise"
100    fi
101
102    echo "Created session '$SESSION':"
103    display_session "$SESSION"
104}
105
106# start_check
107start_check() {
108    chpst -u "$USER:$GROUP" bash -c "test -r $TTY && test -w $TTY"
109}
110export -f start_check
111
112# start_session SESSION
113start_session() {
114    local SESSION="$1"
115    ln -s "$SESSIONDIR/$SESSION" "$SERVICE.$SESSION"
116    log_write "$SESSION" "session '$SESSION' started."
117}
118export -f start_session
119
120# start session
121start() {
122    if [ -z "$1" ] ; then
123        failure "Not enough input arguments.
124Type '$CMD help' for more info."
125    elif [ "$1" = '--all' -o "$1" = '-a' ] ; then
126        SESSIONS=$(list) || 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_linked "$SESSION" ; then
135            error "Session '$SESSION' is already running." 1
136        elif ! chpst -e "$SESSIONDIR/$SESSION/env/" sh -c start_check ; then
137            error "Session '$SESSION' not properly configured, or you do not have permission to start session." 2
138        else
139            if start_session "$SESSION" ; then
140                echo "Started session '$SESSION'."
141            else
142                error "Session '$SESSION' could not be started." 2
143            fi
144        fi
145    done
146}
147
148# stop_session SESSION
149stop_session() {
150    local SESSION="$1"
151    log_write "$SESSION" "stopping session '$SESSION'..."
152    sv exit "$SERVICE.$SESSION"
153    rm "$SERVICE.$SESSION"
154}
155export -f stop_session
156
157# stop session
158stop() {
159    if [ -z "$1" ] ; then
160        failure "Not enough input arguments.
161Type '$CMD help' for more info."
162    elif [ "$1" = '--all' -o "$1" = '-a' ] ; then
163        SESSIONS=$(list) || failure "There are no sessions." 1
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_linked "$SESSION" ; then
172            error "Session '$SESSION' not linked." 1
173        else
174            if stop_session "$SESSION" ; then
175                echo "Stopped session '$SESSION'."
176            else
177                error "Session '$SESSION' could not be stopped." 2
178            fi
179        fi
180    done
181}
182
183# restart_session SESSION
184restart_session() {
185    local SESSION="$1"
186    log_write "$SESSION" "restarting session '$SESSION'..."
187    sv restart "$SERVICE.$SESSION"
188}
189export -f restart_session
190
191# restart session
192restart() {
193    if [ -z "$1" ] ; then
194        failure "Not enough input arguments.
195Type '$CMD help' for more info."
196    elif [ "$1" = '--all' -o "$1" = '-a' ] ; then
197        SESSIONS=$(list) || failure "There are no sessions." 1
198    elif [ "$1" = '--running' -o "$1" = '-r' ] ; then
199        SESSIONS=$(list -d | grep '^+' | cut -d ' ' -f 2)
200        [ "$SESSIONS" ] || failure "There are no running sessions." 0
201    else
202        SESSIONS="$@"
203    fi
204   
205    for SESSION in $SESSIONS ; do
206        if ! is_session "$SESSION" ; then
207            echo "Session '$SESSION' not found."
208            continue
209        elif ! is_linked "$SESSION" ; then
210            start "$SESSION"
211        else
212            if restart_session "$SESSION" ; then
213                echo "Restarted session '$SESSION'."
214            else
215                error "Session '$SESSION' could not be restarted." 2
216            fi
217        fi
218    done
219}
220
221# destroy_session SESSION
222destroy_session() {
223    rm -rf "$SESSIONDIR/$1"
224}
225export -f destroy_session
226
227# destroy session
228destroy() {
229    if [ -z "$1" ] ; then
230        failure "Not enough input arguments.
231Type '$CMD help' for more info."
232    elif [ "$1" = '--all' -o "$1" = '-a' ] ; then
233        SESSIONS=$(list) || failure "There are no sessions." 1
234    else
235        SESSIONS="$@"
236    fi
237
238    for SESSION in $SESSIONS ; do
239        if ! is_session "$SESSION" ; then
240            error "Session '$SESSION' not found." 1
241        elif [ ! -w "$SESSIONDIR/$SESSION" ] ; then
242            error "You do not have permission to destroy session '$SESSION'." 2
243        elif is_linked "$SESSION" ; then
244            echo "Session '$SESSION' is currently linked."
245            read -p "Really stop and destroy session? [Y|n]: " OK
246            if [ -z "$OK" -o "${OK/y/Y}" = 'Y' ] ; then
247                if stop_session "$SESSION" ; then
248                    if destroy_session "$SESSION" ; then
249                        echo "Stopped and destroyed session '$SESSION'."
250                    else
251                        error "Session '$SESSION' could not be destroyed." 2
252                    fi
253                else
254                    error "Session '$SESSION' could not be stopped." 2
255                fi
256            else
257                error "Session '$SESSION' not stopped." 1
258            fi
259        else
260            read -p "Really destroy session '$SESSION'? [Y|n]: " OK
261            if [ -z "$OK" -o "${OK/y/Y}" = 'Y' ] ; then
262                if destroy_session "$SESSION" ; then
263                    echo "Destroyed session '$SESSION'."
264                else
265                    error "Session '$SESSION' could not be destroyed." 2
266                fi
267            else
268                error "Session '$SESSION' not destroyed." 1
269            fi
270        fi
271    done
272}
273
274###############################################################
275### MAIN
276
277COMMAND="$1"
278[ "$COMMAND" ] || failure "Type '$CMD help' for usage."
279shift
280
281case $COMMAND in
282    'create'|'c')
283        create "$@"
284        ;;
285    'start'|'s')
286        start "$@"
287        ;;
288    'restart'|'r')
289        restart "$@"
290        ;;
291    'stop'|'k')
292        stop "$@"
293        ;;
294    'destroy'|'d')
295        destroy "$@"
296        ;;
297    'list'|'l')
298        list -d "$@" || failure "There are no sessions." 1
299        ;;
300    'help'|'h'|'?')
301        usage
302        ;;
303    *)
304        failure "Unknown command: '$COMMAND'
305Type '$CMD help' for usage."
306        ;;
307esac
308
309exit "$ERR"
Note: See TracBrowser for help on using the repository browser.