]> rtime.felk.cvut.cz Git - novaboot.git/blob - server/novaboot-server
d406ac58ea55665e757b56c078433d28ad671e23
[novaboot.git] / server / novaboot-server
1 #!/bin/sh
2
3 set -e
4
5 die() {
6     echo >&2 "$*"
7     exit 1
8 }
9
10 print_help() {
11     cat <<EOF
12 Target commands:
13 - console
14 - reset
15 - on
16 - off
17 - rsync ...
18
19 Management commands:
20 - add-key
21 - help
22 EOF
23     exit 0
24 }
25
26 add_key() {
27     local user
28
29     user="$1"
30     die "Not implemented"
31 }
32
33 lock_queue() {
34     lslocks | awk '{ if ($9 == "'"$RUN_DIR"'") { print $2 } }'
35 }
36
37 print_queue() {
38     local queue
39
40     queue=$(
41         for pid in $(lock_queue); do
42             echo $pid $(sed --null-data -ne '/^NOVABOOT_ID=/ s///p' /proc/$pid/environ)
43         done | sort)
44     if [ "$queue" ]; then
45         echo "Target is occupied by:"
46         ( echo "PID USER LOGIN_TIME FROM"; echo "$queue" ) | column -t
47     fi
48 }
49
50 locked() {
51     print_queue
52     exec flock --no-fork "$RUN_DIR" "$@"
53 }
54
55 unlocked() {
56     exec "$@"
57 }
58
59 check_var() {
60     if eval [ "\"\$$1\"" ]; then
61         return 0
62     else
63         die "$1 variable not defined in $CFG"
64     fi
65 }
66
67 # run_subcommand should be called only after permission checks and/or locking
68 run_subcommand() {
69     case "$*" in
70         "console")
71             trap "rm -f $RUN_DIR/ppid" EXIT
72             echo $NOVABOOT_PPID > $RUN_DIR/ppid
73             echo 'novaboot-server: Connected'
74             $target_reset_begin
75             check_var target_console && eval exec $target_console;;
76         "reset")
77             check_var target_reset && eval exec $target_reset;;
78         "rsync --server "*" . .")
79             if [ $# -ne 5 ]; then die "Unexpected rsync invocation: $*"; fi
80             mkdir -p "$HOME/tftproot"
81             cd "$HOME/tftproot"
82             exec rsync --server $3 . . ;;
83         "on")
84             check_var target_on && eval exec $target_on;;
85         "off")
86             check_var target_off && eval exec $target_off;;
87         *)
88             echo >&2 "novaboot-server: Command not allowed: $*"
89             logger -p error "novaboot-server: Command not allowed: $*"
90             exit 1;;
91     esac
92 }
93
94 main() {
95     if [ "$1" = "-c" ]; then shift
96     else die "Permission denied"; fi
97
98     if [ "${1%% *}" = "user" ]; then
99         # Get user name encoded in ~/.ssh/authorized_keys
100         set -- $1
101         NB_USER="$2";
102         set -- $SSH_ORIGINAL_COMMAND
103     fi
104
105     if [ $# -eq 0 ]; then print_help; fi
106
107     IP=${SSH_CONNECTION%% *}
108     HOST=$(getent hosts $IP) || HOST=$IP
109     REMOTE=${HOST##* }
110     DATE=$(LANG=C date +'%F_%T')
111     export NOVABOOT_ID="${NB_USER:-?} $DATE ${REMOTE}"
112     export NOVABOOT_PPID=$PPID
113
114     mkdir -p "$RUN_DIR"
115
116     # Commands allowed at any time
117     case "$1" in
118         "console") locked $0 console;;
119         "add-key") shift; add_key "$@"; exit $?;;
120         "help") print_help;;
121     esac
122
123
124     # Commands allowed only when nobody or the same user is connected to the console
125     ALLOWED_PPID=$(cat $RUN_DIR/ppid 2>/dev/null || :)
126     if [ "$PPID" -eq "${ALLOWED_PPID:-0}" ]; then run=unlocked; else run=locked; fi
127     $run $0 "$@"
128 }
129
130 RUN_DIR="$XDG_RUNTIME_DIR/novaboot"
131
132 if [ -z "$NOVABOOT_ID" ]; then
133     main "$@"
134 else
135     if [ "$NOVABOOT_SERVER_CONFIG" ]; then
136         CFG="$NOVABOOT_SERVER_CONFIG"
137     else
138         CFG="$HOME/.novaboot-server"
139     fi
140
141     . "$CFG"
142
143     run_subcommand "$@"
144 fi