Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ 51b13ce9

History | View | Annotate | Download (44 kB)

1 2f31098c Iustin Pop
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 eb202c13 Manuel Franceschini
# Copyright (C) 2006, 2007, 2010 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 eb202c13 Manuel Franceschini
from ganeti import ssconf
48 a8083063 Iustin Pop
49 fe267188 Iustin Pop
# pylint has a bug here, doesn't see this import
50 fe267188 Iustin Pop
import ganeti.http.client  # pylint: disable-msg=W0611
51 ae88ef45 Michael Hanselmann
52 a8083063 Iustin Pop
53 33231500 Michael Hanselmann
# Timeout for connecting to nodes (seconds)
54 33231500 Michael Hanselmann
_RPC_CONNECT_TIMEOUT = 5
55 33231500 Michael Hanselmann
56 33231500 Michael Hanselmann
_RPC_CLIENT_HEADERS = [
57 33231500 Michael Hanselmann
  "Content-type: %s" % http.HTTP_APP_JSON,
58 33231500 Michael Hanselmann
  ]
59 4331f6cd Michael Hanselmann
60 92fd2250 Iustin Pop
# Various time constants for the timeout table
61 92fd2250 Iustin Pop
_TMO_URGENT = 60 # one minute
62 92fd2250 Iustin Pop
_TMO_FAST = 5 * 60 # five minutes
63 92fd2250 Iustin Pop
_TMO_NORMAL = 15 * 60 # 15 minutes
64 92fd2250 Iustin Pop
_TMO_SLOW = 3600 # one hour
65 92fd2250 Iustin Pop
_TMO_4HRS = 4 * 3600
66 92fd2250 Iustin Pop
_TMO_1DAY = 86400
67 92fd2250 Iustin Pop
68 92fd2250 Iustin Pop
# Timeout table that will be built later by decorators
69 92fd2250 Iustin Pop
# Guidelines for choosing timeouts:
70 92fd2250 Iustin Pop
# - call used during watcher: timeout -> 1min, _TMO_URGENT
71 92fd2250 Iustin Pop
# - trivial (but be sure it is trivial) (e.g. reading a file): 5min, _TMO_FAST
72 92fd2250 Iustin Pop
# - other calls: 15 min, _TMO_NORMAL
73 92fd2250 Iustin Pop
# - special calls (instance add, etc.): either _TMO_SLOW (1h) or huge timeouts
74 92fd2250 Iustin Pop
75 92fd2250 Iustin Pop
_TIMEOUTS = {
76 92fd2250 Iustin Pop
}
77 92fd2250 Iustin Pop
78 4331f6cd Michael Hanselmann
79 4331f6cd Michael Hanselmann
def Init():
80 4331f6cd Michael Hanselmann
  """Initializes the module-global HTTP client manager.
81 4331f6cd Michael Hanselmann

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

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

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

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

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

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

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

146 92fd2250 Iustin Pop
  """
147 92fd2250 Iustin Pop
  def decorator(f):
148 92fd2250 Iustin Pop
    name = f.__name__
149 92fd2250 Iustin Pop
    assert name.startswith("call_")
150 92fd2250 Iustin Pop
    _TIMEOUTS[name[len("call_"):]] = secs
151 92fd2250 Iustin Pop
    return f
152 92fd2250 Iustin Pop
  return decorator
153 92fd2250 Iustin Pop
154 92fd2250 Iustin Pop
155 e0e916fe Iustin Pop
def RunWithRPC(fn):
156 e0e916fe Iustin Pop
  """RPC-wrapper decorator.
157 e0e916fe Iustin Pop

158 e0e916fe Iustin Pop
  When applied to a function, it runs it with the RPC system
159 e0e916fe Iustin Pop
  initialized, and it shutsdown the system afterwards. This means the
160 e0e916fe Iustin Pop
  function must be called without RPC being initialized.
161 e0e916fe Iustin Pop

162 e0e916fe Iustin Pop
  """
163 e0e916fe Iustin Pop
  def wrapper(*args, **kwargs):
164 e0e916fe Iustin Pop
    Init()
165 e0e916fe Iustin Pop
    try:
166 e0e916fe Iustin Pop
      return fn(*args, **kwargs)
167 e0e916fe Iustin Pop
    finally:
168 e0e916fe Iustin Pop
      Shutdown()
169 e0e916fe Iustin Pop
  return wrapper
170 e0e916fe Iustin Pop
171 e0e916fe Iustin Pop
172 781de953 Iustin Pop
class RpcResult(object):
173 781de953 Iustin Pop
  """RPC Result class.
174 781de953 Iustin Pop

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

179 5bbd3f7f Michael Hanselmann
  @ivar data: the data payload, for successful results, or None
180 ed83f5cc Iustin Pop
  @ivar call: the name of the RPC call
181 ed83f5cc Iustin Pop
  @ivar node: the name of the node to which we made the call
182 ed83f5cc Iustin Pop
  @ivar offline: whether the operation failed because the node was
183 ed83f5cc Iustin Pop
      offline, as opposed to actual failure; offline=True will always
184 ed83f5cc Iustin Pop
      imply failed=True, in order to allow simpler checking if
185 ed83f5cc Iustin Pop
      the user doesn't care about the exact failure mode
186 4c4e4e1e Iustin Pop
  @ivar fail_msg: the error message if the call failed
187 ed83f5cc Iustin Pop

188 781de953 Iustin Pop
  """
189 ed83f5cc Iustin Pop
  def __init__(self, data=None, failed=False, offline=False,
190 ed83f5cc Iustin Pop
               call=None, node=None):
191 ed83f5cc Iustin Pop
    self.offline = offline
192 ed83f5cc Iustin Pop
    self.call = call
193 ed83f5cc Iustin Pop
    self.node = node
194 1645d22d Michael Hanselmann
195 ed83f5cc Iustin Pop
    if offline:
196 4c4e4e1e Iustin Pop
      self.fail_msg = "Node is marked offline"
197 f2def43a Iustin Pop
      self.data = self.payload = None
198 ed83f5cc Iustin Pop
    elif failed:
199 4c4e4e1e Iustin Pop
      self.fail_msg = self._EnsureErr(data)
200 f2def43a Iustin Pop
      self.data = self.payload = None
201 781de953 Iustin Pop
    else:
202 781de953 Iustin Pop
      self.data = data
203 d3c8b360 Iustin Pop
      if not isinstance(self.data, (tuple, list)):
204 4c4e4e1e Iustin Pop
        self.fail_msg = ("RPC layer error: invalid result type (%s)" %
205 4c4e4e1e Iustin Pop
                         type(self.data))
206 1645d22d Michael Hanselmann
        self.payload = None
207 d3c8b360 Iustin Pop
      elif len(data) != 2:
208 4c4e4e1e Iustin Pop
        self.fail_msg = ("RPC layer error: invalid result length (%d), "
209 4c4e4e1e Iustin Pop
                         "expected 2" % len(self.data))
210 1645d22d Michael Hanselmann
        self.payload = None
211 d3c8b360 Iustin Pop
      elif not self.data[0]:
212 4c4e4e1e Iustin Pop
        self.fail_msg = self._EnsureErr(self.data[1])
213 1645d22d Michael Hanselmann
        self.payload = None
214 f2def43a Iustin Pop
      else:
215 d3c8b360 Iustin Pop
        # finally success
216 4c4e4e1e Iustin Pop
        self.fail_msg = None
217 d3c8b360 Iustin Pop
        self.payload = data[1]
218 d3c8b360 Iustin Pop
219 1645d22d Michael Hanselmann
    assert hasattr(self, "call")
220 1645d22d Michael Hanselmann
    assert hasattr(self, "data")
221 1645d22d Michael Hanselmann
    assert hasattr(self, "fail_msg")
222 1645d22d Michael Hanselmann
    assert hasattr(self, "node")
223 1645d22d Michael Hanselmann
    assert hasattr(self, "offline")
224 1645d22d Michael Hanselmann
    assert hasattr(self, "payload")
225 1645d22d Michael Hanselmann
226 d3c8b360 Iustin Pop
  @staticmethod
227 d3c8b360 Iustin Pop
  def _EnsureErr(val):
228 d3c8b360 Iustin Pop
    """Helper to ensure we return a 'True' value for error."""
229 d3c8b360 Iustin Pop
    if val:
230 d3c8b360 Iustin Pop
      return val
231 d3c8b360 Iustin Pop
    else:
232 d3c8b360 Iustin Pop
      return "No error information"
233 781de953 Iustin Pop
234 045dd6d9 Iustin Pop
  def Raise(self, msg, prereq=False, ecode=None):
235 781de953 Iustin Pop
    """If the result has failed, raise an OpExecError.
236 781de953 Iustin Pop

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

240 781de953 Iustin Pop
    """
241 4c4e4e1e Iustin Pop
    if not self.fail_msg:
242 4c4e4e1e Iustin Pop
      return
243 4c4e4e1e Iustin Pop
244 4c4e4e1e Iustin Pop
    if not msg: # one could pass None for default message
245 4c4e4e1e Iustin Pop
      msg = ("Call '%s' to node '%s' has failed: %s" %
246 4c4e4e1e Iustin Pop
             (self.call, self.node, self.fail_msg))
247 4c4e4e1e Iustin Pop
    else:
248 4c4e4e1e Iustin Pop
      msg = "%s: %s" % (msg, self.fail_msg)
249 4c4e4e1e Iustin Pop
    if prereq:
250 4c4e4e1e Iustin Pop
      ec = errors.OpPrereqError
251 4c4e4e1e Iustin Pop
    else:
252 4c4e4e1e Iustin Pop
      ec = errors.OpExecError
253 045dd6d9 Iustin Pop
    if ecode is not None:
254 27137e55 Iustin Pop
      args = (msg, ecode)
255 045dd6d9 Iustin Pop
    else:
256 045dd6d9 Iustin Pop
      args = (msg, )
257 7260cfbe Iustin Pop
    raise ec(*args) # pylint: disable-msg=W0142
258 781de953 Iustin Pop
259 781de953 Iustin Pop
260 eb202c13 Manuel Franceschini
def _AddressLookup(node_list,
261 eb202c13 Manuel Franceschini
                   ssc=ssconf.SimpleStore,
262 b705c7a6 Manuel Franceschini
                   nslookup_fn=netutils.Hostname.GetIP):
263 eb202c13 Manuel Franceschini
  """Return addresses for given node names.
264 eb202c13 Manuel Franceschini

265 eb202c13 Manuel Franceschini
  @type node_list: list
266 eb202c13 Manuel Franceschini
  @param node_list: List of node names
267 eb202c13 Manuel Franceschini
  @type ssc: class
268 eb202c13 Manuel Franceschini
  @param ssc: SimpleStore class that is used to obtain node->ip mappings
269 eb202c13 Manuel Franceschini
  @type lookup_fn: callable
270 eb202c13 Manuel Franceschini
  @param lookup_fn: function use to do NS lookup
271 eb202c13 Manuel Franceschini
  @rtype: list of addresses and/or None's
272 eb202c13 Manuel Franceschini
  @returns: List of corresponding addresses, if found
273 eb202c13 Manuel Franceschini

274 eb202c13 Manuel Franceschini
  """
275 b43dcc5a Manuel Franceschini
  ss = ssc()
276 b43dcc5a Manuel Franceschini
  iplist = ss.GetNodePrimaryIPList()
277 b43dcc5a Manuel Franceschini
  family = ss.GetPrimaryIPFamily()
278 eb202c13 Manuel Franceschini
  addresses = []
279 b705c7a6 Manuel Franceschini
  ipmap = dict(entry.split() for entry in iplist)
280 b705c7a6 Manuel Franceschini
  for node in node_list:
281 b705c7a6 Manuel Franceschini
    address = ipmap.get(node)
282 b705c7a6 Manuel Franceschini
    if address is None:
283 b43dcc5a Manuel Franceschini
      address = nslookup_fn(node, family=family)
284 b705c7a6 Manuel Franceschini
    addresses.append(address)
285 eb202c13 Manuel Franceschini
286 eb202c13 Manuel Franceschini
  return addresses
287 eb202c13 Manuel Franceschini
288 eb202c13 Manuel Franceschini
289 a8083063 Iustin Pop
class Client:
290 a8083063 Iustin Pop
  """RPC Client class.
291 a8083063 Iustin Pop

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

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

300 a8083063 Iustin Pop
  """
301 eb202c13 Manuel Franceschini
  def __init__(self, procedure, body, port, address_lookup_fn=_AddressLookup):
302 92fd2250 Iustin Pop
    assert procedure in _TIMEOUTS, ("New RPC call not declared in the"
303 92fd2250 Iustin Pop
                                    " timeouts table")
304 a8083063 Iustin Pop
    self.procedure = procedure
305 160e2921 Iustin Pop
    self.body = body
306 160e2921 Iustin Pop
    self.port = port
307 33231500 Michael Hanselmann
    self._request = {}
308 eb202c13 Manuel Franceschini
    self._address_lookup_fn = address_lookup_fn
309 d57ae7f7 Michael Hanselmann
310 e0036155 Iustin Pop
  def ConnectList(self, node_list, address_list=None, read_timeout=None):
311 a8083063 Iustin Pop
    """Add a list of nodes to the target nodes.
312 a8083063 Iustin Pop

313 3ef3c771 Iustin Pop
    @type node_list: list
314 3ef3c771 Iustin Pop
    @param node_list: the list of node names to connect
315 bdf7d8c0 Iustin Pop
    @type address_list: list or None
316 bdf7d8c0 Iustin Pop
    @keyword address_list: either None or a list with node addresses,
317 bdf7d8c0 Iustin Pop
        which must have the same length as the node list
318 e0036155 Iustin Pop
    @type read_timeout: int
319 eb202c13 Manuel Franceschini
    @param read_timeout: overwrites default timeout for operation
320 3ef3c771 Iustin Pop

321 a8083063 Iustin Pop
    """
322 bdf7d8c0 Iustin Pop
    if address_list is None:
323 eb202c13 Manuel Franceschini
      # Always use IP address instead of node name
324 eb202c13 Manuel Franceschini
      address_list = self._address_lookup_fn(node_list)
325 eb202c13 Manuel Franceschini
326 eb202c13 Manuel Franceschini
    assert len(node_list) == len(address_list), \
327 eb202c13 Manuel Franceschini
           "Name and address lists must have the same length"
328 eb202c13 Manuel Franceschini
329 bdf7d8c0 Iustin Pop
    for node, address in zip(node_list, address_list):
330 e0036155 Iustin Pop
      self.ConnectNode(node, address, read_timeout=read_timeout)
331 bdf7d8c0 Iustin Pop
332 e0036155 Iustin Pop
  def ConnectNode(self, name, address=None, read_timeout=None):
333 a8083063 Iustin Pop
    """Add a node to the target list.
334 a8083063 Iustin Pop

335 bdf7d8c0 Iustin Pop
    @type name: str
336 bdf7d8c0 Iustin Pop
    @param name: the node name
337 bdf7d8c0 Iustin Pop
    @type address: str
338 eb202c13 Manuel Franceschini
    @param address: the node address, if known
339 eb202c13 Manuel Franceschini
    @type read_timeout: int
340 eb202c13 Manuel Franceschini
    @param read_timeout: overwrites default timeout for operation
341 bdf7d8c0 Iustin Pop

342 a8083063 Iustin Pop
    """
343 ecfe9491 Michael Hanselmann
    if address is None:
344 eb202c13 Manuel Franceschini
      # Always use IP address instead of node name
345 eb202c13 Manuel Franceschini
      address = self._address_lookup_fn([name])[0]
346 eb202c13 Manuel Franceschini
347 eb202c13 Manuel Franceschini
    assert(address is not None)
348 ecfe9491 Michael Hanselmann
349 92fd2250 Iustin Pop
    if read_timeout is None:
350 92fd2250 Iustin Pop
      read_timeout = _TIMEOUTS[self.procedure]
351 92fd2250 Iustin Pop
352 33231500 Michael Hanselmann
    self._request[name] = \
353 33231500 Michael Hanselmann
      http.client.HttpClientRequest(str(address), self.port,
354 33231500 Michael Hanselmann
                                    http.HTTP_PUT, str("/%s" % self.procedure),
355 33231500 Michael Hanselmann
                                    headers=_RPC_CLIENT_HEADERS,
356 33231500 Michael Hanselmann
                                    post_data=str(self.body),
357 e0036155 Iustin Pop
                                    read_timeout=read_timeout)
358 a8083063 Iustin Pop
359 33231500 Michael Hanselmann
  def GetResults(self, http_pool=None):
360 ecfe9491 Michael Hanselmann
    """Call nodes and return results.
361 ecfe9491 Michael Hanselmann

362 ecfe9491 Michael Hanselmann
    @rtype: list
363 5fcc718f Iustin Pop
    @return: List of RPC results
364 a8083063 Iustin Pop

365 a8083063 Iustin Pop
    """
366 33231500 Michael Hanselmann
    if not http_pool:
367 33231500 Michael Hanselmann
      http_pool = _thread_local.GetHttpClientPool()
368 4331f6cd Michael Hanselmann
369 33231500 Michael Hanselmann
    http_pool.ProcessRequests(self._request.values())
370 a8083063 Iustin Pop
371 ecfe9491 Michael Hanselmann
    results = {}
372 a8083063 Iustin Pop
373 33231500 Michael Hanselmann
    for name, req in self._request.iteritems():
374 ae88ef45 Michael Hanselmann
      if req.success and req.resp_status_code == http.HTTP_OK:
375 781de953 Iustin Pop
        results[name] = RpcResult(data=serializer.LoadJson(req.resp_body),
376 781de953 Iustin Pop
                                  node=name, call=self.procedure)
377 ecfe9491 Michael Hanselmann
        continue
378 a8083063 Iustin Pop
379 d57ae7f7 Michael Hanselmann
      # TODO: Better error reporting
380 ecfe9491 Michael Hanselmann
      if req.error:
381 ecfe9491 Michael Hanselmann
        msg = req.error
382 ecfe9491 Michael Hanselmann
      else:
383 ecfe9491 Michael Hanselmann
        msg = req.resp_body
384 ecfe9491 Michael Hanselmann
385 1b8acf70 Iustin Pop
      logging.error("RPC error in %s from node %s: %s",
386 1b8acf70 Iustin Pop
                    self.procedure, name, msg)
387 781de953 Iustin Pop
      results[name] = RpcResult(data=msg, failed=True, node=name,
388 781de953 Iustin Pop
                                call=self.procedure)
389 ecfe9491 Michael Hanselmann
390 ecfe9491 Michael Hanselmann
    return results
391 a8083063 Iustin Pop
392 a8083063 Iustin Pop
393 1651d116 Michael Hanselmann
def _EncodeImportExportIO(ieio, ieioargs):
394 1651d116 Michael Hanselmann
  """Encodes import/export I/O information.
395 1651d116 Michael Hanselmann

396 1651d116 Michael Hanselmann
  """
397 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_RAW_DISK:
398 1651d116 Michael Hanselmann
    assert len(ieioargs) == 1
399 1651d116 Michael Hanselmann
    return (ieioargs[0].ToDict(), )
400 1651d116 Michael Hanselmann
401 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_SCRIPT:
402 1651d116 Michael Hanselmann
    assert len(ieioargs) == 2
403 1651d116 Michael Hanselmann
    return (ieioargs[0].ToDict(), ieioargs[1])
404 1651d116 Michael Hanselmann
405 1651d116 Michael Hanselmann
  return ieioargs
406 1651d116 Michael Hanselmann
407 1651d116 Michael Hanselmann
408 72737a7f Iustin Pop
class RpcRunner(object):
409 72737a7f Iustin Pop
  """RPC runner class"""
410 a8083063 Iustin Pop
411 72737a7f Iustin Pop
  def __init__(self, cfg):
412 72737a7f Iustin Pop
    """Initialized the rpc runner.
413 a8083063 Iustin Pop

414 72737a7f Iustin Pop
    @type cfg:  C{config.ConfigWriter}
415 72737a7f Iustin Pop
    @param cfg: the configuration object that will be used to get data
416 72737a7f Iustin Pop
                about the cluster
417 a8083063 Iustin Pop

418 72737a7f Iustin Pop
    """
