Revision 1f9066c0

b/Ganeti/HTools/CLI.hs
58 58
    , oMinDisk
59 59
    , oDiskMoves
60 60
    , oDynuFile
61
    , oTieredSpec
61 62
    , oShowVer
62 63
    , oShowHelp
63 64
    ) where
......
73 74

  
74 75
import qualified Ganeti.HTools.Version as Version(version)
75 76
import Ganeti.HTools.Types
77
import Ganeti.HTools.Utils
76 78

  
77 79
-- | The default value for the luxi socket
78 80
defaultLuxiSocket :: FilePath
......
80 82

  
81 83
-- | Command line options structure.
82 84
data Options = Options
83
    { optShowNodes :: Bool           -- ^ Whether to show node status
84
    , optShowInsts :: Bool           -- ^ Whether to show the instance map
85
    , optShowCmds  :: Maybe FilePath -- ^ Whether to show the command list
86
    , optOneline   :: Bool           -- ^ Switch output to a single line
87
    , optOutPath   :: FilePath       -- ^ Path to the output directory
88
    , optNoHeaders :: Bool           -- ^ Do not show a header line
89
    , optNodeFile  :: FilePath       -- ^ Path to the nodes file
90
    , optNodeSet   :: Bool           -- ^ The nodes have been set by options
91
    , optInstFile  :: FilePath       -- ^ Path to the instances file
92
    , optInstSet   :: Bool           -- ^ The insts have been set by options
93
    , optNodeSim   :: Maybe String   -- ^ Cluster simulation mode
94
    , optMaxLength :: Int            -- ^ Stop after this many steps
95
    , optMaster    :: String         -- ^ Collect data from RAPI
96
    , optLuxi      :: Maybe FilePath -- ^ Collect data from Luxi
97
    , optExecJobs  :: Bool           -- ^ Execute the commands via Luxi
98
    , optOffline   :: [String]       -- ^ Names of offline nodes
99
    , optIMem      :: Int            -- ^ Instance memory
100
    , optIDsk      :: Int            -- ^ Instance disk
101
    , optIVCPUs    :: Int            -- ^ Instance VCPUs
102
    , optINodes    :: Int            -- ^ Nodes required for an instance
103
    , optMinScore  :: Score          -- ^ The minimum score we aim for
104
    , optMcpu      :: Double         -- ^ Max cpu ratio for nodes
105
    , optMdsk      :: Double         -- ^ Max disk usage ratio for nodes
106
    , optDiskMoves :: Bool           -- ^ Allow disk moves
107
    , optDynuFile  :: Maybe FilePath -- ^ Optional file with dynamic use data
108
    , optVerbose   :: Int            -- ^ Verbosity level
109
    , optShowVer   :: Bool           -- ^ Just show the program version
110
    , optShowHelp  :: Bool           -- ^ Just show the help
85
    { optShowNodes   :: Bool           -- ^ Whether to show node status
86
    , optShowInsts   :: Bool           -- ^ Whether to show the instance map
87
    , optShowCmds    :: Maybe FilePath -- ^ Whether to show the command list
88
    , optOneline     :: Bool           -- ^ Switch output to a single line
89
    , optOutPath     :: FilePath       -- ^ Path to the output directory
90
    , optNoHeaders   :: Bool           -- ^ Do not show a header line
91
    , optNodeFile    :: FilePath       -- ^ Path to the nodes file
92
    , optNodeSet     :: Bool           -- ^ The nodes have been set by options
93
    , optInstFile    :: FilePath       -- ^ Path to the instances file
94
    , optInstSet     :: Bool           -- ^ The insts have been set by options
95
    , optNodeSim     :: Maybe String   -- ^ Cluster simulation mode
96
    , optMaxLength   :: Int            -- ^ Stop after this many steps
97
    , optMaster      :: String         -- ^ Collect data from RAPI
98
    , optLuxi        :: Maybe FilePath -- ^ Collect data from Luxi
99
    , optExecJobs    :: Bool           -- ^ Execute the commands via Luxi
100
    , optOffline     :: [String]       -- ^ Names of offline nodes
101
    , optINodes      :: Int            -- ^ Nodes required for an instance
102
    , optISpec       :: RSpec          -- ^ Requested instance specs
103
    , optTieredSpec  :: Maybe RSpec    -- ^ Requested specs for tiered mode
104
    , optMinScore    :: Score          -- ^ The minimum score we aim for
105
    , optMcpu        :: Double         -- ^ Max cpu ratio for nodes
106
    , optMdsk        :: Double         -- ^ Max disk usage ratio for nodes
107
    , optDiskMoves   :: Bool           -- ^ Allow disk moves
108
    , optDynuFile    :: Maybe FilePath -- ^ Optional file with dynamic use data
109
    , optVerbose     :: Int            -- ^ Verbosity level
110
    , optShowVer     :: Bool           -- ^ Just show the program version
111
    , optShowHelp    :: Bool           -- ^ Just show the help
111 112
    } deriving Show
112 113

  
113 114
-- | Default values for the command line options.
114 115
defaultOptions :: Options
115 116
defaultOptions  = Options
116
 { optShowNodes = False
117
 , optShowInsts = False
118
 , optShowCmds  = Nothing
119
 , optOneline   = False
120
 , optNoHeaders = False
121
 , optOutPath   = "."
122
 , optNodeFile  = "nodes"
123
 , optNodeSet   = False
124
 , optInstFile  = "instances"
125
 , optInstSet   = False
126
 , optNodeSim   = Nothing
127
 , optMaxLength = -1
128
 , optMaster    = ""
129
 , optLuxi      = Nothing
130
 , optExecJobs  = False
131
 , optOffline   = []
132
 , optIMem      = 4096
133
 , optIDsk      = 102400
134
 , optIVCPUs    = 1
135
 , optINodes    = 2
136
 , optMinScore  = 1e-9
137
 , optMcpu      = -1
138
 , optMdsk      = -1
139
 , optDiskMoves = True
140
 , optDynuFile  = Nothing
141
 , optVerbose   = 1
142
 , optShowVer   = False
143
 , optShowHelp  = False
117
 { optShowNodes   = False
118
 , optShowInsts   = False
119
 , optShowCmds    = Nothing
120
 , optOneline     = False
121
 , optNoHeaders   = False
122
 , optOutPath     = "."
123
 , optNodeFile    = "nodes"
124
 , optNodeSet     = False
125
 , optInstFile    = "instances"
126
 , optInstSet     = False
127
 , optNodeSim     = Nothing
128
 , optMaxLength   = -1
129
 , optMaster      = ""
130
 , optLuxi        = Nothing
131
 , optExecJobs    = False
132
 , optOffline     = []
133
 , optINodes      = 2
134
 , optISpec       = RSpec 1 4096 102400
135
 , optTieredSpec  = Nothing
136
 , optMinScore    = 1e-9
137
 , optMcpu        = -1
138
 , optMdsk        = -1
139
 , optDiskMoves   = True
140
 , optDynuFile    = Nothing
141
 , optVerbose     = 1
142
 , optShowVer     = False
143
 , optShowHelp    = False
144 144
 }
145 145

  
146 146
-- | Abrreviation for the option type
......
242 242

  
243 243
oIMem :: OptType
244 244
oIMem = Option "" ["memory"]
245
        (ReqArg (\ m opts -> Ok opts { optIMem = read m }) "MEMORY")
245
        (ReqArg (\ m opts ->
246
                     let ospec = optISpec opts
247
                         nspec = ospec { rspecMem = read m }
248
                     in Ok opts { optISpec = nspec }) "MEMORY")
246 249
        "memory size for instances"
247 250

  
248 251
oIDisk :: OptType
249 252
oIDisk = Option "" ["disk"]
250
         (ReqArg (\ d opts -> Ok opts { optIDsk = read d }) "DISK")
253
         (ReqArg (\ d opts ->
254
                     let ospec = optISpec opts
255
                         nspec = ospec { rspecDsk = read d }
256
                     in Ok opts { optISpec = nspec }) "DISK")
251 257
         "disk size for instances"
252 258

  
253 259
oIVcpus :: OptType
254 260
oIVcpus = Option "" ["vcpus"]
255
          (ReqArg (\ p opts -> Ok opts { optIVCPUs = read p }) "NUM")
261
          (ReqArg (\ p opts ->
262
                       let ospec = optISpec opts
263
                           nspec = ospec { rspecCpu = read p }
264
                       in Ok opts { optISpec = nspec }) "NUM")
256 265
          "number of virtual cpus for instances"
257 266

  
258 267
oINodes :: OptType
......
281 290
            (ReqArg (\ f opts -> Ok opts { optDynuFile = Just f }) "FILE")
282 291
            "Import dynamic utilisation data from the given FILE"
283 292

  
293
oTieredSpec :: OptType
294
oTieredSpec = Option "" ["tiered-alloc"]
295
             (ReqArg (\ inp opts -> do
296
                          let sp = sepSplit ',' inp
297
                          prs <- mapM (tryRead "tiered specs") sp
298
                          tspec <-
299
                              case prs of
300
                                [cpu, ram, dsk] -> return $ RSpec cpu ram dsk
301
                                _ -> Bad $ "Invalid specification: " ++ inp
302
                          return $ opts { optTieredSpec = Just tspec } )
303
              "TSPEC")
304
             "enable tiered specs allocation, where we decrease the instance\
305
             \ spec on failure to allocate and restart the allocation process"
306

  
284 307
oShowVer :: OptType
285 308
oShowVer = Option "V" ["version"]
286 309
           (NoArg (\ opts -> Ok opts { optShowVer = True}))
b/Ganeti/HTools/Types.hs
29 29
    , NameAssoc
30 30
    , Score
31 31
    , Weight
32
    , RSpec(..)
32 33
    , DynUtil(..)
33 34
    , zeroUtil
34 35
    , baseUtil
......
62 63
-- | A separate name for a weight metric.
63 64
type Weight = Double
64 65

  
66
-- | The resource spec type.
67
data RSpec = RSpec
68
    { rspecCpu  :: Int  -- ^ Requested VCPUs
69
    , rspecMem  :: Int  -- ^ Requested memory
70
    , rspecDsk  :: Int  -- ^ Requested disk
71
    } deriving (Show)
72

  
65 73
-- | The dynamic resource specs of a machine (i.e. load or load
66 74
-- capacity, as opposed to size).
67 75
data DynUtil = DynUtil
b/hspace.hs
63 63
    , oINodes
64 64
    , oMaxCpu
65 65
    , oMinDisk
66
    , oTieredSpec
66 67
    , oShowVer
67 68
    , oShowHelp
68 69
    ]
......
98 99
            , ("MNODE_DSK_AVAIL", printf "%d" . Cluster.csMdsk)
99 100
            ]
