Set the correct group for confd
[ganeti-local] / daemons / daemon-util.in
1 #!/bin/bash
2 #
3
4 # Copyright (C) 2009, 2011, 2012 Google Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA.
20
21 set -e
22
23 @SHELL_ENV_INIT@
24
25 readonly defaults_file="$SYSCONFDIR/default/ganeti"
26
27 # This is a list of all daemons and the order in which they're started. The
28 # order is important as there are dependencies between them. On shutdown,
29 # they're stopped in reverse order.
30 DAEMONS=(
31   ganeti-noded
32   ganeti-masterd
33   ganeti-rapi
34   )
35
36 _confd_enabled() {
37   [[ "@CUSTOM_ENABLE_CONFD@" == True ]]
38 }
39
40 if _confd_enabled; then
41   DAEMONS+=( ganeti-confd )
42 fi
43
44 _mond_enabled() {
45   [[ "@CUSTOM_ENABLE_MOND@" == True ]]
46 }
47
48 if _mond_enabled; then
49   DAEMONS+=( ganeti-mond )
50 fi
51
52 NODED_ARGS=
53 MASTERD_ARGS=
54 CONFD_ARGS=
55 RAPI_ARGS=
56 MOND_ARGS=
57
58 # Read defaults file if it exists
59 if [[ -s $defaults_file ]]; then
60   . $defaults_file
61 fi
62
63 # Meant to facilitate use utilities in /etc/rc.d/init.d/functions in case
64 # start-stop-daemon is not available.
65 _ignore_error() {
66   eval "$@" || :
67 }
68
69 _daemon_pidfile() {
70   echo "$RUN_DIR/$1.pid"
71 }
72
73 _daemon_executable() {
74   echo "@PREFIX@/sbin/$1"
75 }
76
77 _daemon_usergroup() {
78   case "$1" in
79     masterd)
80       echo "@GNTMASTERUSER@:@GNTMASTERDGROUP@"
81       ;;
82     confd)
83       echo "@GNTCONFDUSER@:@GNTDAEMONSGROUP@"
84       ;;
85     rapi)
86       echo "@GNTRAPIUSER@:@GNTRAPIGROUP@"
87       ;;
88     noded)
89       echo "@GNTNODEDUSER@:@GNTDAEMONSGROUP@"
90       ;;
91     mond)
92       echo "@GNTMONDUSER@:@GNTMONDGROUP@"
93       ;;
94     *)
95       echo "root:@GNTDAEMONSGROUP@"
96       ;;
97   esac
98 }
99
100 # Checks whether the local machine is part of a cluster
101 check_config() {
102   local server_pem=$DATA_DIR/server.pem
103   local fname
104
105   for fname in $server_pem; do
106     if [[ ! -f $fname ]]; then
107       echo "Missing configuration file $fname" >&2
108       return 1
109     fi
110   done
111
112   return 0
113 }
114
115 # Checks the exit code of a daemon
116 check_exitcode() {
117   if [[ "$#" -lt 1 ]]; then
118     echo 'Missing exit code.' >&2
119     return 1
120   fi
121
122   local rc="$1"; shift
123
124   case "$rc" in
125     0) ;;
126     11)
127       echo "not master"
128     ;;
129     *)
130       echo "exit code $rc"
131       return 1
132     ;;
133   esac
134
135   return 0
136 }
137
138 # Prints path to PID file for a daemon.
139 daemon_pidfile() {
140   if [[ "$#" -lt 1 ]]; then
141     echo 'Missing daemon name.' >&2
142     return 1
143   fi
144
145   local name="$1"; shift
146
147   _daemon_pidfile $name
148 }
149
150 # Prints path to daemon executable.
151 daemon_executable() {
152   if [[ "$#" -lt 1 ]]; then
153     echo 'Missing daemon name.' >&2
154     return 1
155   fi
156
157   local name="$1"; shift
158
159   _daemon_executable $name
160 }
161
162 # Prints a list of all daemons in the order in which they should be started
163 list_start_daemons() {
164   local name
165
166   for name in "${DAEMONS[@]}"; do
167     echo "$name"
168   done
169 }
170
171 # Prints a list of all daemons in the order in which they should be stopped
172 list_stop_daemons() {
173   list_start_daemons | tac
174 }
175
176 # Checks whether a daemon name is known
177 is_daemon_name() {
178   if [[ "$#" -lt 1 ]]; then
179     echo 'Missing daemon name.' >&2
180     return 1
181   fi
182
183   local name="$1"; shift
184
185   for i in "${DAEMONS[@]}"; do
186     if [[ "$i" == "$name" ]]; then
187       return 0
188     fi
189   done
190
191   echo "Unknown daemon name '$name'" >&2
192   return 1
193 }
194
195 # Checks whether daemon is running
196 check() {
197   if [[ "$#" -lt 1 ]]; then
198     echo 'Missing daemon name.' >&2
199     return 1
200   fi
201
202   local name="$1"; shift
203   local pidfile=$(_daemon_pidfile $name)
204   local daemonexec=$(_daemon_executable $name)
205
206   if type -p start-stop-daemon >/dev/null; then
207     start-stop-daemon --stop --signal 0 --quiet \
208       --pidfile $pidfile
209   else
210     _ignore_error status \
211       -p $pidfile \
212       $daemonexec
213   fi
214 }
215
216 # Starts a daemon
217 start() {
218   if [[ "$#" -lt 1 ]]; then
219     echo 'Missing daemon name.' >&2
220     return 1
221   fi
222
223   local name="$1"; shift
224   # Convert daemon name to uppercase after removing "ganeti-" prefix
225   local plain_name=${name#ganeti-}
226   local ucname=$(tr a-z A-Z <<<$plain_name)
227   local pidfile=$(_daemon_pidfile $name)
228   local usergroup=$(_daemon_usergroup $plain_name)
229   local daemonexec=$(_daemon_executable $name)
230
231   if [[ "$name" == ganeti-confd ]] && ! _confd_enabled; then
232     echo 'ganeti-confd disabled at build time' >&2
233     return 1
234   fi
235
236   # Read $<daemon>_ARGS and $EXTRA_<daemon>_ARGS
237   eval local args="\"\$${ucname}_ARGS \$EXTRA_${ucname}_ARGS\""
238
239   @PKGLIBDIR@/ensure-dirs
240
241   if type -p start-stop-daemon >/dev/null; then
242     start-stop-daemon --start --quiet --oknodo \
243       --pidfile $pidfile \
244       --startas $daemonexec \
245       --chuid $usergroup \
246       -- $args "$@"
247   else
248     # TODO: Find a way to start daemon with a group, until then the group must
249     # be removed
250     _ignore_error daemon \
251       --pidfile $pidfile \
252       --user ${usergroup%:*} \
253       $daemonexec $args "$@"
254   fi
255
256 }
257
258 # Stops a daemon
259 stop() {
260   if [[ "$#" -lt 1 ]]; then
261     echo 'Missing daemon name.' >&2
262     return 1
263   fi
264
265   local name="$1"; shift
266   local pidfile=$(_daemon_pidfile $name)
267
268   if type -p start-stop-daemon >/dev/null; then
269     start-stop-daemon --stop --quiet --oknodo --retry 30 \
270       --pidfile $pidfile
271   else
272     _ignore_error killproc -p $pidfile $name
273   fi
274 }
275
276 # Starts a daemon if it's not yet running
277 check_and_start() {
278   local name="$1"
279
280   if ! check $name; then
281     start $name
282   fi
283 }
284
285 # Starts the master role
286 start_master() {
287   start ganeti-masterd
288   start ganeti-rapi
289 }
290
291 # Stops the master role
292 stop_master() {
293   stop ganeti-rapi
294   stop ganeti-masterd
295 }
296
297 # Start all daemons
298 start_all() {
299   for i in $(list_start_daemons); do
300     local rc=0
301
302     # Try to start daemon
303     start $i || rc=$?
304
305     if ! errmsg=$(check_exitcode $rc); then
306       echo "$errmsg" >&2
307       return 1
308     fi
309   done
310
311   return 0
312 }
313
314 # Stop all daemons
315 stop_all() {
316   for i in $(list_stop_daemons); do
317     stop $i
318   done
319 }
320
321 # Reloads the SSH keys
322 reload_ssh_keys() {
323   @RPL_SSH_INITD_SCRIPT@ restart
324 }
325
326 # Read @SYSCONFDIR@/rc.d/init.d/functions if start-stop-daemon not available
327 if ! type -p start-stop-daemon >/dev/null && \
328    [[ -f @SYSCONFDIR@/rc.d/init.d/functions ]]; then
329   _ignore_error . @SYSCONFDIR@/rc.d/init.d/functions
330 fi
331
332 if [[ "$#" -lt 1 ]]; then
333   echo "Usage: $0 <action>" >&2
334   exit 1
335 fi
336
337 orig_action=$1; shift
338
339 if [[ "$orig_action" == *_* ]]; then
340   echo "Command must not contain underscores" >&2
341   exit 1
342 fi
343
344 # Replace all dashes (-) with underlines (_)
345 action=${orig_action//-/_}
346
347 # Is it a known function?
348 if ! declare -F "$action" >/dev/null 2>&1; then
349   echo "Unknown command: $orig_action" >&2
350   exit 1
351 fi
352
353 # Call handler function
354 $action "$@"