Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ 84a12e40

History | View | Annotate | Download (42.8 kB)

1 2f31098c Iustin Pop
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 3ef3c771 Iustin Pop
"""Inter-node RPC library.
23 a8083063 Iustin Pop

24 a8083063 Iustin Pop
"""
25 a8083063 Iustin Pop
26 72737a7f Iustin Pop
# pylint: disable-msg=C0103,R0201,R0904
27 72737a7f Iustin Pop
# C0103: Invalid name, since call_ are not valid
28 72737a7f Iustin Pop
# R0201: Method could be a function, we keep all rpcs instance methods
29 72737a7f Iustin Pop
# as not to change them back and forth between static/instance methods
30 72737a7f Iustin Pop
# if they need to start using instance attributes
31 72737a7f Iustin Pop
# R0904: Too many public methods
32 a8083063 Iustin Pop
33 a8083063 Iustin Pop
import os
34 58b311ca Iustin Pop
import logging
35 12bce260 Michael Hanselmann
import zlib
36 12bce260 Michael Hanselmann
import base64
37 33231500 Michael Hanselmann
import pycurl
38 33231500 Michael Hanselmann
import threading
39 a8083063 Iustin Pop
40 a8083063 Iustin Pop
from ganeti import utils
41 a8083063 Iustin Pop
from ganeti import objects
42 ecfe9491 Michael Hanselmann
from ganeti import http
43 7c28c575 Michael Hanselmann
from ganeti import serializer
44 eafd8762 Michael Hanselmann
from ganeti import constants
45 781de953 Iustin Pop
from ganeti import errors
46 a744b676 Manuel Franceschini
from ganeti import netutils
47 a8083063 Iustin Pop
48 fe267188 Iustin Pop
# pylint has a bug here, doesn't see this import
49 fe267188 Iustin Pop
import ganeti.http.client  # pylint: disable-msg=W0611
50 ae88ef45 Michael Hanselmann
51 a8083063 Iustin Pop
52 33231500 Michael Hanselmann
# Timeout for connecting to nodes (seconds)
53 33231500 Michael Hanselmann
_RPC_CONNECT_TIMEOUT = 5
54 33231500 Michael Hanselmann
55 33231500 Michael Hanselmann
_RPC_CLIENT_HEADERS = [
56 33231500 Michael Hanselmann
  "Content-type: %s" % http.HTTP_APP_JSON,
57 33231500 Michael Hanselmann
  ]
58 4331f6cd Michael Hanselmann
59 92fd2250 Iustin Pop
# Various time constants for the timeout table
60 92fd2250 Iustin Pop
_TMO_URGENT = 60 # one minute
61 92fd2250 Iustin Pop
_TMO_FAST = 5 * 60 # five minutes
62 92fd2250 Iustin Pop
_TMO_NORMAL = 15 * 60 # 15 minutes
63 92fd2250 Iustin Pop
_TMO_SLOW = 3600 # one hour
64 92fd2250 Iustin Pop
_TMO_4HRS = 4 * 3600
65 92fd2250 Iustin Pop
_TMO_1DAY = 86400
66 92fd2250 Iustin Pop
67 92fd2250 Iustin Pop
# Timeout table that will be built later by decorators
68 92fd2250 Iustin Pop
# Guidelines for choosing timeouts:
69 92fd2250 Iustin Pop
# - call used during watcher: timeout -> 1min, _TMO_URGENT
70 92fd2250 Iustin Pop
# - trivial (but be sure it is trivial) (e.g. reading a file): 5min, _TMO_FAST
71 92fd2250 Iustin Pop
# - other calls: 15 min, _TMO_NORMAL
72 92fd2250 Iustin Pop
# - special calls (instance add, etc.): either _TMO_SLOW (1h) or huge timeouts
73 92fd2250 Iustin Pop
74 92fd2250 Iustin Pop
_TIMEOUTS = {
75 92fd2250 Iustin Pop
}
76 92fd2250 Iustin Pop
77 4331f6cd Michael Hanselmann
78 4331f6cd Michael Hanselmann
def Init():
79 4331f6cd Michael Hanselmann
  """Initializes the module-global HTTP client manager.
80 4331f6cd Michael Hanselmann

81 33231500 Michael Hanselmann
  Must be called before using any RPC function and while exactly one thread is
82 33231500 Michael Hanselmann
  running.
83 4331f6cd Michael Hanselmann

84 4331f6cd Michael Hanselmann
  """
85 33231500 Michael Hanselmann
  # curl_global_init(3) and curl_global_cleanup(3) must be called with only
86 33231500 Michael Hanselmann
  # one thread running. This check is just a safety measure -- it doesn't
87 33231500 Michael Hanselmann
  # cover all cases.
88 33231500 Michael Hanselmann
  assert threading.activeCount() == 1, \
89 33231500 Michael Hanselmann
         "Found more than one active thread when initializing pycURL"
90 4331f6cd Michael Hanselmann
91 33231500 Michael Hanselmann
  logging.info("Using PycURL %s", pycurl.version)
92 8d0a4f99 Michael Hanselmann
93 33231500 Michael Hanselmann
  pycurl.global_init(pycurl.GLOBAL_ALL)
94 4331f6cd Michael Hanselmann
95 4331f6cd Michael Hanselmann
96 4331f6cd Michael Hanselmann
def Shutdown():
97 4331f6cd Michael Hanselmann
  """Stops the module-global HTTP client manager.
98 4331f6cd Michael Hanselmann

99 33231500 Michael Hanselmann
  Must be called before quitting the program and while exactly one thread is
100 33231500 Michael Hanselmann
  running.
101 4331f6cd Michael Hanselmann

102 4331f6cd Michael Hanselmann
  """
103 33231500 Michael Hanselmann
  pycurl.global_cleanup()
104 33231500 Michael Hanselmann
105 33231500 Michael Hanselmann
106 33231500 Michael Hanselmann
def _ConfigRpcCurl(curl):
107 33231500 Michael Hanselmann
  noded_cert = str(constants.NODED_CERT_FILE)
108 4331f6cd Michael Hanselmann
109 33231500 Michael Hanselmann
  curl.setopt(pycurl.FOLLOWLOCATION, False)
110 33231500 Michael Hanselmann
  curl.setopt(pycurl.CAINFO, noded_cert)
111 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSL_VERIFYHOST, 0)
112 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSL_VERIFYPEER, True)
113 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSLCERTTYPE, "PEM")
114 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSLCERT, noded_cert)
115 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSLKEYTYPE, "PEM")
116 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSLKEY, noded_cert)
117 33231500 Michael Hanselmann
  curl.setopt(pycurl.CONNECTTIMEOUT, _RPC_CONNECT_TIMEOUT)
118 33231500 Michael Hanselmann
119 33231500 Michael Hanselmann
120 33231500 Michael Hanselmann
class _RpcThreadLocal(threading.local):
121 33231500 Michael Hanselmann
  def GetHttpClientPool(self):
122 33231500 Michael Hanselmann
    """Returns a per-thread HTTP client pool.
123 33231500 Michael Hanselmann

124 33231500 Michael Hanselmann
    @rtype: L{http.client.HttpClientPool}
125 33231500 Michael Hanselmann

126 33231500 Michael Hanselmann
    """
127 33231500 Michael Hanselmann
    try:
128 33231500 Michael Hanselmann
      pool = self.hcp
129 33231500 Michael Hanselmann
    except AttributeError:
130 33231500 Michael Hanselmann
      pool = http.client.HttpClientPool(_ConfigRpcCurl)
131 33231500 Michael Hanselmann
      self.hcp = pool
132 33231500 Michael Hanselmann
133 33231500 Michael Hanselmann
    return pool
134 33231500 Michael Hanselmann
135 33231500 Michael Hanselmann
136 33231500 Michael Hanselmann
_thread_local = _RpcThreadLocal()
137 4331f6cd Michael Hanselmann
138 4331f6cd Michael Hanselmann
139 92fd2250 Iustin Pop
def _RpcTimeout(secs):
140 92fd2250 Iustin Pop
  """Timeout decorator.
141 92fd2250 Iustin Pop

142 92fd2250 Iustin Pop
  When applied to a rpc call_* function, it updates the global timeout
143 92fd2250 Iustin Pop
  table with the given function/timeout.
144 92fd2250 Iustin Pop

145 92fd2250 Iustin Pop
  """
146 92fd2250 Iustin Pop
  def decorator(f):
147 92fd2250 Iustin Pop
    name = f.__name__
148 92fd2250 Iustin Pop
    assert name.startswith("call_")
149 92fd2250 Iustin Pop
    _TIMEOUTS[name[len("call_"):]] = secs
150 92fd2250 Iustin Pop
    return f
151 92fd2250 Iustin Pop
  return decorator
152 92fd2250 Iustin Pop
153 92fd2250 Iustin Pop
154 781de953 Iustin Pop
class RpcResult(object):
155 781de953 Iustin Pop
  """RPC Result class.
156 781de953 Iustin Pop

157 781de953 Iustin Pop
  This class holds an RPC result. It is needed since in multi-node
158 781de953 Iustin Pop
  calls we can't raise an exception just because one one out of many
159 781de953 Iustin Pop
  failed, and therefore we use this class to encapsulate the result.
160 781de953 Iustin Pop

161 5bbd3f7f Michael Hanselmann
  @ivar data: the data payload, for successful results, or None
162 ed83f5cc Iustin Pop
  @ivar call: the name of the RPC call
163 ed83f5cc Iustin Pop
  @ivar node: the name of the node to which we made the call
164 ed83f5cc Iustin Pop
  @ivar offline: whether the operation failed because the node was
165 ed83f5cc Iustin Pop
      offline, as opposed to actual failure; offline=True will always
166 ed83f5cc Iustin Pop
      imply failed=True, in order to allow simpler checking if
167 ed83f5cc Iustin Pop
      the user doesn't care about the exact failure mode
168 4c4e4e1e Iustin Pop
  @ivar fail_msg: the error message if the call failed
169 ed83f5cc Iustin Pop

170 781de953 Iustin Pop
  """
171 ed83f5cc Iustin Pop
  def __init__(self, data=None, failed=False, offline=False,
172 ed83f5cc Iustin Pop
               call=None, node=None):
173 ed83f5cc Iustin Pop
    self.offline = offline
174 ed83f5cc Iustin Pop
    self.call = call
175 ed83f5cc Iustin Pop
    self.node = node
176 1645d22d Michael Hanselmann
177 ed83f5cc Iustin Pop
    if offline:
178 4c4e4e1e Iustin Pop
      self.fail_msg = "Node is marked offline"
179 f2def43a Iustin Pop
      self.data = self.payload = None
180 ed83f5cc Iustin Pop
    elif failed:
181 4c4e4e1e Iustin Pop
      self.fail_msg = self._EnsureErr(data)
182 f2def43a Iustin Pop
      self.data = self.payload = None
183 781de953 Iustin Pop
    else:
184 781de953 Iustin Pop
      self.data = data
185 d3c8b360 Iustin Pop
      if not isinstance(self.data, (tuple, list)):
186 4c4e4e1e Iustin Pop
        self.fail_msg = ("RPC layer error: invalid result type (%s)" %
187 4c4e4e1e Iustin Pop
                         type(self.data))
188 1645d22d Michael Hanselmann
        self.payload = None
189 d3c8b360 Iustin Pop
      elif len(data) != 2:
190 4c4e4e1e Iustin Pop
        self.fail_msg = ("RPC layer error: invalid result length (%d), "
191 4c4e4e1e Iustin Pop
                         "expected 2" % len(self.data))
192 1645d22d Michael Hanselmann
        self.payload = None
193 d3c8b360 Iustin Pop
      elif not self.data[0]:
194 4c4e4e1e Iustin Pop
        self.fail_msg = self._EnsureErr(self.data[1])
195 1645d22d Michael Hanselmann
        self.payload = None
196 f2def43a Iustin Pop
      else:
197 d3c8b360 Iustin Pop
        # finally success
198 4c4e4e1e Iustin Pop
        self.fail_msg = None
199 d3c8b360 Iustin Pop
        self.payload = data[1]
200 d3c8b360 Iustin Pop
201 1645d22d Michael Hanselmann
    assert hasattr(self, "call")
202 1645d22d Michael Hanselmann
    assert hasattr(self, "data")
203 1645d22d Michael Hanselmann
    assert hasattr(self, "fail_msg")
204 1645d22d Michael Hanselmann
    assert hasattr(self, "node")
205 1645d22d Michael Hanselmann
    assert hasattr(self, "offline")
206 1645d22d Michael Hanselmann
    assert hasattr(self, "payload")
207 1645d22d Michael Hanselmann
208 d3c8b360 Iustin Pop
  @staticmethod
209 d3c8b360 Iustin Pop
  def _EnsureErr(val):
210 d3c8b360 Iustin Pop
    """Helper to ensure we return a 'True' value for error."""
211 d3c8b360 Iustin Pop
    if val:
212 d3c8b360 Iustin Pop
      return val
213 d3c8b360 Iustin Pop
    else:
214 d3c8b360 Iustin Pop
      return "No error information"
215 781de953 Iustin Pop
216 045dd6d9 Iustin Pop
  def Raise(self, msg, prereq=False, ecode=None):
217 781de953 Iustin Pop
    """If the result has failed, raise an OpExecError.
218 781de953 Iustin Pop

219 781de953 Iustin Pop
    This is used so that LU code doesn't have to check for each
220 781de953 Iustin Pop
    result, but instead can call this function.
221 781de953 Iustin Pop

222 781de953 Iustin Pop
    """
223 4c4e4e1e Iustin Pop
    if not self.fail_msg:
224 4c4e4e1e Iustin Pop
      return
225 4c4e4e1e Iustin Pop
226 4c4e4e1e Iustin Pop
    if not msg: # one could pass None for default message
227 4c4e4e1e Iustin Pop
      msg = ("Call '%s' to node '%s' has failed: %s" %
228 4c4e4e1e Iustin Pop
             (self.call, self.node, self.fail_msg))
229 4c4e4e1e Iustin Pop
    else:
230 4c4e4e1e Iustin Pop
      msg = "%s: %s" % (msg, self.fail_msg)
231 4c4e4e1e Iustin Pop
    if prereq:
232 4c4e4e1e Iustin Pop
      ec = errors.OpPrereqError
233 4c4e4e1e Iustin Pop
    else:
234 4c4e4e1e Iustin Pop
      ec = errors.OpExecError
235 045dd6d9 Iustin Pop
    if ecode is not None:
236 27137e55 Iustin Pop
      args = (msg, ecode)
237 045dd6d9 Iustin Pop
    else:
238 045dd6d9 Iustin Pop
      args = (msg, )
239 7260cfbe Iustin Pop
    raise ec(*args) # pylint: disable-msg=W0142
240 781de953 Iustin Pop
241 781de953 Iustin Pop
242 a8083063 Iustin Pop
class Client:
243 a8083063 Iustin Pop
  """RPC Client class.
244 a8083063 Iustin Pop

245 2f8598a5 Alexander Schreiber
  This class, given a (remote) method name, a list of parameters and a
246 a8083063 Iustin Pop
  list of nodes, will contact (in parallel) all nodes, and return a
247 a8083063 Iustin Pop
  dict of results (key: node name, value: result).
248 a8083063 Iustin Pop

249 5bbd3f7f Michael Hanselmann
  One current bug is that generic failure is still signaled by
250 a8083063 Iustin Pop
  'False' result, which is not good. This overloading of values can
251 a8083063 Iustin Pop
  cause bugs.
252 a8083063 Iustin Pop

253 a8083063 Iustin Pop
  """
254 160e2921 Iustin Pop
  def __init__(self, procedure, body, port):
255 92fd2250 Iustin Pop
    assert procedure in _TIMEOUTS, ("New RPC call not declared in the"
256 92fd2250 Iustin Pop
                                    " timeouts table")
257 a8083063 Iustin Pop
    self.procedure = procedure
258 160e2921 Iustin Pop
    self.body = body
259 160e2921 Iustin Pop
    self.port = port
260 33231500 Michael Hanselmann
    self._request = {}
261 d57ae7f7 Michael Hanselmann
262 e0036155 Iustin Pop
  def ConnectList(self, node_list, address_list=None, read_timeout=None):
263 a8083063 Iustin Pop
    """Add a list of nodes to the target nodes.
264 a8083063 Iustin Pop

265 3ef3c771 Iustin Pop
    @type node_list: list
266 3ef3c771 Iustin Pop
    @param node_list: the list of node names to connect
267 bdf7d8c0 Iustin Pop
    @type address_list: list or None
268 bdf7d8c0 Iustin Pop
    @keyword address_list: either None or a list with node addresses,
269 bdf7d8c0 Iustin Pop
        which must have the same length as the node list
270 e0036155 Iustin Pop
    @type read_timeout: int
271 e0036155 Iustin Pop
    @param read_timeout: overwrites the default read timeout for the
272 e0036155 Iustin Pop
        given operation
273 3ef3c771 Iustin Pop

274 a8083063 Iustin Pop
    """
275 bdf7d8c0 Iustin Pop
    if address_list is None:
276 bdf7d8c0 Iustin Pop
      address_list = [None for _ in node_list]
277 bdf7d8c0 Iustin Pop
    else:
278 bdf7d8c0 Iustin Pop
      assert len(node_list) == len(address_list), \
279 bdf7d8c0 Iustin Pop
             "Name and address lists should have the same length"
280 bdf7d8c0 Iustin Pop
    for node, address in zip(node_list, address_list):
281 e0036155 Iustin Pop
      self.ConnectNode(node, address, read_timeout=read_timeout)
282 bdf7d8c0 Iustin Pop
283 e0036155 Iustin Pop
  def ConnectNode(self, name, address=None, read_timeout=None):
284 a8083063 Iustin Pop
    """Add a node to the target list.
285 a8083063 Iustin Pop

286 bdf7d8c0 Iustin Pop
    @type name: str
287 bdf7d8c0 Iustin Pop
    @param name: the node name
288 bdf7d8c0 Iustin Pop
    @type address: str
289 bdf7d8c0 Iustin Pop
    @keyword address: the node address, if known
290 bdf7d8c0 Iustin Pop

291 a8083063 Iustin Pop
    """
292 ecfe9491 Michael Hanselmann
    if address is None:
293 ecfe9491 Michael Hanselmann
      address = name
294 ecfe9491 Michael Hanselmann
295 92fd2250 Iustin Pop
    if read_timeout is None:
296 92fd2250 Iustin Pop
      read_timeout = _TIMEOUTS[self.procedure]
297 92fd2250 Iustin Pop
298 33231500 Michael Hanselmann
    self._request[name] = \
299 33231500 Michael Hanselmann
      http.client.HttpClientRequest(str(address), self.port,
300 33231500 Michael Hanselmann
                                    http.HTTP_PUT, str("/%s" % self.procedure),
301 33231500 Michael Hanselmann
                                    headers=_RPC_CLIENT_HEADERS,
302 33231500 Michael Hanselmann
                                    post_data=str(self.body),
303 e0036155 Iustin Pop
                                    read_timeout=read_timeout)
304 a8083063 Iustin Pop
305 33231500 Michael Hanselmann
  def GetResults(self, http_pool=None):
306 ecfe9491 Michael Hanselmann
    """Call nodes and return results.
307 ecfe9491 Michael Hanselmann

308 ecfe9491 Michael Hanselmann
    @rtype: list
309 5fcc718f Iustin Pop
    @return: List of RPC results
310 a8083063 Iustin Pop

311 a8083063 Iustin Pop
    """
312 33231500 Michael Hanselmann
    if not http_pool:
313 33231500 Michael Hanselmann
      http_pool = _thread_local.GetHttpClientPool()
314 4331f6cd Michael Hanselmann
315 33231500 Michael Hanselmann
    http_pool.ProcessRequests(self._request.values())
316 a8083063 Iustin Pop
317 ecfe9491 Michael Hanselmann
    results = {}
318 a8083063 Iustin Pop
319 33231500 Michael Hanselmann
    for name, req in self._request.iteritems():
320 ae88ef45 Michael Hanselmann
      if req.success and req.resp_status_code == http.HTTP_OK:
321 781de953 Iustin Pop
        results[name] = RpcResult(data=serializer.LoadJson(req.resp_body),
322 781de953 Iustin Pop
                                  node=name, call=self.procedure)
323 ecfe9491 Michael Hanselmann
        continue
324 a8083063 Iustin Pop
325 d57ae7f7 Michael Hanselmann
      # TODO: Better error reporting
326 ecfe9491 Michael Hanselmann
      if req.error:
327 ecfe9491 Michael Hanselmann
        msg = req.error
328 ecfe9491 Michael Hanselmann
      else:
329 ecfe9491 Michael Hanselmann
        msg = req.resp_body
330 ecfe9491 Michael Hanselmann
331 1b8acf70 Iustin Pop
      logging.error("RPC error in %s from node %s: %s",
332 1b8acf70 Iustin Pop
                    self.procedure, name, msg)
333 781de953 Iustin Pop
      results[name] = RpcResult(data=msg, failed=True, node=name,
334 781de953 Iustin Pop
                                call=self.procedure)
335 ecfe9491 Michael Hanselmann
336 ecfe9491 Michael Hanselmann
    return results
337 a8083063 Iustin Pop
338 a8083063 Iustin Pop
339 1651d116 Michael Hanselmann
def _EncodeImportExportIO(ieio, ieioargs):
340 1651d116 Michael Hanselmann
  """Encodes import/export I/O information.
341 1651d116 Michael Hanselmann

342 1651d116 Michael Hanselmann
  """
343 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_RAW_DISK:
344 1651d116 Michael Hanselmann
    assert len(ieioargs) == 1
345 1651d116 Michael Hanselmann
    return (ieioargs[0].ToDict(), )
346 1651d116 Michael Hanselmann
347 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_SCRIPT:
348 1651d116 Michael Hanselmann
    assert len(ieioargs) == 2
349 1651d116 Michael Hanselmann
    return (ieioargs[0].ToDict(), ieioargs[1])
350 1651d116 Michael Hanselmann
351 1651d116 Michael Hanselmann
  return ieioargs
352 1651d116 Michael Hanselmann
353 1651d116 Michael Hanselmann
354 72737a7f Iustin Pop
class RpcRunner(object):
355 72737a7f Iustin Pop
  """RPC runner class"""
356 a8083063 Iustin Pop
357 72737a7f Iustin Pop
  def __init__(self, cfg):
358 72737a7f Iustin Pop
    """Initialized the rpc runner.
359 a8083063 Iustin Pop

360 72737a7f Iustin Pop
    @type cfg:  C{config.ConfigWriter}
361 72737a7f Iustin Pop
    @param cfg: the configuration object that will be used to get data
362 72737a7f Iustin Pop
                about the cluster
363 a8083063 Iustin Pop

364 72737a7f Iustin Pop
    """
365 72737a7f Iustin Pop
    self._cfg = cfg
366 a744b676 Manuel Franceschini
    self.port = netutils.GetDaemonPort(constants.NODED)
367 a8083063 Iustin Pop
368 1bdcbbab Iustin Pop
  def _InstDict(self, instance, hvp=None, bep=None, osp=None):
369 26ba2bd8 Iustin Pop
    """Convert the given instance to a dict.
370 26ba2bd8 Iustin Pop

371 26ba2bd8 Iustin Pop
    This is done via the instance's ToDict() method and additionally
372 26ba2bd8 Iustin Pop
    we fill the hvparams with the cluster defaults.
373 26ba2bd8 Iustin Pop

374 26ba2bd8 Iustin Pop
    @type instance: L{objects.Instance}
375 26ba2bd8 Iustin Pop
    @param instance: an Instance object
376 0eca8e0c Iustin Pop
    @type hvp: dict or None
377 5bbd3f7f Michael Hanselmann
    @param hvp: a dictionary with overridden hypervisor parameters
378 0eca8e0c Iustin Pop
    @type bep: dict or None
379 5bbd3f7f Michael Hanselmann
    @param bep: a dictionary with overridden backend parameters
380 1bdcbbab Iustin Pop
    @type osp: dict or None
381 1bdcbbab Iustin Pop
    @param osp: a dictionary with overriden os parameters
382 26ba2bd8 Iustin Pop
    @rtype: dict
383 26ba2bd8 Iustin Pop
    @return: the instance dict, with the hvparams filled with the
384 26ba2bd8 Iustin Pop
        cluster defaults
385 26ba2bd8 Iustin Pop

386 26ba2bd8 Iustin Pop
    """
387 26ba2bd8 Iustin Pop
    idict = instance.ToDict()
388 5b442704 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
389 5b442704 Iustin Pop
    idict["hvparams"] = cluster.FillHV(instance)
390 0eca8e0c Iustin Pop
    if hvp is not None:
391 0eca8e0c Iustin Pop
      idict["hvparams"].update(hvp)
392 5b442704 Iustin Pop
    idict["beparams"] = cluster.FillBE(instance)
393 0eca8e0c Iustin Pop
    if bep is not None:
394 0eca8e0c Iustin Pop
      idict["beparams"].update(bep)
395 1bdcbbab Iustin Pop
    idict["osparams"] = cluster.SimpleFillOS(instance.os, instance.osparams)
396 1bdcbbab Iustin Pop
    if osp is not None:
397 1bdcbbab Iustin Pop
      idict["osparams"].update(osp)
398 b848ce79 Guido Trotter
    for nic in idict["nics"]:
399 b848ce79 Guido Trotter
      nic['nicparams'] = objects.FillDict(
400 b848ce79 Guido Trotter
        cluster.nicparams[constants.PP_DEFAULT],
401 b848ce79 Guido Trotter
        nic['nicparams'])
402 26ba2bd8 Iustin Pop
    return idict
403 26ba2bd8 Iustin Pop
404 e0036155 Iustin Pop
  def _ConnectList(self, client, node_list, call, read_timeout=None):
405 25348212 Iustin Pop
    """Helper for computing node addresses.
406 25348212 Iustin Pop

407 6af6270a Iustin Pop
    @type client: L{ganeti.rpc.Client}
408 25348212 Iustin Pop
    @param client: a C{Client} instance
409 25348212 Iustin Pop
    @type node_list: list
410 25348212 Iustin Pop
    @param node_list: the node list we should connect
411 84b45587 Iustin Pop
    @type call: string
412 84b45587 Iustin Pop
    @param call: the name of the remote procedure call, for filling in
413 84b45587 Iustin Pop
        correctly any eventual offline nodes' results
414 e0036155 Iustin Pop
    @type read_timeout: int
415 e0036155 Iustin Pop
    @param read_timeout: overwrites the default read timeout for the
416 e0036155 Iustin Pop
        given operation
417 25348212 Iustin Pop

418 25348212 Iustin Pop
    """
419 25348212 Iustin Pop
    all_nodes = self._cfg.GetAllNodesInfo()
420 ed83f5cc Iustin Pop
    name_list = []
421 25348212 Iustin Pop
    addr_list = []
422 ed83f5cc Iustin Pop
    skip_dict = {}
423 25348212 Iustin Pop
    for node in node_list:
424 25348212 Iustin Pop
      if node in all_nodes:
425 ed83f5cc Iustin Pop
        if all_nodes[node].offline:
426 84b45587 Iustin Pop
          skip_dict[node] = RpcResult(node=node, offline=True, call=call)
427 ed83f5cc Iustin Pop
          continue
428 25348212 Iustin Pop
        val = all_nodes[node].primary_ip
429 25348212 Iustin Pop
      else:
430 25348212 Iustin Pop
        val = None
431 25348212 Iustin Pop
      addr_list.append(val)
432 ed83f5cc Iustin Pop
      name_list.append(node)
433 ed83f5cc Iustin Pop
    if name_list:
434 e0036155 Iustin Pop
      client.ConnectList(name_list, address_list=addr_list,
435 e0036155 Iustin Pop
                         read_timeout=read_timeout)
436 ed83f5cc Iustin Pop
    return skip_dict
437 25348212 Iustin Pop
438 e0036155 Iustin Pop
  def _ConnectNode(self, client, node, call, read_timeout=None):
439 25348212 Iustin Pop
    """Helper for computing one node's address.
440 25348212 Iustin Pop

441 6af6270a Iustin Pop
    @type client: L{ganeti.rpc.Client}
442 25348212 Iustin Pop
    @param client: a C{Client} instance
443 25348212 Iustin Pop
    @type node: str
444 25348212 Iustin Pop
    @param node: the node we should connect
445 84b45587 Iustin Pop
    @type call: string
446 84b45587 Iustin Pop
    @param call: the name of the remote procedure call, for filling in
447 84b45587 Iustin Pop
        correctly any eventual offline nodes' results
448 e0036155 Iustin Pop
    @type read_timeout: int
449 e0036155 Iustin Pop
    @param read_timeout: overwrites the default read timeout for the
450 e0036155 Iustin Pop
        given operation
451 25348212 Iustin Pop

452 25348212 Iustin Pop
    """
453 25348212 Iustin Pop
    node_info = self._cfg.GetNodeInfo(node)
454 25348212 Iustin Pop
    if node_info is not None:
455 ed83f5cc Iustin Pop
      if node_info.offline:
456 84b45587 Iustin Pop
        return RpcResult(node=node, offline=True, call=call)
457 25348212 Iustin Pop
      addr = node_info.primary_ip
458 25348212 Iustin Pop
    else:
459 25348212 Iustin Pop
      addr = None
460 e0036155 Iustin Pop
    client.ConnectNode(node, address=addr, read_timeout=read_timeout)
461 25348212 Iustin Pop
462 e0036155 Iustin Pop
  def _MultiNodeCall(self, node_list, procedure, args, read_timeout=None):
463 160e2921 Iustin Pop
    """Helper for making a multi-node call
464 160e2921 Iustin Pop

465 160e2921 Iustin Pop
    """
466 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
467 160e2921 Iustin Pop
    c = Client(procedure, body, self.port)
468 e0036155 Iustin Pop
    skip_dict = self._ConnectList(c, node_list, procedure,
469 e0036155 Iustin Pop
                                  read_timeout=read_timeout)
470 ed83f5cc Iustin Pop
    skip_dict.update(c.GetResults())
471 ed83f5cc Iustin Pop
    return skip_dict
472 9a525d83 Michael Hanselmann
473 9a525d83 Michael Hanselmann
  @classmethod
474 9a525d83 Michael Hanselmann
  def _StaticMultiNodeCall(cls, node_list, procedure, args,
475 e0036155 Iustin Pop
                           address_list=None, read_timeout=None):
476 160e2921 Iustin Pop
    """Helper for making a multi-node static call
477 160e2921 Iustin Pop

478 160e2921 Iustin Pop
    """
479 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
480 a744b676 Manuel Franceschini
    c = Client(procedure, body, netutils.GetDaemonPort(constants.NODED))
481 e0036155 Iustin Pop
    c.ConnectList(node_list, address_list=address_list,
482 e0036155 Iustin Pop
                  read_timeout=read_timeout)
483 9a525d83 Michael Hanselmann
    return c.GetResults()
484 9a525d83 Michael Hanselmann
485 e0036155 Iustin Pop
  def _SingleNodeCall(self, node, procedure, args, read_timeout=None):
486 160e2921 Iustin Pop
    """Helper for making a single-node call
487 9a525d83 Michael Hanselmann

488 9a525d83 Michael Hanselmann
    """
489 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
490 160e2921 Iustin Pop
    c = Client(procedure, body, self.port)
491 e0036155 Iustin Pop
    result = self._ConnectNode(c, node, procedure, read_timeout=read_timeout)
492 ed83f5cc Iustin Pop
    if result is None:
493 ed83f5cc Iustin Pop
      # we did connect, node is not offline
494 ed83f5cc Iustin Pop
      result = c.GetResults()[node]
495 ed83f5cc Iustin Pop
    return result
496 9a525d83 Michael Hanselmann
497 9a525d83 Michael Hanselmann
  @classmethod
498 e0036155 Iustin Pop
  def _StaticSingleNodeCall(cls, node, procedure, args, read_timeout=None):
499 160e2921 Iustin Pop
    """Helper for making a single-node static call
500 9a525d83 Michael Hanselmann

501 9a525d83 Michael Hanselmann
    """
502 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
503 a744b676 Manuel Franceschini
    c = Client(procedure, body, netutils.GetDaemonPort(constants.NODED))
504 e0036155 Iustin Pop
    c.ConnectNode(node, read_timeout=read_timeout)
505 ed83f5cc Iustin Pop
    return c.GetResults()[node]
506 9a525d83 Michael Hanselmann
507 12bce260 Michael Hanselmann
  @staticmethod
508 12bce260 Michael Hanselmann
  def _Compress(data):
509 12bce260 Michael Hanselmann
    """Compresses a string for transport over RPC.
510 12bce260 Michael Hanselmann

511 12bce260 Michael Hanselmann
    Small amounts of data are not compressed.
512 12bce260 Michael Hanselmann

513 12bce260 Michael Hanselmann
    @type data: str
514 12bce260 Michael Hanselmann
    @param data: Data
515 12bce260 Michael Hanselmann
    @rtype: tuple
516 12bce260 Michael Hanselmann
    @return: Encoded data to send
517 12bce260 Michael Hanselmann

518 12bce260 Michael Hanselmann
    """
519 12bce260 Michael Hanselmann
    # Small amounts of data are not compressed
520 12bce260 Michael Hanselmann
    if len(data) < 512:
521 12bce260 Michael Hanselmann
      return (constants.RPC_ENCODING_NONE, data)
522 12bce260 Michael Hanselmann
523 12bce260 Michael Hanselmann
    # Compress with zlib and encode in base64
524 12bce260 Michael Hanselmann
    return (constants.RPC_ENCODING_ZLIB_BASE64,
525 12bce260 Michael Hanselmann
            base64.b64encode(zlib.compress(data, 3)))
526 12bce260 Michael Hanselmann
527 781de953 Iustin Pop
  #
528 781de953 Iustin Pop
  # Begin RPC calls
529 781de953 Iustin Pop
  #
530 781de953 Iustin Pop
531 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
532 b2a6ccd4 Iustin Pop
  def call_lv_list(self, node_list, vg_name):
533 72737a7f Iustin Pop
    """Gets the logical volumes present in a given volume group.
534 a8083063 Iustin Pop

535 72737a7f Iustin Pop
    This is a multi-node call.
536 a8083063 Iustin Pop

537 72737a7f Iustin Pop
    """
538 b2a6ccd4 Iustin Pop
    return self._MultiNodeCall(node_list, "lv_list", [vg_name])
539 a8083063 Iustin Pop
540 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
541 72737a7f Iustin Pop
  def call_vg_list(self, node_list):
542 72737a7f Iustin Pop
    """Gets the volume group list.
543 a8083063 Iustin Pop

544 72737a7f Iustin Pop
    This is a multi-node call.
545 a8083063 Iustin Pop

546 72737a7f Iustin Pop
    """
547 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "vg_list", [])
548 a8083063 Iustin Pop
549 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
550 e337de97 Michael Hanselmann
  def call_storage_list(self, node_list, su_name, su_args, name, fields):
551 8979196a Michael Hanselmann
    """Get list of storage units.
552 e337de97 Michael Hanselmann

553 e337de97 Michael Hanselmann
    This is a multi-node call.
554 e337de97 Michael Hanselmann

555 e337de97 Michael Hanselmann
    """
556 e337de97 Michael Hanselmann
    return self._MultiNodeCall(node_list, "storage_list",
557 e337de97 Michael Hanselmann
                               [su_name, su_args, name, fields])
558 e337de97 Michael Hanselmann
559 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
560 8979196a Michael Hanselmann
  def call_storage_modify(self, node, su_name, su_args, name, changes):
561 8979196a Michael Hanselmann
    """Modify a storage unit.
562 8979196a Michael Hanselmann

563 8979196a Michael Hanselmann
    This is a single-node call.
564 8979196a Michael Hanselmann

565 8979196a Michael Hanselmann
    """
566 8979196a Michael Hanselmann
    return self._SingleNodeCall(node, "storage_modify",
567 8979196a Michael Hanselmann
                                [su_name, su_args, name, changes])
568 8979196a Michael Hanselmann
569 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
570 637b8d7e Michael Hanselmann
  def call_storage_execute(self, node, su_name, su_args, name, op):
571 637b8d7e Michael Hanselmann
    """Executes an operation on a storage unit.
572 637b8d7e Michael Hanselmann

573 637b8d7e Michael Hanselmann
    This is a single-node call.
574 637b8d7e Michael Hanselmann

575 637b8d7e Michael Hanselmann
    """
576 637b8d7e Michael Hanselmann
    return self._SingleNodeCall(node, "storage_execute",
577 637b8d7e Michael Hanselmann
                                [su_name, su_args, name, op])
578 637b8d7e Michael Hanselmann
579 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
580 72737a7f Iustin Pop
  def call_bridges_exist(self, node, bridges_list):
581 72737a7f Iustin Pop
    """Checks if a node has all the bridges given.
582 a8083063 Iustin Pop

583 72737a7f Iustin Pop
    This method checks if all bridges given in the bridges_list are
584 72737a7f Iustin Pop
    present on the remote node, so that an instance that uses interfaces
585 72737a7f Iustin Pop
    on those bridges can be started.
586 a8083063 Iustin Pop

587 72737a7f Iustin Pop
    This is a single-node call.
588 a8083063 Iustin Pop

589 72737a7f Iustin Pop
    """
590 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "bridges_exist", [bridges_list])
591 a8083063 Iustin Pop
592 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
593 0eca8e0c Iustin Pop
  def call_instance_start(self, node, instance, hvp, bep):
594 72737a7f Iustin Pop
    """Starts an instance.
595 a8083063 Iustin Pop

596 72737a7f Iustin Pop
    This is a single-node call.
597 a8083063 Iustin Pop

598 72737a7f Iustin Pop
    """
599 0eca8e0c Iustin Pop
    idict = self._InstDict(instance, hvp=hvp, bep=bep)
600 0eca8e0c Iustin Pop
    return self._SingleNodeCall(node, "instance_start", [idict])
601 a8083063 Iustin Pop
602 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
603 6263189c Guido Trotter
  def call_instance_shutdown(self, node, instance, timeout):
604 72737a7f Iustin Pop
    """Stops an instance.
605 a8083063 Iustin Pop

606 72737a7f Iustin Pop
    This is a single-node call.
607 2a10865c Iustin Pop

608 72737a7f Iustin Pop
    """
609 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_shutdown",
610 6263189c Guido Trotter
                                [self._InstDict(instance), timeout])
611 2a10865c Iustin Pop
612 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
613 6906a9d8 Guido Trotter
  def call_migration_info(self, node, instance):
614 6906a9d8 Guido Trotter
    """Gather the information necessary to prepare an instance migration.
615 6906a9d8 Guido Trotter

616 6906a9d8 Guido Trotter
    This is a single-node call.
617 6906a9d8 Guido Trotter

618 6906a9d8 Guido Trotter
    @type node: string
619 6906a9d8 Guido Trotter
    @param node: the node on which the instance is currently running
620 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
621 6906a9d8 Guido Trotter
    @param instance: the instance definition
622 6906a9d8 Guido Trotter

623 6906a9d8 Guido Trotter
    """
624 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "migration_info",
625 6906a9d8 Guido Trotter
                                [self._InstDict(instance)])
626 6906a9d8 Guido Trotter
627 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
628 6906a9d8 Guido Trotter
  def call_accept_instance(self, node, instance, info, target):
629 6906a9d8 Guido Trotter
    """Prepare a node to accept an instance.
630 6906a9d8 Guido Trotter

631 6906a9d8 Guido Trotter
    This is a single-node call.
632 6906a9d8 Guido Trotter

633 6906a9d8 Guido Trotter
    @type node: string
634 6906a9d8 Guido Trotter
    @param node: the target node for the migration
635 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
636 6906a9d8 Guido Trotter
    @param instance: the instance definition
637 6906a9d8 Guido Trotter
    @type info: opaque/hypervisor specific (string/data)
638 6906a9d8 Guido Trotter
    @param info: result for the call_migration_info call
639 6906a9d8 Guido Trotter
    @type target: string
640 6906a9d8 Guido Trotter
    @param target: target hostname (usually ip address) (on the node itself)
641 6906a9d8 Guido Trotter

642 6906a9d8 Guido Trotter
    """
643 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "accept_instance",
644 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, target])
645 6906a9d8 Guido Trotter
646 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
647 6906a9d8 Guido Trotter
  def call_finalize_migration(self, node, instance, info, success):
648 6906a9d8 Guido Trotter
    """Finalize any target-node migration specific operation.
649 6906a9d8 Guido Trotter

650 6906a9d8 Guido Trotter
    This is called both in case of a successful migration and in case of error
651 6906a9d8 Guido Trotter
    (in which case it should abort the migration).
652 6906a9d8 Guido Trotter

653 6906a9d8 Guido Trotter
    This is a single-node call.
654 6906a9d8 Guido Trotter

655 6906a9d8 Guido Trotter
    @type node: string
656 6906a9d8 Guido Trotter
    @param node: the target node for the migration
657 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
658 6906a9d8 Guido Trotter
    @param instance: the instance definition
659 6906a9d8 Guido Trotter
    @type info: opaque/hypervisor specific (string/data)
660 6906a9d8 Guido Trotter
    @param info: result for the call_migration_info call
661 6906a9d8 Guido Trotter
    @type success: boolean
662 6906a9d8 Guido Trotter
    @param success: whether the migration was a success or a failure
663 6906a9d8 Guido Trotter

664 6906a9d8 Guido Trotter
    """
665 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "finalize_migration",
666 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, success])
667 6906a9d8 Guido Trotter
668 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
669 72737a7f Iustin Pop
  def call_instance_migrate(self, node, instance, target, live):
670 72737a7f Iustin Pop
    """Migrate an instance.
671 2a10865c Iustin Pop

672 72737a7f Iustin Pop
    This is a single-node call.
673 2a10865c Iustin Pop

674 72737a7f Iustin Pop
    @type node: string
675 72737a7f Iustin Pop
    @param node: the node on which the instance is currently running
676 72737a7f Iustin Pop
    @type instance: C{objects.Instance}
677 72737a7f Iustin Pop
    @param instance: the instance definition
678 72737a7f Iustin Pop
    @type target: string
679 72737a7f Iustin Pop
    @param target: the target node name
680 72737a7f Iustin Pop
    @type live: boolean
681 72737a7f Iustin Pop
    @param live: whether the migration should be done live or not (the
682 72737a7f Iustin Pop
        interpretation of this parameter is left to the hypervisor)
683 007a2f3e Alexander Schreiber

684 72737a7f Iustin Pop
    """
685 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_migrate",
686 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), target, live])
687 007a2f3e Alexander Schreiber
688 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
689 17c3f802 Guido Trotter
  def call_instance_reboot(self, node, inst, reboot_type, shutdown_timeout):
690 72737a7f Iustin Pop
    """Reboots an instance.
691 007a2f3e Alexander Schreiber

692 72737a7f Iustin Pop
    This is a single-node call.
693 a8083063 Iustin Pop

694 72737a7f Iustin Pop
    """
695 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_reboot",
696 17c3f802 Guido Trotter
                                [self._InstDict(inst), reboot_type,
697 17c3f802 Guido Trotter
                                 shutdown_timeout])
698 a8083063 Iustin Pop
699 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_1DAY)
700 4a0e011f Iustin Pop
  def call_instance_os_add(self, node, inst, reinstall, debug):
701 72737a7f Iustin Pop
    """Installs an OS on the given instance.
702 a8083063 Iustin Pop

703 72737a7f Iustin Pop
    This is a single-node call.
704 decd5f45 Iustin Pop

705 72737a7f Iustin Pop
    """
706 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_os_add",
707 4a0e011f Iustin Pop
                                [self._InstDict(inst), reinstall, debug])
708 decd5f45 Iustin Pop
709 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
710 4a0e011f Iustin Pop
  def call_instance_run_rename(self, node, inst, old_name, debug):
711 72737a7f Iustin Pop
    """Run the OS rename script for an instance.
712 decd5f45 Iustin Pop

713 72737a7f Iustin Pop
    This is a single-node call.
714 a8083063 Iustin Pop

715 72737a7f Iustin Pop
    """
716 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_run_rename",
717 4a0e011f Iustin Pop
                                [self._InstDict(inst), old_name, debug])
718 a8083063 Iustin Pop
719 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
720 72737a7f Iustin Pop
  def call_instance_info(self, node, instance, hname):
721 72737a7f Iustin Pop
    """Returns information about a single instance.
722 a8083063 Iustin Pop

723 72737a7f Iustin Pop
    This is a single-node call.
724 a8083063 Iustin Pop

725 9a525d83 Michael Hanselmann
    @type node: list
726 9a525d83 Michael Hanselmann
    @param node: the list of nodes to query
727 72737a7f Iustin Pop
    @type instance: string
728 72737a7f Iustin Pop
    @param instance: the instance name
729 72737a7f Iustin Pop
    @type hname: string
730 72737a7f Iustin Pop
    @param hname: the hypervisor type of the instance
731 a8083063 Iustin Pop

732 72737a7f Iustin Pop
    """
733 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_info", [instance, hname])
734 e69d05fd Iustin Pop
735 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
736 56e7640c Iustin Pop
  def call_instance_migratable(self, node, instance):
737 56e7640c Iustin Pop
    """Checks whether the given instance can be migrated.
738 56e7640c Iustin Pop

739 56e7640c Iustin Pop
    This is a single-node call.
740 56e7640c Iustin Pop

741 56e7640c Iustin Pop
    @param node: the node to query
742 56e7640c Iustin Pop
    @type instance: L{objects.Instance}
743 56e7640c Iustin Pop
    @param instance: the instance to check
744 56e7640c Iustin Pop

745 56e7640c Iustin Pop

746 56e7640c Iustin Pop
    """
747 56e7640c Iustin Pop
    return self._SingleNodeCall(node, "instance_migratable",
748 56e7640c Iustin Pop
                                [self._InstDict(instance)])
749 56e7640c Iustin Pop
750 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
751 72737a7f Iustin Pop
  def call_all_instances_info(self, node_list, hypervisor_list):
752 72737a7f Iustin Pop
    """Returns information about all instances on the given nodes.
753 a8083063 Iustin Pop

754 72737a7f Iustin Pop
    This is a multi-node call.
755 a8083063 Iustin Pop

756 72737a7f Iustin Pop
    @type node_list: list
757 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
758 72737a7f Iustin Pop
    @type hypervisor_list: list
759 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
760 a8083063 Iustin Pop

761 72737a7f Iustin Pop
    """
762 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "all_instances_info",
763 9a525d83 Michael Hanselmann
                               [hypervisor_list])
764 e69d05fd Iustin Pop
765 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
766 72737a7f Iustin Pop
  def call_instance_list(self, node_list, hypervisor_list):
767 72737a7f Iustin Pop
    """Returns the list of running instances on a given node.
768 a8083063 Iustin Pop

769 72737a7f Iustin Pop
    This is a multi-node call.
770 a8083063 Iustin Pop

771 72737a7f Iustin Pop
    @type node_list: list
772 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
773 72737a7f Iustin Pop
    @type hypervisor_list: list
774 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
775 16abfbc2 Alexander Schreiber

776 72737a7f Iustin Pop
    """
777 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "instance_list", [hypervisor_list])
778 16abfbc2 Alexander Schreiber
779 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
780 72737a7f Iustin Pop
  def call_node_tcp_ping(self, node, source, target, port, timeout,
781 72737a7f Iustin Pop
                         live_port_needed):
782 72737a7f Iustin Pop
    """Do a TcpPing on the remote node
783 a8083063 Iustin Pop

784 72737a7f Iustin Pop
    This is a single-node call.
785 caad16e2 Iustin Pop

786 72737a7f Iustin Pop
    """
787 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_tcp_ping",
788 9a525d83 Michael Hanselmann
                                [source, target, port, timeout,
789 72737a7f Iustin Pop
                                 live_port_needed])
790 a8083063 Iustin Pop
791 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
792 caad16e2 Iustin Pop
  def call_node_has_ip_address(self, node, address):
793 caad16e2 Iustin Pop
    """Checks if a node has the given IP address.
794 caad16e2 Iustin Pop

795 caad16e2 Iustin Pop
    This is a single-node call.
796 caad16e2 Iustin Pop

797 caad16e2 Iustin Pop
    """
798 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_has_ip_address", [address])
799 a8083063 Iustin Pop
800 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
801 72737a7f Iustin Pop
  def call_node_info(self, node_list, vg_name, hypervisor_type):
802 72737a7f Iustin Pop
    """Return node information.
803 e69d05fd Iustin Pop

804 72737a7f Iustin Pop
    This will return memory information and volume group size and free
805 72737a7f Iustin Pop
    space.
806 a8083063 Iustin Pop

807 72737a7f Iustin Pop
    This is a multi-node call.
808 a8083063 Iustin Pop

809 72737a7f Iustin Pop
    @type node_list: list
810 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
811 c41eea6e Iustin Pop
    @type vg_name: C{string}
812 c41eea6e Iustin Pop
    @param vg_name: the name of the volume group to ask for disk space
813 72737a7f Iustin Pop
        information
814 72737a7f Iustin Pop
    @type hypervisor_type: C{str}
815 72737a7f Iustin Pop
    @param hypervisor_type: the name of the hypervisor to ask for
816 72737a7f Iustin Pop
        memory information
817 a8083063 Iustin Pop

818 72737a7f Iustin Pop
    """
819 070e998b Iustin Pop
    return self._MultiNodeCall(node_list, "node_info",
820 070e998b Iustin Pop
                               [vg_name, hypervisor_type])
821 a8083063 Iustin Pop
822 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
823 72737a7f Iustin Pop
  def call_node_add(self, node, dsa, dsapub, rsa, rsapub, ssh, sshpub):
824 72737a7f Iustin Pop
    """Add a node to the cluster.
825 a8083063 Iustin Pop

826 72737a7f Iustin Pop
    This is a single-node call.
827 a8083063 Iustin Pop

828 72737a7f Iustin Pop
    """
829 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_add",
830 9a525d83 Michael Hanselmann
                                [dsa, dsapub, rsa, rsapub, ssh, sshpub])
831 a8083063 Iustin Pop
832 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
833 72737a7f Iustin Pop
  def call_node_verify(self, node_list, checkdict, cluster_name):
834 72737a7f Iustin Pop
    """Request verification of given parameters.
835 a8083063 Iustin Pop

836 72737a7f Iustin Pop
    This is a multi-node call.
837 a8083063 Iustin Pop

838 72737a7f Iustin Pop
    """
839 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_verify",
840 9a525d83 Michael Hanselmann
                               [checkdict, cluster_name])
841 a8083063 Iustin Pop
842 9a525d83 Michael Hanselmann
  @classmethod
843 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
844 3583908a Guido Trotter
  def call_node_start_master(cls, node, start_daemons, no_voting):
845 72737a7f Iustin Pop
    """Tells a node to activate itself as a master.
846 a8083063 Iustin Pop

847 72737a7f Iustin Pop
    This is a single-node call.
848 a8083063 Iustin Pop

849 72737a7f Iustin Pop
    """
850 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_start_master",
851 3583908a Guido Trotter
                                     [start_daemons, no_voting])
852 a8083063 Iustin Pop
853 9a525d83 Michael Hanselmann
  @classmethod
854 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
855 9a525d83 Michael Hanselmann
  def call_node_stop_master(cls, node, stop_daemons):
856 72737a7f Iustin Pop
    """Tells a node to demote itself from master status.
857 a8083063 Iustin Pop

858 72737a7f Iustin Pop
    This is a single-node call.
859 4e071d3b Iustin Pop

860 72737a7f Iustin Pop
    """
861 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_stop_master", [stop_daemons])
862 4e071d3b Iustin Pop
863 9a525d83 Michael Hanselmann
  @classmethod
864 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
865 9a525d83 Michael Hanselmann
  def call_master_info(cls, node_list):
866 72737a7f Iustin Pop
    """Query master info.
867 4e071d3b Iustin Pop

868 72737a7f Iustin Pop
    This is a multi-node call.
869 a8083063 Iustin Pop

870 72737a7f Iustin Pop
    """
871 72737a7f Iustin Pop
    # TODO: should this method query down nodes?
872 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "master_info", [])
873 a8083063 Iustin Pop
874 8f215968 Michael Hanselmann
  @classmethod
875 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
876 8f215968 Michael Hanselmann
  def call_version(cls, node_list):
877 72737a7f Iustin Pop
    """Query node version.
878 a8083063 Iustin Pop

879 72737a7f Iustin Pop
    This is a multi-node call.
880 a8083063 Iustin Pop

881 72737a7f Iustin Pop
    """
882 8f215968 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "version", [])
883 a8083063 Iustin Pop
884 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
885 72737a7f Iustin Pop
  def call_blockdev_create(self, node, bdev, size, owner, on_primary, info):
886 72737a7f Iustin Pop
    """Request creation of a given block device.
887 a8083063 Iustin Pop

888 72737a7f Iustin Pop
    This is a single-node call.
889 a8083063 Iustin Pop

890 72737a7f Iustin Pop
    """
891 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_create",
892 9a525d83 Michael Hanselmann
                                [bdev.ToDict(), size, owner, on_primary, info])
893 a8083063 Iustin Pop
894 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
895 72737a7f Iustin Pop
  def call_blockdev_remove(self, node, bdev):
896 72737a7f Iustin Pop
    """Request removal of a given block device.
897 a8083063 Iustin Pop

898 72737a7f Iustin Pop
    This is a single-node call.
899 f3e513ad Iustin Pop

900 72737a7f Iustin Pop
    """
901 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_remove", [bdev.ToDict()])
902 f3e513ad Iustin Pop
903 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
904 72737a7f Iustin Pop
  def call_blockdev_rename(self, node, devlist):
905 72737a7f Iustin Pop
    """Request rename of the given block devices.
906 f3e513ad Iustin Pop

907 72737a7f Iustin Pop
    This is a single-node call.
908 a8083063 Iustin Pop

909 72737a7f Iustin Pop
    """
910 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_rename",
911 9a525d83 Michael Hanselmann
                                [(d.ToDict(), uid) for d, uid in devlist])
912 a8083063 Iustin Pop
913 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
914 72737a7f Iustin Pop
  def call_blockdev_assemble(self, node, disk, owner, on_primary):
915 72737a7f Iustin Pop
    """Request assembling of a given block device.
916 a8083063 Iustin Pop

917 72737a7f Iustin Pop
    This is a single-node call.
918 a8083063 Iustin Pop

919 72737a7f Iustin Pop
    """
920 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_assemble",
921 9a525d83 Michael Hanselmann
                                [disk.ToDict(), owner, on_primary])
922 a8083063 Iustin Pop
923 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
924 72737a7f Iustin Pop
  def call_blockdev_shutdown(self, node, disk):
925 72737a7f Iustin Pop
    """Request shutdown of a given block device.
926 a8083063 Iustin Pop

927 72737a7f Iustin Pop
    This is a single-node call.
928 a8083063 Iustin Pop

929 72737a7f Iustin Pop
    """
930 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_shutdown", [disk.ToDict()])
931 a8083063 Iustin Pop
932 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
933 72737a7f Iustin Pop
  def call_blockdev_addchildren(self, node, bdev, ndevs):
934 72737a7f Iustin Pop
    """Request adding a list of children to a (mirroring) device.
935 a8083063 Iustin Pop

936 72737a7f Iustin Pop
    This is a single-node call.
937 a8083063 Iustin Pop

938 72737a7f Iustin Pop
    """
939 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_addchildren",
940 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
941 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
942 a8083063 Iustin Pop
943 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
944 72737a7f Iustin Pop
  def call_blockdev_removechildren(self, node, bdev, ndevs):
945 72737a7f Iustin Pop
    """Request removing a list of children from a (mirroring) device.
946 a8083063 Iustin Pop

947 72737a7f Iustin Pop
    This is a single-node call.
948 a8083063 Iustin Pop

949 72737a7f Iustin Pop
    """
950 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_removechildren",
951 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
952 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
953 a8083063 Iustin Pop
954 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
955 72737a7f Iustin Pop
  def call_blockdev_getmirrorstatus(self, node, disks):
956 72737a7f Iustin Pop
    """Request status of a (mirroring) device.
957 a8083063 Iustin Pop

958 72737a7f Iustin Pop
    This is a single-node call.
959 a8083063 Iustin Pop

960 72737a7f Iustin Pop
    """
961 36145b12 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_getmirrorstatus",
962 36145b12 Michael Hanselmann
                                  [dsk.ToDict() for dsk in disks])
963 edb4b374 Michael Hanselmann
    if not result.fail_msg:
964 36145b12 Michael Hanselmann
      result.payload = [objects.BlockDevStatus.FromDict(i)
965 36145b12 Michael Hanselmann
                        for i in result.payload]
966 36145b12 Michael Hanselmann
    return result
967 a8083063 Iustin Pop
968 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
969 72737a7f Iustin Pop
  def call_blockdev_find(self, node, disk):
970 72737a7f Iustin Pop
    """Request identification of a given block device.
971 72737a7f Iustin Pop

972 72737a7f Iustin Pop
    This is a single-node call.
973 a8083063 Iustin Pop

974 72737a7f Iustin Pop
    """
975 96acbc09 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_find", [disk.ToDict()])
976 edb4b374 Michael Hanselmann
    if not result.fail_msg and result.payload is not None:
977 96acbc09 Michael Hanselmann
      result.payload = objects.BlockDevStatus.FromDict(result.payload)
978 96acbc09 Michael Hanselmann
    return result
979 d61cbe76 Iustin Pop
980 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
981 b2e7666a Iustin Pop
  def call_blockdev_close(self, node, instance_name, disks):
982 72737a7f Iustin Pop
    """Closes the given block devices.
983 d61cbe76 Iustin Pop

984 72737a7f Iustin Pop
    This is a single-node call.
985 d61cbe76 Iustin Pop

986 72737a7f Iustin Pop
    """
987 b2e7666a Iustin Pop
    params = [instance_name, [cf.ToDict() for cf in disks]]
988 b2e7666a Iustin Pop
    return self._SingleNodeCall(node, "blockdev_close", params)
989 a8083063 Iustin Pop
990 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
991 968a7623 Iustin Pop
  def call_blockdev_getsizes(self, node, disks):
992 968a7623 Iustin Pop
    """Returns the size of the given disks.
993 968a7623 Iustin Pop

994 968a7623 Iustin Pop
    This is a single-node call.
995 968a7623 Iustin Pop

996 968a7623 Iustin Pop
    """
997 968a7623 Iustin Pop
    params = [[cf.ToDict() for cf in disks]]
998 968a7623 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_getsize", params)
999 968a7623 Iustin Pop
1000 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1001 6b93ec9d Iustin Pop
  def call_drbd_disconnect_net(self, node_list, nodes_ip, disks):
1002 6b93ec9d Iustin Pop
    """Disconnects the network of the given drbd devices.
1003 6b93ec9d Iustin Pop

1004 6b93ec9d Iustin Pop
    This is a multi-node call.
1005 6b93ec9d Iustin Pop

1006 6b93ec9d Iustin Pop
    """
1007 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_disconnect_net",
1008 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1009 6b93ec9d Iustin Pop
1010 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1011 6b93ec9d Iustin Pop
  def call_drbd_attach_net(self, node_list, nodes_ip,
1012 6b93ec9d Iustin Pop
                           disks, instance_name, multimaster):
1013 6b93ec9d Iustin Pop
    """Disconnects the given drbd devices.
1014 6b93ec9d Iustin Pop

1015 6b93ec9d Iustin Pop
    This is a multi-node call.
1016 6b93ec9d Iustin Pop

1017 6b93ec9d Iustin Pop
    """
1018 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_attach_net",
1019 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks],
1020 6b93ec9d Iustin Pop
                                instance_name, multimaster])
1021 6b93ec9d Iustin Pop
1022 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
1023 6b93ec9d Iustin Pop
  def call_drbd_wait_sync(self, node_list, nodes_ip, disks):
1024 6b93ec9d Iustin Pop
    """Waits for the synchronization of drbd devices is complete.
1025 6b93ec9d Iustin Pop

1026 6b93ec9d Iustin Pop
    This is a multi-node call.
1027 6b93ec9d Iustin Pop

1028 6b93ec9d Iustin Pop
    """
1029 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_wait_sync",
1030 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1031 6b93ec9d Iustin Pop
1032 c46b9782 Luca Bigliardi
  @_RpcTimeout(_TMO_URGENT)
1033 c46b9782 Luca Bigliardi
  def call_drbd_helper(self, node_list):
1034 c46b9782 Luca Bigliardi
    """Gets drbd helper.
1035 c46b9782 Luca Bigliardi

1036 c46b9782 Luca Bigliardi
    This is a multi-node call.
1037 c46b9782 Luca Bigliardi

1038 c46b9782 Luca Bigliardi
    """
1039 c46b9782 Luca Bigliardi
    return self._MultiNodeCall(node_list, "drbd_helper", [])
1040 c46b9782 Luca Bigliardi
1041 9a525d83 Michael Hanselmann
  @classmethod
1042 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1043 9a525d83 Michael Hanselmann
  def call_upload_file(cls, node_list, file_name, address_list=None):
1044 72737a7f Iustin Pop
    """Upload a file.
1045 72737a7f Iustin Pop

1046 72737a7f Iustin Pop
    The node will refuse the operation in case the file is not on the
1047 72737a7f Iustin Pop
    approved file list.
1048 72737a7f Iustin Pop

1049 72737a7f Iustin Pop
    This is a multi-node call.
1050 a8083063 Iustin Pop

1051 6b294c53 Iustin Pop
    @type node_list: list
1052 6b294c53 Iustin Pop
    @param node_list: the list of node names to upload to
1053 6b294c53 Iustin Pop
    @type file_name: str
1054 6b294c53 Iustin Pop
    @param file_name: the filename to upload
1055 6b294c53 Iustin Pop
    @type address_list: list or None
1056 6b294c53 Iustin Pop
    @keyword address_list: an optional list of node addresses, in order
1057 6b294c53 Iustin Pop
        to optimize the RPC speed
1058 6b294c53 Iustin Pop

1059 72737a7f Iustin Pop
    """
1060 12bce260 Michael Hanselmann
    file_contents = utils.ReadFile(file_name)
1061 12bce260 Michael Hanselmann
    data = cls._Compress(file_contents)
1062 72737a7f Iustin Pop
    st = os.stat(file_name)
1063 72737a7f Iustin Pop
    params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
1064 72737a7f Iustin Pop
              st.st_atime, st.st_mtime]
1065 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "upload_file", params,
1066 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1067 72737a7f Iustin Pop
1068 6ddc95ec Michael Hanselmann
  @classmethod
1069 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1070 03d1dba2 Michael Hanselmann
  def call_write_ssconf_files(cls, node_list, values):
1071 6ddc95ec Michael Hanselmann
    """Write ssconf files.
1072 6ddc95ec Michael Hanselmann

1073 6ddc95ec Michael Hanselmann
    This is a multi-node call.
1074 6ddc95ec Michael Hanselmann

1075 6ddc95ec Michael Hanselmann
    """
1076 03d1dba2 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "write_ssconf_files", [values])
1077 6ddc95ec Michael Hanselmann
1078 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1079 72737a7f Iustin Pop
  def call_os_diagnose(self, node_list):
1080 72737a7f Iustin Pop
    """Request a diagnose of OS definitions.
1081 72737a7f Iustin Pop

1082 72737a7f Iustin Pop
    This is a multi-node call.
1083 a8083063 Iustin Pop

1084 72737a7f Iustin Pop
    """
1085 83d92ad8 Iustin Pop
    return self._MultiNodeCall(node_list, "os_diagnose", [])
1086 a8083063 Iustin Pop
1087 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1088 72737a7f Iustin Pop
  def call_os_get(self, node, name):
1089 72737a7f Iustin Pop
    """Returns an OS definition.
1090 a8083063 Iustin Pop

1091 72737a7f Iustin Pop
    This is a single-node call.
1092 a8083063 Iustin Pop

1093 72737a7f Iustin Pop
    """
1094 9a525d83 Michael Hanselmann
    result = self._SingleNodeCall(node, "os_get", [name])
1095 84e3f66f Guido Trotter
    if not result.fail_msg and isinstance(result.payload, dict):
1096 84e3f66f Guido Trotter
      result.payload = objects.OS.FromDict(result.payload)
1097 781de953 Iustin Pop
    return result
1098 a8083063 Iustin Pop
1099 acd9ff9e Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1100 acd9ff9e Iustin Pop
  def call_os_validate(self, required, nodes, name, checks, params):
1101 acd9ff9e Iustin Pop
    """Run a validation routine for a given OS.
1102 acd9ff9e Iustin Pop

1103 acd9ff9e Iustin Pop
    This is a multi-node call.
1104 acd9ff9e Iustin Pop

1105 acd9ff9e Iustin Pop
    """
1106 acd9ff9e Iustin Pop
    return self._MultiNodeCall(nodes, "os_validate",
1107 acd9ff9e Iustin Pop
                               [required, name, checks, params])
1108 acd9ff9e Iustin Pop
1109 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1110 72737a7f Iustin Pop
  def call_hooks_runner(self, node_list, hpath, phase, env):
1111 72737a7f Iustin Pop
    """Call the hooks runner.
1112 a8083063 Iustin Pop

1113 72737a7f Iustin Pop
    Args:
1114 72737a7f Iustin Pop
      - op: the OpCode instance
1115 72737a7f Iustin Pop
      - env: a dictionary with the environment
1116 a8083063 Iustin Pop

1117 72737a7f Iustin Pop
    This is a multi-node call.
1118 a8083063 Iustin Pop

1119 72737a7f Iustin Pop
    """
1120 72737a7f Iustin Pop
    params = [hpath, phase, env]
1121 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hooks_runner", params)
1122 a8083063 Iustin Pop
1123 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1124 72737a7f Iustin Pop
  def call_iallocator_runner(self, node, name, idata):
1125 72737a7f Iustin Pop
    """Call an iallocator on a remote node
1126 8d528b7c Iustin Pop

1127 72737a7f Iustin Pop
    Args:
1128 72737a7f Iustin Pop
      - name: the iallocator name
1129 72737a7f Iustin Pop
      - input: the json-encoded input string
1130 8d528b7c Iustin Pop

1131 72737a7f Iustin Pop
    This is a single-node call.
1132 8d528b7c Iustin Pop

1133 72737a7f Iustin Pop
    """
1134 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "iallocator_runner", [name, idata])
1135 8d528b7c Iustin Pop
1136 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1137 72737a7f Iustin Pop
  def call_blockdev_grow(self, node, cf_bdev, amount):
1138 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1139 4c8ba8b3 Iustin Pop

1140 72737a7f Iustin Pop
    This is a single-node call.
1141 4c8ba8b3 Iustin Pop

1142 72737a7f Iustin Pop
    """
1143 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_grow",
1144 9a525d83 Michael Hanselmann
                                [cf_bdev.ToDict(), amount])
1145 4c8ba8b3 Iustin Pop
1146 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_1DAY)
1147 858f3d18 Iustin Pop
  def call_blockdev_export(self, node, cf_bdev,
1148 858f3d18 Iustin Pop
                           dest_node, dest_path, cluster_name):
1149 858f3d18 Iustin Pop
    """Export a given disk to another node.
1150 858f3d18 Iustin Pop

1151 858f3d18 Iustin Pop
    This is a single-node call.
1152 858f3d18 Iustin Pop

1153 858f3d18 Iustin Pop
    """
1154 858f3d18 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_export",
1155 858f3d18 Iustin Pop
                                [cf_bdev.ToDict(), dest_node, dest_path,
1156 858f3d18 Iustin Pop
                                 cluster_name])
1157 858f3d18 Iustin Pop
1158 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1159 72737a7f Iustin Pop
  def call_blockdev_snapshot(self, node, cf_bdev):
1160 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1161 a8083063 Iustin Pop

1162 72737a7f Iustin Pop
    This is a single-node call.
1163 a8083063 Iustin Pop

1164 72737a7f Iustin Pop
    """
1165 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_snapshot", [cf_bdev.ToDict()])
1166 a8083063 Iustin Pop
1167 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1168 72737a7f Iustin Pop
  def call_finalize_export(self, node, instance, snap_disks):
1169 72737a7f Iustin Pop
    """Request the completion of an export operation.
1170 a8083063 Iustin Pop

1171 72737a7f Iustin Pop
    This writes the export config file, etc.
1172 a8083063 Iustin Pop

1173 72737a7f Iustin Pop
    This is a single-node call.
1174 a8083063 Iustin Pop

1175 72737a7f Iustin Pop
    """
1176 72737a7f Iustin Pop
    flat_disks = []
1177 72737a7f Iustin Pop
    for disk in snap_disks:
1178 a97da6b7 Iustin Pop
      if isinstance(disk, bool):
1179 a97da6b7 Iustin Pop
        flat_disks.append(disk)
1180 a97da6b7 Iustin Pop
      else:
1181 a97da6b7 Iustin Pop
        flat_disks.append(disk.ToDict())
1182 9a525d83 Michael Hanselmann
1183 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "finalize_export",
1184 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), flat_disks])
1185 a8083063 Iustin Pop
1186 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1187 72737a7f Iustin Pop
  def call_export_info(self, node, path):
1188 72737a7f Iustin Pop
    """Queries the export information in a given path.
1189 a8083063 Iustin Pop

1190 72737a7f Iustin Pop
    This is a single-node call.
1191 a8083063 Iustin Pop

1192 72737a7f Iustin Pop
    """
1193 3eccac06 Iustin Pop
    return self._SingleNodeCall(node, "export_info", [path])
1194 a8083063 Iustin Pop
1195 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1196 72737a7f Iustin Pop
  def call_export_list(self, node_list):
1197 72737a7f Iustin Pop
    """Gets the stored exports list.
1198 a8083063 Iustin Pop

1199 72737a7f Iustin Pop
    This is a multi-node call.
1200 a8083063 Iustin Pop

1201 72737a7f Iustin Pop
    """
1202 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "export_list", [])
1203 a8083063 Iustin Pop
1204 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1205 72737a7f Iustin Pop
  def call_export_remove(self, node, export):
1206 72737a7f Iustin Pop
    """Requests removal of a given export.
1207 a8083063 Iustin Pop

1208 72737a7f Iustin Pop
    This is a single-node call.
1209 a8083063 Iustin Pop

1210 72737a7f Iustin Pop
    """
1211 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "export_remove", [export])
1212 a8083063 Iustin Pop
1213 9a525d83 Michael Hanselmann
  @classmethod
1214 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1215 b989b9d9 Ken Wehr
  def call_node_leave_cluster(cls, node, modify_ssh_setup):
1216 72737a7f Iustin Pop
    """Requests a node to clean the cluster information it has.
1217 a8083063 Iustin Pop

1218 72737a7f Iustin Pop
    This will remove the configuration information from the ganeti data
1219 72737a7f Iustin Pop
    dir.
1220 a8083063 Iustin Pop

1221 72737a7f Iustin Pop
    This is a single-node call.
1222 a8083063 Iustin Pop

1223 72737a7f Iustin Pop
    """
1224 b989b9d9 Ken Wehr
    return cls._StaticSingleNodeCall(node, "node_leave_cluster",
1225 b989b9d9 Ken Wehr
                                     [modify_ssh_setup])
1226 dcb93971 Michael Hanselmann
1227 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1228 72737a7f Iustin Pop
  def call_node_volumes(self, node_list):
1229 72737a7f Iustin Pop
    """Gets all volumes on node(s).
1230 dcb93971 Michael Hanselmann

1231 72737a7f Iustin Pop
    This is a multi-node call.
1232 dcb93971 Michael Hanselmann

1233 72737a7f Iustin Pop
    """
1234 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_volumes", [])
1235 06009e27 Iustin Pop
1236 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1237 56aa9fd5 Iustin Pop
  def call_node_demote_from_mc(self, node):
1238 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
1239 56aa9fd5 Iustin Pop

1240 56aa9fd5 Iustin Pop
    This is a single-node call.
1241 56aa9fd5 Iustin Pop

1242 56aa9fd5 Iustin Pop
    """
1243 56aa9fd5 Iustin Pop
    return self._SingleNodeCall(node, "node_demote_from_mc", [])
1244 56aa9fd5 Iustin Pop
1245 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1246 f5118ade Iustin Pop
  def call_node_powercycle(self, node, hypervisor):
1247 f5118ade Iustin Pop
    """Tries to powercycle a node.
1248 f5118ade Iustin Pop

1249 f5118ade Iustin Pop
    This is a single-node call.
1250 f5118ade Iustin Pop

1251 f5118ade Iustin Pop
    """
1252 f5118ade Iustin Pop
    return self._SingleNodeCall(node, "node_powercycle", [hypervisor])
1253 f5118ade Iustin Pop
1254 92fd2250 Iustin Pop
  @_RpcTimeout(None)
1255 72737a7f Iustin Pop
  def call_test_delay(self, node_list, duration):
1256 72737a7f Iustin Pop
    """Sleep for a fixed time on given node(s).
1257 06009e27 Iustin Pop

1258 72737a7f Iustin Pop
    This is a multi-node call.
1259 06009e27 Iustin Pop

1260 72737a7f Iustin Pop
    """
1261 92fd2250 Iustin Pop
    return self._MultiNodeCall(node_list, "test_delay", [duration],
1262 92fd2250 Iustin Pop
                               read_timeout=int(duration + 5))
1263 5e04ed8b Manuel Franceschini
1264 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1265 72737a7f Iustin Pop
  def call_file_storage_dir_create(self, node, file_storage_dir):
1266 72737a7f Iustin Pop
    """Create the given file storage directory.
1267 5e04ed8b Manuel Franceschini

1268 72737a7f Iustin Pop
    This is a single-node call.
1269 5e04ed8b Manuel Franceschini

1270 72737a7f Iustin Pop
    """
1271 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_create",
1272 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1273 5e04ed8b Manuel Franceschini
1274 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1275 72737a7f Iustin Pop
  def call_file_storage_dir_remove(self, node, file_storage_dir):
1276 72737a7f Iustin Pop
    """Remove the given file storage directory.
1277 5e04ed8b Manuel Franceschini

1278 72737a7f Iustin Pop
    This is a single-node call.
1279 5e04ed8b Manuel Franceschini

1280 72737a7f Iustin Pop
    """
1281 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_remove",
1282 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1283 5e04ed8b Manuel Franceschini
1284 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1285 72737a7f Iustin Pop
  def call_file_storage_dir_rename(self, node, old_file_storage_dir,
1286 72737a7f Iustin Pop
                                   new_file_storage_dir):
1287 72737a7f Iustin Pop
    """Rename file storage directory.
1288 5e04ed8b Manuel Franceschini

1289 72737a7f Iustin Pop
    This is a single-node call.
1290 5e04ed8b Manuel Franceschini

1291 72737a7f Iustin Pop
    """
1292 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_rename",
1293 9a525d83 Michael Hanselmann
                                [old_file_storage_dir, new_file_storage_dir])
1294 ca52cdeb Michael Hanselmann
1295 9a525d83 Michael Hanselmann
  @classmethod
1296 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1297 9a525d83 Michael Hanselmann
  def call_jobqueue_update(cls, node_list, address_list, file_name, content):
1298 72737a7f Iustin Pop
    """Update job queue.
1299 ca52cdeb Michael Hanselmann

1300 72737a7f Iustin Pop
    This is a multi-node call.
1301 ca52cdeb Michael Hanselmann

1302 72737a7f Iustin Pop
    """
1303 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_update",
1304 12bce260 Michael Hanselmann
                                    [file_name, cls._Compress(content)],
1305 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1306 ca52cdeb Michael Hanselmann
1307 9a525d83 Michael Hanselmann
  @classmethod
1308 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1309 9a525d83 Michael Hanselmann
  def call_jobqueue_purge(cls, node):
1310 72737a7f Iustin Pop
    """Purge job queue.
1311 ca52cdeb Michael Hanselmann

1312 72737a7f Iustin Pop
    This is a single-node call.
1313 ca52cdeb Michael Hanselmann

1314 72737a7f Iustin Pop
    """
1315 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "jobqueue_purge", [])
1316 af5ebcb1 Michael Hanselmann
1317 9a525d83 Michael Hanselmann
  @classmethod
1318 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1319 dd875d32 Michael Hanselmann
  def call_jobqueue_rename(cls, node_list, address_list, rename):
1320 72737a7f Iustin Pop
    """Rename a job queue file.
1321 af5ebcb1 Michael Hanselmann

1322 72737a7f Iustin Pop
    This is a multi-node call.
1323 af5ebcb1 Michael Hanselmann

1324 72737a7f Iustin Pop
    """
1325 dd875d32 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_rename", rename,
1326 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1327 6217e295 Iustin Pop
1328 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1329 6217e295 Iustin Pop
  def call_hypervisor_validate_params(self, node_list, hvname, hvparams):
1330 6217e295 Iustin Pop
    """Validate the hypervisor params.
1331 6217e295 Iustin Pop

1332 6217e295 Iustin Pop
    This is a multi-node call.
1333 6217e295 Iustin Pop

1334 6217e295 Iustin Pop
    @type node_list: list
1335 6217e295 Iustin Pop
    @param node_list: the list of nodes to query
1336 6217e295 Iustin Pop
    @type hvname: string
1337 6217e295 Iustin Pop
    @param hvname: the hypervisor name
1338 6217e295 Iustin Pop
    @type hvparams: dict
1339 6217e295 Iustin Pop
    @param hvparams: the hypervisor parameters to be validated
1340 6217e295 Iustin Pop

1341 6217e295 Iustin Pop
    """
1342 6217e295 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
1343 abe609b2 Guido Trotter
    hv_full = objects.FillDict(cluster.hvparams.get(hvname, {}), hvparams)
1344 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hypervisor_validate_params",
1345 9a525d83 Michael Hanselmann
                               [hvname, hv_full])
1346 f942a838 Michael Hanselmann
1347 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1348 37549316 Michael Hanselmann
  def call_x509_cert_create(self, node, validity):
1349 f942a838 Michael Hanselmann
    """Creates a new X509 certificate for SSL/TLS.
1350 f942a838 Michael Hanselmann

1351 f942a838 Michael Hanselmann
    This is a single-node call.
1352 f942a838 Michael Hanselmann

1353 f942a838 Michael Hanselmann
    @type validity: int
1354 f942a838 Michael Hanselmann
    @param validity: Validity in seconds
1355 f942a838 Michael Hanselmann

1356 f942a838 Michael Hanselmann
    """
1357 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_create", [validity])
1358 f942a838 Michael Hanselmann
1359 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1360 37549316 Michael Hanselmann
  def call_x509_cert_remove(self, node, name):
1361 f942a838 Michael Hanselmann
    """Removes a X509 certificate.
1362 f942a838 Michael Hanselmann

1363 f942a838 Michael Hanselmann
    This is a single-node call.
1364 f942a838 Michael Hanselmann

1365 f942a838 Michael Hanselmann
    @type name: string
1366 f942a838 Michael Hanselmann
    @param name: Certificate name
1367 f942a838 Michael Hanselmann

1368 f942a838 Michael Hanselmann
    """
1369 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_remove", [name])
1370 1651d116 Michael Hanselmann
1371 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1372 eb630f50 Michael Hanselmann
  def call_import_start(self, node, opts, instance, dest, dest_args):
1373 1651d116 Michael Hanselmann
    """Starts a listener for an import.
1374 1651d116 Michael Hanselmann

1375 1651d116 Michael Hanselmann
    This is a single-node call.
1376 1651d116 Michael Hanselmann

1377 1651d116 Michael Hanselmann
    @type node: string
1378 1651d116 Michael Hanselmann
    @param node: Node name
1379 1651d116 Michael Hanselmann
    @type instance: C{objects.Instance}
1380 1651d116 Michael Hanselmann
    @param instance: Instance object
1381 1651d116 Michael Hanselmann

1382 1651d116 Michael Hanselmann
    """
1383 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "import_start",
1384 eb630f50 Michael Hanselmann
                                [opts.ToDict(),
1385 1651d116 Michael Hanselmann
                                 self._InstDict(instance), dest,
1386 1651d116 Michael Hanselmann
                                 _EncodeImportExportIO(dest, dest_args)])
1387 1651d116 Michael Hanselmann
1388 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1389 eb630f50 Michael Hanselmann
  def call_export_start(self, node, opts, host, port,
1390 1651d116 Michael Hanselmann
                        instance, source, source_args):
1391 1651d116 Michael Hanselmann
    """Starts an export daemon.
1392 1651d116 Michael Hanselmann

1393 1651d116 Michael Hanselmann
    This is a single-node call.
1394 1651d116 Michael Hanselmann

1395 1651d116 Michael Hanselmann
    @type node: string
1396 1651d116 Michael Hanselmann
    @param node: Node name
1397 1651d116 Michael Hanselmann
    @type instance: C{objects.Instance}
1398 1651d116 Michael Hanselmann
    @param instance: Instance object
1399 1651d116 Michael Hanselmann

1400 1651d116 Michael Hanselmann
    """
1401 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "export_start",
1402 eb630f50 Michael Hanselmann
                                [opts.ToDict(), host, port,
1403 1651d116 Michael Hanselmann
                                 self._InstDict(instance), source,
1404 1651d116 Michael Hanselmann
                                 _EncodeImportExportIO(source, source_args)])
1405 1651d116 Michael Hanselmann
1406 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1407 ef40fbfb Michael Hanselmann
  def call_impexp_status(self, node, names):
1408 1651d116 Michael Hanselmann
    """Gets the status of an import or export.
1409 1651d116 Michael Hanselmann

1410 1651d116 Michael Hanselmann
    This is a single-node call.
1411 1651d116 Michael Hanselmann

1412 1651d116 Michael Hanselmann
    @type node: string
1413 1651d116 Michael Hanselmann
    @param node: Node name
1414 1651d116 Michael Hanselmann
    @type names: List of strings
1415 1651d116 Michael Hanselmann
    @param names: Import/export names
1416 1651d116 Michael Hanselmann
    @rtype: List of L{objects.ImportExportStatus} instances
1417 1651d116 Michael Hanselmann
    @return: Returns a list of the state of each named import/export or None if
1418 1651d116 Michael Hanselmann
             a status couldn't be retrieved
1419 1651d116 Michael Hanselmann

1420 1651d116 Michael Hanselmann
    """
1421 ef40fbfb Michael Hanselmann
    result = self._SingleNodeCall(node, "impexp_status", [names])
1422 1651d116 Michael Hanselmann
1423 1651d116 Michael Hanselmann
    if not result.fail_msg:
1424 1651d116 Michael Hanselmann
      decoded = []
1425 1651d116 Michael Hanselmann
1426 1651d116 Michael Hanselmann
      for i in result.payload:
1427 1651d116 Michael Hanselmann
        if i is None:
1428 1651d116 Michael Hanselmann
          decoded.append(None)
1429 1651d116 Michael Hanselmann
          continue
1430 1651d116 Michael Hanselmann
        decoded.append(objects.ImportExportStatus.FromDict(i))
1431 1651d116 Michael Hanselmann
1432 1651d116 Michael Hanselmann
      result.payload = decoded
1433 1651d116 Michael Hanselmann
1434 1651d116 Michael Hanselmann
    return result
1435 1651d116 Michael Hanselmann
1436 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1437 f81c4737 Michael Hanselmann
  def call_impexp_abort(self, node, name):
1438 f81c4737 Michael Hanselmann
    """Aborts an import or export.
1439 f81c4737 Michael Hanselmann

1440 f81c4737 Michael Hanselmann
    This is a single-node call.
1441 f81c4737 Michael Hanselmann

1442 f81c4737 Michael Hanselmann
    @type node: string
1443 f81c4737 Michael Hanselmann
    @param node: Node name
1444 f81c4737 Michael Hanselmann
    @type name: string
1445 f81c4737 Michael Hanselmann
    @param name: Import/export name
1446 f81c4737 Michael Hanselmann

1447 f81c4737 Michael Hanselmann
    """
1448 f81c4737 Michael Hanselmann
    return self._SingleNodeCall(node, "impexp_abort", [name])
1449 f81c4737 Michael Hanselmann
1450 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1451 ef40fbfb Michael Hanselmann
  def call_impexp_cleanup(self, node, name):
1452 1651d116 Michael Hanselmann
    """Cleans up after an import or export.
1453 1651d116 Michael Hanselmann

1454 1651d116 Michael Hanselmann
    This is a single-node call.
1455 1651d116 Michael Hanselmann

1456 1651d116 Michael Hanselmann
    @type node: string
1457 1651d116 Michael Hanselmann
    @param node: Node name
1458 1651d116 Michael Hanselmann
    @type name: string
1459 1651d116 Michael Hanselmann
    @param name: Import/export name
1460 1651d116 Michael Hanselmann

1461 1651d116 Michael Hanselmann
    """
1462 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "impexp_cleanup", [name])