Check the full instance specs in htools
authorBernardo Dal Seno <bdalseno@google.com>
Wed, 29 May 2013 18:50:42 +0000 (20:50 +0200)
committerBernardo Dal Seno <bdalseno@google.com>
Mon, 3 Jun 2013 13:15:29 +0000 (15:15 +0200)
Spindles and disk count are checked too. Existing functions have been
refactored, so common parts are not duplicated.

Signed-off-by: Bernardo Dal Seno <bdalseno@google.com>
Reviewed-by: Klaus Aehlig <aehlig@google.com>

src/Ganeti/HTools/Instance.hs
src/Ganeti/HTools/Types.hs

index b3dce08..44c5afd 100644 (file)
@@ -275,23 +275,29 @@ specOf :: Instance -> T.RSpec
 specOf Instance { mem = m, dsk = d, vcpus = c } =
   T.RSpec { T.rspecCpu = c, T.rspecMem = m, T.rspecDsk = d }
 
--- | Checks if an instance is smaller than a given spec. Returns
+-- | Checks if an instance is smaller/bigger than a given spec. Returns
 -- OpGood for a correct spec, otherwise Bad one of the possible
 -- failure modes.
-instBelowISpec :: Instance -> T.ISpec -> T.OpResult ()
-instBelowISpec inst ispec
-  | mem inst > T.iSpecMemorySize ispec = Bad T.FailMem
-  | any (> T.iSpecDiskSize ispec) (map dskSize $ disks inst) = Bad T.FailDisk
-  | vcpus inst > T.iSpecCpuCount ispec = Bad T.FailCPU
+instCompareISpec :: Ordering -> Instance-> T.ISpec -> T.OpResult ()
+instCompareISpec which inst ispec
+  | which == mem inst `compare` T.iSpecMemorySize ispec = Bad T.FailMem
+  | which `elem` map ((`compare` T.iSpecDiskSize ispec) . dskSize)
+    (disks inst) = Bad T.FailDisk
+  | which == vcpus inst `compare` T.iSpecCpuCount ispec = Bad T.FailCPU
+  | which == spindleUse inst `compare` T.iSpecSpindleUse ispec
+    = Bad T.FailSpindles
+  | diskTemplate inst /= T.DTDiskless &&
+    which == length (disks inst) `compare` T.iSpecDiskCount ispec
+    = Bad T.FailDiskCount
   | otherwise = Ok ()
 
+-- | Checks if an instance is smaller than a given spec.
+instBelowISpec :: Instance -> T.ISpec -> T.OpResult ()
+instBelowISpec = instCompareISpec GT
+
 -- | Checks if an instance is bigger than a given spec.
 instAboveISpec :: Instance -> T.ISpec -> T.OpResult ()
-instAboveISpec inst ispec
-  | mem inst < T.iSpecMemorySize ispec = Bad T.FailMem
-  | any (< T.iSpecDiskSize ispec) (map dskSize $ disks inst) = Bad T.FailDisk
-  | vcpus inst < T.iSpecCpuCount ispec = Bad T.FailCPU
-  | otherwise = Ok ()
+instAboveISpec = instCompareISpec LT
 
 -- | Checks if an instance matches a min/max specs pair
 instMatchesMinMaxSpecs :: Instance -> T.MinMaxISpecs -> T.OpResult ()
@@ -303,11 +309,11 @@ instMatchesMinMaxSpecs inst minmax = do
 instMatchesSpecs :: Instance -> [T.MinMaxISpecs] -> T.OpResult ()
  -- Return Ok for no constraints, though this should never happen
 instMatchesSpecs _ [] = Ok ()
-instMatchesSpecs inst (minmax:minmaxes) =
-  foldr eithermatch (instMatchesMinMaxSpecs inst minmax) minmaxes
+instMatchesSpecs inst minmaxes =
+  -- The initial "Bad" should be always replaced by a real result
+  foldr eithermatch (Bad T.FailInternal) minmaxes
   where eithermatch mm (Bad _) = instMatchesMinMaxSpecs inst mm
         eithermatch _ y@(Ok ()) = y
---  # See 04f231771
 
 -- | Checks if an instance matches a policy.
 instMatchesPolicy :: Instance -> T.IPolicy -> T.OpResult ()
index 21d7ee1..af533dc 100644 (file)
@@ -323,6 +323,9 @@ data FailMode = FailMem  -- ^ Failed due to not enough RAM
               | FailCPU  -- ^ Failed due to not enough CPU capacity
               | FailN1   -- ^ Failed due to not passing N1 checks
               | FailTags -- ^ Failed due to tag exclusion
+              | FailDiskCount -- ^ Failed due to wrong number of disks
+              | FailSpindles -- ^ Failed due to wrong/missing spindles
+              | FailInternal -- ^ Internal error
                 deriving (Eq, Enum, Bounded, Show)
 
 -- | List with failure statistics.