LUClusterSetParams: When ipolicy is updated warn for new violations
[ganeti-local] / lib / client / gnt_cluster.py
index 15a99c8..2fa42cd 100644 (file)
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2006, 2007, 2010, 2011 Google Inc.
+# Copyright (C) 2006, 2007, 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
@@ -52,6 +52,10 @@ GROUPS_OPT = cli_option("--groups", default=False,
                     action="store_true", dest="groups",
                     help="Arguments are node groups instead of nodes")
 
+SHOW_MACHINE_OPT = cli_option("-M", "--show-machine-names", default=False,
+                              action="store_true",
+                              help="Show machine name for every line in output")
+
 _EPO_PING_INTERVAL = 30 # 30 seconds between pings
 _EPO_PING_TIMEOUT = 1 # 1 second
 _EPO_REACHABLE_TIMEOUT = 15 * 60 # 15 minutes
@@ -138,6 +142,18 @@ def InitCluster(opts, args):
                                          diskparams[templ])
     utils.ForceDictType(diskparams[templ], constants.DISK_DT_TYPES)
 
+  # prepare ipolicy dict
+  ispecs_dts = opts.ipolicy_disk_templates # hate long var names
+  ipolicy_raw = \
+    objects.CreateIPolicyFromOpts(ispecs_mem_size=opts.ispecs_mem_size,
+                                  ispecs_cpu_count=opts.ispecs_cpu_count,
+                                  ispecs_disk_count=opts.ispecs_disk_count,
+                                  ispecs_disk_size=opts.ispecs_disk_size,
+                                  ispecs_nic_count=opts.ispecs_nic_count,
+                                  ipolicy_disk_templates=ispecs_dts,
+                                  fill_all=True)
+  ipolicy = objects.FillIPolicy(constants.IPOLICY_DEFAULTS, ipolicy_raw)
+
   if opts.candidate_pool_size is None:
     opts.candidate_pool_size = constants.MASTER_POOL_SIZE_DEFAULT
 
@@ -169,6 +185,13 @@ def InitCluster(opts, args):
     ToStderr("Invalid master netmask value: %s" % str(err))
     return 1
 
+  if opts.disk_state:
+    disk_state = utils.FlatToDict(opts.disk_state)
+  else:
+    disk_state = {}
+
+  hv_state = dict(opts.hv_state)
+
   bootstrap.InitCluster(cluster_name=args[0],
                         secondary_ip=opts.secondary_ip,
                         vg_name=vg_name,
@@ -183,6 +206,7 @@ def InitCluster(opts, args):
                         nicparams=nicparams,
                         ndparams=ndparams,
                         diskparams=diskparams,
+                        ipolicy=ipolicy,
                         candidate_pool_size=opts.candidate_pool_size,
                         modify_etc_hosts=opts.modify_etc_hosts,
                         modify_ssh_setup=opts.modify_ssh_setup,
@@ -193,6 +217,8 @@ def InitCluster(opts, args):
                         primary_ip_version=primary_ip_version,
                         prealloc_wipe_disks=opts.prealloc_wipe_disks,
                         use_external_mip_script=external_ip_setup_script,
+                        hv_state=hv_state,
+                        disk_state=disk_state,
                         )
   op = opcodes.OpClusterPostInit()
   SubmitOpCode(op, opts=opts)
@@ -436,6 +462,13 @@ def ShowClusterConfig(opts, args):
   ToStdout("Default nic parameters:")
   _PrintGroupedParams(result["nicparams"], roman=opts.roman_integers)
 
+  ToStdout("Instance policy - limits for instances:")
+  for key in constants.IPOLICY_PARAMETERS:
+    ToStdout("  - %s", key)
+    _PrintGroupedParams(result["ipolicy"][key], roman=opts.roman_integers)
+  ToStdout("  - enabled disk templates: %s",
+           utils.CommaJoin(result["ipolicy"][constants.IPOLICY_DTS]))
+
   return 0
 
 
@@ -500,8 +533,12 @@ def RunClusterCommand(opts, args):
   for name in nodes:
     result = srun.Run(name, "root", command)
     ToStdout("------------------------------------------------")
-    ToStdout("node: %s", name)
-    ToStdout("%s", result.output)
+    if opts.show_machine_names:
+      for line in result.output.splitlines():
+        ToStdout("%s: %s", name, line)
+    else:
+      ToStdout("node: %s", name)
+      ToStdout("%s", result.output)
     ToStdout("return code = %s", result.exit_code)
 
   return 0
@@ -907,7 +944,14 @@ def SetClusterParams(opts, args):
           opts.master_netdev is not None or
           opts.master_netmask is not None or
           opts.use_external_mip_script is not None or
-          opts.prealloc_wipe_disks is not None):
+          opts.prealloc_wipe_disks is not None or
+          opts.hv_state or
+          opts.disk_state or
+          opts.ispecs_mem_size is not None or
+          opts.ispecs_cpu_count is not None or
+          opts.ispecs_disk_count is not None or
+          opts.ispecs_disk_size is not None or
+          opts.ispecs_nic_count is not None):
     ToStderr("Please give at least one of the parameters.")
     return 1
 
