Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ df5a5730

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

817 56e7640c Iustin Pop

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

916 72737a7f Iustin Pop
    """
917 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_verify",
918 9a525d83 Michael Hanselmann
                               [checkdict, cluster_name])
919 a8083063 Iustin Pop
920 9a525d83 Michael Hanselmann
  @classmethod
921 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
922 c06e0c83 Andrea Spadaccini
  def call_node_start_master_daemons(cls, node, no_voting):
923 c06e0c83 Andrea Spadaccini
    """Starts master daemons on a node.
924 a8083063 Iustin Pop

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

927 72737a7f Iustin Pop
    """
928 c06e0c83 Andrea Spadaccini
    return cls._StaticSingleNodeCall(node, "node_start_master_daemons",
929 c06e0c83 Andrea Spadaccini
                                     [no_voting])
930 a8083063 Iustin Pop
931 9a525d83 Michael Hanselmann
  @classmethod
932 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
933 c06e0c83 Andrea Spadaccini
  def call_node_activate_master_ip(cls, node):
934 c06e0c83 Andrea Spadaccini
    """Activates master IP on a node.
935 a8083063 Iustin Pop

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

938 72737a7f Iustin Pop
    """
939 c06e0c83 Andrea Spadaccini
    return cls._StaticSingleNodeCall(node, "node_activate_master_ip", [])
940 c06e0c83 Andrea Spadaccini
941 c06e0c83 Andrea Spadaccini
  @classmethod
942 c06e0c83 Andrea Spadaccini
  @_RpcTimeout(_TMO_FAST)
943 c06e0c83 Andrea Spadaccini
  def call_node_stop_master(cls, node):
944 c06e0c83 Andrea Spadaccini
    """Deactivates master IP and stops master daemons on a node.
945 c06e0c83 Andrea Spadaccini

946 c06e0c83 Andrea Spadaccini
    This is a single-node call.
947 c06e0c83 Andrea Spadaccini

948 c06e0c83 Andrea Spadaccini
    """
949 c06e0c83 Andrea Spadaccini
    return cls._StaticSingleNodeCall(node, "node_stop_master", [])
950 c06e0c83 Andrea Spadaccini
951 c06e0c83 Andrea Spadaccini
  @classmethod
952 c06e0c83 Andrea Spadaccini
  @_RpcTimeout(_TMO_FAST)
953 c06e0c83 Andrea Spadaccini
  def call_node_deactivate_master_ip(cls, node):
954 c06e0c83 Andrea Spadaccini
    """Deactivates master IP on a node.
955 c06e0c83 Andrea Spadaccini

956 c06e0c83 Andrea Spadaccini
    This is a single-node call.
957 c06e0c83 Andrea Spadaccini

958 c06e0c83 Andrea Spadaccini
    """
959 c06e0c83 Andrea Spadaccini
    return cls._StaticSingleNodeCall(node, "node_deactivate_master_ip", [])
960 4e071d3b Iustin Pop
961 9a525d83 Michael Hanselmann
  @classmethod
962 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
963 9a525d83 Michael Hanselmann
  def call_master_info(cls, node_list):
964 72737a7f Iustin Pop
    """Query master info.
965 4e071d3b Iustin Pop

966 72737a7f Iustin Pop
    This is a multi-node call.
967 a8083063 Iustin Pop

968 72737a7f Iustin Pop
    """
969 72737a7f Iustin Pop
    # TODO: should this method query down nodes?
970 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "master_info", [])
971 a8083063 Iustin Pop
972 8f215968 Michael Hanselmann
  @classmethod
973 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
974 8f215968 Michael Hanselmann
  def call_version(cls, node_list):
975 72737a7f Iustin Pop
    """Query node version.
976 a8083063 Iustin Pop

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

979 72737a7f Iustin Pop
    """
980 8f215968 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "version", [])
981 a8083063 Iustin Pop
982 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
983 72737a7f Iustin Pop
  def call_blockdev_create(self, node, bdev, size, owner, on_primary, info):
984 72737a7f Iustin Pop
    """Request creation of a given block device.
985 a8083063 Iustin Pop

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

988 72737a7f Iustin Pop
    """
989 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_create",
990 9a525d83 Michael Hanselmann
                                [bdev.ToDict(), size, owner, on_primary, info])
991 a8083063 Iustin Pop
992 271b7cf9 René Nussbaumer
  @_RpcTimeout(_TMO_SLOW)
993 271b7cf9 René Nussbaumer
  def call_blockdev_wipe(self, node, bdev, offset, size):
994 271b7cf9 René Nussbaumer
    """Request wipe at given offset with given size of a block device.
995 271b7cf9 René Nussbaumer

996 271b7cf9 René Nussbaumer
    This is a single-node call.
997 271b7cf9 René Nussbaumer

998 271b7cf9 René Nussbaumer
    """
999 271b7cf9 René Nussbaumer
    return self._SingleNodeCall(node, "blockdev_wipe",
1000 271b7cf9 René Nussbaumer
                                [bdev.ToDict(), offset, size])
1001 271b7cf9 René Nussbaumer
1002 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1003 72737a7f Iustin Pop
  def call_blockdev_remove(self, node, bdev):
1004 72737a7f Iustin Pop
    """Request removal of a given block device.
1005 a8083063 Iustin Pop

1006 72737a7f Iustin Pop
    This is a single-node call.
1007 f3e513ad Iustin Pop

1008 72737a7f Iustin Pop
    """
1009 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_remove", [bdev.ToDict()])
1010 f3e513ad Iustin Pop
1011 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1012 72737a7f Iustin Pop
  def call_blockdev_rename(self, node, devlist):
1013 72737a7f Iustin Pop
    """Request rename of the given block devices.
1014 f3e513ad Iustin Pop

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

1017 72737a7f Iustin Pop
    """
1018 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_rename",
1019 9a525d83 Michael Hanselmann
                                [(d.ToDict(), uid) for d, uid in devlist])
1020 a8083063 Iustin Pop
1021 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1022 9c007da8 René Nussbaumer
  def call_blockdev_pause_resume_sync(self, node, disks, pause):
1023 9c007da8 René Nussbaumer
    """Request a pause/resume of given block device.
1024 9c007da8 René Nussbaumer

1025 9c007da8 René Nussbaumer
    This is a single-node call.
1026 9c007da8 René Nussbaumer

1027 9c007da8 René Nussbaumer
    """
1028 9c007da8 René Nussbaumer
    return self._SingleNodeCall(node, "blockdev_pause_resume_sync",
1029 9c007da8 René Nussbaumer
                                [[bdev.ToDict() for bdev in disks], pause])
1030 9c007da8 René Nussbaumer
1031 9c007da8 René Nussbaumer
  @_RpcTimeout(_TMO_NORMAL)
1032 c417e115 Iustin Pop
  def call_blockdev_assemble(self, node, disk, owner, on_primary, idx):
1033 72737a7f Iustin Pop
    """Request assembling of a given block device.
1034 a8083063 Iustin Pop

1035 72737a7f Iustin Pop
    This is a single-node call.
1036 a8083063 Iustin Pop

1037 72737a7f Iustin Pop
    """
1038 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_assemble",
1039 c417e115 Iustin Pop
                                [disk.ToDict(), owner, on_primary, idx])
1040 a8083063 Iustin Pop
1041 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1042 72737a7f Iustin Pop
  def call_blockdev_shutdown(self, node, disk):
1043 72737a7f Iustin Pop
    """Request shutdown of a given block device.
1044 a8083063 Iustin Pop

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

1047 72737a7f Iustin Pop
    """
1048 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_shutdown", [disk.ToDict()])
1049 a8083063 Iustin Pop
1050 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1051 72737a7f Iustin Pop
  def call_blockdev_addchildren(self, node, bdev, ndevs):
1052 72737a7f Iustin Pop
    """Request adding a list of children to a (mirroring) device.
1053 a8083063 Iustin Pop

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

1056 72737a7f Iustin Pop
    """
1057 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_addchildren",
1058 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
1059 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
1060 a8083063 Iustin Pop
1061 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1062 72737a7f Iustin Pop
  def call_blockdev_removechildren(self, node, bdev, ndevs):
1063 72737a7f Iustin Pop
    """Request removing a list of children from a (mirroring) device.
1064 a8083063 Iustin Pop

1065 72737a7f Iustin Pop
    This is a single-node call.
1066 a8083063 Iustin Pop

1067 72737a7f Iustin Pop
    """
1068 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_removechildren",
1069 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
1070 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
1071 a8083063 Iustin Pop
1072 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1073 72737a7f Iustin Pop
  def call_blockdev_getmirrorstatus(self, node, disks):
1074 72737a7f Iustin Pop
    """Request status of a (mirroring) device.
1075 a8083063 Iustin Pop

1076 72737a7f Iustin Pop
    This is a single-node call.
1077 a8083063 Iustin Pop

1078 72737a7f Iustin Pop
    """
1079 36145b12 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_getmirrorstatus",
1080 36145b12 Michael Hanselmann
                                  [dsk.ToDict() for dsk in disks])
1081 edb4b374 Michael Hanselmann
    if not result.fail_msg:
1082 36145b12 Michael Hanselmann
      result.payload = [objects.BlockDevStatus.FromDict(i)
1083 36145b12 Michael Hanselmann
                        for i in result.payload]
1084 36145b12 Michael Hanselmann
    return result
1085 a8083063 Iustin Pop
1086 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1087 b8d26c6e Michael Hanselmann
  def call_blockdev_getmirrorstatus_multi(self, node_list, node_disks):
1088 b8d26c6e Michael Hanselmann
    """Request status of (mirroring) devices from multiple nodes.
1089 b8d26c6e Michael Hanselmann

1090 b8d26c6e Michael Hanselmann
    This is a multi-node call.
1091 b8d26c6e Michael Hanselmann

1092 b8d26c6e Michael Hanselmann
    """
1093 b8d26c6e Michael Hanselmann
    result = self._MultiNodeCall(node_list, "blockdev_getmirrorstatus_multi",
1094 b8d26c6e Michael Hanselmann
                                 [dict((name, [dsk.ToDict() for dsk in disks])
1095 b8d26c6e Michael Hanselmann
                                       for name, disks in node_disks.items())])
1096 b8d26c6e Michael Hanselmann
    for nres in result.values():
1097 c6a9dffa Michael Hanselmann
      if nres.fail_msg:
1098 c6a9dffa Michael Hanselmann
        continue
1099 c6a9dffa Michael Hanselmann
1100 c6a9dffa Michael Hanselmann
      for idx, (success, status) in enumerate(nres.payload):
1101 c6a9dffa Michael Hanselmann
        if success:
1102 c6a9dffa Michael Hanselmann
          nres.payload[idx] = (success, objects.BlockDevStatus.FromDict(status))
1103 c6a9dffa Michael Hanselmann
1104 b8d26c6e Michael Hanselmann
    return result
1105 b8d26c6e Michael Hanselmann
1106 b8d26c6e Michael Hanselmann
  @_RpcTimeout(_TMO_NORMAL)
1107 72737a7f Iustin Pop
  def call_blockdev_find(self, node, disk):
1108 72737a7f Iustin Pop
    """Request identification of a given block device.
1109 72737a7f Iustin Pop

1110 72737a7f Iustin Pop
    This is a single-node call.
1111 a8083063 Iustin Pop

1112 72737a7f Iustin Pop
    """
1113 96acbc09 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_find", [disk.ToDict()])
1114 edb4b374 Michael Hanselmann
    if not result.fail_msg and result.payload is not None:
1115 96acbc09 Michael Hanselmann
      result.payload = objects.BlockDevStatus.FromDict(result.payload)
1116 96acbc09 Michael Hanselmann
    return result
1117 d61cbe76 Iustin Pop
1118 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1119 b2e7666a Iustin Pop
  def call_blockdev_close(self, node, instance_name, disks):
1120 72737a7f Iustin Pop
    """Closes the given block devices.
1121 d61cbe76 Iustin Pop

1122 72737a7f Iustin Pop
    This is a single-node call.
1123 d61cbe76 Iustin Pop

1124 72737a7f Iustin Pop
    """
1125 b2e7666a Iustin Pop
    params = [instance_name, [cf.ToDict() for cf in disks]]
1126 b2e7666a Iustin Pop
    return self._SingleNodeCall(node, "blockdev_close", params)
1127 a8083063 Iustin Pop
1128 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1129 ccfbbd2d Iustin Pop
  def call_blockdev_getsize(self, node, disks):
1130 968a7623 Iustin Pop
    """Returns the size of the given disks.
1131 968a7623 Iustin Pop

1132 968a7623 Iustin Pop
    This is a single-node call.
1133 968a7623 Iustin Pop

1134 968a7623 Iustin Pop
    """
1135 968a7623 Iustin Pop
    params = [[cf.ToDict() for cf in disks]]
1136 968a7623 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_getsize", params)
1137 968a7623 Iustin Pop
1138 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1139 6b93ec9d Iustin Pop
  def call_drbd_disconnect_net(self, node_list, nodes_ip, disks):
1140 6b93ec9d Iustin Pop
    """Disconnects the network of the given drbd devices.
1141 6b93ec9d Iustin Pop

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

1144 6b93ec9d Iustin Pop
    """
1145 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_disconnect_net",
1146 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1147 6b93ec9d Iustin Pop
1148 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1149 6b93ec9d Iustin Pop
  def call_drbd_attach_net(self, node_list, nodes_ip,
1150 6b93ec9d Iustin Pop
                           disks, instance_name, multimaster):
1151 6b93ec9d Iustin Pop
    """Disconnects the given drbd devices.
1152 6b93ec9d Iustin Pop

1153 6b93ec9d Iustin Pop
    This is a multi-node call.
1154 6b93ec9d Iustin Pop

1155 6b93ec9d Iustin Pop
    """
1156 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_attach_net",
1157 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks],
1158 6b93ec9d Iustin Pop
                                instance_name, multimaster])
1159 6b93ec9d Iustin Pop
1160 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
1161 6b93ec9d Iustin Pop
  def call_drbd_wait_sync(self, node_list, nodes_ip, disks):
1162 6b93ec9d Iustin Pop
    """Waits for the synchronization of drbd devices is complete.
1163 6b93ec9d Iustin Pop

1164 6b93ec9d Iustin Pop
    This is a multi-node call.
1165 6b93ec9d Iustin Pop

1166 6b93ec9d Iustin Pop
    """
1167 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_wait_sync",
1168 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1169 6b93ec9d Iustin Pop
1170 c46b9782 Luca Bigliardi
  @_RpcTimeout(_TMO_URGENT)
1171 c46b9782 Luca Bigliardi
  def call_drbd_helper(self, node_list):
1172 c46b9782 Luca Bigliardi
    """Gets drbd helper.
1173 c46b9782 Luca Bigliardi

1174 c46b9782 Luca Bigliardi
    This is a multi-node call.
1175 c46b9782 Luca Bigliardi

1176 c46b9782 Luca Bigliardi
    """
1177 c46b9782 Luca Bigliardi
    return self._MultiNodeCall(node_list, "drbd_helper", [])
1178 c46b9782 Luca Bigliardi
1179 9a525d83 Michael Hanselmann
  @classmethod
1180 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1181 9a525d83 Michael Hanselmann
  def call_upload_file(cls, node_list, file_name, address_list=None):
1182 72737a7f Iustin Pop
    """Upload a file.
1183 72737a7f Iustin Pop

1184 72737a7f Iustin Pop
    The node will refuse the operation in case the file is not on the
1185 72737a7f Iustin Pop
    approved file list.
1186 72737a7f Iustin Pop

1187 72737a7f Iustin Pop
    This is a multi-node call.
1188 a8083063 Iustin Pop

1189 6b294c53 Iustin Pop
    @type node_list: list
1190 6b294c53 Iustin Pop
    @param node_list: the list of node names to upload to
1191 6b294c53 Iustin Pop
    @type file_name: str
1192 6b294c53 Iustin Pop
    @param file_name: the filename to upload
1193 6b294c53 Iustin Pop
    @type address_list: list or None
1194 6b294c53 Iustin Pop
    @keyword address_list: an optional list of node addresses, in order
1195 6b294c53 Iustin Pop
        to optimize the RPC speed
1196 6b294c53 Iustin Pop

1197 72737a7f Iustin Pop
    """
1198 12bce260 Michael Hanselmann
    file_contents = utils.ReadFile(file_name)
1199 12bce260 Michael Hanselmann
    data = cls._Compress(file_contents)
1200 72737a7f Iustin Pop
    st = os.stat(file_name)
1201 9a914f7a René Nussbaumer
    getents = runtime.GetEnts()
1202 9a914f7a René Nussbaumer
    params = [file_name, data, st.st_mode, getents.LookupUid(st.st_uid),
1203 9a914f7a René Nussbaumer
              getents.LookupGid(st.st_gid), st.st_atime, st.st_mtime]
1204 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "upload_file", params,
1205 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1206 72737a7f Iustin Pop
1207 6ddc95ec Michael Hanselmann
  @classmethod
1208 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1209 03d1dba2 Michael Hanselmann
  def call_write_ssconf_files(cls, node_list, values):
1210 6ddc95ec Michael Hanselmann
    """Write ssconf files.
1211 6ddc95ec Michael Hanselmann

1212 6ddc95ec Michael Hanselmann
    This is a multi-node call.
1213 6ddc95ec Michael Hanselmann

1214 6ddc95ec Michael Hanselmann
    """
1215 03d1dba2 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "write_ssconf_files", [values])
1216 6ddc95ec Michael Hanselmann
1217 4f6014d4 René Nussbaumer
  @_RpcTimeout(_TMO_NORMAL)
1218 0092d621 René Nussbaumer
  def call_run_oob(self, node, oob_program, command, remote_node, timeout):
1219 4f6014d4 René Nussbaumer
    """Runs OOB.
1220 4f6014d4 René Nussbaumer

1221 4f6014d4 René Nussbaumer
    This is a single-node call.
1222 4f6014d4 René Nussbaumer

1223 4f6014d4 René Nussbaumer
    """
1224 4f6014d4 René Nussbaumer
    return self._SingleNodeCall(node, "run_oob", [oob_program, command,
1225 0092d621 René Nussbaumer
                                                  remote_node, timeout])
1226 4f6014d4 René Nussbaumer
1227 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1228 72737a7f Iustin Pop
  def call_os_diagnose(self, node_list):
1229 72737a7f Iustin Pop
    """Request a diagnose of OS definitions.
1230 72737a7f Iustin Pop

1231 72737a7f Iustin Pop
    This is a multi-node call.
1232 a8083063 Iustin Pop

1233 72737a7f Iustin Pop
    """
1234 83d92ad8 Iustin Pop
    return self._MultiNodeCall(node_list, "os_diagnose", [])
1235 a8083063 Iustin Pop
1236 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1237 72737a7f Iustin Pop
  def call_os_get(self, node, name):
1238 72737a7f Iustin Pop
    """Returns an OS definition.
1239 a8083063 Iustin Pop

1240 72737a7f Iustin Pop
    This is a single-node call.
1241 a8083063 Iustin Pop

1242 72737a7f Iustin Pop
    """
1243 9a525d83 Michael Hanselmann
    result = self._SingleNodeCall(node, "os_get", [name])
1244 84e3f66f Guido Trotter
    if not result.fail_msg and isinstance(result.payload, dict):
1245 84e3f66f Guido Trotter
      result.payload = objects.OS.FromDict(result.payload)
1246 781de953 Iustin Pop
    return result
1247 a8083063 Iustin Pop
1248 acd9ff9e Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1249 acd9ff9e Iustin Pop
  def call_os_validate(self, required, nodes, name, checks, params):
1250 acd9ff9e Iustin Pop
    """Run a validation routine for a given OS.
1251 acd9ff9e Iustin Pop

1252 acd9ff9e Iustin Pop
    This is a multi-node call.
1253 acd9ff9e Iustin Pop

1254 acd9ff9e Iustin Pop
    """
1255 acd9ff9e Iustin Pop
    return self._MultiNodeCall(nodes, "os_validate",
1256 acd9ff9e Iustin Pop
                               [required, name, checks, params])
1257 acd9ff9e Iustin Pop
1258 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1259 72737a7f Iustin Pop
  def call_hooks_runner(self, node_list, hpath, phase, env):
1260 72737a7f Iustin Pop
    """Call the hooks runner.
1261 a8083063 Iustin Pop

1262 72737a7f Iustin Pop
    Args:
1263 72737a7f Iustin Pop
      - op: the OpCode instance
1264 72737a7f Iustin Pop
      - env: a dictionary with the environment
1265 a8083063 Iustin Pop

1266 72737a7f Iustin Pop
    This is a multi-node call.
1267 a8083063 Iustin Pop

1268 72737a7f Iustin Pop
    """
1269 72737a7f Iustin Pop
    params = [hpath, phase, env]
1270 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hooks_runner", params)
1271 a8083063 Iustin Pop
1272 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1273 72737a7f Iustin Pop
  def call_iallocator_runner(self, node, name, idata):
1274 72737a7f Iustin Pop
    """Call an iallocator on a remote node
1275 8d528b7c Iustin Pop

1276 72737a7f Iustin Pop
    Args:
1277 72737a7f Iustin Pop
      - name: the iallocator name
1278 72737a7f Iustin Pop
      - input: the json-encoded input string
1279 8d528b7c Iustin Pop

1280 72737a7f Iustin Pop
    This is a single-node call.
1281 8d528b7c Iustin Pop

1282 72737a7f Iustin Pop
    """
1283 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "iallocator_runner", [name, idata])
1284 8d528b7c Iustin Pop
1285 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1286 a59faf4b Iustin Pop
  def call_blockdev_grow(self, node, cf_bdev, amount, dryrun):
1287 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1288 4c8ba8b3 Iustin Pop

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

1291 72737a7f Iustin Pop
    """
1292 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_grow",
1293 a59faf4b Iustin Pop
                                [cf_bdev.ToDict(), amount, dryrun])
1294 4c8ba8b3 Iustin Pop
1295 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_1DAY)
1296 858f3d18 Iustin Pop
  def call_blockdev_export(self, node, cf_bdev,
1297 858f3d18 Iustin Pop
                           dest_node, dest_path, cluster_name):
1298 858f3d18 Iustin Pop
    """Export a given disk to another node.
1299 858f3d18 Iustin Pop

1300 858f3d18 Iustin Pop
    This is a single-node call.
1301 858f3d18 Iustin Pop

1302 858f3d18 Iustin Pop
    """
1303 858f3d18 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_export",
1304 858f3d18 Iustin Pop
                                [cf_bdev.ToDict(), dest_node, dest_path,
1305 858f3d18 Iustin Pop
                                 cluster_name])
1306 858f3d18 Iustin Pop
1307 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1308 72737a7f Iustin Pop
  def call_blockdev_snapshot(self, node, cf_bdev):
1309 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1310 a8083063 Iustin Pop

1311 72737a7f Iustin Pop
    This is a single-node call.
1312 a8083063 Iustin Pop

1313 72737a7f Iustin Pop
    """
1314 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_snapshot", [cf_bdev.ToDict()])
1315 a8083063 Iustin Pop
1316 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1317 72737a7f Iustin Pop
  def call_finalize_export(self, node, instance, snap_disks):
1318 72737a7f Iustin Pop
    """Request the completion of an export operation.
1319 a8083063 Iustin Pop

1320 72737a7f Iustin Pop
    This writes the export config file, etc.
1321 a8083063 Iustin Pop

1322 72737a7f Iustin Pop
    This is a single-node call.
1323 a8083063 Iustin Pop

1324 72737a7f Iustin Pop
    """
1325 72737a7f Iustin Pop
    flat_disks = []
1326 72737a7f Iustin Pop
    for disk in snap_disks:
1327 a97da6b7 Iustin Pop
      if isinstance(disk, bool):
1328 a97da6b7 Iustin Pop
        flat_disks.append(disk)
1329 a97da6b7 Iustin Pop
      else:
1330 a97da6b7 Iustin Pop
        flat_disks.append(disk.ToDict())
1331 9a525d83 Michael Hanselmann
1332 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "finalize_export",
1333 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), flat_disks])
1334 a8083063 Iustin Pop
1335 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1336 72737a7f Iustin Pop
  def call_export_info(self, node, path):
1337 72737a7f Iustin Pop
    """Queries the export information in a given path.
1338 a8083063 Iustin Pop

1339 72737a7f Iustin Pop
    This is a single-node call.
1340 a8083063 Iustin Pop

1341 72737a7f Iustin Pop
    """
1342 3eccac06 Iustin Pop
    return self._SingleNodeCall(node, "export_info", [path])
1343 a8083063 Iustin Pop
1344 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1345 72737a7f Iustin Pop
  def call_export_list(self, node_list):
1346 72737a7f Iustin Pop
    """Gets the stored exports list.
1347 a8083063 Iustin Pop

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

1350 72737a7f Iustin Pop
    """
1351 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "export_list", [])
1352 a8083063 Iustin Pop
1353 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1354 72737a7f Iustin Pop
  def call_export_remove(self, node, export):
1355 72737a7f Iustin Pop
    """Requests removal of a given export.
1356 a8083063 Iustin Pop

1357 72737a7f Iustin Pop
    This is a single-node call.
1358 a8083063 Iustin Pop

1359 72737a7f Iustin Pop
    """
1360 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "export_remove", [export])
1361 a8083063 Iustin Pop
1362 9a525d83 Michael Hanselmann
  @classmethod
1363 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1364 b989b9d9 Ken Wehr
  def call_node_leave_cluster(cls, node, modify_ssh_setup):
1365 72737a7f Iustin Pop
    """Requests a node to clean the cluster information it has.
1366 a8083063 Iustin Pop

1367 72737a7f Iustin Pop
    This will remove the configuration information from the ganeti data
1368 72737a7f Iustin Pop
    dir.
1369 a8083063 Iustin Pop

1370 72737a7f Iustin Pop
    This is a single-node call.
1371 a8083063 Iustin Pop

1372 72737a7f Iustin Pop
    """
1373 b989b9d9 Ken Wehr
    return cls._StaticSingleNodeCall(node, "node_leave_cluster",
1374 b989b9d9 Ken Wehr
                                     [modify_ssh_setup])
1375 dcb93971 Michael Hanselmann
1376 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1377 72737a7f Iustin Pop
  def call_node_volumes(self, node_list):
1378 72737a7f Iustin Pop
    """Gets all volumes on node(s).
1379 dcb93971 Michael Hanselmann

1380 72737a7f Iustin Pop
    This is a multi-node call.
1381 dcb93971 Michael Hanselmann

1382 72737a7f Iustin Pop
    """
1383 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_volumes", [])
1384 06009e27 Iustin Pop
1385 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1386 56aa9fd5 Iustin Pop
  def call_node_demote_from_mc(self, node):
1387 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
1388 56aa9fd5 Iustin Pop

1389 56aa9fd5 Iustin Pop
    This is a single-node call.
1390 56aa9fd5 Iustin Pop

1391 56aa9fd5 Iustin Pop
    """
1392 56aa9fd5 Iustin Pop
    return self._SingleNodeCall(node, "node_demote_from_mc", [])
1393 56aa9fd5 Iustin Pop
1394 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1395 f5118ade Iustin Pop
  def call_node_powercycle(self, node, hypervisor):
1396 f5118ade Iustin Pop
    """Tries to powercycle a node.
1397 f5118ade Iustin Pop

1398 f5118ade Iustin Pop
    This is a single-node call.
1399 f5118ade Iustin Pop

1400 f5118ade Iustin Pop
    """
1401 f5118ade Iustin Pop
    return self._SingleNodeCall(node, "node_powercycle", [hypervisor])
1402 f5118ade Iustin Pop
1403 92fd2250 Iustin Pop
  @_RpcTimeout(None)
1404 72737a7f Iustin Pop
  def call_test_delay(self, node_list, duration):
1405 72737a7f Iustin Pop
    """Sleep for a fixed time on given node(s).
1406 06009e27 Iustin Pop

1407 72737a7f Iustin Pop
    This is a multi-node call.
1408 06009e27 Iustin Pop

1409 72737a7f Iustin Pop
    """
1410 92fd2250 Iustin Pop
    return self._MultiNodeCall(node_list, "test_delay", [duration],
1411 92fd2250 Iustin Pop
                               read_timeout=int(duration + 5))
1412 5e04ed8b Manuel Franceschini
1413 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1414 72737a7f Iustin Pop
  def call_file_storage_dir_create(self, node, file_storage_dir):
1415 72737a7f Iustin Pop
    """Create the given file storage directory.
1416 5e04ed8b Manuel Franceschini

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

1419 72737a7f Iustin Pop
    """
1420 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_create",
1421 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1422 5e04ed8b Manuel Franceschini
1423 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1424 72737a7f Iustin Pop
  def call_file_storage_dir_remove(self, node, file_storage_dir):
1425 72737a7f Iustin Pop
    """Remove the given file storage directory.
1426 5e04ed8b Manuel Franceschini

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

1429 72737a7f Iustin Pop
    """
1430 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_remove",
1431 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1432 5e04ed8b Manuel Franceschini
1433 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1434 72737a7f Iustin Pop
  def call_file_storage_dir_rename(self, node, old_file_storage_dir,
1435 72737a7f Iustin Pop
                                   new_file_storage_dir):
1436 72737a7f Iustin Pop
    """Rename file storage directory.
1437 5e04ed8b Manuel Franceschini

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

1440 72737a7f Iustin Pop
    """
1441 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_rename",
1442 9a525d83 Michael Hanselmann
                                [old_file_storage_dir, new_file_storage_dir])
1443 ca52cdeb Michael Hanselmann
1444 9a525d83 Michael Hanselmann
  @classmethod
1445 d2cd6944 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
1446 9a525d83 Michael Hanselmann
  def call_jobqueue_update(cls, node_list, address_list, file_name, content):
1447 72737a7f Iustin Pop
    """Update job queue.
1448 ca52cdeb Michael Hanselmann

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

1451 72737a7f Iustin Pop
    """
1452 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_update",
1453 12bce260 Michael Hanselmann
                                    [file_name, cls._Compress(content)],
1454 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1455 ca52cdeb Michael Hanselmann
1456 9a525d83 Michael Hanselmann
  @classmethod
1457 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1458 9a525d83 Michael Hanselmann
  def call_jobqueue_purge(cls, node):
1459 72737a7f Iustin Pop
    """Purge job queue.
1460 ca52cdeb Michael Hanselmann

1461 72737a7f Iustin Pop
    This is a single-node call.
1462 ca52cdeb Michael Hanselmann

1463 72737a7f Iustin Pop
    """
1464 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "jobqueue_purge", [])
1465 af5ebcb1 Michael Hanselmann
1466 9a525d83 Michael Hanselmann
  @classmethod
1467 d2cd6944 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
1468 dd875d32 Michael Hanselmann
  def call_jobqueue_rename(cls, node_list, address_list, rename):
1469 72737a7f Iustin Pop
    """Rename a job queue file.
1470 af5ebcb1 Michael Hanselmann

1471 72737a7f Iustin Pop
    This is a multi-node call.
1472 af5ebcb1 Michael Hanselmann

1473 72737a7f Iustin Pop
    """
1474 dd875d32 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_rename", rename,
1475 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1476 6217e295 Iustin Pop
1477 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1478 6217e295 Iustin Pop
  def call_hypervisor_validate_params(self, node_list, hvname, hvparams):
1479 6217e295 Iustin Pop
    """Validate the hypervisor params.
1480 6217e295 Iustin Pop

1481 6217e295 Iustin Pop
    This is a multi-node call.
1482 6217e295 Iustin Pop

1483 6217e295 Iustin Pop
    @type node_list: list
1484 6217e295 Iustin Pop
    @param node_list: the list of nodes to query
1485 6217e295 Iustin Pop
    @type hvname: string
1486 6217e295 Iustin Pop
    @param hvname: the hypervisor name
1487 6217e295 Iustin Pop
    @type hvparams: dict
1488 6217e295 Iustin Pop
    @param hvparams: the hypervisor parameters to be validated
1489 6217e295 Iustin Pop

1490 6217e295 Iustin Pop
    """
1491 6217e295 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
1492 abe609b2 Guido Trotter
    hv_full = objects.FillDict(cluster.hvparams.get(hvname, {}), hvparams)
1493 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hypervisor_validate_params",
1494 9a525d83 Michael Hanselmann
                               [hvname, hv_full])
1495 f942a838 Michael Hanselmann
1496 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1497 37549316 Michael Hanselmann
  def call_x509_cert_create(self, node, validity):
1498 f942a838 Michael Hanselmann
    """Creates a new X509 certificate for SSL/TLS.
1499 f942a838 Michael Hanselmann

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

1502 f942a838 Michael Hanselmann
    @type validity: int
1503 f942a838 Michael Hanselmann
    @param validity: Validity in seconds
1504 f942a838 Michael Hanselmann

1505 f942a838 Michael Hanselmann
    """
1506 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_create", [validity])
1507 f942a838 Michael Hanselmann
1508 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1509 37549316 Michael Hanselmann
  def call_x509_cert_remove(self, node, name):
1510 f942a838 Michael Hanselmann
    """Removes a X509 certificate.
1511 f942a838 Michael Hanselmann

1512 f942a838 Michael Hanselmann
    This is a single-node call.
1513 f942a838 Michael Hanselmann

1514 f942a838 Michael Hanselmann
    @type name: string
1515 f942a838 Michael Hanselmann
    @param name: Certificate name
1516 f942a838 Michael Hanselmann

1517 f942a838 Michael Hanselmann
    """
1518 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_remove", [name])
1519 1651d116 Michael Hanselmann
1520 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1521 6613661a Iustin Pop
  def call_import_start(self, node, opts, instance, component,
1522 6613661a Iustin Pop
                        dest, dest_args):
1523 1651d116 Michael Hanselmann
    """Starts a listener for an import.
1524 1651d116 Michael Hanselmann

1525 1651d116 Michael Hanselmann
    This is a single-node call.
1526 1651d116 Michael Hanselmann

1527 1651d116 Michael Hanselmann
    @type node: string
1528 1651d116 Michael Hanselmann
    @param node: Node name
1529 1651d116 Michael Hanselmann
    @type instance: C{objects.Instance}
1530 1651d116 Michael Hanselmann
    @param instance: Instance object
1531 6613661a Iustin Pop
    @type component: string
1532 6613661a Iustin Pop
    @param component: which part of the instance is being imported
1533 1651d116 Michael Hanselmann

1534 1651d116 Michael Hanselmann
    """
1535 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "import_start",
1536 eb630f50 Michael Hanselmann
                                [opts.ToDict(),
1537 6613661a Iustin Pop
                                 self._InstDict(instance), component, dest,
1538 1651d116 Michael Hanselmann
                                 _EncodeImportExportIO(dest, dest_args)])
1539 1651d116 Michael Hanselmann
1540 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1541 eb630f50 Michael Hanselmann
  def call_export_start(self, node, opts, host, port,
1542 6613661a Iustin Pop
                        instance, component, source, source_args):
1543 1651d116 Michael Hanselmann
    """Starts an export daemon.
1544 1651d116 Michael Hanselmann

1545 1651d116 Michael Hanselmann
    This is a single-node call.
1546 1651d116 Michael Hanselmann

1547 1651d116 Michael Hanselmann
    @type node: string
1548 1651d116 Michael Hanselmann
    @param node: Node name
1549 1651d116 Michael Hanselmann
    @type instance: C{objects.Instance}
1550 1651d116 Michael Hanselmann
    @param instance: Instance object
1551 6613661a Iustin Pop
    @type component: string
1552 6613661a Iustin Pop
    @param component: which part of the instance is being imported
1553 1651d116 Michael Hanselmann

1554 1651d116 Michael Hanselmann
    """
1555 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "export_start",
1556 eb630f50 Michael Hanselmann
                                [opts.ToDict(), host, port,
1557 6613661a Iustin Pop
                                 self._InstDict(instance),
1558 6613661a Iustin Pop
                                 component, source,
1559 1651d116 Michael Hanselmann
                                 _EncodeImportExportIO(source, source_args)])
1560 1651d116 Michael Hanselmann
1561 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1562 ef40fbfb Michael Hanselmann
  def call_impexp_status(self, node, names):
1563 1651d116 Michael Hanselmann
    """Gets the status of 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 names: List of strings
1570 1651d116 Michael Hanselmann
    @param names: Import/export names
1571 1651d116 Michael Hanselmann
    @rtype: List of L{objects.ImportExportStatus} instances
1572 1651d116 Michael Hanselmann
    @return: Returns a list of the state of each named import/export or None if
1573 1651d116 Michael Hanselmann
             a status couldn't be retrieved
1574 1651d116 Michael Hanselmann

1575 1651d116 Michael Hanselmann
    """
1576 ef40fbfb Michael Hanselmann
    result = self._SingleNodeCall(node, "impexp_status", [names])
1577 1651d116 Michael Hanselmann
1578 1651d116 Michael Hanselmann
    if not result.fail_msg:
1579 1651d116 Michael Hanselmann
      decoded = []
1580 1651d116 Michael Hanselmann
1581 1651d116 Michael Hanselmann
      for i in result.payload:
1582 1651d116 Michael Hanselmann
        if i is None:
1583 1651d116 Michael Hanselmann
          decoded.append(None)
1584 1651d116 Michael Hanselmann
          continue
1585 1651d116 Michael Hanselmann
        decoded.append(objects.ImportExportStatus.FromDict(i))
1586 1651d116 Michael Hanselmann
1587 1651d116 Michael Hanselmann
      result.payload = decoded
1588 1651d116 Michael Hanselmann
1589 1651d116 Michael Hanselmann
    return result
1590 1651d116 Michael Hanselmann
1591 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1592 f81c4737 Michael Hanselmann
  def call_impexp_abort(self, node, name):
1593 f81c4737 Michael Hanselmann
    """Aborts an import or export.
1594 f81c4737 Michael Hanselmann

1595 f81c4737 Michael Hanselmann
    This is a single-node call.
1596 f81c4737 Michael Hanselmann

1597 f81c4737 Michael Hanselmann
    @type node: string
1598 f81c4737 Michael Hanselmann
    @param node: Node name
1599 f81c4737 Michael Hanselmann
    @type name: string
1600 f81c4737 Michael Hanselmann
    @param name: Import/export name
1601 f81c4737 Michael Hanselmann

1602 f81c4737 Michael Hanselmann
    """
1603 f81c4737 Michael Hanselmann
    return self._SingleNodeCall(node, "impexp_abort", [name])
1604 f81c4737 Michael Hanselmann
1605 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1606 ef40fbfb Michael Hanselmann
  def call_impexp_cleanup(self, node, name):
1607 1651d116 Michael Hanselmann
    """Cleans up after an import or export.
1608 1651d116 Michael Hanselmann

1609 1651d116 Michael Hanselmann
    This is a single-node call.
1610 1651d116 Michael Hanselmann

1611 1651d116 Michael Hanselmann
    @type node: string
1612 1651d116 Michael Hanselmann
    @param node: Node name
1613 1651d116 Michael Hanselmann
    @type name: string
1614 1651d116 Michael Hanselmann
    @param name: Import/export name
1615 1651d116 Michael Hanselmann

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