LUNodeQueryStorage: Acquire all locks in shared mode
[ganeti-local] / lib / bootstrap.py
index 85c2251..2f6f985 100644 (file)
@@ -222,7 +222,7 @@ def _WaitForNodeDaemon(node_name):
 
   """
   def _CheckNodeDaemon():
-    result = rpc.RpcRunner.call_version([node_name])[node_name]
+    result = rpc.BootstrapRunner().call_version([node_name])[node_name]
     if result.fail_msg:
       raise utils.RetryAgain()
 
@@ -283,13 +283,14 @@ def _InitFileStorage(file_storage_dir):
 
 
 def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913
-                master_netdev, file_storage_dir, shared_file_storage_dir,
-                candidate_pool_size, secondary_ip=None, vg_name=None,
-                beparams=None, nicparams=None, ndparams=None, hvparams=None,
-                enabled_hypervisors=None, modify_etc_hosts=True,
+                master_netmask, master_netdev, file_storage_dir,
+                shared_file_storage_dir, candidate_pool_size, secondary_ip=None,
+                vg_name=None, beparams=None, nicparams=None, ndparams=None,
+                hvparams=None, enabled_hypervisors=None, modify_etc_hosts=True,
                 modify_ssh_setup=True, maintain_node_health=False,
                 drbd_helper=None, uid_pool=None, default_iallocator=None,
-                primary_ip_version=None, prealloc_wipe_disks=False):
+                primary_ip_version=None, prealloc_wipe_disks=False,
+                use_external_mip_script=False):
   """Initialise the cluster.
 
   @type candidate_pool_size: int
@@ -310,12 +311,9 @@ def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913
                                " entries: %s" % invalid_hvs,
                                errors.ECODE_INVAL)
 
-  ipcls = None
-  if primary_ip_version == constants.IP4_VERSION:
-    ipcls = netutils.IP4Address
-  elif primary_ip_version == constants.IP6_VERSION:
-    ipcls = netutils.IP6Address
-  else:
+  try:
+    ipcls = netutils.IPAddress.GetClassFromIpVersion(primary_ip_version)
+  except errors.ProgrammerError:
     raise errors.OpPrereqError("Invalid primary ip version: %d." %
                                primary_ip_version)
 
@@ -359,6 +357,13 @@ def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913
                                " but it does not belong to this host." %
                                secondary_ip, errors.ECODE_ENVIRON)
 
+  if master_netmask is not None:
+    if not ipcls.ValidateNetmask(master_netmask):
+      raise errors.OpPrereqError("CIDR netmask (%s) not valid for IPv%s " %
+                                  (master_netmask, primary_ip_version))
+  else:
+    master_netmask = ipcls.iplen
+
   if vg_name is not None:
     # Check if volume group is valid
     vgstatus = utils.CheckVolumeGroupSize(utils.ListVolumeGroups(), vg_name,
@@ -457,6 +462,7 @@ def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913
     tcpudp_port_pool=set(),
     master_node=hostname.name,
     master_ip=clustername.ip,
+    master_netmask=master_netmask,
     master_netdev=master_netdev,
     cluster_name=clustername.name,
     file_storage_dir=file_storage_dir,
@@ -477,6 +483,7 @@ def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913
     default_iallocator=default_iallocator,
     primary_ip_family=ipcls.family,
     prealloc_wipe_disks=prealloc_wipe_disks,
+    use_external_mip_script=use_external_mip_script,
     )
   master_node_config = objects.Node(name=hostname.name,
                                     primary_ip=hostname.ip,
@@ -560,11 +567,24 @@ def FinalizeClusterDestroy(master):
   """
   cfg = config.ConfigWriter()
   modify_ssh_setup = cfg.GetClusterInfo().modify_ssh_setup
-  result = rpc.RpcRunner.call_node_stop_master(master, True)
+  runner = rpc.BootstrapRunner()
+
+  master_params = cfg.GetMasterNetworkParameters()
+  master_params.name = master
+  ems = cfg.GetUseExternalMipScript()
+  result = runner.call_node_deactivate_master_ip(master_params.name,
+                                                 master_params, ems)
+
+  msg = result.fail_msg
+  if msg:
+    logging.warning("Could not disable the master IP: %s", msg)
+
+  result = runner.call_node_stop_master(master)
   msg = result.fail_msg
   if msg:
     logging.warning("Could not disable the master role: %s", msg)
-  result = rpc.RpcRunner.call_node_leave_cluster(master, modify_ssh_setup)
+
+  result = runner.call_node_leave_cluster(master, modify_ssh_setup)
   msg = result.fail_msg
   if msg:
     logging.warning("Could not shutdown the node daemon and cleanup"
@@ -692,7 +712,18 @@ def MasterFailover(no_voting=False):
 
   logging.info("Stopping the master daemon on node %s", old_master)
 
-  result = rpc.RpcRunner.call_node_stop_master(old_master, True)
+  runner = rpc.BootstrapRunner()
+  master_params = cfg.GetMasterNetworkParameters()
+  master_params.name = old_master
+  ems = cfg.GetUseExternalMipScript()
+  result = runner.call_node_deactivate_master_ip(master_params.name,
+                                                 master_params, ems)
+
+  msg = result.fail_msg
+  if msg:
+    logging.warning("Could not disable the master IP: %s", msg)
+
+  result = runner.call_node_stop_master(old_master)
   msg = result.fail_msg
   if msg:
     logging.error("Could not disable the master role on the old master"
@@ -721,7 +752,8 @@ def MasterFailover(no_voting=False):
 
   logging.info("Starting the master daemons on the new master")
 
-  result = rpc.RpcRunner.call_node_start_master(new_master, True, no_voting)
+  result = rpc.BootstrapRunner().call_node_start_master_daemons(new_master,
+                                                                no_voting)
   msg = result.fail_msg
   if msg:
     logging.error("Could not start the master role on the new master"
@@ -777,7 +809,7 @@ def GatherMasterVotes(node_list):
   if not node_list:
     # no nodes left (eventually after removing myself)
     return []
-  results = rpc.RpcRunner.call_master_info(node_list)
+  results = rpc.BootstrapRunner().call_master_info(node_list)
   if not isinstance(results, dict):
     # this should not happen (unless internal error in rpc)
     logging.critical("Can't complete rpc call, aborting master startup")
@@ -791,7 +823,8 @@ def GatherMasterVotes(node_list):
     if msg:
       logging.warning("Error contacting node %s: %s", node, msg)
       fail = True
-    # for now we accept both length 3 and 4 (data[3] is primary ip version)
+    # for now we accept both length 3, 4 and 5 (data[3] is primary ip version
+    # and data[4] is the master netmask)
     elif not isinstance(data, (tuple, list)) or len(data) < 3:
       logging.warning("Invalid data received from node %s: %s", node, data)
       fail = True