419 72737a7f Iustin Pop
    self._cfg = cfg
420 a744b676 Manuel Franceschini
    self.port = netutils.GetDaemonPort(constants.NODED)
421 a8083063 Iustin Pop
422 1bdcbbab Iustin Pop
  def _InstDict(self, instance, hvp=None, bep=None, osp=None):
423 26ba2bd8 Iustin Pop
    """Convert the given instance to a dict.
424 26ba2bd8 Iustin Pop

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

428 26ba2bd8 Iustin Pop
    @type instance: L{objects.Instance}
429 26ba2bd8 Iustin Pop
    @param instance: an Instance object
430 0eca8e0c Iustin Pop
    @type hvp: dict or None
431 5bbd3f7f Michael Hanselmann
    @param hvp: a dictionary with overridden hypervisor parameters
432 0eca8e0c Iustin Pop
    @type bep: dict or None
433 5bbd3f7f Michael Hanselmann
    @param bep: a dictionary with overridden backend parameters
434 1bdcbbab Iustin Pop
    @type osp: dict or None
435 1bdcbbab Iustin Pop
    @param osp: a dictionary with overriden os parameters
436 26ba2bd8 Iustin Pop
    @rtype: dict
437 26ba2bd8 Iustin Pop
    @return: the instance dict, with the hvparams filled with the
438 26ba2bd8 Iustin Pop
        cluster defaults
439 26ba2bd8 Iustin Pop

440 26ba2bd8 Iustin Pop
    """
441 26ba2bd8 Iustin Pop
    idict = instance.ToDict()
442 5b442704 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
443 5b442704 Iustin Pop
    idict["hvparams"] = cluster.FillHV(instance)
444 0eca8e0c Iustin Pop
    if hvp is not None:
445 0eca8e0c Iustin Pop
      idict["hvparams"].update(hvp)
446 5b442704 Iustin Pop
    idict["beparams"] = cluster.FillBE(instance)
447 0eca8e0c Iustin Pop
    if bep is not None:
448 0eca8e0c Iustin Pop
      idict["beparams"].update(bep)
449 1bdcbbab Iustin Pop
    idict["osparams"] = cluster.SimpleFillOS(instance.os, instance.osparams)
450 1bdcbbab Iustin Pop
    if osp is not None:
451 1bdcbbab Iustin Pop
      idict["osparams"].update(osp)
452 b848ce79 Guido Trotter
    for nic in idict["nics"]:
453 b848ce79 Guido Trotter
      nic['nicparams'] = objects.FillDict(
454 b848ce79 Guido Trotter
        cluster.nicparams[constants.PP_DEFAULT],
455 b848ce79 Guido Trotter
        nic['nicparams'])
456 26ba2bd8 Iustin Pop
    return idict
457 26ba2bd8 Iustin Pop
458 e0036155 Iustin Pop
  def _ConnectList(self, client, node_list, call, read_timeout=None):
459 25348212 Iustin Pop
    """Helper for computing node addresses.
460 25348212 Iustin Pop

461 6af6270a Iustin Pop
    @type client: L{ganeti.rpc.Client}
462 25348212 Iustin Pop
    @param client: a C{Client} instance
463 25348212 Iustin Pop
    @type node_list: list
464 25348212 Iustin Pop
    @param node_list: the node list we should connect
465 84b45587 Iustin Pop
    @type call: string
466 84b45587 Iustin Pop
    @param call: the name of the remote procedure call, for filling in
467 84b45587 Iustin Pop
        correctly any eventual offline nodes' results
468 e0036155 Iustin Pop
    @type read_timeout: int
469 e0036155 Iustin Pop
    @param read_timeout: overwrites the default read timeout for the
470 e0036155 Iustin Pop
        given operation
471 25348212 Iustin Pop

472 25348212 Iustin Pop
    """
473 25348212 Iustin Pop
    all_nodes = self._cfg.GetAllNodesInfo()
474 ed83f5cc Iustin Pop
    name_list = []
475 25348212 Iustin Pop
    addr_list = []
476 ed83f5cc Iustin Pop
    skip_dict = {}
477 25348212 Iustin Pop
    for node in node_list:
478 25348212 Iustin Pop
      if node in all_nodes:
479 ed83f5cc Iustin Pop
        if all_nodes[node].offline:
480 84b45587 Iustin Pop
          skip_dict[node] = RpcResult(node=node, offline=True, call=call)
481 ed83f5cc Iustin Pop
          continue
482 25348212 Iustin Pop
        val = all_nodes[node].primary_ip
483 25348212 Iustin Pop
      else:
484 25348212 Iustin Pop
        val = None
485 25348212 Iustin Pop
      addr_list.append(val)
486 ed83f5cc Iustin Pop
      name_list.append(node)
487 ed83f5cc Iustin Pop
    if name_list:
488 e0036155 Iustin Pop
      client.ConnectList(name_list, address_list=addr_list,
489 e0036155 Iustin Pop
                         read_timeout=read_timeout)
490 ed83f5cc Iustin Pop
    return skip_dict
491 25348212 Iustin Pop
492 e0036155 Iustin Pop
  def _ConnectNode(self, client, node, call, read_timeout=None):
493 25348212 Iustin Pop
    """Helper for computing one node's address.
494 25348212 Iustin Pop

495 6af6270a Iustin Pop
    @type client: L{ganeti.rpc.Client}
496 25348212 Iustin Pop
    @param client: a C{Client} instance
497 25348212 Iustin Pop
    @type node: str
498 25348212 Iustin Pop
    @param node: the node we should connect
499 84b45587 Iustin Pop
    @type call: string
500 84b45587 Iustin Pop
    @param call: the name of the remote procedure call, for filling in
501 84b45587 Iustin Pop
        correctly any eventual offline nodes' results
502 e0036155 Iustin Pop
    @type read_timeout: int
503 e0036155 Iustin Pop
    @param read_timeout: overwrites the default read timeout for the
504 e0036155 Iustin Pop
        given operation
505 25348212 Iustin Pop

506 25348212 Iustin Pop
    """
507 25348212 Iustin Pop
    node_info = self._cfg.GetNodeInfo(node)
508 25348212 Iustin Pop
    if node_info is not None:
509 ed83f5cc Iustin Pop
      if node_info.offline:
510 84b45587 Iustin Pop
        return RpcResult(node=node, offline=True, call=call)
511 25348212 Iustin Pop
      addr = node_info.primary_ip
512 25348212 Iustin Pop
    else:
513 25348212 Iustin Pop
      addr = None
514 e0036155 Iustin Pop
    client.ConnectNode(node, address=addr, read_timeout=read_timeout)
515 25348212 Iustin Pop
516 e0036155 Iustin Pop
  def _MultiNodeCall(self, node_list, procedure, args, read_timeout=None):
517 160e2921 Iustin Pop
    """Helper for making a multi-node call
518 160e2921 Iustin Pop

519 160e2921 Iustin Pop
    """
520 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
521 160e2921 Iustin Pop
    c = Client(procedure, body, self.port)
522 e0036155 Iustin Pop
    skip_dict = self._ConnectList(c, node_list, procedure,
523 e0036155 Iustin Pop
                                  read_timeout=read_timeout)
524 ed83f5cc Iustin Pop
    skip_dict.update(c.GetResults())
525 ed83f5cc Iustin Pop
    return skip_dict
526 9a525d83 Michael Hanselmann
527 9a525d83 Michael Hanselmann
  @classmethod
528 9a525d83 Michael Hanselmann
  def _StaticMultiNodeCall(cls, node_list, procedure, args,
529 e0036155 Iustin Pop
                           address_list=None, read_timeout=None):
530 160e2921 Iustin Pop
    """Helper for making a multi-node static call
531 160e2921 Iustin Pop

532 160e2921 Iustin Pop
    """
533 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
534 a744b676 Manuel Franceschini
    c = Client(procedure, body, netutils.GetDaemonPort(constants.NODED))
535 e0036155 Iustin Pop
    c.ConnectList(node_list, address_list=address_list,
536 e0036155 Iustin Pop
                  read_timeout=read_timeout)
537 9a525d83 Michael Hanselmann
    return c.GetResults()
538 9a525d83 Michael Hanselmann
539 e0036155 Iustin Pop
  def _SingleNodeCall(self, node, procedure, args, read_timeout=None):
540 160e2921 Iustin Pop
    """Helper for making a single-node call
541 9a525d83 Michael Hanselmann

542 9a525d83 Michael Hanselmann
    """
543 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
544 160e2921 Iustin Pop
    c = Client(procedure, body, self.port)
545 e0036155 Iustin Pop
    result = self._ConnectNode(c, node, procedure, read_timeout=read_timeout)
546 ed83f5cc Iustin Pop
    if result is None:
547 ed83f5cc Iustin Pop
      # we did connect, node is not offline
548 ed83f5cc Iustin Pop
      result = c.GetResults()[node]
549 ed83f5cc Iustin Pop
    return result
550 9a525d83 Michael Hanselmann
551 9a525d83 Michael Hanselmann
  @classmethod
552 e0036155 Iustin Pop
  def _StaticSingleNodeCall(cls, node, procedure, args, read_timeout=None):
553 160e2921 Iustin Pop
    """Helper for making a single-node static call
554 9a525d83 Michael Hanselmann

555 9a525d83 Michael Hanselmann
    """
556 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
557 a744b676 Manuel Franceschini
    c = Client(procedure, body, netutils.GetDaemonPort(constants.NODED))
558 e0036155 Iustin Pop
    c.ConnectNode(node, read_timeout=read_timeout)
559 ed83f5cc Iustin Pop
    return c.GetResults()[node]
560 9a525d83 Michael Hanselmann
561 12bce260 Michael Hanselmann
  @staticmethod
562 12bce260 Michael Hanselmann
  def _Compress(data):
563 12bce260 Michael Hanselmann
    """Compresses a string for transport over RPC.
564 12bce260 Michael Hanselmann

565 12bce260 Michael Hanselmann
    Small amounts of data are not compressed.
566 12bce260 Michael Hanselmann

567 12bce260 Michael Hanselmann
    @type data: str
568 12bce260 Michael Hanselmann
    @param data: Data
569 12bce260 Michael Hanselmann
    @rtype: tuple
570 12bce260 Michael Hanselmann
    @return: Encoded data to send
571 12bce260 Michael Hanselmann

572 12bce260 Michael Hanselmann
    """
573 12bce260 Michael Hanselmann
    # Small amounts of data are not compressed
574 12bce260 Michael Hanselmann
    if len(data) < 512:
575 12bce260 Michael Hanselmann
      return (constants.RPC_ENCODING_NONE, data)
576 12bce260 Michael Hanselmann
577 12bce260 Michael Hanselmann
    # Compress with zlib and encode in base64
578 12bce260 Michael Hanselmann
    return (constants.RPC_ENCODING_ZLIB_BASE64,
579 12bce260 Michael Hanselmann
            base64.b64encode(zlib.compress(data, 3)))
580 12bce260 Michael Hanselmann
581 781de953 Iustin Pop
  #
582 781de953 Iustin Pop
  # Begin RPC calls
583 781de953 Iustin Pop
  #
584 781de953 Iustin Pop
585 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
586 b2a6ccd4 Iustin Pop
  def call_lv_list(self, node_list, vg_name):
587 72737a7f Iustin Pop
    """Gets the logical volumes present in a given volume group.
588 a8083063 Iustin Pop

589 72737a7f Iustin Pop
    This is a multi-node call.
590 a8083063 Iustin Pop

591 72737a7f Iustin Pop
    """
592 b2a6ccd4 Iustin Pop
    return self._MultiNodeCall(node_list, "lv_list", [vg_name])
593 a8083063 Iustin Pop
594 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
595 72737a7f Iustin Pop
  def call_vg_list(self, node_list):
596 72737a7f Iustin Pop
    """Gets the volume group list.
597 a8083063 Iustin Pop

598 72737a7f Iustin Pop
    This is a multi-node call.
599 a8083063 Iustin Pop

600 72737a7f Iustin Pop
    """
601 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "vg_list", [])
602 a8083063 Iustin Pop
603 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
604 e337de97 Michael Hanselmann
  def call_storage_list(self, node_list, su_name, su_args, name, fields):
605 8979196a Michael Hanselmann
    """Get list of storage units.
606 e337de97 Michael Hanselmann

607 e337de97 Michael Hanselmann
    This is a multi-node call.
608 e337de97 Michael Hanselmann

609 e337de97 Michael Hanselmann
    """
610 e337de97 Michael Hanselmann
    return self._MultiNodeCall(node_list, "storage_list",
611 e337de97 Michael Hanselmann
                               [su_name, su_args, name, fields])
612 e337de97 Michael Hanselmann
613 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
614 8979196a Michael Hanselmann
  def call_storage_modify(self, node, su_name, su_args, name, changes):
615 8979196a Michael Hanselmann
    """Modify a storage unit.
616 8979196a Michael Hanselmann

617 8979196a Michael Hanselmann
    This is a single-node call.
618 8979196a Michael Hanselmann

619 8979196a Michael Hanselmann
    """
620 8979196a Michael Hanselmann
    return self._SingleNodeCall(node, "storage_modify",
621 8979196a Michael Hanselmann
                                [su_name, su_args, name, changes])
622 8979196a Michael Hanselmann
623 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
624 637b8d7e Michael Hanselmann
  def call_storage_execute(self, node, su_name, su_args, name, op):
625 637b8d7e Michael Hanselmann
    """Executes an operation on a storage unit.
626 637b8d7e Michael Hanselmann

627 637b8d7e Michael Hanselmann
    This is a single-node call.
628 637b8d7e Michael Hanselmann

629 637b8d7e Michael Hanselmann
    """
630 637b8d7e Michael Hanselmann
    return self._SingleNodeCall(node, "storage_execute",
631 637b8d7e Michael Hanselmann
                                [su_name, su_args, name, op])
632 637b8d7e Michael Hanselmann
633 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
634 72737a7f Iustin Pop
  def call_bridges_exist(self, node, bridges_list):
635 72737a7f Iustin Pop
    """Checks if a node has all the bridges given.
636 a8083063 Iustin Pop

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

641 72737a7f Iustin Pop
    This is a single-node call.
642 a8083063 Iustin Pop

643 72737a7f Iustin Pop
    """
644 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "bridges_exist", [bridges_list])
645 a8083063 Iustin Pop
646 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
647 0eca8e0c Iustin Pop
  def call_instance_start(self, node, instance, hvp, bep):
648 72737a7f Iustin Pop
    """Starts an instance.
649 a8083063 Iustin Pop

650 72737a7f Iustin Pop
    This is a single-node call.
651 a8083063 Iustin Pop

652 72737a7f Iustin Pop
    """
653 0eca8e0c Iustin Pop
    idict = self._InstDict(instance, hvp=hvp, bep=bep)
654 0eca8e0c Iustin Pop
    return self._SingleNodeCall(node, "instance_start", [idict])
655 a8083063 Iustin Pop
656 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
657 6263189c Guido Trotter
  def call_instance_shutdown(self, node, instance, timeout):
658 72737a7f Iustin Pop
    """Stops an instance.
659 a8083063 Iustin Pop

660 72737a7f Iustin Pop
    This is a single-node call.
661 2a10865c Iustin Pop

662 72737a7f Iustin Pop
    """
663 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_shutdown",
664 6263189c Guido Trotter
                                [self._InstDict(instance), timeout])
665 2a10865c Iustin Pop
666 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
667 6906a9d8 Guido Trotter
  def call_migration_info(self, node, instance):
668 6906a9d8 Guido Trotter
    """Gather the information necessary to prepare an instance migration.
669 6906a9d8 Guido Trotter

670 6906a9d8 Guido Trotter
    This is a single-node call.
671 6906a9d8 Guido Trotter

672 6906a9d8 Guido Trotter
    @type node: string
673 6906a9d8 Guido Trotter
    @param node: the node on which the instance is currently running
674 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
675 6906a9d8 Guido Trotter
    @param instance: the instance definition
676 6906a9d8 Guido Trotter

677 6906a9d8 Guido Trotter
    """
678 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "migration_info",
679 6906a9d8 Guido Trotter
                                [self._InstDict(instance)])
680 6906a9d8 Guido Trotter
681 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
682 6906a9d8 Guido Trotter
  def call_accept_instance(self, node, instance, info, target):
683 6906a9d8 Guido Trotter
    """Prepare a node to accept an instance.
684 6906a9d8 Guido Trotter

685 6906a9d8 Guido Trotter
    This is a single-node call.
686 6906a9d8 Guido Trotter

687 6906a9d8 Guido Trotter
    @type node: string
688 6906a9d8 Guido Trotter
    @param node: the target node for the migration
689 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
690 6906a9d8 Guido Trotter
    @param instance: the instance definition
691 6906a9d8 Guido Trotter
    @type info: opaque/hypervisor specific (string/data)
692 6906a9d8 Guido Trotter
    @param info: result for the call_migration_info call
693 6906a9d8 Guido Trotter
    @type target: string
694 6906a9d8 Guido Trotter
    @param target: target hostname (usually ip address) (on the node itself)
695 6906a9d8 Guido Trotter

696 6906a9d8 Guido Trotter
    """
697 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "accept_instance",
698 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, target])
699 6906a9d8 Guido Trotter
700 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
701 6906a9d8 Guido Trotter
  def call_finalize_migration(self, node, instance, info, success):
702 6906a9d8 Guido Trotter
    """Finalize any target-node migration specific operation.
703 6906a9d8 Guido Trotter

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

707 6906a9d8 Guido Trotter
    This is a single-node call.
708 6906a9d8 Guido Trotter

709 6906a9d8 Guido Trotter
    @type node: string
710 6906a9d8 Guido Trotter
    @param node: the target node for the migration
711 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
712 6906a9d8 Guido Trotter
    @param instance: the instance definition
713 6906a9d8 Guido Trotter
    @type info: opaque/hypervisor specific (string/data)
714 6906a9d8 Guido Trotter
    @param info: result for the call_migration_info call
715 6906a9d8 Guido Trotter
    @type success: boolean
716 6906a9d8 Guido Trotter
    @param success: whether the migration was a success or a failure
717 6906a9d8 Guido Trotter

718 6906a9d8 Guido Trotter
    """
719 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "finalize_migration",
720 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, success])
721 6906a9d8 Guido Trotter
722 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
723 72737a7f Iustin Pop
  def call_instance_migrate(self, node, instance, target, live):
724 72737a7f Iustin Pop
    """Migrate an instance.
725 2a10865c Iustin Pop

726 72737a7f Iustin Pop
    This is a single-node call.
727 2a10865c Iustin Pop

728 72737a7f Iustin Pop
    @type node: string
729 72737a7f Iustin Pop
    @param node: the node on which the instance is currently running
730 72737a7f Iustin Pop
    @type instance: C{objects.Instance}
731 72737a7f Iustin Pop
    @param instance: the instance definition
732 72737a7f Iustin Pop
    @type target: string
733 72737a7f Iustin Pop
    @param target: the target node name
734 72737a7f Iustin Pop
    @type live: boolean
735 72737a7f Iustin Pop
    @param live: whether the migration should be done live or not (the
736 72737a7f Iustin Pop
        interpretation of this parameter is left to the hypervisor)
737 007a2f3e Alexander Schreiber

738 72737a7f Iustin Pop
    """
739 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_migrate",
740 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), target, live])
741 007a2f3e Alexander Schreiber
742 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
743 17c3f802 Guido Trotter
  def call_instance_reboot(self, node, inst, reboot_type, shutdown_timeout):
744 72737a7f Iustin Pop
    """Reboots an instance.
745 007a2f3e Alexander Schreiber

746 72737a7f Iustin Pop
    This is a single-node call.
747 a8083063 Iustin Pop

748 72737a7f Iustin Pop
    """
749 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_reboot",
750 17c3f802 Guido Trotter
                                [self._InstDict(inst), reboot_type,
751 17c3f802 Guido Trotter
                                 shutdown_timeout])
752 a8083063 Iustin Pop
753 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_1DAY)
754 4a0e011f Iustin Pop
  def call_instance_os_add(self, node, inst, reinstall, debug):
755 72737a7f Iustin Pop
    """Installs an OS on the given instance.
756 a8083063 Iustin Pop

757 72737a7f Iustin Pop
    This is a single-node call.
758 decd5f45 Iustin Pop

759 72737a7f Iustin Pop
    """
760 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_os_add",
761 4a0e011f Iustin Pop
                                [self._InstDict(inst), reinstall, debug])
762 decd5f45 Iustin Pop
763 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
764 4a0e011f Iustin Pop
  def call_instance_run_rename(self, node, inst, old_name, debug):
765 72737a7f Iustin Pop
    """Run the OS rename script for an instance.
766 decd5f45 Iustin Pop

767 72737a7f Iustin Pop
    This is a single-node call.
768 a8083063 Iustin Pop

769 72737a7f Iustin Pop
    """
770 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_run_rename",
771 4a0e011f Iustin Pop
                                [self._InstDict(inst), old_name, debug])
772 a8083063 Iustin Pop
773 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
774 72737a7f Iustin Pop
  def call_instance_info(self, node, instance, hname):
775 72737a7f Iustin Pop
    """Returns information about a single instance.
776 a8083063 Iustin Pop

777 72737a7f Iustin Pop
    This is a single-node call.
778 a8083063 Iustin Pop

779 9a525d83 Michael Hanselmann
    @type node: list
780 9a525d83 Michael Hanselmann
    @param node: the list of nodes to query
781 72737a7f Iustin Pop
    @type instance: string
782 72737a7f Iustin Pop
    @param instance: the instance name
783 72737a7f Iustin Pop
    @type hname: string
784 72737a7f Iustin Pop
    @param hname: the hypervisor type of the instance
785 a8083063 Iustin Pop

786 72737a7f Iustin Pop
    """
787 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_info", [instance, hname])
788 e69d05fd Iustin Pop
789 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
790 56e7640c Iustin Pop
  def call_instance_migratable(self, node, instance):
791 56e7640c Iustin Pop
    """Checks whether the given instance can be migrated.
792 56e7640c Iustin Pop

793 56e7640c Iustin Pop
    This is a single-node call.
794 56e7640c Iustin Pop

795 56e7640c Iustin Pop
    @param node: the node to query
796 56e7640c Iustin Pop
    @type instance: L{objects.Instance}
797 56e7640c Iustin Pop
    @param instance: the instance to check
798 56e7640c Iustin Pop

799 56e7640c Iustin Pop

800 56e7640c Iustin Pop
    """
801 56e7640c Iustin Pop
    return self._SingleNodeCall(node, "instance_migratable",
802 56e7640c Iustin Pop
                                [self._InstDict(instance)])
803 56e7640c Iustin Pop
804 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
805 72737a7f Iustin Pop
  def call_all_instances_info(self, node_list, hypervisor_list):
806 72737a7f Iustin Pop
    """Returns information about all instances on the given nodes.
807 a8083063 Iustin Pop

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

810 72737a7f Iustin Pop
    @type node_list: list
811 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
812 72737a7f Iustin Pop
    @type hypervisor_list: list
813 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
814 a8083063 Iustin Pop

815 72737a7f Iustin Pop
    """
816 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "all_instances_info",
817 9a525d83 Michael Hanselmann
                               [hypervisor_list])
818 e69d05fd Iustin Pop
819 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
820 72737a7f Iustin Pop
  def call_instance_list(self, node_list, hypervisor_list):
821 72737a7f Iustin Pop
    """Returns the list of running instances on a given node.
822 a8083063 Iustin Pop

823 72737a7f Iustin Pop
    This is a multi-node call.
824 a8083063 Iustin Pop

825 72737a7f Iustin Pop
    @type node_list: list
826 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
827 72737a7f Iustin Pop
    @type hypervisor_list: list
828 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
829 16abfbc2 Alexander Schreiber

830 72737a7f Iustin Pop
    """
831 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "instance_list", [hypervisor_list])
832 16abfbc2 Alexander Schreiber
833 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
834 72737a7f Iustin Pop
  def call_node_tcp_ping(self, node, source, target, port, timeout,
835 72737a7f Iustin Pop
                         live_port_needed):
836 72737a7f Iustin Pop
    """Do a TcpPing on the remote node
837 a8083063 Iustin Pop

838 72737a7f Iustin Pop
    This is a single-node call.
839 caad16e2 Iustin Pop

840 72737a7f Iustin Pop
    """
841 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_tcp_ping",
842 9a525d83 Michael Hanselmann
                                [source, target, port, timeout,
843 72737a7f Iustin Pop
                                 live_port_needed])
844 a8083063 Iustin Pop
845 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
846 caad16e2 Iustin Pop
  def call_node_has_ip_address(self, node, address):
847 caad16e2 Iustin Pop
    """Checks if a node has the given IP address.
848 caad16e2 Iustin Pop

849 caad16e2 Iustin Pop
    This is a single-node call.
850 caad16e2 Iustin Pop

851 caad16e2 Iustin Pop
    """
852 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_has_ip_address", [address])
853 a8083063 Iustin Pop
854 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
855 72737a7f Iustin Pop
  def call_node_info(self, node_list, vg_name, hypervisor_type):
856 72737a7f Iustin Pop
    """Return node information.
857 e69d05fd Iustin Pop

858 72737a7f Iustin Pop
    This will return memory information and volume group size and free
859 72737a7f Iustin Pop
    space.
860 a8083063 Iustin Pop

861 72737a7f Iustin Pop
    This is a multi-node call.
862 a8083063 Iustin Pop

863 72737a7f Iustin Pop
    @type node_list: list
864 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
865 c41eea6e Iustin Pop
    @type vg_name: C{string}
866 c41eea6e Iustin Pop
    @param vg_name: the name of the volume group to ask for disk space
867 72737a7f Iustin Pop
        information
868 72737a7f Iustin Pop
    @type hypervisor_type: C{str}
869 72737a7f Iustin Pop
    @param hypervisor_type: the name of the hypervisor to ask for
870 72737a7f Iustin Pop
        memory information
871 a8083063 Iustin Pop

872 72737a7f Iustin Pop
    """
873 070e998b Iustin Pop
    return self._MultiNodeCall(node_list, "node_info",
874 070e998b Iustin Pop
                               [vg_name, hypervisor_type])
875 a8083063 Iustin Pop
876 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
877 72737a7f Iustin Pop
  def call_node_verify(self, node_list, checkdict, cluster_name):
878 72737a7f Iustin Pop
    """Request verification of given parameters.
879 a8083063 Iustin Pop

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

882 72737a7f Iustin Pop
    """
883 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_verify",
884 9a525d83 Michael Hanselmann
                               [checkdict, cluster_name])
885 a8083063 Iustin Pop
886 9a525d83 Michael Hanselmann
  @classmethod
887 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
888 3583908a Guido Trotter
  def call_node_start_master(cls, node, start_daemons, no_voting):
889 72737a7f Iustin Pop
    """Tells a node to activate itself as a master.
890 a8083063 Iustin Pop

891 72737a7f Iustin Pop
    This is a single-node call.
892 a8083063 Iustin Pop

893 72737a7f Iustin Pop
    """
894 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_start_master",
895 3583908a Guido Trotter
                                     [start_daemons, no_voting])
896 a8083063 Iustin Pop
897 9a525d83 Michael Hanselmann
  @classmethod
898 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
899 9a525d83 Michael Hanselmann
  def call_node_stop_master(cls, node, stop_daemons):
900 72737a7f Iustin Pop
    """Tells a node to demote itself from master status.
901 a8083063 Iustin Pop

902 72737a7f Iustin Pop
    This is a single-node call.
903 4e071d3b Iustin Pop

904 72737a7f Iustin Pop
    """
905 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_stop_master", [stop_daemons])
906 4e071d3b Iustin Pop
907 9a525d83 Michael Hanselmann
  @classmethod
908 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
909 9a525d83 Michael Hanselmann
  def call_master_info(cls, node_list):
910 72737a7f Iustin Pop
    """Query master info.
911 4e071d3b Iustin Pop

912 72737a7f Iustin Pop
    This is a multi-node call.
913 a8083063 Iustin Pop

914 72737a7f Iustin Pop
    """
915 72737a7f Iustin Pop
    # TODO: should this method query down nodes?
916 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "master_info", [])
917 a8083063 Iustin Pop
918 8f215968 Michael Hanselmann
  @classmethod
919 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
920 8f215968 Michael Hanselmann
  def call_version(cls, node_list):
921 72737a7f Iustin Pop
    """Query node version.
922 a8083063 Iustin Pop

923 72737a7f Iustin Pop
    This is a multi-node call.
924 a8083063 Iustin Pop

925 72737a7f Iustin Pop
    """
926 8f215968 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "version", [])
927 a8083063 Iustin Pop
928 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
929 72737a7f Iustin Pop
  def call_blockdev_create(self, node, bdev, size, owner, on_primary, info):
930 72737a7f Iustin Pop
    """Request creation of a given block device.
931 a8083063 Iustin Pop

932 72737a7f Iustin Pop
    This is a single-node call.
933 a8083063 Iustin Pop

934 72737a7f Iustin Pop
    """
935 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_create",
936 9a525d83 Michael Hanselmann
                                [bdev.ToDict(), size, owner, on_primary, info])
937 a8083063 Iustin Pop
938 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
939 72737a7f Iustin Pop
  def call_blockdev_remove(self, node, bdev):
940 72737a7f Iustin Pop
    """Request removal of a given block device.
941 a8083063 Iustin Pop

942 72737a7f Iustin Pop
    This is a single-node call.
943 f3e513ad Iustin Pop

944 72737a7f Iustin Pop
    """
945 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_remove", [bdev.ToDict()])
946 f3e513ad Iustin Pop
947 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
948 72737a7f Iustin Pop
  def call_blockdev_rename(self, node, devlist):
949 72737a7f Iustin Pop
    """Request rename of the given block devices.
950 f3e513ad Iustin Pop

951 72737a7f Iustin Pop
    This is a single-node call.
952 a8083063 Iustin Pop

953 72737a7f Iustin Pop
    """
954 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_rename",
955 9a525d83 Michael Hanselmann
                                [(d.ToDict(), uid) for d, uid in devlist])
956 a8083063 Iustin Pop
957 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
958 72737a7f Iustin Pop
  def call_blockdev_assemble(self, node, disk, owner, on_primary):
959 72737a7f Iustin Pop
    """Request assembling of a given block device.
960 a8083063 Iustin Pop

961 72737a7f Iustin Pop
    This is a single-node call.
962 a8083063 Iustin Pop

963 72737a7f Iustin Pop
    """
964 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_assemble",
965 9a525d83 Michael Hanselmann
                                [disk.ToDict(), owner, on_primary])
966 a8083063 Iustin Pop
967 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
968 72737a7f Iustin Pop
  def call_blockdev_shutdown(self, node, disk):
969 72737a7f Iustin Pop
    """Request shutdown of a given block device.
970 a8083063 Iustin Pop

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

973 72737a7f Iustin Pop
    """
974 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_shutdown", [disk.ToDict()])
975 a8083063 Iustin Pop
976 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
977 72737a7f Iustin Pop
  def call_blockdev_addchildren(self, node, bdev, ndevs):
978 72737a7f Iustin Pop
    """Request adding a list of children to a (mirroring) device.
979 a8083063 Iustin Pop

980 72737a7f Iustin Pop
    This is a single-node call.
981 a8083063 Iustin Pop

982 72737a7f Iustin Pop
    """
983 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_addchildren",
984 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
985 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
986 a8083063 Iustin Pop
987 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
988 72737a7f Iustin Pop
  def call_blockdev_removechildren(self, node, bdev, ndevs):
989 72737a7f Iustin Pop
    """Request removing a list of children from a (mirroring) device.
990 a8083063 Iustin Pop

991 72737a7f Iustin Pop
    This is a single-node call.
992 a8083063 Iustin Pop

993 72737a7f Iustin Pop
    """
994 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_removechildren",
995 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
996 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
997 a8083063 Iustin Pop
998 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
999 72737a7f Iustin Pop
  def call_blockdev_getmirrorstatus(self, node, disks):
1000 72737a7f Iustin Pop
    """Request status of a (mirroring) device.
1001 a8083063 Iustin Pop

1002 72737a7f Iustin Pop
    This is a single-node call.
1003 a8083063 Iustin Pop

1004 72737a7f Iustin Pop
    """
1005 36145b12 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_getmirrorstatus",
1006 36145b12 Michael Hanselmann
                                  [dsk.ToDict() for dsk in disks])
1007 edb4b374 Michael Hanselmann
    if not result.fail_msg:
1008 36145b12 Michael Hanselmann
      result.payload = [objects.BlockDevStatus.FromDict(i)
1009 36145b12 Michael Hanselmann
                        for i in result.payload]
1010 36145b12 Michael Hanselmann
    return result
1011 a8083063 Iustin Pop
1012 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1013 72737a7f Iustin Pop
  def call_blockdev_find(self, node, disk):
1014 72737a7f Iustin Pop
    """Request identification of a given block device.
1015 72737a7f Iustin Pop

1016 72737a7f Iustin Pop
    This is a single-node call.
1017 a8083063 Iustin Pop

1018 72737a7f Iustin Pop
    """
1019 96acbc09 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_find", [disk.ToDict()])
1020 edb4b374 Michael Hanselmann
    if not result.fail_msg and result.payload is not None:
1021 96acbc09 Michael Hanselmann
      result.payload = objects.BlockDevStatus.FromDict(result.payload)
1022 96acbc09 Michael Hanselmann
    return result
1023 d61cbe76 Iustin Pop
1024 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1025 b2e7666a Iustin Pop
  def call_blockdev_close(self, node, instance_name, disks):
1026 72737a7f Iustin Pop
    """Closes the given block devices.
1027 d61cbe76 Iustin Pop

1028 72737a7f Iustin Pop
    This is a single-node call.
1029 d61cbe76 Iustin Pop

1030 72737a7f Iustin Pop
    """
1031 b2e7666a Iustin Pop
    params = [instance_name, [cf.ToDict() for cf in disks]]
1032 b2e7666a Iustin Pop
    return self._SingleNodeCall(node, "blockdev_close", params)
1033 a8083063 Iustin Pop
1034 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1035 968a7623 Iustin Pop
  def call_blockdev_getsizes(self, node, disks):
1036 968a7623 Iustin Pop
    """Returns the size of the given disks.
1037 968a7623 Iustin Pop

1038 968a7623 Iustin Pop
    This is a single-node call.
1039 968a7623 Iustin Pop

1040 968a7623 Iustin Pop
    """
1041 968a7623 Iustin Pop
    params = [[cf.ToDict() for cf in disks]]
1042 968a7623 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_getsize", params)
1043 968a7623 Iustin Pop
1044 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1045 6b93ec9d Iustin Pop
  def call_drbd_disconnect_net(self, node_list, nodes_ip, disks):
1046 6b93ec9d Iustin Pop
    """Disconnects the network of the given drbd devices.
1047 6b93ec9d Iustin Pop

1048 6b93ec9d Iustin Pop
    This is a multi-node call.
1049 6b93ec9d Iustin Pop

1050 6b93ec9d Iustin Pop
    """
1051 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_disconnect_net",
1052 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1053 6b93ec9d Iustin Pop
1054 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1055 6b93ec9d Iustin Pop
  def call_drbd_attach_net(self, node_list, nodes_ip,
1056 6b93ec9d Iustin Pop
                           disks, instance_name, multimaster):
1057 6b93ec9d Iustin Pop
    """Disconnects the given drbd devices.
1058 6b93ec9d Iustin Pop

1059 6b93ec9d Iustin Pop
    This is a multi-node call.
1060 6b93ec9d Iustin Pop

1061 6b93ec9d Iustin Pop
    """
1062 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_attach_net",
1063 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks],
1064 6b93ec9d Iustin Pop
                                instance_name, multimaster])
1065 6b93ec9d Iustin Pop
1066 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
1067 6b93ec9d Iustin Pop
  def call_drbd_wait_sync(self, node_list, nodes_ip, disks):
1068 6b93ec9d Iustin Pop
    """Waits for the synchronization of drbd devices is complete.
1069 6b93ec9d Iustin Pop

1070 6b93ec9d Iustin Pop
    This is a multi-node call.
1071 6b93ec9d Iustin Pop

1072 6b93ec9d Iustin Pop
    """
1073 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_wait_sync",
1074 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1075 6b93ec9d Iustin Pop
1076 c46b9782 Luca Bigliardi
  @_RpcTimeout(_TMO_URGENT)
1077 c46b9782 Luca Bigliardi
  def call_drbd_helper(self, node_list):
1078 c46b9782 Luca Bigliardi
    """Gets drbd helper.
1079 c46b9782 Luca Bigliardi

1080 c46b9782 Luca Bigliardi
    This is a multi-node call.
1081 c46b9782 Luca Bigliardi

1082 c46b9782 Luca Bigliardi
    """
1083 c46b9782 Luca Bigliardi
    return self._MultiNodeCall(node_list, "drbd_helper", [])
1084 c46b9782 Luca Bigliardi
1085 9a525d83 Michael Hanselmann
  @classmethod
1086 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1087 9a525d83 Michael Hanselmann
  def call_upload_file(cls, node_list, file_name, address_list=None):
1088 72737a7f Iustin Pop
    """Upload a file.
1089 72737a7f Iustin Pop

1090 72737a7f Iustin Pop
    The node will refuse the operation in case the file is not on the
1091 72737a7f Iustin Pop
    approved file list.
1092 72737a7f Iustin Pop

1093 72737a7f Iustin Pop
    This is a multi-node call.
1094 a8083063 Iustin Pop

1095 6b294c53 Iustin Pop
    @type node_list: list
1096 6b294c53 Iustin Pop
    @param node_list: the list of node names to upload to
1097 6b294c53 Iustin Pop
    @type file_name: str
1098 6b294c53 Iustin Pop
    @param file_name: the filename to upload
1099 6b294c53 Iustin Pop
    @type address_list: list or None
1100 6b294c53 Iustin Pop
    @keyword address_list: an optional list of node addresses, in order
1101 6b294c53 Iustin Pop
        to optimize the RPC speed
1102 6b294c53 Iustin Pop

1103 72737a7f Iustin Pop
    """
1104 12bce260 Michael Hanselmann
    file_contents = utils.ReadFile(file_name)
1105 12bce260 Michael Hanselmann
    data = cls._Compress(file_contents)
1106 72737a7f Iustin Pop
    st = os.stat(file_name)
1107 72737a7f Iustin Pop
    params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
1108 72737a7f Iustin Pop
              st.st_atime, st.st_mtime]
1109 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "upload_file", params,
1110 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1111 72737a7f Iustin Pop
1112 6ddc95ec Michael Hanselmann
  @classmethod
1113 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1114 03d1dba2 Michael Hanselmann
  def call_write_ssconf_files(cls, node_list, values):
1115 6ddc95ec Michael Hanselmann
    """Write ssconf files.
1116 6ddc95ec Michael Hanselmann

1117 6ddc95ec Michael Hanselmann
    This is a multi-node call.
1118 6ddc95ec Michael Hanselmann

1119 6ddc95ec Michael Hanselmann
    """
1120 03d1dba2 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "write_ssconf_files", [values])
1121 6ddc95ec Michael Hanselmann
1122 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1123 72737a7f Iustin Pop
  def call_os_diagnose(self, node_list):
1124 72737a7f Iustin Pop
    """Request a diagnose of OS definitions.
1125 72737a7f Iustin Pop

1126 72737a7f Iustin Pop
    This is a multi-node call.
1127 a8083063 Iustin Pop

1128 72737a7f Iustin Pop
    """
1129 83d92ad8 Iustin Pop
    return self._MultiNodeCall(node_list, "os_diagnose", [])
1130 a8083063 Iustin Pop
1131 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1132 72737a7f Iustin Pop
  def call_os_get(self, node, name):
1133 72737a7f Iustin Pop
    """Returns an OS definition.
1134 a8083063 Iustin Pop

1135 72737a7f Iustin Pop
    This is a single-node call.
1136 a8083063 Iustin Pop

1137 72737a7f Iustin Pop
    """
1138 9a525d83 Michael Hanselmann
    result = self._SingleNodeCall(node, "os_get", [name])