100 101

  
101
specData :: [(String, Options -> String)]
102
specData = [ ("MEM", printf "%d" . optIMem)
103
           , ("DSK", printf "%d" . optIDsk)
104
           , ("CPU", printf "%d" . optIVCPUs)
105
           , ("RQN", printf "%d" . optINodes)
102
specData :: [(String, RSpec -> String)]
103
specData = [ ("MEM", printf "%d" . rspecMem)
104
           , ("DSK", printf "%d" . rspecDsk)
105
           , ("CPU", printf "%d" . rspecCpu)
106 106
           ]
107 107

  
108 108
clusterData :: [(String, Cluster.CStats -> String)]
......
179 179
         exitWith $ ExitFailure 1
180 180

  
181 181
  let verbose = optVerbose opts
182
      ispec = optISpec opts
182 183

  
183 184
  (fixed_nl, il, csf) <- loadExternalData opts
184 185

  
185
  printKeys $ map (\(a, fn) -> ("SPEC_" ++ a, fn opts)) specData
186
  printKeys $ map (\(a, fn) -> ("SPEC_" ++ a, fn ispec)) specData
187
  printKeys [ ("SPEC_RQN", printf "%d" (optINodes opts)) ]
186 188

  
187 189
  let num_instances = length $ Container.elems il
188 190

  
......
239 241
         exitWith ExitSuccess
240 242

  
241 243
  let nmlen = Container.maxNameLen nl
242
      newinst = Instance.create "new" (optIMem opts) (optIDsk opts)
243
                (optIVCPUs opts) "ADMIN_down" (-1) (-1)
244
      reqinst = Instance.create "new" (rspecMem ispec) (rspecDsk ispec)
245
                (rspecCpu ispec) "ADMIN_down" (-1) (-1)
244 246

  
245
  let result = iterateDepth nl il newinst req_nodes []
247
  let result = iterateDepth nl il reqinst req_nodes []
246 248
  (ereason, fin_nl, ixes) <- (case result of
247 249
                                Bad s -> do
248 250
                                  hPrintf stderr "Failure: %s\n" s

Also available in: Unified diff