From 01fec0a1df3e67901294f1926c07b0ba5d278683 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Fri, 17 Dec 2010 13:26:15 +0100
Subject: [PATCH] hail: allow overriding cluster data from requests
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Currently, it's not easy to generate β€œfake” IAllocator request files
for hail. As such, testing on simulated clusters is hard to do.

To workaround this, we change hail to also take the β€˜-t’ and
β€˜--simulate’ options, so that we can override the cluster data read
from the request. Note that this will not change the request itself
(so for example an evacuation will need to make sure uses the correct
node names), but it's a step forward in testing hail. The other tools
already can use text files which allow for better flexibility.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Balazs Lecz <leczb@google.com>
---
 hail.hs      | 44 +++++++++++++++++++++++++++++++-------------
 man/hail.rst | 27 ++++++++++++++++++++++++++-
 2 files changed, 57 insertions(+), 14 deletions(-)

diff --git a/hail.hs b/hail.hs
index a40898738..2ee6d99a4 100644
--- a/hail.hs
+++ b/hail.hs
@@ -38,10 +38,17 @@ import Ganeti.HTools.CLI
 import Ganeti.HTools.IAlloc
 import Ganeti.HTools.Types
 import Ganeti.HTools.Loader (RqType(..), Request(..))
+import Ganeti.HTools.ExtLoader (loadExternalData)
 
 -- | Options list and functions
 options :: [OptType]
-options = [oPrintNodes, oShowVer, oShowHelp]
+options =
+    [ oPrintNodes
+    , oDataFile
+    , oNodeSim
+    , oShowVer
+    , oShowHelp
+    ]
 
 processResults :: (Monad m) =>
                   RqType -> Cluster.AllocSolution
@@ -67,25 +74,36 @@ processRequest request =
        Relocate idx reqn exnodes -> Cluster.tryReloc nl il idx reqn exnodes
        Evacuate exnodes -> Cluster.tryEvac nl il exnodes
 
+-- | Reads the request from the data file(s)
+readRequest :: Options -> [String] -> IO Request
+readRequest opts args = do
+  when (null args) $ do
+         hPutStrLn stderr "Error: this program needs an input file."
+         exitWith $ ExitFailure 1
+
+  input_data <- readFile (head args)
+  r1 <- case (parseData input_data) of
+          Bad err -> do
+            hPutStrLn stderr $ "Error: " ++ err
+            exitWith $ ExitFailure 1
+          Ok rq -> return rq
+  r2 <- if isJust (optDataFile opts) || isJust (optNodeSim opts)
+        then  do
+          (gl, nl, il, ctags) <- loadExternalData opts
+          let Request rqt _ _ _ _ = r1
+          return $ Request rqt gl nl il ctags
+        else return r1
+  return r2
+
 -- | Main function.
 main :: IO ()
 main = do
   cmd_args <- System.getArgs
   (opts, args) <- parseOpts cmd_args "hail" options
 
-  when (null args) $ do
-         hPutStrLn stderr "Error: this program needs an input file."
-         exitWith $ ExitFailure 1
-
-  let input_file = head args
-      shownodes = optShowNodes opts
-  input_data <- readFile input_file
+  let shownodes = optShowNodes opts
 
-  request <- case (parseData input_data) of
-               Bad err -> do
-                 hPutStrLn stderr $ "Error: " ++ err
-                 exitWith $ ExitFailure 1
-               Ok rq -> return rq
+  request <- readRequest opts args
 
   let Request rq _ nl _ _ = request
 
diff --git a/man/hail.rst b/man/hail.rst
index ef5b62e32..42acef61e 100644
--- a/man/hail.rst
+++ b/man/hail.rst
@@ -9,7 +9,7 @@ hail - Ganeti IAllocator plugin
 SYNOPSIS
 --------
 
-**hail** *input-file*
+**hail** [ **-t** *datafile* | **--simulate** *spec* ] *input-file*
 
 **hail** --version
 
@@ -48,6 +48,26 @@ them using the single-instance relocation algorithm.
 
 In all cases, the cluster scoring is identical to the hbal algorithm.
 
+OPTIONS
+-------
+
+The options that can be passed to the program are as follows:
+
+-p, --print-nodes
+  Prints the before and after node status, in a format designed to
+  allow the user to understand the node's most important
+  parameters. See the man page **hbal**(1) for more details about this
+  field.
+
+-t *datafile*, --text-data=*datafile*
+  The name of the file holding cluster information, to override the
+  data in the JSON request itself. This is mostly used for debugging.
+
+--simulate *description*
+  Similar to the **-t** option, this allows overriding the cluster
+  data with a simulated cluster. For details about the description,
+  see the man page **hspace**(1).
+
 CONFIGURATION
 -------------
 
@@ -63,6 +83,11 @@ all instance tags of the form **service:X** will be considered as
 exclusion tags, meaning that (e.g.) two instances which both have a
 tag **service:foo** will not be placed on the same primary node.
 
+OPTIONS
+-------
+
+The options that can be passed to the program are as follows:
+
 EXIT STATUS
 -----------
 
-- 
GitLab