Revision 22278fa7
b/htest/Test/Ganeti/Common.hs | ||
---|---|---|
64 | 64 |
cmdarg:_ -> |
65 | 65 |
case parseOptsInner defaults |
66 | 66 |
["--" ++ cmdarg ++ maybe "" ("=" ++) (repr val)] |
67 |
"prog" [opt] of |
|
67 |
"prog" [opt] [] of
|
|
68 | 68 |
Left e -> failfn $ "Failed to parse option '" ++ cmdarg ++ ": " ++ |
69 | 69 |
show e |
70 | 70 |
Right (options, _) -> eqcheck ("Wrong value in option " ++ |
... | ... | |
83 | 83 |
let prefix = "--" ++ head longs ++ "=" |
84 | 84 |
good_cmd = prefix ++ good |
85 | 85 |
bad_cmd = prefix ++ bad in |
86 |
case (parseOptsInner defaults [bad_cmd] "prog" [opt], |
|
87 |
parseOptsInner defaults [good_cmd] "prog" [opt]) of |
|
86 |
case (parseOptsInner defaults [bad_cmd] "prog" [opt] [],
|
|
87 |
parseOptsInner defaults [good_cmd] "prog" [opt] []) of
|
|
88 | 88 |
(Left _, Right _) -> passfn |
89 | 89 |
(Right _, Right _) -> failfn $ "Command line '" ++ bad_cmd ++ |
90 | 90 |
"' succeeded when it shouldn't" |
... | ... | |
97 | 97 |
|
98 | 98 |
-- | Helper to test that a given option is accepted OK with quick exit. |
99 | 99 |
checkEarlyExit :: (StandardOptions a) => |
100 |
a -> String -> [GenericOptType a] -> Assertion |
|
101 |
checkEarlyExit defaults name options = |
|
100 |
a -> String -> [GenericOptType a] -> [ArgCompletion] |
|
101 |
-> Assertion |
|
102 |
checkEarlyExit defaults name options arguments = |
|
102 | 103 |
mapM_ (\param -> |
103 |
case parseOptsInner defaults [param] name options of |
|
104 |
case parseOptsInner defaults [param] name options arguments of
|
|
104 | 105 |
Left (code, _) -> |
105 | 106 |
assertEqual ("Program " ++ name ++ |
106 | 107 |
" returns invalid code " ++ show code ++ |
b/htest/Test/Ganeti/Daemon.hs | ||
---|---|---|
76 | 76 |
-- | Test that the option list supports some common options. |
77 | 77 |
case_stdopts :: Assertion |
78 | 78 |
case_stdopts = |
79 |
checkEarlyExit defaultOptions "prog" [oShowHelp, oShowVer] |
|
79 |
checkEarlyExit defaultOptions "prog" [oShowHelp, oShowVer] []
|
|
80 | 80 |
|
81 | 81 |
testSuite "Daemon" |
82 | 82 |
[ 'prop_string_arg |
b/htest/Test/Ganeti/HTools/CLI.hs | ||
---|---|---|
118 | 118 |
-- | Test that all binaries support some common options. |
119 | 119 |
case_stdopts :: Assertion |
120 | 120 |
case_stdopts = |
121 |
mapM_ (\(name, (_, o)) -> checkEarlyExit defaultOptions name |
|
122 |
(o ++ genericOpts)) Program.personalities
|
|
121 |
mapM_ (\(name, (_, o, a)) -> checkEarlyExit defaultOptions name
|
|
122 |
(o ++ genericOpts) a) Program.personalities
|
|
123 | 123 |
|
124 | 124 |
testSuite "HTools/CLI" |
125 | 125 |
[ 'prop_parseISpec |
b/htools/Ganeti/Common.hs | ||
---|---|---|
183 | 183 |
-> [String] -- ^ The command line arguments |
184 | 184 |
-> String -- ^ The program name |
185 | 185 |
-> [GenericOptType a] -- ^ The supported command line options |
186 |
-> [ArgCompletion] -- ^ The supported command line arguments |
|
186 | 187 |
-> IO (a, [String]) -- ^ The resulting options and |
187 | 188 |
-- leftover arguments |
188 |
parseOpts defaults argv progname options = |
|
189 |
case parseOptsInner defaults argv progname options of |
|
189 |
parseOpts defaults argv progname options arguments =
|
|
190 |
case parseOptsInner defaults argv progname options arguments of
|
|
190 | 191 |
Left (code, msg) -> do |
191 | 192 |
hPutStr (if code == ExitSuccess then stdout else stderr) msg |
192 | 193 |
exitWith code |
... | ... | |
201 | 202 |
-> [String] |
202 | 203 |
-> String |
203 | 204 |
-> [GenericOptType a] |
205 |
-> [ArgCompletion] |
|
204 | 206 |
-> Either (ExitCode, String) (a, [String]) |
205 |
parseOptsInner defaults argv progname options = |
|
207 |
parseOptsInner defaults argv progname options arguments =
|
|
206 | 208 |
case getOpt Permute (map fst options) argv of |
207 | 209 |
(opts, args, []) -> |
208 | 210 |
case foldM (flip id) defaults opts of |
... | ... | |
216 | 218 |
, (verRequested parsed, |
217 | 219 |
Left (ExitSuccess, versionInfo progname)) |
218 | 220 |
, (compRequested parsed, |
219 |
Left (ExitSuccess, completionInfo progname options [])) |
|
221 |
Left (ExitSuccess, completionInfo progname options |
|
222 |
arguments)) |
|
220 | 223 |
] |
221 | 224 |
(_, _, errs) -> |
222 | 225 |
Left (ExitFailure 2, "Command line error: " ++ concat errs ++ "\n" ++ |
b/htools/Ganeti/Daemon.hs | ||
---|---|---|
176 | 176 |
parseArgs :: String -> [OptType] -> IO (DaemonOptions, [String]) |
177 | 177 |
parseArgs cmd options = do |
178 | 178 |
cmd_args <- getArgs |
179 |
parseOpts defaultOptions cmd_args cmd $ options ++ genericOpts
|
|
179 |
parseOpts defaultOptions cmd_args cmd (options ++ genericOpts) []
|
|
180 | 180 |
|
181 | 181 |
-- * Daemon-related functions |
182 | 182 |
-- | PID file mode. |
b/htools/Ganeti/HTools/CLI.hs | ||
---|---|---|
526 | 526 |
parseOpts :: [String] -- ^ The command line arguments |
527 | 527 |
-> String -- ^ The program name |
528 | 528 |
-> [OptType] -- ^ The supported command line options |
529 |
-> [ArgCompletion] -- ^ The supported command line arguments |
|
529 | 530 |
-> IO (Options, [String]) -- ^ The resulting options and leftover |
530 | 531 |
-- arguments |
531 | 532 |
parseOpts = Common.parseOpts defaultOptions |
b/htools/Ganeti/HTools/Program.hs | ||
---|---|---|
27 | 27 |
( personalities |
28 | 28 |
) where |
29 | 29 |
|
30 |
import Ganeti.Common (ArgCompletion) |
|
30 | 31 |
import Ganeti.HTools.CLI (OptType, Options) |
31 | 32 |
|
32 | 33 |
import qualified Ganeti.HTools.Program.Hail as Hail |
... | ... | |
37 | 38 |
import qualified Ganeti.HTools.Program.Hinfo as Hinfo |
38 | 39 |
|
39 | 40 |
-- | Supported binaries. |
40 |
personalities :: [(String, (Options -> [String] -> IO (), [OptType]))] |
|
41 |
personalities = [ ("hail", (Hail.main, Hail.options)) |
|
42 |
, ("hbal", (Hbal.main, Hbal.options)) |
|
43 |
, ("hcheck", (Hcheck.main, Hcheck.options)) |
|
44 |
, ("hscan", (Hscan.main, Hscan.options)) |
|
45 |
, ("hspace", (Hspace.main, Hspace.options)) |
|
46 |
, ("hinfo", (Hinfo.main, Hinfo.options)) |
|
41 |
personalities :: [(String, |
|
42 |
(Options -> [String] -> IO (), [OptType], [ArgCompletion]))] |
|
43 |
personalities = [ ("hail", (Hail.main, Hail.options, Hail.arguments)) |
|
44 |
, ("hbal", (Hbal.main, Hbal.options, Hbal.arguments)) |
|
45 |
, ("hcheck", (Hcheck.main, Hcheck.options, Hcheck.arguments)) |
|
46 |
, ("hscan", (Hscan.main, Hscan.options, Hscan.arguments )) |
|
47 |
, ("hspace", (Hspace.main, Hspace.options, Hspace.arguments)) |
|
48 |
, ("hinfo", (Hinfo.main, Hinfo.options, Hinfo.arguments)) |
|
47 | 49 |
] |
b/htools/Ganeti/HTools/Program/Hail.hs | ||
---|---|---|
23 | 23 |
|
24 | 24 |
-} |
25 | 25 |
|
26 |
module Ganeti.HTools.Program.Hail (main, options) where |
|
26 |
module Ganeti.HTools.Program.Hail |
|
27 |
( main |
|
28 |
, options |
|
29 |
, arguments |
|
30 |
) where |
|
27 | 31 |
|
28 | 32 |
import Control.Monad |
29 | 33 |
import Data.Maybe (fromMaybe, isJust) |
... | ... | |
32 | 36 |
|
33 | 37 |
import qualified Ganeti.HTools.Cluster as Cluster |
34 | 38 |
|
39 |
import Ganeti.Common |
|
35 | 40 |
import Ganeti.HTools.CLI |
36 | 41 |
import Ganeti.HTools.IAlloc |
37 | 42 |
import Ganeti.HTools.Loader (Request(..), ClusterData(..)) |
... | ... | |
47 | 52 |
, oVerbose |
48 | 53 |
] |
49 | 54 |
|
55 |
-- | The list of arguments supported by the program. |
|
56 |
arguments :: [ArgCompletion] |
|
57 |
arguments = [ArgCompletion OptComplFile 1 (Just 1)] |
|
58 |
|
|
50 | 59 |
wrapReadRequest :: Options -> [String] -> IO Request |
51 | 60 |
wrapReadRequest opts args = do |
52 | 61 |
when (null args) $ do |
b/htools/Ganeti/HTools/Program/Hbal.hs | ||
---|---|---|
24 | 24 |
-} |
25 | 25 |
|
26 | 26 |
module Ganeti.HTools.Program.Hbal |
27 |
( main |
|
28 |
, options |
|
29 |
, iterateDepth |
|
30 |
) where |
|
27 |
( main |
|
28 |
, options |
|
29 |
, arguments |
|
30 |
, iterateDepth |
|
31 |
) where |
|
31 | 32 |
|
32 | 33 |
import Control.Concurrent (threadDelay) |
33 | 34 |
import Control.Exception (bracket) |
... | ... | |
48 | 49 |
import qualified Ganeti.HTools.Node as Node |
49 | 50 |
import qualified Ganeti.HTools.Instance as Instance |
50 | 51 |
|
52 |
import Ganeti.Common |
|
51 | 53 |
import Ganeti.HTools.CLI |
52 | 54 |
import Ganeti.HTools.ExtLoader |
53 | 55 |
import Ganeti.HTools.Types |
... | ... | |
88 | 90 |
, oSaveCluster |
89 | 91 |
] |
90 | 92 |
|
93 |
-- | The list of arguments supported by the program. |
|
94 |
arguments :: [ArgCompletion] |
|
95 |
arguments = [] |
|
96 |
|
|
91 | 97 |
{- | Start computing the solution at the given depth and recurse until |
92 | 98 |
we find a valid solution or we exceed the maximum depth. |
93 | 99 |
|
b/htools/Ganeti/HTools/Program/Hcheck.hs | ||
---|---|---|
23 | 23 |
|
24 | 24 |
-} |
25 | 25 |
|
26 |
module Ganeti.HTools.Program.Hcheck (main, options) where |
|
26 |
module Ganeti.HTools.Program.Hcheck |
|
27 |
( main |
|
28 |
, options |
|
29 |
, arguments |
|
30 |
) where |
|
27 | 31 |
|
28 | 32 |
import Control.Monad |
29 | 33 |
import Data.List (transpose) |
... | ... | |
39 | 43 |
|
40 | 44 |
import qualified Ganeti.HTools.Program.Hbal as Hbal |
41 | 45 |
|
46 |
import Ganeti.Common |
|
42 | 47 |
import Ganeti.HTools.CLI |
43 | 48 |
import Ganeti.HTools.ExtLoader |
44 | 49 |
import Ganeti.HTools.Loader |
... | ... | |
71 | 76 |
, oVerbose |
72 | 77 |
] |
73 | 78 |
|
79 |
-- | The list of arguments supported by the program. |
|
80 |
arguments :: [ArgCompletion] |
|
81 |
arguments = [] |
|
82 |
|
|
74 | 83 |
-- | Check phase - are we before (initial) or after rebalance. |
75 | 84 |
data Phase = Initial |
76 | 85 |
| Rebalanced |
b/htools/Ganeti/HTools/Program/Hinfo.hs | ||
---|---|---|
23 | 23 |
|
24 | 24 |
-} |
25 | 25 |
|
26 |
module Ganeti.HTools.Program.Hinfo (main, options) where |
|
26 |
module Ganeti.HTools.Program.Hinfo |
|
27 |
( main |
|
28 |
, options |
|
29 |
, arguments |
|
30 |
) where |
|
27 | 31 |
|
28 | 32 |
import Control.Monad |
29 | 33 |
import Data.List |
... | ... | |
38 | 42 |
import qualified Ganeti.HTools.Group as Group |
39 | 43 |
import qualified Ganeti.HTools.Instance as Instance |
40 | 44 |
|
45 |
import Ganeti.Common |
|
41 | 46 |
import Ganeti.HTools.CLI |
42 | 47 |
import Ganeti.HTools.ExtLoader |
43 | 48 |
import Ganeti.HTools.Loader |
... | ... | |
57 | 62 |
, oOfflineNode |
58 | 63 |
] |
59 | 64 |
|
65 |
-- | The list of arguments supported by the program. |
|
66 |
arguments :: [ArgCompletion] |
|
67 |
arguments = [] |
|
68 |
|
|
60 | 69 |
-- | Group information data-type. |
61 | 70 |
data GroupInfo = GroupInfo { giName :: String |
62 | 71 |
, giNodeCount :: Int |
b/htools/Ganeti/HTools/Program/Hscan.hs | ||
---|---|---|
23 | 23 |
|
24 | 24 |
-} |
25 | 25 |
|
26 |
module Ganeti.HTools.Program.Hscan (main, options) where |
|
26 |
module Ganeti.HTools.Program.Hscan |
|
27 |
( main |
|
28 |
, options |
|
29 |
, arguments |
|
30 |
) where |
|
27 | 31 |
|
28 | 32 |
import Control.Monad |
29 | 33 |
import Data.Maybe (isJust, fromJust, fromMaybe) |
... | ... | |
43 | 47 |
import Ganeti.HTools.Loader (checkData, mergeData, ClusterData(..)) |
44 | 48 |
import Ganeti.HTools.Text (serializeCluster) |
45 | 49 |
|
50 |
import Ganeti.Common |
|
46 | 51 |
import Ganeti.HTools.CLI |
47 | 52 |
import Ganeti.HTools.Types |
48 | 53 |
|
... | ... | |
56 | 61 |
, oNoHeaders |
57 | 62 |
] |
58 | 63 |
|
64 |
-- | The list of arguments supported by the program. |
|
65 |
arguments :: [ArgCompletion] |
|
66 |
arguments = [ArgCompletion OptComplHost 0 Nothing] |
|
67 |
|
|
59 | 68 |
-- | Return a one-line summary of cluster state. |
60 | 69 |
printCluster :: Node.List -> Instance.List |
61 | 70 |
-> String |
b/htools/Ganeti/HTools/Program/Hspace.hs | ||
---|---|---|
23 | 23 |
|
24 | 24 |
-} |
25 | 25 |
|
26 |
module Ganeti.HTools.Program.Hspace (main, options) where |
|
26 |
module Ganeti.HTools.Program.Hspace |
|
27 |
(main |
|
28 |
, options |
|
29 |
, arguments |
|
30 |
) where |
|
27 | 31 |
|
28 | 32 |
import Control.Monad |
29 | 33 |
import Data.Char (toUpper, toLower) |
... | ... | |
40 | 44 |
import qualified Ganeti.HTools.Node as Node |
41 | 45 |
import qualified Ganeti.HTools.Instance as Instance |
42 | 46 |
|
47 |
import Ganeti.Common |
|
43 | 48 |
import Ganeti.HTools.Types |
44 | 49 |
import Ganeti.HTools.CLI |
45 | 50 |
import Ganeti.HTools.ExtLoader |
... | ... | |
69 | 74 |
, oSaveCluster |
70 | 75 |
] |
71 | 76 |
|
77 |
-- | The list of arguments supported by the program. |
|
78 |
arguments :: [ArgCompletion] |
|
79 |
arguments = [] |
|
80 |
|
|
72 | 81 |
-- | The allocation phase we're in (initial, after tiered allocs, or |
73 | 82 |
-- after regular allocation). |
74 | 83 |
data Phase = PInitial |
b/htools/htools.hs | ||
---|---|---|
57 | 57 |
boolnames = map (\(x, y) -> (x == name, Just y)) personalities |
58 | 58 |
case select Nothing boolnames of |
59 | 59 |
Nothing -> usage name |
60 |
Just (fn, options) -> do |
|
60 |
Just (fn, options, arguments) -> do
|
|
61 | 61 |
cmd_args <- getArgs |
62 |
(opts, args) <- parseOpts cmd_args name $ options ++ genericOpts |
|
62 |
(opts, args) <- parseOpts cmd_args name (options ++ genericOpts) |
|
63 |
arguments |
|
63 | 64 |
fn opts args |
Also available in: Unified diff