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