Update default instance kernel version
[ganeti-local] / lib / bootstrap.py
index bc4fd15..8c4663f 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
@@ -282,15 +282,16 @@ def _InitFileStorage(file_storage_dir):
   return file_storage_dir
 
 
-def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913
+def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913, R0914
                 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,
-                use_external_mip_script=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, ipolicy=None,
+                prealloc_wipe_disks=False, use_external_mip_script=False,
+                hv_state=None, disk_state=None):
   """Initialise the cluster.
 
   @type candidate_pool_size: int
@@ -413,19 +414,54 @@ def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913
   objects.UpgradeBeParams(beparams)
   utils.ForceDictType(beparams, constants.BES_PARAMETER_TYPES)
   utils.ForceDictType(nicparams, constants.NICS_PARAMETER_TYPES)
+
   objects.NIC.CheckParameterSyntax(nicparams)
 
+  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)
     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]
@@ -473,6 +509,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,
@@ -485,6 +522,9 @@ def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913
     primary_ip_family=ipcls.family,
     prealloc_wipe_disks=prealloc_wipe_disks,
     use_external_mip_script=use_external_mip_script,
+    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,
@@ -542,6 +582,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,
@@ -625,7 +666,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)
@@ -667,7 +708,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: