Revision e0eb63f0
b/Ganeti/HTools/CLI.hs | ||
---|---|---|
10 | 10 |
( |
11 | 11 |
parseOpts |
12 | 12 |
, showVersion |
13 |
, shTemplate |
|
13 | 14 |
) where |
14 | 15 |
|
15 | 16 |
import System.Console.GetOpt |
... | ... | |
54 | 55 |
name Version.version |
55 | 56 |
compilerName (Data.Version.showVersion compilerVersion) |
56 | 57 |
os arch |
58 |
|
|
59 |
-- | A shell script template for autogenerated scripts |
|
60 |
shTemplate :: String |
|
61 |
shTemplate = |
|
62 |
printf "#!/bin/sh\n\n\ |
|
63 |
\# Auto-generated script for executing cluster rebalancing\n\n\ |
|
64 |
\# To stop, touch the file /tmp/stop-htools\n\n\ |
|
65 |
\set -e\n\n\ |
|
66 |
\check() {\n\ |
|
67 |
\ if [ -f /tmp/stop-htools ]; then\n\ |
|
68 |
\ echo 'Stop requested, exiting'\n\ |
|
69 |
\ exit 0\n\ |
|
70 |
\ fi\n\ |
|
71 |
\}\n\n" |
b/Ganeti/HTools/Cluster.hs | ||
---|---|---|
563 | 563 |
else |
564 | 564 |
if c == b then {- Failover and ... -} |
565 | 565 |
if d == a then {- that's all -} |
566 |
("f", [printf "migrate %s" i]) |
|
566 |
("f", [printf "migrate -f %s" i])
|
|
567 | 567 |
else |
568 | 568 |
(printf "f r:%s" d, |
569 |
[printf "migrate %s" i, |
|
569 |
[printf "migrate -f %s" i,
|
|
570 | 570 |
printf "replace-disks -n %s %s" d i]) |
571 | 571 |
else |
572 | 572 |
if d == a then {- ... and keep primary as secondary -} |
573 | 573 |
(printf "r:%s f" c, |
574 | 574 |
[printf "replace-disks -n %s %s" c i, |
575 |
printf "migrate %s" i]) |
|
575 |
printf "migrate -f %s" i])
|
|
576 | 576 |
else |
577 | 577 |
if d == b then {- ... keep same secondary -} |
578 | 578 |
(printf "f r:%s f" c, |
579 |
[printf "migrate %s" i, |
|
579 |
[printf "migrate -f %s" i,
|
|
580 | 580 |
printf "replace-disks -n %s %s" c i, |
581 |
printf "migrate %s" i]) |
|
581 |
printf "migrate -f %s" i])
|
|
582 | 582 |
|
583 | 583 |
else {- Nothing in common -} |
584 | 584 |
(printf "r:%s f r:%s" c d, |
585 | 585 |
[printf "replace-disks -n %s %s" c i, |
586 |
printf "migrate %s" i, |
|
586 |
printf "migrate -f %s" i,
|
|
587 | 587 |
printf "replace-disks -n %s %s" d i]) |
588 | 588 |
|
589 | 589 |
{-| Converts a placement to string format -} |
... | ... | |
616 | 616 |
|
617 | 617 |
formatCmds :: [[String]] -> String |
618 | 618 |
formatCmds cmd_strs = |
619 |
unlines $ map (" echo " ++) $
|
|
619 |
unlines $ |
|
620 | 620 |
concat $ map (\(a, b) -> |
621 |
(printf "step %d" (a::Int)):(map ("gnt-instance " ++) b)) $ |
|
621 |
(printf "echo step %d" (a::Int)): |
|
622 |
(printf "check"): |
|
623 |
(map ("gnt-instance " ++) b)) $ |
|
622 | 624 |
zip [1..] cmd_strs |
623 | 625 |
|
624 | 626 |
{-| Converts a solution to string format -} |
b/hbal.hs | ||
---|---|---|
6 | 6 |
|
7 | 7 |
import Data.List |
8 | 8 |
import Data.Function |
9 |
import Data.Maybe (isJust, fromJust, fromMaybe) |
|
9 | 10 |
import Monad |
10 | 11 |
import System |
11 | 12 |
import System.IO |
... | ... | |
23 | 24 |
|
24 | 25 |
-- | Command line options structure. |
25 | 26 |
data Options = Options |
26 |
{ optShowNodes :: Bool -- ^ Whether to show node status |
|
27 |
, optShowCmds :: Bool -- ^ Whether to show the command list
|
|
28 |
, optOneline :: Bool -- ^ Switch output to a single line |
|
29 |
, optNodef :: FilePath -- ^ Path to the nodes file |
|
30 |
, optInstf :: FilePath -- ^ Path to the instances file |
|
31 |
, optMaxLength :: Int -- ^ Stop after this many steps |
|
32 |
, optMaster :: String -- ^ Collect data from RAPI |
|
33 |
, optVerbose :: Int -- ^ Verbosity level |
|
34 |
, optOffline :: [String] -- ^ Names of offline nodes |
|
35 |
, optShowVer :: Bool -- ^ Just show the program version |
|
36 |
, optShowHelp :: Bool -- ^ Just show the help |
|
27 |
{ optShowNodes :: Bool -- ^ Whether to show node status
|
|
28 |
, optShowCmds :: Maybe FilePath -- ^ Whether to show the command list
|
|
29 |
, optOneline :: Bool -- ^ Switch output to a single line
|
|
30 |
, optNodef :: FilePath -- ^ Path to the nodes file
|
|
31 |
, optInstf :: FilePath -- ^ Path to the instances file
|
|
32 |
, optMaxLength :: Int -- ^ Stop after this many steps
|
|
33 |
, optMaster :: String -- ^ Collect data from RAPI
|
|
34 |
, optVerbose :: Int -- ^ Verbosity level
|
|
35 |
, optOffline :: [String] -- ^ Names of offline nodes
|
|
36 |
, optShowVer :: Bool -- ^ Just show the program version
|
|
37 |
, optShowHelp :: Bool -- ^ Just show the help
|
|
37 | 38 |
} deriving Show |
38 | 39 |
|
39 | 40 |
-- | Default values for the command line options. |
40 | 41 |
defaultOptions :: Options |
41 | 42 |
defaultOptions = Options |
42 | 43 |
{ optShowNodes = False |
43 |
, optShowCmds = False
|
|
44 |
, optShowCmds = Nothing
|
|
44 | 45 |
, optOneline = False |
45 | 46 |
, optNodef = "nodes" |
46 | 47 |
, optInstf = "instances" |
... | ... | |
59 | 60 |
(NoArg (\ opts -> opts { optShowNodes = True })) |
60 | 61 |
"print the final node list" |
61 | 62 |
, Option ['C'] ["print-commands"] |
62 |
(NoArg (\ opts -> opts { optShowCmds = True })) |
|
63 |
"print the ganeti command list for reaching the solution" |
|
63 |
(OptArg ((\ f opts -> opts { optShowCmds = Just f }) . fromMaybe "-") |
|
64 |
"FILE") |
|
65 |
"print the ganeti command list for reaching the solution,\ |
|
66 |
\if an argument is passed then write the commands to a file named\ |
|
67 |
\ as such" |
|
64 | 68 |
, Option ['o'] ["oneline"] |
65 | 69 |
(NoArg (\ opts -> opts { optOneline = True })) |
66 | 70 |
"print the ganeti command list for reaching the solution" |
... | ... | |
226 | 230 |
unless (oneline || verbose == 0) $ |
227 | 231 |
printf "Solution length=%d\n" (length ord_plc) |
228 | 232 |
|
229 |
when (optShowCmds opts) $ |
|
233 |
let cmd_data = Cluster.formatCmds . reverse $ cmd_strs |
|
234 |
|
|
235 |
when (isJust $ optShowCmds opts) $ |
|
230 | 236 |
do |
237 |
let out_path = fromJust $ optShowCmds opts |
|
231 | 238 |
putStrLn "" |
232 |
putStrLn "Commands to run to reach the above solution:" |
|
233 |
putStr . Cluster.formatCmds . reverse $ cmd_strs |
|
239 |
(if out_path == "-" then |
|
240 |
printf "Commands to run to reach the above solution:\n%s" |
|
241 |
(unlines . map (" " ++) . |
|
242 |
filter (/= "check") . |
|
243 |
lines $ cmd_data) |
|
244 |
else do |
|
245 |
writeFile out_path (CLI.shTemplate ++ cmd_data) |
|
246 |
printf "The commands have been written to file '%s'\n" out_path) |
|
247 |
|
|
234 | 248 |
when (optShowNodes opts) $ |
235 | 249 |
do |
236 | 250 |
let (orig_mem, orig_disk) = Cluster.totalResources nl |
Also available in: Unified diff