Revision 2cc673a3

b/lib/bootstrap.py
421 421
    utils.ForceDictType(val, constants.ISPECS_PARAMETER_TYPES)
422 422

  
423 423
  objects.NIC.CheckParameterSyntax(nicparams)
424
  full_ipolicy = objects.FillDictOfDicts(constants.IPOLICY_DEFAULTS,
425
                                         ipolicy)
424
  full_ipolicy = objects.FillIPolicy(constants.IPOLICY_DEFAULTS, ipolicy)
426 425
  objects.InstancePolicy.CheckParameterSyntax(full_ipolicy)
427 426

  
428 427
  if ndparams is not None:
b/lib/client/gnt_cluster.py
139 139
    utils.ForceDictType(diskparams[templ], constants.DISK_DT_TYPES)
140 140

  
141 141
  # prepare ipolicy dict
142
  ispecs_dts = opts.ispecs_disk_templates # hate long var names
142 143
  ipolicy_raw = \
143 144
    objects.CreateIPolicyFromOpts(ispecs_mem_size=opts.ispecs_mem_size,
144 145
                                  ispecs_cpu_count=opts.ispecs_cpu_count,
145 146
                                  ispecs_disk_count=opts.ispecs_disk_count,
146 147
                                  ispecs_disk_size=opts.ispecs_disk_size,
147
                                  ispecs_nic_count=opts.ispecs_nic_count)
148
  ipolicy = objects.FillDictOfDicts(constants.IPOLICY_DEFAULTS, ipolicy_raw)
148
                                  ispecs_nic_count=opts.ispecs_nic_count,
149
                                  ispecs_disk_templates=ispecs_dts,
150
                                  fill_all=True)
151
  ipolicy = objects.FillIPolicy(constants.IPOLICY_DEFAULTS, ipolicy_raw)
149 152
  for value in ipolicy.values():
150 153
    utils.ForceDictType(value, constants.ISPECS_PARAMETER_TYPES)
151 154

  
......
461 464
  for key in constants.IPOLICY_PARAMETERS:
462 465
    ToStdout("  - %s", key)
463 466
    _PrintGroupedParams(result["ipolicy"][key], roman=opts.roman_integers)
467
  ToStdout("  - enabled disk templates: %s",
468
           utils.CommaJoin(result["ipolicy"][constants.ISPECS_DTS]))
464 469

  
465 470
  return 0
466 471

  
......
984 989
  if ndparams is not None:
985 990
    utils.ForceDictType(ndparams, constants.NDS_PARAMETER_TYPES)
986 991

  
992
  ispecs_dts = opts.ispecs_disk_templates
987 993
  ipolicy = \
988 994
    objects.CreateIPolicyFromOpts(ispecs_mem_size=opts.ispecs_mem_size,
989 995
                                  ispecs_cpu_count=opts.ispecs_cpu_count,
990 996
                                  ispecs_disk_count=opts.ispecs_disk_count,
991 997
                                  ispecs_disk_size=opts.ispecs_disk_size,
992
                                  ispecs_nic_count=opts.ispecs_nic_count)
998
                                  ispecs_nic_count=opts.ispecs_nic_count,
999
                                  ispecs_disk_templates=ispecs_dts)
993 1000

  
994 1001
  mnh = opts.maintain_node_health
995 1002

  
b/lib/client/gnt_group.py
192 192
    ispecs_disk_count=opts.ispecs_disk_count,
193 193
    ispecs_disk_size=opts.ispecs_disk_size,
194 194
    ispecs_nic_count=opts.ispecs_nic_count,
195
    ispecs_disk_templates=opts.ispecs_disk_templates,
195 196
    group_ipolicy=True,
196 197
    allowed_values=[constants.VALUE_DEFAULT])
197 198

  
b/lib/cmdlib.py
721 721
  return params_copy
722 722

  
723 723

  
724
def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False):
725
  """Return the new version of a instance policy.
726

  
727
  @param group_policy: whether this policy applies to a group and thus
728
    we should support removal of policy entries
729

  
730
  """
731
  use_none = use_default = group_policy
732
  ipolicy = copy.deepcopy(old_ipolicy)
733
  for key, value in new_ipolicy.items():
734
    if key in constants.IPOLICY_PARAMETERS:
735
      utils.ForceDictType(value, constants.ISPECS_PARAMETER_TYPES)
736
      ipolicy[key] = _GetUpdatedParams(old_ipolicy.get(key, {}), value,
737
                                       use_none=use_none,
738
                                       use_default=use_default)
739
    else:
740
      # FIXME: we assume all others are lists; this should be redone
741
      # in a nicer way
742
      if not value or value == [constants.VALUE_DEFAULT]:
743
        if group_policy:
744
          del ipolicy[key]
745
        else:
746
          raise errors.OpPrereqError("Can't unset ipolicy attribute '%s'"
747
                                     " on the cluster'" % key,
748
                                     errors.ECODE_INVAL)
749
      else:
750
        logging.info("Setting %s to %s", key, value)
751
        ipolicy[key] = list(value)
752
  try:
753
    objects.InstancePolicy.CheckParameterSyntax(ipolicy)
