This commit enables the logical volume data collector to get information about
the instances and to link it to the information about logical volumes.

The list of parameters accepted by the collector is expanded to allow proper
testing and connections to Confd in non-standard locations.

The shelltest test is updated accordingly.

Signed-off-by: Michele Tartara <[email protected]>
---
 Makefile.am                                  |  1 +
 src/Ganeti/DataCollectors/Lv.hs              | 68 ++++++++++++++++++++----
 test/data/instance-prim-sec.txt              | 78 ++++++++++++++++++++++++++++
 test/hs/shelltests/htools-mon-collector.test |  3 +-
 4 files changed, 139 insertions(+), 11 deletions(-)
 create mode 100644 test/data/instance-prim-sec.txt

diff --git a/Makefile.am b/Makefile.am
index 64109a8..dd9dbd2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1134,6 +1134,7 @@ TEST_FILES = \
        test/data/cluster_config_2.7.json \
        test/data/cluster_config_2.8.json \
        test/data/instance-minor-pairing.txt \
+       test/data/instance-prim-sec.txt \
        test/data/ip-addr-show-dummy0.txt \
        test/data/ip-addr-show-lo-ipv4.txt \
        test/data/ip-addr-show-lo-ipv6.txt \
diff --git a/src/Ganeti/DataCollectors/Lv.hs b/src/Ganeti/DataCollectors/Lv.hs
index 5c4abcd..d296b0f 100644
--- a/src/Ganeti/DataCollectors/Lv.hs
+++ b/src/Ganeti/DataCollectors/Lv.hs
@@ -39,14 +39,19 @@ module Ganeti.DataCollectors.Lv
 import qualified Control.Exception as E
 import Control.Monad
 import Data.Attoparsec.Text.Lazy as A
+import Data.List
 import Data.Text.Lazy (pack, unpack)
+import Network.BSD (getHostName)
 import System.Process
 import qualified Text.JSON as J
 
 import qualified Ganeti.BasicTypes as BT
 import Ganeti.Common
+import Ganeti.Confd.ClientFunctions
 import Ganeti.DataCollectors.CLI
 import Ganeti.DataCollectors.Types
+import Ganeti.JSON
+import Ganeti.Objects
 import Ganeti.Storage.Lvm.LVParser
 import Ganeti.Storage.Lvm.Types
 import Ganeti.Utils
@@ -81,7 +86,7 @@ dcKind = DCKPerf
 
 -- | The data exported by the data collector, taken from the default location.
 dcReport :: IO DCReport
-dcReport = buildDCReport Nothing
+dcReport = buildDCReport defaultOptions
 
 -- * Command line options
 
@@ -89,6 +94,9 @@ options :: IO [OptType]
 options =
   return
     [ oInputFile
+    , oConfdAddr
+    , oConfdPort
+    , oInstances
     ]
 
 -- | The list of arguments supported by the program.
@@ -103,7 +111,7 @@ getLvInfo inputFile = do
       params = lvParams
       fromLvs =
         ((E.try $ readProcess cmd params "") :: IO (Either IOError String)) >>=
-          exitIfBad "running command" . either (BT.Bad . show) BT.Ok
+        exitIfBad "running command" . either (BT.Bad . show) BT.Ok
   contents <-
     maybe fromLvs (\fn -> ((E.try $ readFile fn) :: IO (Either IOError String))
       >>= exitIfBad "reading from file" . either (BT.Bad . show) BT.Ok)
@@ -114,16 +122,56 @@ getLvInfo inputFile = do
         ++ show contexts ++ "\n" ++ errorMessage
     A.Done _ lvinfoD -> return lvinfoD
 
--- | This function computes the JSON representation of the LV status
-buildJsonReport :: Maybe FilePath -> IO J.JSValue
-buildJsonReport inputFile = do
+-- | Get the list of instances on the current node (both primary and secondary)
+-- either from a provided file or by querying Confd.
+getInstanceList :: Options -> IO ([Instance], [Instance])
+getInstanceList opts = do
+  let srvAddr = optConfdAddr opts
+      srvPort = optConfdPort opts
+      instFile = optInstances opts
+      fromConfdUnchecked :: IO (BT.Result ([Instance], [Instance]))
+      fromConfdUnchecked = getHostName >>= \n -> getInstances n srvAddr srvPort
+      fromConfd :: IO (BT.Result ([Instance], [Instance]))
+      fromConfd =
+        liftM (either (BT.Bad . show) id) (E.try fromConfdUnchecked :: 
+          IO (Either IOError (BT.Result ([Instance], [Instance]))))
+      fromFile :: FilePath -> IO (BT.Result ([Instance], [Instance]))
+      fromFile inputFile = do
+        contents <-
+          ((E.try $ readFile inputFile) :: IO (Either IOError String))
+            >>= exitIfBad "reading from file" . either (BT.Bad . show) BT.Ok
+        return . fromJResult "Not a list of instances" $ J.decode contents
+  instances <- maybe fromConfd fromFile instFile
+  exitIfBad "Unable to obtain the list of instances" instances
+
+-- | Adds the name of the instance to the information about one logical volume.
+addInstNameToOneLv :: [Instance] -> LVInfo -> LVInfo
+addInstNameToOneLv instances lvInfo =
+  let vg_name = lviVgName lvInfo
+      lv_name = lviName lvInfo
+      instanceHasDisk = any (includesLogicalId vg_name lv_name) . instDisks
+      rightInstance = find instanceHasDisk instances
+    in 
+      case rightInstance of
+        Nothing -> lvInfo
+        Just i -> lvInfo { lviInstance = Just $ instName i }
+
+-- | Adds the name of the instance to the information about logical volumes.
+addInstNameToLv :: [Instance] -> [LVInfo] -> [LVInfo]
+addInstNameToLv instances = map (addInstNameToOneLv instances)
+
+-- | This function computes the JSON representation of the LV status.
+buildJsonReport :: Options -> IO J.JSValue
+buildJsonReport opts = do
+  let inputFile = optInputFile opts
   lvInfo <- getLvInfo inputFile
