daemon-util.in 8.05 KB
Newer Older
1
2
3
#!/bin/bash
#

Michael Hanselmann's avatar
Michael Hanselmann committed
4
# Copyright (C) 2009, 2011, 2012 Google Inc.
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

set -e

23
24
25
@SHELL_ENV_INIT@

readonly defaults_file="$SYSCONFDIR/default/ganeti"
26

27
28
29
30
# This is a list of all daemons and the order in which they're started. The
# order is important as there are dependencies between them. On shutdown,
# they're stopped in reverse order.
DAEMONS=(
Petr Pudlak's avatar
Petr Pudlak committed
31
  ganeti-wconfd
32
33
34
  ganeti-noded
  ganeti-masterd
  ganeti-rapi
35
  ganeti-luxid
36
37
  )

38
39
40
41
42
43
44
# This is the list of daemons that are loaded on demand; they should only be
# stopped, not started.
ON_DEMAND_DAEMONS=(
  ganeti-metad
  ganeti-kvmd
  )

45
46
47
48
49
_confd_enabled() {
  [[ "@CUSTOM_ENABLE_CONFD@" == True ]]
}

if _confd_enabled; then
Iustin Pop's avatar
Iustin Pop committed
50
51
52
  DAEMONS+=( ganeti-confd )
fi

53
54
55
56
57
58
59
60
_mond_enabled() {
  [[ "@CUSTOM_ENABLE_MOND@" == True ]]
}

if _mond_enabled; then
  DAEMONS+=( ganeti-mond )
fi

61
62
63
# The full list of all daemons we know about
ALL_DAEMONS=( ${DAEMONS[@]} ${ON_DEMAND_DAEMONS[@]} )

64
65
66
NODED_ARGS=
MASTERD_ARGS=
CONFD_ARGS=
Petr Pudlak's avatar
Petr Pudlak committed
67
WCONFD_ARGS=
Thomas Thrainer's avatar
Thomas Thrainer committed
68
LUXID_ARGS=
69
RAPI_ARGS=
70
MOND_ARGS=
71
72
73
74
75
76

# Read defaults file if it exists
if [[ -s $defaults_file ]]; then
  . $defaults_file
fi

77
78
79
80
81
82
# Meant to facilitate use utilities in /etc/rc.d/init.d/functions in case
# start-stop-daemon is not available.
_ignore_error() {
  eval "$@" || :
}

83
_daemon_pidfile() {
84
  echo "$RUN_DIR/$1.pid"
85
86
}

87
88
89
90
_daemon_executable() {
  echo "@PREFIX@/sbin/$1"
}

91
92
93
94
95
96
_daemon_usergroup() {
  case "$1" in
    masterd)
      echo "@GNTMASTERUSER@:@GNTMASTERDGROUP@"
      ;;
    confd)
97
      echo "@GNTCONFDUSER@:@GNTCONFDGROUP@"
98
      ;;
Petr Pudlak's avatar
Petr Pudlak committed
99
100
101
    wconfd)
      echo "@GNTWCONFDUSER@:@GNTWCONFDGROUP@"
      ;;
Thomas Thrainer's avatar
Thomas Thrainer committed
102
103
    luxid)
      echo "@GNTLUXIDUSER@:@GNTLUXIDGROUP@"
104
      ;;
105
106
107
108
    rapi)
      echo "@GNTRAPIUSER@:@GNTRAPIGROUP@"
      ;;
    noded)
Michele Tartara's avatar
Michele Tartara committed
109
      echo "@GNTNODEDUSER@:@GNTNODEDGROUP@"
110
      ;;
111
112
113
    mond)
      echo "@GNTMONDUSER@:@GNTMONDGROUP@"
      ;;
114
115
116
117
118
119
    *)
      echo "root:@GNTDAEMONSGROUP@"
      ;;
  esac
}