754
  except errors.ConfigurationError, err:
755
    raise errors.OpPrereqError("Invalid instance policy: %s" % err,
756
                               errors.ECODE_INVAL)
757
  return ipolicy
758

  
759

  
724 760
def _UpdateAndVerifySubDict(base, updates, type_check):
725 761
  """Updates and verifies a dict with sub dicts of the same type.
726 762

  
......
3830 3866
             for storage, svalues in new_disk_state.items())
3831 3867

  
3832 3868
    if self.op.ipolicy:
3833
      ipolicy = {}
3834
      for key, value in self.op.ipolicy.items():
3835
        utils.ForceDictType(value, constants.ISPECS_PARAMETER_TYPES)
3836
        ipolicy[key] = _GetUpdatedParams(cluster.ipolicy.get(key, {}),
3837
                                          value)
3838
      try:
3839
        objects.InstancePolicy.CheckParameterSyntax(ipolicy)
3840
      except errors.ConfigurationError, err:
3841
        raise errors.OpPrereqError("Invalid instance policy: %s" % err,
3842
                                   errors.ECODE_INVAL)
3843
      self.new_ipolicy = ipolicy
3869
      self.new_ipolicy = _GetUpdatedIPolicy(cluster.ipolicy, self.op.ipolicy,
3870
                                            group_policy=False)
3844 3871

  
3845 3872
    if self.op.nicparams:
3846 3873
      utils.ForceDictType(self.op.nicparams, constants.NICS_PARAMETER_TYPES)
......
13306 13333
                                 self.group.disk_state_static)
13307 13334

  
13308 13335
    if self.op.ipolicy:
13309
      g_ipolicy = {}
13310
      for key, value in self.op.ipolicy.iteritems():
13311
        g_ipolicy[key] = _GetUpdatedParams(self.group.ipolicy.get(key, {}),
13312
                                           value,
13313
                                           use_none=True)
13314
        utils.ForceDictType(g_ipolicy[key], constants.ISPECS_PARAMETER_TYPES)
13315
      self.new_ipolicy = g_ipolicy
13316
      try:
13317
        objects.InstancePolicy.CheckParameterSyntax(self.new_ipolicy)
13318
      except errors.ConfigurationError, err:
13319
        raise errors.OpPrereqError("Invalid instance policy: %s" % err,
13320
                                   errors.ECODE_INVAL)
13336
      self.new_ipolicy = _GetUpdatedIPolicy(self.group.ipolicy,
13337
                                            self.op.ipolicy,
13338
                                            group_policy=True)
13321 13339

  
13322 13340
  def BuildHooksEnv(self):
13323 13341
    """Build hooks env.
b/lib/config.py
433 433
        result.append("%s has invalid instance policy: %s" % (owner, err))
434 434

  
435 435
    def _helper_ispecs(owner, params):
436
      for key, value in params.iteritems():
437
        fullkey = "ipolicy/" + key
438
        _helper(owner, fullkey, value, constants.ISPECS_PARAMETER_TYPES)
436
      for key, value in params.items():
437
        if key in constants.IPOLICY_PARAMETERS:
438
          fullkey = "ipolicy/" + key
439
          _helper(owner, fullkey, value, constants.ISPECS_PARAMETER_TYPES)
440
        else:
441
          # FIXME: assuming list type
442
          if not isinstance(value, list):
443
            result.append("%s has invalid instance policy: for %s,"
444
                          " expecting list, got %s" %
445
                          (owner, key, type(value)))
439 446

  
440 447
    # check cluster parameters
441 448
    _helper("cluster", "beparams", cluster.SimpleFillBE({}),
b/lib/constants.py
941 941
ISPECS_MIN = "min"
942 942
ISPECS_MAX = "max"
943 943
ISPECS_STD = "std"
944
ISPECS_DTS = "disk_templates"
944 945

  
945 946
IPOLICY_PARAMETERS = frozenset([
946 947
  ISPECS_MIN,
947 948
  ISPECS_MAX,
948 949
  ISPECS_STD,
949 950
  ])
951
IPOLICY_ALL_KEYS = IPOLICY_PARAMETERS.union([ISPECS_DTS])
950 952

  
951 953
# Node parameter names
952 954
ND_OOB_PROGRAM = "oob_program"
......
1885 1887
    ISPEC_DISK_COUNT: 1,
1886 1888
    ISPEC_DISK_SIZE: 1024,
1887 1889
    ISPEC_NIC_COUNT: 1,
1888
    }
1890
    },
1891
  ISPECS_DTS: DISK_TEMPLATES,
1889 1892
  }
1890 1893

  
1891 1894
MASTER_POOL_SIZE_DEFAULT = 10
b/lib/objects.py
1 1
#
2 2
#
3 3

  
4
# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Google Inc.
4
# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Google Inc.
5 5
#
6 6
# This program is free software; you can redistribute it and/or modify
7 7
# it under the terms of the GNU General Public License as published by
......
59 59
TISPECS_GROUP_TYPES = {
60 60
  constants.ISPECS_MIN: constants.VTYPE_INT,
61 61
  constants.ISPECS_MAX: constants.VTYPE_INT,
62
}
62
  }
