Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ 26d3fd2f

History | View | Annotate | Download (44.5 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 17f7fd27 Manuel Franceschini
  @type nslookup_fn: callable
270 17f7fd27 Manuel Franceschini
  @param nslookup_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 19ddc57a Renรฉ Nussbaumer
  def call_etc_hosts_modify(self, node, mode, name, ip):
878 19ddc57a Renรฉ Nussbaumer
    """Modify hosts file with name
879 19ddc57a Renรฉ Nussbaumer

880 19ddc57a Renรฉ Nussbaumer
    @type node: string
881 19ddc57a Renรฉ Nussbaumer
    @param node: The node to call
882 19ddc57a Renรฉ Nussbaumer
    @type mode: string
883 19ddc57a Renรฉ Nussbaumer
    @param mode: The mode to operate. Currently "add" or "remove"
884 19ddc57a Renรฉ Nussbaumer
    @type name: string
885 19ddc57a Renรฉ Nussbaumer
    @param name: The host name to be modified
886 19ddc57a Renรฉ Nussbaumer
    @type ip: string
887 19ddc57a Renรฉ Nussbaumer
    @param ip: The ip of the entry (just valid if mode is "add")
888 19ddc57a Renรฉ Nussbaumer

889 19ddc57a Renรฉ Nussbaumer
    """
890 19ddc57a Renรฉ Nussbaumer
    return self._SingleNodeCall(node, "etc_hosts_modify", [mode, name, ip])
891 19ddc57a Renรฉ Nussbaumer
892 19ddc57a Renรฉ Nussbaumer
  @_RpcTimeout(_TMO_NORMAL)
893 72737a7f Iustin Pop
  def call_node_verify(self, node_list, checkdict, cluster_name):
894 72737a7f Iustin Pop
    """Request verification of given parameters.
895 a8083063 Iustin Pop

896 72737a7f Iustin Pop
    This is a multi-node call.
897 a8083063 Iustin Pop

898 72737a7f Iustin Pop
    """
899 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_verify",
900 9a525d83 Michael Hanselmann
                               [checkdict, cluster_name])
901 a8083063 Iustin Pop
902 9a525d83 Michael Hanselmann
  @classmethod
903 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
904 3583908a Guido Trotter
  def call_node_start_master(cls, node, start_daemons, no_voting):
905 72737a7f Iustin Pop
    """Tells a node to activate itself as a master.
906 a8083063 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 cls._StaticSingleNodeCall(node, "node_start_master",
911 3583908a Guido Trotter
                                     [start_daemons, no_voting])
912 a8083063 Iustin Pop
913 9a525d83 Michael Hanselmann
  @classmethod
914 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
915 9a525d83 Michael Hanselmann
  def call_node_stop_master(cls, node, stop_daemons):
916 72737a7f Iustin Pop
    """Tells a node to demote itself from master status.
917 a8083063 Iustin Pop

918 72737a7f Iustin Pop
    This is a single-node call.
919 4e071d3b Iustin Pop

920 72737a7f Iustin Pop
    """
921 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_stop_master", [stop_daemons])
922 4e071d3b Iustin Pop
923 9a525d83 Michael Hanselmann
  @classmethod
924 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
925 9a525d83 Michael Hanselmann
  def call_master_info(cls, node_list):
926 72737a7f Iustin Pop
    """Query master info.
927 4e071d3b Iustin Pop

928 72737a7f Iustin Pop
    This is a multi-node call.
929 a8083063 Iustin Pop

930 72737a7f Iustin Pop
    """
931 72737a7f Iustin Pop
    # TODO: should this method query down nodes?
932 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "master_info", [])
933 a8083063 Iustin Pop
934 8f215968 Michael Hanselmann
  @classmethod
935 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
936 8f215968 Michael Hanselmann
  def call_version(cls, node_list):
937 72737a7f Iustin Pop
    """Query node version.
938 a8083063 Iustin Pop

939 72737a7f Iustin Pop
    This is a multi-node call.
940 a8083063 Iustin Pop

941 72737a7f Iustin Pop
    """
942 8f215968 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "version", [])
943 a8083063 Iustin Pop
944 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
945 72737a7f Iustin Pop
  def call_blockdev_create(self, node, bdev, size, owner, on_primary, info):
946 72737a7f Iustin Pop
    """Request creation of a given block device.
947 a8083063 Iustin Pop

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

950 72737a7f Iustin Pop
    """
951 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_create",
952 9a525d83 Michael Hanselmann
                                [bdev.ToDict(), size, owner, on_primary, info])
953 a8083063 Iustin Pop
954 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
955 72737a7f Iustin Pop
  def call_blockdev_remove(self, node, bdev):
956 72737a7f Iustin Pop
    """Request removal of a given block device.
957 a8083063 Iustin Pop

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

960 72737a7f Iustin Pop
    """
961 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_remove", [bdev.ToDict()])
962 f3e513ad Iustin Pop
963 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
964 72737a7f Iustin Pop
  def call_blockdev_rename(self, node, devlist):
965 72737a7f Iustin Pop
    """Request rename of the given block devices.
966 f3e513ad Iustin Pop

967 72737a7f Iustin Pop
    This is a single-node call.
968 a8083063 Iustin Pop

969 72737a7f Iustin Pop
    """
970 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_rename",
971 9a525d83 Michael Hanselmann
                                [(d.ToDict(), uid) for d, uid in devlist])
972 a8083063 Iustin Pop
973 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
974 72737a7f Iustin Pop
  def call_blockdev_assemble(self, node, disk, owner, on_primary):
975 72737a7f Iustin Pop
    """Request assembling of a given block device.
976 a8083063 Iustin Pop

977 72737a7f Iustin Pop
    This is a single-node call.
978 a8083063 Iustin Pop

979 72737a7f Iustin Pop
    """
980 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_assemble",
981 9a525d83 Michael Hanselmann
                                [disk.ToDict(), owner, on_primary])
982 a8083063 Iustin Pop
983 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
984 72737a7f Iustin Pop
  def call_blockdev_shutdown(self, node, disk):
985 72737a7f Iustin Pop
    """Request shutdown of a given block device.
986 a8083063 Iustin Pop

987 72737a7f Iustin Pop
    This is a single-node call.
988 a8083063 Iustin Pop

989 72737a7f Iustin Pop
    """
990 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_shutdown", [disk.ToDict()])
991 a8083063 Iustin Pop
992 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
993 72737a7f Iustin Pop
  def call_blockdev_addchildren(self, node, bdev, ndevs):
994 72737a7f Iustin Pop
    """Request adding a list of children to a (mirroring) device.
995 a8083063 Iustin Pop

996 72737a7f Iustin Pop
    This is a single-node call.
997 a8083063 Iustin Pop

998 72737a7f Iustin Pop
    """
999 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_addchildren",
1000 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
1001 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
1002 a8083063 Iustin Pop
1003 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1004 72737a7f Iustin Pop
  def call_blockdev_removechildren(self, node, bdev, ndevs):
1005 72737a7f Iustin Pop
    """Request removing a list of children from a (mirroring) device.
1006 a8083063 Iustin Pop

1007 72737a7f Iustin Pop
    This is a single-node call.
1008 a8083063 Iustin Pop

1009 72737a7f Iustin Pop
    """
1010 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_removechildren",
1011 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
1012 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
1013 a8083063 Iustin Pop
1014 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1015 72737a7f Iustin Pop
  def call_blockdev_getmirrorstatus(self, node, disks):
1016 72737a7f Iustin Pop
    """Request status of a (mirroring) device.
1017 a8083063 Iustin Pop

1018 72737a7f Iustin Pop
    This is a single-node call.
1019 a8083063 Iustin Pop

1020 72737a7f Iustin Pop
    """
1021 36145b12 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_getmirrorstatus",
1022 36145b12 Michael Hanselmann
                                  [dsk.ToDict() for dsk in disks])
1023 edb4b374 Michael Hanselmann
    if not result.fail_msg:
1024 36145b12 Michael Hanselmann
      result.payload = [objects.BlockDevStatus.FromDict(i)
1025 36145b12 Michael Hanselmann
                        for i in result.payload]
1026 36145b12 Michael Hanselmann
    return result
1027 a8083063 Iustin Pop
1028 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1029 72737a7f Iustin Pop
  def call_blockdev_find(self, node, disk):
1030 72737a7f Iustin Pop
    """Request identification of a given block device.
1031 72737a7f Iustin Pop

1032 72737a7f Iustin Pop
    This is a single-node call.
1033 a8083063 Iustin Pop

1034 72737a7f Iustin Pop
    """
1035 96acbc09 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_find", [disk.ToDict()])
1036 edb4b374 Michael Hanselmann
    if not result.fail_msg and result.payload is not None:
1037 96acbc09 Michael Hanselmann
      result.payload = objects.BlockDevStatus.FromDict(result.payload)
1038 96acbc09 Michael Hanselmann
    return result
1039 d61cbe76 Iustin Pop
1040 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1041 b2e7666a Iustin Pop
  def call_blockdev_close(self, node, instance_name, disks):
1042 72737a7f Iustin Pop
    """Closes the given block devices.
1043 d61cbe76 Iustin Pop

1044 72737a7f Iustin Pop
    This is a single-node call.
1045 d61cbe76 Iustin Pop

1046 72737a7f Iustin Pop
    """
1047 b2e7666a Iustin Pop
    params = [instance_name, [cf.ToDict() for cf in disks]]
1048 b2e7666a Iustin Pop
    return self._SingleNodeCall(node, "blockdev_close", params)
1049 a8083063 Iustin Pop
1050 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1051 968a7623 Iustin Pop
  def call_blockdev_getsizes(self, node, disks):
1052 968a7623 Iustin Pop
    """Returns the size of the given disks.
1053 968a7623 Iustin Pop

1054 968a7623 Iustin Pop
    This is a single-node call.
1055 968a7623 Iustin Pop

1056 968a7623 Iustin Pop
    """
1057 968a7623 Iustin Pop
    params = [[cf.ToDict() for cf in disks]]
1058 968a7623 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_getsize", params)
1059 968a7623 Iustin Pop
1060 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1061 6b93ec9d Iustin Pop
  def call_drbd_disconnect_net(self, node_list, nodes_ip, disks):
1062 6b93ec9d Iustin Pop
    """Disconnects the network of the given drbd devices.
1063 6b93ec9d Iustin Pop

1064 6b93ec9d Iustin Pop
    This is a multi-node call.
1065 6b93ec9d Iustin Pop

1066 6b93ec9d Iustin Pop
    """
1067 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_disconnect_net",
1068 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1069 6b93ec9d Iustin Pop
1070 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1071 6b93ec9d Iustin Pop
  def call_drbd_attach_net(self, node_list, nodes_ip,
1072 6b93ec9d Iustin Pop
                           disks, instance_name, multimaster):
1073 6b93ec9d Iustin Pop
    """Disconnects the given drbd devices.
1074 6b93ec9d Iustin Pop

1075 6b93ec9d Iustin Pop
    This is a multi-node call.
1076 6b93ec9d Iustin Pop

1077 6b93ec9d Iustin Pop
    """
1078 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_attach_net",
1079 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks],
1080 6b93ec9d Iustin Pop
                                instance_name, multimaster])
1081 6b93ec9d Iustin Pop
1082 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
1083 6b93ec9d Iustin Pop
  def call_drbd_wait_sync(self, node_list, nodes_ip, disks):
1084 6b93ec9d Iustin Pop
    """Waits for the synchronization of drbd devices is complete.
1085 6b93ec9d Iustin Pop

1086 6b93ec9d Iustin Pop
    This is a multi-node call.
1087 6b93ec9d Iustin Pop

1088 6b93ec9d Iustin Pop
    """
1089 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_wait_sync",
1090 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1091 6b93ec9d Iustin Pop
1092 c46b9782 Luca Bigliardi
  @_RpcTimeout(_TMO_URGENT)
1093 c46b9782 Luca Bigliardi
  def call_drbd_helper(self, node_list):
1094 c46b9782 Luca Bigliardi
    """Gets drbd helper.
1095 c46b9782 Luca Bigliardi

1096 c46b9782 Luca Bigliardi
    This is a multi-node call.
1097 c46b9782 Luca Bigliardi

1098 c46b9782 Luca Bigliardi
    """
1099 c46b9782 Luca Bigliardi
    return self._MultiNodeCall(node_list, "drbd_helper", [])
1100 c46b9782 Luca Bigliardi
1101 9a525d83 Michael Hanselmann
  @classmethod
1102 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1103 9a525d83 Michael Hanselmann
  def call_upload_file(cls, node_list, file_name, address_list=None):
1104 72737a7f Iustin Pop
    """Upload a file.
1105 72737a7f Iustin Pop

1106 72737a7f Iustin Pop
    The node will refuse the operation in case the file is not on the
1107 72737a7f Iustin Pop
    approved file list.
1108 72737a7f Iustin Pop

1109 72737a7f Iustin Pop
    This is a multi-node call.
1110 a8083063 Iustin Pop

1111 6b294c53 Iustin Pop
    @type node_list: list
1112 6b294c53 Iustin Pop
    @param node_list: the list of node names to upload to
1113 6b294c53 Iustin Pop
    @type file_name: str
1114 6b294c53 Iustin Pop
    @param file_name: the filename to upload
1115 6b294c53 Iustin Pop
    @type address_list: list or None
1116 6b294c53 Iustin Pop
    @keyword address_list: an optional list of node addresses, in order
1117 6b294c53 Iustin Pop
        to optimize the RPC speed
1118 6b294c53 Iustin Pop

1119 72737a7f Iustin Pop
    """
1120 12bce260 Michael Hanselmann
    file_contents = utils.ReadFile(file_name)
1121 12bce260 Michael Hanselmann
    data = cls._Compress(file_contents)
1122 72737a7f Iustin Pop
    st = os.stat(file_name)
1123 72737a7f Iustin Pop
    params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
1124 72737a7f Iustin Pop
              st.st_atime, st.st_mtime]
1125 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "upload_file", params,
1126 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1127 72737a7f Iustin Pop
1128 6ddc95ec Michael Hanselmann
  @classmethod
1129 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1130 03d1dba2 Michael Hanselmann
  def call_write_ssconf_files(cls, node_list, values):
1131 6ddc95ec Michael Hanselmann
    """Write ssconf files.
1132 6ddc95ec Michael Hanselmann

1133 6ddc95ec Michael Hanselmann
    This is a multi-node call.
1134 6ddc95ec Michael Hanselmann

1135 6ddc95ec Michael Hanselmann
    """
1136 03d1dba2 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "write_ssconf_files", [values])
1137 6ddc95ec Michael Hanselmann
1138 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1139 72737a7f Iustin Pop
  def call_os_diagnose(self, node_list):
1140 72737a7f Iustin Pop
    """Request a diagnose of OS definitions.
1141 72737a7f Iustin Pop

1142 72737a7f Iustin Pop
    This is a multi-node call.
1143 a8083063 Iustin Pop

1144 72737a7f Iustin Pop
    """
1145 83d92ad8 Iustin Pop
    return self._MultiNodeCall(node_list, "os_diagnose", [])
1146 a8083063 Iustin Pop
1147 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1148 72737a7f Iustin Pop
  def call_os_get(self, node, name):
1149 72737a7f Iustin Pop
    """Returns an OS definition.
1150 a8083063 Iustin Pop

1151 72737a7f Iustin Pop
    This is a single-node call.
1152 a8083063 Iustin Pop

1153 72737a7f Iustin Pop
    """
1154 9a525d83 Michael Hanselmann
    result = self._SingleNodeCall(node, "os_get", [name])
1155 84e3f66f Guido Trotter
    if not result.fail_msg and isinstance(result.payload, dict):
1156 84e3f66f Guido Trotter
      result.payload = objects.OS.FromDict(result.payload)
1157 781de953 Iustin Pop
    return result
1158 a8083063 Iustin Pop
1159 acd9ff9e Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1160 acd9ff9e Iustin Pop
  def call_os_validate(self, required, nodes, name, checks, params):
1161 acd9ff9e Iustin Pop
    """Run a validation routine for a given OS.
1162 acd9ff9e Iustin Pop

1163 acd9ff9e Iustin Pop
    This is a multi-node call.
1164 acd9ff9e Iustin Pop

1165 acd9ff9e Iustin Pop
    """
1166 acd9ff9e Iustin Pop
    return self._MultiNodeCall(nodes, "os_validate",
1167 acd9ff9e Iustin Pop
                               [required, name, checks, params])
1168 acd9ff9e Iustin Pop
1169 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1170 72737a7f Iustin Pop
  def call_hooks_runner(self, node_list, hpath, phase, env):
1171 72737a7f Iustin Pop
    """Call the hooks runner.
1172 a8083063 Iustin Pop

1173 72737a7f Iustin Pop
    Args:
1174 72737a7f Iustin Pop
      - op: the OpCode instance
1175 72737a7f Iustin Pop
      - env: a dictionary with the environment
1176 a8083063 Iustin Pop

1177 72737a7f Iustin Pop
    This is a multi-node call.
1178 a8083063 Iustin Pop

1179 72737a7f Iustin Pop
    """
1180 72737a7f Iustin Pop
    params = [hpath, phase, env]
1181 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hooks_runner", params)
1182 a8083063 Iustin Pop
1183 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1184 72737a7f Iustin Pop
  def call_iallocator_runner(self, node, name, idata):
1185 72737a7f Iustin Pop
    """Call an iallocator on a remote node
1186 8d528b7c Iustin Pop

1187 72737a7f Iustin Pop
    Args:
1188 72737a7f Iustin Pop
      - name: the iallocator name
1189 72737a7f Iustin Pop
      - input: the json-encoded input string
1190 8d528b7c Iustin Pop

1191 72737a7f Iustin Pop
    This is a single-node call.
1192 8d528b7c Iustin Pop

1193 72737a7f Iustin Pop
    """
1194 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "iallocator_runner", [name, idata])
1195 8d528b7c Iustin Pop
1196 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1197 72737a7f Iustin Pop
  def call_blockdev_grow(self, node, cf_bdev, amount):
1198 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1199 4c8ba8b3 Iustin Pop

1200 72737a7f Iustin Pop
    This is a single-node call.
1201 4c8ba8b3 Iustin Pop

1202 72737a7f Iustin Pop
    """
1203 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_grow",
1204 9a525d83 Michael Hanselmann
                                [cf_bdev.ToDict(), amount])
1205 4c8ba8b3 Iustin Pop
1206 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_1DAY)
1207 858f3d18 Iustin Pop
  def call_blockdev_export(self, node, cf_bdev,
1208 858f3d18 Iustin Pop
                           dest_node, dest_path, cluster_name):
1209 858f3d18 Iustin Pop
    """Export a given disk to another node.
1210 858f3d18 Iustin Pop

1211 858f3d18 Iustin Pop
    This is a single-node call.
1212 858f3d18 Iustin Pop

1213 858f3d18 Iustin Pop
    """
1214 858f3d18 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_export",
1215 858f3d18 Iustin Pop
                                [cf_bdev.ToDict(), dest_node, dest_path,
1216 858f3d18 Iustin Pop
                                 cluster_name])
1217 858f3d18 Iustin Pop
1218 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1219 72737a7f Iustin Pop
  def call_blockdev_snapshot(self, node, cf_bdev):
1220 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1221 a8083063 Iustin Pop

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

1224 72737a7f Iustin Pop
    """
1225 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_snapshot", [cf_bdev.ToDict()])
1226 a8083063 Iustin Pop
1227 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1228 72737a7f Iustin Pop
  def call_finalize_export(self, node, instance, snap_disks):
1229 72737a7f Iustin Pop
    """Request the completion of an export operation.
1230 a8083063 Iustin Pop

1231 72737a7f Iustin Pop
    This writes the export config file, etc.
1232 a8083063 Iustin Pop

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

1235 72737a7f Iustin Pop
    """
1236 72737a7f Iustin Pop
    flat_disks = []
1237 72737a7f Iustin Pop
    for disk in snap_disks:
1238 a97da6b7 Iustin Pop
      if isinstance(disk, bool):
1239 a97da6b7 Iustin Pop
        flat_disks.append(disk)
1240 a97da6b7 Iustin Pop
      else:
1241 a97da6b7 Iustin Pop
        flat_disks.append(disk.ToDict())
1242 9a525d83 Michael Hanselmann
1243 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "finalize_export",
1244 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), flat_disks])
1245 a8083063 Iustin Pop
1246 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1247 72737a7f Iustin Pop
  def call_export_info(self, node, path):
1248 72737a7f Iustin Pop
    """Queries the export information in a given path.
1249 a8083063 Iustin Pop

1250 72737a7f Iustin Pop
    This is a single-node call.
1251 a8083063 Iustin Pop

1252 72737a7f Iustin Pop
    """
1253 3eccac06 Iustin Pop
    return self._SingleNodeCall(node, "export_info", [path])
1254 a8083063 Iustin Pop
1255 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1256 72737a7f Iustin Pop
  def call_export_list(self, node_list):
1257 72737a7f Iustin Pop
    """Gets the stored exports list.
1258 a8083063 Iustin Pop

1259 72737a7f Iustin Pop
    This is a multi-node call.
1260 a8083063 Iustin Pop

1261 72737a7f Iustin Pop
    """
1262 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "export_list", [])
1263 a8083063 Iustin Pop
1264 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1265 72737a7f Iustin Pop
  def call_export_remove(self, node, export):
1266 72737a7f Iustin Pop
    """Requests removal of a given export.
1267 a8083063 Iustin Pop

1268 72737a7f Iustin Pop
    This is a single-node call.
1269 a8083063 Iustin Pop

1270 72737a7f Iustin Pop
    """
1271 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "export_remove", [export])
1272 a8083063 Iustin Pop
1273 9a525d83 Michael Hanselmann
  @classmethod
1274 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1275 b989b9d9 Ken Wehr
  def call_node_leave_cluster(cls, node, modify_ssh_setup):
1276 72737a7f Iustin Pop
    """Requests a node to clean the cluster information it has.
1277 a8083063 Iustin Pop

1278 72737a7f Iustin Pop
    This will remove the configuration information from the ganeti data
1279 72737a7f Iustin Pop
    dir.
1280 a8083063 Iustin Pop

1281 72737a7f Iustin Pop
    This is a single-node call.
1282 a8083063 Iustin Pop

1283 72737a7f Iustin Pop
    """
1284 b989b9d9 Ken Wehr
    return cls._StaticSingleNodeCall(node, "node_leave_cluster",
1285 b989b9d9 Ken Wehr
                                     [modify_ssh_setup])
1286 dcb93971 Michael Hanselmann
1287 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1288 72737a7f Iustin Pop
  def call_node_volumes(self, node_list):
1289 72737a7f Iustin Pop
    """Gets all volumes on node(s).
1290 dcb93971 Michael Hanselmann

1291 72737a7f Iustin Pop
    This is a multi-node call.
1292 dcb93971 Michael Hanselmann

1293 72737a7f Iustin Pop
    """
1294 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_volumes", [])
1295 06009e27 Iustin Pop
1296 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1297 56aa9fd5 Iustin Pop
  def call_node_demote_from_mc(self, node):
1298 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
1299 56aa9fd5 Iustin Pop

1300 56aa9fd5 Iustin Pop
    This is a single-node call.
1301 56aa9fd5 Iustin Pop

1302 56aa9fd5 Iustin Pop
    """
1303 56aa9fd5 Iustin Pop
    return self._SingleNodeCall(node, "node_demote_from_mc", [])
1304 56aa9fd5 Iustin Pop
1305 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1306 f5118ade Iustin Pop
  def call_node_powercycle(self, node, hypervisor):
1307 f5118ade Iustin Pop
    """Tries to powercycle a node.
1308 f5118ade Iustin Pop

1309 f5118ade Iustin Pop
    This is a single-node call.
1310 f5118ade Iustin Pop

1311 f5118ade Iustin Pop
    """
1312 f5118ade Iustin Pop
    return self._SingleNodeCall(node, "node_powercycle", [hypervisor])
1313 f5118ade Iustin Pop
1314 92fd2250 Iustin Pop
  @_RpcTimeout(None)
1315 72737a7f Iustin Pop
  def call_test_delay(self, node_list, duration):
1316 72737a7f Iustin Pop
    """Sleep for a fixed time on given node(s).
1317 06009e27 Iustin Pop

1318 72737a7f Iustin Pop
    This is a multi-node call.
1319 06009e27 Iustin Pop

1320 72737a7f Iustin Pop
    """
1321 92fd2250 Iustin Pop
    return self._MultiNodeCall(node_list, "test_delay", [duration],
1322 92fd2250 Iustin Pop
                               read_timeout=int(duration + 5))
1323 5e04ed8b Manuel Franceschini
1324 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1325 72737a7f Iustin Pop
  def call_file_storage_dir_create(self, node, file_storage_dir):
1326 72737a7f Iustin Pop
    """Create the given file storage directory.
1327 5e04ed8b Manuel Franceschini

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

1330 72737a7f Iustin Pop
    """
1331 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_create",
1332 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1333 5e04ed8b Manuel Franceschini
1334 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1335 72737a7f Iustin Pop
  def call_file_storage_dir_remove(self, node, file_storage_dir):
1336 72737a7f Iustin Pop
    """Remove the given file storage directory.
1337 5e04ed8b Manuel Franceschini

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

1340 72737a7f Iustin Pop
    """
1341 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_remove",
1342 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1343 5e04ed8b Manuel Franceschini
1344 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1345 72737a7f Iustin Pop
  def call_file_storage_dir_rename(self, node, old_file_storage_dir,
1346 72737a7f Iustin Pop
                                   new_file_storage_dir):
1347 72737a7f Iustin Pop
    """Rename file storage directory.
1348 5e04ed8b Manuel Franceschini

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

1351 72737a7f Iustin Pop
    """
1352 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_rename",
1353 9a525d83 Michael Hanselmann
                                [old_file_storage_dir, new_file_storage_dir])
1354 ca52cdeb Michael Hanselmann
1355 9a525d83 Michael Hanselmann
  @classmethod
1356 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1357 9a525d83 Michael Hanselmann
  def call_jobqueue_update(cls, node_list, address_list, file_name, content):
1358 72737a7f Iustin Pop
    """Update job queue.
1359 ca52cdeb Michael Hanselmann

1360 72737a7f Iustin Pop
    This is a multi-node call.
1361 ca52cdeb Michael Hanselmann

1362 72737a7f Iustin Pop
    """
1363 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_update",
1364 12bce260 Michael Hanselmann
                                    [file_name, cls._Compress(content)],
1365 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1366 ca52cdeb Michael Hanselmann
1367 9a525d83 Michael Hanselmann
  @classmethod
1368 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1369 9a525d83 Michael Hanselmann
  def call_jobqueue_purge(cls, node):
1370 72737a7f Iustin Pop
    """Purge job queue.
1371 ca52cdeb Michael Hanselmann

1372 72737a7f Iustin Pop
    This is a single-node call.
1373 ca52cdeb Michael Hanselmann

1374 72737a7f Iustin Pop
    """
1375 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "jobqueue_purge", [])
1376 af5ebcb1 Michael Hanselmann
1377 9a525d83 Michael Hanselmann
  @classmethod
1378 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1379 dd875d32 Michael Hanselmann
  def call_jobqueue_rename(cls, node_list, address_list, rename):
1380 72737a7f Iustin Pop
    """Rename a job queue file.
1381 af5ebcb1 Michael Hanselmann

1382 72737a7f Iustin Pop
    This is a multi-node call.
1383 af5ebcb1 Michael Hanselmann

1384 72737a7f Iustin Pop
    """
1385 dd875d32 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_rename", rename,
1386 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1387 6217e295 Iustin Pop
1388 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1389 6217e295 Iustin Pop
  def call_hypervisor_validate_params(self, node_list, hvname, hvparams):
1390 6217e295 Iustin Pop
    """Validate the hypervisor params.
1391 6217e295 Iustin Pop

1392 6217e295 Iustin Pop
    This is a multi-node call.
1393 6217e295 Iustin Pop

1394 6217e295 Iustin Pop
    @type node_list: list
1395 6217e295 Iustin Pop
    @param node_list: the list of nodes to query
1396 6217e295 Iustin Pop
    @type hvname: string
1397 6217e295 Iustin Pop
    @param hvname: the hypervisor name
1398 6217e295 Iustin Pop
    @type hvparams: dict
1399 6217e295 Iustin Pop
    @param hvparams: the hypervisor parameters to be validated
1400 6217e295 Iustin Pop

1401 6217e295 Iustin Pop
    """
1402 6217e295 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
1403 abe609b2 Guido Trotter
    hv_full = objects.FillDict(cluster.hvparams.get(hvname, {}), hvparams)
1404 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hypervisor_validate_params",
1405 9a525d83 Michael Hanselmann
                               [hvname, hv_full])
1406 f942a838 Michael Hanselmann
1407 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1408 37549316 Michael Hanselmann
  def call_x509_cert_create(self, node, validity):
1409 f942a838 Michael Hanselmann
    """Creates a new X509 certificate for SSL/TLS.
1410 f942a838 Michael Hanselmann

1411 f942a838 Michael Hanselmann
    This is a single-node call.
1412 f942a838 Michael Hanselmann

1413 f942a838 Michael Hanselmann
    @type validity: int
1414 f942a838 Michael Hanselmann
    @param validity: Validity in seconds
1415 f942a838 Michael Hanselmann

1416 f942a838 Michael Hanselmann
    """
1417 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_create", [validity])
1418 f942a838 Michael Hanselmann
1419 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1420 37549316 Michael Hanselmann
  def call_x509_cert_remove(self, node, name):
1421 f942a838 Michael Hanselmann
    """Removes a X509 certificate.
1422 f942a838 Michael Hanselmann

1423 f942a838 Michael Hanselmann
    This is a single-node call.
1424 f942a838 Michael Hanselmann

1425 f942a838 Michael Hanselmann
    @type name: string
1426 f942a838 Michael Hanselmann
    @param name: Certificate name
1427 f942a838 Michael Hanselmann

1428 f942a838 Michael Hanselmann
    """
1429 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_remove", [name])
1430 1651d116 Michael Hanselmann
1431 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1432 eb630f50 Michael Hanselmann
  def call_import_start(self, node, opts, instance, dest, dest_args):
1433 1651d116 Michael Hanselmann
    """Starts a listener for an import.
1434 1651d116 Michael Hanselmann

1435 1651d116 Michael Hanselmann
    This is a single-node call.
1436 1651d116 Michael Hanselmann

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

1442 1651d116 Michael Hanselmann
    """
1443 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "import_start",
1444 eb630f50 Michael Hanselmann
                                [opts.ToDict(),
1445 1651d116 Michael Hanselmann
                                 self._InstDict(instance), dest,
1446 1651d116 Michael Hanselmann
                                 _EncodeImportExportIO(dest, dest_args)])
