Commit 820ca72d authored by Michele Tartara's avatar Michele Tartara
Browse files

Include "instance" information in LV data collector



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: default avatarMichele Tartara <mtartara@google.com>
Reviewed-by: default avatarKlaus Aehlig <aehlig@google.com>
parent 76968973
......@@ -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 \
......
......@@ -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
[[{"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"
}], []]
......@@ -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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment