Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ 66e884e1

History | View | Annotate | Download (46.1 kB)

1 2f31098c Iustin Pop
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 8e29563f Iustin Pop
# Copyright (C) 2006, 2007, 2008, 2009, 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 8e29563f Iustin Pop
  "Expect:",
59 33231500 Michael Hanselmann
  ]
60 4331f6cd Michael Hanselmann
61 92fd2250 Iustin Pop
# Various time constants for the timeout table
62 92fd2250 Iustin Pop
_TMO_URGENT = 60 # one minute
63 92fd2250 Iustin Pop
_TMO_FAST = 5 * 60 # five minutes
64 92fd2250 Iustin Pop
_TMO_NORMAL = 15 * 60 # 15 minutes
65 92fd2250 Iustin Pop
_TMO_SLOW = 3600 # one hour
66 92fd2250 Iustin Pop
_TMO_4HRS = 4 * 3600
67 92fd2250 Iustin Pop
_TMO_1DAY = 86400
68 92fd2250 Iustin Pop
69 92fd2250 Iustin Pop
# Timeout table that will be built later by decorators
70 92fd2250 Iustin Pop
# Guidelines for choosing timeouts:
71 92fd2250 Iustin Pop
# - call used during watcher: timeout -> 1min, _TMO_URGENT
72 92fd2250 Iustin Pop
# - trivial (but be sure it is trivial) (e.g. reading a file): 5min, _TMO_FAST
73 92fd2250 Iustin Pop
# - other calls: 15 min, _TMO_NORMAL
74 92fd2250 Iustin Pop
# - special calls (instance add, etc.): either _TMO_SLOW (1h) or huge timeouts
75 92fd2250 Iustin Pop
76 92fd2250 Iustin Pop
_TIMEOUTS = {
77 92fd2250 Iustin Pop
}
78 92fd2250 Iustin Pop
79 4331f6cd Michael Hanselmann
80 4331f6cd Michael Hanselmann
def Init():
81 4331f6cd Michael Hanselmann
  """Initializes the module-global HTTP client manager.
82 4331f6cd Michael Hanselmann

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

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

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

104 4331f6cd Michael Hanselmann
  """
105 33231500 Michael Hanselmann
  pycurl.global_cleanup()
106 33231500 Michael Hanselmann
107 33231500 Michael Hanselmann
108 33231500 Michael Hanselmann
def _ConfigRpcCurl(curl):
109 33231500 Michael Hanselmann
  noded_cert = str(constants.NODED_CERT_FILE)
110 4331f6cd Michael Hanselmann
111 33231500 Michael Hanselmann
  curl.setopt(pycurl.FOLLOWLOCATION, False)
112 33231500 Michael Hanselmann
  curl.setopt(pycurl.CAINFO, noded_cert)
113 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSL_VERIFYHOST, 0)
114 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSL_VERIFYPEER, True)
115 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSLCERTTYPE, "PEM")
116 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSLCERT, noded_cert)
117 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSLKEYTYPE, "PEM")
118 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSLKEY, noded_cert)
119 33231500 Michael Hanselmann
  curl.setopt(pycurl.CONNECTTIMEOUT, _RPC_CONNECT_TIMEOUT)
120 33231500 Michael Hanselmann
121 33231500 Michael Hanselmann
122 c29e35fe Michael Hanselmann
# Aliasing this module avoids the following warning by epydoc: "Warning: No
123 c29e35fe Michael Hanselmann
# information available for ganeti.rpc._RpcThreadLocal's base threading.local"
124 c29e35fe Michael Hanselmann
_threading = threading
125 c29e35fe Michael Hanselmann
126 c29e35fe Michael Hanselmann
127 c29e35fe Michael Hanselmann
class _RpcThreadLocal(_threading.local):
128 33231500 Michael Hanselmann
  def GetHttpClientPool(self):
129 33231500 Michael Hanselmann
    """Returns a per-thread HTTP client pool.
130 33231500 Michael Hanselmann

131 33231500 Michael Hanselmann
    @rtype: L{http.client.HttpClientPool}
132 33231500 Michael Hanselmann

133 33231500 Michael Hanselmann
    """
134 33231500 Michael Hanselmann
    try:
135 33231500 Michael Hanselmann
      pool = self.hcp
136 33231500 Michael Hanselmann
    except AttributeError:
137 33231500 Michael Hanselmann
      pool = http.client.HttpClientPool(_ConfigRpcCurl)
138 33231500 Michael Hanselmann
      self.hcp = pool
139 33231500 Michael Hanselmann
140 33231500 Michael Hanselmann
    return pool
141 33231500 Michael Hanselmann
142 33231500 Michael Hanselmann
143 c29e35fe Michael Hanselmann
# Remove module alias (see above)
144 c29e35fe Michael Hanselmann
del _threading
145 c29e35fe Michael Hanselmann
146 c29e35fe Michael Hanselmann
147 33231500 Michael Hanselmann
_thread_local = _RpcThreadLocal()
148 4331f6cd Michael Hanselmann
149 4331f6cd Michael Hanselmann
150 92fd2250 Iustin Pop
def _RpcTimeout(secs):
151 92fd2250 Iustin Pop
  """Timeout decorator.
152 92fd2250 Iustin Pop

153 92fd2250 Iustin Pop
  When applied to a rpc call_* function, it updates the global timeout
154 92fd2250 Iustin Pop
  table with the given function/timeout.
155 92fd2250 Iustin Pop

156 92fd2250 Iustin Pop
  """
157 92fd2250 Iustin Pop
  def decorator(f):
158 92fd2250 Iustin Pop
    name = f.__name__
159 92fd2250 Iustin Pop
    assert name.startswith("call_")
160 92fd2250 Iustin Pop
    _TIMEOUTS[name[len("call_"):]] = secs
161 92fd2250 Iustin Pop
    return f
162 92fd2250 Iustin Pop
  return decorator
163 92fd2250 Iustin Pop
164 92fd2250 Iustin Pop
165 e0e916fe Iustin Pop
def RunWithRPC(fn):
166 e0e916fe Iustin Pop
  """RPC-wrapper decorator.
167 e0e916fe Iustin Pop

168 e0e916fe Iustin Pop
  When applied to a function, it runs it with the RPC system
169 e0e916fe Iustin Pop
  initialized, and it shutsdown the system afterwards. This means the
170 e0e916fe Iustin Pop
  function must be called without RPC being initialized.
171 e0e916fe Iustin Pop

172 e0e916fe Iustin Pop
  """
173 e0e916fe Iustin Pop
  def wrapper(*args, **kwargs):
174 e0e916fe Iustin Pop
    Init()
175 e0e916fe Iustin Pop
    try:
176 e0e916fe Iustin Pop
      return fn(*args, **kwargs)
177 e0e916fe Iustin Pop
    finally:
178 e0e916fe Iustin Pop
      Shutdown()
179 e0e916fe Iustin Pop
  return wrapper
180 e0e916fe Iustin Pop
181 e0e916fe Iustin Pop
182 781de953 Iustin Pop
class RpcResult(object):
183 781de953 Iustin Pop
  """RPC Result class.
184 781de953 Iustin Pop

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

189 5bbd3f7f Michael Hanselmann
  @ivar data: the data payload, for successful results, or None
190 ed83f5cc Iustin Pop
  @ivar call: the name of the RPC call
191 ed83f5cc Iustin Pop
  @ivar node: the name of the node to which we made the call
192 ed83f5cc Iustin Pop
  @ivar offline: whether the operation failed because the node was
193 ed83f5cc Iustin Pop
      offline, as opposed to actual failure; offline=True will always
194 ed83f5cc Iustin Pop
      imply failed=True, in order to allow simpler checking if
195 ed83f5cc Iustin Pop
      the user doesn't care about the exact failure mode
196 4c4e4e1e Iustin Pop
  @ivar fail_msg: the error message if the call failed
197 ed83f5cc Iustin Pop

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

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

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

275 eb202c13 Manuel Franceschini
  @type node_list: list
276 eb202c13 Manuel Franceschini
  @param node_list: List of node names
277 eb202c13 Manuel Franceschini
  @type ssc: class
278 eb202c13 Manuel Franceschini
  @param ssc: SimpleStore class that is used to obtain node->ip mappings
279 17f7fd27 Manuel Franceschini
  @type nslookup_fn: callable
280 17f7fd27 Manuel Franceschini
  @param nslookup_fn: function use to do NS lookup
281 eb202c13 Manuel Franceschini
  @rtype: list of addresses and/or None's
282 eb202c13 Manuel Franceschini
  @returns: List of corresponding addresses, if found
283 eb202c13 Manuel Franceschini

284 eb202c13 Manuel Franceschini
  """
285 b43dcc5a Manuel Franceschini
  ss = ssc()
286 b43dcc5a Manuel Franceschini
  iplist = ss.GetNodePrimaryIPList()
287 b43dcc5a Manuel Franceschini
  family = ss.GetPrimaryIPFamily()
288 eb202c13 Manuel Franceschini
  addresses = []
289 b705c7a6 Manuel Franceschini
  ipmap = dict(entry.split() for entry in iplist)
290 b705c7a6 Manuel Franceschini
  for node in node_list:
291 b705c7a6 Manuel Franceschini
    address = ipmap.get(node)
292 b705c7a6 Manuel Franceschini
    if address is None:
293 b43dcc5a Manuel Franceschini
      address = nslookup_fn(node, family=family)
294 b705c7a6 Manuel Franceschini
    addresses.append(address)
295 eb202c13 Manuel Franceschini
296 eb202c13 Manuel Franceschini
  return addresses
297 eb202c13 Manuel Franceschini
298 eb202c13 Manuel Franceschini
299 a8083063 Iustin Pop
class Client:
300 a8083063 Iustin Pop
  """RPC Client class.
301 a8083063 Iustin Pop

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

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

310 a8083063 Iustin Pop
  """
311 eb202c13 Manuel Franceschini
  def __init__(self, procedure, body, port, address_lookup_fn=_AddressLookup):
312 92fd2250 Iustin Pop
    assert procedure in _TIMEOUTS, ("New RPC call not declared in the"
313 92fd2250 Iustin Pop
                                    " timeouts table")
314 a8083063 Iustin Pop
    self.procedure = procedure
315 160e2921 Iustin Pop
    self.body = body
316 160e2921 Iustin Pop
    self.port = port
317 33231500 Michael Hanselmann
    self._request = {}
318 eb202c13 Manuel Franceschini
    self._address_lookup_fn = address_lookup_fn
319 d57ae7f7 Michael Hanselmann
320 e0036155 Iustin Pop
  def ConnectList(self, node_list, address_list=None, read_timeout=None):
321 a8083063 Iustin Pop
    """Add a list of nodes to the target nodes.
322 a8083063 Iustin Pop

323 3ef3c771 Iustin Pop
    @type node_list: list
324 3ef3c771 Iustin Pop
    @param node_list: the list of node names to connect
325 bdf7d8c0 Iustin Pop
    @type address_list: list or None
326 bdf7d8c0 Iustin Pop
    @keyword address_list: either None or a list with node addresses,
327 bdf7d8c0 Iustin Pop
        which must have the same length as the node list
328 e0036155 Iustin Pop
    @type read_timeout: int
329 eb202c13 Manuel Franceschini
    @param read_timeout: overwrites default timeout for operation
330 3ef3c771 Iustin Pop

331 a8083063 Iustin Pop
    """
332 bdf7d8c0 Iustin Pop
    if address_list is None:
333 eb202c13 Manuel Franceschini
      # Always use IP address instead of node name
334 eb202c13 Manuel Franceschini
      address_list = self._address_lookup_fn(node_list)
335 eb202c13 Manuel Franceschini
336 eb202c13 Manuel Franceschini
    assert len(node_list) == len(address_list), \
337 eb202c13 Manuel Franceschini
           "Name and address lists must have the same length"
338 eb202c13 Manuel Franceschini
339 bdf7d8c0 Iustin Pop
    for node, address in zip(node_list, address_list):
340 e0036155 Iustin Pop
      self.ConnectNode(node, address, read_timeout=read_timeout)
341 bdf7d8c0 Iustin Pop
342 e0036155 Iustin Pop
  def ConnectNode(self, name, address=None, read_timeout=None):
343 a8083063 Iustin Pop
    """Add a node to the target list.
344 a8083063 Iustin Pop

345 bdf7d8c0 Iustin Pop
    @type name: str
346 bdf7d8c0 Iustin Pop
    @param name: the node name
347 bdf7d8c0 Iustin Pop
    @type address: str
348 eb202c13 Manuel Franceschini
    @param address: the node address, if known
349 eb202c13 Manuel Franceschini
    @type read_timeout: int
350 eb202c13 Manuel Franceschini
    @param read_timeout: overwrites default timeout for operation
351 bdf7d8c0 Iustin Pop

352 a8083063 Iustin Pop
    """
353 ecfe9491 Michael Hanselmann
    if address is None:
354 eb202c13 Manuel Franceschini
      # Always use IP address instead of node name
355 eb202c13 Manuel Franceschini
      address = self._address_lookup_fn([name])[0]
356 eb202c13 Manuel Franceschini
357 eb202c13 Manuel Franceschini
    assert(address is not None)
358 ecfe9491 Michael Hanselmann
359 92fd2250 Iustin Pop
    if read_timeout is None:
360 92fd2250 Iustin Pop
      read_timeout = _TIMEOUTS[self.procedure]
361 92fd2250 Iustin Pop
362 33231500 Michael Hanselmann
    self._request[name] = \
363 33231500 Michael Hanselmann
      http.client.HttpClientRequest(str(address), self.port,
364 33231500 Michael Hanselmann
                                    http.HTTP_PUT, str("/%s" % self.procedure),
365 33231500 Michael Hanselmann
                                    headers=_RPC_CLIENT_HEADERS,
366 33231500 Michael Hanselmann
                                    post_data=str(self.body),
367 e0036155 Iustin Pop
                                    read_timeout=read_timeout)
368 a8083063 Iustin Pop
369 33231500 Michael Hanselmann
  def GetResults(self, http_pool=None):
370 ecfe9491 Michael Hanselmann
    """Call nodes and return results.
371 ecfe9491 Michael Hanselmann

372 ecfe9491 Michael Hanselmann
    @rtype: list
373 5fcc718f Iustin Pop
    @return: List of RPC results
374 a8083063 Iustin Pop

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

406 1651d116 Michael Hanselmann
  """
407 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_RAW_DISK:
408 1651d116 Michael Hanselmann
    assert len(ieioargs) == 1
409 1651d116 Michael Hanselmann
    return (ieioargs[0].ToDict(), )
410 1651d116 Michael Hanselmann
411 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_SCRIPT:
412 1651d116 Michael Hanselmann
    assert len(ieioargs) == 2
413 1651d116 Michael Hanselmann
    return (ieioargs[0].ToDict(), ieioargs[1])
414 1651d116 Michael Hanselmann
415 1651d116 Michael Hanselmann
  return ieioargs
416 1651d116 Michael Hanselmann
417 1651d116 Michael Hanselmann
418 72737a7f Iustin Pop
class RpcRunner(object):
419 72737a7f Iustin Pop
  """RPC runner class"""
420 a8083063 Iustin Pop
421 72737a7f Iustin Pop
  def __init__(self, cfg):
422 72737a7f Iustin Pop
    """Initialized the rpc runner.
423 a8083063 Iustin Pop

424 72737a7f Iustin Pop
    @type cfg:  C{config.ConfigWriter}
425 72737a7f Iustin Pop
    @param cfg: the configuration object that will be used to get data
426 72737a7f Iustin Pop
                about the cluster
427 a8083063 Iustin Pop

428 72737a7f Iustin Pop
    """
429 72737a7f Iustin Pop
    self._cfg = cfg
430 a744b676 Manuel Franceschini
    self.port = netutils.GetDaemonPort(constants.NODED)
431 a8083063 Iustin Pop
432 1bdcbbab Iustin Pop
  def _InstDict(self, instance, hvp=None, bep=None, osp=None):
433 26ba2bd8 Iustin Pop
    """Convert the given instance to a dict.
434 26ba2bd8 Iustin Pop

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

438 26ba2bd8 Iustin Pop
    @type instance: L{objects.Instance}
439 26ba2bd8 Iustin Pop
    @param instance: an Instance object
440 0eca8e0c Iustin Pop
    @type hvp: dict or None
441 5bbd3f7f Michael Hanselmann
    @param hvp: a dictionary with overridden hypervisor parameters
442 0eca8e0c Iustin Pop
    @type bep: dict or None
443 5bbd3f7f Michael Hanselmann
    @param bep: a dictionary with overridden backend parameters
444 1bdcbbab Iustin Pop
    @type osp: dict or None
445 8d8c4eff Michael Hanselmann
    @param osp: a dictionary with overridden os parameters
446 26ba2bd8 Iustin Pop
    @rtype: dict
447 26ba2bd8 Iustin Pop
    @return: the instance dict, with the hvparams filled with the
448 26ba2bd8 Iustin Pop
        cluster defaults
449 26ba2bd8 Iustin Pop

450 26ba2bd8 Iustin Pop
    """
451 26ba2bd8 Iustin Pop
    idict = instance.ToDict()
452 5b442704 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
453 5b442704 Iustin Pop
    idict["hvparams"] = cluster.FillHV(instance)
454 0eca8e0c Iustin Pop
    if hvp is not None:
455 0eca8e0c Iustin Pop
      idict["hvparams"].update(hvp)
456 5b442704 Iustin Pop
    idict["beparams"] = cluster.FillBE(instance)
457 0eca8e0c Iustin Pop
    if bep is not None:
458 0eca8e0c Iustin Pop
      idict["beparams"].update(bep)
459 1bdcbbab Iustin Pop
    idict["osparams"] = cluster.SimpleFillOS(instance.os, instance.osparams)
460 1bdcbbab Iustin Pop
    if osp is not None:
461 1bdcbbab Iustin Pop
      idict["osparams"].update(osp)
462 b848ce79 Guido Trotter
    for nic in idict["nics"]:
463 b848ce79 Guido Trotter
      nic['nicparams'] = objects.FillDict(
464 b848ce79 Guido Trotter
        cluster.nicparams[constants.PP_DEFAULT],
465 b848ce79 Guido Trotter
        nic['nicparams'])
466 26ba2bd8 Iustin Pop
    return idict
467 26ba2bd8 Iustin Pop
468 e0036155 Iustin Pop
  def _ConnectList(self, client, node_list, call, read_timeout=None):
469 25348212 Iustin Pop
    """Helper for computing node addresses.
470 25348212 Iustin Pop

471 6af6270a Iustin Pop
    @type client: L{ganeti.rpc.Client}
472 25348212 Iustin Pop
    @param client: a C{Client} instance
473 25348212 Iustin Pop
    @type node_list: list
474 25348212 Iustin Pop
    @param node_list: the node list we should connect
475 84b45587 Iustin Pop
    @type call: string
476 84b45587 Iustin Pop
    @param call: the name of the remote procedure call, for filling in
477 84b45587 Iustin Pop
        correctly any eventual offline nodes' results
478 e0036155 Iustin Pop
    @type read_timeout: int
479 e0036155 Iustin Pop
    @param read_timeout: overwrites the default read timeout for the
480 e0036155 Iustin Pop
        given operation
481 25348212 Iustin Pop

482 25348212 Iustin Pop
    """
483 25348212 Iustin Pop
    all_nodes = self._cfg.GetAllNodesInfo()
484 ed83f5cc Iustin Pop
    name_list = []
485 25348212 Iustin Pop
    addr_list = []
486 ed83f5cc Iustin Pop
    skip_dict = {}
487 25348212 Iustin Pop
    for node in node_list:
488 25348212 Iustin Pop
      if node in all_nodes:
489 ed83f5cc Iustin Pop
        if all_nodes[node].offline:
490 84b45587 Iustin Pop
          skip_dict[node] = RpcResult(node=node, offline=True, call=call)
491 ed83f5cc Iustin Pop
          continue
492 25348212 Iustin Pop
        val = all_nodes[node].primary_ip
493 25348212 Iustin Pop
      else:
494 25348212 Iustin Pop
        val = None
495 25348212 Iustin Pop
      addr_list.append(val)
496 ed83f5cc Iustin Pop
      name_list.append(node)
497 ed83f5cc Iustin Pop
    if name_list:
498 e0036155 Iustin Pop
      client.ConnectList(name_list, address_list=addr_list,
499 e0036155 Iustin Pop
                         read_timeout=read_timeout)
500 ed83f5cc Iustin Pop
    return skip_dict
501 25348212 Iustin Pop
502 e0036155 Iustin Pop
  def _ConnectNode(self, client, node, call, read_timeout=None):
503 25348212 Iustin Pop
    """Helper for computing one node's address.
504 25348212 Iustin Pop

505 6af6270a Iustin Pop
    @type client: L{ganeti.rpc.Client}
506 25348212 Iustin Pop
    @param client: a C{Client} instance
507 25348212 Iustin Pop
    @type node: str
508 25348212 Iustin Pop
    @param node: the node we should connect
509 84b45587 Iustin Pop
    @type call: string
510 84b45587 Iustin Pop
    @param call: the name of the remote procedure call, for filling in
511 84b45587 Iustin Pop
        correctly any eventual offline nodes' results
512 e0036155 Iustin Pop
    @type read_timeout: int
513 e0036155 Iustin Pop
    @param read_timeout: overwrites the default read timeout for the
514 e0036155 Iustin Pop
        given operation
515 25348212 Iustin Pop

516 25348212 Iustin Pop
    """
517 25348212 Iustin Pop
    node_info = self._cfg.GetNodeInfo(node)
518 25348212 Iustin Pop
    if node_info is not None:
519 ed83f5cc Iustin Pop
      if node_info.offline:
520 84b45587 Iustin Pop
        return RpcResult(node=node, offline=True, call=call)
521 25348212 Iustin Pop
      addr = node_info.primary_ip
522 25348212 Iustin Pop
    else:
523 25348212 Iustin Pop
      addr = None
524 e0036155 Iustin Pop
    client.ConnectNode(node, address=addr, read_timeout=read_timeout)
525 25348212 Iustin Pop
526 e0036155 Iustin Pop
  def _MultiNodeCall(self, node_list, procedure, args, read_timeout=None):
527 160e2921 Iustin Pop
    """Helper for making a multi-node call
528 160e2921 Iustin Pop

529 160e2921 Iustin Pop
    """
530 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
531 160e2921 Iustin Pop
    c = Client(procedure, body, self.port)
532 e0036155 Iustin Pop
    skip_dict = self._ConnectList(c, node_list, procedure,
533 e0036155 Iustin Pop
                                  read_timeout=read_timeout)
534 ed83f5cc Iustin Pop
    skip_dict.update(c.GetResults())
535 ed83f5cc Iustin Pop
    return skip_dict
536 9a525d83 Michael Hanselmann
537 9a525d83 Michael Hanselmann
  @classmethod
538 9a525d83 Michael Hanselmann
  def _StaticMultiNodeCall(cls, node_list, procedure, args,
539 e0036155 Iustin Pop
                           address_list=None, read_timeout=None):
540 160e2921 Iustin Pop
    """Helper for making a multi-node static call
541 160e2921 Iustin Pop

542 160e2921 Iustin Pop
    """
543 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
544 a744b676 Manuel Franceschini
    c = Client(procedure, body, netutils.GetDaemonPort(constants.NODED))
545 e0036155 Iustin Pop
    c.ConnectList(node_list, address_list=address_list,
546 e0036155 Iustin Pop
                  read_timeout=read_timeout)
547 9a525d83 Michael Hanselmann
    return c.GetResults()
548 9a525d83 Michael Hanselmann
549 e0036155 Iustin Pop
  def _SingleNodeCall(self, node, procedure, args, read_timeout=None):
550 160e2921 Iustin Pop
    """Helper for making a single-node call
551 9a525d83 Michael Hanselmann

552 9a525d83 Michael Hanselmann
    """
553 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
554 160e2921 Iustin Pop
    c = Client(procedure, body, self.port)
555 e0036155 Iustin Pop
    result = self._ConnectNode(c, node, procedure, read_timeout=read_timeout)
556 ed83f5cc Iustin Pop
    if result is None:
557 ed83f5cc Iustin Pop
      # we did connect, node is not offline
558 ed83f5cc Iustin Pop
      result = c.GetResults()[node]
559 ed83f5cc Iustin Pop
    return result
560 9a525d83 Michael Hanselmann
561 9a525d83 Michael Hanselmann
  @classmethod
562 e0036155 Iustin Pop
  def _StaticSingleNodeCall(cls, node, procedure, args, read_timeout=None):
563 160e2921 Iustin Pop
    """Helper for making a single-node static call
564 9a525d83 Michael Hanselmann

565 9a525d83 Michael Hanselmann
    """
566 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
567 a744b676 Manuel Franceschini
    c = Client(procedure, body, netutils.GetDaemonPort(constants.NODED))
568 e0036155 Iustin Pop
    c.ConnectNode(node, read_timeout=read_timeout)
569 ed83f5cc Iustin Pop
    return c.GetResults()[node]
570 9a525d83 Michael Hanselmann
571 12bce260 Michael Hanselmann
  @staticmethod
572 12bce260 Michael Hanselmann
  def _Compress(data):
573 12bce260 Michael Hanselmann
    """Compresses a string for transport over RPC.
574 12bce260 Michael Hanselmann

575 12bce260 Michael Hanselmann
    Small amounts of data are not compressed.
576 12bce260 Michael Hanselmann

577 12bce260 Michael Hanselmann
    @type data: str
578 12bce260 Michael Hanselmann
    @param data: Data
579 12bce260 Michael Hanselmann
    @rtype: tuple
580 12bce260 Michael Hanselmann
    @return: Encoded data to send
581 12bce260 Michael Hanselmann

582 12bce260 Michael Hanselmann
    """
583 12bce260 Michael Hanselmann
    # Small amounts of data are not compressed
584 12bce260 Michael Hanselmann
    if len(data) < 512:
585 12bce260 Michael Hanselmann
      return (constants.RPC_ENCODING_NONE, data)
586 12bce260 Michael Hanselmann
587 12bce260 Michael Hanselmann
    # Compress with zlib and encode in base64
588 12bce260 Michael Hanselmann
    return (constants.RPC_ENCODING_ZLIB_BASE64,
589 12bce260 Michael Hanselmann
            base64.b64encode(zlib.compress(data, 3)))
590 12bce260 Michael Hanselmann
591 781de953 Iustin Pop
  #
592 781de953 Iustin Pop
  # Begin RPC calls
593 781de953 Iustin Pop
  #
594 781de953 Iustin Pop
595 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
596 b2a6ccd4 Iustin Pop
  def call_lv_list(self, node_list, vg_name):
597 72737a7f Iustin Pop
    """Gets the logical volumes present in a given volume group.
598 a8083063 Iustin Pop

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

601 72737a7f Iustin Pop
    """
602 b2a6ccd4 Iustin Pop
    return self._MultiNodeCall(node_list, "lv_list", [vg_name])
603 a8083063 Iustin Pop
604 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
605 72737a7f Iustin Pop
  def call_vg_list(self, node_list):
606 72737a7f Iustin Pop
    """Gets the volume group list.
607 a8083063 Iustin Pop

608 72737a7f Iustin Pop
    This is a multi-node call.
609 a8083063 Iustin Pop

610 72737a7f Iustin Pop
    """
611 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "vg_list", [])
612 a8083063 Iustin Pop
613 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
614 e337de97 Michael Hanselmann
  def call_storage_list(self, node_list, su_name, su_args, name, fields):
615 8979196a Michael Hanselmann
    """Get list of storage units.
616 e337de97 Michael Hanselmann

617 e337de97 Michael Hanselmann
    This is a multi-node call.
618 e337de97 Michael Hanselmann

619 e337de97 Michael Hanselmann
    """
620 e337de97 Michael Hanselmann
    return self._MultiNodeCall(node_list, "storage_list",
621 e337de97 Michael Hanselmann
                               [su_name, su_args, name, fields])
622 e337de97 Michael Hanselmann
623 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
624 8979196a Michael Hanselmann
  def call_storage_modify(self, node, su_name, su_args, name, changes):
625 8979196a Michael Hanselmann
    """Modify a storage unit.
626 8979196a Michael Hanselmann

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

629 8979196a Michael Hanselmann
    """
630 8979196a Michael Hanselmann
    return self._SingleNodeCall(node, "storage_modify",
631 8979196a Michael Hanselmann
                                [su_name, su_args, name, changes])
632 8979196a Michael Hanselmann
633 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
634 637b8d7e Michael Hanselmann
  def call_storage_execute(self, node, su_name, su_args, name, op):
635 637b8d7e Michael Hanselmann
    """Executes an operation on a storage unit.
636 637b8d7e Michael Hanselmann

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

639 637b8d7e Michael Hanselmann
    """
640 637b8d7e Michael Hanselmann
    return self._SingleNodeCall(node, "storage_execute",
641 637b8d7e Michael Hanselmann
                                [su_name, su_args, name, op])
642 637b8d7e Michael Hanselmann
643 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
644 72737a7f Iustin Pop
  def call_bridges_exist(self, node, bridges_list):
645 72737a7f Iustin Pop
    """Checks if a node has all the bridges given.
646 a8083063 Iustin Pop

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

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

653 72737a7f Iustin Pop
    """
654 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "bridges_exist", [bridges_list])
655 a8083063 Iustin Pop
656 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
657 0eca8e0c Iustin Pop
  def call_instance_start(self, node, instance, hvp, bep):
658 72737a7f Iustin Pop
    """Starts an instance.
659 a8083063 Iustin Pop

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

662 72737a7f Iustin Pop
    """
663 0eca8e0c Iustin Pop
    idict = self._InstDict(instance, hvp=hvp, bep=bep)
664 0eca8e0c Iustin Pop
    return self._SingleNodeCall(node, "instance_start", [idict])
665 a8083063 Iustin Pop
666 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
667 6263189c Guido Trotter
  def call_instance_shutdown(self, node, instance, timeout):
668 72737a7f Iustin Pop
    """Stops an instance.
669 a8083063 Iustin Pop

670 72737a7f Iustin Pop
    This is a single-node call.
671 2a10865c Iustin Pop

672 72737a7f Iustin Pop
    """
673 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_shutdown",
674 6263189c Guido Trotter
                                [self._InstDict(instance), timeout])
675 2a10865c Iustin Pop
676 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
677 6906a9d8 Guido Trotter
  def call_migration_info(self, node, instance):
678 6906a9d8 Guido Trotter
    """Gather the information necessary to prepare an instance migration.
679 6906a9d8 Guido Trotter

680 6906a9d8 Guido Trotter
    This is a single-node call.
681 6906a9d8 Guido Trotter

682 6906a9d8 Guido Trotter
    @type node: string
683 6906a9d8 Guido Trotter
    @param node: the node on which the instance is currently running
684 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
685 6906a9d8 Guido Trotter
    @param instance: the instance definition
686 6906a9d8 Guido Trotter

687 6906a9d8 Guido Trotter
    """
688 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "migration_info",
689 6906a9d8 Guido Trotter
                                [self._InstDict(instance)])
690 6906a9d8 Guido Trotter
691 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
692 6906a9d8 Guido Trotter
  def call_accept_instance(self, node, instance, info, target):
693 6906a9d8 Guido Trotter
    """Prepare a node to accept an instance.
694 6906a9d8 Guido Trotter

695 6906a9d8 Guido Trotter
    This is a single-node call.
696 6906a9d8 Guido Trotter

697 6906a9d8 Guido Trotter
    @type node: string
698 6906a9d8 Guido Trotter
    @param node: the target node for the migration
699 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
700 6906a9d8 Guido Trotter
    @param instance: the instance definition
701 6906a9d8 Guido Trotter
    @type info: opaque/hypervisor specific (string/data)
702 6906a9d8 Guido Trotter
    @param info: result for the call_migration_info call
703 6906a9d8 Guido Trotter
    @type target: string
704 6906a9d8 Guido Trotter
    @param target: target hostname (usually ip address) (on the node itself)
705 6906a9d8 Guido Trotter

706 6906a9d8 Guido Trotter
    """
707 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "accept_instance",
708 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, target])
709 6906a9d8 Guido Trotter
710 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
711 6906a9d8 Guido Trotter
  def call_finalize_migration(self, node, instance, info, success):
712 6906a9d8 Guido Trotter
    """Finalize any target-node migration specific operation.
713 6906a9d8 Guido Trotter

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

717 6906a9d8 Guido Trotter
    This is a single-node call.
718 6906a9d8 Guido Trotter

719 6906a9d8 Guido Trotter
    @type node: string
720 6906a9d8 Guido Trotter
    @param node: the target node for the migration
721 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
722 6906a9d8 Guido Trotter
    @param instance: the instance definition
723 6906a9d8 Guido Trotter
    @type info: opaque/hypervisor specific (string/data)
724 6906a9d8 Guido Trotter
    @param info: result for the call_migration_info call
725 6906a9d8 Guido Trotter
    @type success: boolean
726 6906a9d8 Guido Trotter
    @param success: whether the migration was a success or a failure
727 6906a9d8 Guido Trotter

728 6906a9d8 Guido Trotter
    """
729 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "finalize_migration",
730 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, success])
731 6906a9d8 Guido Trotter
732 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
733 72737a7f Iustin Pop
  def call_instance_migrate(self, node, instance, target, live):
734 72737a7f Iustin Pop
    """Migrate an instance.
735 2a10865c Iustin Pop

736 72737a7f Iustin Pop
    This is a single-node call.
737 2a10865c Iustin Pop

738 72737a7f Iustin Pop
    @type node: string
739 72737a7f Iustin Pop
    @param node: the node on which the instance is currently running
740 72737a7f Iustin Pop
    @type instance: C{objects.Instance}
741 72737a7f Iustin Pop
    @param instance: the instance definition
742 72737a7f Iustin Pop
    @type target: string
743 72737a7f Iustin Pop
    @param target: the target node name
744 72737a7f Iustin Pop
    @type live: boolean
745 72737a7f Iustin Pop
    @param live: whether the migration should be done live or not (the
746 72737a7f Iustin Pop
        interpretation of this parameter is left to the hypervisor)
747 007a2f3e Alexander Schreiber

748 72737a7f Iustin Pop
    """
749 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_migrate",
750 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), target, live])
751 007a2f3e Alexander Schreiber
752 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
753 17c3f802 Guido Trotter
  def call_instance_reboot(self, node, inst, reboot_type, shutdown_timeout):
754 72737a7f Iustin Pop
    """Reboots an instance.
755 007a2f3e Alexander Schreiber

756 72737a7f Iustin Pop
    This is a single-node call.
757 a8083063 Iustin Pop

758 72737a7f Iustin Pop
    """
759 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_reboot",
760 17c3f802 Guido Trotter
                                [self._InstDict(inst), reboot_type,
761 17c3f802 Guido Trotter
                                 shutdown_timeout])
762 a8083063 Iustin Pop
763 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_1DAY)
764 8d8c4eff Michael Hanselmann
  def call_instance_os_add(self, node, inst, reinstall, debug, osparams=None):
765 72737a7f Iustin Pop
    """Installs an OS on the given instance.
766 a8083063 Iustin Pop

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

769 72737a7f Iustin Pop
    """
770 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_os_add",
771 8d8c4eff Michael Hanselmann
                                [self._InstDict(inst, osp=osparams),
772 8d8c4eff Michael Hanselmann
                                 reinstall, debug])
773 decd5f45 Iustin Pop
774 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
775 4a0e011f Iustin Pop
  def call_instance_run_rename(self, node, inst, old_name, debug):
776 72737a7f Iustin Pop
    """Run the OS rename script for an instance.
777 decd5f45 Iustin Pop

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

780 72737a7f Iustin Pop
    """
781 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_run_rename",
782 4a0e011f Iustin Pop
                                [self._InstDict(inst), old_name, debug])
783 a8083063 Iustin Pop
784 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
785 72737a7f Iustin Pop
  def call_instance_info(self, node, instance, hname):
786 72737a7f Iustin Pop
    """Returns information about a single instance.
787 a8083063 Iustin Pop

788 72737a7f Iustin Pop
    This is a single-node call.
789 a8083063 Iustin Pop

790 9a525d83 Michael Hanselmann
    @type node: list
791 9a525d83 Michael Hanselmann
    @param node: the list of nodes to query
792 72737a7f Iustin Pop
    @type instance: string
793 72737a7f Iustin Pop
    @param instance: the instance name
794 72737a7f Iustin Pop
    @type hname: string
795 72737a7f Iustin Pop
    @param hname: the hypervisor type of the instance
796 a8083063 Iustin Pop

797 72737a7f Iustin Pop
    """
798 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_info", [instance, hname])
799 e69d05fd Iustin Pop
800 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
801 56e7640c Iustin Pop
  def call_instance_migratable(self, node, instance):
802 56e7640c Iustin Pop
    """Checks whether the given instance can be migrated.
803 56e7640c Iustin Pop

804 56e7640c Iustin Pop
    This is a single-node call.
805 56e7640c Iustin Pop

806 56e7640c Iustin Pop
    @param node: the node to query
807 56e7640c Iustin Pop
    @type instance: L{objects.Instance}
808 56e7640c Iustin Pop
    @param instance: the instance to check
809 56e7640c Iustin Pop

810 56e7640c Iustin Pop

811 56e7640c Iustin Pop
    """
812 56e7640c Iustin Pop
    return self._SingleNodeCall(node, "instance_migratable",
813 56e7640c Iustin Pop
                                [self._InstDict(instance)])
814 56e7640c Iustin Pop
815 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
816 72737a7f Iustin Pop
  def call_all_instances_info(self, node_list, hypervisor_list):
817 72737a7f Iustin Pop
    """Returns information about all instances on the given nodes.
818 a8083063 Iustin Pop

819 72737a7f Iustin Pop
    This is a multi-node call.
820 a8083063 Iustin Pop

821 72737a7f Iustin Pop
    @type node_list: list
822 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
823 72737a7f Iustin Pop
    @type hypervisor_list: list
824 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
825 a8083063 Iustin Pop

826 72737a7f Iustin Pop
    """
827 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "all_instances_info",
828 9a525d83 Michael Hanselmann
                               [hypervisor_list])
829 e69d05fd Iustin Pop
830 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
831 72737a7f Iustin Pop
  def call_instance_list(self, node_list, hypervisor_list):
832 72737a7f Iustin Pop
    """Returns the list of running instances on a given node.
833 a8083063 Iustin Pop

834 72737a7f Iustin Pop
    This is a multi-node call.
835 a8083063 Iustin Pop

836 72737a7f Iustin Pop
    @type node_list: list
837 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
838 72737a7f Iustin Pop
    @type hypervisor_list: list
839 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
840 16abfbc2 Alexander Schreiber

841 72737a7f Iustin Pop
    """
842 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "instance_list", [hypervisor_list])
843 16abfbc2 Alexander Schreiber
844 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
845 72737a7f Iustin Pop
  def call_node_tcp_ping(self, node, source, target, port, timeout,
846 72737a7f Iustin Pop
                         live_port_needed):
847 72737a7f Iustin Pop
    """Do a TcpPing on the remote node
848 a8083063 Iustin Pop

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

851 72737a7f Iustin Pop
    """
852 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_tcp_ping",
853 9a525d83 Michael Hanselmann
                                [source, target, port, timeout,
854 72737a7f Iustin Pop
                                 live_port_needed])
855 a8083063 Iustin Pop
856 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
857 caad16e2 Iustin Pop
  def call_node_has_ip_address(self, node, address):
858 caad16e2 Iustin Pop
    """Checks if a node has the given IP address.
859 caad16e2 Iustin Pop

860 caad16e2 Iustin Pop
    This is a single-node call.
861 caad16e2 Iustin Pop

862 caad16e2 Iustin Pop
    """
863 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_has_ip_address", [address])
864 a8083063 Iustin Pop
865 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
866 72737a7f Iustin Pop
  def call_node_info(self, node_list, vg_name, hypervisor_type):
867 72737a7f Iustin Pop
    """Return node information.
868 e69d05fd Iustin Pop

869 72737a7f Iustin Pop
    This will return memory information and volume group size and free
870 72737a7f Iustin Pop
    space.
871 a8083063 Iustin Pop

872 72737a7f Iustin Pop
    This is a multi-node call.
873 a8083063 Iustin Pop

874 72737a7f Iustin Pop
    @type node_list: list
875 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
876 c41eea6e Iustin Pop
    @type vg_name: C{string}
877 c41eea6e Iustin Pop
    @param vg_name: the name of the volume group to ask for disk space
878 72737a7f Iustin Pop
        information
879 72737a7f Iustin Pop
    @type hypervisor_type: C{str}
880 72737a7f Iustin Pop
    @param hypervisor_type: the name of the hypervisor to ask for
881 72737a7f Iustin Pop
        memory information
882 a8083063 Iustin Pop

883 72737a7f Iustin Pop
    """
884 070e998b Iustin Pop
    return self._MultiNodeCall(node_list, "node_info",
885 070e998b Iustin Pop
                               [vg_name, hypervisor_type])
886 a8083063 Iustin Pop
887 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
888 19ddc57a Renรฉ Nussbaumer
  def call_etc_hosts_modify(self, node, mode, name, ip):
889 19ddc57a Renรฉ Nussbaumer
    """Modify hosts file with name
890 19ddc57a Renรฉ Nussbaumer

891 19ddc57a Renรฉ Nussbaumer
    @type node: string
892 19ddc57a Renรฉ Nussbaumer
    @param node: The node to call
893 19ddc57a Renรฉ Nussbaumer
    @type mode: string
894 19ddc57a Renรฉ Nussbaumer
    @param mode: The mode to operate. Currently "add" or "remove"
895 19ddc57a Renรฉ Nussbaumer
    @type name: string
896 19ddc57a Renรฉ Nussbaumer
    @param name: The host name to be modified
897 19ddc57a Renรฉ Nussbaumer
    @type ip: string
898 19ddc57a Renรฉ Nussbaumer
    @param ip: The ip of the entry (just valid if mode is "add")
899 19ddc57a Renรฉ Nussbaumer

900 19ddc57a Renรฉ Nussbaumer
    """
901 19ddc57a Renรฉ Nussbaumer
    return self._SingleNodeCall(node, "etc_hosts_modify", [mode, name, ip])
902 19ddc57a Renรฉ Nussbaumer
903 19ddc57a Renรฉ Nussbaumer
  @_RpcTimeout(_TMO_NORMAL)
904 72737a7f Iustin Pop
  def call_node_verify(self, node_list, checkdict, cluster_name):
905 72737a7f Iustin Pop
    """Request verification of given parameters.
906 a8083063 Iustin Pop

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

909 72737a7f Iustin Pop
    """
910 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_verify",
911 9a525d83 Michael Hanselmann
                               [checkdict, cluster_name])
912 a8083063 Iustin Pop
913 9a525d83 Michael Hanselmann
  @classmethod
914 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
915 3583908a Guido Trotter
  def call_node_start_master(cls, node, start_daemons, no_voting):
916 72737a7f Iustin Pop
    """Tells a node to activate itself as a master.
917 a8083063 Iustin Pop

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

920 72737a7f Iustin Pop
    """
921 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_start_master",
922 3583908a Guido Trotter
                                     [start_daemons, no_voting])
923 a8083063 Iustin Pop
924 9a525d83 Michael Hanselmann
  @classmethod
925 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
926 9a525d83 Michael Hanselmann
  def call_node_stop_master(cls, node, stop_daemons):
927 72737a7f Iustin Pop
    """Tells a node to demote itself from master status.
928 a8083063 Iustin Pop

929 72737a7f Iustin Pop
    This is a single-node call.
930 4e071d3b Iustin Pop

931 72737a7f Iustin Pop
    """
932 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_stop_master", [stop_daemons])
933 4e071d3b Iustin Pop
934 9a525d83 Michael Hanselmann
  @classmethod
935 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
936 9a525d83 Michael Hanselmann
  def call_master_info(cls, node_list):
937 72737a7f Iustin Pop
    """Query master info.
938 4e071d3b Iustin Pop

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

941 72737a7f Iustin Pop
    """
942 72737a7f Iustin Pop
    # TODO: should this method query down nodes?
943 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "master_info", [])
944 a8083063 Iustin Pop
945 8f215968 Michael Hanselmann
  @classmethod
946 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
947 8f215968 Michael Hanselmann
  def call_version(cls, node_list):
948 72737a7f Iustin Pop
    """Query node version.
949 a8083063 Iustin Pop

950 72737a7f Iustin Pop
    This is a multi-node call.
951 a8083063 Iustin Pop

952 72737a7f Iustin Pop
    """
953 8f215968 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "version", [])
954 a8083063 Iustin Pop
955 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
956 72737a7f Iustin Pop
  def call_blockdev_create(self, node, bdev, size, owner, on_primary, info):
957 72737a7f Iustin Pop
    """Request creation of a given block device.
958 a8083063 Iustin Pop

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

961 72737a7f Iustin Pop
    """
962 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_create",
963 9a525d83 Michael Hanselmann
                                [bdev.ToDict(), size, owner, on_primary, info])
964 a8083063 Iustin Pop
965 271b7cf9 Renรฉ Nussbaumer
  @_RpcTimeout(_TMO_SLOW)
966 271b7cf9 Renรฉ Nussbaumer
  def call_blockdev_wipe(self, node, bdev, offset, size):
967 271b7cf9 Renรฉ Nussbaumer
    """Request wipe at given offset with given size of a block device.
968 271b7cf9 Renรฉ Nussbaumer

969 271b7cf9 Renรฉ Nussbaumer
    This is a single-node call.
970 271b7cf9 Renรฉ Nussbaumer

971 271b7cf9 Renรฉ Nussbaumer
    """
972 271b7cf9 Renรฉ Nussbaumer
    return self._SingleNodeCall(node, "blockdev_wipe",
973 271b7cf9 Renรฉ Nussbaumer
                                [bdev.ToDict(), offset, size])
974 271b7cf9 Renรฉ Nussbaumer
975 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
976 72737a7f Iustin Pop
  def call_blockdev_remove(self, node, bdev):
977 72737a7f Iustin Pop
    """Request removal of a given block device.
978 a8083063 Iustin Pop

979 72737a7f Iustin Pop
    This is a single-node call.
980 f3e513ad Iustin Pop

981 72737a7f Iustin Pop
    """
982 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_remove", [bdev.ToDict()])
983 f3e513ad Iustin Pop
984 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
985 72737a7f Iustin Pop
  def call_blockdev_rename(self, node, devlist):
986 72737a7f Iustin Pop
    """Request rename of the given block devices.
987 f3e513ad Iustin Pop

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

990 72737a7f Iustin Pop
    """
991 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_rename",
992 9a525d83 Michael Hanselmann
                                [(d.ToDict(), uid) for d, uid in devlist])
993 a8083063 Iustin Pop
994 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
995 72737a7f Iustin Pop
  def call_blockdev_assemble(self, node, disk, owner, on_primary):
996 72737a7f Iustin Pop
    """Request assembling of a given block device.
997 a8083063 Iustin Pop

998 72737a7f Iustin Pop
    This is a single-node call.
999 a8083063 Iustin Pop

1000 72737a7f Iustin Pop
    """
1001 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_assemble",
1002 9a525d83 Michael Hanselmann
                                [disk.ToDict(), owner, on_primary])
1003 a8083063 Iustin Pop
1004 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1005 72737a7f Iustin Pop
  def call_blockdev_shutdown(self, node, disk):
1006 72737a7f Iustin Pop
    """Request shutdown of a given block device.
1007 a8083063 Iustin Pop

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

1010 72737a7f Iustin Pop
    """
1011 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_shutdown", [disk.ToDict()])
1012 a8083063 Iustin Pop
1013 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1014 72737a7f Iustin Pop
  def call_blockdev_addchildren(self, node, bdev, ndevs):
1015 72737a7f Iustin Pop
    """Request adding a list of children to a (mirroring) device.
1016 a8083063 Iustin Pop

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

1019 72737a7f Iustin Pop
    """
1020 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_addchildren",
1021 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
1022 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
1023 a8083063 Iustin Pop
1024 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1025 72737a7f Iustin Pop
  def call_blockdev_removechildren(self, node, bdev, ndevs):
1026 72737a7f Iustin Pop
    """Request removing a list of children from a (mirroring) device.
1027 a8083063 Iustin Pop

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

1030 72737a7f Iustin Pop
    """
1031 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_removechildren",
1032 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
1033 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
1034 a8083063 Iustin Pop
1035 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1036 72737a7f Iustin Pop
  def call_blockdev_getmirrorstatus(self, node, disks):
1037 72737a7f Iustin Pop
    """Request status of a (mirroring) device.
1038 a8083063 Iustin Pop

1039 72737a7f Iustin Pop
    This is a single-node call.
1040 a8083063 Iustin Pop

1041 72737a7f Iustin Pop
    """
1042 36145b12 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_getmirrorstatus",
1043 36145b12 Michael Hanselmann
                                  [dsk.ToDict() for dsk in disks])
1044 edb4b374 Michael Hanselmann
    if not result.fail_msg:
1045 36145b12 Michael Hanselmann
      result.payload = [objects.BlockDevStatus.FromDict(i)
1046 36145b12 Michael Hanselmann
                        for i in result.payload]
1047 36145b12 Michael Hanselmann
    return result
1048 a8083063 Iustin Pop
1049 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1050 b8d26c6e Michael Hanselmann
  def call_blockdev_getmirrorstatus_multi(self, node_list, node_disks):
1051 b8d26c6e Michael Hanselmann
    """Request status of (mirroring) devices from multiple nodes.
1052 b8d26c6e Michael Hanselmann

1053 b8d26c6e Michael Hanselmann
    This is a multi-node call.
1054 b8d26c6e Michael Hanselmann

1055 b8d26c6e Michael Hanselmann
    """
1056 b8d26c6e Michael Hanselmann
    result = self._MultiNodeCall(node_list, "blockdev_getmirrorstatus_multi",
1057 b8d26c6e Michael Hanselmann
                                 [dict((name, [dsk.ToDict() for dsk in disks])
1058 b8d26c6e Michael Hanselmann
                                       for name, disks in node_disks.items())])
1059 b8d26c6e Michael Hanselmann
    for nres in result.values():
1060 c6a9dffa Michael Hanselmann
      if nres.fail_msg:
1061 c6a9dffa Michael Hanselmann
        continue
1062 c6a9dffa Michael Hanselmann
1063 c6a9dffa Michael Hanselmann
      for idx, (success, status) in enumerate(nres.payload):
1064 c6a9dffa Michael Hanselmann
        if success:
1065 c6a9dffa Michael Hanselmann
          nres.payload[idx] = (success, objects.BlockDevStatus.FromDict(status))
1066 c6a9dffa Michael Hanselmann
1067 b8d26c6e Michael Hanselmann
    return result
1068 b8d26c6e Michael Hanselmann
1069 b8d26c6e Michael Hanselmann
  @_RpcTimeout(_TMO_NORMAL)
1070 72737a7f Iustin Pop
  def call_blockdev_find(self, node, disk):
1071 72737a7f Iustin Pop
    """Request identification of a given block device.
1072 72737a7f Iustin Pop

1073 72737a7f Iustin Pop
    This is a single-node call.
1074 a8083063 Iustin Pop

1075 72737a7f Iustin Pop
    """
1076 96acbc09 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_find", [disk.ToDict()])
1077 edb4b374 Michael Hanselmann
    if not result.fail_msg and result.payload is not None:
1078 96acbc09 Michael Hanselmann
      result.payload = objects.BlockDevStatus.FromDict(result.payload)
1079 96acbc09 Michael Hanselmann
    return result
1080 d61cbe76 Iustin Pop
1081 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1082 b2e7666a Iustin Pop
  def call_blockdev_close(self, node, instance_name, disks):
1083 72737a7f Iustin Pop
    """Closes the given block devices.
1084 d61cbe76 Iustin Pop

1085 72737a7f Iustin Pop
    This is a single-node call.
1086 d61cbe76 Iustin Pop

1087 72737a7f Iustin Pop
    """
1088 b2e7666a Iustin Pop
    params = [instance_name, [cf.ToDict() for cf in disks]]
1089 b2e7666a Iustin Pop
    return self._SingleNodeCall(node, "blockdev_close", params)
1090 a8083063 Iustin Pop
1091 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1092 968a7623 Iustin Pop
  def call_blockdev_getsizes(self, node, disks):
1093 968a7623 Iustin Pop
    """Returns the size of the given disks.
1094 968a7623 Iustin Pop

1095 968a7623 Iustin Pop
    This is a single-node call.
1096 968a7623 Iustin Pop

1097 968a7623 Iustin Pop
    """
1098 968a7623 Iustin Pop
    params = [[cf.ToDict() for cf in disks]]
1099 968a7623 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_getsize", params)
1100 968a7623 Iustin Pop
1101 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1102 6b93ec9d Iustin Pop
  def call_drbd_disconnect_net(self, node_list, nodes_ip, disks):
1103 6b93ec9d Iustin Pop
    """Disconnects the network of the given drbd devices.
1104 6b93ec9d Iustin Pop

1105 6b93ec9d Iustin Pop
    This is a multi-node call.
1106 6b93ec9d Iustin Pop

1107 6b93ec9d Iustin Pop
    """
1108 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_disconnect_net",
1109 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1110 6b93ec9d Iustin Pop
1111 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1112 6b93ec9d Iustin Pop
  def call_drbd_attach_net(self, node_list, nodes_ip,
1113 6b93ec9d Iustin Pop
                           disks, instance_name, multimaster):
1114 6b93ec9d Iustin Pop
    """Disconnects the given drbd devices.
1115 6b93ec9d Iustin Pop

1116 6b93ec9d Iustin Pop
    This is a multi-node call.
1117 6b93ec9d Iustin Pop

1118 6b93ec9d Iustin Pop
    """
1119 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_attach_net",
1120 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks],
1121 6b93ec9d Iustin Pop
                                instance_name, multimaster])
1122 6b93ec9d Iustin Pop
1123 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
1124 6b93ec9d Iustin Pop
  def call_drbd_wait_sync(self, node_list, nodes_ip, disks):
1125 6b93ec9d Iustin Pop
    """Waits for the synchronization of drbd devices is complete.
1126 6b93ec9d Iustin Pop

1127 6b93ec9d Iustin Pop
    This is a multi-node call.
1128 6b93ec9d Iustin Pop

1129 6b93ec9d Iustin Pop
    """
1130 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_wait_sync",
1131 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1132 6b93ec9d Iustin Pop
1133 c46b9782 Luca Bigliardi
  @_RpcTimeout(_TMO_URGENT)
1134 c46b9782 Luca Bigliardi
  def call_drbd_helper(self, node_list):
1135 c46b9782 Luca Bigliardi
    """Gets drbd helper.
1136 c46b9782 Luca Bigliardi

1137 c46b9782 Luca Bigliardi
    This is a multi-node call.
1138 c46b9782 Luca Bigliardi

1139 c46b9782 Luca Bigliardi
    """
1140 c46b9782 Luca Bigliardi
    return self._MultiNodeCall(node_list, "drbd_helper", [])
1141 c46b9782 Luca Bigliardi
1142 9a525d83 Michael Hanselmann
  @classmethod
1143 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1144 9a525d83 Michael Hanselmann
  def call_upload_file(cls, node_list, file_name, address_list=None):
1145 72737a7f Iustin Pop
    """Upload a file.
1146 72737a7f Iustin Pop

1147 72737a7f Iustin Pop
    The node will refuse the operation in case the file is not on the
1148 72737a7f Iustin Pop
    approved file list.
1149 72737a7f Iustin Pop

1150 72737a7f Iustin Pop
    This is a multi-node call.
1151 a8083063 Iustin Pop

1152 6b294c53 Iustin Pop
    @type node_list: list
1153 6b294c53 Iustin Pop
    @param node_list: the list of node names to upload to
1154 6b294c53 Iustin Pop
    @type file_name: str
1155 6b294c53 Iustin Pop
    @param file_name: the filename to upload
1156 6b294c53 Iustin Pop
    @type address_list: list or None
1157 6b294c53 Iustin Pop
    @keyword address_list: an optional list of node addresses, in order
1158 6b294c53 Iustin Pop
        to optimize the RPC speed
1159 6b294c53 Iustin Pop

1160 72737a7f Iustin Pop
    """
1161 12bce260 Michael Hanselmann
    file_contents = utils.ReadFile(file_name)
1162 12bce260 Michael Hanselmann
    data = cls._Compress(file_contents)
1163 72737a7f Iustin Pop
    st = os.stat(file_name)
1164 72737a7f Iustin Pop
    params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
1165 72737a7f Iustin Pop
              st.st_atime, st.st_mtime]
1166 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "upload_file", params,
1167 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1168 72737a7f Iustin Pop
1169 6ddc95ec Michael Hanselmann
  @classmethod
1170 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1171 03d1dba2 Michael Hanselmann
  def call_write_ssconf_files(cls, node_list, values):
1172 6ddc95ec Michael Hanselmann
    """Write ssconf files.
1173 6ddc95ec Michael Hanselmann

1174 6ddc95ec Michael Hanselmann
    This is a multi-node call.
1175 6ddc95ec Michael Hanselmann

1176 6ddc95ec Michael Hanselmann
    """
1177 03d1dba2 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "write_ssconf_files", [values])
1178 6ddc95ec Michael Hanselmann
1179 4f6014d4 Renรฉ Nussbaumer
  @_RpcTimeout(_TMO_NORMAL)
1180 4f6014d4 Renรฉ Nussbaumer
  def call_run_oob(self, node, oob_program, command, remote_node):
1181 4f6014d4 Renรฉ Nussbaumer
    """Runs OOB.
1182 4f6014d4 Renรฉ Nussbaumer

1183 4f6014d4 Renรฉ Nussbaumer
    This is a single-node call.
1184 4f6014d4 Renรฉ Nussbaumer

1185 4f6014d4 Renรฉ Nussbaumer
    """
1186 4f6014d4 Renรฉ Nussbaumer
    return self._SingleNodeCall(node, "run_oob", [oob_program, command,
1187 4f6014d4 Renรฉ Nussbaumer
                                                  remote_node])
1188 4f6014d4 Renรฉ Nussbaumer
1189 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1190 72737a7f Iustin Pop
  def call_os_diagnose(self, node_list):
1191 72737a7f Iustin Pop
    """Request a diagnose of OS definitions.
1192 72737a7f Iustin Pop

1193 72737a7f Iustin Pop
    This is a multi-node call.
1194 a8083063 Iustin Pop

1195 72737a7f Iustin Pop
    """
1196 83d92ad8 Iustin Pop
    return self._MultiNodeCall(node_list, "os_diagnose", [])
1197 a8083063 Iustin Pop
1198 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1199 72737a7f Iustin Pop
  def call_os_get(self, node, name):
1200 72737a7f Iustin Pop
    """Returns an OS definition.
1201 a8083063 Iustin Pop

1202 72737a7f Iustin Pop
    This is a single-node call.
1203 a8083063 Iustin Pop

1204 72737a7f Iustin Pop
    """
1205 9a525d83 Michael Hanselmann
    result = self._SingleNodeCall(node, "os_get", [name])
1206 84e3f66f Guido Trotter
    if not result.fail_msg and isinstance(result.payload, dict):
1207 84e3f66f Guido Trotter
      result.payload = objects.OS.FromDict(result.payload)
1208 781de953 Iustin Pop
    return result
1209 a8083063 Iustin Pop
1210 acd9ff9e Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1211 acd9ff9e Iustin Pop
  def call_os_validate(self, required, nodes, name, checks, params):
1212 acd9ff9e Iustin Pop
    """Run a validation routine for a given OS.
1213 acd9ff9e Iustin Pop

1214 acd9ff9e Iustin Pop
    This is a multi-node call.
1215 acd9ff9e Iustin Pop

1216 acd9ff9e Iustin Pop
    """
1217 acd9ff9e Iustin Pop
    return self._MultiNodeCall(nodes, "os_validate",
1218 acd9ff9e Iustin Pop
                               [required, name, checks, params])
1219 acd9ff9e Iustin Pop
1220 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1221 72737a7f Iustin Pop
  def call_hooks_runner(self, node_list, hpath, phase, env):
1222 72737a7f Iustin Pop
    """Call the hooks runner.
1223 a8083063 Iustin Pop

1224 72737a7f Iustin Pop
    Args:
1225 72737a7f Iustin Pop
      - op: the OpCode instance
1226 72737a7f Iustin Pop
      - env: a dictionary with the environment
1227 a8083063 Iustin Pop

1228 72737a7f Iustin Pop
    This is a multi-node call.
1229 a8083063 Iustin Pop

1230 72737a7f Iustin Pop
    """
1231 72737a7f Iustin Pop
    params = [hpath, phase, env]
1232 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hooks_runner", params)
1233 a8083063 Iustin Pop
1234 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1235 72737a7f Iustin Pop
  def call_iallocator_runner(self, node, name, idata):
1236 72737a7f Iustin Pop
    """Call an iallocator on a remote node
1237 8d528b7c Iustin Pop

1238 72737a7f Iustin Pop
    Args:
1239 72737a7f Iustin Pop
      - name: the iallocator name
1240 72737a7f Iustin Pop
      - input: the json-encoded input string
1241 8d528b7c Iustin Pop

1242 72737a7f Iustin Pop
    This is a single-node call.
1243 8d528b7c Iustin Pop

1244 72737a7f Iustin Pop
    """
1245 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "iallocator_runner", [name, idata])
1246 8d528b7c Iustin Pop
1247 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1248 72737a7f Iustin Pop
  def call_blockdev_grow(self, node, cf_bdev, amount):
1249 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1250 4c8ba8b3 Iustin Pop

1251 72737a7f Iustin Pop
    This is a single-node call.
1252 4c8ba8b3 Iustin Pop

1253 72737a7f Iustin Pop
    """
1254 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_grow",
1255 9a525d83 Michael Hanselmann
                                [cf_bdev.ToDict(), amount])
1256 4c8ba8b3 Iustin Pop
1257 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_1DAY)
1258 858f3d18 Iustin Pop
  def call_blockdev_export(self, node, cf_bdev,
1259 858f3d18 Iustin Pop
                           dest_node, dest_path, cluster_name):
1260 858f3d18 Iustin Pop
    """Export a given disk to another node.
1261 858f3d18 Iustin Pop

1262 858f3d18 Iustin Pop
    This is a single-node call.
1263 858f3d18 Iustin Pop

1264 858f3d18 Iustin Pop
    """
1265 858f3d18 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_export",
1266 858f3d18 Iustin Pop
                                [cf_bdev.ToDict(), dest_node, dest_path,
1267 858f3d18 Iustin Pop
                                 cluster_name])
1268 858f3d18 Iustin Pop
1269 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1270 72737a7f Iustin Pop
  def call_blockdev_snapshot(self, node, cf_bdev):
1271 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1272 a8083063 Iustin Pop

1273 72737a7f Iustin Pop
    This is a single-node call.
1274 a8083063 Iustin Pop

1275 72737a7f Iustin Pop
    """
1276 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_snapshot", [cf_bdev.ToDict()])
1277 a8083063 Iustin Pop
1278 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1279 72737a7f Iustin Pop
  def call_finalize_export(self, node, instance, snap_disks):
1280 72737a7f Iustin Pop
    """Request the completion of an export operation.
1281 a8083063 Iustin Pop

1282 72737a7f Iustin Pop
    This writes the export config file, etc.
1283 a8083063 Iustin Pop

1284 72737a7f Iustin Pop
    This is a single-node call.
1285 a8083063 Iustin Pop

1286 72737a7f Iustin Pop
    """
1287 72737a7f Iustin Pop
    flat_disks = []
1288 72737a7f Iustin Pop
    for disk in snap_disks:
1289 a97da6b7 Iustin Pop
      if isinstance(disk, bool):
1290 a97da6b7 Iustin Pop
        flat_disks.append(disk)
1291 a97da6b7 Iustin Pop
      else:
1292 a97da6b7 Iustin Pop
        flat_disks.append(disk.ToDict())
1293 9a525d83 Michael Hanselmann
1294 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "finalize_export",
1295 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), flat_disks])
1296 a8083063 Iustin Pop
1297 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1298 72737a7f Iustin Pop
  def call_export_info(self, node, path):
1299 72737a7f Iustin Pop
    """Queries the export information in a given path.
1300 a8083063 Iustin Pop

1301 72737a7f Iustin Pop
    This is a single-node call.
1302 a8083063 Iustin Pop

1303 72737a7f Iustin Pop
    """
1304 3eccac06 Iustin Pop
    return self._SingleNodeCall(node, "export_info", [path])
1305 a8083063 Iustin Pop
1306 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1307 72737a7f Iustin Pop
  def call_export_list(self, node_list):
1308 72737a7f Iustin Pop
    """Gets the stored exports list.
1309 a8083063 Iustin Pop

1310 72737a7f Iustin Pop
    This is a multi-node call.
1311 a8083063 Iustin Pop

1312 72737a7f Iustin Pop
    """
1313 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "export_list", [])
1314 a8083063 Iustin Pop
1315 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1316 72737a7f Iustin Pop
  def call_export_remove(self, node, export):
1317 72737a7f Iustin Pop
    """Requests removal of a given export.
1318 a8083063 Iustin Pop

1319 72737a7f Iustin Pop
    This is a single-node call.
1320 a8083063 Iustin Pop

1321 72737a7f Iustin Pop
    """
1322 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "export_remove", [export])
1323 a8083063 Iustin Pop
1324 9a525d83 Michael Hanselmann
  @classmethod
1325 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1326 b989b9d9 Ken Wehr
  def call_node_leave_cluster(cls, node, modify_ssh_setup):
1327 72737a7f Iustin Pop
    """Requests a node to clean the cluster information it has.
1328 a8083063 Iustin Pop

1329 72737a7f Iustin Pop
    This will remove the configuration information from the ganeti data
1330 72737a7f Iustin Pop
    dir.
1331 a8083063 Iustin Pop

1332 72737a7f Iustin Pop
    This is a single-node call.
1333 a8083063 Iustin Pop

1334 72737a7f Iustin Pop
    """
1335 b989b9d9 Ken Wehr
    return cls._StaticSingleNodeCall(node, "node_leave_cluster",
1336 b989b9d9 Ken Wehr
                                     [modify_ssh_setup])
1337 dcb93971 Michael Hanselmann
1338 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1339 72737a7f Iustin Pop
  def call_node_volumes(self, node_list):
1340 72737a7f Iustin Pop
    """Gets all volumes on node(s).
1341 dcb93971 Michael Hanselmann

1342 72737a7f Iustin Pop
    This is a multi-node call.
1343 dcb93971 Michael Hanselmann

1344 72737a7f Iustin Pop
    """
1345 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_volumes", [])
1346 06009e27 Iustin Pop
1347 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1348 56aa9fd5 Iustin Pop
  def call_node_demote_from_mc(self, node):
1349 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
1350 56aa9fd5 Iustin Pop

1351 56aa9fd5 Iustin Pop
    This is a single-node call.
1352 56aa9fd5 Iustin Pop

1353 56aa9fd5 Iustin Pop
    """
1354 56aa9fd5 Iustin Pop
    return self._SingleNodeCall(node, "node_demote_from_mc", [])
1355 56aa9fd5 Iustin Pop
1356 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1357 f5118ade Iustin Pop
  def call_node_powercycle(self, node, hypervisor):
1358 f5118ade Iustin Pop
    """Tries to powercycle a node.
1359 f5118ade Iustin Pop

1360 f5118ade Iustin Pop
    This is a single-node call.
1361 f5118ade Iustin Pop

1362 f5118ade Iustin Pop
    """
1363 f5118ade Iustin Pop
    return self._SingleNodeCall(node, "node_powercycle", [hypervisor])
1364 f5118ade Iustin Pop
1365 92fd2250 Iustin Pop
  @_RpcTimeout(None)
1366 72737a7f Iustin Pop
  def call_test_delay(self, node_list, duration):
1367 72737a7f Iustin Pop
    """Sleep for a fixed time on given node(s).
1368 06009e27 Iustin Pop

1369 72737a7f Iustin Pop
    This is a multi-node call.
1370 06009e27 Iustin Pop

1371 72737a7f Iustin Pop
    """
1372 92fd2250 Iustin Pop
    return self._MultiNodeCall(node_list, "test_delay", [duration],
1373 92fd2250 Iustin Pop
                               read_timeout=int(duration + 5))
1374 5e04ed8b Manuel Franceschini
1375 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1376 72737a7f Iustin Pop
  def call_file_storage_dir_create(self, node, file_storage_dir):
1377 72737a7f Iustin Pop
    """Create the given file storage directory.
1378 5e04ed8b Manuel Franceschini

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

1381 72737a7f Iustin Pop
    """
1382 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_create",
1383 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1384 5e04ed8b Manuel Franceschini
1385 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1386 72737a7f Iustin Pop
  def call_file_storage_dir_remove(self, node, file_storage_dir):
1387 72737a7f Iustin Pop
    """Remove the given file storage directory.
1388 5e04ed8b Manuel Franceschini

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

1391 72737a7f Iustin Pop
    """
1392 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_remove",
1393 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1394 5e04ed8b Manuel Franceschini
1395 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1396 72737a7f Iustin Pop
  def call_file_storage_dir_rename(self, node, old_file_storage_dir,
1397 72737a7f Iustin Pop
                                   new_file_storage_dir):
1398 72737a7f Iustin Pop
    """Rename file storage directory.
1399 5e04ed8b Manuel Franceschini

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

1402 72737a7f Iustin Pop
    """
1403 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_rename",
1404 9a525d83 Michael Hanselmann
                                [old_file_storage_dir, new_file_storage_dir])
1405 ca52cdeb Michael Hanselmann
1406 9a525d83 Michael Hanselmann
  @classmethod
1407 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1408 9a525d83 Michael Hanselmann
  def call_jobqueue_update(cls, node_list, address_list, file_name, content):
1409 72737a7f Iustin Pop
    """Update job queue.
1410 ca52cdeb Michael Hanselmann

1411 72737a7f Iustin Pop
    This is a multi-node call.
1412 ca52cdeb Michael Hanselmann

1413 72737a7f Iustin Pop
    """
1414 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_update",
1415 12bce260 Michael Hanselmann
                                    [file_name, cls._Compress(content)],
1416 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1417 ca52cdeb Michael Hanselmann
1418 9a525d83 Michael Hanselmann
  @classmethod
1419 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1420 9a525d83 Michael Hanselmann
  def call_jobqueue_purge(cls, node):
1421 72737a7f Iustin Pop
    """Purge job queue.
1422 ca52cdeb Michael Hanselmann

1423 72737a7f Iustin Pop
    This is a single-node call.
1424 ca52cdeb Michael Hanselmann

1425 72737a7f Iustin Pop
    """
1426 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "jobqueue_purge", [])
1427 af5ebcb1 Michael Hanselmann
1428 9a525d83 Michael Hanselmann
  @classmethod
1429 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1430 dd875d32 Michael Hanselmann
  def call_jobqueue_rename(cls, node_list, address_list, rename):
1431 72737a7f Iustin Pop
    """Rename a job queue file.
1432 af5ebcb1 Michael Hanselmann

1433 72737a7f Iustin Pop
    This is a multi-node call.
1434 af5ebcb1 Michael Hanselmann

1435 72737a7f Iustin Pop
    """
1436 dd875d32 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_rename", rename,
1437 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1438 6217e295 Iustin Pop
1439 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1440 6217e295 Iustin Pop
  def call_hypervisor_validate_params(self, node_list, hvname, hvparams):
1441 6217e295 Iustin Pop
    """Validate the hypervisor params.
1442 6217e295 Iustin Pop

1443 6217e295 Iustin Pop
    This is a multi-node call.
1444 6217e295 Iustin Pop

1445 6217e295 Iustin Pop
    @type node_list: list
1446 6217e295 Iustin Pop
    @param node_list: the list of nodes to query
1447 6217e295 Iustin Pop
    @type hvname: string
1448 6217e295 Iustin Pop
    @param hvname: the hypervisor name
1449 6217e295 Iustin Pop
    @type hvparams: dict
1450 6217e295 Iustin Pop
    @param hvparams: the hypervisor parameters to be validated
1451 6217e295 Iustin Pop

1452 6217e295 Iustin Pop
    """
1453 6217e295 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
1454 abe609b2 Guido Trotter
    hv_full = objects.FillDict(cluster.hvparams.get(hvname, {}), hvparams)
1455 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hypervisor_validate_params",
1456 9a525d83 Michael Hanselmann
                               [hvname, hv_full])
1457 f942a838 Michael Hanselmann
1458 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1459 37549316 Michael Hanselmann
  def call_x509_cert_create(self, node, validity):
1460 f942a838 Michael Hanselmann
    """Creates a new X509 certificate for SSL/TLS.
1461 f942a838 Michael Hanselmann

1462 f942a838 Michael Hanselmann
    This is a single-node call.
1463 f942a838 Michael Hanselmann

1464 f942a838 Michael Hanselmann
    @type validity: int
1465 f942a838 Michael Hanselmann
    @param validity: Validity in seconds
1466 f942a838 Michael Hanselmann

1467 f942a838 Michael Hanselmann
    """
1468 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_create", [validity])
1469 f942a838 Michael Hanselmann
1470 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1471 37549316 Michael Hanselmann
  def call_x509_cert_remove(self, node, name):
1472 f942a838 Michael Hanselmann
    """Removes a X509 certificate.
1473 f942a838 Michael Hanselmann

1474 f942a838 Michael Hanselmann
    This is a single-node call.
1475 f942a838 Michael Hanselmann

1476 f942a838 Michael Hanselmann
    @type name: string
1477 f942a838 Michael Hanselmann
    @param name: Certificate name
1478 f942a838 Michael Hanselmann

1479 f942a838 Michael Hanselmann
    """
1480 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_remove", [name])
1481 1651d116 Michael Hanselmann
1482 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1483 eb630f50 Michael Hanselmann
  def call_import_start(self, node, opts, instance, dest, dest_args):
1484 1651d116 Michael Hanselmann
    """Starts a listener for an import.
1485 1651d116 Michael Hanselmann

1486 1651d116 Michael Hanselmann
    This is a single-node call.
1487 1651d116 Michael Hanselmann

1488 1651d116 Michael Hanselmann
    @type node: string
1489 1651d116 Michael Hanselmann
    @param node: Node name
1490 1651d116 Michael Hanselmann
    @type instance: C{objects.Instance}
1491 1651d116 Michael Hanselmann
    @param instance: Instance object
1492 1651d116 Michael Hanselmann

1493 1651d116 Michael Hanselmann
    """
1494 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "import_start",
1495 eb630f50 Michael Hanselmann
                                [opts.ToDict(),
1496 1651d116 Michael Hanselmann
                                 self._InstDict(instance), dest,
1497 1651d116 Michael Hanselmann
                                 _EncodeImportExportIO(dest, dest_args)])
1498 1651d116 Michael Hanselmann
1499 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1500 eb630f50 Michael Hanselmann
  def call_export_start(self, node, opts, host, port,
1501 1651d116 Michael Hanselmann
                        instance, source, source_args):
1502 1651d116 Michael Hanselmann
    """Starts an export daemon.
1503 1651d116 Michael Hanselmann

1504 1651d116 Michael Hanselmann
    This is a single-node call.
1505 1651d116 Michael Hanselmann

1506 1651d116 Michael Hanselmann
    @type node: string
1507 1651d116 Michael Hanselmann
    @param node: Node name
1508 1651d116 Michael Hanselmann
    @type instance: C{objects.Instance}
1509 1651d116 Michael Hanselmann
    @param instance: Instance object
1510 1651d116 Michael Hanselmann

1511 1651d116 Michael Hanselmann
    """
1512 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "export_start",
1513 eb630f50 Michael Hanselmann
                                [opts.ToDict(), host, port,
1514 1651d116 Michael Hanselmann
                                 self._InstDict(instance), source,
1515 1651d116 Michael Hanselmann
                                 _EncodeImportExportIO(source, source_args)])
1516 1651d116 Michael Hanselmann
1517 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1518 ef40fbfb Michael Hanselmann
  def call_impexp_status(self, node, names):
1519 1651d116 Michael Hanselmann
    """Gets the status of an import or export.
1520 1651d116 Michael Hanselmann

1521 1651d116 Michael Hanselmann
    This is a single-node call.
1522 1651d116 Michael Hanselmann

1523 1651d116 Michael Hanselmann
    @type node: string
1524 1651d116 Michael Hanselmann
    @param node: Node name
1525 1651d116 Michael Hanselmann
    @type names: List of strings
1526 1651d116 Michael Hanselmann
    @param names: Import/export names
1527 1651d116 Michael Hanselmann
    @rtype: List of L{objects.ImportExportStatus} instances
1528 1651d116 Michael Hanselmann
    @return: Returns a list of the state of each named import/export or None if
1529 1651d116 Michael Hanselmann
             a status couldn't be retrieved
1530 1651d116 Michael Hanselmann

1531 1651d116 Michael Hanselmann
    """
1532 ef40fbfb Michael Hanselmann
    result = self._SingleNodeCall(node, "impexp_status", [names])
1533 1651d116 Michael Hanselmann
1534 1651d116 Michael Hanselmann
    if not result.fail_msg:
1535 1651d116 Michael Hanselmann
      decoded = []
1536 1651d116 Michael Hanselmann
1537 1651d116 Michael Hanselmann
      for i in result.payload:
1538 1651d116 Michael Hanselmann
        if i is None:
1539 1651d116 Michael Hanselmann
          decoded.append(None)
1540 1651d116 Michael Hanselmann
          continue
1541 1651d116 Michael Hanselmann
        decoded.append(objects.ImportExportStatus.FromDict(i))
1542 1651d116 Michael Hanselmann
1543 1651d116 Michael Hanselmann
      result.payload = decoded
1544 1651d116 Michael Hanselmann
1545 1651d116 Michael Hanselmann
    return result
1546 1651d116 Michael Hanselmann
1547 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1548 f81c4737 Michael Hanselmann
  def call_impexp_abort(self, node, name):
1549 f81c4737 Michael Hanselmann
    """Aborts an import or export.
1550 f81c4737 Michael Hanselmann

1551 f81c4737 Michael Hanselmann
    This is a single-node call.
1552 f81c4737 Michael Hanselmann

1553 f81c4737 Michael Hanselmann
    @type node: string
1554 f81c4737 Michael Hanselmann
    @param node: Node name
1555 f81c4737 Michael Hanselmann
    @type name: string
1556 f81c4737 Michael Hanselmann
    @param name: Import/export name
1557 f81c4737 Michael Hanselmann

1558 f81c4737 Michael Hanselmann
    """
1559 f81c4737 Michael Hanselmann
    return self._SingleNodeCall(node, "impexp_abort", [name])
1560 f81c4737 Michael Hanselmann
1561 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1562 ef40fbfb Michael Hanselmann
  def call_impexp_cleanup(self, node, name):
1563 1651d116 Michael Hanselmann
    """Cleans up after an import or export.
1564 1651d116 Michael Hanselmann

1565 1651d116 Michael Hanselmann
    This is a single-node call.
1566 1651d116 Michael Hanselmann

1567 1651d116 Michael Hanselmann
    @type node: string
1568 1651d116 Michael Hanselmann
    @param node: Node name
1569 1651d116 Michael Hanselmann
    @type name: string
1570 1651d116 Michael Hanselmann
    @param name: Import/export name
1571 1651d116 Michael Hanselmann

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