Revision 2c9fa1ff

b/lib/cmdlib.py
7213 7213
                 utils.CommaJoin(ial.result))
7214 7214

  
7215 7215
  def CheckArguments(self):
7216
    if self.op.disks and ht.TPositiveInt(self.op.disks[0]):
7216
    if self.op.disks and ht.TNonNegativeInt(self.op.disks[0]):
7217 7217
      # Normalize and convert deprecated list of disk indices
7218 7218
      self.op.disks = [(idx, {}) for idx in sorted(frozenset(self.op.disks))]
7219 7219

  
b/lib/ht.py
1 1
#
2 2
#
3 3

  
4
# Copyright (C) 2010, 2011 Google Inc.
4
# Copyright (C) 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
......
318 318
#: Maybe a dictionary (dict or None)
319 319
TMaybeDict = TOr(TDict, TNone)
320 320

  
321
#: a positive integer
321
#: a non-negative integer (value >= 0)
322
TNonNegativeInt = \
323
  TAnd(TInt, WithDesc("EqualOrGreaterThanZero")(lambda v: v >= 0))
324

  
325
#: a positive integer (value > 0)
322 326
TPositiveInt = \
323
  TAnd(TInt, WithDesc("EqualGreaterZero")(lambda v: v >= 0))
327
  TAnd(TInt, WithDesc("GreaterThanZero")(lambda v: v > 0))
324 328

  
325 329
#: a maybe positive integer (positive integer or None)
326 330
TMaybePositiveInt = TOr(TPositiveInt, TNone)
327 331

  
328
#: a strictly positive integer
329
TStrictPositiveInt = \
330
  TAnd(TInt, WithDesc("GreaterThanZero")(lambda v: v > 0))
331

  
332
#: a maybe strictly positive integer (strictly positive integer or None)
333
TMaybeStrictPositiveInt = TOr(TStrictPositiveInt, TNone)
334

  
335
#: a strictly negative integer (0 > value)
336
TStrictNegativeInt = \
332
#: a negative integer (value < 0)
333
TNegativeInt = \
337 334
  TAnd(TInt, WithDesc("LessThanZero")(compat.partial(operator.gt, 0)))
338 335

  
339 336
#: a positive float
340
TPositiveFloat = \
341
  TAnd(TFloat, WithDesc("EqualGreaterZero")(lambda v: v >= 0.0))
337
TNonNegativeFloat = \
338
  TAnd(TFloat, WithDesc("EqualOrGreaterThanZero")(lambda v: v >= 0.0))
342 339

  
343 340
#: Job ID
344
TJobId = WithDesc("JobId")(TOr(TPositiveInt,
341
TJobId = WithDesc("JobId")(TOr(TNonNegativeInt,
345 342
                               TRegex(re.compile("^%s$" %
346 343
                                                 constants.JOB_ID_TEMPLATE))))
347 344

  
......
349 346
TNumber = TOr(TInt, TFloat)
350 347

  
351 348
#: Relative job ID
352
TRelativeJobId = WithDesc("RelativeJobId")(TStrictNegativeInt)
349
TRelativeJobId = WithDesc("RelativeJobId")(TNegativeInt)
353 350

  
354 351

  
355 352
def TInstanceOf(my_inst):
b/lib/jqueue.py
1913 1913
    @return: a list of job identifiers.
1914 1914

  
1915 1915
    """
1916
    assert ht.TPositiveInt(count)
1916
    assert ht.TNonNegativeInt(count)
1917 1917

  
1918 1918
    # New number
1919 1919
    serial = self._last_serial + count
b/lib/masterd/iallocator.py
144 144
  MODE = constants.IALLOCATOR_MODE_ALLOC
145 145
  REQ_PARAMS = [
146 146
    _INST_NAME,
147
    ("memory", ht.TPositiveInt),
148
    ("spindle_use", ht.TPositiveInt),
147
    ("memory", ht.TNonNegativeInt),
148
    ("spindle_use", ht.TNonNegativeInt),
149 149
    ("disks", ht.TListOf(ht.TDict)),
150 150
    ("disk_template", ht.TString),
151 151
    ("os", ht.TString),
b/lib/opcodes.py
51 51

  
52 52
#: the shutdown timeout
53 53
_PShutdownTimeout = \
54
  ("shutdown_timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT, ht.TPositiveInt,
54
  ("shutdown_timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT, ht.TNonNegativeInt,
55 55
   "How long to wait for instance to shut down")
56 56

  
57 57
#: the force parameter
......
541 541
  WITH_LU = True
542 542
  OP_PARAMS = [
543 543
    ("dry_run", None, ht.TMaybeBool, "Run checks only, don't execute"),
544
    ("debug_level", None, ht.TOr(ht.TNone, ht.TPositiveInt), "Debug level"),
544
    ("debug_level", None, ht.TOr(ht.TNone, ht.TNonNegativeInt), "Debug level"),
545 545
    ("priority", constants.OP_PRIO_DEFAULT,
546 546
     ht.TElemOf(constants.OP_PRIO_SUBMIT_VALID), "Opcode priority"),
547 547
    (DEPEND_ATTR, None, _BuildJobDepCheck(True),
......
768 768
    ]
769 769
  OP_RESULT = ht.TListOf(ht.TAnd(ht.TIsLength(3),
770 770
                                 ht.TItems([ht.TNonEmptyString,
771
                                            ht.TPositiveInt,
772
                                            ht.TPositiveInt])))
771
                                            ht.TNonNegativeInt,
772
                                            ht.TNonNegativeInt])))
773 773

  
774 774

  
775 775
class OpClusterConfigQuery(OpCode):
......
823 823
                              ht.TNone),
824 824
     "Cluster-wide OS parameter defaults"),
825 825
    _PDiskParams,
826
    ("candidate_pool_size", None, ht.TOr(ht.TStrictPositiveInt, ht.TNone),
826
    ("candidate_pool_size", None, ht.TOr(ht.TPositiveInt, ht.TNone),
827 827
     "Master candidate pool size"),
828 828
    ("uid_pool", None, ht.NoType,
829 829
     "Set UID pool, must be list of lists describing UID ranges (two items,"
......
940 940
     "Timeout before the OOB helper will be terminated"),
941 941
    ("ignore_status", False, ht.TBool,
942 942
     "Ignores the node offline status for power off"),
943
    ("power_delay", constants.OOB_POWER_DELAY, ht.TPositiveFloat,
943
    ("power_delay", constants.OOB_POWER_DELAY, ht.TNonNegativeFloat,
944 944
     "Time in seconds to wait between powering on nodes"),
945 945
    ]
946 946
  # Fixme: Make it more specific with all the special cases in LUOobCommand
......
1220 1220
    ("source_instance_name", None, ht.TMaybeString,
1221 1221
     "Source instance name (remote import only)"),
1222 1222
    ("source_shutdown_timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT,
1223
     ht.TPositiveInt,
1223
     ht.TNonNegativeInt,
1224 1224
     "How long source instance was given to shut down (remote import only)"),
1225 1225
    ("source_x509_ca", None, ht.TMaybeString,
1226 1226
     "Source X509 CA in PEM format (remote import only)"),
......
1349 1349
  OP_PARAMS = [
1350 1350
    _PInstanceName,
1351 1351
    _PIgnoreOfflineNodes,
1352
    ("timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT, ht.TPositiveInt,
1352
    ("timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT, ht.TNonNegativeInt,
1353 1353
     "How long to wait for instance to shut down"),
1354 1354
    _PNoRemember,
1355 1355
    ]
......
1379 1379
    _PIgnoreIpolicy,
1380 1380
    ("mode", ht.NoDefault, ht.TElemOf(constants.REPLACE_MODES),
1381 1381
     "Replacement mode"),
1382
    ("disks", ht.EmptyList, ht.TListOf(ht.TPositiveInt),
1382
    ("disks", ht.EmptyList, ht.TListOf(ht.TNonNegativeInt),
1383 1383
     "Disk indexes"),
1384 1384
    ("remote_node", None, ht.TMaybeString, "New secondary node"),
1385 1385
    ("iallocator", None, ht.TMaybeString,
......
1489 1489
  """Recreate an instance's disks."""
1490 1490
  _TDiskChanges = \
1491 1491
    ht.TAnd(ht.TIsLength(2),
1492
            ht.TItems([ht.Comment("Disk index")(ht.TPositiveInt),
1492
            ht.TItems([ht.Comment("Disk index")(ht.TNonNegativeInt),
1493 1493
                       ht.Comment("Parameters")(_TDiskParams)]))
1494 1494

  
1495 1495
  OP_DSC_FIELD = "instance_name"
1496 1496
  OP_PARAMS = [
1497 1497
    _PInstanceName,
1498 1498
    ("disks", ht.EmptyList,
1499
     ht.TOr(ht.TListOf(ht.TPositiveInt), ht.TListOf(_TDiskChanges)),
1499
     ht.TOr(ht.TListOf(ht.TNonNegativeInt), ht.TListOf(_TDiskChanges)),
1500 1500
     "List of disk indexes (deprecated) or a list of tuples containing a disk"
1501 1501
     " index and a possibly empty dictionary with disk parameter changes"),
1502 1502
    ("nodes", ht.EmptyList, ht.TListOf(ht.TNonEmptyString),
......
1539 1539
  # TODO: Remove in version 2.8 including support in LUInstanceSetParams
1540 1540
  old_mod_item_fn = \
1541 1541
    ht.TAnd(ht.TIsLength(2), ht.TItems([
1542
      ht.TOr(ht.TElemOf(constants.DDMS_VALUES), ht.TPositiveInt),
1542
      ht.TOr(ht.TElemOf(constants.DDMS_VALUES), ht.TNonNegativeInt),
1543 1543
      fn,
1544 1544
      ]))
1545 1545

  
......
1581 1581
    ("disks", ht.EmptyList, TestDiskModifications,
1582 1582
     "List of disk changes; see ``nics``"),
1583 1583
    ("beparams", ht.EmptyDict, ht.TDict, "Per-instance backend parameters"),
1584
    ("runtime_mem", None, ht.TMaybeStrictPositiveInt, "New runtime memory"),
1584
    ("runtime_mem", None, ht.TMaybePositiveInt, "New runtime memory"),
1585 1585
    ("hvparams", ht.EmptyDict, ht.TDict,
1586 1586
     "Per-instance hypervisor parameters, hypervisor-dependent"),
1587 1587
    ("disk_template", None, ht.TOr(ht.TNone, _BuildDiskTemplateCheck(False)),
......
1605 1605
    _PInstanceName,
1606 1606
    _PWaitForSync,
1607 1607
    ("disk", ht.NoDefault, ht.TInt, "Disk index"),
1608
    ("amount", ht.NoDefault, ht.TPositiveInt,
1608
    ("amount", ht.NoDefault, ht.TNonNegativeInt,
1609 1609
     "Amount of disk space to add (megabytes)"),
1610 1610
    ("absolute", False, ht.TBool,
1611 1611
     "Whether the amount parameter is an absolute target or a relative one"),
......
1883 1883
    ("duration", ht.NoDefault, ht.TNumber, None),
1884 1884
    ("on_master", True, ht.TBool, None),
1885 1885
    ("on_nodes", ht.EmptyList, ht.TListOf(ht.TNonEmptyString), None),
1886
    ("repeat", 0, ht.TPositiveInt, None),
1886
    ("repeat", 0, ht.TNonNegativeInt, None),
1887 1887
    ]
1888 1888

  
1889 1889

  
......
1914 1914
    ("hypervisor", None, ht.TMaybeString, None),
1915 1915
    ("allocator", None, ht.TMaybeString, None),
1916 1916
    ("tags", ht.EmptyList, ht.TListOf(ht.TNonEmptyString), None),
1917
    ("memory", None, ht.TOr(ht.TNone, ht.TPositiveInt), None),
1918
    ("vcpus", None, ht.TOr(ht.TNone, ht.TPositiveInt), None),
1917
    ("memory", None, ht.TOr(ht.TNone, ht.TNonNegativeInt), None),
1918
    ("vcpus", None, ht.TOr(ht.TNone, ht.TNonNegativeInt), None),
1919 1919
    ("os", None, ht.TMaybeString, None),
1920 1920
    ("disk_template", None, ht.TMaybeString, None),
1921 1921
    ("instances", None, ht.TMaybeListOf(ht.TNonEmptyString), None),
1922 1922
    ("evac_mode", None,
1923 1923
     ht.TOr(ht.TNone, ht.TElemOf(constants.IALLOCATOR_NEVAC_MODES)), None),
1924 1924
    ("target_groups", None, ht.TMaybeListOf(ht.TNonEmptyString), None),
1925
    ("spindle_use", 1, ht.TPositiveInt, None),
1926
    ("count", 1, ht.TPositiveInt, None),
1925
    ("spindle_use", 1, ht.TNonNegativeInt, None),
1926
    ("count", 1, ht.TNonNegativeInt, None),
1927 1927
    ]
1928 1928

  
1929 1929

  
b/test/ganeti.ht_unittest.py
1 1
#!/usr/bin/python
2 2
#
3 3

  
4
# Copyright (C) 2011 Google Inc.
4
# Copyright (C) 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
      self.assertFalse(ht.TInt(val))
60 60

  
61 61
    for val in range(0, 100, 4):
62
      self.assertTrue(ht.TPositiveInt(val))
62
      self.assertTrue(ht.TNonNegativeInt(val))
63 63
      neg = -(val + 1)
64
      self.assertFalse(ht.TNonNegativeInt(neg))
64 65
      self.assertFalse(ht.TPositiveInt(neg))
65
      self.assertFalse(ht.TStrictPositiveInt(neg))
66 66

  
67
      self.assertFalse(ht.TNonNegativeInt(0.1 + val))
67 68
      self.assertFalse(ht.TPositiveInt(0.1 + val))
68
      self.assertFalse(ht.TStrictPositiveInt(0.1 + val))
69 69

  
70 70
    for val in [0, 0.1, 0.9, -0.3]:
71
      self.assertFalse(ht.TStrictPositiveInt(val))
71
      self.assertFalse(ht.TPositiveInt(val))
72 72

  
73 73
    for val in range(1, 100, 4):
74
      self.assertTrue(ht.TStrictPositiveInt(val))
75
      self.assertFalse(ht.TStrictPositiveInt(0.1 + val))
74
      self.assertTrue(ht.TPositiveInt(val))
75
      self.assertFalse(ht.TPositiveInt(0.1 + val))
76 76

  
77 77
  def testFloat(self):
78 78
    for val in [-100.21, -3.0, 0.0, 16.12, 128.3433, 923874.928]:

Also available in: Unified diff