Revision 914c6df4
b/src/Ganeti/HTools/CLI.hs | ||
---|---|---|
232 | 232 |
let sp = sepSplit ',' inp |
233 | 233 |
err = Bad ("Invalid " ++ descr ++ " specification: '" ++ inp ++ |
234 | 234 |
"', expected disk,ram,cpu") |
235 |
when (length sp /= 3) err
|
|
235 |
when (length sp < 3 || length sp > 4) err
|
|
236 | 236 |
prs <- mapM (\(fn, val) -> fn val) $ |
237 | 237 |
zip [ annotateResult (descr ++ " specs disk") . parseUnit |
238 | 238 |
, annotateResult (descr ++ " specs memory") . parseUnit |
239 | 239 |
, tryRead (descr ++ " specs cpus") |
240 |
, tryRead (descr ++ " specs spindles") |
|
240 | 241 |
] sp |
241 | 242 |
case prs of |
242 |
[dsk, ram, cpu] -> return $ RSpec cpu ram dsk |
|
243 |
{- Spindles are optional, so that they are not needed when exclusive storage |
|
244 |
is disabled. When exclusive storage is disabled, spindles are ignored, |
|
245 |
so the actual value doesn't matter. We use 1 as a default so that in |
|
246 |
case someone forgets and exclusive storage is enabled, we don't run into |
|
247 |
weird situations. -} |
|
248 |
[dsk, ram, cpu] -> return $ RSpec cpu ram dsk 1 |
|
249 |
[dsk, ram, cpu, spn] -> return $ RSpec cpu ram dsk spn |
|
243 | 250 |
_ -> err |
244 | 251 |
|
245 | 252 |
-- | Disk template choices. |
b/src/Ganeti/HTools/Instance.hs | ||
---|---|---|
274 | 274 |
|
275 | 275 |
-- | Return the spec of an instance. |
276 | 276 |
specOf :: Instance -> T.RSpec |
277 |
specOf Instance { mem = m, dsk = d, vcpus = c } = |
|
278 |
T.RSpec { T.rspecCpu = c, T.rspecMem = m, T.rspecDsk = d } |
|
277 |
specOf Instance { mem = m, dsk = d, vcpus = c, disks = dl } = |
|
278 |
let sp = case dl of |
|
279 |
[Disk _ (Just sp')] -> sp' |
|
280 |
_ -> 0 |
|
281 |
in T.RSpec { T.rspecCpu = c, T.rspecMem = m, |
|
282 |
T.rspecDsk = d, T.rspecSpn = sp } |
|
279 | 283 |
|
280 | 284 |
-- | Checks if an instance is smaller/bigger than a given spec. Returns |
281 | 285 |
-- OpGood for a correct spec, otherwise Bad one of the possible |
b/src/Ganeti/HTools/Program/Hspace.hs | ||
---|---|---|
396 | 396 |
instFromSpec :: RSpec -> DiskTemplate -> Int -> Instance.Instance |
397 | 397 |
instFromSpec spx dt su = |
398 | 398 |
Instance.create "new" (rspecMem spx) (rspecDsk spx) |
399 |
[Instance.Disk (rspecDsk spx) (Just su)]
|
|
399 |
[Instance.Disk (rspecDsk spx) (Just $ rspecSpn spx)]
|
|
400 | 400 |
(rspecCpu spx) Running [] True (-1) (-1) dt su [] |
401 | 401 |
|
402 | 402 |
combineTiered :: Maybe Int -> Cluster.AllocNodes -> Cluster.AllocResult -> |
b/src/Ganeti/HTools/Types.hs | ||
---|---|---|
142 | 142 |
{ rspecCpu :: Int -- ^ Requested VCPUs |
143 | 143 |
, rspecMem :: Int -- ^ Requested memory |
144 | 144 |
, rspecDsk :: Int -- ^ Requested disk |
145 |
, rspecSpn :: Int -- ^ Requested spindles |
|
145 | 146 |
} deriving (Show, Eq) |
146 | 147 |
|
147 | 148 |
-- | Allocation stats type. This is used instead of 'RSpec' (which was |
... | ... | |
232 | 233 |
rspecFromISpec ispec = RSpec { rspecCpu = iSpecCpuCount ispec |
233 | 234 |
, rspecMem = iSpecMemorySize ispec |
234 | 235 |
, rspecDsk = iSpecDiskSize ispec |
236 |
, rspecSpn = iSpecSpindleUse ispec |
|
235 | 237 |
} |
236 | 238 |
|
237 | 239 |
-- | The default instance policy. |
b/test/hs/Test/Ganeti/HTools/CLI.hs | ||
---|---|---|
47 | 47 |
{-# ANN module "HLint: ignore Use camelCase" #-} |
48 | 48 |
|
49 | 49 |
-- | Test correct parsing. |
50 |
prop_parseISpec :: String -> Int -> Int -> Int -> Property |
|
51 |
prop_parseISpec descr dsk mem cpu = |
|
52 |
let str = printf "%d,%d,%d" dsk mem cpu::String |
|
53 |
in parseISpecString descr str ==? Ok (Types.RSpec cpu mem dsk) |
|
50 |
prop_parseISpec :: String -> Int -> Int -> Int -> Maybe Int -> Property |
|
51 |
prop_parseISpec descr dsk mem cpu spn = |
|
52 |
let (str, spn') = case spn of |
|
53 |
Nothing -> (printf "%d,%d,%d" dsk mem cpu::String, 1) |
|
54 |
Just spn'' -> |
|
55 |
(printf "%d,%d,%d,%d" dsk mem cpu spn''::String, spn'') |
|
56 |
in parseISpecString descr str ==? Ok (Types.RSpec cpu mem dsk spn') |
|
54 | 57 |
|
55 | 58 |
-- | Test parsing failure due to wrong section count. |
56 | 59 |
prop_parseISpecFail :: String -> Property |
57 | 60 |
prop_parseISpecFail descr = |
58 |
forAll (choose (0,100) `suchThat` (/= 3)) $ \nelems ->
|
|
61 |
forAll (choose (0,100) `suchThat` (not . flip elem [3, 4])) $ \nelems ->
|
|
59 | 62 |
forAll (replicateM nelems arbitrary) $ \values -> |
60 | 63 |
let str = intercalate "," $ map show (values::[Int]) |
61 | 64 |
in case parseISpecString descr str of |
Also available in: Unified diff