@@ -938,7 +982,7 @@ def SetClusterParams(opts, args):
 
   diskparams = dict(opts.diskparams)
 
-  for dt_params in hvparams.values():
+  for dt_params in diskparams.values():
     utils.ForceDictType(dt_params, constants.DISK_DT_TYPES)
 
   beparams = opts.beparams
@@ -951,6 +995,15 @@ def SetClusterParams(opts, args):
   if ndparams is not None:
     utils.ForceDictType(ndparams, constants.NDS_PARAMETER_TYPES)
 
+  ispecs_dts = opts.ipolicy_disk_templates
+  ipolicy = \
+    objects.CreateIPolicyFromOpts(ispecs_mem_size=opts.ispecs_mem_size,
+                                  ispecs_cpu_count=opts.ispecs_cpu_count,
+                                  ispecs_disk_count=opts.ispecs_disk_count,
+                                  ispecs_disk_size=opts.ispecs_disk_size,
+                                  ispecs_nic_count=opts.ispecs_nic_count,
+                                  ipolicy_disk_templates=ispecs_dts)
+
   mnh = opts.maintain_node_health
 
   uid_pool = opts.uid_pool
@@ -980,6 +1033,13 @@ def SetClusterParams(opts, args):
 
   ext_ip_script = opts.use_external_mip_script
 
+  if opts.disk_state:
+    disk_state = utils.FlatToDict(opts.disk_state)
+  else:
+    disk_state = {}
+
+  hv_state = dict(opts.hv_state)
+
   op = opcodes.OpClusterSetParams(vg_name=vg_name,
                                   drbd_helper=drbd_helper,
                                   enabled_hypervisors=hvlist,
@@ -989,6 +1049,7 @@ def SetClusterParams(opts, args):
                                   nicparams=nicparams,
                                   ndparams=ndparams,
                                   diskparams=diskparams,
+                                  ipolicy=ipolicy,
                                   candidate_pool_size=opts.candidate_pool_size,
                                   maintain_node_health=mnh,
                                   uid_pool=uid_pool,
@@ -1000,6 +1061,8 @@ def SetClusterParams(opts, args):
                                   master_netmask=opts.master_netmask,
                                   reserved_lvs=opts.reserved_lvs,
                                   use_external_mip_script=ext_ip_script,
+                                  hv_state=hv_state,
+                                  disk_state=disk_state,
                                   )
   SubmitOpCode(op, opts=opts)
   return 0
@@ -1392,7 +1455,6 @@ def Epo(opts, args):
   else:
     return _EpoOff(opts, node_list, inst_map)
 
-
 commands = {
   "init": (
     InitCluster, [ArgHost(min=1, max=1)],
@@ -1403,7 +1465,7 @@ commands = {
      MAINTAIN_NODE_HEALTH_OPT, UIDPOOL_OPT, DRBD_HELPER_OPT, NODRBD_STORAGE_OPT,
      DEFAULT_IALLOCATOR_OPT, PRIMARY_IP_VERSION_OPT, PREALLOC_WIPE_DISKS_OPT,
      NODE_PARAMS_OPT, GLOBAL_SHARED_FILEDIR_OPT, USE_EXTERNAL_MIP_SCRIPT,
-     DISK_PARAMS_OPT],
+     DISK_PARAMS_OPT, HV_STATE_OPT, DISK_STATE_OPT] + INSTANCE_POLICY_OPTS,
     "[opts...] <cluster_name>", "Initialises a new cluster configuration"),
   "destroy": (
     DestroyCluster, ARGS_NONE, [YES_DOIT_OPT],
@@ -1446,7 +1508,7 @@ commands = {
     "[-n node...] <filename>", "Copies a file to all (or only some) nodes"),
   "command": (
     RunClusterCommand, [ArgCommand(min=1)],
-    [NODE_LIST_OPT, NODEGROUP_OPT],
+    [NODE_LIST_OPT, NODEGROUP_OPT, SHOW_MACHINE_OPT],
     "[-n node...] <command>", "Runs a command on all (or only some) nodes"),
   "info": (
     ShowClusterConfig, ARGS_NONE, [ROMAN_OPT],
@@ -1480,7 +1542,9 @@ commands = {
      MAINTAIN_NODE_HEALTH_OPT, UIDPOOL_OPT, ADD_UIDS_OPT, REMOVE_UIDS_OPT,
      DRBD_HELPER_OPT, NODRBD_STORAGE_OPT, DEFAULT_IALLOCATOR_OPT,
      RESERVED_LVS_OPT, DRY_RUN_OPT, PRIORITY_OPT, PREALLOC_WIPE_DISKS_OPT,
-     NODE_PARAMS_OPT, USE_EXTERNAL_MIP_SCRIPT, DISK_PARAMS_OPT],
+     NODE_PARAMS_OPT, USE_EXTERNAL_MIP_SCRIPT, DISK_PARAMS_OPT, HV_STATE_OPT,
+     DISK_STATE_OPT] +
+    INSTANCE_POLICY_OPTS,
     "[opts...]",
     "Alters the parameters of the cluster"),
   "renew-crypto": (