Revision 85f6a869

b/src/Ganeti/Rpc.hs
146 146

  
147 147
-- | Http Request definition.
148 148
data HttpClientRequest = HttpClientRequest
149
  { requestTimeout :: Int
150
  , requestUrl :: String
151
  , requestPostData :: String
149
  { requestUrl  :: String       -- ^ The actual URL for the node endpoint
150
  , requestData :: String       -- ^ The arguments for the call
151
  , requestOpts :: [CurlOption] -- ^ The various curl options
152 152
  }
153 153

  
154 154
-- | Execute the request and return the result as a plain String. When
155 155
-- curl reports an error, we propagate it.
156 156
executeHttpRequest :: Node -> ERpcError HttpClientRequest
157 157
                   -> IO (ERpcError String)
158

  
159 158
executeHttpRequest _ (Left rpc_err) = return $ Left rpc_err
160 159
executeHttpRequest node (Right request) = do
161
  cert_file <- P.nodedCertFile
162
  let reqOpts = [ CurlTimeout (fromIntegral $ requestTimeout request)
163
                , CurlPostFields [requestPostData request]
164
                , CurlSSLCert cert_file
165
                , CurlSSLKey cert_file
166
                , CurlCAInfo cert_file
167
                ]
160
  let reqOpts = CurlPostFields [requestData request]:requestOpts request
168 161
      url = requestUrl request
169 162
  -- FIXME: This is very similar to getUrl in Htools/Rapi.hs
170 163
  (code, !body) <- curlGetString url $ curlOpts ++ reqOpts
......
182 175

  
183 176
-- | Create HTTP request for a given node provided it is online,
184 177
-- otherwise create empty response.
185
prepareHttpRequest ::  (RpcCall a) => Node -> a
178
prepareHttpRequest :: (RpcCall a) => [CurlOption] -> Node -> a
186 179
                   -> ERpcError HttpClientRequest
187
prepareHttpRequest node call
180
prepareHttpRequest opts node call
188 181
  | rpcCallAcceptOffline call || not (nodeOffline node) =
189
      Right HttpClientRequest { requestTimeout = rpcCallTimeout call
190
                              , requestUrl = prepareUrl node call
191
                              , requestPostData = rpcCallData node call
182
      Right HttpClientRequest { requestUrl  = prepareUrl node call
183
                              , requestData = rpcCallData node call
184
                              , requestOpts = opts ++ curlOpts
192 185
                              }
193 186
  | otherwise = Left $ OfflineNodeError node
194 187

  
......
204 197
       _ -> Left . JsonDecodeError $ show (pp_value jerr)
205 198

  
206 199
-- | Execute RPC call for a sigle node.
207
executeSingleRpcCall :: (Rpc a b) => Node -> a -> IO (Node, ERpcError b)
208
executeSingleRpcCall node call = do
209
  let request = prepareHttpRequest node call
200
executeSingleRpcCall :: (Rpc a b) =>
201
                        [CurlOption] -> Node -> a -> IO (Node, ERpcError b)
202
executeSingleRpcCall opts node call = do
203
  let request = prepareHttpRequest opts node call
210 204
  response <- executeHttpRequest node request
211 205
  let result = parseHttpResponse call response
212 206
  return (node, result)
213 207

  
214 208
-- | Execute RPC call for many nodes in parallel.
215 209
executeRpcCall :: (Rpc a b) => [Node] -> a -> IO [(Node, ERpcError b)]
216
executeRpcCall nodes call =
217
  sequence $ parMap rwhnf (uncurry executeSingleRpcCall)
218
               (zip nodes $ repeat call)
210
executeRpcCall nodes call = do
211
  cert_file <- P.nodedCertFile
212
  let opts = [ CurlTimeout (fromIntegral $ rpcCallTimeout call)
213
             , CurlSSLCert cert_file
214
             , CurlSSLKey cert_file
215
             , CurlCAInfo cert_file
216
             ]
217
  sequence $ parMap rwhnf (\n -> executeSingleRpcCall opts n call) nodes
219 218

  
220 219
-- | Helper function that is used to read dictionaries of values.
221 220
sanitizeDictResults :: [(String, J.Result a)] -> ERpcError [(String, a)]

Also available in: Unified diff