1 {-| Instance status data collector.
7 Copyright (C) 2013 Google Inc.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 module Ganeti.DataCollectors.InstStatus
34 import qualified Data.Map as Map
35 import Network.BSD (getHostName)
36 import qualified Text.JSON as J
38 import qualified Ganeti.BasicTypes as BT
39 import Ganeti.Confd.Client
40 import Ganeti.Confd.Types
42 import Ganeti.DataCollectors.CLI
43 import Ganeti.DataCollectors.InstStatusTypes
44 import Ganeti.Hypervisor.Xen
45 import Ganeti.Hypervisor.Xen.Types
49 -- * Command line options
51 options :: IO [OptType]
57 -- | The list of arguments supported by the program.
58 arguments :: [ArgCompletion]
61 -- | Get the list of instances ([primary], [secondary]) on the given node.
62 -- Implemented as a function, even if used a single time, to specify in a
63 -- convenient and elegant way the return data type, required in order to
64 -- prevent incurring in the monomorphism restriction.
65 -- The server address and the server port parameters are mainly intended
66 -- for testing purposes. If they are Nothing, the default values will be used.
71 -> IO (BT.Result ([Ganeti.Objects.Instance], [Ganeti.Objects.Instance]))
72 getInstances node srvAddr srvPort = do
73 client <- getConfdClient srvAddr srvPort
74 reply <- query client ReqNodeInstances $ PlainQuery node
76 case fmap (J.readJSON . confdReplyAnswer) reply of
77 Just (J.Ok instances) -> BT.Ok instances
78 Just (J.Error msg) -> BT.Bad msg
79 Nothing -> BT.Bad "No answer from the Confd server"
81 -- Builds the status of an instance using runtime information about the Xen
82 -- Domains, their uptime information and the static information provided by
84 buildStatus :: Map.Map String Domain -> Map.Map Int UptimeInfo -> Instance
86 buildStatus domains uptimes inst = do
87 let name = instName inst
88 currDomain = Map.lookup name domains
89 idNum = fmap domId currDomain
90 currUInfo = idNum >>= (`Map.lookup` uptimes)
91 uptime = fmap uInfoUptime currUInfo
92 adminState = instAdminState inst
94 if adminState == AdminDown && isNothing currDomain
96 else case currDomain of
97 (Just dom@(Domain _ _ _ _ (Just isHung))) ->
112 main :: Options -> [String] -> IO ()
114 curNode <- getHostName
115 let node = fromMaybe curNode $ optNode opts
116 answer <- getInstances node (optConfdAddr opts) (optConfdPort opts)
117 inst <- exitIfBad "Can't get instance info from ConfD" answer
118 domains <- getInferredDomInfo
119 uptimes <- getUptimeInfo
120 let primaryInst = fst inst
121 iStatus <- mapM (buildStatus domains uptimes) primaryInst
122 putStrLn $ J.encode iStatus