Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / Rpc.hs @ c92b4671

History | View | Annotate | Download (21.6 kB)

1 1ca709c1 Iustin Pop
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies,
2 96dad12d Agata Murawska
  BangPatterns, TemplateHaskell #-}
3 d4709cce Agata Murawska
4 d4709cce Agata Murawska
{-| Implementation of the RPC client.
5 d4709cce Agata Murawska
6 d4709cce Agata Murawska
-}
7 d4709cce Agata Murawska
8 d4709cce Agata Murawska
{-
9 d4709cce Agata Murawska
10 1ca709c1 Iustin Pop
Copyright (C) 2012, 2013 Google Inc.
11 d4709cce Agata Murawska
12 d4709cce Agata Murawska
This program is free software; you can redistribute it and/or modify
13 d4709cce Agata Murawska
it under the terms of the GNU General Public License as published by
14 d4709cce Agata Murawska
the Free Software Foundation; either version 2 of the License, or
15 d4709cce Agata Murawska
(at your option) any later version.
16 d4709cce Agata Murawska
17 d4709cce Agata Murawska
This program is distributed in the hope that it will be useful, but
18 d4709cce Agata Murawska
WITHOUT ANY WARRANTY; without even the implied warranty of
19 d4709cce Agata Murawska
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 d4709cce Agata Murawska
General Public License for more details.
21 d4709cce Agata Murawska
22 d4709cce Agata Murawska
You should have received a copy of the GNU General Public License
23 d4709cce Agata Murawska
along with this program; if not, write to the Free Software
24 d4709cce Agata Murawska
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 d4709cce Agata Murawska
02110-1301, USA.
26 d4709cce Agata Murawska
27 d4709cce Agata Murawska
-}
28 d4709cce Agata Murawska
29 d4709cce Agata Murawska
module Ganeti.Rpc
30 d4709cce Agata Murawska
  ( RpcCall
31 d4709cce Agata Murawska
  , Rpc
32 d4709cce Agata Murawska
  , RpcError(..)
33 599239ad Agata Murawska
  , ERpcError
34 60443f61 Agata Murawska
  , explainRpcError
35 eaed5f19 Agata Murawska
  , executeRpcCall
36 ad56f735 Hrvoje Ribicic
  , executeRpcCalls
37 a246ce76 Michele Tartara
  , logRpcErrors
38 d4709cce Agata Murawska
39 d4709cce Agata Murawska
  , rpcCallName
40 d4709cce Agata Murawska
  , rpcCallTimeout
41 d4709cce Agata Murawska
  , rpcCallData
42 d4709cce Agata Murawska
  , rpcCallAcceptOffline
43 d4709cce Agata Murawska
44 d4709cce Agata Murawska
  , rpcResultFill
45 96dad12d Agata Murawska
46 5188fdb7 Agata Murawska
  , RpcCallInstanceInfo(..)
47 14933c17 Jose A. Lopes
  , InstanceState(..)
48 14933c17 Jose A. Lopes
  , InstanceInfo(..)
49 5188fdb7 Agata Murawska
  , RpcResultInstanceInfo(..)
50 5188fdb7 Agata Murawska
51 96dad12d Agata Murawska
  , RpcCallAllInstancesInfo(..)
52 96dad12d Agata Murawska
  , RpcResultAllInstancesInfo(..)
53 96dad12d Agata Murawska
54 b9e12624 Hrvoje Ribicic
  , InstanceConsoleInfoParams(..)
55 b9e12624 Hrvoje Ribicic
  , InstanceConsoleInfo(..)
56 b9e12624 Hrvoje Ribicic
  , RpcCallInstanceConsoleInfo(..)
57 b9e12624 Hrvoje Ribicic
  , RpcResultInstanceConsoleInfo(..)
58 b9e12624 Hrvoje Ribicic
59 c1c5aab1 Agata Murawska
  , RpcCallInstanceList(..)
60 c1c5aab1 Agata Murawska
  , RpcResultInstanceList(..)
61 c1c5aab1 Agata Murawska
62 dc623a95 Agata Murawska
  , HvInfo(..)
63 32389d91 Helga Velroyen
  , StorageInfo(..)
64 dc623a95 Agata Murawska
  , RpcCallNodeInfo(..)
65 dc623a95 Agata Murawska
  , RpcResultNodeInfo(..)
66 dc623a95 Agata Murawska
67 8779d21a Agata Murawska
  , RpcCallVersion(..)
68 8779d21a Agata Murawska
  , RpcResultVersion(..)
69 8779d21a Agata Murawska
70 47163f0f Agata Murawska
  , RpcCallStorageList(..)
71 47163f0f Agata Murawska
  , RpcResultStorageList(..)
72 47163f0f Agata Murawska
73 de2a5704 Iustin Pop
  , RpcCallTestDelay(..)
74 de2a5704 Iustin Pop
  , RpcResultTestDelay(..)
75 de2a5704 Iustin Pop
76 842515dd Iustin Pop
  , RpcCallExportList(..)
77 842515dd Iustin Pop
  , RpcResultExportList(..)
78 a716edba Klaus Aehlig
79 a716edba Klaus Aehlig
  , RpcCallJobqueueUpdate(..)
80 5ce9cc30 Klaus Aehlig
  , RpcCallSetWatcherPause(..)
81 83a451f5 Klaus Aehlig
  , RpcCallSetDrainFlag(..)
82 d4709cce Agata Murawska
  ) where
83 d4709cce Agata Murawska
84 9b09c0be Agata Murawska
import Control.Arrow (second)
85 835050f3 Klaus Aehlig
import qualified Codec.Compression.Zlib as Zlib
86 835050f3 Klaus Aehlig
import qualified Data.ByteString.Lazy.Char8 as BL
87 319322a7 Bernardo Dal Seno
import qualified Data.Map as Map
88 319322a7 Bernardo Dal Seno
import Data.Maybe (fromMaybe)
89 d4709cce Agata Murawska
import qualified Text.JSON as J
90 9b09c0be Agata Murawska
import Text.JSON.Pretty (pp_value)
91 835050f3 Klaus Aehlig
import qualified Data.ByteString.Base64.Lazy as Base64
92 b3cc1646 Helga Velroyen
import System.Directory
93 d4709cce Agata Murawska
94 a716edba Klaus Aehlig
import Network.Curl hiding (content)
95 7766de33 Agata Murawska
import qualified Ganeti.Path as P
96 eaed5f19 Agata Murawska
97 8920fa09 Iustin Pop
import Ganeti.BasicTypes
98 eaed5f19 Agata Murawska
import qualified Ganeti.Constants as C
99 c14ba680 Hrvoje Ribicic
import Ganeti.JSON
100 a246ce76 Michele Tartara
import Ganeti.Logging
101 d4709cce Agata Murawska
import Ganeti.Objects
102 96dad12d Agata Murawska
import Ganeti.THH
103 22381768 Iustin Pop
import Ganeti.Types
104 8920fa09 Iustin Pop
import Ganeti.Curl.Multi
105 8920fa09 Iustin Pop
import Ganeti.Utils
106 eaed5f19 Agata Murawska
107 de2a5704 Iustin Pop
-- * Base RPC functionality and types
108 de2a5704 Iustin Pop
109 eaed5f19 Agata Murawska
-- | The curl options used for RPC.
110 eaed5f19 Agata Murawska
curlOpts :: [CurlOption]
111 eaed5f19 Agata Murawska
curlOpts = [ CurlFollowLocation False
112 eaed5f19 Agata Murawska
           , CurlSSLVerifyHost 0
113 eaed5f19 Agata Murawska
           , CurlSSLVerifyPeer True
114 eaed5f19 Agata Murawska
           , CurlSSLCertType "PEM"
115 eaed5f19 Agata Murawska
           , CurlSSLKeyType "PEM"
116 eaed5f19 Agata Murawska
           , CurlConnectTimeout (fromIntegral C.rpcConnectTimeout)
117 eaed5f19 Agata Murawska
           ]
118 d4709cce Agata Murawska
119 d4709cce Agata Murawska
-- | Data type for RPC error reporting.
120 d4709cce Agata Murawska
data RpcError
121 9c0a27d0 Iustin Pop
  = CurlLayerError String
122 d4709cce Agata Murawska
  | JsonDecodeError String
123 6fddde87 Agata Murawska
  | RpcResultError String
124 9c0a27d0 Iustin Pop
  | OfflineNodeError
125 60443f61 Agata Murawska
  deriving (Show, Eq)
126 d4709cce Agata Murawska
127 60443f61 Agata Murawska
-- | Provide explanation to RPC errors.
128 60443f61 Agata Murawska
explainRpcError :: RpcError -> String
129 9c0a27d0 Iustin Pop
explainRpcError (CurlLayerError code) =
130 9c0a27d0 Iustin Pop
    "Curl error:" ++ code
131 60443f61 Agata Murawska
explainRpcError (JsonDecodeError msg) =
132 6fddde87 Agata Murawska
    "Error while decoding JSON from HTTP response: " ++ msg
133 60443f61 Agata Murawska
explainRpcError (RpcResultError msg) =
134 6fddde87 Agata Murawska
    "Error reponse received from RPC server: " ++ msg
135 9c0a27d0 Iustin Pop
explainRpcError OfflineNodeError =
136 9c0a27d0 Iustin Pop
    "Node is marked offline"
137 d4709cce Agata Murawska
138 599239ad Agata Murawska
type ERpcError = Either RpcError
139 599239ad Agata Murawska
140 d4709cce Agata Murawska
-- | A generic class for RPC calls.
141 d4709cce Agata Murawska
class (J.JSON a) => RpcCall a where
142 d4709cce Agata Murawska
  -- | Give the (Python) name of the procedure.
143 d4709cce Agata Murawska
  rpcCallName :: a -> String
144 d4709cce Agata Murawska
  -- | Calculate the timeout value for the call execution.
145 d4709cce Agata Murawska
  rpcCallTimeout :: a -> Int
146 d4709cce Agata Murawska
  -- | Prepare arguments of the call to be send as POST.
147 d4709cce Agata Murawska
  rpcCallData :: Node -> a -> String
148 d4709cce Agata Murawska
  -- | Whether we accept offline nodes when making a call.
149 d4709cce Agata Murawska
  rpcCallAcceptOffline :: a -> Bool
150 d4709cce Agata Murawska
151 d4709cce Agata Murawska
-- | Generic class that ensures matching RPC call with its respective
152 d4709cce Agata Murawska
-- result.
153 47163f0f Agata Murawska
class (RpcCall a, J.JSON b) => Rpc a b  | a -> b, b -> a where
154 47163f0f Agata Murawska
  -- | Create a result based on the received HTTP response.
155 a93b711b Agata Murawska
  rpcResultFill :: a -> J.JSValue -> ERpcError b
156 eaed5f19 Agata Murawska
157 eaed5f19 Agata Murawska
-- | Http Request definition.
158 eaed5f19 Agata Murawska
data HttpClientRequest = HttpClientRequest
159 85f6a869 Iustin Pop
  { requestUrl  :: String       -- ^ The actual URL for the node endpoint
160 85f6a869 Iustin Pop
  , requestData :: String       -- ^ The arguments for the call
161 85f6a869 Iustin Pop
  , requestOpts :: [CurlOption] -- ^ The various curl options
162 eaed5f19 Agata Murawska
  }
163 eaed5f19 Agata Murawska
164 b5c3a4f2 Guido Trotter
-- | Check if a string represented address is IPv6
165 b5c3a4f2 Guido Trotter
isIpV6 :: String -> Bool
166 289e7fcc Klaus Aehlig
isIpV6 = (':' `elem`)
167 b5c3a4f2 Guido Trotter
168 eaed5f19 Agata Murawska
-- | Prepare url for the HTTP request.
169 eaed5f19 Agata Murawska
prepareUrl :: (RpcCall a) => Node -> a -> String
170 eaed5f19 Agata Murawska
prepareUrl node call =
171 eaed5f19 Agata Murawska
  let node_ip = nodePrimaryIp node
172 b5c3a4f2 Guido Trotter
      node_address = if isIpV6 node_ip
173 b5c3a4f2 Guido Trotter
                     then "[" ++ node_ip ++ "]"
174 b5c3a4f2 Guido Trotter
                     else node_ip
175 6dc0cb59 Jose A. Lopes
      port = C.defaultNodedPort
176 b5c3a4f2 Guido Trotter
      path_prefix = "https://" ++ node_address ++ ":" ++ show port
177 5b11f8db Iustin Pop
  in path_prefix ++ "/" ++ rpcCallName call
178 eaed5f19 Agata Murawska
179 eaed5f19 Agata Murawska
-- | Create HTTP request for a given node provided it is online,
180 eaed5f19 Agata Murawska
-- otherwise create empty response.
181 85f6a869 Iustin Pop
prepareHttpRequest :: (RpcCall a) => [CurlOption] -> Node -> a
182 599239ad Agata Murawska
                   -> ERpcError HttpClientRequest
183 85f6a869 Iustin Pop
prepareHttpRequest opts node call
184 5b11f8db Iustin Pop
  | rpcCallAcceptOffline call || not (nodeOffline node) =
185 85f6a869 Iustin Pop
      Right HttpClientRequest { requestUrl  = prepareUrl node call
186 85f6a869 Iustin Pop
                              , requestData = rpcCallData node call
187 85f6a869 Iustin Pop
                              , requestOpts = opts ++ curlOpts
188 5b11f8db Iustin Pop
                              }
189 9c0a27d0 Iustin Pop
  | otherwise = Left OfflineNodeError
190 eaed5f19 Agata Murawska
191 8920fa09 Iustin Pop
-- | Parse an HTTP reply.
192 8920fa09 Iustin Pop
parseHttpReply :: (Rpc a b) =>
193 8920fa09 Iustin Pop
                  a -> ERpcError (CurlCode, String) -> ERpcError b
194 8920fa09 Iustin Pop
parseHttpReply _ (Left e) = Left e
195 8920fa09 Iustin Pop
parseHttpReply call (Right (CurlOK, body)) = parseHttpResponse call body
196 8920fa09 Iustin Pop
parseHttpReply _ (Right (code, err)) =
197 8920fa09 Iustin Pop
  Left . CurlLayerError $ "code: " ++ show code ++ ", explanation: " ++ err
198 8920fa09 Iustin Pop
199 9b09c0be Agata Murawska
-- | Parse a result based on the received HTTP response.
200 8920fa09 Iustin Pop
parseHttpResponse :: (Rpc a b) => a -> String -> ERpcError b
201 8920fa09 Iustin Pop
parseHttpResponse call res =
202 a93b711b Agata Murawska
  case J.decode res of
203 a93b711b Agata Murawska
    J.Error val -> Left $ JsonDecodeError val
204 a93b711b Agata Murawska
    J.Ok (True, res'') -> rpcResultFill call res''
205 a93b711b Agata Murawska
    J.Ok (False, jerr) -> case jerr of
206 a93b711b Agata Murawska
       J.JSString msg -> Left $ RpcResultError (J.fromJSString msg)
207 a93b711b Agata Murawska
       _ -> Left . JsonDecodeError $ show (pp_value jerr)
208 9b09c0be Agata Murawska
209 a246ce76 Michele Tartara
-- | Scan the list of results produced by executeRpcCall and log all the RPC
210 a246ce76 Michele Tartara
-- errors.
211 a246ce76 Michele Tartara
logRpcErrors :: [(a, ERpcError b)] -> IO ()
212 a246ce76 Michele Tartara
logRpcErrors allElems =
213 a246ce76 Michele Tartara
  let logOneRpcErr (_, Right _) = return ()
214 a246ce76 Michele Tartara
      logOneRpcErr (_, Left err) =
215 a246ce76 Michele Tartara
        logError $ "Error in the RPC HTTP reply: " ++ show err
216 a246ce76 Michele Tartara
  in mapM_ logOneRpcErr allElems
217 a246ce76 Michele Tartara
218 ad56f735 Hrvoje Ribicic
-- | Get options for RPC call
219 b3cc1646 Helga Velroyen
getOptionsForCall :: (Rpc a b) => FilePath -> FilePath -> a -> [CurlOption]
220 b3cc1646 Helga Velroyen
getOptionsForCall cert_path client_cert_path call =
221 ad56f735 Hrvoje Ribicic
  [ CurlTimeout (fromIntegral $ rpcCallTimeout call)
222 b3cc1646 Helga Velroyen
  , CurlSSLCert client_cert_path
223 b3cc1646 Helga Velroyen
  , CurlSSLKey client_cert_path
224 b3cc1646 Helga Velroyen
  , CurlCAInfo cert_path
225 ad56f735 Hrvoje Ribicic
  ]
226 ad56f735 Hrvoje Ribicic
227 ad56f735 Hrvoje Ribicic
-- | Execute multiple RPC calls in parallel
228 ad56f735 Hrvoje Ribicic
executeRpcCalls :: (Rpc a b) => [(Node, a)] -> IO [(Node, ERpcError b)]
229 ad56f735 Hrvoje Ribicic
executeRpcCalls nodeCalls = do
230 85f6a869 Iustin Pop
  cert_file <- P.nodedCertFile
231 b3cc1646 Helga Velroyen
  client_cert_file_name <- P.nodedClientCertFile
232 b3cc1646 Helga Velroyen
  client_file_exists <- doesFileExist client_cert_file_name
233 b3cc1646 Helga Velroyen
  -- FIXME: This is needed to ensure upgradability to 2.11
234 b3cc1646 Helga Velroyen
  -- Remove in 2.12.
235 b3cc1646 Helga Velroyen
  let client_cert_file = if client_file_exists
236 b3cc1646 Helga Velroyen
                         then client_cert_file_name
237 b3cc1646 Helga Velroyen
                         else cert_file
238 b3cc1646 Helga Velroyen
      (nodes, calls) = unzip nodeCalls
239 b3cc1646 Helga Velroyen
      opts = map (getOptionsForCall cert_file client_cert_file) calls
240 ad56f735 Hrvoje Ribicic
      opts_urls = zipWith3 (\n c o ->
241 ad56f735 Hrvoje Ribicic
                         case prepareHttpRequest o n c of
242 8920fa09 Iustin Pop
                           Left v -> Left v
243 8920fa09 Iustin Pop
                           Right request ->
244 8920fa09 Iustin Pop
                             Right (CurlPostFields [requestData request]:
245 8920fa09 Iustin Pop
                                    requestOpts request,
246 8920fa09 Iustin Pop
                                    requestUrl request)
247 ad56f735 Hrvoje Ribicic
                    ) nodes calls opts
248 8920fa09 Iustin Pop
  -- split the opts_urls list; we don't want to pass the
249 8920fa09 Iustin Pop
  -- failed-already nodes to Curl
250 8920fa09 Iustin Pop
  let (lefts, rights, trail) = splitEithers opts_urls
251 8920fa09 Iustin Pop
  results <- execMultiCall rights
252 8920fa09 Iustin Pop
  results' <- case recombineEithers lefts results trail of
253 8920fa09 Iustin Pop
                Bad msg -> error msg
254 8920fa09 Iustin Pop
                Ok r -> return r
255 8920fa09 Iustin Pop
  -- now parse the replies
256 ad56f735 Hrvoje Ribicic
  let results'' = zipWith parseHttpReply calls results'
257 c393abbf Michele Tartara
      pairedList = zip nodes results''
258 c393abbf Michele Tartara
  logRpcErrors pairedList
259 c393abbf Michele Tartara
  return pairedList
260 96dad12d Agata Murawska
261 ad56f735 Hrvoje Ribicic
-- | Execute an RPC call for many nodes in parallel.
262 ad56f735 Hrvoje Ribicic
executeRpcCall :: (Rpc a b) => [Node] -> a -> IO [(Node, ERpcError b)]
263 ad56f735 Hrvoje Ribicic
executeRpcCall nodes call = executeRpcCalls . zip nodes $ repeat call
264 ad56f735 Hrvoje Ribicic
265 9b09c0be Agata Murawska
-- | Helper function that is used to read dictionaries of values.
266 9b09c0be Agata Murawska
sanitizeDictResults :: [(String, J.Result a)] -> ERpcError [(String, a)]
267 3d3f562b Agata Murawska
sanitizeDictResults =
268 3d3f562b Agata Murawska
  foldr sanitize1 (Right [])
269 3d3f562b Agata Murawska
  where
270 3d3f562b Agata Murawska
    sanitize1 _ (Left e) = Left e
271 3d3f562b Agata Murawska
    sanitize1 (_, J.Error e) _ = Left $ JsonDecodeError e
272 3d3f562b Agata Murawska
    sanitize1 (name, J.Ok v) (Right res) = Right $ (name, v) : res
273 9b09c0be Agata Murawska
274 7328a28c Agata Murawska
-- | Helper function to tranform JSON Result to Either RpcError b.
275 7328a28c Agata Murawska
-- Note: For now we really only use it for b s.t. Rpc c b for some c
276 7328a28c Agata Murawska
fromJResultToRes :: J.Result a -> (a -> b) -> ERpcError b
277 7328a28c Agata Murawska
fromJResultToRes (J.Error v) _ = Left $ JsonDecodeError v
278 7328a28c Agata Murawska
fromJResultToRes (J.Ok v) f = Right $ f v
279 7328a28c Agata Murawska
280 7328a28c Agata Murawska
-- | Helper function transforming JSValue to Rpc result type.
281 7328a28c Agata Murawska
fromJSValueToRes :: (J.JSON a) => J.JSValue -> (a -> b) -> ERpcError b
282 7328a28c Agata Murawska
fromJSValueToRes val = fromJResultToRes (J.readJSON val)
283 7328a28c Agata Murawska
284 96dad12d Agata Murawska
-- * RPC calls and results
285 96dad12d Agata Murawska
286 de2a5704 Iustin Pop
-- ** Instance info
287 de2a5704 Iustin Pop
288 b9e12624 Hrvoje Ribicic
-- | Returns information about a single instance
289 5188fdb7 Agata Murawska
$(buildObject "RpcCallInstanceInfo" "rpcCallInstInfo"
290 5188fdb7 Agata Murawska
  [ simpleField "instance" [t| String |]
291 5188fdb7 Agata Murawska
  , simpleField "hname" [t| Hypervisor |]
292 5188fdb7 Agata Murawska
  ])
293 96dad12d Agata Murawska
294 14933c17 Jose A. Lopes
$(declareILADT "InstanceState"
295 14933c17 Jose A. Lopes
  [ ("InstanceStateRunning", 0)
296 14933c17 Jose A. Lopes
  , ("InstanceStateShutdown", 1)
297 14933c17 Jose A. Lopes
  ])
298 14933c17 Jose A. Lopes
299 14933c17 Jose A. Lopes
$(makeJSONInstance ''InstanceState)
300 14933c17 Jose A. Lopes
301 14933c17 Jose A. Lopes
instance PyValue InstanceState where
302 14933c17 Jose A. Lopes
  showValue = show . instanceStateToRaw
303 14933c17 Jose A. Lopes
304 5b11f8db Iustin Pop
$(buildObject "InstanceInfo" "instInfo"
305 9b09c0be Agata Murawska
  [ simpleField "memory" [t| Int|]
306 14933c17 Jose A. Lopes
  , simpleField "state"  [t| InstanceState |]
307 96dad12d Agata Murawska
  , simpleField "vcpus"  [t| Int |]
308 96dad12d Agata Murawska
  , simpleField "time"   [t| Int |]
309 96dad12d Agata Murawska
  ])
310 96dad12d Agata Murawska
311 5188fdb7 Agata Murawska
-- This is optional here because the result may be empty if instance is
312 5188fdb7 Agata Murawska
-- not on a node - and this is not considered an error.
313 5188fdb7 Agata Murawska
$(buildObject "RpcResultInstanceInfo" "rpcResInstInfo"
314 5188fdb7 Agata Murawska
  [ optionalField $ simpleField "inst_info" [t| InstanceInfo |]])
315 5188fdb7 Agata Murawska
316 5188fdb7 Agata Murawska
instance RpcCall RpcCallInstanceInfo where
317 274366e5 Agata Murawska
  rpcCallName _          = "instance_info"
318 274366e5 Agata Murawska
  rpcCallTimeout _       = rpcTimeoutToRaw Urgent
319 5188fdb7 Agata Murawska
  rpcCallAcceptOffline _ = False
320 274366e5 Agata Murawska
  rpcCallData _ call     = J.encode
321 5188fdb7 Agata Murawska
    ( rpcCallInstInfoInstance call
322 5188fdb7 Agata Murawska
    , rpcCallInstInfoHname call
323 5188fdb7 Agata Murawska
    )
324 5188fdb7 Agata Murawska
325 5188fdb7 Agata Murawska
instance Rpc RpcCallInstanceInfo RpcResultInstanceInfo where
326 5188fdb7 Agata Murawska
  rpcResultFill _ res =
327 a93b711b Agata Murawska
    case res of
328 5188fdb7 Agata Murawska
      J.JSObject res' ->
329 5188fdb7 Agata Murawska
        case J.fromJSObject res' of
330 5188fdb7 Agata Murawska
          [] -> Right $ RpcResultInstanceInfo Nothing
331 7328a28c Agata Murawska
          _ -> fromJSValueToRes res (RpcResultInstanceInfo . Just)
332 5188fdb7 Agata Murawska
      _ -> Left $ JsonDecodeError
333 70c2362e Agata Murawska
           ("Expected JSObject, got " ++ show (pp_value res))
334 5188fdb7 Agata Murawska
335 de2a5704 Iustin Pop
-- ** AllInstancesInfo
336 de2a5704 Iustin Pop
337 b9e12624 Hrvoje Ribicic
-- | Returns information about all running instances on the given nodes
338 5188fdb7 Agata Murawska
$(buildObject "RpcCallAllInstancesInfo" "rpcCallAllInstInfo"
339 c14ba680 Hrvoje Ribicic
  [ simpleField "hypervisors" [t| [(Hypervisor, HvParams)] |] ])
340 5188fdb7 Agata Murawska
341 5b11f8db Iustin Pop
$(buildObject "RpcResultAllInstancesInfo" "rpcResAllInstInfo"
342 9b09c0be Agata Murawska
  [ simpleField "instances" [t| [(String, InstanceInfo)] |] ])
343 96dad12d Agata Murawska
344 96dad12d Agata Murawska
instance RpcCall RpcCallAllInstancesInfo where
345 274366e5 Agata Murawska
  rpcCallName _          = "all_instances_info"
346 274366e5 Agata Murawska
  rpcCallTimeout _       = rpcTimeoutToRaw Urgent
347 96dad12d Agata Murawska
  rpcCallAcceptOffline _ = False
348 c14ba680 Hrvoje Ribicic
  rpcCallData _ call     = J.encode (
349 c14ba680 Hrvoje Ribicic
    map fst $ rpcCallAllInstInfoHypervisors call,
350 c14ba680 Hrvoje Ribicic
    GenericContainer . Map.fromList $ rpcCallAllInstInfoHypervisors call)
351 9b09c0be Agata Murawska
352 47163f0f Agata Murawska
instance Rpc RpcCallAllInstancesInfo RpcResultAllInstancesInfo where
353 9b09c0be Agata Murawska
  -- FIXME: Is there a simpler way to do it?
354 47163f0f Agata Murawska
  rpcResultFill _ res =
355 a93b711b Agata Murawska
    case res of
356 a93b711b Agata Murawska
      J.JSObject res' ->
