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