1447 1651d116 Michael Hanselmann
1448 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1449 eb630f50 Michael Hanselmann
  def call_export_start(self, node, opts, host, port,
1450 1651d116 Michael Hanselmann
                        instance, source, source_args):
1451 1651d116 Michael Hanselmann
    """Starts an export daemon.
1452 1651d116 Michael Hanselmann

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

1455 1651d116 Michael Hanselmann
    @type node: string
1456 1651d116 Michael Hanselmann
    @param node: Node name
1457 1651d116 Michael Hanselmann
    @type instance: C{objects.Instance}
1458 1651d116 Michael Hanselmann
    @param instance: Instance object
1459 1651d116 Michael Hanselmann

1460 1651d116 Michael Hanselmann
    """
1461 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "export_start",
1462 eb630f50 Michael Hanselmann
                                [opts.ToDict(), host, port,
1463 1651d116 Michael Hanselmann
                                 self._InstDict(instance), source,
1464 1651d116 Michael Hanselmann
                                 _EncodeImportExportIO(source, source_args)])
1465 1651d116 Michael Hanselmann
1466 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1467 ef40fbfb Michael Hanselmann
  def call_impexp_status(self, node, names):
1468 1651d116 Michael Hanselmann
    """Gets the status of an import or export.
1469 1651d116 Michael Hanselmann

1470 1651d116 Michael Hanselmann
    This is a single-node call.
1471 1651d116 Michael Hanselmann

1472 1651d116 Michael Hanselmann
    @type node: string
1473 1651d116 Michael Hanselmann
    @param node: Node name
1474 1651d116 Michael Hanselmann
    @type names: List of strings
1475 1651d116 Michael Hanselmann
    @param names: Import/export names
1476 1651d116 Michael Hanselmann
    @rtype: List of L{objects.ImportExportStatus} instances
1477 1651d116 Michael Hanselmann
    @return: Returns a list of the state of each named import/export or None if
1478 1651d116 Michael Hanselmann
             a status couldn't be retrieved
1479 1651d116 Michael Hanselmann

1480 1651d116 Michael Hanselmann
    """
1481 ef40fbfb Michael Hanselmann
    result = self._SingleNodeCall(node, "impexp_status", [names])
1482 1651d116 Michael Hanselmann
1483 1651d116 Michael Hanselmann
    if not result.fail_msg:
1484 1651d116 Michael Hanselmann
      decoded = []
1485 1651d116 Michael Hanselmann
1486 1651d116 Michael Hanselmann
      for i in result.payload:
1487 1651d116 Michael Hanselmann
        if i is None:
1488 1651d116 Michael Hanselmann
          decoded.append(None)
1489 1651d116 Michael Hanselmann
          continue
1490 1651d116 Michael Hanselmann
        decoded.append(objects.ImportExportStatus.FromDict(i))
1491 1651d116 Michael Hanselmann
1492 1651d116 Michael Hanselmann
      result.payload = decoded
1493 1651d116 Michael Hanselmann
1494 1651d116 Michael Hanselmann
    return result
1495 1651d116 Michael Hanselmann
1496 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1497 f81c4737 Michael Hanselmann
  def call_impexp_abort(self, node, name):
1498 f81c4737 Michael Hanselmann
    """Aborts an import or export.
1499 f81c4737 Michael Hanselmann

1500 f81c4737 Michael Hanselmann
    This is a single-node call.
1501 f81c4737 Michael Hanselmann

1502 f81c4737 Michael Hanselmann
    @type node: string
1503 f81c4737 Michael Hanselmann
    @param node: Node name
1504 f81c4737 Michael Hanselmann
    @type name: string
1505 f81c4737 Michael Hanselmann
    @param name: Import/export name
1506 f81c4737 Michael Hanselmann

1507 f81c4737 Michael Hanselmann
    """
1508 f81c4737 Michael Hanselmann
    return self._SingleNodeCall(node, "impexp_abort", [name])
1509 f81c4737 Michael Hanselmann
1510 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1511 ef40fbfb Michael Hanselmann
  def call_impexp_cleanup(self, node, name):
1512 1651d116 Michael Hanselmann
    """Cleans up after an import or export.
1513 1651d116 Michael Hanselmann

1514 1651d116 Michael Hanselmann
    This is a single-node call.
1515 1651d116 Michael Hanselmann

1516 1651d116 Michael Hanselmann
    @type node: string
1517 1651d116 Michael Hanselmann
    @param node: Node name
1518 1651d116 Michael Hanselmann
    @type name: string
1519 1651d116 Michael Hanselmann
    @param name: Import/export name
1520 1651d116 Michael Hanselmann

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