Add basic support for disk parameters
[ganeti-local] / lib / bootstrap.py
index 2f720a2..62d59ce 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()
 
@@ -286,10 +286,11 @@ def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913
                 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):
+                hvparams=None, diskparams=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, use_external_mip_script=False):
   """Initialise the cluster.
 
   @type candidate_pool_size: int
@@ -409,6 +410,7 @@ def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913
   dirs = [(constants.RUN_GANETI_DIR, constants.RUN_DIRS_MODE)]
   utils.EnsureDirs(dirs)
 
+  objects.UpgradeBeParams(beparams)
   utils.ForceDictType(beparams, constants.BES_PARAMETER_TYPES)
   utils.ForceDictType(nicparams, constants.NICS_PARAMETER_TYPES)
   objects.NIC.CheckParameterSyntax(nicparams)
@@ -424,6 +426,17 @@ def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913
     hv_class = hypervisor.GetHypervisor(hv_name)
     hv_class.CheckParameterSyntax(hv_params)
 
+  # diskparams is a mapping of disk-template->diskparams dict
+  for template, dt_params in diskparams.items():
+    param_keys = set(dt_params.keys())
+    default_param_keys = set(constants.DISK_DT_DEFAULTS[template].keys())
+    if not (param_keys <= default_param_keys):
+      unknown_params = param_keys - default_param_keys
+      raise errors.OpPrereqError("Invalid parameters for disk template %s:"
+                                 " %s" % (template,
+                                          utils.CommaJoin(unknown_params)))
+    utils.ForceDictType(dt_params, constants.DISK_DT_TYPES)
+
   # set up ssh config and /etc/hosts
   sshline = utils.ReadFile(constants.SSH_HOST_RSA_PUB)
   sshkey = sshline.split(" ")[1]
@@ -471,6 +484,7 @@ def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913
     nicparams={constants.PP_DEFAULT: nicparams},
     ndparams=ndparams,
     hvparams=hvparams,
+    diskparams=diskparams,
     candidate_pool_size=candidate_pool_size,
     modify_etc_hosts=modify_etc_hosts,
     modify_ssh_setup=modify_ssh_setup,
@@ -482,6 +496,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,
@@ -539,6 +554,7 @@ def InitConfig(version, cluster_config, master_node_config,
     uuid=uuid_generator.Generate([], utils.NewUUID, _INITCONF_ECID),
     name=constants.INITIAL_NODE_GROUP_NAME,
     members=[master_node_config.name],
+    diskparams=cluster_config.diskparams,
     )
   nodegroups = {
     default_nodegroup.uuid: default_nodegroup,
@@ -565,11 +581,24 @@ def FinalizeClusterDestroy(master):
   """
   cfg = config.ConfigWriter()
   modify_ssh_setup = cfg.GetClusterInfo().modify_ssh_setup
-  result = rpc.RpcRunner.call_node_stop_master(master)
+  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"
@@ -697,7 +726,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)
+  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"
@@ -726,7 +766,8 @@ def MasterFailover(no_voting=False):
 
   logging.info("Starting the master daemons on the new master")
 
-  result = rpc.RpcRunner.call_node_start_master_daemons(new_master, 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"
@@ -782,7 +823,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")