Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / Rpc.hs @ 560ef132

History | View | Annotate | Download (22.2 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 40ad3e85 Klaus Aehlig
  , RpcCallJobqueueRename(..)
81 5ce9cc30 Klaus Aehlig
  , RpcCallSetWatcherPause(..)
82 83a451f5 Klaus Aehlig
  , RpcCallSetDrainFlag(..)
83 d4709cce Agata Murawska
  ) where
84 d4709cce Agata Murawska
85 9b09c0be Agata Murawska
import Control.Arrow (second)
86 835050f3 Klaus Aehlig
import qualified Codec.Compression.Zlib as Zlib
87 835050f3 Klaus Aehlig
import qualified Data.ByteString.Lazy.Char8 as BL
88 319322a7 Bernardo Dal Seno
import qualified Data.Map as Map
89 319322a7 Bernardo Dal Seno
import Data.Maybe (fromMaybe)
90 d4709cce Agata Murawska
import qualified Text.JSON as J
91 9b09c0be Agata Murawska
import Text.JSON.Pretty (pp_value)
92 835050f3 Klaus Aehlig
import qualified Data.ByteString.Base64.Lazy as Base64
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 45f75526 Helga Velroyen
  let (nodes, calls) = unzip nodeCalls
232 45f75526 Helga Velroyen
      opts = map (getOptionsForCall cert_file cert_file) calls
233 ad56f735 Hrvoje Ribicic
      opts_urls = zipWith3 (\n c o ->
234 ad56f735 Hrvoje Ribicic
                         case prepareHttpRequest o n c of
235 8920fa09 Iustin Pop
                           Left v -> Left v
236 8920fa09 Iustin Pop
                           Right request ->
237 8920fa09 Iustin Pop
                             Right (CurlPostFields [requestData request]:
238 8920fa09 Iustin Pop
                                    requestOpts request,
239 8920fa09 Iustin Pop
                                    requestUrl request)
240 ad56f735 Hrvoje Ribicic
                    ) nodes calls opts
241 8920fa09 Iustin Pop
  -- split the opts_urls list; we don't want to pass the
242 8920fa09 Iustin Pop
  -- failed-already nodes to Curl
243 8920fa09 Iustin Pop
  let (lefts, rights, trail) = splitEithers opts_urls
244 8920fa09 Iustin Pop
  results <- execMultiCall rights
245 8920fa09 Iustin Pop
  results' <- case recombineEithers lefts results trail of
246 8920fa09 Iustin Pop
                Bad msg -> error msg
247 8920fa09 Iustin Pop
                Ok r -> return r
248 8920fa09 Iustin Pop
  -- now parse the replies
249 ad56f735 Hrvoje Ribicic
  let results'' = zipWith parseHttpReply calls results'
250 c393abbf Michele Tartara
      pairedList = zip nodes results''
251 c393abbf Michele Tartara
  logRpcErrors pairedList
252 c393abbf Michele Tartara
  return pairedList
253 96dad12d Agata Murawska
254 ad56f735 Hrvoje Ribicic
-- | Execute an RPC call for many nodes in parallel.
255 ad56f735 Hrvoje Ribicic
executeRpcCall :: (Rpc a b) => [Node] -> a -> IO [(Node, ERpcError b)]
256 ad56f735 Hrvoje Ribicic
executeRpcCall nodes call = executeRpcCalls . zip nodes $ repeat call
257 ad56f735 Hrvoje Ribicic
258 9b09c0be Agata Murawska
-- | Helper function that is used to read dictionaries of values.
259 9b09c0be Agata Murawska
sanitizeDictResults :: [(String, J.Result a)] -> ERpcError [(String, a)]
260 3d3f562b Agata Murawska
sanitizeDictResults =
261 3d3f562b Agata Murawska
  foldr sanitize1 (Right [])
262 3d3f562b Agata Murawska
  where
263 3d3f562b Agata Murawska
    sanitize1 _ (Left e) = Left e
264 3d3f562b Agata Murawska
    sanitize1 (_, J.Error e) _ = Left $ JsonDecodeError e
265 3d3f562b Agata Murawska
    sanitize1 (name, J.Ok v) (Right res) = Right $ (name, v) : res
266 9b09c0be Agata Murawska
267 7328a28c Agata Murawska
-- | Helper function to tranform JSON Result to Either RpcError b.
268 7328a28c Agata Murawska
-- Note: For now we really only use it for b s.t. Rpc c b for some c
269 7328a28c Agata Murawska
fromJResultToRes :: J.Result a -> (a -> b) -> ERpcError b
270 7328a28c Agata Murawska
fromJResultToRes (J.Error v) _ = Left $ JsonDecodeError v
271 7328a28c Agata Murawska
fromJResultToRes (J.Ok v) f = Right $ f v
272 7328a28c Agata Murawska
273 7328a28c Agata Murawska
-- | Helper function transforming JSValue to Rpc result type.
274 7328a28c Agata Murawska
fromJSValueToRes :: (J.JSON a) => J.JSValue -> (a -> b) -> ERpcError b
275 7328a28c Agata Murawska
fromJSValueToRes val = fromJResultToRes (J.readJSON val)
276 7328a28c Agata Murawska
277 96dad12d Agata Murawska
-- * RPC calls and results
278 96dad12d Agata Murawska
279 de2a5704 Iustin Pop
-- ** Instance info
280 de2a5704 Iustin Pop
281 b9e12624 Hrvoje Ribicic
-- | Returns information about a single instance
282 5188fdb7 Agata Murawska
$(buildObject "RpcCallInstanceInfo" "rpcCallInstInfo"
283 5188fdb7 Agata Murawska
  [ simpleField "instance" [t| String |]
284 5188fdb7 Agata Murawska
  , simpleField "hname" [t| Hypervisor |]
285 5188fdb7 Agata Murawska
  ])
286 96dad12d Agata Murawska
287 14933c17 Jose A. Lopes
$(declareILADT "InstanceState"
288 14933c17 Jose A. Lopes
  [ ("InstanceStateRunning", 0)
289 14933c17 Jose A. Lopes
  , ("InstanceStateShutdown", 1)
290 14933c17 Jose A. Lopes
  ])
291 14933c17 Jose A. Lopes
292 14933c17 Jose A. Lopes
$(makeJSONInstance ''InstanceState)
293 14933c17 Jose A. Lopes
294 14933c17 Jose A. Lopes
instance PyValue InstanceState where
295 14933c17 Jose A. Lopes
  showValue = show . instanceStateToRaw
296 14933c17 Jose A. Lopes
297 5b11f8db Iustin Pop
$(buildObject "InstanceInfo" "instInfo"
298 9b09c0be Agata Murawska
  [ simpleField "memory" [t| Int|]
299 14933c17 Jose A. Lopes
  , simpleField "state"  [t| InstanceState |]
300 96dad12d Agata Murawska
  , simpleField "vcpus"  [t| Int |]
301 96dad12d Agata Murawska
  , simpleField "time"   [t| Int |]
302 96dad12d Agata Murawska
  ])
303 96dad12d Agata Murawska
304 5188fdb7 Agata Murawska
-- This is optional here because the result may be empty if instance is
305 5188fdb7 Agata Murawska
-- not on a node - and this is not considered an error.
306 5188fdb7 Agata Murawska
$(buildObject "RpcResultInstanceInfo" "rpcResInstInfo"
307 5188fdb7 Agata Murawska
  [ optionalField $ simpleField "inst_info" [t| InstanceInfo |]])
308 5188fdb7 Agata Murawska
309 5188fdb7 Agata Murawska
instance RpcCall RpcCallInstanceInfo where
310 274366e5 Agata Murawska
  rpcCallName _          = "instance_info"
311 274366e5 Agata Murawska
  rpcCallTimeout _       = rpcTimeoutToRaw Urgent
312 5188fdb7 Agata Murawska
  rpcCallAcceptOffline _ = False
313 274366e5 Agata Murawska
  rpcCallData _ call     = J.encode
314 5188fdb7 Agata Murawska
    ( rpcCallInstInfoInstance call
315 5188fdb7 Agata Murawska
    , rpcCallInstInfoHname call
316 5188fdb7 Agata Murawska
    )
317 5188fdb7 Agata Murawska
318 5188fdb7 Agata Murawska
instance Rpc RpcCallInstanceInfo RpcResultInstanceInfo where
319 5188fdb7 Agata Murawska
  rpcResultFill _ res =
320 a93b711b Agata Murawska
    case res of
321 5188fdb7 Agata Murawska
      J.JSObject res' ->
322 5188fdb7 Agata Murawska
        case J.fromJSObject res' of
323 5188fdb7 Agata Murawska
          [] -> Right $ RpcResultInstanceInfo Nothing
324 7328a28c Agata Murawska
          _ -> fromJSValueToRes res (RpcResultInstanceInfo . Just)
325 5188fdb7 Agata Murawska
      _ -> Left $ JsonDecodeError
326 70c2362e Agata Murawska
           ("Expected JSObject, got " ++ show (pp_value res))
327 5188fdb7 Agata Murawska
328 de2a5704 Iustin Pop
-- ** AllInstancesInfo
329 de2a5704 Iustin Pop
330 b9e12624 Hrvoje Ribicic
-- | Returns information about all running instances on the given nodes
331 5188fdb7 Agata Murawska
$(buildObject "RpcCallAllInstancesInfo" "rpcCallAllInstInfo"
332 c14ba680 Hrvoje Ribicic
  [ simpleField "hypervisors" [t| [(Hypervisor, HvParams)] |] ])
333 5188fdb7 Agata Murawska
334 5b11f8db Iustin Pop
$(buildObject "RpcResultAllInstancesInfo" "rpcResAllInstInfo"
335 9b09c0be Agata Murawska
  [ simpleField "instances" [t| [(String, InstanceInfo)] |] ])
336 96dad12d Agata Murawska
337 96dad12d Agata Murawska
instance RpcCall RpcCallAllInstancesInfo where
338 274366e5 Agata Murawska
  rpcCallName _          = "all_instances_info"
339 274366e5 Agata Murawska
  rpcCallTimeout _       = rpcTimeoutToRaw Urgent
340 96dad12d Agata Murawska
  rpcCallAcceptOffline _ = False
341 c14ba680 Hrvoje Ribicic
  rpcCallData _ call     = J.encode (
342 c14ba680 Hrvoje Ribicic
    map fst $ rpcCallAllInstInfoHypervisors call,
343 c14ba680 Hrvoje Ribicic
    GenericContainer . Map.fromList $ rpcCallAllInstInfoHypervisors call)
344 9b09c0be Agata Murawska
345 47163f0f Agata Murawska
instance Rpc RpcCallAllInstancesInfo RpcResultAllInstancesInfo where
346 9b09c0be Agata Murawska
  -- FIXME: Is there a simpler way to do it?
347 47163f0f Agata Murawska
  rpcResultFill _ res =
348 a93b711b Agata Murawska
    case res of
349 a93b711b Agata Murawska
      J.JSObject res' ->
350 9b09c0be Agata Murawska
        let res'' = map (second J.readJSON) (J.fromJSObject res')
351 a93b711b Agata Murawska
                        :: [(String, J.Result InstanceInfo)] in
352 9b09c0be Agata Murawska
        case sanitizeDictResults res'' of
353 9b09c0be Agata Murawska
          Left err -> Left err
354 9b09c0be Agata Murawska
          Right insts -> Right $ RpcResultAllInstancesInfo insts
355 9b09c0be Agata Murawska
      _ -> Left $ JsonDecodeError
356 70c2362e Agata Murawska
           ("Expected JSObject, got " ++ show (pp_value res))
357 96dad12d Agata Murawska
358 b9e12624 Hrvoje Ribicic
-- ** InstanceConsoleInfo
359 b9e12624 Hrvoje Ribicic
360 b9e12624 Hrvoje Ribicic
-- | Returns information about how to access instances on the given node
361 b9e12624 Hrvoje Ribicic
$(buildObject "InstanceConsoleInfoParams" "instConsInfoParams"
362 b9e12624 Hrvoje Ribicic
  [ simpleField "instance"    [t| Instance |]
363 b9e12624 Hrvoje Ribicic
  , simpleField "node"        [t| Node |]
364 0808e9d5 Petr Pudlak
  , simpleField "group"       [t| NodeGroup |]
365 b9e12624 Hrvoje Ribicic
  , simpleField "hvParams"    [t| HvParams |]
366 b9e12624 Hrvoje Ribicic
  , simpleField "beParams"    [t| FilledBeParams |]
367 b9e12624 Hrvoje Ribicic
  ])
368 b9e12624 Hrvoje Ribicic
369 b9e12624 Hrvoje Ribicic
$(buildObject "RpcCallInstanceConsoleInfo" "rpcCallInstConsInfo"
370 b9e12624 Hrvoje Ribicic
  [ simpleField "instanceInfo" [t| [(String, InstanceConsoleInfoParams)] |] ])
371 b9e12624 Hrvoje Ribicic
372 b9e12624 Hrvoje Ribicic
$(buildObject "InstanceConsoleInfo" "instConsInfo"
373 b9e12624 Hrvoje Ribicic
  [ simpleField "instance"    [t| String |]
374 b9e12624 Hrvoje Ribicic
  , simpleField "kind"        [t| String |]
375 b9e12624 Hrvoje Ribicic
  , optionalField $
376 b9e12624 Hrvoje Ribicic
    simpleField "message"     [t| String |]
377 b9e12624 Hrvoje Ribicic
  , optionalField $
378 b9e12624 Hrvoje Ribicic
    simpleField "host"        [t| String |]
379 b9e12624 Hrvoje Ribicic
  , optionalField $
380 b9e12624 Hrvoje Ribicic
    simpleField "port"        [t| Int |]
381 b9e12624 Hrvoje Ribicic
  , optionalField $
382 b9e12624 Hrvoje Ribicic
    simpleField "user"        [t| String |]
383 b9e12624 Hrvoje Ribicic
  , optionalField $
384 b9e12624 Hrvoje Ribicic
    simpleField "command"     [t| [String] |]
385 b9e12624 Hrvoje Ribicic
  , optionalField $
386 b9e12624 Hrvoje Ribicic
    simpleField "display"     [t| String |]
387 b9e12624 Hrvoje Ribicic
  ])
388 b9e12624 Hrvoje Ribicic
389 b9e12624 Hrvoje Ribicic
$(buildObject "RpcResultInstanceConsoleInfo" "rpcResInstConsInfo"
390 b9e12624 Hrvoje Ribicic
  [ simpleField "instancesInfo" [t| [(String, InstanceConsoleInfo)] |] ])
391 b9e12624 Hrvoje Ribicic
392 b9e12624 Hrvoje Ribicic
instance RpcCall RpcCallInstanceConsoleInfo where
393 b9e12624 Hrvoje Ribicic
  rpcCallName _          = "instance_console_info"
394 b9e12624 Hrvoje Ribicic
  rpcCallTimeout _       = rpcTimeoutToRaw Urgent
395 b9e12624 Hrvoje Ribicic
  rpcCallAcceptOffline _ = False
396 b9e12624 Hrvoje Ribicic
  rpcCallData _ call     = J.encode .
397 b9e12624 Hrvoje Ribicic
    GenericContainer $ Map.fromList (rpcCallInstConsInfoInstanceInfo call)
398 b9e12624 Hrvoje Ribicic
399 b9e12624 Hrvoje Ribicic
instance Rpc RpcCallInstanceConsoleInfo RpcResultInstanceConsoleInfo where
400 b9e12624 Hrvoje Ribicic
  rpcResultFill _ res =
401 b9e12624 Hrvoje Ribicic
    case res of
402 b9e12624 Hrvoje Ribicic
      J.JSObject res' ->
403 b9e12624 Hrvoje Ribicic
        let res'' = map (second J.readJSON) (J.fromJSObject res')
404 b9e12624 Hrvoje Ribicic
                        :: [(String, J.Result InstanceConsoleInfo)] in
405 b9e12624 Hrvoje Ribicic
        case sanitizeDictResults res'' of
406 b9e12624 Hrvoje Ribicic
          Left err -> Left err
407 b9e12624 Hrvoje Ribicic
          Right instInfos -> Right $ RpcResultInstanceConsoleInfo instInfos
408 b9e12624 Hrvoje Ribicic
      _ -> Left $ JsonDecodeError
409 b9e12624 Hrvoje Ribicic
           ("Expected JSObject, got " ++ show (pp_value res))
410 b9e12624 Hrvoje Ribicic
411 de2a5704 Iustin Pop
-- ** InstanceList
412 de2a5704 Iustin Pop
413 b9e12624 Hrvoje Ribicic
-- | Returns the list of running instances on the given nodes
414 5b11f8db Iustin Pop
$(buildObject "RpcCallInstanceList" "rpcCallInstList"
415 c1c5aab1 Agata Murawska
  [ simpleField "hypervisors" [t| [Hypervisor] |] ])
416 c1c5aab1 Agata Murawska
417 5b11f8db Iustin Pop
$(buildObject "RpcResultInstanceList" "rpcResInstList"
418 9b09c0be Agata Murawska
  [ simpleField "instances" [t| [String] |] ])
419 c1c5aab1 Agata Murawska
420 c1c5aab1 Agata Murawska
instance RpcCall RpcCallInstanceList where
421 274366e5 Agata Murawska
  rpcCallName _          = "instance_list"
422 274366e5 Agata Murawska
  rpcCallTimeout _       = rpcTimeoutToRaw Urgent
423 c1c5aab1 Agata Murawska
  rpcCallAcceptOffline _ = False
424 274366e5 Agata Murawska
  rpcCallData _ call     = J.encode [rpcCallInstListHypervisors call]
425 c1c5aab1 Agata Murawska
426 47163f0f Agata Murawska
instance Rpc RpcCallInstanceList RpcResultInstanceList where
427 7328a28c Agata Murawska
  rpcResultFill _ res = fromJSValueToRes res RpcResultInstanceList
428 c1c5aab1 Agata Murawska
429 de2a5704 Iustin Pop
-- ** NodeInfo
430 de2a5704 Iustin Pop
431 b9e12624 Hrvoje Ribicic
-- | Returns node information
432 5b11f8db Iustin Pop
$(buildObject "RpcCallNodeInfo" "rpcCallNodeInfo"
433 212b66c3 Helga Velroyen
  [ simpleField "storage_units" [t| Map.Map String [StorageUnit] |]
434 030ab01a Helga Velroyen
  , simpleField "hypervisors" [t| [ (Hypervisor, HvParams) ] |]
435 dc623a95 Agata Murawska
  ])
436 dc623a95 Agata Murawska
437 32389d91 Helga Velroyen
$(buildObject "StorageInfo" "storageInfo"
438 dc623a95 Agata Murawska
  [ simpleField "name" [t| String |]
439 0f0f6d7d Helga Velroyen
  , simpleField "type" [t| String |]
440 32389d91 Helga Velroyen
  , optionalField $ simpleField "storage_free" [t| Int |]
441 32389d91 Helga Velroyen
  , optionalField $ simpleField "storage_size" [t| Int |]
442 dc623a95 Agata Murawska
  ])
443 dc623a95 Agata Murawska
444 dc623a95 Agata Murawska
-- | We only provide common fields as described in hv_base.py.
445 5b11f8db Iustin Pop
$(buildObject "HvInfo" "hvInfo"
446 dc623a95 Agata Murawska
  [ simpleField "memory_total" [t| Int |]
447 dc623a95 Agata Murawska
  , simpleField "memory_free" [t| Int |]
448 dc623a95 Agata Murawska
  , simpleField "memory_dom0" [t| Int |]
449 dc623a95 Agata Murawska
  , simpleField "cpu_total" [t| Int |]
450 dc623a95 Agata Murawska
  , simpleField "cpu_nodes" [t| Int |]
451 dc623a95 Agata Murawska
  , simpleField "cpu_sockets" [t| Int |]
452 f43c898d Bernardo Dal Seno
  , simpleField "cpu_dom0" [t| Int |]
453 dc623a95 Agata Murawska
  ])
454 dc623a95 Agata Murawska
455 5b11f8db Iustin Pop
$(buildObject "RpcResultNodeInfo" "rpcResNodeInfo"
456 dc623a95 Agata Murawska
  [ simpleField "boot_id" [t| String |]
457 32389d91 Helga Velroyen
  , simpleField "storage_info" [t| [StorageInfo] |]
458 dc623a95 Agata Murawska
  , simpleField "hv_info" [t| [HvInfo] |]
459 dc623a95 Agata Murawska
  ])
460 dc623a95 Agata Murawska
461 dc623a95 Agata Murawska
instance RpcCall RpcCallNodeInfo where
462 274366e5 Agata Murawska
  rpcCallName _          = "node_info"
463 274366e5 Agata Murawska
  rpcCallTimeout _       = rpcTimeoutToRaw Urgent
464 dc623a95 Agata Murawska
  rpcCallAcceptOffline _ = False
465 319322a7 Bernardo Dal Seno
  rpcCallData n call     = J.encode
466 212b66c3 Helga Velroyen
    ( fromMaybe (error $ "Programmer error: missing parameter for node named "
467 319322a7 Bernardo Dal Seno
                         ++ nodeName n)
468 212b66c3 Helga Velroyen
          $ Map.lookup (nodeUuid n) (rpcCallNodeInfoStorageUnits call)
469 212b66c3 Helga Velroyen
    , rpcCallNodeInfoHypervisors call
470 274366e5 Agata Murawska
    )
471 9b09c0be Agata Murawska
472 47163f0f Agata Murawska
instance Rpc RpcCallNodeInfo RpcResultNodeInfo where
473 47163f0f Agata Murawska
  rpcResultFill _ res =
474 7328a28c Agata Murawska
    fromJSValueToRes res (\(b, vg, hv) -> RpcResultNodeInfo b vg hv)
475 dc623a95 Agata Murawska
476 de2a5704 Iustin Pop
-- ** Version
477 de2a5704 Iustin Pop
478 08f7d24d Iustin Pop
-- | Query node version.
479 08f7d24d Iustin Pop
$(buildObject "RpcCallVersion" "rpcCallVersion" [])
480 8779d21a Agata Murawska
481 08f7d24d Iustin Pop
-- | Query node reply.
482 8779d21a Agata Murawska
$(buildObject "RpcResultVersion" "rpcResultVersion"
483 8779d21a Agata Murawska
  [ simpleField "version" [t| Int |]
484 8779d21a Agata Murawska
  ])
485 8779d21a Agata Murawska
486 8779d21a Agata Murawska
instance RpcCall RpcCallVersion where
487 274366e5 Agata Murawska
  rpcCallName _          = "version"
488 274366e5 Agata Murawska
  rpcCallTimeout _       = rpcTimeoutToRaw Urgent
489 8779d21a Agata Murawska
  rpcCallAcceptOffline _ = True
490 ff8f0049 Iustin Pop
  rpcCallData _          = J.encode
491 8779d21a Agata Murawska
492 47163f0f Agata Murawska
instance Rpc RpcCallVersion RpcResultVersion where
493 7328a28c Agata Murawska
  rpcResultFill _ res = fromJSValueToRes res RpcResultVersion
494 8779d21a Agata Murawska
495 de2a5704 Iustin Pop
-- ** StorageList
496 de2a5704 Iustin Pop
497 47163f0f Agata Murawska
$(buildObject "RpcCallStorageList" "rpcCallStorageList"
498 47163f0f Agata Murawska
  [ simpleField "su_name" [t| StorageType |]
499 47163f0f Agata Murawska
  , simpleField "su_args" [t| [String] |]
500 47163f0f Agata Murawska
  , simpleField "name"    [t| String |]
501 47163f0f Agata Murawska
  , simpleField "fields"  [t| [StorageField] |]
502 47163f0f Agata Murawska
  ])
503 47163f0f Agata Murawska
504 47163f0f Agata Murawska
-- FIXME: The resulting JSValues should have types appropriate for their
505 47163f0f Agata Murawska
-- StorageField value: Used -> Bool, Name -> String etc
506 47163f0f Agata Murawska
$(buildObject "RpcResultStorageList" "rpcResStorageList"
507 47163f0f Agata Murawska
  [ simpleField "storage" [t| [[(StorageField, J.JSValue)]] |] ])
508 47163f0f Agata Murawska
509 47163f0f Agata Murawska
instance RpcCall RpcCallStorageList where
510 274366e5 Agata Murawska
  rpcCallName _          = "storage_list"
511 274366e5 Agata Murawska
  rpcCallTimeout _       = rpcTimeoutToRaw Normal
512 47163f0f Agata Murawska
  rpcCallAcceptOffline _ = False
513 274366e5 Agata Murawska
  rpcCallData _ call     = J.encode
514 47163f0f Agata Murawska
    ( rpcCallStorageListSuName call
515 47163f0f Agata Murawska
    , rpcCallStorageListSuArgs call
516 47163f0f Agata Murawska
    , rpcCallStorageListName call
517 47163f0f Agata Murawska
    , rpcCallStorageListFields call
518 47163f0f Agata Murawska
    )
519 47163f0f Agata Murawska
520 47163f0f Agata Murawska
instance Rpc RpcCallStorageList RpcResultStorageList where
521 47163f0f Agata Murawska
  rpcResultFill call res =
522 47163f0f Agata Murawska
    let sfields = rpcCallStorageListFields call in
523 7328a28c Agata Murawska
    fromJSValueToRes res (RpcResultStorageList . map (zip sfields))
524 de2a5704 Iustin Pop
525 de2a5704 Iustin Pop
-- ** TestDelay
526 de2a5704 Iustin Pop
527 de2a5704 Iustin Pop
-- | Call definition for test delay.
528 de2a5704 Iustin Pop
$(buildObject "RpcCallTestDelay" "rpcCallTestDelay"
529 de2a5704 Iustin Pop
  [ simpleField "duration" [t| Double |]
530 de2a5704 Iustin Pop
  ])
531 de2a5704 Iustin Pop
532 de2a5704 Iustin Pop
-- | Result definition for test delay.
533 de2a5704 Iustin Pop
data RpcResultTestDelay = RpcResultTestDelay
534 de2a5704 Iustin Pop
                          deriving Show
535 de2a5704 Iustin Pop
536 de2a5704 Iustin Pop
-- | Custom JSON instance for null result.
537 de2a5704 Iustin Pop
instance J.JSON RpcResultTestDelay where
538 de2a5704 Iustin Pop
  showJSON _        = J.JSNull
539 de2a5704 Iustin Pop
  readJSON J.JSNull = return RpcResultTestDelay
540 de2a5704 Iustin Pop
  readJSON _        = fail "Unable to read RpcResultTestDelay"
541 de2a5704 Iustin Pop
542 de2a5704 Iustin Pop
instance RpcCall RpcCallTestDelay where
543 de2a5704 Iustin Pop
  rpcCallName _          = "test_delay"
544 de2a5704 Iustin Pop
  rpcCallTimeout         = ceiling . (+ 5) . rpcCallTestDelayDuration
545 de2a5704 Iustin Pop
  rpcCallAcceptOffline _ = False
546 de2a5704 Iustin Pop
  rpcCallData _ call     = J.encode [rpcCallTestDelayDuration call]
547 de2a5704 Iustin Pop
548 de2a5704 Iustin Pop
instance Rpc RpcCallTestDelay RpcResultTestDelay where
549 de2a5704 Iustin Pop
  rpcResultFill _ res = fromJSValueToRes res id
550 842515dd Iustin Pop
551 842515dd Iustin Pop
-- ** ExportList
552 842515dd Iustin Pop
553 842515dd Iustin Pop
-- | Call definition for export list.
554 842515dd Iustin Pop
555 842515dd Iustin Pop
$(buildObject "RpcCallExportList" "rpcCallExportList" [])
556 842515dd Iustin Pop
557 842515dd Iustin Pop
-- | Result definition for export list.
558 842515dd Iustin Pop
$(buildObject "RpcResultExportList" "rpcResExportList"
559 842515dd Iustin Pop
  [ simpleField "exports" [t| [String] |]
560 842515dd Iustin Pop
  ])
561 842515dd Iustin Pop
562 842515dd Iustin Pop
instance RpcCall RpcCallExportList where
563 842515dd Iustin Pop
  rpcCallName _          = "export_list"
564 842515dd Iustin Pop
  rpcCallTimeout _       = rpcTimeoutToRaw Fast
565 842515dd Iustin Pop
  rpcCallAcceptOffline _ = False
566 842515dd Iustin Pop
  rpcCallData _          = J.encode
567 842515dd Iustin Pop
568 842515dd Iustin Pop
instance Rpc RpcCallExportList RpcResultExportList where
569 842515dd Iustin Pop
  rpcResultFill _ res = fromJSValueToRes res RpcResultExportList
570 a716edba Klaus Aehlig
571 a716edba Klaus Aehlig
-- ** Job Queue Replication
572 a716edba Klaus Aehlig
  
573 a716edba Klaus Aehlig
-- | Update a job queue file
574 a716edba Klaus Aehlig
  
575 a716edba Klaus Aehlig
$(buildObject "RpcCallJobqueueUpdate" "rpcCallJobqueueUpdate"
576 a716edba Klaus Aehlig
  [ simpleField "file_name" [t| String |]
577 a716edba Klaus Aehlig
  , simpleField "content" [t| String |]
578 a716edba Klaus Aehlig
  ])
579 a716edba Klaus Aehlig
580 557f5dad Klaus Aehlig
$(buildObject "RpcResultJobQueueUpdate" "rpcResultJobQueueUpdate" [])
581 557f5dad Klaus Aehlig
582 a716edba Klaus Aehlig
instance RpcCall RpcCallJobqueueUpdate where
583 a716edba Klaus Aehlig
  rpcCallName _          = "jobqueue_update"
584 a716edba Klaus Aehlig
  rpcCallTimeout _       = rpcTimeoutToRaw Fast
585 a716edba Klaus Aehlig
  rpcCallAcceptOffline _ = False
586 a716edba Klaus Aehlig
  rpcCallData _ call     = J.encode
587 a716edba Klaus Aehlig
    ( rpcCallJobqueueUpdateFileName call
588 835050f3 Klaus Aehlig
    , ( C.rpcEncodingZlibBase64
589 835050f3 Klaus Aehlig
      , BL.unpack . Base64.encode . Zlib.compress . BL.pack
590 835050f3 Klaus Aehlig
          $ rpcCallJobqueueUpdateContent call
591 a716edba Klaus Aehlig
      )
592 a716edba Klaus Aehlig
    )
593 a716edba Klaus Aehlig
594 557f5dad Klaus Aehlig
instance Rpc RpcCallJobqueueUpdate RpcResultJobQueueUpdate where
595 a716edba Klaus Aehlig
  rpcResultFill _ res =
596 a716edba Klaus Aehlig
    case res of
597 557f5dad Klaus Aehlig
      J.JSNull ->  Right RpcResultJobQueueUpdate
598 a716edba Klaus Aehlig
      _ -> Left $ JsonDecodeError
599 a716edba Klaus Aehlig
           ("Expected JSNull, got " ++ show (pp_value res))
600 a716edba Klaus Aehlig
601 40ad3e85 Klaus Aehlig
-- | Rename a file in the job queue
602 40ad3e85 Klaus Aehlig
603 40ad3e85 Klaus Aehlig
$(buildObject "RpcCallJobqueueRename" "rpcCallJobqueueRename"
604 40ad3e85 Klaus Aehlig
  [ simpleField "rename" [t| [(String, String)] |]
605 40ad3e85 Klaus Aehlig
  ])
606 40ad3e85 Klaus Aehlig
607 40ad3e85 Klaus Aehlig
$(buildObject "RpcResultJobqueueRename" "rpcResultJobqueueRename" [])
608 40ad3e85 Klaus Aehlig
609 40ad3e85 Klaus Aehlig
instance RpcCall RpcCallJobqueueRename where
610 40ad3e85 Klaus Aehlig
  rpcCallName _          = "jobqueue_rename"
611 40ad3e85 Klaus Aehlig
  rpcCallTimeout _       = rpcTimeoutToRaw Fast
612 40ad3e85 Klaus Aehlig
  rpcCallAcceptOffline _ = False
613 40ad3e85 Klaus Aehlig
  rpcCallData _ call     = J.encode [ rpcCallJobqueueRenameRename call ]
614 40ad3e85 Klaus Aehlig
615 40ad3e85 Klaus Aehlig
instance Rpc RpcCallJobqueueRename RpcResultJobqueueRename where
616 f4d0c84a Klaus Aehlig
  rpcResultFill call res =
617 f4d0c84a Klaus Aehlig
    -- Upon success, the RPC returns the list of return values of
618 f4d0c84a Klaus Aehlig
    -- the rename operations, which is always None, serialized to
619 f4d0c84a Klaus Aehlig
    -- null in JSON.
620 f4d0c84a Klaus Aehlig
    let expected = J.showJSON . map (const J.JSNull)
621 f4d0c84a Klaus Aehlig
                     $ rpcCallJobqueueRenameRename call
622 f4d0c84a Klaus Aehlig
    in if res == expected
623 f4d0c84a Klaus Aehlig
      then Right RpcResultJobqueueRename
624 f4d0c84a Klaus Aehlig
      else Left
625 f4d0c84a Klaus Aehlig
             $ JsonDecodeError ("Expected JSNull, got " ++ show (pp_value res))
626 40ad3e85 Klaus Aehlig
627 5ce9cc30 Klaus Aehlig
-- ** Watcher Status Update
628 5ce9cc30 Klaus Aehlig
      
629 5ce9cc30 Klaus Aehlig
-- | Set the watcher status
630 5ce9cc30 Klaus Aehlig
      
631 5ce9cc30 Klaus Aehlig
$(buildObject "RpcCallSetWatcherPause" "rpcCallSetWatcherPause"
632 ed7f7fd9 Petr Pudlak
  [ optionalField $ timeAsDoubleField "time"
633 5ce9cc30 Klaus Aehlig
  ])
634 5ce9cc30 Klaus Aehlig
635 5ce9cc30 Klaus Aehlig
instance RpcCall RpcCallSetWatcherPause where
636 5ce9cc30 Klaus Aehlig
  rpcCallName _          = "set_watcher_pause"
637 5ce9cc30 Klaus Aehlig
  rpcCallTimeout _       = rpcTimeoutToRaw Fast
638 5ce9cc30 Klaus Aehlig
  rpcCallAcceptOffline _ = False
639 5ce9cc30 Klaus Aehlig
  rpcCallData _ call     = J.encode
640 ed7f7fd9 Petr Pudlak
    [ maybe J.JSNull (J.showJSON . TimeAsDoubleJSON) $
641 ed7f7fd9 Petr Pudlak
            rpcCallSetWatcherPauseTime call ]
642 5ce9cc30 Klaus Aehlig
643 5ce9cc30 Klaus Aehlig
$(buildObject "RpcResultSetWatcherPause" "rpcResultSetWatcherPause" [])
644 5ce9cc30 Klaus Aehlig
645 5ce9cc30 Klaus Aehlig
instance Rpc RpcCallSetWatcherPause RpcResultSetWatcherPause where
646 5ce9cc30 Klaus Aehlig
  rpcResultFill _ res =
647 5ce9cc30 Klaus Aehlig
    case res of
648 5ce9cc30 Klaus Aehlig
      J.JSNull ->  Right RpcResultSetWatcherPause
649 5ce9cc30 Klaus Aehlig
      _ -> Left $ JsonDecodeError
650 5ce9cc30 Klaus Aehlig
           ("Expected JSNull, got " ++ show (pp_value res))
651 5ce9cc30 Klaus Aehlig
652 83a451f5 Klaus Aehlig
-- ** Queue drain status
653 83a451f5 Klaus Aehlig
      
654 83a451f5 Klaus Aehlig
-- | Set the queu drain flag
655 83a451f5 Klaus Aehlig
      
656 83a451f5 Klaus Aehlig
$(buildObject "RpcCallSetDrainFlag" "rpcCallSetDrainFlag"
657 83a451f5 Klaus Aehlig
  [ simpleField "value" [t| Bool |]
658 83a451f5 Klaus Aehlig
  ])
659 83a451f5 Klaus Aehlig
660 83a451f5 Klaus Aehlig
instance RpcCall RpcCallSetDrainFlag where
661 83a451f5 Klaus Aehlig
  rpcCallName _          = "jobqueue_set_drain_flag"
662 83a451f5 Klaus Aehlig
  rpcCallTimeout _       = rpcTimeoutToRaw Fast
663 83a451f5 Klaus Aehlig
  rpcCallAcceptOffline _ = False
664 83a451f5 Klaus Aehlig
  rpcCallData _ call     = J.encode [ rpcCallSetDrainFlagValue call ]
665 83a451f5 Klaus Aehlig
666 83a451f5 Klaus Aehlig
$(buildObject "RpcResultSetDrainFlag" "rpcResultSetDrainFalg" [])
667 83a451f5 Klaus Aehlig
668 83a451f5 Klaus Aehlig
instance Rpc RpcCallSetDrainFlag RpcResultSetDrainFlag where
669 83a451f5 Klaus Aehlig
  rpcResultFill _ res =
670 83a451f5 Klaus Aehlig
    case res of
671 83a451f5 Klaus Aehlig
      J.JSNull ->  Right RpcResultSetDrainFlag
672 83a451f5 Klaus Aehlig
      _ -> Left $ JsonDecodeError
673 83a451f5 Klaus Aehlig
           ("Expected JSNull, got " ++ show (pp_value res))