Revision 880478f8 lib/cmdlib.py
b/lib/cmdlib.py | ||
---|---|---|
19 | 19 |
# 02110-1301, USA. |
20 | 20 |
|
21 | 21 |
|
22 |
"""Module implementing the commands used by gnt-* programs."""
|
|
22 |
"""Module implementing the master-side code."""
|
|
23 | 23 |
|
24 | 24 |
# pylint: disable-msg=W0613,W0201 |
25 | 25 |
|
... | ... | |
84 | 84 |
raise errors.OpPrereqError, ("Cluster not initialized yet," |
85 | 85 |
" use 'gnt-cluster init' first.") |
86 | 86 |
if self.REQ_MASTER: |
87 |
master = cfg.GetMaster()
|
|
87 |
master = sstore.GetMasterNode()
|
|
88 | 88 |
if master != socket.gethostname(): |
89 | 89 |
raise errors.OpPrereqError, ("Commands must be run on the master" |
90 | 90 |
" node %s" % master) |
... | ... | |
406 | 406 |
(result.cmd, result.exit_code, result.output)) |
407 | 407 |
|
408 | 408 |
|
409 |
def _InitClusterInterface(fullname, name, ip): |
|
410 |
"""Initialize the master startup script. |
|
411 |
|
|
412 |
""" |
|
413 |
f = file(constants.CLUSTER_NAME_FILE, 'w') |
|
414 |
f.write("%s\n" % fullname) |
|
415 |
f.close() |
|
416 |
|
|
417 |
f = file(constants.MASTER_INITD_SCRIPT, 'w') |
|
418 |
f.write ("#!/bin/sh\n") |
|
419 |
f.write ("\n") |
|
420 |
f.write ("# Start Ganeti Master Virtual Address\n") |
|
421 |
f.write ("\n") |
|
422 |
f.write ("DESC=\"Ganeti Master IP\"\n") |
|
423 |
f.write ("MASTERNAME=\"%s\"\n" % name) |
|
424 |
f.write ("MASTERIP=\"%s\"\n" % ip) |
|
425 |
f.write ("case \"$1\" in\n") |
|
426 |
f.write (" start)\n") |
|
427 |
f.write (" if fping -q -c 3 ${MASTERIP} &>/dev/null; then\n") |
|
428 |
f.write (" echo \"$MASTERNAME no-go - there is already a master.\"\n") |
|
429 |
f.write (" rm -f %s\n" % constants.MASTER_CRON_LINK) |
|
430 |
f.write (" scp ${MASTERNAME}:%s %s\n" % |
|
431 |
(constants.CLUSTER_CONF_FILE, constants.CLUSTER_CONF_FILE)) |
|
432 |
f.write (" else\n") |
|
433 |
f.write (" echo -n \"Starting $DESC: \"\n") |
|
434 |
f.write (" ip address add ${MASTERIP}/32 dev xen-br0" |
|
435 |
" label xen-br0:0\n") |
|
436 |
f.write (" arping -q -U -c 3 -I xen-br0 -s ${MASTERIP} ${MASTERIP}\n") |
|
437 |
f.write (" echo \"$MASTERNAME.\"\n") |
|
438 |
f.write (" fi\n") |
|
439 |
f.write (" ;;\n") |
|
440 |
f.write (" stop)\n") |
|
441 |
f.write (" echo -n \"Stopping $DESC: \"\n") |
|
442 |
f.write (" ip address del ${MASTERIP}/32 dev xen-br0\n") |
|
443 |
f.write (" echo \"$MASTERNAME.\"\n") |
|
444 |
f.write (" ;;\n") |
|
445 |
f.write (" *)\n") |
|
446 |
f.write (" echo \"Usage: $0 {start|stop}\" >&2\n") |
|
447 |
f.write (" exit 1\n") |
|
448 |
f.write (" ;;\n") |
|
449 |
f.write ("esac\n") |
|
450 |
f.write ("\n") |
|
451 |
f.write ("exit 0\n") |
|
452 |
f.flush() |
|
453 |
os.fsync(f.fileno()) |
|
454 |
f.close() |
|
455 |
os.chmod(constants.MASTER_INITD_SCRIPT, 0755) |
|
456 |
|
|
457 |
|
|
458 | 409 |
class LUInitCluster(LogicalUnit): |
459 | 410 |
"""Initialise the cluster. |
460 | 411 |
|
... | ... | |
462 | 413 |
HPATH = "cluster-init" |
463 | 414 |
HTYPE = constants.HTYPE_CLUSTER |
464 | 415 |
_OP_REQP = ["cluster_name", "hypervisor_type", "vg_name", "mac_prefix", |
465 |
"def_bridge"] |
|
416 |
"def_bridge", "master_netdev"]
|
|
466 | 417 |
REQ_CLUSTER = False |
467 | 418 |
|
468 | 419 |
def BuildHooksEnv(self): |
... | ... | |
474 | 425 |
""" |
475 | 426 |
|
476 | 427 |
env = {"CLUSTER": self.op.cluster_name, |
477 |
"MASTER": self.hostname} |
|
428 |
"MASTER": self.hostname['hostname_full']}
|
|
478 | 429 |
return env, [], [self.hostname['hostname_full']] |
479 | 430 |
|
480 | 431 |
def CheckPrereq(self): |
... | ... | |
528 | 479 |
raise errors.OpPrereqError, ("Invalid hypervisor type given '%s'" % |
529 | 480 |
self.op.hypervisor_type) |
530 | 481 |
|
482 |
result = utils.RunCmd(["ip", "link", "show", "dev", self.op.master_netdev]) |
|
483 |
if result.failed: |
|
484 |
raise errors.OpPrereqError, ("Invalid master netdev given (%s): '%s'" % |
|
485 |
(self.op.master_netdev, result.output)) |
|
486 |
|
|
531 | 487 |
def Exec(self, feedback_fn): |
532 | 488 |
"""Initialize the cluster. |
533 | 489 |
|
... | ... | |
535 | 491 |
clustername = self.clustername |
536 | 492 |
hostname = self.hostname |
537 | 493 |
|
538 |
# adds the cluste name file and master startup script |
|
539 |
_InitClusterInterface(clustername['hostname_full'], |
|
540 |
clustername['hostname'], |
|
541 |
clustername['ip']) |
|
542 |
|
|
543 | 494 |
# set up the simple store |
544 | 495 |
ss = ssconf.SimpleStore() |
545 | 496 |
ss.SetKey(ss.SS_HYPERVISOR, self.op.hypervisor_type) |
497 |
ss.SetKey(ss.SS_MASTER_NODE, hostname['hostname_full']) |
|
498 |
ss.SetKey(ss.SS_MASTER_IP, clustername['ip']) |
|
499 |
ss.SetKey(ss.SS_MASTER_NETDEV, self.op.master_netdev) |
|
546 | 500 |
|
547 | 501 |
# set up the inter-node password and certificate |
548 | 502 |
_InitGanetiServerSetup(ss) |
... | ... | |
590 | 544 |
Any errors are signalled by raising errors.OpPrereqError. |
591 | 545 |
|
592 | 546 |
""" |
593 |
master = self.cfg.GetMaster()
|
|
547 |
master = self.sstore.GetMasterNode()
|
|
594 | 548 |
|
595 | 549 |
nodelist = self.cfg.GetNodeList() |
596 | 550 |
if len(nodelist) > 0 and nodelist != [master]: |
597 |
raise errors.OpPrereqError, ("There are still %d node(s) in "
|
|
598 |
"this cluster." % (len(nodelist) - 1))
|
|
551 |
raise errors.OpPrereqError, ("There are still %d node(s) in " |
|
552 |
"this cluster." % (len(nodelist) - 1)) |
|
599 | 553 |
|
600 | 554 |
def Exec(self, feedback_fn): |
601 | 555 |
"""Destroys the cluster. |
... | ... | |
603 | 557 |
""" |
604 | 558 |
utils.CreateBackup('/root/.ssh/id_dsa') |
605 | 559 |
utils.CreateBackup('/root/.ssh/id_dsa.pub') |
606 |
rpc.call_node_leave_cluster(self.cfg.GetMaster())
|
|
560 |
rpc.call_node_leave_cluster(self.sstore.GetMasterNode())
|
|
607 | 561 |
|
608 | 562 |
|
609 | 563 |
class LUVerifyCluster(NoHooksLU): |
... | ... | |
795 | 749 |
feedback_fn("* Verifying global settings") |
796 | 750 |
self.cfg.VerifyConfig() |
797 | 751 |
|
798 |
master = self.cfg.GetMaster()
|
|
752 |
master = self.sstore.GetMasterNode()
|
|
799 | 753 |
vg_name = self.cfg.GetVGName() |
800 | 754 |
nodelist = utils.NiceSort(self.cfg.GetNodeList()) |
801 | 755 |
instancelist = utils.NiceSort(self.cfg.GetInstanceList()) |
... | ... | |
1029 | 983 |
|
1030 | 984 |
instance_list = self.cfg.GetInstanceList() |
1031 | 985 |
|
1032 |
masternode = self.cfg.GetMaster()
|
|
986 |
masternode = self.sstore.GetMasterNode()
|
|
1033 | 987 |
if node.name == masternode: |
1034 | 988 |
raise errors.OpPrereqError, ("Node is the master node," |
1035 | 989 |
" you need to failover first.") |
... | ... | |
1253 | 1207 |
|
1254 | 1208 |
# check that the type of the node (single versus dual homed) is the |
1255 | 1209 |
# same as for the master |
1256 |
myself = cfg.GetNodeInfo(cfg.GetMaster())
|
|
1210 |
myself = cfg.GetNodeInfo(self.sstore.GetMasterNode())
|
|
1257 | 1211 |
master_singlehomed = myself.secondary_ip == myself.primary_ip |
1258 | 1212 |
newbie_singlehomed = secondary_ip == primary_ip |
1259 | 1213 |
if master_singlehomed != newbie_singlehomed: |
... | ... | |
1378 | 1332 |
|
1379 | 1333 |
# Distribute updated /etc/hosts and known_hosts to all nodes, |
1380 | 1334 |
# including the node just added |
1381 |
myself = self.cfg.GetNodeInfo(self.cfg.GetMaster())
|
|
1335 |
myself = self.cfg.GetNodeInfo(self.sstore.GetMasterNode())
|
|
1382 | 1336 |
dist_nodes = self.cfg.GetNodeList() + [node] |
1383 | 1337 |
if myself.name in dist_nodes: |
1384 | 1338 |
dist_nodes.remove(myself.name) |
... | ... | |
1391 | 1345 |
logger.Error("copy of file %s to node %s failed" % |
1392 | 1346 |
(fname, to_node)) |
1393 | 1347 |
|
1394 |
to_copy = [constants.MASTER_CRON_FILE, |
|
1395 |
constants.MASTER_INITD_SCRIPT, |
|
1396 |
constants.CLUSTER_NAME_FILE] |
|
1348 |
to_copy = [constants.MASTER_CRON_FILE] |
|
1397 | 1349 |
to_copy.extend(ss.GetFileList()) |
1398 | 1350 |
for fname in to_copy: |
1399 | 1351 |
if not ssh.CopyFileToNode(node, fname): |
... | ... | |
1435 | 1387 |
""" |
1436 | 1388 |
self.new_master = socket.gethostname() |
1437 | 1389 |
|
1438 |
self.old_master = self.cfg.GetMaster()
|
|
1390 |
self.old_master = self.sstore.GetMasterNode()
|
|
1439 | 1391 |
|
1440 | 1392 |
if self.old_master == self.new_master: |
1441 | 1393 |
raise errors.OpPrereqError, ("This commands must be run on the node" |
... | ... | |
1460 | 1412 |
logger.Error("could disable the master role on the old master" |
1461 | 1413 |
" %s, please disable manually" % self.old_master) |
1462 | 1414 |
|
1415 |
ss = self.sstore |
|
1416 |
ss.SetKey(ss.SS_MASTER_NODE, self.new_master) |
|
1417 |
if not rpc.call_upload_file(self.cfg.GetNodeList(), |
|
1418 |
ss.KeyToFilename(ss.SS_MASTER_NODE)): |
|
1419 |
logger.Error("could not distribute the new simple store master file" |
|
1420 |
" to the other nodes, please check.") |
|
1421 |
|
|
1463 | 1422 |
if not rpc.call_node_start_master(self.new_master): |
1464 | 1423 |
logger.Error("could not start the master role on the new master" |
1465 | 1424 |
" %s, please check" % self.new_master) |
1425 |
feedback_fn("Error in activating the master IP on the new master,\n" |
|
1426 |
"please fix manually.") |
|
1466 | 1427 |
|
1467 |
self.cfg.SetMaster(self.new_master) |
|
1468 | 1428 |
|
1469 | 1429 |
|
1470 | 1430 |
class LUQueryClusterInfo(NoHooksLU): |
... | ... | |
1492 | 1452 |
"config_version": constants.CONFIG_VERSION, |
1493 | 1453 |
"os_api_version": constants.OS_API_VERSION, |
1494 | 1454 |
"export_version": constants.EXPORT_VERSION, |
1495 |
"master": self.cfg.GetMaster(),
|
|
1455 |
"master": self.sstore.GetMasterNode(),
|
|
1496 | 1456 |
"architecture": (platform.architecture()[0], platform.machine()), |
1497 | 1457 |
"instances": [(instance.name, instance.primary_node) |
1498 | 1458 |
for instance in instances], |
... | ... | |
1748 | 1708 |
"INSTANCE_SECONDARIES": " ".join(self.instance.secondary_nodes), |
1749 | 1709 |
"FORCE": self.op.force, |
1750 | 1710 |
} |
1751 |
nl = ([self.cfg.GetMaster(), self.instance.primary_node] +
|
|
1711 |
nl = ([self.sstore.GetMasterNode(), self.instance.primary_node] +
|
|
1752 | 1712 |
list(self.instance.secondary_nodes)) |
1753 | 1713 |
return env, nl, nl |
1754 | 1714 |
|
... | ... | |
1833 | 1793 |
"INSTANCE_PRIMARY": self.instance.primary_node, |
1834 | 1794 |
"INSTANCE_SECONDARIES": " ".join(self.instance.secondary_nodes), |
1835 | 1795 |
} |
1836 |
nl = ([self.cfg.GetMaster(), self.instance.primary_node] +
|
|
1796 |
nl = ([self.sstore.GetMasterNode(), self.instance.primary_node] +
|
|
1837 | 1797 |
list(self.instance.secondary_nodes)) |
1838 | 1798 |
return env, nl, nl |
1839 | 1799 |
|
... | ... | |
1882 | 1842 |
"INSTANCE_PRIMARY": self.instance.primary_node, |
1883 | 1843 |
"INSTANCE_SECONDARIES": " ".join(self.instance.secondary_nodes), |
1884 | 1844 |
} |
1885 |
nl = ([self.cfg.GetMaster(), self.instance.primary_node] +
|
|
1845 |
nl = ([self.sstore.GetMasterNode(), self.instance.primary_node] +
|
|
1886 | 1846 |
list(self.instance.secondary_nodes)) |
1887 | 1847 |
return env, nl, nl |
1888 | 1848 |
|
... | ... | |
2044 | 2004 |
"INSTANCE_SECONDARIES": " ".join(self.instance.secondary_nodes), |
2045 | 2005 |
"IGNORE_CONSISTENCY": self.op.ignore_consistency, |
2046 | 2006 |
} |
2047 |
nl = [self.cfg.GetMaster()] + list(self.instance.secondary_nodes)
|
|
2007 |
nl = [self.sstore.GetMasterNode()] + list(self.instance.secondary_nodes)
|
|
2048 | 2008 |
return env, nl, nl |
2049 | 2009 |
|
2050 | 2010 |
def CheckPrereq(self): |
... | ... | |
2367 | 2327 |
if self.inst_ip: |
2368 | 2328 |
env["INSTANCE_IP"] = self.inst_ip |
2369 | 2329 |
|
2370 |
nl = ([self.cfg.GetMaster(), self.op.pnode] +
|
|
2330 |
nl = ([self.sstore.GetMasterNode(), self.op.pnode] +
|
|
2371 | 2331 |
self.secondaries) |
2372 | 2332 |
return env, nl, nl |
2373 | 2333 |
|
... | ... | |
2675 | 2635 |
"NEW_SECONDARY": self.op.remote_node, |
2676 | 2636 |
"DISK_NAME": self.op.disk_name, |
2677 | 2637 |
} |
2678 |
nl = [self.cfg.GetMaster(), self.instance.primary_node,
|
|
2638 |
nl = [self.sstore.GetMasterNode(), self.instance.primary_node,
|
|
2679 | 2639 |
self.op.remote_node,] + list(self.instance.secondary_nodes) |
2680 | 2640 |
return env, nl, nl |
2681 | 2641 |
|
... | ... | |
2787 | 2747 |
"DISK_ID": self.op.disk_id, |
2788 | 2748 |
"OLD_SECONDARY": self.old_secondary, |
2789 | 2749 |
} |
2790 |
nl = [self.cfg.GetMaster(),
|
|
2750 |
nl = [self.sstore.GetMasterNode(),
|
|
2791 | 2751 |
self.instance.primary_node] + list(self.instance.secondary_nodes) |
2792 | 2752 |
return env, nl, nl |
2793 | 2753 |
|
... | ... | |
2872 | 2832 |
"NEW_SECONDARY": self.op.remote_node, |
2873 | 2833 |
"OLD_SECONDARY": self.instance.secondary_nodes[0], |
2874 | 2834 |
} |
2875 |
nl = [self.cfg.GetMaster(),
|
|
2835 |
nl = [self.sstore.GetMasterNode(),
|
|
2876 | 2836 |
self.instance.primary_node] + list(self.instance.secondary_nodes) |
2877 | 2837 |
return env, nl, nl |
2878 | 2838 |
|
... | ... | |
2920 | 2880 |
# start of work |
2921 | 2881 |
remote_node = self.op.remote_node |
2922 | 2882 |
cfg = self.cfg |
2883 |
vgname = cfg.GetVGName() |
|
2923 | 2884 |
for dev in instance.disks: |
2924 | 2885 |
size = dev.size |
2925 |
new_drbd = _GenerateMDDRBDBranch(cfg, self.cfg.GetVGName(),
|
|
2926 |
instance.primary_node, remote_node, size,
|
|
2886 |
new_drbd = _GenerateMDDRBDBranch(cfg, vgname, instance.primary_node,
|
|
2887 |
remote_node, size, |
|
2927 | 2888 |
"%s-%s" % (instance.name, dev.iv_name)) |
2928 | 2889 |
iv_names[dev.iv_name] = (dev, dev.children[0], new_drbd) |
2929 | 2890 |
logger.Info("adding new mirror component on secondary for %s" % |
... | ... | |
2948 | 2909 |
# call the primary node to add the mirror to md |
2949 | 2910 |
logger.Info("adding new mirror component to md") |
2950 | 2911 |
if not rpc.call_blockdev_addchild(instance.primary_node, dev, |
2951 |
new_drbd):
|
|
2912 |
new_drbd): |
|
2952 | 2913 |
logger.Error("Can't add mirror compoment to md!") |
2953 | 2914 |
cfg.SetDiskID(new_drbd, remote_node) |
2954 | 2915 |
if not rpc.call_blockdev_remove(remote_node, new_drbd): |
... | ... | |
3172 | 3133 |
if self.bridge: |
3173 | 3134 |
env["BRIDGE"] = self.bridge |
3174 | 3135 |
|
3175 |
nl = [self.cfg.GetMaster(),
|
|
3136 |
nl = [self.sstore.GetMasterNode(),
|
|
3176 | 3137 |
self.instance.primary_node] + list(self.instance.secondary_nodes) |
3177 | 3138 |
|
3178 | 3139 |
return env, nl, nl |
... | ... | |
3295 | 3256 |
"EXPORT_NODE": self.op.target_node, |
3296 | 3257 |
"EXPORT_DO_SHUTDOWN": self.op.shutdown, |
3297 | 3258 |
} |
3298 |
nl = [self.cfg.GetMaster(), self.instance.primary_node,
|
|
3259 |
nl = [self.sstore.GetMasterNode(), self.instance.primary_node,
|
|
3299 | 3260 |
self.op.target_node] |
3300 | 3261 |
return env, nl, nl |
3301 | 3262 |
|
Also available in: Unified diff