Revision 820ca72d src/Ganeti/DataCollectors/Lv.hs
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 |
Also available in: Unified diff