Revision 9c0a27d0 src/Ganeti/Rpc.hs
b/src/Ganeti/Rpc.hs | ||
---|---|---|
98 | 98 |
|
99 | 99 |
-- | Data type for RPC error reporting. |
100 | 100 |
data RpcError |
101 |
= CurlLayerError Node String
|
|
101 |
= CurlLayerError String |
|
102 | 102 |
| JsonDecodeError String |
103 | 103 |
| RpcResultError String |
104 |
| OfflineNodeError Node
|
|
104 |
| OfflineNodeError |
|
105 | 105 |
deriving (Show, Eq) |
106 | 106 |
|
107 | 107 |
-- | Provide explanation to RPC errors. |
108 | 108 |
explainRpcError :: RpcError -> String |
109 |
explainRpcError (CurlLayerError node code) =
|
|
110 |
"Curl error for " ++ nodeName node ++ ", " ++ code
|
|
109 |
explainRpcError (CurlLayerError code) = |
|
110 |
"Curl error:" ++ code
|
|
111 | 111 |
explainRpcError (JsonDecodeError msg) = |
112 | 112 |
"Error while decoding JSON from HTTP response: " ++ msg |
113 | 113 |
explainRpcError (RpcResultError msg) = |
114 | 114 |
"Error reponse received from RPC server: " ++ msg |
115 |
explainRpcError (OfflineNodeError node) =
|
|
116 |
"Node " ++ nodeName node ++ " is marked as offline"
|
|
115 |
explainRpcError OfflineNodeError =
|
|
116 |
"Node is marked offline"
|
|
117 | 117 |
|
118 | 118 |
type ERpcError = Either RpcError |
119 | 119 |
|
... | ... | |
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 |
executeHttpRequest :: Node -> ERpcError HttpClientRequest |
|
157 |
-> IO (ERpcError String) |
|
158 |
executeHttpRequest _ (Left rpc_err) = return $ Left rpc_err |
|
159 |
executeHttpRequest node (Right request) = do |
|
156 |
executeHttpRequest :: ERpcError HttpClientRequest -> IO (ERpcError String) |
|
157 |
executeHttpRequest (Left rpc_err) = return $ Left rpc_err |
|
158 |
executeHttpRequest (Right request) = do |
|
160 | 159 |
let reqOpts = CurlPostFields [requestData request]:requestOpts request |
161 | 160 |
url = requestUrl request |
162 | 161 |
-- FIXME: This is very similar to getUrl in Htools/Rapi.hs |
163 | 162 |
(code, !body) <- curlGetString url $ curlOpts ++ reqOpts |
164 | 163 |
return $ case code of |
165 | 164 |
CurlOK -> Right body |
166 |
_ -> Left $ CurlLayerError node (show code)
|
|
165 |
_ -> Left $ CurlLayerError (show code) |
|
167 | 166 |
|
168 | 167 |
-- | Prepare url for the HTTP request. |
169 | 168 |
prepareUrl :: (RpcCall a) => Node -> a -> String |
... | ... | |
183 | 182 |
, requestData = rpcCallData node call |
184 | 183 |
, requestOpts = opts ++ curlOpts |
185 | 184 |
} |
186 |
| otherwise = Left $ OfflineNodeError node
|
|
185 |
| otherwise = Left OfflineNodeError
|
|
187 | 186 |
|
188 | 187 |
-- | Parse a result based on the received HTTP response. |
189 | 188 |
parseHttpResponse :: (Rpc a b) => a -> ERpcError String -> ERpcError b |
... | ... | |
201 | 200 |
[CurlOption] -> Node -> a -> IO (Node, ERpcError b) |
202 | 201 |
executeSingleRpcCall opts node call = do |
203 | 202 |
let request = prepareHttpRequest opts node call |
204 |
response <- executeHttpRequest node request
|
|
203 |
response <- executeHttpRequest request |
|
205 | 204 |
let result = parseHttpResponse call response |
206 | 205 |
return (node, result) |
207 | 206 |
|
Also available in: Unified diff