Revision c06e0c83 lib/backend.py
b/lib/backend.py | ||
---|---|---|
246 | 246 |
return (master_netdev, master_ip, master_node, primary_ip_family) |
247 | 247 |
|
248 | 248 |
|
249 |
def StartMaster(start_daemons, no_voting): |
|
249 |
def ActivateMasterIp(): |
|
250 |
"""Activate the IP address of the master daemon. |
|
251 |
|
|
252 |
""" |
|
253 |
# GetMasterInfo will raise an exception if not able to return data |
|
254 |
master_netdev, master_ip, _, family = GetMasterInfo() |
|
255 |
|
|
256 |
err_msg = None |
|
257 |
if netutils.TcpPing(master_ip, constants.DEFAULT_NODED_PORT): |
|
258 |
if netutils.IPAddress.Own(master_ip): |
|
259 |
# we already have the ip: |
|
260 |
logging.debug("Master IP already configured, doing nothing") |
|
261 |
else: |
|
262 |
err_msg = "Someone else has the master ip, not activating" |
|
263 |
logging.error(err_msg) |
|
264 |
else: |
|
265 |
ipcls = netutils.IP4Address |
|
266 |
if family == netutils.IP6Address.family: |
|
267 |
ipcls = netutils.IP6Address |
|
268 |
|
|
269 |
result = utils.RunCmd([constants.IP_COMMAND_PATH, "address", "add", |
|
270 |
"%s/%d" % (master_ip, ipcls.iplen), |
|
271 |
"dev", master_netdev, "label", |
|
272 |
"%s:0" % master_netdev]) |
|
273 |
if result.failed: |
|
274 |
err_msg = "Can't activate master IP: %s" % result.output |
|
275 |
logging.error(err_msg) |
|
276 |
|
|
277 |
# we ignore the exit code of the following cmds |
|
278 |
if ipcls == netutils.IP4Address: |
|
279 |
utils.RunCmd(["arping", "-q", "-U", "-c 3", "-I", master_netdev, "-s", |
|
280 |
master_ip, master_ip]) |
|
281 |
elif ipcls == netutils.IP6Address: |
|
282 |
try: |
|
283 |
utils.RunCmd(["ndisc6", "-q", "-r 3", master_ip, master_netdev]) |
|
284 |
except errors.OpExecError: |
|
285 |
# TODO: Better error reporting |
|
286 |
logging.warning("Can't execute ndisc6, please install if missing") |
|
287 |
|
|
288 |
if err_msg: |
|
289 |
_Fail(err_msg) |
|
290 |
|
|
291 |
|
|
292 |
def StartMasterDaemons(no_voting): |
|
250 | 293 |
"""Activate local node as master node. |
251 | 294 |
|
252 |
The function will either try activate the IP address of the master |
|
253 |
(unless someone else has it) or also start the master daemons, based |
|
254 |
on the start_daemons parameter. |
|
295 |
The function will start the master daemons (ganeti-masterd and ganeti-rapi). |
|
255 | 296 |
|
256 |
@type start_daemons: boolean |
|
257 |
@param start_daemons: whether to start the master daemons |
|
258 |
(ganeti-masterd and ganeti-rapi), or (if false) activate the |
|
259 |
master ip |
|
260 | 297 |
@type no_voting: boolean |
261 | 298 |
@param no_voting: whether to start ganeti-masterd without a node vote |
262 |
(if start_daemons is True), but still non-interactively
|
|
299 |
but still non-interactively |
|
263 | 300 |
@rtype: None |
264 | 301 |
|
265 | 302 |
""" |
266 |
# GetMasterInfo will raise an exception if not able to return data |
|
267 |
master_netdev, master_ip, _, family = GetMasterInfo() |
|
268 | 303 |
|
269 |
err_msgs = [] |
|
270 |
# either start the master and rapi daemons |
|
271 |
if start_daemons: |
|
272 |
if no_voting: |
|
273 |
masterd_args = "--no-voting --yes-do-it" |
|
274 |
else: |
|
275 |
masterd_args = "" |
|
276 |
|
|
277 |
env = { |
|
278 |
"EXTRA_MASTERD_ARGS": masterd_args, |
|
279 |
} |
|
280 |
|
|
281 |
result = utils.RunCmd([constants.DAEMON_UTIL, "start-master"], env=env) |
|
282 |
if result.failed: |
|
283 |
msg = "Can't start Ganeti master: %s" % result.output |
|
284 |
logging.error(msg) |
|
285 |
err_msgs.append(msg) |
|
286 |
# or activate the IP |
|
304 |
if no_voting: |
|
305 |
masterd_args = "--no-voting --yes-do-it" |
|
287 | 306 |
else: |
288 |
if netutils.TcpPing(master_ip, constants.DEFAULT_NODED_PORT): |
|
289 |
if netutils.IPAddress.Own(master_ip): |
|
290 |
# we already have the ip: |
|
291 |
logging.debug("Master IP already configured, doing nothing") |
|
292 |
else: |
|
293 |
msg = "Someone else has the master ip, not activating" |
|
294 |
logging.error(msg) |
|
295 |
err_msgs.append(msg) |
|
296 |
else: |
|
297 |
ipcls = netutils.IP4Address |
|
298 |
if family == netutils.IP6Address.family: |
|
299 |
ipcls = netutils.IP6Address |
|
300 |
|
|
301 |
result = utils.RunCmd([constants.IP_COMMAND_PATH, "address", "add", |
|
302 |
"%s/%d" % (master_ip, ipcls.iplen), |
|
303 |
"dev", master_netdev, "label", |
|
304 |
"%s:0" % master_netdev]) |
|
305 |
if result.failed: |
|
306 |
msg = "Can't activate master IP: %s" % result.output |
|
307 |
logging.error(msg) |
|
308 |
err_msgs.append(msg) |
|
309 |
|
|
310 |
# we ignore the exit code of the following cmds |
|
311 |
if ipcls == netutils.IP4Address: |
|
312 |
utils.RunCmd(["arping", "-q", "-U", "-c 3", "-I", master_netdev, "-s", |
|
313 |
master_ip, master_ip]) |
|
314 |
elif ipcls == netutils.IP6Address: |
|
315 |
try: |
|
316 |
utils.RunCmd(["ndisc6", "-q", "-r 3", master_ip, master_netdev]) |
|
317 |
except errors.OpExecError: |
|
318 |
# TODO: Better error reporting |
|
319 |
logging.warning("Can't execute ndisc6, please install if missing") |
|
320 |
|
|
321 |
if err_msgs: |
|
322 |
_Fail("; ".join(err_msgs)) |
|
307 |
masterd_args = "" |
|
323 | 308 |
|
309 |
env = { |
|
310 |
"EXTRA_MASTERD_ARGS": masterd_args, |
|
311 |
} |
|
324 | 312 |
|
325 |
def StopMaster(stop_daemons): |
|
326 |
"""Deactivate this node as master. |
|
313 |
result = utils.RunCmd([constants.DAEMON_UTIL, "start-master"], env=env) |
|
314 |
if result.failed: |
|
315 |
msg = "Can't start Ganeti master: %s" % result.output |
|
316 |
logging.error(msg) |
|
317 |
_Fail(msg) |
|
327 | 318 |
|
328 |
The function will always try to deactivate the IP address of the |
|
329 |
master. It will also stop the master daemons depending on the |
|
330 |
stop_daemons parameter. |
|
331 | 319 |
|
332 |
@type stop_daemons: boolean |
|
333 |
@param stop_daemons: whether to also stop the master daemons |
|
334 |
(ganeti-masterd and ganeti-rapi) |
|
335 |
@rtype: None |
|
320 |
def DeactivateMasterIp(): |
|
321 |
"""Deactivate the master IP on this node. |
|
336 | 322 |
|
337 | 323 |
""" |
338 | 324 |
# TODO: log and report back to the caller the error failures; we |
... | ... | |
352 | 338 |
logging.error("Can't remove the master IP, error: %s", result.output) |
353 | 339 |
# but otherwise ignore the failure |
354 | 340 |
|
355 |
if stop_daemons: |
|
356 |
result = utils.RunCmd([constants.DAEMON_UTIL, "stop-master"]) |
|
357 |
if result.failed: |
|
358 |
logging.error("Could not stop Ganeti master, command %s had exitcode %s" |
|
359 |
" and error %s", |
|
360 |
result.cmd, result.exit_code, result.output) |
|
341 |
|
|
342 |
def StopMasterDaemons(): |
|
343 |
"""Stop the master daemons on this node. |
|
344 |
|
|
345 |
Stop the master daemons (ganeti-masterd and ganeti-rapi) on this node. |
|
346 |
|
|
347 |
@rtype: None |
|
348 |
|
|
349 |
""" |
|
350 |
# TODO: log and report back to the caller the error failures; we |
|
351 |
# need to decide in which case we fail the RPC for this |
|
352 |
|
|
353 |
result = utils.RunCmd([constants.DAEMON_UTIL, "stop-master"]) |
|
354 |
if result.failed: |
|
355 |
logging.error("Could not stop Ganeti master, command %s had exitcode %s" |
|
356 |
" and error %s", |
|
357 |
result.cmd, result.exit_code, result.output) |
|
361 | 358 |
|
362 | 359 |
|
363 | 360 |
def EtcHostsModify(mode, host, ip): |
Also available in: Unified diff