63 63

  
64 64
TISPECS_CLUSTER_TYPES = {
65 65
  constants.ISPECS_MIN: constants.VTYPE_INT,
......
92 92
  return ret_dict
93 93

  
94 94

  
95
def FillDictOfDicts(defaults_dict, custom_dict, skip_keys=None):
96
  """Run FillDict for each key in dictionary.
95
def FillIPolicy(default_ipolicy, custom_ipolicy, skip_keys=None):
96
  """Fills an instance policy with defaults.
97 97

  
98 98
  """
99
  assert frozenset(default_ipolicy.keys()) == constants.IPOLICY_ALL_KEYS
99 100
  ret_dict = {}
100
  for key in defaults_dict:
101
    ret_dict[key] = FillDict(defaults_dict[key],
102
                             custom_dict.get(key, {}),
101
  for key in constants.IPOLICY_PARAMETERS:
102
    ret_dict[key] = FillDict(default_ipolicy[key],
103
                             custom_ipolicy.get(key, {}),
103 104
                             skip_keys=skip_keys)
105
  # list items
106
  for key in [constants.ISPECS_DTS]:
107
    ret_dict[key] = list(custom_ipolicy.get(key, default_ipolicy[key]))
108

  
104 109
  return ret_dict
105 110

  
106 111

  
......
166 171

  
167 172
  """
168 173
  return dict([
169
    (constants.ISPECS_MIN, dict()),
170
    (constants.ISPECS_MAX, dict()),
171
    (constants.ISPECS_STD, dict()),
174
    (constants.ISPECS_MIN, {}),
175
    (constants.ISPECS_MAX, {}),
176
    (constants.ISPECS_STD, {}),
172 177
    ])
173 178

  
174 179

  
......
177 182
                          ispecs_disk_count=None,
178 183
                          ispecs_disk_size=None,
179 184
                          ispecs_nic_count=None,
185
                          ispecs_disk_templates=None,
180 186
                          group_ipolicy=False,
181
                          allowed_values=None):
182
  """Creation of instane policy based on command line options.
187
                          allowed_values=None,
188
                          fill_all=False):
189
  """Creation of instance policy based on command line options.
190

  
191
  @param fill_all: whether for cluster policies we should ensure that
192
    all values are filled
183 193

  
184 194

  
185 195
  """
......
208 218
    for key, val in specs.items(): # {min: .. ,max: .., std: ..}
209 219
      ipolicy_out[key][name] = val
210 220

  
221
  # no filldict for lists
222
  if not group_ipolicy and fill_all and ispecs_disk_templates is None:
223
    ispecs_disk_templates = constants.DISK_TEMPLATES
224
  if ispecs_disk_templates is not None:
225
    ipolicy_out[constants.ISPECS_DTS] = list(ispecs_disk_templates)
226

  
211 227
  return ipolicy_out
212 228

  
213 229

  
......
857 873

  
858 874
class InstancePolicy(ConfigObject):
859 875
  """Config object representing instance policy limits dictionary."""
860
  __slots__ = ["min", "max", "std"]
876
  __slots__ = ["min", "max", "std", "disk_templates"]
861 877

  
862 878
  @classmethod
863 879
  def CheckParameterSyntax(cls, ipolicy):
......
866 882
    """
867 883
    for param in constants.ISPECS_PARAMETERS:
868 884
      InstancePolicy.CheckISpecSyntax(ipolicy, param)
885
    if constants.ISPECS_DTS in ipolicy:
886
      InstancePolicy.CheckDiskTemplates(ipolicy[constants.ISPECS_DTS])
869 887

  
870 888
  @classmethod
871 889
  def CheckISpecSyntax(cls, ipolicy, name):
......
892 910
    if min_v > std_v or std_v > max_v:
893 911
      raise errors.ConfigurationError(err)
894 912

  
913
  @classmethod
914
  def CheckDiskTemplates(cls, disk_templates):
915
    """Checks the disk templates for validity.
916

  
917
    """
918
    wrong = frozenset(disk_templates).difference(constants.DISK_TEMPLATES)
919
    if wrong:
920
      raise errors.ConfigurationError("Invalid disk template(s) %s" %
921
                                      utils.CommaJoin(wrong))
922

  
895 923

  
896 924
class Instance(TaggableObject):
897 925
  """Config object representing an instance."""
......
1473 1501

  
1474 1502
    # instance policy added before 2.6
1475 1503
    if self.ipolicy is None:
1476
      self.ipolicy = FillDictOfDicts(constants.IPOLICY_DEFAULTS, {})
1504
      self.ipolicy = FillIPolicy(constants.IPOLICY_DEFAULTS, {})
1477 1505

  
1478 1506
  @property
1479 1507
  def primary_hypervisor(self):
......
1668 1696
      the cluster defaults
1669 1697

  
1670 1698
    """
1671
    return FillDictOfDicts(self.ipolicy, ipolicy)
1699
    return FillIPolicy(self.ipolicy, ipolicy)
1672 1700

  
1673 1701

  
1674 1702
class BlockDevStatus(ConfigObject):

Also available in: Unified diff