357 9b09c0be Agata Murawska
        let res'' = map (second J.readJSON) (J.fromJSObject res')
358 a93b711b Agata Murawska
                        :: [(String, J.Result InstanceInfo)] in
359 9b09c0be Agata Murawska
        case sanitizeDictResults res'' of
360 9b09c0be Agata Murawska
          Left err -> Left err
361 9b09c0be Agata Murawska
          Right insts -> Right $ RpcResultAllInstancesInfo insts
362 9b09c0be Agata Murawska
      _ -> Left $ JsonDecodeError
363 70c2362e Agata Murawska
           ("Expected JSObject, got " ++ show (pp_value res))
364 96dad12d Agata Murawska
365 b9e12624 Hrvoje Ribicic
-- ** InstanceConsoleInfo
366 b9e12624 Hrvoje Ribicic
367 b9e12624 Hrvoje Ribicic
-- | Returns information about how to access instances on the given node
368 b9e12624 Hrvoje Ribicic
$(buildObject "InstanceConsoleInfoParams" "instConsInfoParams"
369 b9e12624 Hrvoje Ribicic
  [ simpleField "instance"    [t| Instance |]
370 b9e12624 Hrvoje Ribicic
  , simpleField "node"        [t| Node |]
371 0808e9d5 Petr Pudlak
  , simpleField "group"       [t| NodeGroup |]
372 b9e12624 Hrvoje Ribicic
  , simpleField "hvParams"    [t| HvParams |]
373 b9e12624 Hrvoje Ribicic
  , simpleField "beParams"    [t| FilledBeParams |]
374 b9e12624 Hrvoje Ribicic
  ])
375 b9e12624 Hrvoje Ribicic
376 b9e12624 Hrvoje Ribicic
$(buildObject "RpcCallInstanceConsoleInfo" "rpcCallInstConsInfo"
377 b9e12624 Hrvoje Ribicic
  [ simpleField "instanceInfo" [t| [(String, InstanceConsoleInfoParams)] |] ])
378 b9e12624 Hrvoje Ribicic
379 b9e12624 Hrvoje Ribicic
$(buildObject "InstanceConsoleInfo" "instConsInfo"
380 b9e12624 Hrvoje Ribicic
  [ simpleField "instance"    [t| String |]
381 b9e12624 Hrvoje Ribicic
  , simpleField "kind"        [t| String |]
382 b9e12624 Hrvoje Ribicic
  , optionalField $
383 b9e12624 Hrvoje Ribicic
    simpleField "message"     [t| String |]
384 b9e12624 Hrvoje Ribicic
  , optionalField $
385 b9e12624 Hrvoje Ribicic
    simpleField "host"        [t| String |]
386 b9e12624 Hrvoje Ribicic
  , optionalField $
387 b9e12624 Hrvoje Ribicic
    simpleField "port"        [t| Int |]
388 b9e12624 Hrvoje Ribicic
  , optionalField $
389 b9e12624 Hrvoje Ribicic
    simpleField "user"        [t| String |]
390 b9e12624 Hrvoje Ribicic
  , optionalField $
391 b9e12624 Hrvoje Ribicic
    simpleField "command"     [t| [String] |]
392 b9e12624 Hrvoje Ribicic
  , optionalField $
393 b9e12624 Hrvoje Ribicic
    simpleField "display"     [t| String |]
394 b9e12624 Hrvoje Ribicic
  ])
395 b9e12624 Hrvoje Ribicic
396 b9e12624 Hrvoje Ribicic
$(buildObject "RpcResultInstanceConsoleInfo" "rpcResInstConsInfo"
397 b9e12624 Hrvoje Ribicic
  [ simpleField "instancesInfo" [t| [(String, InstanceConsoleInfo)] |] ])
398 b9e12624 Hrvoje Ribicic
399 b9e12624 Hrvoje Ribicic
instance RpcCall RpcCallInstanceConsoleInfo where
400 b9e12624 Hrvoje Ribicic
  rpcCallName _          = "instance_console_info"
401 b9e12624 Hrvoje Ribicic
  rpcCallTimeout _       = rpcTimeoutToRaw Urgent
402 b9e12624 Hrvoje Ribicic
  rpcCallAcceptOffline _ = False
403 b9e12624 Hrvoje Ribicic
  rpcCallData _ call     = J.encode .
404 b9e12624 Hrvoje Ribicic
    GenericContainer $ Map.fromList (rpcCallInstConsInfoInstanceInfo call)
405 b9e12624 Hrvoje Ribicic
406 b9e12624 Hrvoje Ribicic
instance Rpc RpcCallInstanceConsoleInfo RpcResultInstanceConsoleInfo where
407 b9e12624 Hrvoje Ribicic
  rpcResultFill _ res =
408 b9e12624 Hrvoje Ribicic
    case res of
409 b9e12624 Hrvoje Ribicic
      J.JSObject res' ->
410 b9e12624 Hrvoje Ribicic
        let res'' = map (second J.readJSON) (J.fromJSObject res')
411 b9e12624 Hrvoje Ribicic
                        :: [(String, J.Result InstanceConsoleInfo)] in
412 b9e12624 Hrvoje Ribicic
        case sanitizeDictResults res'' of
413 b9e12624 Hrvoje Ribicic
          Left err -> Left err
414 b9e12624 Hrvoje Ribicic
          Right instInfos -> Right $ RpcResultInstanceConsoleInfo instInfos
415 b9e12624 Hrvoje Ribicic
      _ -> Left $ JsonDecodeError
416 b9e12624 Hrvoje Ribicic
           ("Expected JSObject, got " ++ show (pp_value res))
417 b9e12624 Hrvoje Ribicic
418 de2a5704 Iustin Pop
-- ** InstanceList
419 de2a5704 Iustin Pop
420 b9e12624 Hrvoje Ribicic
-- | Returns the list of running instances on the given nodes
421 5b11f8db Iustin Pop
$(buildObject "RpcCallInstanceList" "rpcCallInstList"
422 c1c5aab1 Agata Murawska
  [ simpleField "hypervisors" [t| [Hypervisor] |] ])
423 c1c5aab1 Agata Murawska
424 5b11f8db Iustin Pop
$(buildObject "RpcResultInstanceList" "rpcResInstList"
425 9b09c0be Agata Murawska
  [ simpleField "instances" [t| [String] |] ])
426 c1c5aab1 Agata Murawska
427 c1c5aab1 Agata Murawska
instance RpcCall RpcCallInstanceList where
428 274366e5 Agata Murawska
  rpcCallName _          = "instance_list"
429 274366e5 Agata Murawska
  rpcCallTimeout _       = rpcTimeoutToRaw Urgent
430 c1c5aab1 Agata Murawska
  rpcCallAcceptOffline _ = False
431 274366e5 Agata Murawska
  rpcCallData _ call     = J.encode [rpcCallInstListHypervisors call]
432 c1c5aab1 Agata Murawska
433 47163f0f Agata Murawska
instance Rpc RpcCallInstanceList RpcResultInstanceList where
434 7328a28c Agata Murawska
  rpcResultFill _ res = fromJSValueToRes res RpcResultInstanceList
435 c1c5aab1 Agata Murawska
436 de2a5704 Iustin Pop
-- ** NodeInfo
437 de2a5704 Iustin Pop
438 b9e12624 Hrvoje Ribicic
-- | Returns node information
439 5b11f8db Iustin Pop
$(buildObject "RpcCallNodeInfo" "rpcCallNodeInfo"
440 212b66c3 Helga Velroyen
  [ simpleField "storage_units" [t| Map.Map String [StorageUnit] |]
441 030ab01a Helga Velroyen
  , simpleField "hypervisors" [t| [ (Hypervisor, HvParams) ] |]
442 dc623a95 Agata Murawska
  ])
443 dc623a95 Agata Murawska
444 32389d91 Helga Velroyen
$(buildObject "StorageInfo" "storageInfo"
445 dc623a95 Agata Murawska
  [ simpleField "name" [t| String |]
446 0f0f6d7d Helga Velroyen
  , simpleField "type" [t| String |]
447 32389d91 Helga Velroyen
  , optionalField $ simpleField "storage_free" [t| Int |]
448 32389d91 Helga Velroyen
  , optionalField $ simpleField "storage_size" [t| Int |]
449 dc623a95 Agata Murawska
  ])
450 dc623a95 Agata Murawska
451 dc623a95 Agata Murawska
-- | We only provide common fields as described in hv_base.py.
452 5b11f8db Iustin Pop
$(buildObject "HvInfo" "hvInfo"
453 dc623a95 Agata Murawska
  [ simpleField "memory_total" [t| Int |]
454 dc623a95 Agata Murawska
  , simpleField "memory_free" [t| Int |]
455 dc623a95 Agata Murawska
  , simpleField "memory_dom0" [t| Int |]
456 dc623a95 Agata Murawska
  , simpleField "cpu_total" [t| Int |]
457 dc623a95 Agata Murawska
  , simpleField "cpu_nodes" [t| Int |]
458 dc623a95 Agata Murawska
  , simpleField "cpu_sockets" [t| Int |]
459 f43c898d Bernardo Dal Seno
  , simpleField "cpu_dom0" [t| Int |]
460 dc623a95 Agata Murawska
  ])
461 dc623a95 Agata Murawska
462 5b11f8db Iustin Pop
$(buildObject "RpcResultNodeInfo" "rpcResNodeInfo"
463 dc623a95 Agata Murawska
  [ simpleField "boot_id" [t| String |]
464 32389d91 Helga Velroyen
  , simpleField "storage_info" [t| [StorageInfo] |]
465 dc623a95 Agata Murawska
  , simpleField "hv_info" [t| [HvInfo] |]
466 dc623a95 Agata Murawska
  ])
467 dc623a95 Agata Murawska
468 dc623a95 Agata Murawska
instance RpcCall RpcCallNodeInfo where
469 274366e5 Agata Murawska
  rpcCallName _          = "node_info"
470 274366e5 Agata Murawska
  rpcCallTimeout _       = rpcTimeoutToRaw Urgent
471 dc623a95 Agata Murawska
  rpcCallAcceptOffline _ = False
472 319322a7 Bernardo Dal Seno
  rpcCallData n call     = J.encode
473 212b66c3 Helga Velroyen
    ( fromMaybe (error $ "Programmer error: missing parameter for node named "
474 319322a7 Bernardo Dal Seno
                         ++ nodeName n)
475 212b66c3 Helga Velroyen
          $ Map.lookup (nodeUuid n) (rpcCallNodeInfoStorageUnits call)
476 212b66c3 Helga Velroyen
    , rpcCallNodeInfoHypervisors call
477 274366e5 Agata Murawska
    )
478 9b09c0be Agata Murawska
479 47163f0f Agata Murawska
instance Rpc RpcCallNodeInfo RpcResultNodeInfo where
480 47163f0f Agata Murawska
  rpcResultFill _ res =
481 7328a28c Agata Murawska
    fromJSValueToRes res (\(b, vg, hv) -> RpcResultNodeInfo b vg hv)
482 dc623a95 Agata Murawska
483 de2a5704 Iustin Pop
-- ** Version
484 de2a5704 Iustin Pop
485 08f7d24d Iustin Pop
-- | Query node version.
486 08f7d24d Iustin Pop
$(buildObject "RpcCallVersion" "rpcCallVersion" [])
487 8779d21a Agata Murawska
488 08f7d24d Iustin Pop
-- | Query node reply.
489 8779d21a Agata Murawska
$(buildObject "RpcResultVersion" "rpcResultVersion"
490 8779d21a Agata Murawska
  [ simpleField "version" [t| Int |]
491 8779d21a Agata Murawska
  ])
492 8779d21a Agata Murawska
493 8779d21a Agata Murawska
instance RpcCall RpcCallVersion where
494 274366e5 Agata Murawska
  rpcCallName _          = "version"
495 274366e5 Agata Murawska
  rpcCallTimeout _       = rpcTimeoutToRaw Urgent
496 8779d21a Agata Murawska
  rpcCallAcceptOffline _ = True
497 ff8f0049 Iustin Pop
  rpcCallData _          = J.encode
498 8779d21a Agata Murawska
499 47163f0f Agata Murawska
instance Rpc RpcCallVersion RpcResultVersion where
500 7328a28c Agata Murawska
  rpcResultFill _ res = fromJSValueToRes res RpcResultVersion
501 8779d21a Agata Murawska
502 de2a5704 Iustin Pop
-- ** StorageList
503 de2a5704 Iustin Pop
504 47163f0f Agata Murawska
$(buildObject "RpcCallStorageList" "rpcCallStorageList"
505 47163f0f Agata Murawska
  [ simpleField "su_name" [t| StorageType |]
506 47163f0f Agata Murawska
  , simpleField "su_args" [t| [String] |]
507 47163f0f Agata Murawska
  , simpleField "name"    [t| String |]
508 47163f0f Agata Murawska
  , simpleField "fields"  [t| [StorageField] |]
509 47163f0f Agata Murawska
  ])
510 47163f0f Agata Murawska
511 47163f0f Agata Murawska
-- FIXME: The resulting JSValues should have types appropriate for their
512 47163f0f Agata Murawska
-- StorageField value: Used -> Bool, Name -> String etc
513 47163f0f Agata Murawska
$(buildObject "RpcResultStorageList" "rpcResStorageList"
514 47163f0f Agata Murawska
  [ simpleField "storage" [t| [[(StorageField, J.JSValue)]] |] ])
515 47163f0f Agata Murawska
516 47163f0f Agata Murawska
instance RpcCall RpcCallStorageList where
517 274366e5 Agata Murawska
  rpcCallName _          = "storage_list"
518 274366e5 Agata Murawska
  rpcCallTimeout _       = rpcTimeoutToRaw Normal
519 47163f0f Agata Murawska
  rpcCallAcceptOffline _ = False
520 274366e5 Agata Murawska
  rpcCallData _ call     = J.encode
521 47163f0f Agata Murawska
    ( rpcCallStorageListSuName call
522 47163f0f Agata Murawska
    , rpcCallStorageListSuArgs call
523 47163f0f Agata Murawska
    , rpcCallStorageListName call
524 47163f0f Agata Murawska
    , rpcCallStorageListFields call
525 47163f0f Agata Murawska
    )
526 47163f0f Agata Murawska
527 47163f0f Agata Murawska
instance Rpc RpcCallStorageList RpcResultStorageList where
528 47163f0f Agata Murawska
  rpcResultFill call res =
529 47163f0f Agata Murawska
    let sfields = rpcCallStorageListFields call in
530 7328a28c Agata Murawska
    fromJSValueToRes res (RpcResultStorageList . map (zip sfields))
531 de2a5704 Iustin Pop
532 de2a5704 Iustin Pop
-- ** TestDelay
533 de2a5704 Iustin Pop
534 de2a5704 Iustin Pop
-- | Call definition for test delay.
535 de2a5704 Iustin Pop
$(buildObject "RpcCallTestDelay" "rpcCallTestDelay"
536 de2a5704 Iustin Pop
  [ simpleField "duration" [t| Double |]
537 de2a5704 Iustin Pop
  ])
538 de2a5704 Iustin Pop
539 de2a5704 Iustin Pop
-- | Result definition for test delay.
540 de2a5704 Iustin Pop
data RpcResultTestDelay = RpcResultTestDelay
541 de2a5704 Iustin Pop
                          deriving Show
542 de2a5704 Iustin Pop
543 de2a5704 Iustin Pop
-- | Custom JSON instance for null result.
544 de2a5704 Iustin Pop
instance J.JSON RpcResultTestDelay where
545 de2a5704 Iustin Pop
  showJSON _        = J.JSNull
546 de2a5704 Iustin Pop
  readJSON J.JSNull = return RpcResultTestDelay
547 de2a5704 Iustin Pop
  readJSON _        = fail "Unable to read RpcResultTestDelay"
548 de2a5704 Iustin Pop
549 de2a5704 Iustin Pop
instance RpcCall RpcCallTestDelay where
550 de2a5704 Iustin Pop
  rpcCallName _          = "test_delay"
551 de2a5704 Iustin Pop
  rpcCallTimeout         = ceiling . (+ 5) . rpcCallTestDelayDuration
552 de2a5704 Iustin Pop
  rpcCallAcceptOffline _ = False
553 de2a5704 Iustin Pop
  rpcCallData _ call     = J.encode [rpcCallTestDelayDuration call]
554 de2a5704 Iustin Pop
555 de2a5704 Iustin Pop
instance Rpc RpcCallTestDelay RpcResultTestDelay where
556 de2a5704 Iustin Pop
  rpcResultFill _ res = fromJSValueToRes res id
557 842515dd Iustin Pop
558 842515dd Iustin Pop
-- ** ExportList
559 842515dd Iustin Pop
560 842515dd Iustin Pop
-- | Call definition for export list.
561 842515dd Iustin Pop
562 842515dd Iustin Pop
$(buildObject "RpcCallExportList" "rpcCallExportList" [])
563 842515dd Iustin Pop
564 842515dd Iustin Pop
-- | Result definition for export list.
565 842515dd Iustin Pop
$(buildObject "RpcResultExportList" "rpcResExportList"
566 842515dd Iustin Pop
  [ simpleField "exports" [t| [String] |]
567 842515dd Iustin Pop
  ])
568 842515dd Iustin Pop
569 842515dd Iustin Pop
instance RpcCall RpcCallExportList where
570 842515dd Iustin Pop
  rpcCallName _          = "export_list"
571 842515dd Iustin Pop
  rpcCallTimeout _       = rpcTimeoutToRaw Fast
572 842515dd Iustin Pop
  rpcCallAcceptOffline _ = False
573 842515dd Iustin Pop
  rpcCallData _          = J.encode
574 842515dd Iustin Pop
575 842515dd Iustin Pop
instance Rpc RpcCallExportList RpcResultExportList where
576 842515dd Iustin Pop
  rpcResultFill _ res = fromJSValueToRes res RpcResultExportList
577 a716edba Klaus Aehlig
578 a716edba Klaus Aehlig
-- ** Job Queue Replication
579 a716edba Klaus Aehlig
  
580 a716edba Klaus Aehlig
-- | Update a job queue file
581 a716edba Klaus Aehlig
  
582 a716edba Klaus Aehlig
$(buildObject "RpcCallJobqueueUpdate" "rpcCallJobqueueUpdate"
583 a716edba Klaus Aehlig
  [ simpleField "file_name" [t| String |]
584 a716edba Klaus Aehlig
  , simpleField "content" [t| String |]
585 a716edba Klaus Aehlig
  ])
586 a716edba Klaus Aehlig
587 557f5dad Klaus Aehlig
$(buildObject "RpcResultJobQueueUpdate" "rpcResultJobQueueUpdate" [])
588 557f5dad Klaus Aehlig
589 a716edba Klaus Aehlig
instance RpcCall RpcCallJobqueueUpdate where
590 a716edba Klaus Aehlig
  rpcCallName _          = "jobqueue_update"
591 a716edba Klaus Aehlig
  rpcCallTimeout _       = rpcTimeoutToRaw Fast
592 a716edba Klaus Aehlig
  rpcCallAcceptOffline _ = False
593 a716edba Klaus Aehlig
  rpcCallData _ call     = J.encode
594 a716edba Klaus Aehlig
    ( rpcCallJobqueueUpdateFileName call
595 835050f3 Klaus Aehlig
    , ( C.rpcEncodingZlibBase64
596 835050f3 Klaus Aehlig
      , BL.unpack . Base64.encode . Zlib.compress . BL.pack
597 835050f3 Klaus Aehlig
          $ rpcCallJobqueueUpdateContent call
598 a716edba Klaus Aehlig
      )
599 a716edba Klaus Aehlig
    )
600 a716edba Klaus Aehlig
601 557f5dad Klaus Aehlig
instance Rpc RpcCallJobqueueUpdate RpcResultJobQueueUpdate where
602 a716edba Klaus Aehlig
  rpcResultFill _ res =
603 a716edba Klaus Aehlig
    case res of
604 557f5dad Klaus Aehlig
      J.JSNull ->  Right RpcResultJobQueueUpdate
605 a716edba Klaus Aehlig
      _ -> Left $ JsonDecodeError
606 a716edba Klaus Aehlig
           ("Expected JSNull, got " ++ show (pp_value res))
607 a716edba Klaus Aehlig
608 5ce9cc30 Klaus Aehlig
-- ** Watcher Status Update
609 5ce9cc30 Klaus Aehlig
      
610 5ce9cc30 Klaus Aehlig
-- | Set the watcher status
611 5ce9cc30 Klaus Aehlig
      
612 5ce9cc30 Klaus Aehlig
$(buildObject "RpcCallSetWatcherPause" "rpcCallSetWatcherPause"
613 ed7f7fd9 Petr Pudlak
  [ optionalField $ timeAsDoubleField "time"
614 5ce9cc30 Klaus Aehlig
  ])
615 5ce9cc30 Klaus Aehlig
616 5ce9cc30 Klaus Aehlig
instance RpcCall RpcCallSetWatcherPause where
617 5ce9cc30 Klaus Aehlig
  rpcCallName _          = "set_watcher_pause"
618 5ce9cc30 Klaus Aehlig
  rpcCallTimeout _       = rpcTimeoutToRaw Fast
619 5ce9cc30 Klaus Aehlig
  rpcCallAcceptOffline _ = False
620 5ce9cc30 Klaus Aehlig
  rpcCallData _ call     = J.encode
621 ed7f7fd9 Petr Pudlak
    [ maybe J.JSNull (J.showJSON . TimeAsDoubleJSON) $
622 ed7f7fd9 Petr Pudlak
            rpcCallSetWatcherPauseTime call ]
623 5ce9cc30 Klaus Aehlig
624 5ce9cc30 Klaus Aehlig
$(buildObject "RpcResultSetWatcherPause" "rpcResultSetWatcherPause" [])
625 5ce9cc30 Klaus Aehlig
626 5ce9cc30 Klaus Aehlig
instance Rpc RpcCallSetWatcherPause RpcResultSetWatcherPause where
627 5ce9cc30 Klaus Aehlig
  rpcResultFill _ res =
628 5ce9cc30 Klaus Aehlig
    case res of
629 5ce9cc30 Klaus Aehlig
      J.JSNull ->  Right RpcResultSetWatcherPause
630 5ce9cc30 Klaus Aehlig
      _ -> Left $ JsonDecodeError
631 5ce9cc30 Klaus Aehlig
           ("Expected JSNull, got " ++ show (pp_value res))
632 5ce9cc30 Klaus Aehlig
633 83a451f5 Klaus Aehlig
-- ** Queue drain status
634 83a451f5 Klaus Aehlig
      
635 83a451f5 Klaus Aehlig
-- | Set the queu drain flag
636 83a451f5 Klaus Aehlig
      
637 83a451f5 Klaus Aehlig
$(buildObject "RpcCallSetDrainFlag" "rpcCallSetDrainFlag"
638 83a451f5 Klaus Aehlig
  [ simpleField "value" [t| Bool |]
639 83a451f5 Klaus Aehlig
  ])
640 83a451f5 Klaus Aehlig
641 83a451f5 Klaus Aehlig
instance RpcCall RpcCallSetDrainFlag where
642 83a451f5 Klaus Aehlig
  rpcCallName _          = "jobqueue_set_drain_flag"
643 83a451f5 Klaus Aehlig
  rpcCallTimeout _       = rpcTimeoutToRaw Fast
644 83a451f5 Klaus Aehlig
  rpcCallAcceptOffline _ = False
645 83a451f5 Klaus Aehlig
  rpcCallData _ call     = J.encode [ rpcCallSetDrainFlagValue call ]
646 83a451f5 Klaus Aehlig
647 83a451f5 Klaus Aehlig
$(buildObject "RpcResultSetDrainFlag" "rpcResultSetDrainFalg" [])
648 83a451f5 Klaus Aehlig
649 83a451f5 Klaus Aehlig
instance Rpc RpcCallSetDrainFlag RpcResultSetDrainFlag where
650 83a451f5 Klaus Aehlig
  rpcResultFill _ res =
651 83a451f5 Klaus Aehlig
    case res of
652 83a451f5 Klaus Aehlig
      J.JSNull ->  Right RpcResultSetDrainFlag
653 83a451f5 Klaus Aehlig
      _ -> Left $ JsonDecodeError
654 83a451f5 Klaus Aehlig
           ("Expected JSNull, got " ++ show (pp_value res))