Merge branch 'stable-2.6'
[ganeti-local] / lib / bootstrap.py
index f154694..726f7c4 100644 (file)
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2006, 2007, 2008, 2010, 2011 Google Inc.
+# Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -222,6 +222,8 @@ def _WaitForNodeDaemon(node_name):
 
   """
   def _CheckNodeDaemon():
+    # Pylint bug <http://www.logilab.org/ticket/35642>
+    # pylint: disable=E1101
     result = rpc.BootstrapRunner().call_version([node_name])[node_name]
     if result.fail_msg:
       raise utils.RetryAgain()
@@ -290,7 +292,8 @@ def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913, R0914
                 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, ipolicy=None,
-                prealloc_wipe_disks=False, use_external_mip_script=False):
+                prealloc_wipe_disks=False, use_external_mip_script=False,
+                hv_state=None, disk_state=None):
   """Initialise the cluster.
 
   @type candidate_pool_size: int
@@ -413,22 +416,37 @@ def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913, R0914
   objects.UpgradeBeParams(beparams)
   utils.ForceDictType(beparams, constants.BES_PARAMETER_TYPES)
   utils.ForceDictType(nicparams, constants.NICS_PARAMETER_TYPES)
-  for key, val in ipolicy.items():
-    if key not in constants.IPOLICY_PARAMETERS:
-      raise errors.OpPrereqError("'%s' is not a valid key for instance policy"
-                                 " description", key)
-    utils.ForceDictType(val, constants.ISPECS_PARAMETER_TYPES)
 
   objects.NIC.CheckParameterSyntax(nicparams)
-  full_ipolicy = objects.FillDictOfDicts(constants.IPOLICY_DEFAULTS,
-                                         ipolicy)
-  objects.InstancePolicy.CheckParameterSyntax(full_ipolicy)
+
+  full_ipolicy = objects.FillIPolicy(constants.IPOLICY_DEFAULTS, ipolicy)
 
   if ndparams is not None:
     utils.ForceDictType(ndparams, constants.NDS_PARAMETER_TYPES)
   else:
     ndparams = dict(constants.NDC_DEFAULTS)
 
+  # This is ugly, as we modify the dict itself
+  # FIXME: Make utils.ForceDictType pure functional or write a wrapper
+  # around it
+  if hv_state:
+    for hvname, hvs_data in hv_state.items():
+      utils.ForceDictType(hvs_data, constants.HVSTS_PARAMETER_TYPES)
+      hv_state[hvname] = objects.Cluster.SimpleFillHvState(hvs_data)
+  else:
+    hv_state = dict((hvname, constants.HVST_DEFAULTS)
+                    for hvname in enabled_hypervisors)
+
+  # FIXME: disk_state has no default values yet
+  if disk_state:
+    for storage, ds_data in disk_state.items():
+      if storage not in constants.DS_VALID_TYPES:
+        raise errors.OpPrereqError("Invalid storage type in disk state: %s" %
+                                   storage, errors.ECODE_INVAL)
+      for ds_name, state in ds_data.items():
+        utils.ForceDictType(state, constants.DSS_PARAMETER_TYPES)
+        ds_data[ds_name] = objects.Cluster.SimpleFillDiskState(state)
+
   # hvparams is a mapping of hypervisor->hvparams dict
   for hv_name, hv_params in hvparams.iteritems():
     utils.ForceDictType(hv_params, constants.HVS_PARAMETER_TYPES)
@@ -506,7 +524,9 @@ def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913, R0914
     primary_ip_family=ipcls.family,
     prealloc_wipe_disks=prealloc_wipe_disks,
     use_external_mip_script=use_external_mip_script,
-    ipolicy=ipolicy
+    ipolicy=full_ipolicy,
+    hv_state_static=hv_state,
+    disk_state_static=disk_state,
     )
   master_node_config = objects.Node(name=hostname.name,
                                     primary_ip=hostname.ip,
@@ -564,7 +584,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,
+    diskparams={},
     )
   nodegroups = {
     default_nodegroup.uuid: default_nodegroup,
@@ -648,7 +668,7 @@ def SetupNodeDaemon(cluster_name, node, ssh_key_check):
                (constants.DAEMON_UTIL, constants.DAEMON_UTIL, constants.NODED,
                 utils.ShellQuote(bind_address)))
 
-  result = sshrunner.Run(node, 'root', mycommand, batch=False,
+  result = sshrunner.Run(node, "root", mycommand, batch=False,
                          ask_key=ssh_key_check,
                          use_cluster_key=True,
                          strict_host_check=ssh_key_check)
@@ -690,7 +710,7 @@ def MasterFailover(no_voting=False):
                                " as master candidates. Only these nodes"
                                " can become masters. Current list of"
                                " master candidates is:\n"
-                               "%s" % ('\n'.join(mc_no_master)),
+                               "%s" % ("\n".join(mc_no_master)),
                                errors.ECODE_STATE)
 
   if not no_voting: