Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ d6f8db24

History | View | Annotate | Download (47.7 kB)

1 2f31098c Iustin Pop
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 d2cd6944 Iustin Pop
# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 3ef3c771 Iustin Pop
"""Inter-node RPC library.
23 a8083063 Iustin Pop

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

88 33231500 Michael Hanselmann
  Must be called before using any RPC function and while exactly one thread is
89 33231500 Michael Hanselmann
  running.
90 4331f6cd Michael Hanselmann

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

106 33231500 Michael Hanselmann
  Must be called before quitting the program and while exactly one thread is
107 33231500 Michael Hanselmann
  running.
108 4331f6cd Michael Hanselmann

109 4331f6cd Michael Hanselmann
  """
110 33231500 Michael Hanselmann
  pycurl.global_cleanup()
111 33231500 Michael Hanselmann
112 33231500 Michael Hanselmann
113 33231500 Michael Hanselmann
def _ConfigRpcCurl(curl):
114 33231500 Michael Hanselmann
  noded_cert = str(constants.NODED_CERT_FILE)
115 4331f6cd Michael Hanselmann
116 33231500 Michael Hanselmann
  curl.setopt(pycurl.FOLLOWLOCATION, False)
117 33231500 Michael Hanselmann
  curl.setopt(pycurl.CAINFO, noded_cert)
118 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSL_VERIFYHOST, 0)
119 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSL_VERIFYPEER, True)
120 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSLCERTTYPE, "PEM")
121 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSLCERT, noded_cert)
122 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSLKEYTYPE, "PEM")
123 33231500 Michael Hanselmann
  curl.setopt(pycurl.SSLKEY, noded_cert)
124 33231500 Michael Hanselmann
  curl.setopt(pycurl.CONNECTTIMEOUT, _RPC_CONNECT_TIMEOUT)
125 33231500 Michael Hanselmann
126 33231500 Michael Hanselmann
127 92fd2250 Iustin Pop
def _RpcTimeout(secs):
128 92fd2250 Iustin Pop
  """Timeout decorator.
129 92fd2250 Iustin Pop

130 92fd2250 Iustin Pop
  When applied to a rpc call_* function, it updates the global timeout
131 92fd2250 Iustin Pop
  table with the given function/timeout.
132 92fd2250 Iustin Pop

133 92fd2250 Iustin Pop
  """
134 92fd2250 Iustin Pop
  def decorator(f):
135 92fd2250 Iustin Pop
    name = f.__name__
136 92fd2250 Iustin Pop
    assert name.startswith("call_")
137 92fd2250 Iustin Pop
    _TIMEOUTS[name[len("call_"):]] = secs
138 92fd2250 Iustin Pop
    return f
139 92fd2250 Iustin Pop
  return decorator
140 92fd2250 Iustin Pop
141 92fd2250 Iustin Pop
142 e0e916fe Iustin Pop
def RunWithRPC(fn):
143 e0e916fe Iustin Pop
  """RPC-wrapper decorator.
144 e0e916fe Iustin Pop

145 e0e916fe Iustin Pop
  When applied to a function, it runs it with the RPC system
146 e0e916fe Iustin Pop
  initialized, and it shutsdown the system afterwards. This means the
147 e0e916fe Iustin Pop
  function must be called without RPC being initialized.
148 e0e916fe Iustin Pop

149 e0e916fe Iustin Pop
  """
150 e0e916fe Iustin Pop
  def wrapper(*args, **kwargs):
151 e0e916fe Iustin Pop
    Init()
152 e0e916fe Iustin Pop
    try:
153 e0e916fe Iustin Pop
      return fn(*args, **kwargs)
154 e0e916fe Iustin Pop
    finally:
155 e0e916fe Iustin Pop
      Shutdown()
156 e0e916fe Iustin Pop
  return wrapper
157 e0e916fe Iustin Pop
158 e0e916fe Iustin Pop
159 30474135 Michael Hanselmann
def _Compress(data):
160 30474135 Michael Hanselmann
  """Compresses a string for transport over RPC.
161 30474135 Michael Hanselmann

162 30474135 Michael Hanselmann
  Small amounts of data are not compressed.
163 30474135 Michael Hanselmann

164 30474135 Michael Hanselmann
  @type data: str
165 30474135 Michael Hanselmann
  @param data: Data
166 30474135 Michael Hanselmann
  @rtype: tuple
167 30474135 Michael Hanselmann
  @return: Encoded data to send
168 30474135 Michael Hanselmann

169 30474135 Michael Hanselmann
  """
170 30474135 Michael Hanselmann
  # Small amounts of data are not compressed
171 30474135 Michael Hanselmann
  if len(data) < 512:
172 30474135 Michael Hanselmann
    return (constants.RPC_ENCODING_NONE, data)
173 30474135 Michael Hanselmann
174 30474135 Michael Hanselmann
  # Compress with zlib and encode in base64
175 30474135 Michael Hanselmann
  return (constants.RPC_ENCODING_ZLIB_BASE64,
176 30474135 Michael Hanselmann
          base64.b64encode(zlib.compress(data, 3)))
177 30474135 Michael Hanselmann
178 30474135 Michael Hanselmann
179 781de953 Iustin Pop
class RpcResult(object):
180 781de953 Iustin Pop
  """RPC Result class.
181 781de953 Iustin Pop

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

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

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

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

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

269 eb202c13 Manuel Franceschini
  @type node_list: list
270 eb202c13 Manuel Franceschini
  @param node_list: List of node names
271 eb202c13 Manuel Franceschini
  @type ssc: class
272 eb202c13 Manuel Franceschini
  @param ssc: SimpleStore class that is used to obtain node->ip mappings
273 17f7fd27 Manuel Franceschini
  @type nslookup_fn: callable
274 17f7fd27 Manuel Franceschini
  @param nslookup_fn: function use to do NS lookup
275 00267bfe Michael Hanselmann
  @rtype: list of tuple; (string, string)
276 00267bfe Michael Hanselmann
  @return: List of tuples containing node name and IP address
277 eb202c13 Manuel Franceschini

278 eb202c13 Manuel Franceschini
  """
279 b43dcc5a Manuel Franceschini
  ss = ssc()
280 b43dcc5a Manuel Franceschini
  iplist = ss.GetNodePrimaryIPList()
281 b43dcc5a Manuel Franceschini
  family = ss.GetPrimaryIPFamily()
282 b705c7a6 Manuel Franceschini
  ipmap = dict(entry.split() for entry in iplist)
283 00267bfe Michael Hanselmann
284 00267bfe Michael Hanselmann
  result = []
285 b705c7a6 Manuel Franceschini
  for node in node_list:
286 00267bfe Michael Hanselmann
    ip = ipmap.get(node)
287 00267bfe Michael Hanselmann
    if ip is None:
288 00267bfe Michael Hanselmann
      ip = nslookup_fn(node, family=family)
289 00267bfe Michael Hanselmann
    result.append((node, ip))
290 00267bfe Michael Hanselmann
291 00267bfe Michael Hanselmann
  return result
292 00267bfe Michael Hanselmann
293 00267bfe Michael Hanselmann
294 00267bfe Michael Hanselmann
class _StaticResolver:
295 00267bfe Michael Hanselmann
  def __init__(self, addresses):
296 00267bfe Michael Hanselmann
    """Initializes this class.
297 00267bfe Michael Hanselmann

298 00267bfe Michael Hanselmann
    """
299 00267bfe Michael Hanselmann
    self._addresses = addresses
300 00267bfe Michael Hanselmann
301 00267bfe Michael Hanselmann
  def __call__(self, hosts):
302 00267bfe Michael Hanselmann
    """Returns static addresses for hosts.
303 00267bfe Michael Hanselmann

304 00267bfe Michael Hanselmann
    """
305 00267bfe Michael Hanselmann
    assert len(hosts) == len(self._addresses)
306 00267bfe Michael Hanselmann
    return zip(hosts, self._addresses)
307 00267bfe Michael Hanselmann
308 eb202c13 Manuel Franceschini
309 00267bfe Michael Hanselmann
def _CheckConfigNode(name, node):
310 00267bfe Michael Hanselmann
  """Checks if a node is online.
311 eb202c13 Manuel Franceschini

312 00267bfe Michael Hanselmann
  @type name: string
313 00267bfe Michael Hanselmann
  @param name: Node name
314 00267bfe Michael Hanselmann
  @type node: L{objects.Node} or None
315 00267bfe Michael Hanselmann
  @param node: Node object
316 eb202c13 Manuel Franceschini

317 00267bfe Michael Hanselmann
  """
318 00267bfe Michael Hanselmann
  if node is None:
319 00267bfe Michael Hanselmann
    # Depend on DNS for name resolution
320 00267bfe Michael Hanselmann
    ip = name
321 00267bfe Michael Hanselmann
  elif node.offline:
322 00267bfe Michael Hanselmann
    ip = _OFFLINE
323 00267bfe Michael Hanselmann
  else:
324 00267bfe Michael Hanselmann
    ip = node.primary_ip
325 00267bfe Michael Hanselmann
  return (name, ip)
326 a8083063 Iustin Pop
327 a8083063 Iustin Pop
328 00267bfe Michael Hanselmann
def _NodeConfigResolver(single_node_fn, all_nodes_fn, hosts):
329 00267bfe Michael Hanselmann
  """Calculate node addresses using configuration.
330 a8083063 Iustin Pop

331 a8083063 Iustin Pop
  """
332 00267bfe Michael Hanselmann
  # Special case for single-host lookups
333 00267bfe Michael Hanselmann
  if len(hosts) == 1:
334 00267bfe Michael Hanselmann
    (name, ) = hosts
335 00267bfe Michael Hanselmann
    return [_CheckConfigNode(name, single_node_fn(name))]
336 00267bfe Michael Hanselmann
  else:
337 00267bfe Michael Hanselmann
    all_nodes = all_nodes_fn()
338 00267bfe Michael Hanselmann
    return [_CheckConfigNode(name, all_nodes.get(name, None))
339 00267bfe Michael Hanselmann
            for name in hosts]
340 00267bfe Michael Hanselmann
341 00267bfe Michael Hanselmann
342 00267bfe Michael Hanselmann
class _RpcProcessor:
343 aea5caef Michael Hanselmann
  def __init__(self, resolver, port, lock_monitor_cb=None):
344 00267bfe Michael Hanselmann
    """Initializes this class.
345 00267bfe Michael Hanselmann

346 00267bfe Michael Hanselmann
    @param resolver: callable accepting a list of hostnames, returning a list
347 00267bfe Michael Hanselmann
      of tuples containing name and IP address (IP address can be the name or
348 00267bfe Michael Hanselmann
      the special value L{_OFFLINE} to mark offline machines)
349 00267bfe Michael Hanselmann
    @type port: int
350 00267bfe Michael Hanselmann
    @param port: TCP port
351 aea5caef Michael Hanselmann
    @param lock_monitor_cb: Callable for registering with lock monitor
352 3ef3c771 Iustin Pop

353 a8083063 Iustin Pop
    """
354 00267bfe Michael Hanselmann
    self._resolver = resolver
355 00267bfe Michael Hanselmann
    self._port = port
356 aea5caef Michael Hanselmann
    self._lock_monitor_cb = lock_monitor_cb
357 eb202c13 Manuel Franceschini
358 00267bfe Michael Hanselmann
  @staticmethod
359 00267bfe Michael Hanselmann
  def _PrepareRequests(hosts, port, procedure, body, read_timeout):
360 00267bfe Michael Hanselmann
    """Prepares requests by sorting offline hosts into separate list.
361 eb202c13 Manuel Franceschini

362 00267bfe Michael Hanselmann
    """
363 00267bfe Michael Hanselmann
    results = {}
364 00267bfe Michael Hanselmann
    requests = {}
365 bdf7d8c0 Iustin Pop
366 00267bfe Michael Hanselmann
    for (name, ip) in hosts:
367 00267bfe Michael Hanselmann
      if ip is _OFFLINE:
368 00267bfe Michael Hanselmann
        # Node is marked as offline
369 00267bfe Michael Hanselmann
        results[name] = RpcResult(node=name, offline=True, call=procedure)
370 00267bfe Michael Hanselmann
      else:
371 00267bfe Michael Hanselmann
        requests[name] = \
372 00267bfe Michael Hanselmann
          http.client.HttpClientRequest(str(ip), port,
373 00267bfe Michael Hanselmann
                                        http.HTTP_PUT, str("/%s" % procedure),
374 00267bfe Michael Hanselmann
                                        headers=_RPC_CLIENT_HEADERS,
375 00267bfe Michael Hanselmann
                                        post_data=body,
376 7cb2d205 Michael Hanselmann
                                        read_timeout=read_timeout,
377 abbf2cd9 Michael Hanselmann
                                        nicename="%s/%s" % (name, procedure),
378 abbf2cd9 Michael Hanselmann
                                        curl_config_fn=_ConfigRpcCurl)
379 a8083063 Iustin Pop
380 00267bfe Michael Hanselmann
    return (results, requests)
381 00267bfe Michael Hanselmann
382 00267bfe Michael Hanselmann
  @staticmethod
383 00267bfe Michael Hanselmann
  def _CombineResults(results, requests, procedure):
384 00267bfe Michael Hanselmann
    """Combines pre-computed results for offline hosts with actual call results.
385 bdf7d8c0 Iustin Pop

386 a8083063 Iustin Pop
    """
387 00267bfe Michael Hanselmann
    for name, req in requests.items():
388 00267bfe Michael Hanselmann
      if req.success and req.resp_status_code == http.HTTP_OK:
389 00267bfe Michael Hanselmann
        host_result = RpcResult(data=serializer.LoadJson(req.resp_body),
390 00267bfe Michael Hanselmann
                                node=name, call=procedure)
391 00267bfe Michael Hanselmann
      else:
392 00267bfe Michael Hanselmann
        # TODO: Better error reporting
393 00267bfe Michael Hanselmann
        if req.error:
394 00267bfe Michael Hanselmann
          msg = req.error
395 00267bfe Michael Hanselmann
        else:
396 00267bfe Michael Hanselmann
          msg = req.resp_body
397 eb202c13 Manuel Franceschini
398 00267bfe Michael Hanselmann
        logging.error("RPC error in %s on node %s: %s", procedure, name, msg)
399 00267bfe Michael Hanselmann
        host_result = RpcResult(data=msg, failed=True, node=name,
400 00267bfe Michael Hanselmann
                                call=procedure)
401 ecfe9491 Michael Hanselmann
402 00267bfe Michael Hanselmann
      results[name] = host_result
403 92fd2250 Iustin Pop
404 00267bfe Michael Hanselmann
    return results
405 a8083063 Iustin Pop
406 abbf2cd9 Michael Hanselmann
  def __call__(self, hosts, procedure, body, read_timeout=None,
407 abbf2cd9 Michael Hanselmann
               _req_process_fn=http.client.ProcessRequests):
408 00267bfe Michael Hanselmann
    """Makes an RPC request to a number of nodes.
409 ecfe9491 Michael Hanselmann

410 00267bfe Michael Hanselmann
    @type hosts: sequence
411 00267bfe Michael Hanselmann
    @param hosts: Hostnames
412 00267bfe Michael Hanselmann
    @type procedure: string
413 00267bfe Michael Hanselmann
    @param procedure: Request path
414 00267bfe Michael Hanselmann
    @type body: string
415 00267bfe Michael Hanselmann
    @param body: Request body
416 00267bfe Michael Hanselmann
    @type read_timeout: int or None
417 00267bfe Michael Hanselmann
    @param read_timeout: Read timeout for request
418 a8083063 Iustin Pop

419 a8083063 Iustin Pop
    """
420 00267bfe Michael Hanselmann
    assert procedure in _TIMEOUTS, "RPC call not declared in the timeouts table"
421 00267bfe Michael Hanselmann
422 00267bfe Michael Hanselmann
    if read_timeout is None:
423 00267bfe Michael Hanselmann
      read_timeout = _TIMEOUTS[procedure]
424 a8083063 Iustin Pop
425 00267bfe Michael Hanselmann
    (results, requests) = \
426 00267bfe Michael Hanselmann
      self._PrepareRequests(self._resolver(hosts), self._port, procedure,
427 00267bfe Michael Hanselmann
                            str(body), read_timeout)
428 a8083063 Iustin Pop
429 abbf2cd9 Michael Hanselmann
    _req_process_fn(requests.values(), lock_monitor_cb=self._lock_monitor_cb)
430 a8083063 Iustin Pop
431 00267bfe Michael Hanselmann
    assert not frozenset(results).intersection(requests)
432 ecfe9491 Michael Hanselmann
433 00267bfe Michael Hanselmann
    return self._CombineResults(results, requests, procedure)
434 a8083063 Iustin Pop
435 a8083063 Iustin Pop
436 1651d116 Michael Hanselmann
def _EncodeImportExportIO(ieio, ieioargs):
437 1651d116 Michael Hanselmann
  """Encodes import/export I/O information.
438 1651d116 Michael Hanselmann

439 1651d116 Michael Hanselmann
  """
440 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_RAW_DISK:
441 1651d116 Michael Hanselmann
    assert len(ieioargs) == 1
442 1651d116 Michael Hanselmann
    return (ieioargs[0].ToDict(), )
443 1651d116 Michael Hanselmann
444 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_SCRIPT:
445 1651d116 Michael Hanselmann
    assert len(ieioargs) == 2
446 1651d116 Michael Hanselmann
    return (ieioargs[0].ToDict(), ieioargs[1])
447 1651d116 Michael Hanselmann
448 1651d116 Michael Hanselmann
  return ieioargs
449 1651d116 Michael Hanselmann
450 1651d116 Michael Hanselmann
451 72737a7f Iustin Pop
class RpcRunner(object):
452 87b3cb26 Michael Hanselmann
  """RPC runner class.
453 a8083063 Iustin Pop

454 87b3cb26 Michael Hanselmann
  """
455 87b3cb26 Michael Hanselmann
  def __init__(self, context):
456 87b3cb26 Michael Hanselmann
    """Initialized the RPC runner.
457 a8083063 Iustin Pop

458 87b3cb26 Michael Hanselmann
    @type context: C{masterd.GanetiContext}
459 87b3cb26 Michael Hanselmann
    @param context: Ganeti context
460 a8083063 Iustin Pop

461 72737a7f Iustin Pop
    """
462 87b3cb26 Michael Hanselmann
    self._cfg = context.cfg
463 00267bfe Michael Hanselmann
    self._proc = _RpcProcessor(compat.partial(_NodeConfigResolver,
464 00267bfe Michael Hanselmann
                                              self._cfg.GetNodeInfo,
465 00267bfe Michael Hanselmann
                                              self._cfg.GetAllNodesInfo),
466 aea5caef Michael Hanselmann
                               netutils.GetDaemonPort(constants.NODED),
467 aea5caef Michael Hanselmann
                               lock_monitor_cb=context.glm.AddToLockMonitor)
468 a8083063 Iustin Pop
469 1bdcbbab Iustin Pop
  def _InstDict(self, instance, hvp=None, bep=None, osp=None):
470 26ba2bd8 Iustin Pop
    """Convert the given instance to a dict.
471 26ba2bd8 Iustin Pop

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

475 26ba2bd8 Iustin Pop
    @type instance: L{objects.Instance}
476 26ba2bd8 Iustin Pop
    @param instance: an Instance object
477 0eca8e0c Iustin Pop
    @type hvp: dict or None
478 5bbd3f7f Michael Hanselmann
    @param hvp: a dictionary with overridden hypervisor parameters
479 0eca8e0c Iustin Pop
    @type bep: dict or None
480 5bbd3f7f Michael Hanselmann
    @param bep: a dictionary with overridden backend parameters
481 1bdcbbab Iustin Pop
    @type osp: dict or None
482 8d8c4eff Michael Hanselmann
    @param osp: a dictionary with overridden os parameters
483 26ba2bd8 Iustin Pop
    @rtype: dict
484 26ba2bd8 Iustin Pop
    @return: the instance dict, with the hvparams filled with the
485 26ba2bd8 Iustin Pop
        cluster defaults
486 26ba2bd8 Iustin Pop

487 26ba2bd8 Iustin Pop
    """
488 26ba2bd8 Iustin Pop
    idict = instance.ToDict()
489 5b442704 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
490 5b442704 Iustin Pop
    idict["hvparams"] = cluster.FillHV(instance)
491 0eca8e0c Iustin Pop
    if hvp is not None:
492 0eca8e0c Iustin Pop
      idict["hvparams"].update(hvp)
493 5b442704 Iustin Pop
    idict["beparams"] = cluster.FillBE(instance)
494 0eca8e0c Iustin Pop
    if bep is not None:
495 0eca8e0c Iustin Pop
      idict["beparams"].update(bep)
496 1bdcbbab Iustin Pop
    idict["osparams"] = cluster.SimpleFillOS(instance.os, instance.osparams)
497 1bdcbbab Iustin Pop
    if osp is not None:
498 1bdcbbab Iustin Pop
      idict["osparams"].update(osp)
499 b848ce79 Guido Trotter
    for nic in idict["nics"]:
500 b848ce79 Guido Trotter
      nic['nicparams'] = objects.FillDict(
501 b848ce79 Guido Trotter
        cluster.nicparams[constants.PP_DEFAULT],
502 b848ce79 Guido Trotter
        nic['nicparams'])
503 26ba2bd8 Iustin Pop
    return idict
504 26ba2bd8 Iustin Pop
505 e0036155 Iustin Pop
  def _MultiNodeCall(self, node_list, procedure, args, read_timeout=None):
506 160e2921 Iustin Pop
    """Helper for making a multi-node call
507 160e2921 Iustin Pop

508 160e2921 Iustin Pop
    """
509 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
510 00267bfe Michael Hanselmann
    return self._proc(node_list, procedure, body, read_timeout=read_timeout)
511 9a525d83 Michael Hanselmann
512 00267bfe Michael Hanselmann
  @staticmethod
513 00267bfe Michael Hanselmann
  def _StaticMultiNodeCall(node_list, procedure, args,
514 e0036155 Iustin Pop
                           address_list=None, read_timeout=None):
515 160e2921 Iustin Pop
    """Helper for making a multi-node static call
516 160e2921 Iustin Pop

517 160e2921 Iustin Pop
    """
518 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
519 00267bfe Michael Hanselmann
520 00267bfe Michael Hanselmann
    if address_list is None:
521 00267bfe Michael Hanselmann
      resolver = _SsconfResolver
522 00267bfe Michael Hanselmann
    else:
523 00267bfe Michael Hanselmann
      # Caller provided an address list
524 00267bfe Michael Hanselmann
      resolver = _StaticResolver(address_list)
525 00267bfe Michael Hanselmann
526 00267bfe Michael Hanselmann
    proc = _RpcProcessor(resolver,
527 00267bfe Michael Hanselmann
                         netutils.GetDaemonPort(constants.NODED))
528 00267bfe Michael Hanselmann
    return proc(node_list, procedure, body, read_timeout=read_timeout)
529 9a525d83 Michael Hanselmann
530 e0036155 Iustin Pop
  def _SingleNodeCall(self, node, procedure, args, read_timeout=None):
531 160e2921 Iustin Pop
    """Helper for making a single-node call
532 9a525d83 Michael Hanselmann

533 9a525d83 Michael Hanselmann
    """
534 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
535 00267bfe Michael Hanselmann
    return self._proc([node], procedure, body, read_timeout=read_timeout)[node]
536 9a525d83 Michael Hanselmann
537 9a525d83 Michael Hanselmann
  @classmethod
538 e0036155 Iustin Pop
  def _StaticSingleNodeCall(cls, node, procedure, args, read_timeout=None):
539 160e2921 Iustin Pop
    """Helper for making a single-node static call
540 9a525d83 Michael Hanselmann

541 9a525d83 Michael Hanselmann
    """
542 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
543 00267bfe Michael Hanselmann
    proc = _RpcProcessor(_SsconfResolver,
544 00267bfe Michael Hanselmann
                         netutils.GetDaemonPort(constants.NODED))
545 00267bfe Michael Hanselmann
    return proc([node], procedure, body, read_timeout=read_timeout)[node]
546 9a525d83 Michael Hanselmann
547 781de953 Iustin Pop
  #
548 781de953 Iustin Pop
  # Begin RPC calls
549 781de953 Iustin Pop
  #
550 781de953 Iustin Pop
551 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
552 2be7273c Apollon Oikonomopoulos
  def call_bdev_sizes(self, node_list, devices):
553 2be7273c Apollon Oikonomopoulos
    """Gets the sizes of requested block devices present on a node
554 2be7273c Apollon Oikonomopoulos

555 2be7273c Apollon Oikonomopoulos
    This is a multi-node call.
556 2be7273c Apollon Oikonomopoulos

557 2be7273c Apollon Oikonomopoulos
    """
558 2be7273c Apollon Oikonomopoulos
    return self._MultiNodeCall(node_list, "bdev_sizes", [devices])
559 2be7273c Apollon Oikonomopoulos
560 2be7273c Apollon Oikonomopoulos
  @_RpcTimeout(_TMO_URGENT)
561 b2a6ccd4 Iustin Pop
  def call_lv_list(self, node_list, vg_name):
562 72737a7f Iustin Pop
    """Gets the logical volumes present in a given volume group.
563 a8083063 Iustin Pop

564 72737a7f Iustin Pop
    This is a multi-node call.
565 a8083063 Iustin Pop

566 72737a7f Iustin Pop
    """
567 b2a6ccd4 Iustin Pop
    return self._MultiNodeCall(node_list, "lv_list", [vg_name])
568 a8083063 Iustin Pop
569 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
570 72737a7f Iustin Pop
  def call_vg_list(self, node_list):
571 72737a7f Iustin Pop
    """Gets the volume group list.
572 a8083063 Iustin Pop

573 72737a7f Iustin Pop
    This is a multi-node call.
574 a8083063 Iustin Pop

575 72737a7f Iustin Pop
    """
576 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "vg_list", [])
577 a8083063 Iustin Pop
578 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
579 e337de97 Michael Hanselmann
  def call_storage_list(self, node_list, su_name, su_args, name, fields):
580 8979196a Michael Hanselmann
    """Get list of storage units.
581 e337de97 Michael Hanselmann

582 e337de97 Michael Hanselmann
    This is a multi-node call.
583 e337de97 Michael Hanselmann

584 e337de97 Michael Hanselmann
    """
585 e337de97 Michael Hanselmann
    return self._MultiNodeCall(node_list, "storage_list",
586 e337de97 Michael Hanselmann
                               [su_name, su_args, name, fields])
587 e337de97 Michael Hanselmann
588 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
589 8979196a Michael Hanselmann
  def call_storage_modify(self, node, su_name, su_args, name, changes):
590 8979196a Michael Hanselmann
    """Modify a storage unit.
591 8979196a Michael Hanselmann

592 8979196a Michael Hanselmann
    This is a single-node call.
593 8979196a Michael Hanselmann

594 8979196a Michael Hanselmann
    """
595 8979196a Michael Hanselmann
    return self._SingleNodeCall(node, "storage_modify",
596 8979196a Michael Hanselmann
                                [su_name, su_args, name, changes])
597 8979196a Michael Hanselmann
598 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
599 637b8d7e Michael Hanselmann
  def call_storage_execute(self, node, su_name, su_args, name, op):
600 637b8d7e Michael Hanselmann
    """Executes an operation on a storage unit.
601 637b8d7e Michael Hanselmann

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

604 637b8d7e Michael Hanselmann
    """
605 637b8d7e Michael Hanselmann
    return self._SingleNodeCall(node, "storage_execute",
606 637b8d7e Michael Hanselmann
                                [su_name, su_args, name, op])
607 637b8d7e Michael Hanselmann
608 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
609 72737a7f Iustin Pop
  def call_bridges_exist(self, node, bridges_list):
610 72737a7f Iustin Pop
    """Checks if a node has all the bridges given.
611 a8083063 Iustin Pop

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

616 72737a7f Iustin Pop
    This is a single-node call.
617 a8083063 Iustin Pop

618 72737a7f Iustin Pop
    """
619 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "bridges_exist", [bridges_list])
620 a8083063 Iustin Pop
621 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
622 323f9095 Stephen Shirley
  def call_instance_start(self, node, instance, hvp, bep, startup_paused):
623 72737a7f Iustin Pop
    """Starts an instance.
624 a8083063 Iustin Pop

625 72737a7f Iustin Pop
    This is a single-node call.
626 a8083063 Iustin Pop

627 72737a7f Iustin Pop
    """
628 0eca8e0c Iustin Pop
    idict = self._InstDict(instance, hvp=hvp, bep=bep)
629 323f9095 Stephen Shirley
    return self._SingleNodeCall(node, "instance_start", [idict, startup_paused])
630 a8083063 Iustin Pop
631 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
632 6263189c Guido Trotter
  def call_instance_shutdown(self, node, instance, timeout):
633 72737a7f Iustin Pop
    """Stops an instance.
634 a8083063 Iustin Pop

635 72737a7f Iustin Pop
    This is a single-node call.
636 2a10865c Iustin Pop

637 72737a7f Iustin Pop
    """
638 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_shutdown",
639 6263189c Guido Trotter
                                [self._InstDict(instance), timeout])
640 2a10865c Iustin Pop
641 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
642 6906a9d8 Guido Trotter
  def call_migration_info(self, node, instance):
643 6906a9d8 Guido Trotter
    """Gather the information necessary to prepare an instance migration.
644 6906a9d8 Guido Trotter

645 6906a9d8 Guido Trotter
    This is a single-node call.
646 6906a9d8 Guido Trotter

647 6906a9d8 Guido Trotter
    @type node: string
648 6906a9d8 Guido Trotter
    @param node: the node on which the instance is currently running
649 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
650 6906a9d8 Guido Trotter
    @param instance: the instance definition
651 6906a9d8 Guido Trotter

652 6906a9d8 Guido Trotter
    """
653 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "migration_info",
654 6906a9d8 Guido Trotter
                                [self._InstDict(instance)])
655 6906a9d8 Guido Trotter
656 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
657 6906a9d8 Guido Trotter
  def call_accept_instance(self, node, instance, info, target):
658 6906a9d8 Guido Trotter
    """Prepare a node to accept an instance.
659 6906a9d8 Guido Trotter

660 6906a9d8 Guido Trotter
    This is a single-node call.
661 6906a9d8 Guido Trotter

662 6906a9d8 Guido Trotter
    @type node: string
663 6906a9d8 Guido Trotter
    @param node: the target node for the migration
664 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
665 6906a9d8 Guido Trotter
    @param instance: the instance definition
666 6906a9d8 Guido Trotter
    @type info: opaque/hypervisor specific (string/data)
667 6906a9d8 Guido Trotter
    @param info: result for the call_migration_info call
668 6906a9d8 Guido Trotter
    @type target: string
669 6906a9d8 Guido Trotter
    @param target: target hostname (usually ip address) (on the node itself)
670 6906a9d8 Guido Trotter

671 6906a9d8 Guido Trotter
    """
672 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "accept_instance",
673 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, target])
674 6906a9d8 Guido Trotter
675 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
676 6a1434d7 Andrea Spadaccini
  def call_instance_finalize_migration_dst(self, node, instance, info, success):
677 6906a9d8 Guido Trotter
    """Finalize any target-node migration specific operation.
678 6906a9d8 Guido Trotter

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

682 6906a9d8 Guido Trotter
    This is a single-node call.
683 6906a9d8 Guido Trotter

684 6906a9d8 Guido Trotter
    @type node: string
685 6906a9d8 Guido Trotter
    @param node: the target node for the migration
686 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
687 6906a9d8 Guido Trotter
    @param instance: the instance definition
688 6906a9d8 Guido Trotter
    @type info: opaque/hypervisor specific (string/data)
689 6906a9d8 Guido Trotter
    @param info: result for the call_migration_info call
690 6906a9d8 Guido Trotter
    @type success: boolean
691 6906a9d8 Guido Trotter
    @param success: whether the migration was a success or a failure
692 6906a9d8 Guido Trotter

693 6906a9d8 Guido Trotter
    """
694 6a1434d7 Andrea Spadaccini
    return self._SingleNodeCall(node, "instance_finalize_migration_dst",
695 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, success])
696 6906a9d8 Guido Trotter
697 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
698 72737a7f Iustin Pop
  def call_instance_migrate(self, node, instance, target, live):
699 72737a7f Iustin Pop
    """Migrate an instance.
700 2a10865c Iustin Pop

701 72737a7f Iustin Pop
    This is a single-node call.
702 2a10865c Iustin Pop

703 72737a7f Iustin Pop
    @type node: string
704 72737a7f Iustin Pop
    @param node: the node on which the instance is currently running
705 72737a7f Iustin Pop
    @type instance: C{objects.Instance}
706 72737a7f Iustin Pop
    @param instance: the instance definition
707 72737a7f Iustin Pop
    @type target: string
708 72737a7f Iustin Pop
    @param target: the target node name
709 72737a7f Iustin Pop
    @type live: boolean
710 72737a7f Iustin Pop
    @param live: whether the migration should be done live or not (the
711 72737a7f Iustin Pop
        interpretation of this parameter is left to the hypervisor)
712 007a2f3e Alexander Schreiber

713 72737a7f Iustin Pop
    """
714 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_migrate",
715 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), target, live])
716 007a2f3e Alexander Schreiber
717 6a1434d7 Andrea Spadaccini
  @_RpcTimeout(_TMO_SLOW)
718 6a1434d7 Andrea Spadaccini
  def call_instance_finalize_migration_src(self, node, instance, success, live):
719 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the source node.
720 6a1434d7 Andrea Spadaccini

721 6a1434d7 Andrea Spadaccini
    This is a single-node call.
722 6a1434d7 Andrea Spadaccini

723 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
724 6a1434d7 Andrea Spadaccini
    @param instance: the instance that was migrated
725 6a1434d7 Andrea Spadaccini
    @type success: bool
726 6a1434d7 Andrea Spadaccini
    @param success: whether the migration succeeded or not
727 6a1434d7 Andrea Spadaccini
    @type live: bool
728 6a1434d7 Andrea Spadaccini
    @param live: whether the user requested a live migration or not
729 6a1434d7 Andrea Spadaccini

730 6a1434d7 Andrea Spadaccini
    """
731 6a1434d7 Andrea Spadaccini
    return self._SingleNodeCall(node, "instance_finalize_migration_src",
732 6a1434d7 Andrea Spadaccini
                                [self._InstDict(instance), success, live])
733 6a1434d7 Andrea Spadaccini
734 6a1434d7 Andrea Spadaccini
  @_RpcTimeout(_TMO_SLOW)
735 6a1434d7 Andrea Spadaccini
  def call_instance_get_migration_status(self, node, instance):
736 6a1434d7 Andrea Spadaccini
    """Report migration status.
737 6a1434d7 Andrea Spadaccini

738 6a1434d7 Andrea Spadaccini
    This is a single-node call that must be executed on the source node.
739 6a1434d7 Andrea Spadaccini

740 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
741 6a1434d7 Andrea Spadaccini
    @param instance: the instance that is being migrated
742 6a1434d7 Andrea Spadaccini
    @rtype: L{objects.MigrationStatus}
743 6a1434d7 Andrea Spadaccini
    @return: the status of the current migration (one of
744 6a1434d7 Andrea Spadaccini
             L{constants.HV_MIGRATION_VALID_STATUSES}), plus any additional
745 6a1434d7 Andrea Spadaccini
             progress info that can be retrieved from the hypervisor
746 6a1434d7 Andrea Spadaccini

747 6a1434d7 Andrea Spadaccini
    """
748 6a1434d7 Andrea Spadaccini
    result = self._SingleNodeCall(node, "instance_get_migration_status",
749 6a1434d7 Andrea Spadaccini
                                  [self._InstDict(instance)])
750 6a1434d7 Andrea Spadaccini
    if not result.fail_msg and result.payload is not None:
751 6a1434d7 Andrea Spadaccini
      result.payload = objects.MigrationStatus.FromDict(result.payload)
752 6a1434d7 Andrea Spadaccini
    return result
753 6a1434d7 Andrea Spadaccini
754 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
755 17c3f802 Guido Trotter
  def call_instance_reboot(self, node, inst, reboot_type, shutdown_timeout):
756 72737a7f Iustin Pop
    """Reboots an instance.
757 007a2f3e Alexander Schreiber

758 72737a7f Iustin Pop
    This is a single-node call.
759 a8083063 Iustin Pop

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

769 72737a7f Iustin Pop
    This is a single-node call.
770 decd5f45 Iustin Pop

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

780 72737a7f Iustin Pop
    This is a single-node call.
781 a8083063 Iustin Pop

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

790 72737a7f Iustin Pop
    This is a single-node call.
791 a8083063 Iustin Pop

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

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

806 56e7640c Iustin Pop
    This is a single-node call.
807 56e7640c Iustin Pop

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

812 56e7640c Iustin Pop

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

821 72737a7f Iustin Pop
    This is a multi-node call.
822 a8083063 Iustin Pop

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

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

836 72737a7f Iustin Pop
    This is a multi-node call.
837 a8083063 Iustin Pop

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

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

851 72737a7f Iustin Pop
    This is a single-node call.
852 caad16e2 Iustin Pop

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

862 caad16e2 Iustin Pop
    This is a single-node call.
863 caad16e2 Iustin Pop

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

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

874 72737a7f Iustin Pop
    This is a multi-node call.
875 a8083063 Iustin Pop

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

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

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

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

909 72737a7f Iustin Pop
    This is a multi-node call.
910 a8083063 Iustin Pop

911 72737a7f Iustin Pop
    """
912 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_verify",
913 9a525d83 Michael Hanselmann
                               [checkdict, cluster_name])
914 a8083063 Iustin Pop
915 9a525d83 Michael Hanselmann
  @classmethod
916 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
917 fb460cf7 Andrea Spadaccini
  def call_node_start_master_daemons(cls, node, no_voting):
918 fb460cf7 Andrea Spadaccini
    """Starts master daemons on a node.
919 a8083063 Iustin Pop

920 72737a7f Iustin Pop
    This is a single-node call.
921 a8083063 Iustin Pop

922 72737a7f Iustin Pop
    """
923 fb460cf7 Andrea Spadaccini
    return cls._StaticSingleNodeCall(node, "node_start_master_daemons",
924 fb460cf7 Andrea Spadaccini
                                     [no_voting])
925 a8083063 Iustin Pop
926 9a525d83 Michael Hanselmann
  @classmethod
927 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
928 fb460cf7 Andrea Spadaccini
  def call_node_activate_master_ip(cls, node):
929 fb460cf7 Andrea Spadaccini
    """Activates master IP on a node.
930 a8083063 Iustin Pop

931 72737a7f Iustin Pop
    This is a single-node call.
932 4e071d3b Iustin Pop

933 72737a7f Iustin Pop
    """
934 fb460cf7 Andrea Spadaccini
    return cls._StaticSingleNodeCall(node, "node_activate_master_ip", [])
935 fb460cf7 Andrea Spadaccini
936 fb460cf7 Andrea Spadaccini
  @classmethod
937 fb460cf7 Andrea Spadaccini
  @_RpcTimeout(_TMO_FAST)
938 fb460cf7 Andrea Spadaccini
  def call_node_stop_master(cls, node):
939 fb460cf7 Andrea Spadaccini
    """Deactivates master IP and stops master daemons on a node.
940 fb460cf7 Andrea Spadaccini

941 fb460cf7 Andrea Spadaccini
    This is a single-node call.
942 fb460cf7 Andrea Spadaccini

943 fb460cf7 Andrea Spadaccini
    """
944 fb460cf7 Andrea Spadaccini
    return cls._StaticSingleNodeCall(node, "node_stop_master", [])
945 fb460cf7 Andrea Spadaccini
946 fb460cf7 Andrea Spadaccini
  @classmethod
947 fb460cf7 Andrea Spadaccini
  @_RpcTimeout(_TMO_FAST)
948 fb460cf7 Andrea Spadaccini
  def call_node_deactivate_master_ip(cls, node):
949 fb460cf7 Andrea Spadaccini
    """Deactivates master IP on a node.
950 fb460cf7 Andrea Spadaccini

951 fb460cf7 Andrea Spadaccini
    This is a single-node call.
952 fb460cf7 Andrea Spadaccini

953 fb460cf7 Andrea Spadaccini
    """
954 fb460cf7 Andrea Spadaccini
    return cls._StaticSingleNodeCall(node, "node_deactivate_master_ip", [])
955 4e071d3b Iustin Pop
956 9a525d83 Michael Hanselmann
  @classmethod
957 5a8648eb Andrea Spadaccini
  @_RpcTimeout(_TMO_FAST)
958 5a8648eb Andrea Spadaccini
  def call_node_change_master_netmask(cls, node, netmask):
959 5a8648eb Andrea Spadaccini
    """Change master IP netmask.
960 5a8648eb Andrea Spadaccini

961 5a8648eb Andrea Spadaccini
    This is a single-node call.
962 5a8648eb Andrea Spadaccini

963 5a8648eb Andrea Spadaccini
    """
964 5a8648eb Andrea Spadaccini
    return cls._StaticSingleNodeCall(node, "node_change_master_netmask",
965 5a8648eb Andrea Spadaccini
                  [netmask])
966 5a8648eb Andrea Spadaccini
967 5a8648eb Andrea Spadaccini
  @classmethod
968 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
969 9a525d83 Michael Hanselmann
  def call_master_info(cls, node_list):
970 72737a7f Iustin Pop
    """Query master info.
971 4e071d3b Iustin Pop

972 72737a7f Iustin Pop
    This is a multi-node call.
973 a8083063 Iustin Pop

974 72737a7f Iustin Pop
    """
975 72737a7f Iustin Pop
    # TODO: should this method query down nodes?
976 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "master_info", [])
977 a8083063 Iustin Pop
978 8f215968 Michael Hanselmann
  @classmethod
979 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
980 8f215968 Michael Hanselmann
  def call_version(cls, node_list):
981 72737a7f Iustin Pop
    """Query node version.
982 a8083063 Iustin Pop

983 72737a7f Iustin Pop
    This is a multi-node call.
984 a8083063 Iustin Pop

985 72737a7f Iustin Pop
    """
986 8f215968 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "version", [])
987 a8083063 Iustin Pop
988 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
989 72737a7f Iustin Pop
  def call_blockdev_create(self, node, bdev, size, owner, on_primary, info):
990 72737a7f Iustin Pop
    """Request creation of a given block device.
991 a8083063 Iustin Pop

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

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

1002 271b7cf9 René Nussbaumer
    This is a single-node call.
1003 271b7cf9 René Nussbaumer

1004 271b7cf9 René Nussbaumer
    """
1005 271b7cf9 René Nussbaumer
    return self._SingleNodeCall(node, "blockdev_wipe",
1006 271b7cf9 René Nussbaumer
                                [bdev.ToDict(), offset, size])
1007 271b7cf9 René Nussbaumer
1008 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1009 72737a7f Iustin Pop
  def call_blockdev_remove(self, node, bdev):
1010 72737a7f Iustin Pop
    """Request removal of a given block device.
1011 a8083063 Iustin Pop

1012 72737a7f Iustin Pop
    This is a single-node call.
1013 f3e513ad Iustin Pop

1014 72737a7f Iustin Pop
    """
1015 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_remove", [bdev.ToDict()])
1016 f3e513ad Iustin Pop
1017 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1018 72737a7f Iustin Pop
  def call_blockdev_rename(self, node, devlist):
1019 72737a7f Iustin Pop
    """Request rename of the given block devices.
1020 f3e513ad Iustin Pop

1021 72737a7f Iustin Pop
    This is a single-node call.
1022 a8083063 Iustin Pop

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

1031 9c007da8 René Nussbaumer
    This is a single-node call.
1032 9c007da8 René Nussbaumer

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

1041 72737a7f Iustin Pop
    This is a single-node call.
1042 a8083063 Iustin Pop

1043 72737a7f Iustin Pop
    """
1044 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_assemble",
1045 c417e115 Iustin Pop
                                [disk.ToDict(), owner, on_primary, idx])
1046 a8083063 Iustin Pop
1047 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1048 72737a7f Iustin Pop
  def call_blockdev_shutdown(self, node, disk):
1049 72737a7f Iustin Pop
    """Request shutdown of a given block device.
1050 a8083063 Iustin Pop

1051 72737a7f Iustin Pop
    This is a single-node call.
1052 a8083063 Iustin Pop

1053 72737a7f Iustin Pop
    """
1054 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_shutdown", [disk.ToDict()])
1055 a8083063 Iustin Pop
1056 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1057 72737a7f Iustin Pop
  def call_blockdev_addchildren(self, node, bdev, ndevs):
1058 72737a7f Iustin Pop
    """Request adding a list of children to a (mirroring) device.
1059 a8083063 Iustin Pop

1060 72737a7f Iustin Pop
    This is a single-node call.
1061 a8083063 Iustin Pop

1062 72737a7f Iustin Pop
    """
1063 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_addchildren",
1064 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
1065 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
1066 a8083063 Iustin Pop
1067 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1068 72737a7f Iustin Pop
  def call_blockdev_removechildren(self, node, bdev, ndevs):
1069 72737a7f Iustin Pop
    """Request removing a list of children from a (mirroring) device.
1070 a8083063 Iustin Pop

1071 72737a7f Iustin Pop
    This is a single-node call.
1072 a8083063 Iustin Pop

1073 72737a7f Iustin Pop
    """
1074 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_removechildren",
1075 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
1076 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
1077 a8083063 Iustin Pop
1078 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1079 72737a7f Iustin Pop
  def call_blockdev_getmirrorstatus(self, node, disks):
1080 72737a7f Iustin Pop
    """Request status of a (mirroring) device.
1081 a8083063 Iustin Pop

1082 72737a7f Iustin Pop
    This is a single-node call.
1083 a8083063 Iustin Pop

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

1096 b8d26c6e Michael Hanselmann
    This is a multi-node call.
1097 b8d26c6e Michael Hanselmann

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

1116 72737a7f Iustin Pop
    This is a single-node call.
1117 a8083063 Iustin Pop

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

1128 72737a7f Iustin Pop
    This is a single-node call.
1129 d61cbe76 Iustin Pop

1130 72737a7f Iustin Pop
    """
1131 b2e7666a Iustin Pop
    params = [instance_name, [cf.ToDict() for cf in disks]]
1132 b2e7666a Iustin Pop
    return self._SingleNodeCall(node, "blockdev_close", params)
1133 a8083063 Iustin Pop
1134 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1135 ccfbbd2d Iustin Pop
  def call_blockdev_getsize(self, node, disks):
1136 968a7623 Iustin Pop
    """Returns the size of the given disks.
1137 968a7623 Iustin Pop

1138 968a7623 Iustin Pop
    This is a single-node call.
1139 968a7623 Iustin Pop

1140 968a7623 Iustin Pop
    """
1141 968a7623 Iustin Pop
    params = [[cf.ToDict() for cf in disks]]
1142 968a7623 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_getsize", params)
1143 968a7623 Iustin Pop
1144 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1145 6b93ec9d Iustin Pop
  def call_drbd_disconnect_net(self, node_list, nodes_ip, disks):
1146 6b93ec9d Iustin Pop
    """Disconnects the network of the given drbd devices.
1147 6b93ec9d Iustin Pop

1148 6b93ec9d Iustin Pop
    This is a multi-node call.
1149 6b93ec9d Iustin Pop

1150 6b93ec9d Iustin Pop
    """
1151 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_disconnect_net",
1152 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1153 6b93ec9d Iustin Pop
1154 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1155 6b93ec9d Iustin Pop
  def call_drbd_attach_net(self, node_list, nodes_ip,
1156 6b93ec9d Iustin Pop
                           disks, instance_name, multimaster):
1157 6b93ec9d Iustin Pop
    """Disconnects the given drbd devices.
1158 6b93ec9d Iustin Pop

1159 6b93ec9d Iustin Pop
    This is a multi-node call.
1160 6b93ec9d Iustin Pop

1161 6b93ec9d Iustin Pop
    """
1162 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_attach_net",
1163 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks],
1164 6b93ec9d Iustin Pop
                                instance_name, multimaster])
1165 6b93ec9d Iustin Pop
1166 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
1167 6b93ec9d Iustin Pop
  def call_drbd_wait_sync(self, node_list, nodes_ip, disks):
1168 6b93ec9d Iustin Pop
    """Waits for the synchronization of drbd devices is complete.
1169 6b93ec9d Iustin Pop

1170 6b93ec9d Iustin Pop
    This is a multi-node call.
1171 6b93ec9d Iustin Pop

1172 6b93ec9d Iustin Pop
    """
1173 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_wait_sync",
1174 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1175 6b93ec9d Iustin Pop
1176 c46b9782 Luca Bigliardi
  @_RpcTimeout(_TMO_URGENT)
1177 c46b9782 Luca Bigliardi
  def call_drbd_helper(self, node_list):
1178 c46b9782 Luca Bigliardi
    """Gets drbd helper.
1179 c46b9782 Luca Bigliardi

1180 c46b9782 Luca Bigliardi
    This is a multi-node call.
1181 c46b9782 Luca Bigliardi

1182 c46b9782 Luca Bigliardi
    """
1183 c46b9782 Luca Bigliardi
    return self._MultiNodeCall(node_list, "drbd_helper", [])
1184 c46b9782 Luca Bigliardi
1185 9a525d83 Michael Hanselmann
  @classmethod
1186 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1187 9a525d83 Michael Hanselmann
  def call_upload_file(cls, node_list, file_name, address_list=None):
1188 72737a7f Iustin Pop
    """Upload a file.
1189 72737a7f Iustin Pop

1190 72737a7f Iustin Pop
    The node will refuse the operation in case the file is not on the
1191 72737a7f Iustin Pop
    approved file list.
1192 72737a7f Iustin Pop

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

1195 6b294c53 Iustin Pop
    @type node_list: list
1196 6b294c53 Iustin Pop
    @param node_list: the list of node names to upload to
1197 6b294c53 Iustin Pop
    @type file_name: str
1198 6b294c53 Iustin Pop
    @param file_name: the filename to upload
1199 6b294c53 Iustin Pop
    @type address_list: list or None
1200 6b294c53 Iustin Pop
    @keyword address_list: an optional list of node addresses, in order
1201 6b294c53 Iustin Pop
        to optimize the RPC speed
1202 6b294c53 Iustin Pop

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

1218 6ddc95ec Michael Hanselmann
    This is a multi-node call.
1219 6ddc95ec Michael Hanselmann

1220 6ddc95ec Michael Hanselmann
    """
1221 03d1dba2 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "write_ssconf_files", [values])
1222 6ddc95ec Michael Hanselmann
1223 4f6014d4 René Nussbaumer
  @_RpcTimeout(_TMO_NORMAL)
1224 0092d621 René Nussbaumer
  def call_run_oob(self, node, oob_program, command, remote_node, timeout):
1225 4f6014d4 René Nussbaumer
    """Runs OOB.
1226 4f6014d4 René Nussbaumer

1227 4f6014d4 René Nussbaumer
    This is a single-node call.
1228 4f6014d4 René Nussbaumer

1229 4f6014d4 René Nussbaumer
    """
1230 4f6014d4 René Nussbaumer
    return self._SingleNodeCall(node, "run_oob", [oob_program, command,
1231 0092d621 René Nussbaumer
                                                  remote_node, timeout])
1232 4f6014d4 René Nussbaumer
1233 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1234 72737a7f Iustin Pop
  def call_os_diagnose(self, node_list):
1235 72737a7f Iustin Pop
    """Request a diagnose of OS definitions.
1236 72737a7f Iustin Pop

1237 72737a7f Iustin Pop
    This is a multi-node call.
1238 a8083063 Iustin Pop

1239 72737a7f Iustin Pop
    """
1240 83d92ad8 Iustin Pop
    return self._MultiNodeCall(node_list, "os_diagnose", [])
1241 a8083063 Iustin Pop
1242 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1243 72737a7f Iustin Pop
  def call_os_get(self, node, name):
1244 72737a7f Iustin Pop
    """Returns an OS definition.
1245 a8083063 Iustin Pop

1246 72737a7f Iustin Pop
    This is a single-node call.
1247 a8083063 Iustin Pop

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

1258 acd9ff9e Iustin Pop
    This is a multi-node call.
1259 acd9ff9e Iustin Pop

1260 acd9ff9e Iustin Pop
    """
1261 acd9ff9e Iustin Pop
    return self._MultiNodeCall(nodes, "os_validate",
1262 acd9ff9e Iustin Pop
                               [required, name, checks, params])
1263 acd9ff9e Iustin Pop
1264 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1265 72737a7f Iustin Pop
  def call_hooks_runner(self, node_list, hpath, phase, env):
1266 72737a7f Iustin Pop
    """Call the hooks runner.
1267 a8083063 Iustin Pop

1268 72737a7f Iustin Pop
    Args:
1269 72737a7f Iustin Pop
      - op: the OpCode instance
1270 72737a7f Iustin Pop
      - env: a dictionary with the environment
1271 a8083063 Iustin Pop

1272 72737a7f Iustin Pop
    This is a multi-node call.
1273 a8083063 Iustin Pop

1274 72737a7f Iustin Pop
    """
1275 72737a7f Iustin Pop
    params = [hpath, phase, env]
1276 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hooks_runner", params)
1277 a8083063 Iustin Pop
1278 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1279 72737a7f Iustin Pop
  def call_iallocator_runner(self, node, name, idata):
1280 72737a7f Iustin Pop
    """Call an iallocator on a remote node
1281 8d528b7c Iustin Pop

1282 72737a7f Iustin Pop
    Args:
1283 72737a7f Iustin Pop
      - name: the iallocator name
1284 72737a7f Iustin Pop
      - input: the json-encoded input string
1285 8d528b7c Iustin Pop

1286 72737a7f Iustin Pop
    This is a single-node call.
1287 8d528b7c Iustin Pop

1288 72737a7f Iustin Pop
    """
1289 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "iallocator_runner", [name, idata])
1290 8d528b7c Iustin Pop
1291 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1292 a59faf4b Iustin Pop
  def call_blockdev_grow(self, node, cf_bdev, amount, dryrun):
1293 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1294 4c8ba8b3 Iustin Pop

1295 72737a7f Iustin Pop
    This is a single-node call.
1296 4c8ba8b3 Iustin Pop

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

1306 858f3d18 Iustin Pop
    This is a single-node call.
1307 858f3d18 Iustin Pop

1308 858f3d18 Iustin Pop
    """
1309 858f3d18 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_export",
1310 858f3d18 Iustin Pop
                                [cf_bdev.ToDict(), dest_node, dest_path,
1311 858f3d18 Iustin Pop
                                 cluster_name])
1312 858f3d18 Iustin Pop
1313 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1314 72737a7f Iustin Pop
  def call_blockdev_snapshot(self, node, cf_bdev):
1315 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1316 a8083063 Iustin Pop

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

1319 72737a7f Iustin Pop
    """
1320 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_snapshot", [cf_bdev.ToDict()])
1321 a8083063 Iustin Pop
1322 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1323 72737a7f Iustin Pop
  def call_finalize_export(self, node, instance, snap_disks):
1324 72737a7f Iustin Pop
    """Request the completion of an export operation.
1325 a8083063 Iustin Pop

1326 72737a7f Iustin Pop
    This writes the export config file, etc.
1327 a8083063 Iustin Pop

1328 72737a7f Iustin Pop
    This is a single-node call.
1329 a8083063 Iustin Pop

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

1345 72737a7f Iustin Pop
    This is a single-node call.
1346 a8083063 Iustin Pop

1347 72737a7f Iustin Pop
    """
1348 3eccac06 Iustin Pop
    return self._SingleNodeCall(node, "export_info", [path])
1349 a8083063 Iustin Pop
1350 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1351 72737a7f Iustin Pop
  def call_export_list(self, node_list):
1352 72737a7f Iustin Pop
    """Gets the stored exports list.
1353 a8083063 Iustin Pop

1354 72737a7f Iustin Pop
    This is a multi-node call.
1355 a8083063 Iustin Pop

1356 72737a7f Iustin Pop
    """
1357 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "export_list", [])
1358 a8083063 Iustin Pop
1359 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1360 72737a7f Iustin Pop
  def call_export_remove(self, node, export):
1361 72737a7f Iustin Pop
    """Requests removal of a given export.
1362 a8083063 Iustin Pop

1363 72737a7f Iustin Pop
    This is a single-node call.
1364 a8083063 Iustin Pop

1365 72737a7f Iustin Pop
    """
1366 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "export_remove", [export])
1367 a8083063 Iustin Pop
1368 9a525d83 Michael Hanselmann
  @classmethod
1369 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1370 b989b9d9 Ken Wehr
  def call_node_leave_cluster(cls, node, modify_ssh_setup):
1371 72737a7f Iustin Pop
    """Requests a node to clean the cluster information it has.
1372 a8083063 Iustin Pop

1373 72737a7f Iustin Pop
    This will remove the configuration information from the ganeti data
1374 72737a7f Iustin Pop
    dir.
1375 a8083063 Iustin Pop

1376 72737a7f Iustin Pop
    This is a single-node call.
1377 a8083063 Iustin Pop

1378 72737a7f Iustin Pop
    """
1379 b989b9d9 Ken Wehr
    return cls._StaticSingleNodeCall(node, "node_leave_cluster",
1380 b989b9d9 Ken Wehr
                                     [modify_ssh_setup])
1381 dcb93971 Michael Hanselmann
1382 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1383 72737a7f Iustin Pop
  def call_node_volumes(self, node_list):
1384 72737a7f Iustin Pop
    """Gets all volumes on node(s).
1385 dcb93971 Michael Hanselmann

1386 72737a7f Iustin Pop
    This is a multi-node call.
1387 dcb93971 Michael Hanselmann

1388 72737a7f Iustin Pop
    """
1389 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_volumes", [])
1390 06009e27 Iustin Pop
1391 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1392 56aa9fd5 Iustin Pop
  def call_node_demote_from_mc(self, node):
1393 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
1394 56aa9fd5 Iustin Pop

1395 56aa9fd5 Iustin Pop
    This is a single-node call.
1396 56aa9fd5 Iustin Pop

1397 56aa9fd5 Iustin Pop
    """
1398 56aa9fd5 Iustin Pop
    return self._SingleNodeCall(node, "node_demote_from_mc", [])
1399 56aa9fd5 Iustin Pop
1400 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1401 f5118ade Iustin Pop
  def call_node_powercycle(self, node, hypervisor):
1402 f5118ade Iustin Pop
    """Tries to powercycle a node.
1403 f5118ade Iustin Pop

1404 f5118ade Iustin Pop
    This is a single-node call.
1405 f5118ade Iustin Pop

1406 f5118ade Iustin Pop
    """
1407 f5118ade Iustin Pop
    return self._SingleNodeCall(node, "node_powercycle", [hypervisor])
1408 f5118ade Iustin Pop
1409 92fd2250 Iustin Pop
  @_RpcTimeout(None)
1410 72737a7f Iustin Pop
  def call_test_delay(self, node_list, duration):
1411 72737a7f Iustin Pop
    """Sleep for a fixed time on given node(s).
1412 06009e27 Iustin Pop

1413 72737a7f Iustin Pop
    This is a multi-node call.
1414 06009e27 Iustin Pop

1415 72737a7f Iustin Pop
    """
1416 92fd2250 Iustin Pop
    return self._MultiNodeCall(node_list, "test_delay", [duration],
1417 92fd2250 Iustin Pop
                               read_timeout=int(duration + 5))
1418 5e04ed8b Manuel Franceschini
1419 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1420 72737a7f Iustin Pop
  def call_file_storage_dir_create(self, node, file_storage_dir):
1421 72737a7f Iustin Pop
    """Create the given file storage directory.
1422 5e04ed8b Manuel Franceschini

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

1425 72737a7f Iustin Pop
    """