-  return $ J.showJSON lvInfo
+  (prim, sec) <- getInstanceList opts
+  return . J.showJSON $ addInstNameToLv (prim ++ sec) lvInfo
 
 -- | This function computes the DCReport for the logical volumes.
-buildDCReport :: Maybe FilePath -> IO DCReport
-buildDCReport inputFile =
-  buildJsonReport inputFile >>=
+buildDCReport :: Options -> IO DCReport
+buildDCReport opts =
+  buildJsonReport opts >>=
     buildReport dcName dcVersion dcFormatVersion dcCategory dcKind
 
 -- | Main function.
@@ -131,6 +179,6 @@ main :: Options -> [String] -> IO ()
 main opts args = do
   unless (null args) . exitErr $ "This program takes exactly zero" ++
                                  " arguments, got '" ++ unwords args ++ "'"
-  report <- buildDCReport $ optInputFile opts
 
+  report <- buildDCReport opts
   putStrLn $ J.encode report
diff --git a/test/data/instance-prim-sec.txt b/test/data/instance-prim-sec.txt
new file mode 100644
index 0000000..76fa512
--- /dev/null
+++ b/test/data/instance-prim-sec.txt
@@ -0,0 +1,78 @@
+[[{"admin_state": "up",
+   "beparams": {},
+   "ctime": 1372838883.9710441,
+   "disk_template": "drbd",
+   "disks": [
+     {
+       "children": [
+         {
+           "dev_type": "lvm",
+           "logical_id": [
+             "xenvg",
+             "df9ff3f6-a833-48ff-8bd5-bff2eaeab759.disk0_data"
+           ],
+           "params": {},
+           "physical_id": [
+             "xenvg",
+             "df9ff3f6-a833-48ff-8bd5-bff2eaeab759.disk0_data"
+           ],
+           "size": 1024,
+           "uuid": "eaff6322-1bfb-4d59-b306-4535730917cc"
+         },
+         {
+           "dev_type": "lvm",
+           "logical_id": [
+             "xenvg",
+             "df9ff3f6-a833-48ff-8bd5-bff2eaeab759.disk0_meta"
+           ],
+           "params": {},
+           "physical_id": [
+             "xenvg",
+             "df9ff3f6-a833-48ff-8bd5-bff2eaeab759.disk0_meta"
+           ],
+           "size": 128,
+           "uuid": "bf512e95-2a49-4cb3-8d1f-30a503f6bf1b"
+         }
+       ],
+       "dev_type": "drbd8",
+       "iv_name": "disk/0",
+       "logical_id": [
+         "60e687a0-21fc-4577-997f-ccd08925fa65",
+         "c739c7f3-79d8-4e20-ac68-662e16577d2e",
+         11000,
+         0,
+         0,
+         "9bdb15fb7ab6bb4610a313d654ed4d0d2433713e"
+       ],
+       "mode": "rw",
+       "params": {},
+       "physical_id": [
+         "172.16.241.3",
+         11000,
+         "172.16.241.2",
+         11000,
+         0,
+         "9bdb15fb7ab6bb4610a313d654ed4d0d2433713e"
+       ],
+       "size": 1024,
+       "uuid": "5d61e205-bf89-4ba8-a319-589b7bb7419e"
+     }
+   ],
+   "disks_active": true,
+   "hvparams": {},
+   "hypervisor": "xen-pvm",
+   "mtime": 1372838946.2599809,
+   "name": "instance1.example.com",
+   "nics": [
+     {
+       "mac": "aa:00:00:1d:ba:63",
+       "nicparams": {},
+       "uuid": "7b7f4249-fab8-4b3f-b446-d7a2aff37644"
+     }
+   ],
+   "os": "busybox",
+   "osparams": {},
+   "primary_node": "60e687a0-21fc-4577-997f-ccd08925fa65",
+   "serial_no": 2,
+   "uuid": "aec390cb-5eae-44e6-bcc2-ec14d31347f0"
+ }], []]
diff --git a/test/hs/shelltests/htools-mon-collector.test 
b/test/hs/shelltests/htools-mon-collector.test
index 7ad1fbb..6fcecbd 100644
--- a/test/hs/shelltests/htools-mon-collector.test
+++ b/test/hs/shelltests/htools-mon-collector.test
@@ -104,5 +104,6 @@ Failed reading: versionInfo
 >>>= !0
 
 # Test that lv parses correctly a standard test file
-./test/hs/hpc-mon-collector lv -f $PYTESTDATA_DIR/lvs_lv.txt
+./test/hs/hpc-mon-collector lv -f $PYTESTDATA_DIR/lvs_lv.txt -i 
$PYTESTDATA_DIR/instance-prim-sec.txt
+>>>/"instance":"instance1.example.com"/
 >>>= 0
-- 
1.8.3

Reply via email to