120
121
# Checks whether the local machine is part of a cluster
check_config() {
122
  local server_pem=$DATA_DIR/server.pem
123
124
125
126
127
128
129
130
131
132
133
134
  local fname

  for fname in $server_pem; do
    if [[ ! -f $fname ]]; then
      echo "Missing configuration file $fname" >&2
      return 1
    fi
  done

  return 0
}

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# Checks the exit code of a daemon
check_exitcode() {
  if [[ "$#" -lt 1 ]]; then
    echo 'Missing exit code.' >&2
    return 1
  fi

  local rc="$1"; shift

  case "$rc" in
    0) ;;
    11)
      echo "not master"
    ;;
    *)
      echo "exit code $rc"
      return 1
    ;;
  esac

  return 0
}

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# Prints path to PID file for a daemon.
daemon_pidfile() {
  if [[ "$#" -lt 1 ]]; then
    echo 'Missing daemon name.' >&2
    return 1
  fi

  local name="$1"; shift

  _daemon_pidfile $name
}

# Prints path to daemon executable.
daemon_executable() {
  if [[ "$#" -lt 1 ]]; then
    echo 'Missing daemon name.' >&2
    return 1
  fi

  local name="$1"; shift

  _daemon_executable $name
}

182
183
184
185
186
# Prints a list of all daemons in the order in which they should be started
list_start_daemons() {
  local name

  for name in "${DAEMONS[@]}"; do
187
    echo "$name"
188
189
190
191
192
  done
}

# Prints a list of all daemons in the order in which they should be stopped
list_stop_daemons() {
193
  for name in "${ALL_DAEMONS[@]}"; do
194
195
    echo "$name"
  done | tac
196
197
198
199
200
201
202
203
204
205
206
}

# Checks whether a daemon name is known
is_daemon_name() {
  if [[ "$#" -lt 1 ]]; then
    echo 'Missing daemon name.' >&2
    return 1
  fi

  local name="$1"; shift

207
  for i in "${ALL_DAEMONS[@]}"; do
208
209
210
211
212
213
214
215
216
    if [[ "$i" == "$name" ]]; then
      return 0
    fi
  done

  echo "Unknown daemon name '$name'" >&2
  return 1
}

217
218
219
220
# Checks whether daemon is running
check() {
  if [[ "$#" -lt 1 ]]; then
    echo 'Missing daemon name.' >&2
221
    return 1
222
223
224
  fi

  local name="$1"; shift
225
226
227
228
229
230
231
232
233
234
235
  local pidfile=$(_daemon_pidfile $name)
  local daemonexec=$(_daemon_executable $name)

  if type -p start-stop-daemon >/dev/null; then
    start-stop-daemon --stop --signal 0 --quiet \
      --pidfile $pidfile
  else
    _ignore_error status \
      -p $pidfile \
      $daemonexec
  fi
236
237
238
239
240
241
}