1139 84e3f66f Guido Trotter
    if not result.fail_msg and isinstance(result.payload, dict):
1140 84e3f66f Guido Trotter
      result.payload = objects.OS.FromDict(result.payload)
1141 781de953 Iustin Pop
    return result
1142 a8083063 Iustin Pop
1143 acd9ff9e Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1144 acd9ff9e Iustin Pop
  def call_os_validate(self, required, nodes, name, checks, params):
1145 acd9ff9e Iustin Pop
    """Run a validation routine for a given OS.
1146 acd9ff9e Iustin Pop

1147 acd9ff9e Iustin Pop
    This is a multi-node call.
1148 acd9ff9e Iustin Pop

1149 acd9ff9e Iustin Pop
    """
1150 acd9ff9e Iustin Pop
    return self._MultiNodeCall(nodes, "os_validate",
1151 acd9ff9e Iustin Pop
                               [required, name, checks, params])
1152 acd9ff9e Iustin Pop
1153 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1154 72737a7f Iustin Pop
  def call_hooks_runner(self, node_list, hpath, phase, env):
1155 72737a7f Iustin Pop
    """Call the hooks runner.
1156 a8083063 Iustin Pop

1157 72737a7f Iustin Pop
    Args:
1158 72737a7f Iustin Pop
      - op: the OpCode instance
1159 72737a7f Iustin Pop
      - env: a dictionary with the environment
1160 a8083063 Iustin Pop

1161 72737a7f Iustin Pop
    This is a multi-node call.
1162 a8083063 Iustin Pop

1163 72737a7f Iustin Pop
    """
1164 72737a7f Iustin Pop
    params = [hpath, phase, env]
1165 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hooks_runner", params)
1166 a8083063 Iustin Pop
1167 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1168 72737a7f Iustin Pop
  def call_iallocator_runner(self, node, name, idata):
1169 72737a7f Iustin Pop
    """Call an iallocator on a remote node
1170 8d528b7c Iustin Pop

1171 72737a7f Iustin Pop
    Args:
1172 72737a7f Iustin Pop
      - name: the iallocator name
1173 72737a7f Iustin Pop
      - input: the json-encoded input string
1174 8d528b7c Iustin Pop

1175 72737a7f Iustin Pop
    This is a single-node call.
1176 8d528b7c Iustin Pop

1177 72737a7f Iustin Pop
    """
1178 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "iallocator_runner", [name, idata])
1179 8d528b7c Iustin Pop
1180 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1181 72737a7f Iustin Pop
  def call_blockdev_grow(self, node, cf_bdev, amount):
1182 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1183 4c8ba8b3 Iustin Pop

1184 72737a7f Iustin Pop
    This is a single-node call.
1185 4c8ba8b3 Iustin Pop

1186 72737a7f Iustin Pop
    """
1187 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_grow",
1188 9a525d83 Michael Hanselmann
                                [cf_bdev.ToDict(), amount])
1189 4c8ba8b3 Iustin Pop
1190 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_1DAY)
1191 858f3d18 Iustin Pop
  def call_blockdev_export(self, node, cf_bdev,
1192 858f3d18 Iustin Pop
                           dest_node, dest_path, cluster_name):
1193 858f3d18 Iustin Pop
    """Export a given disk to another node.
1194 858f3d18 Iustin Pop

1195 858f3d18 Iustin Pop
    This is a single-node call.
1196 858f3d18 Iustin Pop

1197 858f3d18 Iustin Pop
    """
1198 858f3d18 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_export",
1199 858f3d18 Iustin Pop
                                [cf_bdev.ToDict(), dest_node, dest_path,
1200 858f3d18 Iustin Pop
                                 cluster_name])
1201 858f3d18 Iustin Pop
1202 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1203 72737a7f Iustin Pop
  def call_blockdev_snapshot(self, node, cf_bdev):
1204 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1205 a8083063 Iustin Pop

1206 72737a7f Iustin Pop
    This is a single-node call.
1207 a8083063 Iustin Pop

1208 72737a7f Iustin Pop
    """
1209 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_snapshot", [cf_bdev.ToDict()])
1210 a8083063 Iustin Pop
1211 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1212 72737a7f Iustin Pop
  def call_finalize_export(self, node, instance, snap_disks):
1213 72737a7f Iustin Pop
    """Request the completion of an export operation.
1214 a8083063 Iustin Pop

1215 72737a7f Iustin Pop
    This writes the export config file, etc.
1216 a8083063 Iustin Pop

1217 72737a7f Iustin Pop
    This is a single-node call.
1218 a8083063 Iustin Pop

1219 72737a7f Iustin Pop
    """
1220 72737a7f Iustin Pop
    flat_disks = []
1221 72737a7f Iustin Pop
    for disk in snap_disks:
1222 a97da6b7 Iustin Pop
      if isinstance(disk, bool):
1223 a97da6b7 Iustin Pop
        flat_disks.append(disk)
1224 a97da6b7 Iustin Pop
      else:
1225 a97da6b7 Iustin Pop
        flat_disks.append(disk.ToDict())
1226 9a525d83 Michael Hanselmann
1227 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "finalize_export",
1228 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), flat_disks])
1229 a8083063 Iustin Pop
1230 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1231 72737a7f Iustin Pop
  def call_export_info(self, node, path):
1232 72737a7f Iustin Pop
    """Queries the export information in a given path.
1233 a8083063 Iustin Pop

1234 72737a7f Iustin Pop
    This is a single-node call.
1235 a8083063 Iustin Pop

1236 72737a7f Iustin Pop
    """
1237 3eccac06 Iustin Pop
    return self._SingleNodeCall(node, "export_info", [path])
1238 a8083063 Iustin Pop
1239 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1240 72737a7f Iustin Pop
  def call_export_list(self, node_list):
1241 72737a7f Iustin Pop
    """Gets the stored exports list.
1242 a8083063 Iustin Pop

1243 72737a7f Iustin Pop
    This is a multi-node call.
1244 a8083063 Iustin Pop

1245 72737a7f Iustin Pop
    """
1246 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "export_list", [])
1247 a8083063 Iustin Pop
1248 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1249 72737a7f Iustin Pop
  def call_export_remove(self, node, export):
1250 72737a7f Iustin Pop
    """Requests removal of a given export.
1251 a8083063 Iustin Pop

1252 72737a7f Iustin Pop
    This is a single-node call.
1253 a8083063 Iustin Pop

1254 72737a7f Iustin Pop
    """
1255 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "export_remove", [export])
1256 a8083063 Iustin Pop
1257 9a525d83 Michael Hanselmann
  @classmethod
1258 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1259 b989b9d9 Ken Wehr
  def call_node_leave_cluster(cls, node, modify_ssh_setup):
1260 72737a7f Iustin Pop
    """Requests a node to clean the cluster information it has.
1261 a8083063 Iustin Pop

1262 72737a7f Iustin Pop
    This will remove the configuration information from the ganeti data
1263 72737a7f Iustin Pop
    dir.
1264 a8083063 Iustin Pop

1265 72737a7f Iustin Pop
    This is a single-node call.
1266 a8083063 Iustin Pop

1267 72737a7f Iustin Pop
    """
1268 b989b9d9 Ken Wehr
    return cls._StaticSingleNodeCall(node, "node_leave_cluster",
1269 b989b9d9 Ken Wehr
                                     [modify_ssh_setup])
1270 dcb93971 Michael Hanselmann
1271 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1272 72737a7f Iustin Pop
  def call_node_volumes(self, node_list):
1273 72737a7f Iustin Pop
    """Gets all volumes on node(s).
1274 dcb93971 Michael Hanselmann

1275 72737a7f Iustin Pop
    This is a multi-node call.
1276 dcb93971 Michael Hanselmann

1277 72737a7f Iustin Pop
    """
1278 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_volumes", [])
1279 06009e27 Iustin Pop
1280 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1281 56aa9fd5 Iustin Pop
  def call_node_demote_from_mc(self, node):
1282 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
1283 56aa9fd5 Iustin Pop

1284 56aa9fd5 Iustin Pop
    This is a single-node call.
1285 56aa9fd5 Iustin Pop

1286 56aa9fd5 Iustin Pop
    """
1287 56aa9fd5 Iustin Pop
    return self._SingleNodeCall(node, "node_demote_from_mc", [])
1288 56aa9fd5 Iustin Pop
1289 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1290 f5118ade Iustin Pop
  def call_node_powercycle(self, node, hypervisor):
1291 f5118ade Iustin Pop
    """Tries to powercycle a node.
1292 f5118ade Iustin Pop

1293 f5118ade Iustin Pop
    This is a single-node call.
1294 f5118ade Iustin Pop

1295 f5118ade Iustin Pop
    """
1296 f5118ade Iustin Pop
    return self._SingleNodeCall(node, "node_powercycle", [hypervisor])
1297 f5118ade Iustin Pop
1298 92fd2250 Iustin Pop
  @_RpcTimeout(None)
1299 72737a7f Iustin Pop
  def call_test_delay(self, node_list, duration):
1300 72737a7f Iustin Pop
    """Sleep for a fixed time on given node(s).
1301 06009e27 Iustin Pop

1302 72737a7f Iustin Pop
    This is a multi-node call.
1303 06009e27 Iustin Pop

1304 72737a7f Iustin Pop
    """
1305 92fd2250 Iustin Pop
    return self._MultiNodeCall(node_list, "test_delay", [duration],
1306 92fd2250 Iustin Pop
                               read_timeout=int(duration + 5))
1307 5e04ed8b Manuel Franceschini
1308 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1309 72737a7f Iustin Pop
  def call_file_storage_dir_create(self, node, file_storage_dir):
1310 72737a7f Iustin Pop
    """Create the given file storage directory.
1311 5e04ed8b Manuel Franceschini

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

1314 72737a7f Iustin Pop
    """
1315 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_create",
1316 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1317 5e04ed8b Manuel Franceschini
1318 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1319 72737a7f Iustin Pop
  def call_file_storage_dir_remove(self, node, file_storage_dir):
1320 72737a7f Iustin Pop
    """Remove the given file storage directory.
1321 5e04ed8b Manuel Franceschini

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