1426 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_create",
1427 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1428 5e04ed8b Manuel Franceschini
1429 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1430 72737a7f Iustin Pop
  def call_file_storage_dir_remove(self, node, file_storage_dir):
1431 72737a7f Iustin Pop
    """Remove the given file storage directory.
1432 5e04ed8b Manuel Franceschini

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

1435 72737a7f Iustin Pop
    """
1436 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_remove",
1437 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1438 5e04ed8b Manuel Franceschini
1439 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1440 72737a7f Iustin Pop
  def call_file_storage_dir_rename(self, node, old_file_storage_dir,
1441 72737a7f Iustin Pop
                                   new_file_storage_dir):
1442 72737a7f Iustin Pop
    """Rename file storage directory.
1443 5e04ed8b Manuel Franceschini

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

1446 72737a7f Iustin Pop
    """
1447 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_rename",
1448 9a525d83 Michael Hanselmann
                                [old_file_storage_dir, new_file_storage_dir])
1449 ca52cdeb Michael Hanselmann
1450 9a525d83 Michael Hanselmann
  @classmethod
1451 d2cd6944 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
1452 9a525d83 Michael Hanselmann
  def call_jobqueue_update(cls, node_list, address_list, file_name, content):
1453 72737a7f Iustin Pop
    """Update job queue.
1454 ca52cdeb Michael Hanselmann

1455 72737a7f Iustin Pop
    This is a multi-node call.
1456 ca52cdeb Michael Hanselmann

1457 72737a7f Iustin Pop
    """
1458 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_update",
1459 30474135 Michael Hanselmann
                                    [file_name, _Compress(content)],
1460 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1461 ca52cdeb Michael Hanselmann
1462 9a525d83 Michael Hanselmann
  @classmethod
1463 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1464 9a525d83 Michael Hanselmann
  def call_jobqueue_purge(cls, node):
1465 72737a7f Iustin Pop
    """Purge job queue.
1466 ca52cdeb Michael Hanselmann

1467 72737a7f Iustin Pop
    This is a single-node call.
1468 ca52cdeb Michael Hanselmann

1469 72737a7f Iustin Pop
    """
1470 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "jobqueue_purge", [])
1471 af5ebcb1 Michael Hanselmann
1472 9a525d83 Michael Hanselmann
  @classmethod
1473 d2cd6944 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
1474 dd875d32 Michael Hanselmann
  def call_jobqueue_rename(cls, node_list, address_list, rename):
1475 72737a7f Iustin Pop
    """Rename a job queue file.
1476 af5ebcb1 Michael Hanselmann

1477 72737a7f Iustin Pop
    This is a multi-node call.
1478 af5ebcb1 Michael Hanselmann

1479 72737a7f Iustin Pop
    """
1480 dd875d32 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_rename", rename,
1481 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1482 6217e295 Iustin Pop
1483 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1484 6217e295 Iustin Pop
  def call_hypervisor_validate_params(self, node_list, hvname, hvparams):
1485 6217e295 Iustin Pop
    """Validate the hypervisor params.
1486 6217e295 Iustin Pop

1487 6217e295 Iustin Pop
    This is a multi-node call.
1488 6217e295 Iustin Pop

1489 6217e295 Iustin Pop
    @type node_list: list
1490 6217e295 Iustin Pop
    @param node_list: the list of nodes to query
1491 6217e295 Iustin Pop
    @type hvname: string
1492 6217e295 Iustin Pop
    @param hvname: the hypervisor name
1493 6217e295 Iustin Pop
    @type hvparams: dict
1494 6217e295 Iustin Pop
    @param hvparams: the hypervisor parameters to be validated
1495 6217e295 Iustin Pop

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

1506 f942a838 Michael Hanselmann
    This is a single-node call.
1507 f942a838 Michael Hanselmann

1508 f942a838 Michael Hanselmann
    @type validity: int
1509 f942a838 Michael Hanselmann
    @param validity: Validity in seconds
1510 f942a838 Michael Hanselmann

1511 f942a838 Michael Hanselmann
    """
1512 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_create", [validity])
1513 f942a838 Michael Hanselmann
1514 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1515 37549316 Michael Hanselmann
  def call_x509_cert_remove(self, node, name):
1516 f942a838 Michael Hanselmann
    """Removes a X509 certificate.
1517 f942a838 Michael Hanselmann

1518 f942a838 Michael Hanselmann
    This is a single-node call.
1519 f942a838 Michael Hanselmann

1520 f942a838 Michael Hanselmann
    @type name: string
1521 f942a838 Michael Hanselmann
    @param name: Certificate name
1522 f942a838 Michael Hanselmann

1523 f942a838 Michael Hanselmann
    """
1524 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_remove", [name])
1525 1651d116 Michael Hanselmann
1526 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1527 6613661a Iustin Pop
  def call_import_start(self, node, opts, instance, component,
1528 6613661a Iustin Pop
                        dest, dest_args):
1529 1651d116 Michael Hanselmann
    """Starts a listener for an import.
1530 1651d116 Michael Hanselmann

1531 1651d116 Michael Hanselmann
    This is a single-node call.
1532 1651d116 Michael Hanselmann

1533 1651d116 Michael Hanselmann
    @type node: string
1534 1651d116 Michael Hanselmann
    @param node: Node name
1535 1651d116 Michael Hanselmann
    @type instance: C{objects.Instance}
1536 1651d116 Michael Hanselmann
    @param instance: Instance object
1537 6613661a Iustin Pop
    @type component: string
1538 6613661a Iustin Pop
    @param component: which part of the instance is being imported
1539 1651d116 Michael Hanselmann

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

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

1553 1651d116 Michael Hanselmann
    @type node: string
1554 1651d116 Michael Hanselmann
    @param node: Node name
1555 1651d116 Michael Hanselmann
    @type instance: C{objects.Instance}
1556 1651d116 Michael Hanselmann
    @param instance: Instance object
1557 6613661a Iustin Pop
    @type component: string
1558 6613661a Iustin Pop
    @param component: which part of the instance is being imported
1559 1651d116 Michael Hanselmann

1560 1651d116 Michael Hanselmann
    """
1561 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "export_start",
1562 eb630f50 Michael Hanselmann
                                [opts.ToDict(), host, port,
1563 6613661a Iustin Pop
                                 self._InstDict(instance),
1564 6613661a Iustin Pop
                                 component, source,
1565 1651d116 Michael Hanselmann
                                 _EncodeImportExportIO(source, source_args)])
1566 1651d116 Michael Hanselmann
1567 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1568 ef40fbfb Michael Hanselmann
  def call_impexp_status(self, node, names):
1569 1651d116 Michael Hanselmann
    """Gets the status of an import or export.
1570 1651d116 Michael Hanselmann

1571 1651d116 Michael Hanselmann
    This is a single-node call.
1572 1651d116 Michael Hanselmann

1573 1651d116 Michael Hanselmann
    @type node: string
1574 1651d116 Michael Hanselmann
    @param node: Node name
1575 1651d116 Michael Hanselmann
    @type names: List of strings
1576 1651d116 Michael Hanselmann
    @param names: Import/export names
1577 1651d116 Michael Hanselmann
    @rtype: List of L{objects.ImportExportStatus} instances
1578 1651d116 Michael Hanselmann
    @return: Returns a list of the state of each named import/export or None if
1579 1651d116 Michael Hanselmann
             a status couldn't be retrieved
1580 1651d116 Michael Hanselmann

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

1601 f81c4737 Michael Hanselmann
    This is a single-node call.
1602 f81c4737 Michael Hanselmann

1603 f81c4737 Michael Hanselmann
    @type node: string
1604 f81c4737 Michael Hanselmann
    @param node: Node name
1605 f81c4737 Michael Hanselmann
    @type name: string
1606 f81c4737 Michael Hanselmann
    @param name: Import/export name
1607 f81c4737 Michael Hanselmann

1608 f81c4737 Michael Hanselmann
    """
1609 f81c4737 Michael Hanselmann
    return self._SingleNodeCall(node, "impexp_abort", [name])
1610 f81c4737 Michael Hanselmann
1611 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1612 ef40fbfb Michael Hanselmann
  def call_impexp_cleanup(self, node, name):
1613 1651d116 Michael Hanselmann
    """Cleans up after an import or export.
1614 1651d116 Michael Hanselmann

1615 1651d116 Michael Hanselmann
    This is a single-node call.
1616 1651d116 Michael Hanselmann

1617 1651d116 Michael Hanselmann
    @type node: string
1618 1651d116 Michael Hanselmann
    @param node: Node name
1619 1651d116 Michael Hanselmann
    @type name: string
1620 1651d116 Michael Hanselmann
    @param name: Import/export name
1621 1651d116 Michael Hanselmann

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