# Starts a daemon
start() {
  if [[ "$#" -lt 1 ]]; then
    echo 'Missing daemon name.' >&2
242
    return 1
243
244
245
  fi

  local name="$1"; shift
246
247
248
  # Convert daemon name to uppercase after removing "ganeti-" prefix
  local plain_name=${name#ganeti-}
  local ucname=$(tr a-z A-Z <<<$plain_name)
249
250
251
  local pidfile=$(_daemon_pidfile $name)
  local usergroup=$(_daemon_usergroup $plain_name)
  local daemonexec=$(_daemon_executable $name)
252

253
  if [[ "$name" == ganeti-confd ]] \
254
      && ! _confd_enabled; then
Iustin Pop's avatar
Iustin Pop committed
255
256
257
258
    echo 'ganeti-confd disabled at build time' >&2
    return 1
  fi

259
  # Read $<daemon>_ARGS and $EXTRA_<daemon>_ARGS
260
  eval local args="\"\$${ucname}_ARGS \$EXTRA_${ucname}_ARGS\""
261

262
263
  @PKGLIBDIR@/ensure-dirs

264
265
266
267
268
269
270
271
272
273
274
275
276
277
  if type -p start-stop-daemon >/dev/null; then
    start-stop-daemon --start --quiet --oknodo \
      --pidfile $pidfile \
      --startas $daemonexec \
      --chuid $usergroup \
      -- $args "$@"
  else
    # TODO: Find a way to start daemon with a group, until then the group must
    # be removed
    _ignore_error daemon \
      --pidfile $pidfile \
      --user ${usergroup%:*} \
      $daemonexec $args "$@"
  fi
278

279
280
281
282
283
284
}

# Stops a daemon
stop() {
  if [[ "$#" -lt 1 ]]; then
    echo 'Missing daemon name.' >&2
285
    return 1
286
287
288
  fi

  local name="$1"; shift
289
  local pidfile=$(_daemon_pidfile $name)
290

291
292
293
294
295
296
  if type -p start-stop-daemon >/dev/null; then
    start-stop-daemon --stop --quiet --oknodo --retry 30 \
      --pidfile $pidfile
  else
    _ignore_error killproc -p $pidfile $name
  fi
297
298
299
300
301
302
303
304
305
306
307
308
309
}

# Starts a daemon if it's not yet running
check_and_start() {
  local name="$1"

  if ! check $name; then
    start $name
  fi
}

# Starts the master role
start_master() {
310
  start ganeti-wconfd
311
312
  start ganeti-masterd
  start ganeti-rapi
313
  start ganeti-luxid
314
315
316
317
}

# Stops the master role
stop_master() {
318
  stop ganeti-luxid
319
320
  stop ganeti-rapi
  stop ganeti-masterd
321
  stop ganeti-wconfd
322
323
}

324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
# Start all daemons
start_all() {
  for i in $(list_start_daemons); do
    local rc=0

    # Try to start daemon
    start $i || rc=$?

    if ! errmsg=$(check_exitcode $rc); then
      echo "$errmsg" >&2
      return 1
    fi
  done

  return 0
}

# Stop all daemons
stop_all() {
  for i in $(list_stop_daemons); do
    stop $i
  done
}

348
349
350
351
352
353
354
355
356
357
358
359
360
# SIGHUP a process to force re-opening its logfiles
rotate_logs() {
  if [[ "$#" -lt 1 ]]; then
    echo 'Missing daemon name.' >&2
    return 1
  fi

  local name="$1"; shift
  local pidfile=$(_daemon_pidfile $name)
  local daemonexec=$(_daemon_executable $name)

  if type -p start-stop-daemon >/dev/null; then
    start-stop-daemon --stop --signal HUP --quiet \
361
      --oknodo --pidfile $pidfile
362
363
364
365
366
367
368
369
370
371
372
373
374
375
  else
    _ignore_error killproc \
      -p $pidfile \
      $daemonexec -HUP
  fi
}

# SIGHUP all processes
rotate_all_logs() {
  for i in $(list_stop_daemons); do
    rotate_logs $i
  done
}

376
377
378
379
380
# Reloads the SSH keys
reload_ssh_keys() {
  @RPL_SSH_INITD_SCRIPT@ restart
}

381
382
383
384
385
386
# Read @SYSCONFDIR@/rc.d/init.d/functions if start-stop-daemon not available
if ! type -p start-stop-daemon >/dev/null && \
   [[ -f @SYSCONFDIR@/rc.d/init.d/functions ]]; then
  _ignore_error . @SYSCONFDIR@/rc.d/init.d/functions
fi

387
388
389
390
391
392
393
if [[ "$#" -lt 1 ]]; then
  echo "Usage: $0 <action>" >&2
  exit 1
fi

orig_action=$1; shift

394
395
396
397
398
if [[ "$orig_action" == *_* ]]; then
  echo "Command must not contain underscores" >&2
  exit 1
fi

399
400
401
402
403
404
405
406
407
408
409
# Replace all dashes (-) with underlines (_)
action=${orig_action//-/_}

# Is it a known function?
if ! declare -F "$action" >/dev/null 2>&1; then
  echo "Unknown command: $orig_action" >&2
  exit 1
fi

# Call handler function
$action "$@"