Revision 820ca72d

b/Makefile.am
1134 1134
	test/data/cluster_config_2.7.json \
1135 1135
	test/data/cluster_config_2.8.json \
1136 1136
	test/data/instance-minor-pairing.txt \
1137
	test/data/instance-prim-sec.txt \
1137 1138
	test/data/ip-addr-show-dummy0.txt \
1138 1139
	test/data/ip-addr-show-lo-ipv4.txt \
1139 1140
	test/data/ip-addr-show-lo-ipv6.txt \
b/src/Ganeti/DataCollectors/Lv.hs
39 39
import qualified Control.Exception as E
40 40
import Control.Monad
41 41
import Data.Attoparsec.Text.Lazy as A
42
import Data.List
42 43
import Data.Text.Lazy (pack, unpack)
44
import Network.BSD (getHostName)
43 45
import System.Process
44 46
import qualified Text.JSON as J
45 47

  
46 48
import qualified Ganeti.BasicTypes as BT
47 49
import Ganeti.Common
50
import Ganeti.Confd.ClientFunctions
48 51
import Ganeti.DataCollectors.CLI
49 52
import Ganeti.DataCollectors.Types
53
import Ganeti.JSON
54
import Ganeti.Objects
50 55
import Ganeti.Storage.Lvm.LVParser
51 56
import Ganeti.Storage.Lvm.Types
52 57
import Ganeti.Utils
......
81 86

  
82 87
-- | The data exported by the data collector, taken from the default location.
83 88
dcReport :: IO DCReport
84
dcReport = buildDCReport Nothing
89
dcReport = buildDCReport defaultOptions
85 90

  
86 91
-- * Command line options
87 92

  
......
89 94
options =
90 95
  return
91 96
    [ oInputFile
97
    , oConfdAddr
98
    , oConfdPort
99
    , oInstances
92 100
    ]
93 101

  
94 102
-- | The list of arguments supported by the program.
......
103 111
      params = lvParams
104 112
      fromLvs =
105 113
        ((E.try $ readProcess cmd params "") :: IO (Either IOError String)) >>=
106
          exitIfBad "running command" . either (BT.Bad . show) BT.Ok
114
        exitIfBad "running command" . either (BT.Bad . show) BT.Ok
107 115
  contents <-
108 116
    maybe fromLvs (\fn -> ((E.try $ readFile fn) :: IO (Either IOError String))
109 117
      >>= exitIfBad "reading from file" . either (BT.Bad . show) BT.Ok)
......
114 122
        ++ show contexts ++ "\n" ++ errorMessage
115 123
    A.Done _ lvinfoD -> return lvinfoD
116 124

  
117
-- | This function computes the JSON representation of the LV status
118
buildJsonReport :: Maybe FilePath -> IO J.JSValue
119
buildJsonReport inputFile = do
125
-- | Get the list of instances on the current node (both primary and secondary)
126
-- either from a provided file or by querying Confd.
127
getInstanceList :: Options -> IO ([Instance], [Instance])
128
getInstanceList opts = do
129
  let srvAddr = optConfdAddr opts
130
      srvPort = optConfdPort opts
131
      instFile = optInstances opts
132
      fromConfdUnchecked :: IO (BT.Result ([Instance], [Instance]))
133
      fromConfdUnchecked = getHostName >>= \n -> getInstances n srvAddr srvPort
134
      fromConfd :: IO (BT.Result ([Instance], [Instance]))
135
      fromConfd =
136
        liftM (either (BT.Bad . show) id) (E.try fromConfdUnchecked :: 
137
          IO (Either IOError (BT.Result ([Instance], [Instance]))))
138
      fromFile :: FilePath -> IO (BT.Result ([Instance], [Instance]))
139
      fromFile inputFile = do
140
        contents <-
141
          ((E.try $ readFile inputFile) :: IO (Either IOError String))
142
            >>= exitIfBad "reading from file" . either (BT.Bad . show) BT.Ok
143
        return . fromJResult "Not a list of instances" $ J.decode contents
144
  instances <- maybe fromConfd fromFile instFile
145
  exitIfBad "Unable to obtain the list of instances" instances
146

  
147
-- | Adds the name of the instance to the information about one logical volume.
148
addInstNameToOneLv :: [Instance] -> LVInfo -> LVInfo
149
addInstNameToOneLv instances lvInfo =
150
  let vg_name = lviVgName lvInfo
151
      lv_name = lviName lvInfo
152
      instanceHasDisk = any (includesLogicalId vg_name lv_name) . instDisks
153
      rightInstance = find instanceHasDisk instances
154
    in 
155
      case rightInstance of
156
        Nothing -> lvInfo
157
        Just i -> lvInfo { lviInstance = Just $ instName i }
158

  
159
-- | Adds the name of the instance to the information about logical volumes.
160
addInstNameToLv :: [Instance] -> [LVInfo] -> [LVInfo]
161
addInstNameToLv instances = map (addInstNameToOneLv instances)
162

  
163
-- | This function computes the JSON representation of the LV status.
164
buildJsonReport :: Options -> IO J.JSValue
165
buildJsonReport opts = do
166
  let inputFile = optInputFile opts
120 167
  lvInfo <- getLvInfo inputFile
121
  return $ J.showJSON lvInfo
168
  (prim, sec) <- getInstanceList opts
169
  return . J.showJSON $ addInstNameToLv (prim ++ sec) lvInfo
122 170

  
123 171
-- | This function computes the DCReport for the logical volumes.
124
buildDCReport :: Maybe FilePath -> IO DCReport
125
buildDCReport inputFile =
126
  buildJsonReport inputFile >>=
172
buildDCReport :: Options -> IO DCReport
173
buildDCReport opts =
174
  buildJsonReport opts >>=
127 175
    buildReport dcName dcVersion dcFormatVersion dcCategory dcKind
128 176

  
129 177
-- | Main function.
......
131 179
main opts args = do
132 180
  unless (null args) . exitErr $ "This program takes exactly zero" ++
133 181
                                 " arguments, got '" ++ unwords args ++ "'"
134
  report <- buildDCReport $ optInputFile opts
135 182

  
183
  report <- buildDCReport opts
136 184
  putStrLn $ J.encode report
b/test/data/instance-prim-sec.txt
1
[[{"admin_state": "up",
2
   "beparams": {},
3
   "ctime": 1372838883.9710441,
4
   "disk_template": "drbd",
5
   "disks": [
6
     {
7
       "children": [
8
         {
9
           "dev_type": "lvm",
10
           "logical_id": [
11
             "xenvg",
12
             "df9ff3f6-a833-48ff-8bd5-bff2eaeab759.disk0_data"
13
           ],
14
           "params": {},
15
           "physical_id": [
16
             "xenvg",
17
             "df9ff3f6-a833-48ff-8bd5-bff2eaeab759.disk0_data"
18
           ],
19
           "size": 1024,
20
           "uuid": "eaff6322-1bfb-4d59-b306-4535730917cc"
21
         },
22
         {
23
           "dev_type": "lvm",
24
           "logical_id": [
25
             "xenvg",
26
             "df9ff3f6-a833-48ff-8bd5-bff2eaeab759.disk0_meta"
27
           ],
28
           "params": {},
29
           "physical_id": [
30
             "xenvg",
31
             "df9ff3f6-a833-48ff-8bd5-bff2eaeab759.disk0_meta"
32
           ],
33
           "size": 128,
34
           "uuid": "bf512e95-2a49-4cb3-8d1f-30a503f6bf1b"
35
         }
36
       ],
37
       "dev_type": "drbd8",
38
       "iv_name": "disk/0",
39
       "logical_id": [
40
         "60e687a0-21fc-4577-997f-ccd08925fa65",
41
         "c739c7f3-79d8-4e20-ac68-662e16577d2e",
42
         11000,
43
         0,
44
         0,
45
         "9bdb15fb7ab6bb4610a313d654ed4d0d2433713e"
46
       ],
47
       "mode": "rw",
48
       "params": {},
49
       "physical_id": [
50
         "172.16.241.3",
51
         11000,
52
         "172.16.241.2",
53
         11000,
54
         0,
55
         "9bdb15fb7ab6bb4610a313d654ed4d0d2433713e"
56
       ],
57
       "size": 1024,
58
       "uuid": "5d61e205-bf89-4ba8-a319-589b7bb7419e"
59
     }
60
   ],
61
   "disks_active": true,
62
   "hvparams": {},
63
   "hypervisor": "xen-pvm",
64
   "mtime": 1372838946.2599809,
65
   "name": "instance1.example.com",
66
   "nics": [
67
     {
68
       "mac": "aa:00:00:1d:ba:63",
69
       "nicparams": {},
70
       "uuid": "7b7f4249-fab8-4b3f-b446-d7a2aff37644"
71
     }
72
   ],
73
   "os": "busybox",
74
   "osparams": {},
75
   "primary_node": "60e687a0-21fc-4577-997f-ccd08925fa65",
76
   "serial_no": 2,
77
   "uuid": "aec390cb-5eae-44e6-bcc2-ec14d31347f0"
78
 }], []]
b/test/hs/shelltests/htools-mon-collector.test
104 104
>>>= !0
105 105

  
106 106
# Test that lv parses correctly a standard test file
107
./test/hs/hpc-mon-collector lv -f $PYTESTDATA_DIR/lvs_lv.txt
107
./test/hs/hpc-mon-collector lv -f $PYTESTDATA_DIR/lvs_lv.txt -i $PYTESTDATA_DIR/instance-prim-sec.txt
108
>>>/"instance":"instance1.example.com"/
108 109
>>>= 0

Also available in: Unified diff