diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 7dec2a2797878b04f45bc67e0b8709142cd70a2b..aaf1c64edd21d4f1e857d2fe57b7bfcf478483ca 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -7213,7 +7213,7 @@ class LUInstanceRecreateDisks(LogicalUnit): utils.CommaJoin(ial.result)) def CheckArguments(self): - if self.op.disks and ht.TPositiveInt(self.op.disks[0]): + if self.op.disks and ht.TNonNegativeInt(self.op.disks[0]): # Normalize and convert deprecated list of disk indices self.op.disks = [(idx, {}) for idx in sorted(frozenset(self.op.disks))] diff --git a/lib/ht.py b/lib/ht.py index 2613be326be564cdfbd261ab0f36a4368a0d8de0..31d08c0932094211ed60f06a377b1e1db757a088 100644 --- a/lib/ht.py +++ b/lib/ht.py @@ -1,7 +1,7 @@ # # -# Copyright (C) 2010, 2011 Google Inc. +# Copyright (C) 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 @@ -318,30 +318,27 @@ TMaybeBool = TOr(TBool, TNone) #: Maybe a dictionary (dict or None) TMaybeDict = TOr(TDict, TNone) -#: a positive integer +#: a non-negative integer (value >= 0) +TNonNegativeInt = \ + TAnd(TInt, WithDesc("EqualOrGreaterThanZero")(lambda v: v >= 0)) + +#: a positive integer (value > 0) TPositiveInt = \ - TAnd(TInt, WithDesc("EqualGreaterZero")(lambda v: v >= 0)) + TAnd(TInt, WithDesc("GreaterThanZero")(lambda v: v > 0)) #: a maybe positive integer (positive integer or None) TMaybePositiveInt = TOr(TPositiveInt, TNone) -#: a strictly positive integer -TStrictPositiveInt = \ - TAnd(TInt, WithDesc("GreaterThanZero")(lambda v: v > 0)) - -#: a maybe strictly positive integer (strictly positive integer or None) -TMaybeStrictPositiveInt = TOr(TStrictPositiveInt, TNone) - -#: a strictly negative integer (0 > value) -TStrictNegativeInt = \ +#: a negative integer (value < 0) +TNegativeInt = \ TAnd(TInt, WithDesc("LessThanZero")(compat.partial(operator.gt, 0))) #: a positive float -TPositiveFloat = \ - TAnd(TFloat, WithDesc("EqualGreaterZero")(lambda v: v >= 0.0)) +TNonNegativeFloat = \ + TAnd(TFloat, WithDesc("EqualOrGreaterThanZero")(lambda v: v >= 0.0)) #: Job ID -TJobId = WithDesc("JobId")(TOr(TPositiveInt, +TJobId = WithDesc("JobId")(TOr(TNonNegativeInt, TRegex(re.compile("^%s$" % constants.JOB_ID_TEMPLATE)))) @@ -349,7 +346,7 @@ TJobId = WithDesc("JobId")(TOr(TPositiveInt, TNumber = TOr(TInt, TFloat) #: Relative job ID -TRelativeJobId = WithDesc("RelativeJobId")(TStrictNegativeInt) +TRelativeJobId = WithDesc("RelativeJobId")(TNegativeInt) def TInstanceOf(my_inst): diff --git a/lib/jqueue.py b/lib/jqueue.py index d1b3b521541d423d0fbe901a6e39a40a94918134..5e639950e54ae36b87220e89b3090772c22ab6c4 100644 --- a/lib/jqueue.py +++ b/lib/jqueue.py @@ -1913,7 +1913,7 @@ class JobQueue(object): @return: a list of job identifiers. """ - assert ht.TPositiveInt(count) + assert ht.TNonNegativeInt(count) # New number serial = self._last_serial + count diff --git a/lib/masterd/iallocator.py b/lib/masterd/iallocator.py index 594f1c914c3c4ec4ca2426d8a0cb1534a7b96125..2b0bb54ce740bc6cabe5d95d9d485642de2020ce 100644 --- a/lib/masterd/iallocator.py +++ b/lib/masterd/iallocator.py @@ -144,8 +144,8 @@ class IAReqInstanceAlloc(IARequestBase): MODE = constants.IALLOCATOR_MODE_ALLOC REQ_PARAMS = [ _INST_NAME, - ("memory", ht.TPositiveInt), - ("spindle_use", ht.TPositiveInt), + ("memory", ht.TNonNegativeInt), + ("spindle_use", ht.TNonNegativeInt), ("disks", ht.TListOf(ht.TDict)), ("disk_template", ht.TString), ("os", ht.TString), diff --git a/lib/opcodes.py b/lib/opcodes.py index 74e35b4b465e5089b259f6d74e2287c7dd62a96c..e12a994acc3f017d3e7af575286568abaa58aeea 100644 --- a/lib/opcodes.py +++ b/lib/opcodes.py @@ -51,7 +51,7 @@ _POutputFields = ("output_fields", ht.NoDefault, ht.TListOf(ht.TNonEmptyString), #: the shutdown timeout _PShutdownTimeout = \ - ("shutdown_timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT, ht.TPositiveInt, + ("shutdown_timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT, ht.TNonNegativeInt, "How long to wait for instance to shut down") #: the force parameter @@ -541,7 +541,7 @@ class OpCode(BaseOpCode): WITH_LU = True OP_PARAMS = [ ("dry_run", None, ht.TMaybeBool, "Run checks only, don't execute"), - ("debug_level", None, ht.TOr(ht.TNone, ht.TPositiveInt), "Debug level"), + ("debug_level", None, ht.TOr(ht.TNone, ht.TNonNegativeInt), "Debug level"), ("priority", constants.OP_PRIO_DEFAULT, ht.TElemOf(constants.OP_PRIO_SUBMIT_VALID), "Opcode priority"), (DEPEND_ATTR, None, _BuildJobDepCheck(True), @@ -768,8 +768,8 @@ class OpClusterRepairDiskSizes(OpCode): ] OP_RESULT = ht.TListOf(ht.TAnd(ht.TIsLength(3), ht.TItems([ht.TNonEmptyString, - ht.TPositiveInt, - ht.TPositiveInt]))) + ht.TNonNegativeInt, + ht.TNonNegativeInt]))) class OpClusterConfigQuery(OpCode): @@ -823,7 +823,7 @@ class OpClusterSetParams(OpCode): ht.TNone), "Cluster-wide OS parameter defaults"), _PDiskParams, - ("candidate_pool_size", None, ht.TOr(ht.TStrictPositiveInt, ht.TNone), + ("candidate_pool_size", None, ht.TOr(ht.TPositiveInt, ht.TNone), "Master candidate pool size"), ("uid_pool", None, ht.NoType, "Set UID pool, must be list of lists describing UID ranges (two items," @@ -940,7 +940,7 @@ class OpOobCommand(OpCode): "Timeout before the OOB helper will be terminated"), ("ignore_status", False, ht.TBool, "Ignores the node offline status for power off"), - ("power_delay", constants.OOB_POWER_DELAY, ht.TPositiveFloat, + ("power_delay", constants.OOB_POWER_DELAY, ht.TNonNegativeFloat, "Time in seconds to wait between powering on nodes"), ] # Fixme: Make it more specific with all the special cases in LUOobCommand @@ -1220,7 +1220,7 @@ class OpInstanceCreate(OpCode): ("source_instance_name", None, ht.TMaybeString, "Source instance name (remote import only)"), ("source_shutdown_timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT, - ht.TPositiveInt, + ht.TNonNegativeInt, "How long source instance was given to shut down (remote import only)"), ("source_x509_ca", None, ht.TMaybeString, "Source X509 CA in PEM format (remote import only)"), @@ -1349,7 +1349,7 @@ class OpInstanceShutdown(OpCode): OP_PARAMS = [ _PInstanceName, _PIgnoreOfflineNodes, - ("timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT, ht.TPositiveInt, + ("timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT, ht.TNonNegativeInt, "How long to wait for instance to shut down"), _PNoRemember, ] @@ -1379,7 +1379,7 @@ class OpInstanceReplaceDisks(OpCode): _PIgnoreIpolicy, ("mode", ht.NoDefault, ht.TElemOf(constants.REPLACE_MODES), "Replacement mode"), - ("disks", ht.EmptyList, ht.TListOf(ht.TPositiveInt), + ("disks", ht.EmptyList, ht.TListOf(ht.TNonNegativeInt), "Disk indexes"), ("remote_node", None, ht.TMaybeString, "New secondary node"), ("iallocator", None, ht.TMaybeString, @@ -1489,14 +1489,14 @@ class OpInstanceRecreateDisks(OpCode): """Recreate an instance's disks.""" _TDiskChanges = \ ht.TAnd(ht.TIsLength(2), - ht.TItems([ht.Comment("Disk index")(ht.TPositiveInt), + ht.TItems([ht.Comment("Disk index")(ht.TNonNegativeInt), ht.Comment("Parameters")(_TDiskParams)])) OP_DSC_FIELD = "instance_name" OP_PARAMS = [ _PInstanceName, ("disks", ht.EmptyList, - ht.TOr(ht.TListOf(ht.TPositiveInt), ht.TListOf(_TDiskChanges)), + ht.TOr(ht.TListOf(ht.TNonNegativeInt), ht.TListOf(_TDiskChanges)), "List of disk indexes (deprecated) or a list of tuples containing a disk" " index and a possibly empty dictionary with disk parameter changes"), ("nodes", ht.EmptyList, ht.TListOf(ht.TNonEmptyString), @@ -1539,7 +1539,7 @@ def _TestInstSetParamsModList(fn): # TODO: Remove in version 2.8 including support in LUInstanceSetParams old_mod_item_fn = \ ht.TAnd(ht.TIsLength(2), ht.TItems([ - ht.TOr(ht.TElemOf(constants.DDMS_VALUES), ht.TPositiveInt), + ht.TOr(ht.TElemOf(constants.DDMS_VALUES), ht.TNonNegativeInt), fn, ])) @@ -1581,7 +1581,7 @@ class OpInstanceSetParams(OpCode): ("disks", ht.EmptyList, TestDiskModifications, "List of disk changes; see ``nics``"), ("beparams", ht.EmptyDict, ht.TDict, "Per-instance backend parameters"), - ("runtime_mem", None, ht.TMaybeStrictPositiveInt, "New runtime memory"), + ("runtime_mem", None, ht.TMaybePositiveInt, "New runtime memory"), ("hvparams", ht.EmptyDict, ht.TDict, "Per-instance hypervisor parameters, hypervisor-dependent"), ("disk_template", None, ht.TOr(ht.TNone, _BuildDiskTemplateCheck(False)), @@ -1605,7 +1605,7 @@ class OpInstanceGrowDisk(OpCode): _PInstanceName, _PWaitForSync, ("disk", ht.NoDefault, ht.TInt, "Disk index"), - ("amount", ht.NoDefault, ht.TPositiveInt, + ("amount", ht.NoDefault, ht.TNonNegativeInt, "Amount of disk space to add (megabytes)"), ("absolute", False, ht.TBool, "Whether the amount parameter is an absolute target or a relative one"), @@ -1883,7 +1883,7 @@ class OpTestDelay(OpCode): ("duration", ht.NoDefault, ht.TNumber, None), ("on_master", True, ht.TBool, None), ("on_nodes", ht.EmptyList, ht.TListOf(ht.TNonEmptyString), None), - ("repeat", 0, ht.TPositiveInt, None), + ("repeat", 0, ht.TNonNegativeInt, None), ] @@ -1914,16 +1914,16 @@ class OpTestAllocator(OpCode): ("hypervisor", None, ht.TMaybeString, None), ("allocator", None, ht.TMaybeString, None), ("tags", ht.EmptyList, ht.TListOf(ht.TNonEmptyString), None), - ("memory", None, ht.TOr(ht.TNone, ht.TPositiveInt), None), - ("vcpus", None, ht.TOr(ht.TNone, ht.TPositiveInt), None), + ("memory", None, ht.TOr(ht.TNone, ht.TNonNegativeInt), None), + ("vcpus", None, ht.TOr(ht.TNone, ht.TNonNegativeInt), None), ("os", None, ht.TMaybeString, None), ("disk_template", None, ht.TMaybeString, None), ("instances", None, ht.TMaybeListOf(ht.TNonEmptyString), None), ("evac_mode", None, ht.TOr(ht.TNone, ht.TElemOf(constants.IALLOCATOR_NEVAC_MODES)), None), ("target_groups", None, ht.TMaybeListOf(ht.TNonEmptyString), None), - ("spindle_use", 1, ht.TPositiveInt, None), - ("count", 1, ht.TPositiveInt, None), + ("spindle_use", 1, ht.TNonNegativeInt, None), + ("count", 1, ht.TNonNegativeInt, None), ] diff --git a/test/ganeti.ht_unittest.py b/test/ganeti.ht_unittest.py index 59d97576de59cc54a0cd5b6b758b6f03fa9e45c6..d227dfc8513ab33a1318c1b27e74a7bfc4c893fb 100755 --- a/test/ganeti.ht_unittest.py +++ b/test/ganeti.ht_unittest.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -# Copyright (C) 2011 Google Inc. +# Copyright (C) 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 @@ -59,20 +59,20 @@ class TestTypeChecks(unittest.TestCase): self.assertFalse(ht.TInt(val)) for val in range(0, 100, 4): - self.assertTrue(ht.TPositiveInt(val)) + self.assertTrue(ht.TNonNegativeInt(val)) neg = -(val + 1) + self.assertFalse(ht.TNonNegativeInt(neg)) self.assertFalse(ht.TPositiveInt(neg)) - self.assertFalse(ht.TStrictPositiveInt(neg)) + self.assertFalse(ht.TNonNegativeInt(0.1 + val)) self.assertFalse(ht.TPositiveInt(0.1 + val)) - self.assertFalse(ht.TStrictPositiveInt(0.1 + val)) for val in [0, 0.1, 0.9, -0.3]: - self.assertFalse(ht.TStrictPositiveInt(val)) + self.assertFalse(ht.TPositiveInt(val)) for val in range(1, 100, 4): - self.assertTrue(ht.TStrictPositiveInt(val)) - self.assertFalse(ht.TStrictPositiveInt(0.1 + val)) + self.assertTrue(ht.TPositiveInt(val)) + self.assertFalse(ht.TPositiveInt(0.1 + val)) def testFloat(self): for val in [-100.21, -3.0, 0.0, 16.12, 128.3433, 923874.928]: