Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ 4e272d8c

History | View | Annotate | Download (46.7 kB)

1 2f31098c Iustin Pop
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 d2cd6944 Iustin Pop
# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 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 2c0f74f2 Iustin Pop
    for attr_name in ["call", "data", "fail_msg",
230 2c0f74f2 Iustin Pop
                      "node", "offline", "payload"]:
231 2c0f74f2 Iustin Pop
      assert hasattr(self, attr_name), "Missing attribute %s" % attr_name
232 1645d22d Michael Hanselmann
233 d3c8b360 Iustin Pop
  @staticmethod
234 d3c8b360 Iustin Pop
  def _EnsureErr(val):
235 d3c8b360 Iustin Pop
    """Helper to ensure we return a 'True' value for error."""
236 d3c8b360 Iustin Pop
    if val:
237 d3c8b360 Iustin Pop
      return val
238 d3c8b360 Iustin Pop
    else:
239 d3c8b360 Iustin Pop
      return "No error information"
240 781de953 Iustin Pop
241 045dd6d9 Iustin Pop
  def Raise(self, msg, prereq=False, ecode=None):
242 781de953 Iustin Pop
    """If the result has failed, raise an OpExecError.
243 781de953 Iustin Pop

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

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

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

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

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

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

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

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

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

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

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

369 ecfe9491 Michael Hanselmann
    @rtype: list
370 5fcc718f Iustin Pop
    @return: List of RPC results
371 a8083063 Iustin Pop

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

572 12bce260 Michael Hanselmann
    Small amounts of data are not compressed.
573 12bce260 Michael Hanselmann

574 12bce260 Michael Hanselmann
    @type data: str
575 12bce260 Michael Hanselmann
    @param data: Data
576 12bce260 Michael Hanselmann
    @rtype: tuple
577 12bce260 Michael Hanselmann
    @return: Encoded data to send
578 12bce260 Michael Hanselmann

579 12bce260 Michael Hanselmann
    """
580 12bce260 Michael Hanselmann
    # Small amounts of data are not compressed
581 12bce260 Michael Hanselmann
    if len(data) < 512:
582 12bce260 Michael Hanselmann
      return (constants.RPC_ENCODING_NONE, data)
583 12bce260 Michael Hanselmann
584 12bce260 Michael Hanselmann
    # Compress with zlib and encode in base64
585 12bce260 Michael Hanselmann
    return (constants.RPC_ENCODING_ZLIB_BASE64,
586 12bce260 Michael Hanselmann
            base64.b64encode(zlib.compress(data, 3)))
587 12bce260 Michael Hanselmann
588 781de953 Iustin Pop
  #
589 781de953 Iustin Pop
  # Begin RPC calls
590 781de953 Iustin Pop
  #
591 781de953 Iustin Pop
592 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
593 2be7273c Apollon Oikonomopoulos
  def call_bdev_sizes(self, node_list, devices):
594 2be7273c Apollon Oikonomopoulos
    """Gets the sizes of requested block devices present on a node
595 2be7273c Apollon Oikonomopoulos

596 2be7273c Apollon Oikonomopoulos
    This is a multi-node call.
597 2be7273c Apollon Oikonomopoulos

598 2be7273c Apollon Oikonomopoulos
    """
599 2be7273c Apollon Oikonomopoulos
    return self._MultiNodeCall(node_list, "bdev_sizes", [devices])
600 2be7273c Apollon Oikonomopoulos
601 2be7273c Apollon Oikonomopoulos
  @_RpcTimeout(_TMO_URGENT)
602 b2a6ccd4 Iustin Pop
  def call_lv_list(self, node_list, vg_name):
603 72737a7f Iustin Pop
    """Gets the logical volumes present in a given volume group.
604 a8083063 Iustin Pop

605 72737a7f Iustin Pop
    This is a multi-node call.
606 a8083063 Iustin Pop

607 72737a7f Iustin Pop
    """
608 b2a6ccd4 Iustin Pop
    return self._MultiNodeCall(node_list, "lv_list", [vg_name])
609 a8083063 Iustin Pop
610 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
611 72737a7f Iustin Pop
  def call_vg_list(self, node_list):
612 72737a7f Iustin Pop
    """Gets the volume group list.
613 a8083063 Iustin Pop

614 72737a7f Iustin Pop
    This is a multi-node call.
615 a8083063 Iustin Pop

616 72737a7f Iustin Pop
    """
617 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "vg_list", [])
618 a8083063 Iustin Pop
619 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
620 e337de97 Michael Hanselmann
  def call_storage_list(self, node_list, su_name, su_args, name, fields):
621 8979196a Michael Hanselmann
    """Get list of storage units.
622 e337de97 Michael Hanselmann

623 e337de97 Michael Hanselmann
    This is a multi-node call.
624 e337de97 Michael Hanselmann

625 e337de97 Michael Hanselmann
    """
626 e337de97 Michael Hanselmann
    return self._MultiNodeCall(node_list, "storage_list",
627 e337de97 Michael Hanselmann
                               [su_name, su_args, name, fields])
628 e337de97 Michael Hanselmann
629 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
630 8979196a Michael Hanselmann
  def call_storage_modify(self, node, su_name, su_args, name, changes):
631 8979196a Michael Hanselmann
    """Modify a storage unit.
632 8979196a Michael Hanselmann

633 8979196a Michael Hanselmann
    This is a single-node call.
634 8979196a Michael Hanselmann

635 8979196a Michael Hanselmann
    """
636 8979196a Michael Hanselmann
    return self._SingleNodeCall(node, "storage_modify",
637 8979196a Michael Hanselmann
                                [su_name, su_args, name, changes])
638 8979196a Michael Hanselmann
639 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
640 637b8d7e Michael Hanselmann
  def call_storage_execute(self, node, su_name, su_args, name, op):
641 637b8d7e Michael Hanselmann
    """Executes an operation on a storage unit.
642 637b8d7e Michael Hanselmann

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

645 637b8d7e Michael Hanselmann
    """
646 637b8d7e Michael Hanselmann
    return self._SingleNodeCall(node, "storage_execute",
647 637b8d7e Michael Hanselmann
                                [su_name, su_args, name, op])
648 637b8d7e Michael Hanselmann
649 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
650 72737a7f Iustin Pop
  def call_bridges_exist(self, node, bridges_list):
651 72737a7f Iustin Pop
    """Checks if a node has all the bridges given.
652 a8083063 Iustin Pop

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

657 72737a7f Iustin Pop
    This is a single-node call.
658 a8083063 Iustin Pop

659 72737a7f Iustin Pop
    """
660 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "bridges_exist", [bridges_list])
661 a8083063 Iustin Pop
662 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
663 0eca8e0c Iustin Pop
  def call_instance_start(self, node, instance, hvp, bep):
664 72737a7f Iustin Pop
    """Starts an instance.
665 a8083063 Iustin Pop

666 72737a7f Iustin Pop
    This is a single-node call.
667 a8083063 Iustin Pop

668 72737a7f Iustin Pop
    """
669 0eca8e0c Iustin Pop
    idict = self._InstDict(instance, hvp=hvp, bep=bep)
670 0eca8e0c Iustin Pop
    return self._SingleNodeCall(node, "instance_start", [idict])
671 a8083063 Iustin Pop
672 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
673 6263189c Guido Trotter
  def call_instance_shutdown(self, node, instance, timeout):
674 72737a7f Iustin Pop
    """Stops an instance.
675 a8083063 Iustin Pop

676 72737a7f Iustin Pop
    This is a single-node call.
677 2a10865c Iustin Pop

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

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

688 6906a9d8 Guido Trotter
    @type node: string
689 6906a9d8 Guido Trotter
    @param node: the node on which the instance is currently running
690 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
691 6906a9d8 Guido Trotter
    @param instance: the instance definition
692 6906a9d8 Guido Trotter

693 6906a9d8 Guido Trotter
    """
694 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "migration_info",
695 6906a9d8 Guido Trotter
                                [self._InstDict(instance)])
696 6906a9d8 Guido Trotter
697 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
698 6906a9d8 Guido Trotter
  def call_accept_instance(self, node, instance, info, target):
699 6906a9d8 Guido Trotter
    """Prepare a node to accept an instance.
700 6906a9d8 Guido Trotter

701 6906a9d8 Guido Trotter
    This is a single-node call.
702 6906a9d8 Guido Trotter

703 6906a9d8 Guido Trotter
    @type node: string
704 6906a9d8 Guido Trotter
    @param node: the target node for the migration
705 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
706 6906a9d8 Guido Trotter
    @param instance: the instance definition
707 6906a9d8 Guido Trotter
    @type info: opaque/hypervisor specific (string/data)
708 6906a9d8 Guido Trotter
    @param info: result for the call_migration_info call
709 6906a9d8 Guido Trotter
    @type target: string
710 6906a9d8 Guido Trotter
    @param target: target hostname (usually ip address) (on the node itself)
711 6906a9d8 Guido Trotter

712 6906a9d8 Guido Trotter
    """
713 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "accept_instance",
714 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, target])
715 6906a9d8 Guido Trotter
716 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
717 6906a9d8 Guido Trotter
  def call_finalize_migration(self, node, instance, info, success):
718 6906a9d8 Guido Trotter
    """Finalize any target-node migration specific operation.
719 6906a9d8 Guido Trotter

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

723 6906a9d8 Guido Trotter
    This is a single-node call.
724 6906a9d8 Guido Trotter

725 6906a9d8 Guido Trotter
    @type node: string
726 6906a9d8 Guido Trotter
    @param node: the target node for the migration
727 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
728 6906a9d8 Guido Trotter
    @param instance: the instance definition
729 6906a9d8 Guido Trotter
    @type info: opaque/hypervisor specific (string/data)
730 6906a9d8 Guido Trotter
    @param info: result for the call_migration_info call
731 6906a9d8 Guido Trotter
    @type success: boolean
732 6906a9d8 Guido Trotter
    @param success: whether the migration was a success or a failure
733 6906a9d8 Guido Trotter

734 6906a9d8 Guido Trotter
    """
735 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "finalize_migration",
736 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, success])
737 6906a9d8 Guido Trotter
738 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
739 72737a7f Iustin Pop
  def call_instance_migrate(self, node, instance, target, live):
740 72737a7f Iustin Pop
    """Migrate an instance.
741 2a10865c Iustin Pop

742 72737a7f Iustin Pop
    This is a single-node call.
743 2a10865c Iustin Pop

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

754 72737a7f Iustin Pop
    """
755 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_migrate",
756 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), target, live])
757 007a2f3e Alexander Schreiber
758 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
759 17c3f802 Guido Trotter
  def call_instance_reboot(self, node, inst, reboot_type, shutdown_timeout):
760 72737a7f Iustin Pop
    """Reboots an instance.
761 007a2f3e Alexander Schreiber

762 72737a7f Iustin Pop
    This is a single-node call.
763 a8083063 Iustin Pop

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

773 72737a7f Iustin Pop
    This is a single-node call.
774 decd5f45 Iustin Pop

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

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

786 72737a7f Iustin Pop
    """
787 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_run_rename",
788 4a0e011f Iustin Pop
                                [self._InstDict(inst), old_name, debug])
789 a8083063 Iustin Pop
790 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
791 72737a7f Iustin Pop
  def call_instance_info(self, node, instance, hname):
792 72737a7f Iustin Pop
    """Returns information about a single instance.
793 a8083063 Iustin Pop

794 72737a7f Iustin Pop
    This is a single-node call.
795 a8083063 Iustin Pop

796 9a525d83 Michael Hanselmann
    @type node: list
797 9a525d83 Michael Hanselmann
    @param node: the list of nodes to query
798 72737a7f Iustin Pop
    @type instance: string
799 72737a7f Iustin Pop
    @param instance: the instance name
800 72737a7f Iustin Pop
    @type hname: string
801 72737a7f Iustin Pop
    @param hname: the hypervisor type of the instance
802 a8083063 Iustin Pop

803 72737a7f Iustin Pop
    """
804 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_info", [instance, hname])
805 e69d05fd Iustin Pop
806 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
807 56e7640c Iustin Pop
  def call_instance_migratable(self, node, instance):
808 56e7640c Iustin Pop
    """Checks whether the given instance can be migrated.
809 56e7640c Iustin Pop

810 56e7640c Iustin Pop
    This is a single-node call.
811 56e7640c Iustin Pop

812 56e7640c Iustin Pop
    @param node: the node to query
813 56e7640c Iustin Pop
    @type instance: L{objects.Instance}
814 56e7640c Iustin Pop
    @param instance: the instance to check
815 56e7640c Iustin Pop

816 56e7640c Iustin Pop

817 56e7640c Iustin Pop
    """
818 56e7640c Iustin Pop
    return self._SingleNodeCall(node, "instance_migratable",
819 56e7640c Iustin Pop
                                [self._InstDict(instance)])
820 56e7640c Iustin Pop
821 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
822 72737a7f Iustin Pop
  def call_all_instances_info(self, node_list, hypervisor_list):
823 72737a7f Iustin Pop
    """Returns information about all instances on the given nodes.
824 a8083063 Iustin Pop

825 72737a7f Iustin Pop
    This is a multi-node call.
826 a8083063 Iustin Pop

827 72737a7f Iustin Pop
    @type node_list: list
828 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
829 72737a7f Iustin Pop
    @type hypervisor_list: list
830 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
831 a8083063 Iustin Pop

832 72737a7f Iustin Pop
    """
833 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "all_instances_info",
834 9a525d83 Michael Hanselmann
                               [hypervisor_list])
835 e69d05fd Iustin Pop
836 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
837 72737a7f Iustin Pop
  def call_instance_list(self, node_list, hypervisor_list):
838 72737a7f Iustin Pop
    """Returns the list of running instances on a given node.
839 a8083063 Iustin Pop

840 72737a7f Iustin Pop
    This is a multi-node call.
841 a8083063 Iustin Pop

842 72737a7f Iustin Pop
    @type node_list: list
843 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
844 72737a7f Iustin Pop
    @type hypervisor_list: list
845 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
846 16abfbc2 Alexander Schreiber

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

855 72737a7f Iustin Pop
    This is a single-node call.
856 caad16e2 Iustin Pop

857 72737a7f Iustin Pop
    """
858 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_tcp_ping",
859 9a525d83 Michael Hanselmann
                                [source, target, port, timeout,
860 72737a7f Iustin Pop
                                 live_port_needed])
861 a8083063 Iustin Pop
862 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
863 caad16e2 Iustin Pop
  def call_node_has_ip_address(self, node, address):
864 caad16e2 Iustin Pop
    """Checks if a node has the given IP address.
865 caad16e2 Iustin Pop

866 caad16e2 Iustin Pop
    This is a single-node call.
867 caad16e2 Iustin Pop

868 caad16e2 Iustin Pop
    """
869 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_has_ip_address", [address])
870 a8083063 Iustin Pop
871 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
872 72737a7f Iustin Pop
  def call_node_info(self, node_list, vg_name, hypervisor_type):
873 72737a7f Iustin Pop
    """Return node information.
874 e69d05fd Iustin Pop

875 72737a7f Iustin Pop
    This will return memory information and volume group size and free
876 72737a7f Iustin Pop
    space.
877 a8083063 Iustin Pop

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

880 72737a7f Iustin Pop
    @type node_list: list
881 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
882 c41eea6e Iustin Pop
    @type vg_name: C{string}
883 c41eea6e Iustin Pop
    @param vg_name: the name of the volume group to ask for disk space
884 72737a7f Iustin Pop
        information
885 72737a7f Iustin Pop
    @type hypervisor_type: C{str}
886 72737a7f Iustin Pop
    @param hypervisor_type: the name of the hypervisor to ask for
887 72737a7f Iustin Pop
        memory information
888 a8083063 Iustin Pop

889 72737a7f Iustin Pop
    """
890 070e998b Iustin Pop
    return self._MultiNodeCall(node_list, "node_info",
891 070e998b Iustin Pop
                               [vg_name, hypervisor_type])
892 a8083063 Iustin Pop
893 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
894 19ddc57a Renรฉ Nussbaumer
  def call_etc_hosts_modify(self, node, mode, name, ip):
895 19ddc57a Renรฉ Nussbaumer
    """Modify hosts file with name
896 19ddc57a Renรฉ Nussbaumer

897 19ddc57a Renรฉ Nussbaumer
    @type node: string
898 19ddc57a Renรฉ Nussbaumer
    @param node: The node to call
899 19ddc57a Renรฉ Nussbaumer
    @type mode: string
900 19ddc57a Renรฉ Nussbaumer
    @param mode: The mode to operate. Currently "add" or "remove"
901 19ddc57a Renรฉ Nussbaumer
    @type name: string
902 19ddc57a Renรฉ Nussbaumer
    @param name: The host name to be modified
903 19ddc57a Renรฉ Nussbaumer
    @type ip: string
904 19ddc57a Renรฉ Nussbaumer
    @param ip: The ip of the entry (just valid if mode is "add")
905 19ddc57a Renรฉ Nussbaumer

906 19ddc57a Renรฉ Nussbaumer
    """
907 19ddc57a Renรฉ Nussbaumer
    return self._SingleNodeCall(node, "etc_hosts_modify", [mode, name, ip])
908 19ddc57a Renรฉ Nussbaumer
909 19ddc57a Renรฉ Nussbaumer
  @_RpcTimeout(_TMO_NORMAL)
910 72737a7f Iustin Pop
  def call_node_verify(self, node_list, checkdict, cluster_name):
911 72737a7f Iustin Pop
    """Request verification of given parameters.
912 a8083063 Iustin Pop

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

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

924 72737a7f Iustin Pop
    This is a single-node call.
925 a8083063 Iustin Pop

926 72737a7f Iustin Pop
    """
927 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_start_master",
928 3583908a Guido Trotter
                                     [start_daemons, no_voting])
929 a8083063 Iustin Pop
930 9a525d83 Michael Hanselmann
  @classmethod
931 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
932 9a525d83 Michael Hanselmann
  def call_node_stop_master(cls, node, stop_daemons):
933 72737a7f Iustin Pop
    """Tells a node to demote itself from master status.
934 a8083063 Iustin Pop

935 72737a7f Iustin Pop
    This is a single-node call.
936 4e071d3b Iustin Pop

937 72737a7f Iustin Pop
    """
938 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_stop_master", [stop_daemons])
939 4e071d3b Iustin Pop
940 9a525d83 Michael Hanselmann
  @classmethod
941 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
942 9a525d83 Michael Hanselmann
  def call_master_info(cls, node_list):
943 72737a7f Iustin Pop
    """Query master info.
944 4e071d3b Iustin Pop

945 72737a7f Iustin Pop
    This is a multi-node call.
946 a8083063 Iustin Pop

947 72737a7f Iustin Pop
    """
948 72737a7f Iustin Pop
    # TODO: should this method query down nodes?
949 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "master_info", [])
950 a8083063 Iustin Pop
951 8f215968 Michael Hanselmann
  @classmethod
952 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
953 8f215968 Michael Hanselmann
  def call_version(cls, node_list):
954 72737a7f Iustin Pop
    """Query node version.
955 a8083063 Iustin Pop

956 72737a7f Iustin Pop
    This is a multi-node call.
957 a8083063 Iustin Pop

958 72737a7f Iustin Pop
    """
959 8f215968 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "version", [])
960 a8083063 Iustin Pop
961 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
962 72737a7f Iustin Pop
  def call_blockdev_create(self, node, bdev, size, owner, on_primary, info):
963 72737a7f Iustin Pop
    """Request creation of a given block device.
964 a8083063 Iustin Pop

965 72737a7f Iustin Pop
    This is a single-node call.
966 a8083063 Iustin Pop

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

975 271b7cf9 Renรฉ Nussbaumer
    This is a single-node call.
976 271b7cf9 Renรฉ Nussbaumer

977 271b7cf9 Renรฉ Nussbaumer
    """
978 271b7cf9 Renรฉ Nussbaumer
    return self._SingleNodeCall(node, "blockdev_wipe",
979 271b7cf9 Renรฉ Nussbaumer
                                [bdev.ToDict(), offset, size])
980 271b7cf9 Renรฉ Nussbaumer
981 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
982 72737a7f Iustin Pop
  def call_blockdev_remove(self, node, bdev):
983 72737a7f Iustin Pop
    """Request removal of a given block device.
984 a8083063 Iustin Pop

985 72737a7f Iustin Pop
    This is a single-node call.
986 f3e513ad Iustin Pop

987 72737a7f Iustin Pop
    """
988 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_remove", [bdev.ToDict()])
989 f3e513ad Iustin Pop
990 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
991 72737a7f Iustin Pop
  def call_blockdev_rename(self, node, devlist):
992 72737a7f Iustin Pop
    """Request rename of the given block devices.
993 f3e513ad Iustin Pop

994 72737a7f Iustin Pop
    This is a single-node call.
995 a8083063 Iustin Pop

996 72737a7f Iustin Pop
    """
997 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_rename",
998 9a525d83 Michael Hanselmann
                                [(d.ToDict(), uid) for d, uid in devlist])
999 a8083063 Iustin Pop
1000 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1001 9c007da8 Renรฉ Nussbaumer
  def call_blockdev_pause_resume_sync(self, node, disks, pause):
1002 9c007da8 Renรฉ Nussbaumer
    """Request a pause/resume of given block device.
1003 9c007da8 Renรฉ Nussbaumer

1004 9c007da8 Renรฉ Nussbaumer
    This is a single-node call.
1005 9c007da8 Renรฉ Nussbaumer

1006 9c007da8 Renรฉ Nussbaumer
    """
1007 9c007da8 Renรฉ Nussbaumer
    return self._SingleNodeCall(node, "blockdev_pause_resume_sync",
1008 9c007da8 Renรฉ Nussbaumer
                                [[bdev.ToDict() for bdev in disks], pause])
1009 9c007da8 Renรฉ Nussbaumer
1010 9c007da8 Renรฉ Nussbaumer
  @_RpcTimeout(_TMO_NORMAL)
1011 c417e115 Iustin Pop
  def call_blockdev_assemble(self, node, disk, owner, on_primary, idx):
1012 72737a7f Iustin Pop
    """Request assembling of a given block device.
1013 a8083063 Iustin Pop

1014 72737a7f Iustin Pop
    This is a single-node call.
1015 a8083063 Iustin Pop

1016 72737a7f Iustin Pop
    """
1017 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_assemble",
1018 c417e115 Iustin Pop
                                [disk.ToDict(), owner, on_primary, idx])
1019 a8083063 Iustin Pop
1020 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1021 72737a7f Iustin Pop
  def call_blockdev_shutdown(self, node, disk):
1022 72737a7f Iustin Pop
    """Request shutdown of a given block device.
1023 a8083063 Iustin Pop

1024 72737a7f Iustin Pop
    This is a single-node call.
1025 a8083063 Iustin Pop

1026 72737a7f Iustin Pop
    """
1027 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_shutdown", [disk.ToDict()])
1028 a8083063 Iustin Pop
1029 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1030 72737a7f Iustin Pop
  def call_blockdev_addchildren(self, node, bdev, ndevs):
1031 72737a7f Iustin Pop
    """Request adding a list of children to a (mirroring) device.
1032 a8083063 Iustin Pop

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

1035 72737a7f Iustin Pop
    """
1036 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_addchildren",
1037 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
1038 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
1039 a8083063 Iustin Pop
1040 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1041 72737a7f Iustin Pop
  def call_blockdev_removechildren(self, node, bdev, ndevs):
1042 72737a7f Iustin Pop
    """Request removing a list of children from a (mirroring) device.
1043 a8083063 Iustin Pop

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

1046 72737a7f Iustin Pop
    """
1047 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_removechildren",
1048 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
1049 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
1050 a8083063 Iustin Pop
1051 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1052 72737a7f Iustin Pop
  def call_blockdev_getmirrorstatus(self, node, disks):
1053 72737a7f Iustin Pop
    """Request status of a (mirroring) device.
1054 a8083063 Iustin Pop

1055 72737a7f Iustin Pop
    This is a single-node call.
1056 a8083063 Iustin Pop

1057 72737a7f Iustin Pop
    """
1058 36145b12 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_getmirrorstatus",
1059 36145b12 Michael Hanselmann
                                  [dsk.ToDict() for dsk in disks])
1060 edb4b374 Michael Hanselmann
    if not result.fail_msg:
1061 36145b12 Michael Hanselmann
      result.payload = [objects.BlockDevStatus.FromDict(i)
1062 36145b12 Michael Hanselmann
                        for i in result.payload]
1063 36145b12 Michael Hanselmann
    return result
1064 a8083063 Iustin Pop
1065 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1066 b8d26c6e Michael Hanselmann
  def call_blockdev_getmirrorstatus_multi(self, node_list, node_disks):
1067 b8d26c6e Michael Hanselmann
    """Request status of (mirroring) devices from multiple nodes.
1068 b8d26c6e Michael Hanselmann

1069 b8d26c6e Michael Hanselmann
    This is a multi-node call.
1070 b8d26c6e Michael Hanselmann

1071 b8d26c6e Michael Hanselmann
    """
1072 b8d26c6e Michael Hanselmann
    result = self._MultiNodeCall(node_list, "blockdev_getmirrorstatus_multi",
1073 b8d26c6e Michael Hanselmann
                                 [dict((name, [dsk.ToDict() for dsk in disks])
1074 b8d26c6e Michael Hanselmann
                                       for name, disks in node_disks.items())])
1075 b8d26c6e Michael Hanselmann
    for nres in result.values():
1076 c6a9dffa Michael Hanselmann
      if nres.fail_msg:
1077 c6a9dffa Michael Hanselmann
        continue
1078 c6a9dffa Michael Hanselmann
1079 c6a9dffa Michael Hanselmann
      for idx, (success, status) in enumerate(nres.payload):
1080 c6a9dffa Michael Hanselmann
        if success:
1081 c6a9dffa Michael Hanselmann
          nres.payload[idx] = (success, objects.BlockDevStatus.FromDict(status))
1082 c6a9dffa Michael Hanselmann
1083 b8d26c6e Michael Hanselmann
    return result
1084 b8d26c6e Michael Hanselmann
1085 b8d26c6e Michael Hanselmann
  @_RpcTimeout(_TMO_NORMAL)
1086 72737a7f Iustin Pop
  def call_blockdev_find(self, node, disk):
1087 72737a7f Iustin Pop
    """Request identification of a given block device.
1088 72737a7f Iustin Pop

1089 72737a7f Iustin Pop
    This is a single-node call.
1090 a8083063 Iustin Pop

1091 72737a7f Iustin Pop
    """
1092 96acbc09 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_find", [disk.ToDict()])
1093 edb4b374 Michael Hanselmann
    if not result.fail_msg and result.payload is not None:
1094 96acbc09 Michael Hanselmann
      result.payload = objects.BlockDevStatus.FromDict(result.payload)
1095 96acbc09 Michael Hanselmann
    return result
1096 d61cbe76 Iustin Pop
1097 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1098 b2e7666a Iustin Pop
  def call_blockdev_close(self, node, instance_name, disks):
1099 72737a7f Iustin Pop
    """Closes the given block devices.
1100 d61cbe76 Iustin Pop

1101 72737a7f Iustin Pop
    This is a single-node call.
1102 d61cbe76 Iustin Pop

1103 72737a7f Iustin Pop
    """
1104 b2e7666a Iustin Pop
    params = [instance_name, [cf.ToDict() for cf in disks]]
1105 b2e7666a Iustin Pop
    return self._SingleNodeCall(node, "blockdev_close", params)
1106 a8083063 Iustin Pop
1107 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1108 ccfbbd2d Iustin Pop
  def call_blockdev_getsize(self, node, disks):
1109 968a7623 Iustin Pop
    """Returns the size of the given disks.
1110 968a7623 Iustin Pop

1111 968a7623 Iustin Pop
    This is a single-node call.
1112 968a7623 Iustin Pop

1113 968a7623 Iustin Pop
    """
1114 968a7623 Iustin Pop
    params = [[cf.ToDict() for cf in disks]]
1115 968a7623 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_getsize", params)
1116 968a7623 Iustin Pop
1117 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1118 6b93ec9d Iustin Pop
  def call_drbd_disconnect_net(self, node_list, nodes_ip, disks):
1119 6b93ec9d Iustin Pop
    """Disconnects the network of the given drbd devices.
1120 6b93ec9d Iustin Pop

1121 6b93ec9d Iustin Pop
    This is a multi-node call.
1122 6b93ec9d Iustin Pop

1123 6b93ec9d Iustin Pop
    """
1124 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_disconnect_net",
1125 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1126 6b93ec9d Iustin Pop
1127 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1128 6b93ec9d Iustin Pop
  def call_drbd_attach_net(self, node_list, nodes_ip,
1129 6b93ec9d Iustin Pop
                           disks, instance_name, multimaster):
1130 6b93ec9d Iustin Pop
    """Disconnects the given drbd devices.
1131 6b93ec9d Iustin Pop

1132 6b93ec9d Iustin Pop
    This is a multi-node call.
1133 6b93ec9d Iustin Pop

1134 6b93ec9d Iustin Pop
    """
1135 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_attach_net",
1136 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks],
1137 6b93ec9d Iustin Pop
                                instance_name, multimaster])
1138 6b93ec9d Iustin Pop
1139 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
1140 6b93ec9d Iustin Pop
  def call_drbd_wait_sync(self, node_list, nodes_ip, disks):
1141 6b93ec9d Iustin Pop
    """Waits for the synchronization of drbd devices is complete.
1142 6b93ec9d Iustin Pop

1143 6b93ec9d Iustin Pop
    This is a multi-node call.
1144 6b93ec9d Iustin Pop

1145 6b93ec9d Iustin Pop
    """
1146 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_wait_sync",
1147 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1148 6b93ec9d Iustin Pop
1149 c46b9782 Luca Bigliardi
  @_RpcTimeout(_TMO_URGENT)
1150 c46b9782 Luca Bigliardi
  def call_drbd_helper(self, node_list):
1151 c46b9782 Luca Bigliardi
    """Gets drbd helper.
1152 c46b9782 Luca Bigliardi

1153 c46b9782 Luca Bigliardi
    This is a multi-node call.
1154 c46b9782 Luca Bigliardi

1155 c46b9782 Luca Bigliardi
    """
1156 c46b9782 Luca Bigliardi
    return self._MultiNodeCall(node_list, "drbd_helper", [])
1157 c46b9782 Luca Bigliardi
1158 9a525d83 Michael Hanselmann
  @classmethod
1159 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1160 9a525d83 Michael Hanselmann
  def call_upload_file(cls, node_list, file_name, address_list=None):
1161 72737a7f Iustin Pop
    """Upload a file.
1162 72737a7f Iustin Pop

1163 72737a7f Iustin Pop
    The node will refuse the operation in case the file is not on the
1164 72737a7f Iustin Pop
    approved file list.
1165 72737a7f Iustin Pop

1166 72737a7f Iustin Pop
    This is a multi-node call.
1167 a8083063 Iustin Pop

1168 6b294c53 Iustin Pop
    @type node_list: list
1169 6b294c53 Iustin Pop
    @param node_list: the list of node names to upload to
1170 6b294c53 Iustin Pop
    @type file_name: str
1171 6b294c53 Iustin Pop
    @param file_name: the filename to upload
1172 6b294c53 Iustin Pop
    @type address_list: list or None
1173 6b294c53 Iustin Pop
    @keyword address_list: an optional list of node addresses, in order
1174 6b294c53 Iustin Pop
        to optimize the RPC speed
1175 6b294c53 Iustin Pop

1176 72737a7f Iustin Pop
    """
1177 12bce260 Michael Hanselmann
    file_contents = utils.ReadFile(file_name)
1178 12bce260 Michael Hanselmann
    data = cls._Compress(file_contents)
1179 72737a7f Iustin Pop
    st = os.stat(file_name)
1180 72737a7f Iustin Pop
    params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
1181 72737a7f Iustin Pop
              st.st_atime, st.st_mtime]
1182 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "upload_file", params,
1183 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1184 72737a7f Iustin Pop
1185 6ddc95ec Michael Hanselmann
  @classmethod
1186 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1187 03d1dba2 Michael Hanselmann
  def call_write_ssconf_files(cls, node_list, values):
1188 6ddc95ec Michael Hanselmann
    """Write ssconf files.
1189 6ddc95ec Michael Hanselmann

1190 6ddc95ec Michael Hanselmann
    This is a multi-node call.
1191 6ddc95ec Michael Hanselmann

1192 6ddc95ec Michael Hanselmann
    """
1193 03d1dba2 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "write_ssconf_files", [values])
1194 6ddc95ec Michael Hanselmann
1195 4f6014d4 Renรฉ Nussbaumer
  @_RpcTimeout(_TMO_NORMAL)
1196 0092d621 Renรฉ Nussbaumer
  def call_run_oob(self, node, oob_program, command, remote_node, timeout):
1197 4f6014d4 Renรฉ Nussbaumer
    """Runs OOB.
1198 4f6014d4 Renรฉ Nussbaumer

1199 4f6014d4 Renรฉ Nussbaumer
    This is a single-node call.
1200 4f6014d4 Renรฉ Nussbaumer

1201 4f6014d4 Renรฉ Nussbaumer
    """
1202 4f6014d4 Renรฉ Nussbaumer
    return self._SingleNodeCall(node, "run_oob", [oob_program, command,
1203 0092d621 Renรฉ Nussbaumer
                                                  remote_node, timeout])
1204 4f6014d4 Renรฉ Nussbaumer
1205 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1206 72737a7f Iustin Pop
  def call_os_diagnose(self, node_list):
1207 72737a7f Iustin Pop
    """Request a diagnose of OS definitions.
1208 72737a7f Iustin Pop

1209 72737a7f Iustin Pop
    This is a multi-node call.
1210 a8083063 Iustin Pop

1211 72737a7f Iustin Pop
    """
1212 83d92ad8 Iustin Pop
    return self._MultiNodeCall(node_list, "os_diagnose", [])
1213 a8083063 Iustin Pop
1214 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1215 72737a7f Iustin Pop
  def call_os_get(self, node, name):
1216 72737a7f Iustin Pop
    """Returns an OS definition.
1217 a8083063 Iustin Pop

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

1220 72737a7f Iustin Pop
    """
1221 9a525d83 Michael Hanselmann
    result = self._SingleNodeCall(node, "os_get", [name])
1222 84e3f66f Guido Trotter
    if not result.fail_msg and isinstance(result.payload, dict):
1223 84e3f66f Guido Trotter
      result.payload = objects.OS.FromDict(result.payload)
1224 781de953 Iustin Pop
    return result
1225 a8083063 Iustin Pop
1226 acd9ff9e Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1227 acd9ff9e Iustin Pop
  def call_os_validate(self, required, nodes, name, checks, params):
1228 acd9ff9e Iustin Pop
    """Run a validation routine for a given OS.
1229 acd9ff9e Iustin Pop

1230 acd9ff9e Iustin Pop
    This is a multi-node call.
1231 acd9ff9e Iustin Pop

1232 acd9ff9e Iustin Pop
    """
1233 acd9ff9e Iustin Pop
    return self._MultiNodeCall(nodes, "os_validate",
1234 acd9ff9e Iustin Pop
                               [required, name, checks, params])
1235 acd9ff9e Iustin Pop
1236 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1237 72737a7f Iustin Pop
  def call_hooks_runner(self, node_list, hpath, phase, env):
1238 72737a7f Iustin Pop
    """Call the hooks runner.
1239 a8083063 Iustin Pop

1240 72737a7f Iustin Pop
    Args:
1241 72737a7f Iustin Pop
      - op: the OpCode instance
1242 72737a7f Iustin Pop
      - env: a dictionary with the environment
1243 a8083063 Iustin Pop

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

1246 72737a7f Iustin Pop
    """
1247 72737a7f Iustin Pop
    params = [hpath, phase, env]
1248 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hooks_runner", params)
1249 a8083063 Iustin Pop
1250 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1251 72737a7f Iustin Pop
  def call_iallocator_runner(self, node, name, idata):
1252 72737a7f Iustin Pop
    """Call an iallocator on a remote node
1253 8d528b7c Iustin Pop

1254 72737a7f Iustin Pop
    Args:
1255 72737a7f Iustin Pop
      - name: the iallocator name
1256 72737a7f Iustin Pop
      - input: the json-encoded input string
1257 8d528b7c Iustin Pop

1258 72737a7f Iustin Pop
    This is a single-node call.
1259 8d528b7c Iustin Pop

1260 72737a7f Iustin Pop
    """
1261 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "iallocator_runner", [name, idata])
1262 8d528b7c Iustin Pop
1263 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1264 a59faf4b Iustin Pop
  def call_blockdev_grow(self, node, cf_bdev, amount, dryrun):
1265 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1266 4c8ba8b3 Iustin Pop

1267 72737a7f Iustin Pop
    This is a single-node call.
1268 4c8ba8b3 Iustin Pop

1269 72737a7f Iustin Pop
    """
1270 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_grow",
1271 a59faf4b Iustin Pop
                                [cf_bdev.ToDict(), amount, dryrun])
1272 4c8ba8b3 Iustin Pop
1273 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_1DAY)
1274 858f3d18 Iustin Pop
  def call_blockdev_export(self, node, cf_bdev,
1275 858f3d18 Iustin Pop
                           dest_node, dest_path, cluster_name):
1276 858f3d18 Iustin Pop
    """Export a given disk to another node.
1277 858f3d18 Iustin Pop

1278 858f3d18 Iustin Pop
    This is a single-node call.
1279 858f3d18 Iustin Pop

1280 858f3d18 Iustin Pop
    """
1281 858f3d18 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_export",
1282 858f3d18 Iustin Pop
                                [cf_bdev.ToDict(), dest_node, dest_path,
1283 858f3d18 Iustin Pop
                                 cluster_name])
1284 858f3d18 Iustin Pop
1285 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1286 72737a7f Iustin Pop
  def call_blockdev_snapshot(self, node, cf_bdev):
1287 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1288 a8083063 Iustin Pop

1289 72737a7f Iustin Pop
    This is a single-node call.
1290 a8083063 Iustin Pop

1291 72737a7f Iustin Pop
    """
1292 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_snapshot", [cf_bdev.ToDict()])
1293 a8083063 Iustin Pop
1294 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1295 72737a7f Iustin Pop
  def call_finalize_export(self, node, instance, snap_disks):
1296 72737a7f Iustin Pop
    """Request the completion of an export operation.
1297 a8083063 Iustin Pop

1298 72737a7f Iustin Pop
    This writes the export config file, etc.
1299 a8083063 Iustin Pop

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

1302 72737a7f Iustin Pop
    """
1303 72737a7f Iustin Pop
    flat_disks = []
1304 72737a7f Iustin Pop
    for disk in snap_disks:
1305 a97da6b7 Iustin Pop
      if isinstance(disk, bool):
1306 a97da6b7 Iustin Pop
        flat_disks.append(disk)
1307 a97da6b7 Iustin Pop
      else:
1308 a97da6b7 Iustin Pop
        flat_disks.append(disk.ToDict())
1309 9a525d83 Michael Hanselmann
1310 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "finalize_export",
1311 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), flat_disks])
1312 a8083063 Iustin Pop
1313 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1314 72737a7f Iustin Pop
  def call_export_info(self, node, path):
1315 72737a7f Iustin Pop
    """Queries the export information in a given path.
1316 a8083063 Iustin Pop

1317 72737a7f Iustin Pop
    This is a single-node call.
1318 a8083063 Iustin Pop

1319 72737a7f Iustin Pop
    """
1320 3eccac06 Iustin Pop
    return self._SingleNodeCall(node, "export_info", [path])
1321 a8083063 Iustin Pop
1322 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1323 72737a7f Iustin Pop
  def call_export_list(self, node_list):
1324 72737a7f Iustin Pop
    """Gets the stored exports list.
1325 a8083063 Iustin Pop

1326 72737a7f Iustin Pop
    This is a multi-node call.
1327 a8083063 Iustin Pop

1328 72737a7f Iustin Pop
    """
1329 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "export_list", [])
1330 a8083063 Iustin Pop
1331 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1332 72737a7f Iustin Pop
  def call_export_remove(self, node, export):
1333 72737a7f Iustin Pop
    """Requests removal of a given export.
1334 a8083063 Iustin Pop

1335 72737a7f Iustin Pop
    This is a single-node call.
1336 a8083063 Iustin Pop

1337 72737a7f Iustin Pop
    """
1338 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "export_remove", [export])
1339 a8083063 Iustin Pop
1340 9a525d83 Michael Hanselmann
  @classmethod
1341 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1342 b989b9d9 Ken Wehr
  def call_node_leave_cluster(cls, node, modify_ssh_setup):
1343 72737a7f Iustin Pop
    """Requests a node to clean the cluster information it has.
1344 a8083063 Iustin Pop

1345 72737a7f Iustin Pop
    This will remove the configuration information from the ganeti data
1346 72737a7f Iustin Pop
    dir.
1347 a8083063 Iustin Pop

1348 72737a7f Iustin Pop
    This is a single-node call.
1349 a8083063 Iustin Pop

1350 72737a7f Iustin Pop
    """
1351 b989b9d9 Ken Wehr
    return cls._StaticSingleNodeCall(node, "node_leave_cluster",
1352 b989b9d9 Ken Wehr
                                     [modify_ssh_setup])
1353 dcb93971 Michael Hanselmann
1354 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1355 72737a7f Iustin Pop
  def call_node_volumes(self, node_list):
1356 72737a7f Iustin Pop
    """Gets all volumes on node(s).
1357 dcb93971 Michael Hanselmann

1358 72737a7f Iustin Pop
    This is a multi-node call.
1359 dcb93971 Michael Hanselmann

1360 72737a7f Iustin Pop
    """
1361 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_volumes", [])
1362 06009e27 Iustin Pop
1363 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1364 56aa9fd5 Iustin Pop
  def call_node_demote_from_mc(self, node):
1365 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
1366 56aa9fd5 Iustin Pop

1367 56aa9fd5 Iustin Pop
    This is a single-node call.
1368 56aa9fd5 Iustin Pop

1369 56aa9fd5 Iustin Pop
    """
1370 56aa9fd5 Iustin Pop
    return self._SingleNodeCall(node, "node_demote_from_mc", [])
1371 56aa9fd5 Iustin Pop
1372 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1373 f5118ade Iustin Pop
  def call_node_powercycle(self, node, hypervisor):
1374 f5118ade Iustin Pop
    """Tries to powercycle a node.
1375 f5118ade Iustin Pop

1376 f5118ade Iustin Pop
    This is a single-node call.
1377 f5118ade Iustin Pop

1378 f5118ade Iustin Pop
    """
1379 f5118ade Iustin Pop
    return self._SingleNodeCall(node, "node_powercycle", [hypervisor])
1380 f5118ade Iustin Pop
1381 92fd2250 Iustin Pop
  @_RpcTimeout(None)
1382 72737a7f Iustin Pop
  def call_test_delay(self, node_list, duration):
1383 72737a7f Iustin Pop
    """Sleep for a fixed time on given node(s).
1384 06009e27 Iustin Pop

1385 72737a7f Iustin Pop
    This is a multi-node call.
1386 06009e27 Iustin Pop

1387 72737a7f Iustin Pop
    """
1388 92fd2250 Iustin Pop
    return self._MultiNodeCall(node_list, "test_delay", [duration],
1389 92fd2250 Iustin Pop
                               read_timeout=int(duration + 5))
1390 5e04ed8b Manuel Franceschini
1391 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1392 72737a7f Iustin Pop
  def call_file_storage_dir_create(self, node, file_storage_dir):
1393 72737a7f Iustin Pop
    """Create the given file storage directory.
1394 5e04ed8b Manuel Franceschini

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

1397 72737a7f Iustin Pop
    """
1398 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_create",
1399 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1400 5e04ed8b Manuel Franceschini
1401 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1402 72737a7f Iustin Pop
  def call_file_storage_dir_remove(self, node, file_storage_dir):
1403 72737a7f Iustin Pop
    """Remove the given file storage directory.
1404 5e04ed8b Manuel Franceschini

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

1407 72737a7f Iustin Pop
    """
1408 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_remove",
1409 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1410 5e04ed8b Manuel Franceschini
1411 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1412 72737a7f Iustin Pop
  def call_file_storage_dir_rename(self, node, old_file_storage_dir,
1413 72737a7f Iustin Pop
                                   new_file_storage_dir):
1414 72737a7f Iustin Pop
    """Rename file storage directory.
1415 5e04ed8b Manuel Franceschini

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

1418 72737a7f Iustin Pop
    """
1419 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_rename",
1420 9a525d83 Michael Hanselmann
                                [old_file_storage_dir, new_file_storage_dir])
1421 ca52cdeb Michael Hanselmann
1422 9a525d83 Michael Hanselmann
  @classmethod
1423 d2cd6944 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
1424 9a525d83 Michael Hanselmann
  def call_jobqueue_update(cls, node_list, address_list, file_name, content):
1425 72737a7f Iustin Pop
    """Update job queue.
1426 ca52cdeb Michael Hanselmann

1427 72737a7f Iustin Pop
    This is a multi-node call.
1428 ca52cdeb Michael Hanselmann

1429 72737a7f Iustin Pop
    """
1430 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_update",
1431 12bce260 Michael Hanselmann
                                    [file_name, cls._Compress(content)],
1432 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1433 ca52cdeb Michael Hanselmann
1434 9a525d83 Michael Hanselmann
  @classmethod
1435 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1436 9a525d83 Michael Hanselmann
  def call_jobqueue_purge(cls, node):
1437 72737a7f Iustin Pop
    """Purge job queue.
1438 ca52cdeb Michael Hanselmann

1439 72737a7f Iustin Pop
    This is a single-node call.
1440 ca52cdeb Michael Hanselmann

1441 72737a7f Iustin Pop
    """
1442 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "jobqueue_purge", [])
1443 af5ebcb1 Michael Hanselmann
1444 9a525d83 Michael Hanselmann
  @classmethod
1445 d2cd6944 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
1446 dd875d32 Michael Hanselmann
  def call_jobqueue_rename(cls, node_list, address_list, rename):
1447 72737a7f Iustin Pop
    """Rename a job queue file.
1448 af5ebcb1 Michael Hanselmann

1449 72737a7f Iustin Pop
    This is a multi-node call.
1450 af5ebcb1 Michael Hanselmann

1451 72737a7f Iustin Pop
    """
1452 dd875d32 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_rename", rename,
1453 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1454 6217e295 Iustin Pop
1455 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1456 6217e295 Iustin Pop
  def call_hypervisor_validate_params(self, node_list, hvname, hvparams):
1457 6217e295 Iustin Pop
    """Validate the hypervisor params.
1458 6217e295 Iustin Pop

1459 6217e295 Iustin Pop
    This is a multi-node call.
1460 6217e295 Iustin Pop

1461 6217e295 Iustin Pop
    @type node_list: list
1462 6217e295 Iustin Pop
    @param node_list: the list of nodes to query
1463 6217e295 Iustin Pop
    @type hvname: string
1464 6217e295 Iustin Pop
    @param hvname: the hypervisor name
1465 6217e295 Iustin Pop
    @type hvparams: dict
1466 6217e295 Iustin Pop
    @param hvparams: the hypervisor parameters to be validated
1467 6217e295 Iustin Pop

