Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / Rpc.hs @ 13d26b66

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