Revision 7f0fd838

b/htools/Ganeti/Query/Node.hs
24 24
-}
25 25

  
26 26
module Ganeti.Query.Node
27
  ( NodeRuntime(..)
27
  ( NodeRuntime
28 28
  , nodeFieldsMap
29 29
  ) where
30 30

  
......
34 34

  
35 35
import Ganeti.Config
36 36
import Ganeti.Objects
37
import Ganeti.Rpc
37 38
import Ganeti.Query.Language
38 39
import Ganeti.Query.Common
39 40
import Ganeti.Query.Types
40 41

  
41
-- | Stub data type until we integrate the RPC.
42
data NodeRuntime = NodeRuntime
42
-- | NodeRuntime is the resulting type for NodeInfo call.
43
type NodeRuntime = Either RpcError RpcResultNodeInfo
43 44

  
44 45
-- | List of node live fields, all ignored for now (no RPC).
45 46
nodeLiveFieldsDefs :: [(FieldName, FieldTitle, FieldType, String, FieldDoc)]
b/htools/Ganeti/Query/Query.hs
51 51
    ) where
52 52

  
53 53
import Control.Monad (filterM)
54
import Control.Monad.Trans (lift)
54 55
import Data.Maybe (fromMaybe)
55 56
import qualified Data.Map as Map
56 57

  
57 58
import Ganeti.BasicTypes
58 59
import Ganeti.JSON
60
import Ganeti.Rpc
59 61
import Ganeti.Query.Language
60 62
import Ganeti.Query.Common
61 63
import Ganeti.Query.Filter
......
90 92
getSelectedFields defined =
91 93
  map (\name -> fromMaybe (mkUnknownFDef name) $ name `Map.lookup` defined)
92 94

  
95
-- | Collect live data from RPC query if enabled.
96
-- FIXME: Check which fields we actually need and possibly send empty
97
-- hvs/vgs if no info from hypervisor/volume group respectively
98
-- is required
99
maybeCollectLiveData:: Bool -> ConfigData -> [Node] -> IO [(Node, NodeRuntime)]
100

  
101
maybeCollectLiveData False _ nodes =
102
  return $ zip nodes (repeat $ Left (RpcResultError "Live data disabled"))
103

  
104
maybeCollectLiveData True cfg nodes = do
105
  let vgs = [clusterVolumeGroupName $ configCluster cfg]
106
      hvs = clusterEnabledHypervisors $ configCluster cfg
107
  executeRpcCall nodes (RpcCallNodeInfo vgs hvs)
108

  
109
-- | Check whether list of queried fields contains live fields.
110
needsLiveData :: [FieldGetter a b] -> Bool
111
needsLiveData = any (\getter -> case getter of
112
                     FieldRuntime _ -> True
113
                     _ -> False)
114

  
93 115
-- | Main query execution function.
94 116
query :: ConfigData   -- ^ The current configuration
95 117
      -> Bool         -- ^ Whether to collect live data
96 118
      -> Query        -- ^ The query (item, fields, filter)
97 119
      -> IO (Result QueryResult) -- ^ Result
98 120

  
99
query cfg _ (Query QRNode fields qfilter) = return $ do
100
  cfilter <- compileFilter nodeFieldsMap qfilter
121
query cfg live (Query QRNode fields qfilter) =  runResultT $ do
122
  cfilter <- resultT $ compileFilter nodeFieldsMap qfilter
101 123
  let selected = getSelectedFields nodeFieldsMap fields
102 124
      (fdefs, fgetters) = unzip selected
103 125
      nodes = Map.elems . fromContainer $ configNodes cfg
126
      live' = live && needsLiveData fgetters
104 127
  -- runs first pass of the filter, without a runtime context; this
105 128
  -- will limit the nodes that we'll contact for runtime data
106
  fnodes <- filterM (\n -> evaluateFilter cfg Nothing n cfilter)
107
            nodes
129
  fnodes <- resultT $ filterM (\n -> evaluateFilter cfg Nothing n cfilter) nodes
108 130
  -- here we would run the runtime data gathering, then filter again
109 131
  -- the nodes, based on existing runtime data
110
  let fdata = map (\node -> map (execGetter cfg NodeRuntime node) fgetters)
111
              fnodes
132
  nruntimes <- lift $ maybeCollectLiveData live' cfg fnodes
133
  let fdata = map (\(node, nrt) -> map (execGetter cfg nrt node) fgetters)
134
              nruntimes
112 135
  return QueryResult { qresFields = fdefs, qresData = fdata }
113 136

  
114 137
query cfg _ (Query QRGroup fields qfilter) = return $ do

Also available in: Unified diff