1468 6217e295 Iustin Pop
    """
1469 6217e295 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
1470 abe609b2 Guido Trotter
    hv_full = objects.FillDict(cluster.hvparams.get(hvname, {}), hvparams)
1471 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hypervisor_validate_params",
1472 9a525d83 Michael Hanselmann
                               [hvname, hv_full])
1473 f942a838 Michael Hanselmann
1474 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1475 37549316 Michael Hanselmann
  def call_x509_cert_create(self, node, validity):
1476 f942a838 Michael Hanselmann
    """Creates a new X509 certificate for SSL/TLS.
1477 f942a838 Michael Hanselmann

1478 f942a838 Michael Hanselmann
    This is a single-node call.
1479 f942a838 Michael Hanselmann

1480 f942a838 Michael Hanselmann
    @type validity: int
1481 f942a838 Michael Hanselmann
    @param validity: Validity in seconds
1482 f942a838 Michael Hanselmann

1483 f942a838 Michael Hanselmann
    """
1484 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_create", [validity])
1485 f942a838 Michael Hanselmann
1486 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1487 37549316 Michael Hanselmann
  def call_x509_cert_remove(self, node, name):
1488 f942a838 Michael Hanselmann
    """Removes a X509 certificate.
1489 f942a838 Michael Hanselmann

1490 f942a838 Michael Hanselmann
    This is a single-node call.
1491 f942a838 Michael Hanselmann

1492 f942a838 Michael Hanselmann
    @type name: string
1493 f942a838 Michael Hanselmann
    @param name: Certificate name
1494 f942a838 Michael Hanselmann

1495 f942a838 Michael Hanselmann
    """
1496 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_remove", [name])
1497 1651d116 Michael Hanselmann
1498 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1499 eb630f50 Michael Hanselmann
  def call_import_start(self, node, opts, instance, dest, dest_args):
1500 1651d116 Michael Hanselmann
    """Starts a listener for an import.
1501 1651d116 Michael Hanselmann

1502 1651d116 Michael Hanselmann
    This is a single-node call.
1503 1651d116 Michael Hanselmann

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

1509 1651d116 Michael Hanselmann
    """
1510 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "import_start",
1511 eb630f50 Michael Hanselmann
                                [opts.ToDict(),
1512 1651d116 Michael Hanselmann
                                 self._InstDict(instance), dest,
1513 1651d116 Michael Hanselmann
                                 _EncodeImportExportIO(dest, dest_args)])
1514 1651d116 Michael Hanselmann
1515 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1516 eb630f50 Michael Hanselmann
  def call_export_start(self, node, opts, host, port,
1517 1651d116 Michael Hanselmann
                        instance, source, source_args):
1518 1651d116 Michael Hanselmann
    """Starts an export daemon.
1519 1651d116 Michael Hanselmann

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

1522 1651d116 Michael Hanselmann
    @type node: string
1523 1651d116 Michael Hanselmann
    @param node: Node name
1524 1651d116 Michael Hanselmann
    @type instance: C{objects.Instance}
1525 1651d116 Michael Hanselmann
    @param instance: Instance object
1526 1651d116 Michael Hanselmann

1527 1651d116 Michael Hanselmann
    """
1528 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "export_start",
1529 eb630f50 Michael Hanselmann
                                [opts.ToDict(), host, port,
1530 1651d116 Michael Hanselmann
                                 self._InstDict(instance), source,
1531 1651d116 Michael Hanselmann
                                 _EncodeImportExportIO(source, source_args)])
1532 1651d116 Michael Hanselmann
1533 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1534 ef40fbfb Michael Hanselmann
  def call_impexp_status(self, node, names):
1535 1651d116 Michael Hanselmann
    """Gets the status of an import or export.
1536 1651d116 Michael Hanselmann

1537 1651d116 Michael Hanselmann
    This is a single-node call.
1538 1651d116 Michael Hanselmann

1539 1651d116 Michael Hanselmann
    @type node: string
1540 1651d116 Michael Hanselmann
    @param node: Node name
1541 1651d116 Michael Hanselmann
    @type names: List of strings
1542 1651d116 Michael Hanselmann
    @param names: Import/export names
1543 1651d116 Michael Hanselmann
    @rtype: List of L{objects.ImportExportStatus} instances
1544 1651d116 Michael Hanselmann
    @return: Returns a list of the state of each named import/export or None if
1545 1651d116 Michael Hanselmann
             a status couldn't be retrieved
1546 1651d116 Michael Hanselmann

1547 1651d116 Michael Hanselmann
    """
1548 ef40fbfb Michael Hanselmann
    result = self._SingleNodeCall(node, "impexp_status", [names])
1549 1651d116 Michael Hanselmann
1550 1651d116 Michael Hanselmann
    if not result.fail_msg:
1551 1651d116 Michael Hanselmann
      decoded = []
1552 1651d116 Michael Hanselmann
1553 1651d116 Michael Hanselmann
      for i in result.payload:
1554 1651d116 Michael Hanselmann
        if i is None:
1555 1651d116 Michael Hanselmann
          decoded.append(None)
1556 1651d116 Michael Hanselmann
          continue
1557 1651d116 Michael Hanselmann
        decoded.append(objects.ImportExportStatus.FromDict(i))
1558 1651d116 Michael Hanselmann
1559 1651d116 Michael Hanselmann
      result.payload = decoded
1560 1651d116 Michael Hanselmann
1561 1651d116 Michael Hanselmann
    return result
1562 1651d116 Michael Hanselmann
1563 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1564 f81c4737 Michael Hanselmann
  def call_impexp_abort(self, node, name):
1565 f81c4737 Michael Hanselmann
    """Aborts an import or export.
1566 f81c4737 Michael Hanselmann

1567 f81c4737 Michael Hanselmann
    This is a single-node call.
1568 f81c4737 Michael Hanselmann

1569 f81c4737 Michael Hanselmann
    @type node: string
1570 f81c4737 Michael Hanselmann
    @param node: Node name
1571 f81c4737 Michael Hanselmann
    @type name: string
1572 f81c4737 Michael Hanselmann
    @param name: Import/export name
1573 f81c4737 Michael Hanselmann

1574 f81c4737 Michael Hanselmann
    """
1575 f81c4737 Michael Hanselmann
    return self._SingleNodeCall(node, "impexp_abort", [name])
1576 f81c4737 Michael Hanselmann
1577 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1578 ef40fbfb Michael Hanselmann
  def call_impexp_cleanup(self, node, name):
1579 1651d116 Michael Hanselmann
    """Cleans up after an import or export.
1580 1651d116 Michael Hanselmann

1581 1651d116 Michael Hanselmann
    This is a single-node call.
1582 1651d116 Michael Hanselmann

1583 1651d116 Michael Hanselmann
    @type node: string
1584 1651d116 Michael Hanselmann
    @param node: Node name
1585 1651d116 Michael Hanselmann
    @type name: string
1586 1651d116 Michael Hanselmann
    @param name: Import/export name
1587 1651d116 Michael Hanselmann

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