1324 72737a7f Iustin Pop
    """
1325 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_remove",
1326 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1327 5e04ed8b Manuel Franceschini
1328 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1329 72737a7f Iustin Pop
  def call_file_storage_dir_rename(self, node, old_file_storage_dir,
1330 72737a7f Iustin Pop
                                   new_file_storage_dir):
1331 72737a7f Iustin Pop
    """Rename file storage directory.
1332 5e04ed8b Manuel Franceschini

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

1335 72737a7f Iustin Pop
    """
1336 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_rename",
1337 9a525d83 Michael Hanselmann
                                [old_file_storage_dir, new_file_storage_dir])
1338 ca52cdeb Michael Hanselmann
1339 9a525d83 Michael Hanselmann
  @classmethod
1340 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1341 9a525d83 Michael Hanselmann
  def call_jobqueue_update(cls, node_list, address_list, file_name, content):
1342 72737a7f Iustin Pop
    """Update job queue.
1343 ca52cdeb Michael Hanselmann

1344 72737a7f Iustin Pop
    This is a multi-node call.
1345 ca52cdeb Michael Hanselmann

1346 72737a7f Iustin Pop
    """
1347 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_update",
1348 12bce260 Michael Hanselmann
                                    [file_name, cls._Compress(content)],
1349 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1350 ca52cdeb Michael Hanselmann
1351 9a525d83 Michael Hanselmann
  @classmethod
1352 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1353 9a525d83 Michael Hanselmann
  def call_jobqueue_purge(cls, node):
1354 72737a7f Iustin Pop
    """Purge job queue.
1355 ca52cdeb Michael Hanselmann

1356 72737a7f Iustin Pop
    This is a single-node call.
1357 ca52cdeb Michael Hanselmann

1358 72737a7f Iustin Pop
    """
1359 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "jobqueue_purge", [])
1360 af5ebcb1 Michael Hanselmann
1361 9a525d83 Michael Hanselmann
  @classmethod
1362 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1363 dd875d32 Michael Hanselmann
  def call_jobqueue_rename(cls, node_list, address_list, rename):
1364 72737a7f Iustin Pop
    """Rename a job queue file.
1365 af5ebcb1 Michael Hanselmann

1366 72737a7f Iustin Pop
    This is a multi-node call.
1367 af5ebcb1 Michael Hanselmann

1368 72737a7f Iustin Pop
    """
1369 dd875d32 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_rename", rename,
1370 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1371 6217e295 Iustin Pop
1372 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1373 6217e295 Iustin Pop
  def call_hypervisor_validate_params(self, node_list, hvname, hvparams):
1374 6217e295 Iustin Pop
    """Validate the hypervisor params.
1375 6217e295 Iustin Pop

1376 6217e295 Iustin Pop
    This is a multi-node call.
1377 6217e295 Iustin Pop

1378 6217e295 Iustin Pop
    @type node_list: list
1379 6217e295 Iustin Pop
    @param node_list: the list of nodes to query
1380 6217e295 Iustin Pop
    @type hvname: string
1381 6217e295 Iustin Pop
    @param hvname: the hypervisor name
1382 6217e295 Iustin Pop
    @type hvparams: dict
1383 6217e295 Iustin Pop
    @param hvparams: the hypervisor parameters to be validated
1384 6217e295 Iustin Pop

1385 6217e295 Iustin Pop
    """
1386 6217e295 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
1387 abe609b2 Guido Trotter
    hv_full = objects.FillDict(cluster.hvparams.get(hvname, {}), hvparams)
1388 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hypervisor_validate_params",
1389 9a525d83 Michael Hanselmann
                               [hvname, hv_full])
1390 f942a838 Michael Hanselmann
1391 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1392 37549316 Michael Hanselmann
  def call_x509_cert_create(self, node, validity):
1393 f942a838 Michael Hanselmann
    """Creates a new X509 certificate for SSL/TLS.
1394 f942a838 Michael Hanselmann

1395 f942a838 Michael Hanselmann
    This is a single-node call.
1396 f942a838 Michael Hanselmann

1397 f942a838 Michael Hanselmann
    @type validity: int
1398 f942a838 Michael Hanselmann
    @param validity: Validity in seconds
1399 f942a838 Michael Hanselmann

1400 f942a838 Michael Hanselmann
    """
1401 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_create", [validity])
1402 f942a838 Michael Hanselmann
1403 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1404 37549316 Michael Hanselmann
  def call_x509_cert_remove(self, node, name):
1405 f942a838 Michael Hanselmann
    """Removes a X509 certificate.
1406 f942a838 Michael Hanselmann

1407 f942a838 Michael Hanselmann
    This is a single-node call.
1408 f942a838 Michael Hanselmann

1409 f942a838 Michael Hanselmann
    @type name: string
1410 f942a838 Michael Hanselmann
    @param name: Certificate name
1411 f942a838 Michael Hanselmann

1412 f942a838 Michael Hanselmann
    """
1413 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_remove", [name])
1414 1651d116 Michael Hanselmann
1415 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1416 eb630f50 Michael Hanselmann
  def call_import_start(self, node, opts, instance, dest, dest_args):
1417 1651d116 Michael Hanselmann
    """Starts a listener for an import.
1418 1651d116 Michael Hanselmann

1419 1651d116 Michael Hanselmann
    This is a single-node call.
1420 1651d116 Michael Hanselmann

1421 1651d116 Michael Hanselmann
    @type node: string
1422 1651d116 Michael Hanselmann
    @param node: Node name
1423 1651d116 Michael Hanselmann
    @type instance: C{objects.Instance}
1424 1651d116 Michael Hanselmann
    @param instance: Instance object
1425 1651d116 Michael Hanselmann

1426 1651d116 Michael Hanselmann
    """
1427 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "import_start",
1428 eb630f50 Michael Hanselmann
                                [opts.ToDict(),
1429 1651d116 Michael Hanselmann
                                 self._InstDict(instance), dest,
1430 1651d116 Michael Hanselmann
                                 _EncodeImportExportIO(dest, dest_args)])
1431 1651d116 Michael Hanselmann
1432 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1433 eb630f50 Michael Hanselmann
  def call_export_start(self, node, opts, host, port,
1434 1651d116 Michael Hanselmann
                        instance, source, source_args):
1435 1651d116 Michael Hanselmann
    """Starts an export daemon.
1436 1651d116 Michael Hanselmann

1437 1651d116 Michael Hanselmann
    This is a single-node call.
1438 1651d116 Michael Hanselmann

1439 1651d116 Michael Hanselmann
    @type node: string
1440 1651d116 Michael Hanselmann
    @param node: Node name
1441 1651d116 Michael Hanselmann
    @type instance: C{objects.Instance}
1442 1651d116 Michael Hanselmann
    @param instance: Instance object
1443 1651d116 Michael Hanselmann

1444 1651d116 Michael Hanselmann
    """
1445 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "export_start",
1446 eb630f50 Michael Hanselmann
                                [opts.ToDict(), host, port,
1447 1651d116 Michael Hanselmann
                                 self._InstDict(instance), source,
1448 1651d116 Michael Hanselmann
                                 _EncodeImportExportIO(source, source_args)])
1449 1651d116 Michael Hanselmann
1450 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1451 ef40fbfb Michael Hanselmann
  def call_impexp_status(self, node, names):
1452 1651d116 Michael Hanselmann
    """Gets the status of 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 names: List of strings
1459 1651d116 Michael Hanselmann
    @param names: Import/export names
1460 1651d116 Michael Hanselmann
    @rtype: List of L{objects.ImportExportStatus} instances
1461 1651d116 Michael Hanselmann
    @return: Returns a list of the state of each named import/export or None if
1462 1651d116 Michael Hanselmann
             a status couldn't be retrieved
1463 1651d116 Michael Hanselmann

1464 1651d116 Michael Hanselmann
    """
1465 ef40fbfb Michael Hanselmann
    result = self._SingleNodeCall(node, "impexp_status", [names])
1466 1651d116 Michael Hanselmann
1467 1651d116 Michael Hanselmann
    if not result.fail_msg:
1468 1651d116 Michael Hanselmann
      decoded = []
1469 1651d116 Michael Hanselmann
1470 1651d116 Michael Hanselmann
      for i in result.payload:
1471 1651d116 Michael Hanselmann
        if i is None:
1472 1651d116 Michael Hanselmann
          decoded.append(None)
1473 1651d116 Michael Hanselmann
          continue
1474 1651d116 Michael Hanselmann
        decoded.append(objects.ImportExportStatus.FromDict(i))
1475 1651d116 Michael Hanselmann
1476 1651d116 Michael Hanselmann
      result.payload = decoded
1477 1651d116 Michael Hanselmann
1478 1651d116 Michael Hanselmann
    return result
1479 1651d116 Michael Hanselmann
1480 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1481 f81c4737 Michael Hanselmann
  def call_impexp_abort(self, node, name):
1482 f81c4737 Michael Hanselmann
    """Aborts an import or export.
1483 f81c4737 Michael Hanselmann

1484 f81c4737 Michael Hanselmann
    This is a single-node call.
1485 f81c4737 Michael Hanselmann

1486 f81c4737 Michael Hanselmann
    @type node: string
1487 f81c4737 Michael Hanselmann
    @param node: Node name
1488 f81c4737 Michael Hanselmann
    @type name: string
1489 f81c4737 Michael Hanselmann
    @param name: Import/export name
1490 f81c4737 Michael Hanselmann

1491 f81c4737 Michael Hanselmann
    """
1492 f81c4737 Michael Hanselmann
    return self._SingleNodeCall(node, "impexp_abort", [name])
1493 f81c4737 Michael Hanselmann
1494 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1495 ef40fbfb Michael Hanselmann
  def call_impexp_cleanup(self, node, name):
1496 1651d116 Michael Hanselmann
    """Cleans up after an import or export.
1497 1651d116 Michael Hanselmann

1498 1651d116 Michael Hanselmann
    This is a single-node call.
1499 1651d116 Michael Hanselmann

1500 1651d116 Michael Hanselmann
    @type node: string
1501 1651d116 Michael Hanselmann
    @param node: Node name
1502 1651d116 Michael Hanselmann
    @type name: string
1503 1651d116 Michael Hanselmann
    @param name: Import/export name
1504 1651d116 Michael Hanselmann

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