Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ a629ecb9

History | View | Annotate | Download (48.3 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 c29e35fe Michael Hanselmann
# Aliasing this module avoids the following warning by epydoc: "Warning: No
128 c29e35fe Michael Hanselmann
# information available for ganeti.rpc._RpcThreadLocal's base threading.local"
129 c29e35fe Michael Hanselmann
_threading = threading
130 c29e35fe Michael Hanselmann
131 c29e35fe Michael Hanselmann
132 c29e35fe Michael Hanselmann
class _RpcThreadLocal(_threading.local):
133 33231500 Michael Hanselmann
  def GetHttpClientPool(self):
134 33231500 Michael Hanselmann
    """Returns a per-thread HTTP client pool.
135 33231500 Michael Hanselmann

136 33231500 Michael Hanselmann
    @rtype: L{http.client.HttpClientPool}
137 33231500 Michael Hanselmann

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

158 92fd2250 Iustin Pop
  When applied to a rpc call_* function, it updates the global timeout
159 92fd2250 Iustin Pop
  table with the given function/timeout.
160 92fd2250 Iustin Pop

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

173 e0e916fe Iustin Pop
  When applied to a function, it runs it with the RPC system
174 e0e916fe Iustin Pop
  initialized, and it shutsdown the system afterwards. This means the
175 e0e916fe Iustin Pop
  function must be called without RPC being initialized.
176 e0e916fe Iustin Pop

177 e0e916fe Iustin Pop
  """
178 e0e916fe Iustin Pop
  def wrapper(*args, **kwargs):
179 e0e916fe Iustin Pop
    Init()
180 e0e916fe Iustin Pop
    try:
181 e0e916fe Iustin Pop
      return fn(*args, **kwargs)
182 e0e916fe Iustin Pop
    finally:
183 e0e916fe Iustin Pop
      Shutdown()
184 e0e916fe Iustin Pop
  return wrapper
185 e0e916fe Iustin Pop
186 e0e916fe Iustin Pop
187 30474135 Michael Hanselmann
def _Compress(data):
188 30474135 Michael Hanselmann
  """Compresses a string for transport over RPC.
189 30474135 Michael Hanselmann

190 30474135 Michael Hanselmann
  Small amounts of data are not compressed.
191 30474135 Michael Hanselmann

192 30474135 Michael Hanselmann
  @type data: str
193 30474135 Michael Hanselmann
  @param data: Data
194 30474135 Michael Hanselmann
  @rtype: tuple
195 30474135 Michael Hanselmann
  @return: Encoded data to send
196 30474135 Michael Hanselmann

197 30474135 Michael Hanselmann
  """
198 30474135 Michael Hanselmann
  # Small amounts of data are not compressed
199 30474135 Michael Hanselmann
  if len(data) < 512:
200 30474135 Michael Hanselmann
    return (constants.RPC_ENCODING_NONE, data)
201 30474135 Michael Hanselmann
202 30474135 Michael Hanselmann
  # Compress with zlib and encode in base64
203 30474135 Michael Hanselmann
  return (constants.RPC_ENCODING_ZLIB_BASE64,
204 30474135 Michael Hanselmann
          base64.b64encode(zlib.compress(data, 3)))
205 30474135 Michael Hanselmann
206 30474135 Michael Hanselmann
207 781de953 Iustin Pop
class RpcResult(object):
208 781de953 Iustin Pop
  """RPC Result class.
209 781de953 Iustin Pop

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

214 5bbd3f7f Michael Hanselmann
  @ivar data: the data payload, for successful results, or None
215 ed83f5cc Iustin Pop
  @ivar call: the name of the RPC call
216 ed83f5cc Iustin Pop
  @ivar node: the name of the node to which we made the call
217 ed83f5cc Iustin Pop
  @ivar offline: whether the operation failed because the node was
218 ed83f5cc Iustin Pop
      offline, as opposed to actual failure; offline=True will always
219 ed83f5cc Iustin Pop
      imply failed=True, in order to allow simpler checking if
220 ed83f5cc Iustin Pop
      the user doesn't care about the exact failure mode
221 4c4e4e1e Iustin Pop
  @ivar fail_msg: the error message if the call failed
222 ed83f5cc Iustin Pop

223 781de953 Iustin Pop
  """
224 ed83f5cc Iustin Pop
  def __init__(self, data=None, failed=False, offline=False,
225 ed83f5cc Iustin Pop
               call=None, node=None):
226 ed83f5cc Iustin Pop
    self.offline = offline
227 ed83f5cc Iustin Pop
    self.call = call
228 ed83f5cc Iustin Pop
    self.node = node
229 1645d22d Michael Hanselmann
230 ed83f5cc Iustin Pop
    if offline:
231 4c4e4e1e Iustin Pop
      self.fail_msg = "Node is marked offline"
232 f2def43a Iustin Pop
      self.data = self.payload = None
233 ed83f5cc Iustin Pop
    elif failed:
234 4c4e4e1e Iustin Pop
      self.fail_msg = self._EnsureErr(data)
235 f2def43a Iustin Pop
      self.data = self.payload = None
236 781de953 Iustin Pop
    else:
237 781de953 Iustin Pop
      self.data = data
238 d3c8b360 Iustin Pop
      if not isinstance(self.data, (tuple, list)):
239 4c4e4e1e Iustin Pop
        self.fail_msg = ("RPC layer error: invalid result type (%s)" %
240 4c4e4e1e Iustin Pop
                         type(self.data))
241 1645d22d Michael Hanselmann
        self.payload = None
242 d3c8b360 Iustin Pop
      elif len(data) != 2:
243 4c4e4e1e Iustin Pop
        self.fail_msg = ("RPC layer error: invalid result length (%d), "
244 4c4e4e1e Iustin Pop
                         "expected 2" % len(self.data))
245 1645d22d Michael Hanselmann
        self.payload = None
246 d3c8b360 Iustin Pop
      elif not self.data[0]:
247 4c4e4e1e Iustin Pop
        self.fail_msg = self._EnsureErr(self.data[1])
248 1645d22d Michael Hanselmann
        self.payload = None
249 f2def43a Iustin Pop
      else:
250 d3c8b360 Iustin Pop
        # finally success
251 4c4e4e1e Iustin Pop
        self.fail_msg = None
252 d3c8b360 Iustin Pop
        self.payload = data[1]
253 d3c8b360 Iustin Pop
254 2c0f74f2 Iustin Pop
    for attr_name in ["call", "data", "fail_msg",
255 2c0f74f2 Iustin Pop
                      "node", "offline", "payload"]:
256 2c0f74f2 Iustin Pop
      assert hasattr(self, attr_name), "Missing attribute %s" % attr_name
257 1645d22d Michael Hanselmann
258 d3c8b360 Iustin Pop
  @staticmethod
259 d3c8b360 Iustin Pop
  def _EnsureErr(val):
260 d3c8b360 Iustin Pop
    """Helper to ensure we return a 'True' value for error."""
261 d3c8b360 Iustin Pop
    if val:
262 d3c8b360 Iustin Pop
      return val
263 d3c8b360 Iustin Pop
    else:
264 d3c8b360 Iustin Pop
      return "No error information"
265 781de953 Iustin Pop
266 045dd6d9 Iustin Pop
  def Raise(self, msg, prereq=False, ecode=None):
267 781de953 Iustin Pop
    """If the result has failed, raise an OpExecError.
268 781de953 Iustin Pop

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

272 781de953 Iustin Pop
    """
273 4c4e4e1e Iustin Pop
    if not self.fail_msg:
274 4c4e4e1e Iustin Pop
      return
275 4c4e4e1e Iustin Pop
276 4c4e4e1e Iustin Pop
    if not msg: # one could pass None for default message
277 4c4e4e1e Iustin Pop
      msg = ("Call '%s' to node '%s' has failed: %s" %
278 4c4e4e1e Iustin Pop
             (self.call, self.node, self.fail_msg))
279 4c4e4e1e Iustin Pop
    else:
280 4c4e4e1e Iustin Pop
      msg = "%s: %s" % (msg, self.fail_msg)
281 4c4e4e1e Iustin Pop
    if prereq:
282 4c4e4e1e Iustin Pop
      ec = errors.OpPrereqError
283 4c4e4e1e Iustin Pop
    else:
284 4c4e4e1e Iustin Pop
      ec = errors.OpExecError
285 045dd6d9 Iustin Pop
    if ecode is not None:
286 27137e55 Iustin Pop
      args = (msg, ecode)
287 045dd6d9 Iustin Pop
    else:
288 045dd6d9 Iustin Pop
      args = (msg, )
289 b459a848 Andrea Spadaccini
    raise ec(*args) # pylint: disable=W0142
290 781de953 Iustin Pop
291 781de953 Iustin Pop
292 00267bfe Michael Hanselmann
def _SsconfResolver(node_list,
293 00267bfe Michael Hanselmann
                    ssc=ssconf.SimpleStore,
294 00267bfe Michael Hanselmann
                    nslookup_fn=netutils.Hostname.GetIP):
295 eb202c13 Manuel Franceschini
  """Return addresses for given node names.
296 eb202c13 Manuel Franceschini

297 eb202c13 Manuel Franceschini
  @type node_list: list
298 eb202c13 Manuel Franceschini
  @param node_list: List of node names
299 eb202c13 Manuel Franceschini
  @type ssc: class
300 eb202c13 Manuel Franceschini
  @param ssc: SimpleStore class that is used to obtain node->ip mappings
301 17f7fd27 Manuel Franceschini
  @type nslookup_fn: callable
302 17f7fd27 Manuel Franceschini
  @param nslookup_fn: function use to do NS lookup
303 00267bfe Michael Hanselmann
  @rtype: list of tuple; (string, string)
304 00267bfe Michael Hanselmann
  @return: List of tuples containing node name and IP address
305 eb202c13 Manuel Franceschini

306 eb202c13 Manuel Franceschini
  """
307 b43dcc5a Manuel Franceschini
  ss = ssc()
308 b43dcc5a Manuel Franceschini
  iplist = ss.GetNodePrimaryIPList()
309 b43dcc5a Manuel Franceschini
  family = ss.GetPrimaryIPFamily()
310 b705c7a6 Manuel Franceschini
  ipmap = dict(entry.split() for entry in iplist)
311 00267bfe Michael Hanselmann
312 00267bfe Michael Hanselmann
  result = []
313 b705c7a6 Manuel Franceschini
  for node in node_list:
314 00267bfe Michael Hanselmann
    ip = ipmap.get(node)
315 00267bfe Michael Hanselmann
    if ip is None:
316 00267bfe Michael Hanselmann
      ip = nslookup_fn(node, family=family)
317 00267bfe Michael Hanselmann
    result.append((node, ip))
318 00267bfe Michael Hanselmann
319 00267bfe Michael Hanselmann
  return result
320 00267bfe Michael Hanselmann
321 00267bfe Michael Hanselmann
322 00267bfe Michael Hanselmann
class _StaticResolver:
323 00267bfe Michael Hanselmann
  def __init__(self, addresses):
324 00267bfe Michael Hanselmann
    """Initializes this class.
325 00267bfe Michael Hanselmann

326 00267bfe Michael Hanselmann
    """
327 00267bfe Michael Hanselmann
    self._addresses = addresses
328 00267bfe Michael Hanselmann
329 00267bfe Michael Hanselmann
  def __call__(self, hosts):
330 00267bfe Michael Hanselmann
    """Returns static addresses for hosts.
331 00267bfe Michael Hanselmann

332 00267bfe Michael Hanselmann
    """
333 00267bfe Michael Hanselmann
    assert len(hosts) == len(self._addresses)
334 00267bfe Michael Hanselmann
    return zip(hosts, self._addresses)
335 00267bfe Michael Hanselmann
336 eb202c13 Manuel Franceschini
337 00267bfe Michael Hanselmann
def _CheckConfigNode(name, node):
338 00267bfe Michael Hanselmann
  """Checks if a node is online.
339 eb202c13 Manuel Franceschini

340 00267bfe Michael Hanselmann
  @type name: string
341 00267bfe Michael Hanselmann
  @param name: Node name
342 00267bfe Michael Hanselmann
  @type node: L{objects.Node} or None
343 00267bfe Michael Hanselmann
  @param node: Node object
344 eb202c13 Manuel Franceschini

345 00267bfe Michael Hanselmann
  """
346 00267bfe Michael Hanselmann
  if node is None:
347 00267bfe Michael Hanselmann
    # Depend on DNS for name resolution
348 00267bfe Michael Hanselmann
    ip = name
349 00267bfe Michael Hanselmann
  elif node.offline:
350 00267bfe Michael Hanselmann
    ip = _OFFLINE
351 00267bfe Michael Hanselmann
  else:
352 00267bfe Michael Hanselmann
    ip = node.primary_ip
353 00267bfe Michael Hanselmann
  return (name, ip)
354 a8083063 Iustin Pop
355 a8083063 Iustin Pop
356 00267bfe Michael Hanselmann
def _NodeConfigResolver(single_node_fn, all_nodes_fn, hosts):
357 00267bfe Michael Hanselmann
  """Calculate node addresses using configuration.
358 a8083063 Iustin Pop

359 a8083063 Iustin Pop
  """
360 00267bfe Michael Hanselmann
  # Special case for single-host lookups
361 00267bfe Michael Hanselmann
  if len(hosts) == 1:
362 00267bfe Michael Hanselmann
    (name, ) = hosts
363 00267bfe Michael Hanselmann
    return [_CheckConfigNode(name, single_node_fn(name))]
364 00267bfe Michael Hanselmann
  else:
365 00267bfe Michael Hanselmann
    all_nodes = all_nodes_fn()
366 00267bfe Michael Hanselmann
    return [_CheckConfigNode(name, all_nodes.get(name, None))
367 00267bfe Michael Hanselmann
            for name in hosts]
368 00267bfe Michael Hanselmann
369 00267bfe Michael Hanselmann
370 00267bfe Michael Hanselmann
class _RpcProcessor:
371 aea5caef Michael Hanselmann
  def __init__(self, resolver, port, lock_monitor_cb=None):
372 00267bfe Michael Hanselmann
    """Initializes this class.
373 00267bfe Michael Hanselmann

374 00267bfe Michael Hanselmann
    @param resolver: callable accepting a list of hostnames, returning a list
375 00267bfe Michael Hanselmann
      of tuples containing name and IP address (IP address can be the name or
376 00267bfe Michael Hanselmann
      the special value L{_OFFLINE} to mark offline machines)
377 00267bfe Michael Hanselmann
    @type port: int
378 00267bfe Michael Hanselmann
    @param port: TCP port
379 aea5caef Michael Hanselmann
    @param lock_monitor_cb: Callable for registering with lock monitor
380 3ef3c771 Iustin Pop

381 a8083063 Iustin Pop
    """
382 00267bfe Michael Hanselmann
    self._resolver = resolver
383 00267bfe Michael Hanselmann
    self._port = port
384 aea5caef Michael Hanselmann
    self._lock_monitor_cb = lock_monitor_cb
385 eb202c13 Manuel Franceschini
386 00267bfe Michael Hanselmann
  @staticmethod
387 00267bfe Michael Hanselmann
  def _PrepareRequests(hosts, port, procedure, body, read_timeout):
388 00267bfe Michael Hanselmann
    """Prepares requests by sorting offline hosts into separate list.
389 eb202c13 Manuel Franceschini

390 00267bfe Michael Hanselmann
    """
391 00267bfe Michael Hanselmann
    results = {}
392 00267bfe Michael Hanselmann
    requests = {}
393 bdf7d8c0 Iustin Pop
394 00267bfe Michael Hanselmann
    for (name, ip) in hosts:
395 00267bfe Michael Hanselmann
      if ip is _OFFLINE:
396 00267bfe Michael Hanselmann
        # Node is marked as offline
397 00267bfe Michael Hanselmann
        results[name] = RpcResult(node=name, offline=True, call=procedure)
398 00267bfe Michael Hanselmann
      else:
399 00267bfe Michael Hanselmann
        requests[name] = \
400 00267bfe Michael Hanselmann
          http.client.HttpClientRequest(str(ip), port,
401 00267bfe Michael Hanselmann
                                        http.HTTP_PUT, str("/%s" % procedure),
402 00267bfe Michael Hanselmann
                                        headers=_RPC_CLIENT_HEADERS,
403 00267bfe Michael Hanselmann
                                        post_data=body,
404 7cb2d205 Michael Hanselmann
                                        read_timeout=read_timeout,
405 7cb2d205 Michael Hanselmann
                                        nicename="%s/%s" % (name, procedure))
406 a8083063 Iustin Pop
407 00267bfe Michael Hanselmann
    return (results, requests)
408 00267bfe Michael Hanselmann
409 00267bfe Michael Hanselmann
  @staticmethod
410 00267bfe Michael Hanselmann
  def _CombineResults(results, requests, procedure):
411 00267bfe Michael Hanselmann
    """Combines pre-computed results for offline hosts with actual call results.
412 bdf7d8c0 Iustin Pop

413 a8083063 Iustin Pop
    """
414 00267bfe Michael Hanselmann
    for name, req in requests.items():
415 00267bfe Michael Hanselmann
      if req.success and req.resp_status_code == http.HTTP_OK:
416 00267bfe Michael Hanselmann
        host_result = RpcResult(data=serializer.LoadJson(req.resp_body),
417 00267bfe Michael Hanselmann
                                node=name, call=procedure)
418 00267bfe Michael Hanselmann
      else:
419 00267bfe Michael Hanselmann
        # TODO: Better error reporting
420 00267bfe Michael Hanselmann
        if req.error:
421 00267bfe Michael Hanselmann
          msg = req.error
422 00267bfe Michael Hanselmann
        else:
423 00267bfe Michael Hanselmann
          msg = req.resp_body
424 eb202c13 Manuel Franceschini
425 00267bfe Michael Hanselmann
        logging.error("RPC error in %s on node %s: %s", procedure, name, msg)
426 00267bfe Michael Hanselmann
        host_result = RpcResult(data=msg, failed=True, node=name,
427 00267bfe Michael Hanselmann
                                call=procedure)
428 ecfe9491 Michael Hanselmann
429 00267bfe Michael Hanselmann
      results[name] = host_result
430 92fd2250 Iustin Pop
431 00267bfe Michael Hanselmann
    return results
432 a8083063 Iustin Pop
433 00267bfe Michael Hanselmann
  def __call__(self, hosts, procedure, body, read_timeout=None, http_pool=None):
434 00267bfe Michael Hanselmann
    """Makes an RPC request to a number of nodes.
435 ecfe9491 Michael Hanselmann

436 00267bfe Michael Hanselmann
    @type hosts: sequence
437 00267bfe Michael Hanselmann
    @param hosts: Hostnames
438 00267bfe Michael Hanselmann
    @type procedure: string
439 00267bfe Michael Hanselmann
    @param procedure: Request path
440 00267bfe Michael Hanselmann
    @type body: string
441 00267bfe Michael Hanselmann
    @param body: Request body
442 00267bfe Michael Hanselmann
    @type read_timeout: int or None
443 00267bfe Michael Hanselmann
    @param read_timeout: Read timeout for request
444 a8083063 Iustin Pop

445 a8083063 Iustin Pop
    """
446 00267bfe Michael Hanselmann
    assert procedure in _TIMEOUTS, "RPC call not declared in the timeouts table"
447 00267bfe Michael Hanselmann
448 33231500 Michael Hanselmann
    if not http_pool:
449 33231500 Michael Hanselmann
      http_pool = _thread_local.GetHttpClientPool()
450 4331f6cd Michael Hanselmann
451 00267bfe Michael Hanselmann
    if read_timeout is None:
452 00267bfe Michael Hanselmann
      read_timeout = _TIMEOUTS[procedure]
453 a8083063 Iustin Pop
454 00267bfe Michael Hanselmann
    (results, requests) = \
455 00267bfe Michael Hanselmann
      self._PrepareRequests(self._resolver(hosts), self._port, procedure,
456 00267bfe Michael Hanselmann
                            str(body), read_timeout)
457 a8083063 Iustin Pop
458 aea5caef Michael Hanselmann
    http_pool.ProcessRequests(requests.values(),
459 aea5caef Michael Hanselmann
                              lock_monitor_cb=self._lock_monitor_cb)
460 a8083063 Iustin Pop
461 00267bfe Michael Hanselmann
    assert not frozenset(results).intersection(requests)
462 ecfe9491 Michael Hanselmann
463 00267bfe Michael Hanselmann
    return self._CombineResults(results, requests, procedure)
464 a8083063 Iustin Pop
465 a8083063 Iustin Pop
466 1651d116 Michael Hanselmann
def _EncodeImportExportIO(ieio, ieioargs):
467 1651d116 Michael Hanselmann
  """Encodes import/export I/O information.
468 1651d116 Michael Hanselmann

469 1651d116 Michael Hanselmann
  """
470 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_RAW_DISK:
471 1651d116 Michael Hanselmann
    assert len(ieioargs) == 1
472 1651d116 Michael Hanselmann
    return (ieioargs[0].ToDict(), )
473 1651d116 Michael Hanselmann
474 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_SCRIPT:
475 1651d116 Michael Hanselmann
    assert len(ieioargs) == 2
476 1651d116 Michael Hanselmann
    return (ieioargs[0].ToDict(), ieioargs[1])
477 1651d116 Michael Hanselmann
478 1651d116 Michael Hanselmann
  return ieioargs
479 1651d116 Michael Hanselmann
480 1651d116 Michael Hanselmann
481 72737a7f Iustin Pop
class RpcRunner(object):
482 87b3cb26 Michael Hanselmann
  """RPC runner class.
483 a8083063 Iustin Pop

484 87b3cb26 Michael Hanselmann
  """
485 87b3cb26 Michael Hanselmann
  def __init__(self, context):
486 87b3cb26 Michael Hanselmann
    """Initialized the RPC runner.
487 a8083063 Iustin Pop

488 87b3cb26 Michael Hanselmann
    @type context: C{masterd.GanetiContext}
489 87b3cb26 Michael Hanselmann
    @param context: Ganeti context
490 a8083063 Iustin Pop

491 72737a7f Iustin Pop
    """
492 87b3cb26 Michael Hanselmann
    self._cfg = context.cfg
493 00267bfe Michael Hanselmann
    self._proc = _RpcProcessor(compat.partial(_NodeConfigResolver,
494 00267bfe Michael Hanselmann
                                              self._cfg.GetNodeInfo,
495 00267bfe Michael Hanselmann
                                              self._cfg.GetAllNodesInfo),
496 aea5caef Michael Hanselmann
                               netutils.GetDaemonPort(constants.NODED),
497 aea5caef Michael Hanselmann
                               lock_monitor_cb=context.glm.AddToLockMonitor)
498 a8083063 Iustin Pop
499 1bdcbbab Iustin Pop
  def _InstDict(self, instance, hvp=None, bep=None, osp=None):
500 26ba2bd8 Iustin Pop
    """Convert the given instance to a dict.
501 26ba2bd8 Iustin Pop

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

505 26ba2bd8 Iustin Pop
    @type instance: L{objects.Instance}
506 26ba2bd8 Iustin Pop
    @param instance: an Instance object
507 0eca8e0c Iustin Pop
    @type hvp: dict or None
508 5bbd3f7f Michael Hanselmann
    @param hvp: a dictionary with overridden hypervisor parameters
509 0eca8e0c Iustin Pop
    @type bep: dict or None
510 5bbd3f7f Michael Hanselmann
    @param bep: a dictionary with overridden backend parameters
511 1bdcbbab Iustin Pop
    @type osp: dict or None
512 8d8c4eff Michael Hanselmann
    @param osp: a dictionary with overridden os parameters
513 26ba2bd8 Iustin Pop
    @rtype: dict
514 26ba2bd8 Iustin Pop
    @return: the instance dict, with the hvparams filled with the
515 26ba2bd8 Iustin Pop
        cluster defaults
516 26ba2bd8 Iustin Pop

517 26ba2bd8 Iustin Pop
    """
518 26ba2bd8 Iustin Pop
    idict = instance.ToDict()
519 5b442704 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
520 5b442704 Iustin Pop
    idict["hvparams"] = cluster.FillHV(instance)
521 0eca8e0c Iustin Pop
    if hvp is not None:
522 0eca8e0c Iustin Pop
      idict["hvparams"].update(hvp)
523 5b442704 Iustin Pop
    idict["beparams"] = cluster.FillBE(instance)
524 0eca8e0c Iustin Pop
    if bep is not None:
525 0eca8e0c Iustin Pop
      idict["beparams"].update(bep)
526 1bdcbbab Iustin Pop
    idict["osparams"] = cluster.SimpleFillOS(instance.os, instance.osparams)
527 1bdcbbab Iustin Pop
    if osp is not None:
528 1bdcbbab Iustin Pop
      idict["osparams"].update(osp)
529 b848ce79 Guido Trotter
    for nic in idict["nics"]:
530 b848ce79 Guido Trotter
      nic['nicparams'] = objects.FillDict(
531 b848ce79 Guido Trotter
        cluster.nicparams[constants.PP_DEFAULT],
532 b848ce79 Guido Trotter
        nic['nicparams'])
533 26ba2bd8 Iustin Pop
    return idict
534 26ba2bd8 Iustin Pop
535 e0036155 Iustin Pop
  def _MultiNodeCall(self, node_list, procedure, args, read_timeout=None):
536 160e2921 Iustin Pop
    """Helper for making a multi-node call
537 160e2921 Iustin Pop

538 160e2921 Iustin Pop
    """
539 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
540 00267bfe Michael Hanselmann
    return self._proc(node_list, procedure, body, read_timeout=read_timeout)
541 9a525d83 Michael Hanselmann
542 00267bfe Michael Hanselmann
  @staticmethod
543 00267bfe Michael Hanselmann
  def _StaticMultiNodeCall(node_list, procedure, args,
544 e0036155 Iustin Pop
                           address_list=None, read_timeout=None):
545 160e2921 Iustin Pop
    """Helper for making a multi-node static call
546 160e2921 Iustin Pop

547 160e2921 Iustin Pop
    """
548 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
549 00267bfe Michael Hanselmann
550 00267bfe Michael Hanselmann
    if address_list is None:
551 00267bfe Michael Hanselmann
      resolver = _SsconfResolver
552 00267bfe Michael Hanselmann
    else:
553 00267bfe Michael Hanselmann
      # Caller provided an address list
554 00267bfe Michael Hanselmann
      resolver = _StaticResolver(address_list)
555 00267bfe Michael Hanselmann
556 00267bfe Michael Hanselmann
    proc = _RpcProcessor(resolver,
557 00267bfe Michael Hanselmann
                         netutils.GetDaemonPort(constants.NODED))
558 00267bfe Michael Hanselmann
    return proc(node_list, procedure, body, read_timeout=read_timeout)
559 9a525d83 Michael Hanselmann
560 e0036155 Iustin Pop
  def _SingleNodeCall(self, node, procedure, args, read_timeout=None):
561 160e2921 Iustin Pop
    """Helper for making a single-node call
562 9a525d83 Michael Hanselmann

563 9a525d83 Michael Hanselmann
    """
564 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
565 00267bfe Michael Hanselmann
    return self._proc([node], procedure, body, read_timeout=read_timeout)[node]
566 9a525d83 Michael Hanselmann
567 9a525d83 Michael Hanselmann
  @classmethod
568 e0036155 Iustin Pop
  def _StaticSingleNodeCall(cls, node, procedure, args, read_timeout=None):
569 160e2921 Iustin Pop
    """Helper for making a single-node static call
570 9a525d83 Michael Hanselmann

571 9a525d83 Michael Hanselmann
    """
572 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
573 00267bfe Michael Hanselmann
    proc = _RpcProcessor(_SsconfResolver,
574 00267bfe Michael Hanselmann
                         netutils.GetDaemonPort(constants.NODED))
575 00267bfe Michael Hanselmann
    return proc([node], procedure, body, read_timeout=read_timeout)[node]
576 9a525d83 Michael Hanselmann
577 781de953 Iustin Pop
  #
578 781de953 Iustin Pop
  # Begin RPC calls
579 781de953 Iustin Pop
  #
580 781de953 Iustin Pop
581 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
582 2be7273c Apollon Oikonomopoulos
  def call_bdev_sizes(self, node_list, devices):
583 2be7273c Apollon Oikonomopoulos
    """Gets the sizes of requested block devices present on a node
584 2be7273c Apollon Oikonomopoulos

585 2be7273c Apollon Oikonomopoulos
    This is a multi-node call.
586 2be7273c Apollon Oikonomopoulos

587 2be7273c Apollon Oikonomopoulos
    """
588 2be7273c Apollon Oikonomopoulos
    return self._MultiNodeCall(node_list, "bdev_sizes", [devices])
589 2be7273c Apollon Oikonomopoulos
590 2be7273c Apollon Oikonomopoulos
  @_RpcTimeout(_TMO_URGENT)
591 b2a6ccd4 Iustin Pop
  def call_lv_list(self, node_list, vg_name):
592 72737a7f Iustin Pop
    """Gets the logical volumes present in a given volume group.
593 a8083063 Iustin Pop

594 72737a7f Iustin Pop
    This is a multi-node call.
595 a8083063 Iustin Pop

596 72737a7f Iustin Pop
    """
597 b2a6ccd4 Iustin Pop
    return self._MultiNodeCall(node_list, "lv_list", [vg_name])
598 a8083063 Iustin Pop
599 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
600 72737a7f Iustin Pop
  def call_vg_list(self, node_list):
601 72737a7f Iustin Pop
    """Gets the volume group list.
602 a8083063 Iustin Pop

603 72737a7f Iustin Pop
    This is a multi-node call.
604 a8083063 Iustin Pop

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

612 e337de97 Michael Hanselmann
    This is a multi-node call.
613 e337de97 Michael Hanselmann

614 e337de97 Michael Hanselmann
    """
615 e337de97 Michael Hanselmann
    return self._MultiNodeCall(node_list, "storage_list",
616 e337de97 Michael Hanselmann
                               [su_name, su_args, name, fields])
617 e337de97 Michael Hanselmann
618 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
619 8979196a Michael Hanselmann
  def call_storage_modify(self, node, su_name, su_args, name, changes):
620 8979196a Michael Hanselmann
    """Modify a storage unit.
621 8979196a Michael Hanselmann

622 8979196a Michael Hanselmann
    This is a single-node call.
623 8979196a Michael Hanselmann

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

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

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

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

646 72737a7f Iustin Pop
    This is a single-node call.
647 a8083063 Iustin Pop

648 72737a7f Iustin Pop
    """
649 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "bridges_exist", [bridges_list])
650 a8083063 Iustin Pop
651 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
652 323f9095 Stephen Shirley
  def call_instance_start(self, node, instance, hvp, bep, startup_paused):
653 72737a7f Iustin Pop
    """Starts an instance.
654 a8083063 Iustin Pop

655 72737a7f Iustin Pop
    This is a single-node call.
656 a8083063 Iustin Pop

657 72737a7f Iustin Pop
    """
658 0eca8e0c Iustin Pop
    idict = self._InstDict(instance, hvp=hvp, bep=bep)
659 323f9095 Stephen Shirley
    return self._SingleNodeCall(node, "instance_start", [idict, startup_paused])
660 a8083063 Iustin Pop
661 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
662 6263189c Guido Trotter
  def call_instance_shutdown(self, node, instance, timeout):
663 72737a7f Iustin Pop
    """Stops an instance.
664 a8083063 Iustin Pop

665 72737a7f Iustin Pop
    This is a single-node call.
666 2a10865c Iustin Pop

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

675 6906a9d8 Guido Trotter
    This is a single-node call.
676 6906a9d8 Guido Trotter

677 6906a9d8 Guido Trotter
    @type node: string
678 6906a9d8 Guido Trotter
    @param node: the node on which the instance is currently running
679 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
680 6906a9d8 Guido Trotter
    @param instance: the instance definition
681 6906a9d8 Guido Trotter

682 6906a9d8 Guido Trotter
    """
683 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "migration_info",
684 6906a9d8 Guido Trotter
                                [self._InstDict(instance)])
685 6906a9d8 Guido Trotter
686 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
687 6906a9d8 Guido Trotter
  def call_accept_instance(self, node, instance, info, target):
688 6906a9d8 Guido Trotter
    """Prepare a node to accept an instance.
689 6906a9d8 Guido Trotter

690 6906a9d8 Guido Trotter
    This is a single-node call.
691 6906a9d8 Guido Trotter

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

701 6906a9d8 Guido Trotter
    """
702 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "accept_instance",
703 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, target])
704 6906a9d8 Guido Trotter
705 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
706 6a1434d7 Andrea Spadaccini
  def call_instance_finalize_migration_dst(self, node, instance, info, success):
707 6906a9d8 Guido Trotter
    """Finalize any target-node migration specific operation.
708 6906a9d8 Guido Trotter

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

712 6906a9d8 Guido Trotter
    This is a single-node call.
713 6906a9d8 Guido Trotter

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

723 6906a9d8 Guido Trotter
    """
724 6a1434d7 Andrea Spadaccini
    return self._SingleNodeCall(node, "instance_finalize_migration_dst",
725 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, success])
726 6906a9d8 Guido Trotter
727 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
728 72737a7f Iustin Pop
  def call_instance_migrate(self, node, instance, target, live):
729 72737a7f Iustin Pop
    """Migrate an instance.
730 2a10865c Iustin Pop

731 72737a7f Iustin Pop
    This is a single-node call.
732 2a10865c Iustin Pop

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

743 72737a7f Iustin Pop
    """
744 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_migrate",
745 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), target, live])
746 007a2f3e Alexander Schreiber
747 6a1434d7 Andrea Spadaccini
  @_RpcTimeout(_TMO_SLOW)
748 6a1434d7 Andrea Spadaccini
  def call_instance_finalize_migration_src(self, node, instance, success, live):
749 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the source node.
750 6a1434d7 Andrea Spadaccini

751 6a1434d7 Andrea Spadaccini
    This is a single-node call.
752 6a1434d7 Andrea Spadaccini

753 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
754 6a1434d7 Andrea Spadaccini
    @param instance: the instance that was migrated
755 6a1434d7 Andrea Spadaccini
    @type success: bool
756 6a1434d7 Andrea Spadaccini
    @param success: whether the migration succeeded or not
757 6a1434d7 Andrea Spadaccini
    @type live: bool
758 6a1434d7 Andrea Spadaccini
    @param live: whether the user requested a live migration or not
759 6a1434d7 Andrea Spadaccini

760 6a1434d7 Andrea Spadaccini
    """
761 6a1434d7 Andrea Spadaccini
    return self._SingleNodeCall(node, "instance_finalize_migration_src",
762 6a1434d7 Andrea Spadaccini
                                [self._InstDict(instance), success, live])
763 6a1434d7 Andrea Spadaccini
764 6a1434d7 Andrea Spadaccini
  @_RpcTimeout(_TMO_SLOW)
765 6a1434d7 Andrea Spadaccini
  def call_instance_get_migration_status(self, node, instance):
766 6a1434d7 Andrea Spadaccini
    """Report migration status.
767 6a1434d7 Andrea Spadaccini

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

770 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
771 6a1434d7 Andrea Spadaccini
    @param instance: the instance that is being migrated
772 6a1434d7 Andrea Spadaccini
    @rtype: L{objects.MigrationStatus}
773 6a1434d7 Andrea Spadaccini
    @return: the status of the current migration (one of
774 6a1434d7 Andrea Spadaccini
             L{constants.HV_MIGRATION_VALID_STATUSES}), plus any additional
775 6a1434d7 Andrea Spadaccini
             progress info that can be retrieved from the hypervisor
776 6a1434d7 Andrea Spadaccini

777 6a1434d7 Andrea Spadaccini
    """
778 6a1434d7 Andrea Spadaccini
    result = self._SingleNodeCall(node, "instance_get_migration_status",
779 6a1434d7 Andrea Spadaccini
                                  [self._InstDict(instance)])
780 6a1434d7 Andrea Spadaccini
    if not result.fail_msg and result.payload is not None:
781 6a1434d7 Andrea Spadaccini
      result.payload = objects.MigrationStatus.FromDict(result.payload)
782 6a1434d7 Andrea Spadaccini
    return result
783 6a1434d7 Andrea Spadaccini
784 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
785 17c3f802 Guido Trotter
  def call_instance_reboot(self, node, inst, reboot_type, shutdown_timeout):
786 72737a7f Iustin Pop
    """Reboots an instance.
787 007a2f3e Alexander Schreiber

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

790 72737a7f Iustin Pop
    """
791 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_reboot",
792 17c3f802 Guido Trotter
                                [self._InstDict(inst), reboot_type,
793 17c3f802 Guido Trotter
                                 shutdown_timeout])
794 a8083063 Iustin Pop
795 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_1DAY)
796 8d8c4eff Michael Hanselmann
  def call_instance_os_add(self, node, inst, reinstall, debug, osparams=None):
797 72737a7f Iustin Pop
    """Installs an OS on the given instance.
798 a8083063 Iustin Pop

799 72737a7f Iustin Pop
    This is a single-node call.
800 decd5f45 Iustin Pop

801 72737a7f Iustin Pop
    """
802 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_os_add",
803 8d8c4eff Michael Hanselmann
                                [self._InstDict(inst, osp=osparams),
804 8d8c4eff Michael Hanselmann
                                 reinstall, debug])
805 decd5f45 Iustin Pop
806 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
807 4a0e011f Iustin Pop
  def call_instance_run_rename(self, node, inst, old_name, debug):
808 72737a7f Iustin Pop
    """Run the OS rename script for an instance.
809 decd5f45 Iustin Pop

810 72737a7f Iustin Pop
    This is a single-node call.
811 a8083063 Iustin Pop

812 72737a7f Iustin Pop
    """
813 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_run_rename",
814 4a0e011f Iustin Pop
                                [self._InstDict(inst), old_name, debug])
815 a8083063 Iustin Pop
816 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
817 72737a7f Iustin Pop
  def call_instance_info(self, node, instance, hname):
818 72737a7f Iustin Pop
    """Returns information about a single instance.
819 a8083063 Iustin Pop

820 72737a7f Iustin Pop
    This is a single-node call.
821 a8083063 Iustin Pop

822 9a525d83 Michael Hanselmann
    @type node: list
823 9a525d83 Michael Hanselmann
    @param node: the list of nodes to query
824 72737a7f Iustin Pop
    @type instance: string
825 72737a7f Iustin Pop
    @param instance: the instance name
826 72737a7f Iustin Pop
    @type hname: string
827 72737a7f Iustin Pop
    @param hname: the hypervisor type of the instance
828 a8083063 Iustin Pop

829 72737a7f Iustin Pop
    """
830 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_info", [instance, hname])
831 e69d05fd Iustin Pop
832 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
833 56e7640c Iustin Pop
  def call_instance_migratable(self, node, instance):
834 56e7640c Iustin Pop
    """Checks whether the given instance can be migrated.
835 56e7640c Iustin Pop

836 56e7640c Iustin Pop
    This is a single-node call.
837 56e7640c Iustin Pop

838 56e7640c Iustin Pop
    @param node: the node to query
839 56e7640c Iustin Pop
    @type instance: L{objects.Instance}
840 56e7640c Iustin Pop
    @param instance: the instance to check
841 56e7640c Iustin Pop

842 56e7640c Iustin Pop

843 56e7640c Iustin Pop
    """
844 56e7640c Iustin Pop
    return self._SingleNodeCall(node, "instance_migratable",
845 56e7640c Iustin Pop
                                [self._InstDict(instance)])
846 56e7640c Iustin Pop
847 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
848 72737a7f Iustin Pop
  def call_all_instances_info(self, node_list, hypervisor_list):
849 72737a7f Iustin Pop
    """Returns information about all instances on the given nodes.
850 a8083063 Iustin Pop

851 72737a7f Iustin Pop
    This is a multi-node call.
852 a8083063 Iustin Pop

853 72737a7f Iustin Pop
    @type node_list: list
854 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
855 72737a7f Iustin Pop
    @type hypervisor_list: list
856 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
857 a8083063 Iustin Pop

858 72737a7f Iustin Pop
    """
859 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "all_instances_info",
860 9a525d83 Michael Hanselmann
                               [hypervisor_list])
861 e69d05fd Iustin Pop
862 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
863 72737a7f Iustin Pop
  def call_instance_list(self, node_list, hypervisor_list):
864 72737a7f Iustin Pop
    """Returns the list of running instances on a given node.
865 a8083063 Iustin Pop

866 72737a7f Iustin Pop
    This is a multi-node call.
867 a8083063 Iustin Pop

868 72737a7f Iustin Pop
    @type node_list: list
869 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
870 72737a7f Iustin Pop
    @type hypervisor_list: list
871 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
872 16abfbc2 Alexander Schreiber

873 72737a7f Iustin Pop
    """
874 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "instance_list", [hypervisor_list])
875 16abfbc2 Alexander Schreiber
876 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
877 72737a7f Iustin Pop
  def call_node_tcp_ping(self, node, source, target, port, timeout,
878 72737a7f Iustin Pop
                         live_port_needed):
879 72737a7f Iustin Pop
    """Do a TcpPing on the remote node
880 a8083063 Iustin Pop

881 72737a7f Iustin Pop
    This is a single-node call.
882 caad16e2 Iustin Pop

883 72737a7f Iustin Pop
    """
884 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_tcp_ping",
885 9a525d83 Michael Hanselmann
                                [source, target, port, timeout,
886 72737a7f Iustin Pop
                                 live_port_needed])
887 a8083063 Iustin Pop
888 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
889 caad16e2 Iustin Pop
  def call_node_has_ip_address(self, node, address):
890 caad16e2 Iustin Pop
    """Checks if a node has the given IP address.
891 caad16e2 Iustin Pop

892 caad16e2 Iustin Pop
    This is a single-node call.
893 caad16e2 Iustin Pop

894 caad16e2 Iustin Pop
    """
895 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_has_ip_address", [address])
896 a8083063 Iustin Pop
897 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
898 72737a7f Iustin Pop
  def call_node_info(self, node_list, vg_name, hypervisor_type):
899 72737a7f Iustin Pop
    """Return node information.
900 e69d05fd Iustin Pop

901 72737a7f Iustin Pop
    This will return memory information and volume group size and free
902 72737a7f Iustin Pop
    space.
903 a8083063 Iustin Pop

904 72737a7f Iustin Pop
    This is a multi-node call.
905 a8083063 Iustin Pop

906 72737a7f Iustin Pop
    @type node_list: list
907 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
908 c41eea6e Iustin Pop
    @type vg_name: C{string}
909 c41eea6e Iustin Pop
    @param vg_name: the name of the volume group to ask for disk space
910 72737a7f Iustin Pop
        information
911 72737a7f Iustin Pop
    @type hypervisor_type: C{str}
912 72737a7f Iustin Pop
    @param hypervisor_type: the name of the hypervisor to ask for
913 72737a7f Iustin Pop
        memory information
914 a8083063 Iustin Pop

915 72737a7f Iustin Pop
    """
916 070e998b Iustin Pop
    return self._MultiNodeCall(node_list, "node_info",
917 070e998b Iustin Pop
                               [vg_name, hypervisor_type])
918 a8083063 Iustin Pop
919 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
920 19ddc57a René Nussbaumer
  def call_etc_hosts_modify(self, node, mode, name, ip):
921 19ddc57a René Nussbaumer
    """Modify hosts file with name
922 19ddc57a René Nussbaumer

923 19ddc57a René Nussbaumer
    @type node: string
924 19ddc57a René Nussbaumer
    @param node: The node to call
925 19ddc57a René Nussbaumer
    @type mode: string
926 19ddc57a René Nussbaumer
    @param mode: The mode to operate. Currently "add" or "remove"
927 19ddc57a René Nussbaumer
    @type name: string
928 19ddc57a René Nussbaumer
    @param name: The host name to be modified
929 19ddc57a René Nussbaumer
    @type ip: string
930 19ddc57a René Nussbaumer
    @param ip: The ip of the entry (just valid if mode is "add")
931 19ddc57a René Nussbaumer

932 19ddc57a René Nussbaumer
    """
933 19ddc57a René Nussbaumer
    return self._SingleNodeCall(node, "etc_hosts_modify", [mode, name, ip])
934 19ddc57a René Nussbaumer
935 19ddc57a René Nussbaumer
  @_RpcTimeout(_TMO_NORMAL)
936 72737a7f Iustin Pop
  def call_node_verify(self, node_list, checkdict, cluster_name):
937 72737a7f Iustin Pop
    """Request verification of given parameters.
938 a8083063 Iustin Pop

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

941 72737a7f Iustin Pop
    """
942 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_verify",
943 9a525d83 Michael Hanselmann
                               [checkdict, cluster_name])
944 a8083063 Iustin Pop
945 9a525d83 Michael Hanselmann
  @classmethod
946 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
947 fb460cf7 Andrea Spadaccini
  def call_node_start_master_daemons(cls, node, no_voting):
948 fb460cf7 Andrea Spadaccini
    """Starts master daemons on a node.
949 a8083063 Iustin Pop

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

952 72737a7f Iustin Pop
    """
953 fb460cf7 Andrea Spadaccini
    return cls._StaticSingleNodeCall(node, "node_start_master_daemons",
954 fb460cf7 Andrea Spadaccini
                                     [no_voting])
955 a8083063 Iustin Pop
956 9a525d83 Michael Hanselmann
  @classmethod
957 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
958 fb460cf7 Andrea Spadaccini
  def call_node_activate_master_ip(cls, node):
959 fb460cf7 Andrea Spadaccini
    """Activates master IP on a node.
960 a8083063 Iustin Pop

961 72737a7f Iustin Pop
    This is a single-node call.
962 4e071d3b Iustin Pop

963 72737a7f Iustin Pop
    """
964 fb460cf7 Andrea Spadaccini
    return cls._StaticSingleNodeCall(node, "node_activate_master_ip", [])
965 fb460cf7 Andrea Spadaccini
966 fb460cf7 Andrea Spadaccini
  @classmethod
967 fb460cf7 Andrea Spadaccini
  @_RpcTimeout(_TMO_FAST)
968 fb460cf7 Andrea Spadaccini
  def call_node_stop_master(cls, node):
969 fb460cf7 Andrea Spadaccini
    """Deactivates master IP and stops master daemons on a node.
970 fb460cf7 Andrea Spadaccini

971 fb460cf7 Andrea Spadaccini
    This is a single-node call.
972 fb460cf7 Andrea Spadaccini

973 fb460cf7 Andrea Spadaccini
    """
974 fb460cf7 Andrea Spadaccini
    return cls._StaticSingleNodeCall(node, "node_stop_master", [])
975 fb460cf7 Andrea Spadaccini
976 fb460cf7 Andrea Spadaccini
  @classmethod
977 fb460cf7 Andrea Spadaccini
  @_RpcTimeout(_TMO_FAST)
978 fb460cf7 Andrea Spadaccini
  def call_node_deactivate_master_ip(cls, node):
979 fb460cf7 Andrea Spadaccini
    """Deactivates master IP on a node.
980 fb460cf7 Andrea Spadaccini

981 fb460cf7 Andrea Spadaccini
    This is a single-node call.
982 fb460cf7 Andrea Spadaccini

983 fb460cf7 Andrea Spadaccini
    """
984 fb460cf7 Andrea Spadaccini
    return cls._StaticSingleNodeCall(node, "node_deactivate_master_ip", [])
985 4e071d3b Iustin Pop
986 9a525d83 Michael Hanselmann
  @classmethod
987 5a8648eb Andrea Spadaccini
  @_RpcTimeout(_TMO_FAST)
988 5a8648eb Andrea Spadaccini
  def call_node_change_master_netmask(cls, node, netmask):
989 5a8648eb Andrea Spadaccini
    """Change master IP netmask.
990 5a8648eb Andrea Spadaccini

991 5a8648eb Andrea Spadaccini
    This is a single-node call.
992 5a8648eb Andrea Spadaccini

993 5a8648eb Andrea Spadaccini
    """
994 5a8648eb Andrea Spadaccini
    return cls._StaticSingleNodeCall(node, "node_change_master_netmask",
995 5a8648eb Andrea Spadaccini
                  [netmask])
996 5a8648eb Andrea Spadaccini
997 5a8648eb Andrea Spadaccini
  @classmethod
998 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
999 9a525d83 Michael Hanselmann
  def call_master_info(cls, node_list):
1000 72737a7f Iustin Pop
    """Query master info.
1001 4e071d3b Iustin Pop

1002 72737a7f Iustin Pop
    This is a multi-node call.
1003 a8083063 Iustin Pop

1004 72737a7f Iustin Pop
    """
1005 72737a7f Iustin Pop
    # TODO: should this method query down nodes?
1006 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "master_info", [])
1007 a8083063 Iustin Pop
1008 8f215968 Michael Hanselmann
  @classmethod
1009 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
1010 8f215968 Michael Hanselmann
  def call_version(cls, node_list):
1011 72737a7f Iustin Pop
    """Query node version.
1012 a8083063 Iustin Pop

1013 72737a7f Iustin Pop
    This is a multi-node call.
1014 a8083063 Iustin Pop

1015 72737a7f Iustin Pop
    """
1016 8f215968 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "version", [])
1017 a8083063 Iustin Pop
1018 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1019 72737a7f Iustin Pop
  def call_blockdev_create(self, node, bdev, size, owner, on_primary, info):
1020 72737a7f Iustin Pop
    """Request creation of a given block device.
1021 a8083063 Iustin Pop

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

1024 72737a7f Iustin Pop
    """
1025 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_create",
1026 9a525d83 Michael Hanselmann
                                [bdev.ToDict(), size, owner, on_primary, info])
1027 a8083063 Iustin Pop
1028 271b7cf9 René Nussbaumer
  @_RpcTimeout(_TMO_SLOW)
1029 271b7cf9 René Nussbaumer
  def call_blockdev_wipe(self, node, bdev, offset, size):
1030 271b7cf9 René Nussbaumer
    """Request wipe at given offset with given size of a block device.
1031 271b7cf9 René Nussbaumer

1032 271b7cf9 René Nussbaumer
    This is a single-node call.
1033 271b7cf9 René Nussbaumer

1034 271b7cf9 René Nussbaumer
    """
1035 271b7cf9 René Nussbaumer
    return self._SingleNodeCall(node, "blockdev_wipe",
1036 271b7cf9 René Nussbaumer
                                [bdev.ToDict(), offset, size])
1037 271b7cf9 René Nussbaumer
1038 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1039 72737a7f Iustin Pop
  def call_blockdev_remove(self, node, bdev):
1040 72737a7f Iustin Pop
    """Request removal of a given block device.
1041 a8083063 Iustin Pop

1042 72737a7f Iustin Pop
    This is a single-node call.
1043 f3e513ad Iustin Pop

1044 72737a7f Iustin Pop
    """
1045 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_remove", [bdev.ToDict()])
1046 f3e513ad Iustin Pop
1047 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1048 72737a7f Iustin Pop
  def call_blockdev_rename(self, node, devlist):
1049 72737a7f Iustin Pop
    """Request rename of the given block devices.
1050 f3e513ad 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_rename",
1055 9a525d83 Michael Hanselmann
                                [(d.ToDict(), uid) for d, uid in devlist])
1056 a8083063 Iustin Pop
1057 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1058 9c007da8 René Nussbaumer
  def call_blockdev_pause_resume_sync(self, node, disks, pause):
1059 9c007da8 René Nussbaumer
    """Request a pause/resume of given block device.
1060 9c007da8 René Nussbaumer

1061 9c007da8 René Nussbaumer
    This is a single-node call.
1062 9c007da8 René Nussbaumer

1063 9c007da8 René Nussbaumer
    """
1064 9c007da8 René Nussbaumer
    return self._SingleNodeCall(node, "blockdev_pause_resume_sync",
1065 9c007da8 René Nussbaumer
                                [[bdev.ToDict() for bdev in disks], pause])
1066 9c007da8 René Nussbaumer
1067 9c007da8 René Nussbaumer
  @_RpcTimeout(_TMO_NORMAL)
1068 c417e115 Iustin Pop
  def call_blockdev_assemble(self, node, disk, owner, on_primary, idx):
1069 72737a7f Iustin Pop
    """Request assembling of a given block 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_assemble",
1075 c417e115 Iustin Pop
                                [disk.ToDict(), owner, on_primary, idx])
1076 a8083063 Iustin Pop
1077 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1078 72737a7f Iustin Pop
  def call_blockdev_shutdown(self, node, disk):
1079 72737a7f Iustin Pop
    """Request shutdown of a given block device.
1080 a8083063 Iustin Pop

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

1083 72737a7f Iustin Pop
    """
1084 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_shutdown", [disk.ToDict()])
1085 a8083063 Iustin Pop
1086 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1087 72737a7f Iustin Pop
  def call_blockdev_addchildren(self, node, bdev, ndevs):
1088 72737a7f Iustin Pop
    """Request adding a list of children to a (mirroring) device.
1089 a8083063 Iustin Pop

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

1092 72737a7f Iustin Pop
    """
1093 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_addchildren",
1094 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
1095 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
1096 a8083063 Iustin Pop
1097 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1098 72737a7f Iustin Pop
  def call_blockdev_removechildren(self, node, bdev, ndevs):
1099 72737a7f Iustin Pop
    """Request removing a list of children from a (mirroring) device.
1100 a8083063 Iustin Pop

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

1103 72737a7f Iustin Pop
    """
1104 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_removechildren",
1105 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
1106 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
1107 a8083063 Iustin Pop
1108 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1109 72737a7f Iustin Pop
  def call_blockdev_getmirrorstatus(self, node, disks):
1110 72737a7f Iustin Pop
    """Request status of a (mirroring) device.
1111 a8083063 Iustin Pop

1112 72737a7f Iustin Pop
    This is a single-node call.
1113 a8083063 Iustin Pop

1114 72737a7f Iustin Pop
    """
1115 36145b12 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_getmirrorstatus",
1116 36145b12 Michael Hanselmann
                                  [dsk.ToDict() for dsk in disks])
1117 edb4b374 Michael Hanselmann
    if not result.fail_msg:
1118 36145b12 Michael Hanselmann
      result.payload = [objects.BlockDevStatus.FromDict(i)
1119 36145b12 Michael Hanselmann
                        for i in result.payload]
1120 36145b12 Michael Hanselmann
    return result
1121 a8083063 Iustin Pop
1122 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1123 b8d26c6e Michael Hanselmann
  def call_blockdev_getmirrorstatus_multi(self, node_list, node_disks):
1124 b8d26c6e Michael Hanselmann
    """Request status of (mirroring) devices from multiple nodes.
1125 b8d26c6e Michael Hanselmann

1126 b8d26c6e Michael Hanselmann
    This is a multi-node call.
1127 b8d26c6e Michael Hanselmann

1128 b8d26c6e Michael Hanselmann
    """
1129 b8d26c6e Michael Hanselmann
    result = self._MultiNodeCall(node_list, "blockdev_getmirrorstatus_multi",
1130 b8d26c6e Michael Hanselmann
                                 [dict((name, [dsk.ToDict() for dsk in disks])
1131 b8d26c6e Michael Hanselmann
                                       for name, disks in node_disks.items())])
1132 b8d26c6e Michael Hanselmann
    for nres in result.values():
1133 c6a9dffa Michael Hanselmann
      if nres.fail_msg:
1134 c6a9dffa Michael Hanselmann
        continue
1135 c6a9dffa Michael Hanselmann
1136 c6a9dffa Michael Hanselmann
      for idx, (success, status) in enumerate(nres.payload):
1137 c6a9dffa Michael Hanselmann
        if success:
1138 c6a9dffa Michael Hanselmann
          nres.payload[idx] = (success, objects.BlockDevStatus.FromDict(status))
1139 c6a9dffa Michael Hanselmann
1140 b8d26c6e Michael Hanselmann
    return result
1141 b8d26c6e Michael Hanselmann
1142 b8d26c6e Michael Hanselmann
  @_RpcTimeout(_TMO_NORMAL)
1143 72737a7f Iustin Pop
  def call_blockdev_find(self, node, disk):
1144 72737a7f Iustin Pop
    """Request identification of a given block device.
1145 72737a7f Iustin Pop

1146 72737a7f Iustin Pop
    This is a single-node call.
1147 a8083063 Iustin Pop

1148 72737a7f Iustin Pop
    """
1149 96acbc09 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_find", [disk.ToDict()])
1150 edb4b374 Michael Hanselmann
    if not result.fail_msg and result.payload is not None:
1151 96acbc09 Michael Hanselmann
      result.payload = objects.BlockDevStatus.FromDict(result.payload)
1152 96acbc09 Michael Hanselmann
    return result
1153 d61cbe76 Iustin Pop
1154 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1155 b2e7666a Iustin Pop
  def call_blockdev_close(self, node, instance_name, disks):
1156 72737a7f Iustin Pop
    """Closes the given block devices.
1157 d61cbe76 Iustin Pop

1158 72737a7f Iustin Pop
    This is a single-node call.
1159 d61cbe76 Iustin Pop

1160 72737a7f Iustin Pop
    """
1161 b2e7666a Iustin Pop
    params = [instance_name, [cf.ToDict() for cf in disks]]
1162 b2e7666a Iustin Pop
    return self._SingleNodeCall(node, "blockdev_close", params)
1163 a8083063 Iustin Pop
1164 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1165 ccfbbd2d Iustin Pop
  def call_blockdev_getsize(self, node, disks):
1166 968a7623 Iustin Pop
    """Returns the size of the given disks.
1167 968a7623 Iustin Pop

1168 968a7623 Iustin Pop
    This is a single-node call.
1169 968a7623 Iustin Pop

1170 968a7623 Iustin Pop
    """
1171 968a7623 Iustin Pop
    params = [[cf.ToDict() for cf in disks]]
1172 968a7623 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_getsize", params)
1173 968a7623 Iustin Pop
1174 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1175 6b93ec9d Iustin Pop
  def call_drbd_disconnect_net(self, node_list, nodes_ip, disks):
1176 6b93ec9d Iustin Pop
    """Disconnects the network of the given drbd devices.
1177 6b93ec9d Iustin Pop

1178 6b93ec9d Iustin Pop
    This is a multi-node call.
1179 6b93ec9d Iustin Pop

1180 6b93ec9d Iustin Pop
    """
1181 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_disconnect_net",
1182 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1183 6b93ec9d Iustin Pop
1184 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1185 6b93ec9d Iustin Pop
  def call_drbd_attach_net(self, node_list, nodes_ip,
1186 6b93ec9d Iustin Pop
                           disks, instance_name, multimaster):
1187 6b93ec9d Iustin Pop
    """Disconnects the given drbd devices.
1188 6b93ec9d Iustin Pop

1189 6b93ec9d Iustin Pop
    This is a multi-node call.
1190 6b93ec9d Iustin Pop

1191 6b93ec9d Iustin Pop
    """
1192 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_attach_net",
1193 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks],
1194 6b93ec9d Iustin Pop
                                instance_name, multimaster])
1195 6b93ec9d Iustin Pop
1196 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_SLOW)
1197 6b93ec9d Iustin Pop
  def call_drbd_wait_sync(self, node_list, nodes_ip, disks):
1198 6b93ec9d Iustin Pop
    """Waits for the synchronization of drbd devices is complete.
1199 6b93ec9d Iustin Pop

1200 6b93ec9d Iustin Pop
    This is a multi-node call.
1201 6b93ec9d Iustin Pop

1202 6b93ec9d Iustin Pop
    """
1203 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_wait_sync",
1204 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
1205 6b93ec9d Iustin Pop
1206 c46b9782 Luca Bigliardi
  @_RpcTimeout(_TMO_URGENT)
1207 c46b9782 Luca Bigliardi
  def call_drbd_helper(self, node_list):
1208 c46b9782 Luca Bigliardi
    """Gets drbd helper.
1209 c46b9782 Luca Bigliardi

1210 c46b9782 Luca Bigliardi
    This is a multi-node call.
1211 c46b9782 Luca Bigliardi

1212 c46b9782 Luca Bigliardi
    """
1213 c46b9782 Luca Bigliardi
    return self._MultiNodeCall(node_list, "drbd_helper", [])
1214 c46b9782 Luca Bigliardi
1215 9a525d83 Michael Hanselmann
  @classmethod
1216 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1217 9a525d83 Michael Hanselmann
  def call_upload_file(cls, node_list, file_name, address_list=None):
1218 72737a7f Iustin Pop
    """Upload a file.
1219 72737a7f Iustin Pop

1220 72737a7f Iustin Pop
    The node will refuse the operation in case the file is not on the
1221 72737a7f Iustin Pop
    approved file list.
1222 72737a7f Iustin Pop

1223 72737a7f Iustin Pop
    This is a multi-node call.
1224 a8083063 Iustin Pop

1225 6b294c53 Iustin Pop
    @type node_list: list
1226 6b294c53 Iustin Pop
    @param node_list: the list of node names to upload to
1227 6b294c53 Iustin Pop
    @type file_name: str
1228 6b294c53 Iustin Pop
    @param file_name: the filename to upload
1229 6b294c53 Iustin Pop
    @type address_list: list or None
1230 6b294c53 Iustin Pop
    @keyword address_list: an optional list of node addresses, in order
1231 6b294c53 Iustin Pop
        to optimize the RPC speed
1232 6b294c53 Iustin Pop

1233 72737a7f Iustin Pop
    """
1234 12bce260 Michael Hanselmann
    file_contents = utils.ReadFile(file_name)
1235 30474135 Michael Hanselmann
    data = _Compress(file_contents)
1236 72737a7f Iustin Pop
    st = os.stat(file_name)
1237 9a914f7a René Nussbaumer
    getents = runtime.GetEnts()
1238 9a914f7a René Nussbaumer
    params = [file_name, data, st.st_mode, getents.LookupUid(st.st_uid),
1239 9a914f7a René Nussbaumer
              getents.LookupGid(st.st_gid), st.st_atime, st.st_mtime]
1240 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "upload_file", params,
1241 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1242 72737a7f Iustin Pop
1243 6ddc95ec Michael Hanselmann
  @classmethod
1244 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1245 03d1dba2 Michael Hanselmann
  def call_write_ssconf_files(cls, node_list, values):
1246 6ddc95ec Michael Hanselmann
    """Write ssconf files.
1247 6ddc95ec Michael Hanselmann

1248 6ddc95ec Michael Hanselmann
    This is a multi-node call.
1249 6ddc95ec Michael Hanselmann

1250 6ddc95ec Michael Hanselmann
    """
1251 03d1dba2 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "write_ssconf_files", [values])
1252 6ddc95ec Michael Hanselmann
1253 4f6014d4 René Nussbaumer
  @_RpcTimeout(_TMO_NORMAL)
1254 0092d621 René Nussbaumer
  def call_run_oob(self, node, oob_program, command, remote_node, timeout):
1255 4f6014d4 René Nussbaumer
    """Runs OOB.
1256 4f6014d4 René Nussbaumer

1257 4f6014d4 René Nussbaumer
    This is a single-node call.
1258 4f6014d4 René Nussbaumer

1259 4f6014d4 René Nussbaumer
    """
1260 4f6014d4 René Nussbaumer
    return self._SingleNodeCall(node, "run_oob", [oob_program, command,
1261 0092d621 René Nussbaumer
                                                  remote_node, timeout])
1262 4f6014d4 René Nussbaumer
1263 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1264 72737a7f Iustin Pop
  def call_os_diagnose(self, node_list):
1265 72737a7f Iustin Pop
    """Request a diagnose of OS definitions.
1266 72737a7f Iustin Pop

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

1269 72737a7f Iustin Pop
    """
1270 83d92ad8 Iustin Pop
    return self._MultiNodeCall(node_list, "os_diagnose", [])
1271 a8083063 Iustin Pop
1272 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1273 72737a7f Iustin Pop
  def call_os_get(self, node, name):
1274 72737a7f Iustin Pop
    """Returns an OS definition.
1275 a8083063 Iustin Pop

1276 72737a7f Iustin Pop
    This is a single-node call.
1277 a8083063 Iustin Pop

1278 72737a7f Iustin Pop
    """
1279 9a525d83 Michael Hanselmann
    result = self._SingleNodeCall(node, "os_get", [name])
1280 84e3f66f Guido Trotter
    if not result.fail_msg and isinstance(result.payload, dict):
1281 84e3f66f Guido Trotter
      result.payload = objects.OS.FromDict(result.payload)
1282 781de953 Iustin Pop
    return result
1283 a8083063 Iustin Pop
1284 acd9ff9e Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1285 acd9ff9e Iustin Pop
  def call_os_validate(self, required, nodes, name, checks, params):
1286 acd9ff9e Iustin Pop
    """Run a validation routine for a given OS.
1287 acd9ff9e Iustin Pop

1288 acd9ff9e Iustin Pop
    This is a multi-node call.
1289 acd9ff9e Iustin Pop

1290 acd9ff9e Iustin Pop
    """
1291 acd9ff9e Iustin Pop
    return self._MultiNodeCall(nodes, "os_validate",
1292 acd9ff9e Iustin Pop
                               [required, name, checks, params])
1293 acd9ff9e Iustin Pop
1294 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1295 72737a7f Iustin Pop
  def call_hooks_runner(self, node_list, hpath, phase, env):
1296 72737a7f Iustin Pop
    """Call the hooks runner.
1297 a8083063 Iustin Pop

1298 72737a7f Iustin Pop
    Args:
1299 72737a7f Iustin Pop
      - op: the OpCode instance
1300 72737a7f Iustin Pop
      - env: a dictionary with the environment
1301 a8083063 Iustin Pop

1302 72737a7f Iustin Pop
    This is a multi-node call.
1303 a8083063 Iustin Pop

1304 72737a7f Iustin Pop
    """
1305 72737a7f Iustin Pop
    params = [hpath, phase, env]
1306 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hooks_runner", params)
1307 a8083063 Iustin Pop
1308 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1309 72737a7f Iustin Pop
  def call_iallocator_runner(self, node, name, idata):
1310 72737a7f Iustin Pop
    """Call an iallocator on a remote node
1311 8d528b7c Iustin Pop

1312 72737a7f Iustin Pop
    Args:
1313 72737a7f Iustin Pop
      - name: the iallocator name
1314 72737a7f Iustin Pop
      - input: the json-encoded input string
1315 8d528b7c Iustin Pop

1316 72737a7f Iustin Pop
    This is a single-node call.
1317 8d528b7c Iustin Pop

1318 72737a7f Iustin Pop
    """
1319 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "iallocator_runner", [name, idata])
1320 8d528b7c Iustin Pop
1321 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1322 a59faf4b Iustin Pop
  def call_blockdev_grow(self, node, cf_bdev, amount, dryrun):
1323 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1324 4c8ba8b3 Iustin Pop

1325 72737a7f Iustin Pop
    This is a single-node call.
1326 4c8ba8b3 Iustin Pop

1327 72737a7f Iustin Pop
    """
1328 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_grow",
1329 a59faf4b Iustin Pop
                                [cf_bdev.ToDict(), amount, dryrun])
1330 4c8ba8b3 Iustin Pop
1331 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_1DAY)
1332 858f3d18 Iustin Pop
  def call_blockdev_export(self, node, cf_bdev,
1333 858f3d18 Iustin Pop
                           dest_node, dest_path, cluster_name):
1334 858f3d18 Iustin Pop
    """Export a given disk to another node.
1335 858f3d18 Iustin Pop

1336 858f3d18 Iustin Pop
    This is a single-node call.
1337 858f3d18 Iustin Pop

1338 858f3d18 Iustin Pop
    """
1339 858f3d18 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_export",
1340 858f3d18 Iustin Pop
                                [cf_bdev.ToDict(), dest_node, dest_path,
1341 858f3d18 Iustin Pop
                                 cluster_name])
1342 858f3d18 Iustin Pop
1343 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1344 72737a7f Iustin Pop
  def call_blockdev_snapshot(self, node, cf_bdev):
1345 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
1346 a8083063 Iustin Pop

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

1349 72737a7f Iustin Pop
    """
1350 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_snapshot", [cf_bdev.ToDict()])
1351 a8083063 Iustin Pop
1352 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1353 72737a7f Iustin Pop
  def call_finalize_export(self, node, instance, snap_disks):
1354 72737a7f Iustin Pop
    """Request the completion of an export operation.
1355 a8083063 Iustin Pop

1356 72737a7f Iustin Pop
    This writes the export config file, etc.
1357 a8083063 Iustin Pop

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

1360 72737a7f Iustin Pop
    """
1361 72737a7f Iustin Pop
    flat_disks = []
1362 72737a7f Iustin Pop
    for disk in snap_disks:
1363 a97da6b7 Iustin Pop
      if isinstance(disk, bool):
1364 a97da6b7 Iustin Pop
        flat_disks.append(disk)
1365 a97da6b7 Iustin Pop
      else:
1366 a97da6b7 Iustin Pop
        flat_disks.append(disk.ToDict())
1367 9a525d83 Michael Hanselmann
1368 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "finalize_export",
1369 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), flat_disks])
1370 a8083063 Iustin Pop
1371 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1372 72737a7f Iustin Pop
  def call_export_info(self, node, path):
1373 72737a7f Iustin Pop
    """Queries the export information in a given path.
1374 a8083063 Iustin Pop

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

1377 72737a7f Iustin Pop
    """
1378 3eccac06 Iustin Pop
    return self._SingleNodeCall(node, "export_info", [path])
1379 a8083063 Iustin Pop
1380 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1381 72737a7f Iustin Pop
  def call_export_list(self, node_list):
1382 72737a7f Iustin Pop
    """Gets the stored exports list.
1383 a8083063 Iustin Pop

1384 72737a7f Iustin Pop
    This is a multi-node call.
1385 a8083063 Iustin Pop

1386 72737a7f Iustin Pop
    """
1387 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "export_list", [])
1388 a8083063 Iustin Pop
1389 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1390 72737a7f Iustin Pop
  def call_export_remove(self, node, export):
1391 72737a7f Iustin Pop
    """Requests removal of a given export.
1392 a8083063 Iustin Pop

1393 72737a7f Iustin Pop
    This is a single-node call.
1394 a8083063 Iustin Pop

1395 72737a7f Iustin Pop
    """
1396 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "export_remove", [export])
1397 a8083063 Iustin Pop
1398 9a525d83 Michael Hanselmann
  @classmethod
1399 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1400 b989b9d9 Ken Wehr
  def call_node_leave_cluster(cls, node, modify_ssh_setup):
1401 72737a7f Iustin Pop
    """Requests a node to clean the cluster information it has.
1402 a8083063 Iustin Pop

1403 72737a7f Iustin Pop
    This will remove the configuration information from the ganeti data
1404 72737a7f Iustin Pop
    dir.
1405 a8083063 Iustin Pop

1406 72737a7f Iustin Pop
    This is a single-node call.
1407 a8083063 Iustin Pop

1408 72737a7f Iustin Pop
    """
1409 b989b9d9 Ken Wehr
    return cls._StaticSingleNodeCall(node, "node_leave_cluster",
1410 b989b9d9 Ken Wehr
                                     [modify_ssh_setup])
1411 dcb93971 Michael Hanselmann
1412 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1413 72737a7f Iustin Pop
  def call_node_volumes(self, node_list):
1414 72737a7f Iustin Pop
    """Gets all volumes on node(s).
1415 dcb93971 Michael Hanselmann

1416 72737a7f Iustin Pop
    This is a multi-node call.
1417 dcb93971 Michael Hanselmann

1418 72737a7f Iustin Pop
    """
1419 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_volumes", [])
1420 06009e27 Iustin Pop
1421 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1422 56aa9fd5 Iustin Pop
  def call_node_demote_from_mc(self, node):
1423 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
1424 56aa9fd5 Iustin Pop

1425 56aa9fd5 Iustin Pop
    This is a single-node call.
1426 56aa9fd5 Iustin Pop

1427 56aa9fd5 Iustin Pop
    """
1428 56aa9fd5 Iustin Pop
    return self._SingleNodeCall(node, "node_demote_from_mc", [])
1429 56aa9fd5 Iustin Pop
1430 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1431 f5118ade Iustin Pop
  def call_node_powercycle(self, node, hypervisor):
1432 f5118ade Iustin Pop
    """Tries to powercycle a node.
1433 f5118ade Iustin Pop

1434 f5118ade Iustin Pop
    This is a single-node call.
1435 f5118ade Iustin Pop

1436 f5118ade Iustin Pop
    """
1437 f5118ade Iustin Pop
    return self._SingleNodeCall(node, "node_powercycle", [hypervisor])
1438 f5118ade Iustin Pop
1439 92fd2250 Iustin Pop
  @_RpcTimeout(None)
1440 72737a7f Iustin Pop
  def call_test_delay(self, node_list, duration):
1441 72737a7f Iustin Pop
    """Sleep for a fixed time on given node(s).
1442 06009e27 Iustin Pop

1443 72737a7f Iustin Pop
    This is a multi-node call.
1444 06009e27 Iustin Pop

1445 72737a7f Iustin Pop
    """
1446 92fd2250 Iustin Pop
    return self._MultiNodeCall(node_list, "test_delay", [duration],
1447 92fd2250 Iustin Pop
                               read_timeout=int(duration + 5))
1448 5e04ed8b Manuel Franceschini
1449 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1450 72737a7f Iustin Pop
  def call_file_storage_dir_create(self, node, file_storage_dir):
1451 72737a7f Iustin Pop
    """Create the given file storage directory.
1452 5e04ed8b Manuel Franceschini

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

1455 72737a7f Iustin Pop
    """
1456 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_create",
1457 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1458 5e04ed8b Manuel Franceschini
1459 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1460 72737a7f Iustin Pop
  def call_file_storage_dir_remove(self, node, file_storage_dir):
1461 72737a7f Iustin Pop
    """Remove the given file storage directory.
1462 5e04ed8b Manuel Franceschini

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

1465 72737a7f Iustin Pop
    """
1466 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_remove",
1467 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1468 5e04ed8b Manuel Franceschini
1469 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1470 72737a7f Iustin Pop
  def call_file_storage_dir_rename(self, node, old_file_storage_dir,
1471 72737a7f Iustin Pop
                                   new_file_storage_dir):
1472 72737a7f Iustin Pop
    """Rename file storage directory.
1473 5e04ed8b Manuel Franceschini

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

1476 72737a7f Iustin Pop
    """
1477 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_rename",
1478 9a525d83 Michael Hanselmann
                                [old_file_storage_dir, new_file_storage_dir])
1479 ca52cdeb Michael Hanselmann
1480 9a525d83 Michael Hanselmann
  @classmethod
1481 d2cd6944 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
1482 9a525d83 Michael Hanselmann
  def call_jobqueue_update(cls, node_list, address_list, file_name, content):
1483 72737a7f Iustin Pop
    """Update job queue.
1484 ca52cdeb Michael Hanselmann

1485 72737a7f Iustin Pop
    This is a multi-node call.
1486 ca52cdeb Michael Hanselmann

1487 72737a7f Iustin Pop
    """
1488 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_update",
1489 30474135 Michael Hanselmann
                                    [file_name, _Compress(content)],
1490 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1491 ca52cdeb Michael Hanselmann
1492 9a525d83 Michael Hanselmann
  @classmethod
1493 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1494 9a525d83 Michael Hanselmann
  def call_jobqueue_purge(cls, node):
1495 72737a7f Iustin Pop
    """Purge job queue.
1496 ca52cdeb Michael Hanselmann

1497 72737a7f Iustin Pop
    This is a single-node call.
1498 ca52cdeb Michael Hanselmann

1499 72737a7f Iustin Pop
    """
1500 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "jobqueue_purge", [])
1501 af5ebcb1 Michael Hanselmann
1502 9a525d83 Michael Hanselmann
  @classmethod
1503 d2cd6944 Iustin Pop
  @_RpcTimeout(_TMO_URGENT)
1504 dd875d32 Michael Hanselmann
  def call_jobqueue_rename(cls, node_list, address_list, rename):
1505 72737a7f Iustin Pop
    """Rename a job queue file.
1506 af5ebcb1 Michael Hanselmann

1507 72737a7f Iustin Pop
    This is a multi-node call.
1508 af5ebcb1 Michael Hanselmann

1509 72737a7f Iustin Pop
    """
1510 dd875d32 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_rename", rename,
1511 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1512 6217e295 Iustin Pop
1513 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1514 6217e295 Iustin Pop
  def call_hypervisor_validate_params(self, node_list, hvname, hvparams):
1515 6217e295 Iustin Pop
    """Validate the hypervisor params.
1516 6217e295 Iustin Pop

1517 6217e295 Iustin Pop
    This is a multi-node call.
1518 6217e295 Iustin Pop

1519 6217e295 Iustin Pop
    @type node_list: list
1520 6217e295 Iustin Pop
    @param node_list: the list of nodes to query
1521 6217e295 Iustin Pop
    @type hvname: string
1522 6217e295 Iustin Pop
    @param hvname: the hypervisor name
1523 6217e295 Iustin Pop
    @type hvparams: dict
1524 6217e295 Iustin Pop
    @param hvparams: the hypervisor parameters to be validated
1525 6217e295 Iustin Pop

1526 6217e295 Iustin Pop
    """
1527 6217e295 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
1528 abe609b2 Guido Trotter
    hv_full = objects.FillDict(cluster.hvparams.get(hvname, {}), hvparams)
1529 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hypervisor_validate_params",
1530 9a525d83 Michael Hanselmann
                               [hvname, hv_full])
1531 f942a838 Michael Hanselmann
1532 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1533 37549316 Michael Hanselmann
  def call_x509_cert_create(self, node, validity):
1534 f942a838 Michael Hanselmann
    """Creates a new X509 certificate for SSL/TLS.
1535 f942a838 Michael Hanselmann

1536 f942a838 Michael Hanselmann
    This is a single-node call.
1537 f942a838 Michael Hanselmann

1538 f942a838 Michael Hanselmann
    @type validity: int
1539 f942a838 Michael Hanselmann
    @param validity: Validity in seconds
1540 f942a838 Michael Hanselmann

1541 f942a838 Michael Hanselmann
    """
1542 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_create", [validity])
1543 f942a838 Michael Hanselmann
1544 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1545 37549316 Michael Hanselmann
  def call_x509_cert_remove(self, node, name):
1546 f942a838 Michael Hanselmann
    """Removes a X509 certificate.
1547 f942a838 Michael Hanselmann

1548 f942a838 Michael Hanselmann
    This is a single-node call.
1549 f942a838 Michael Hanselmann

1550 f942a838 Michael Hanselmann
    @type name: string
1551 f942a838 Michael Hanselmann
    @param name: Certificate name
1552 f942a838 Michael Hanselmann

1553 f942a838 Michael Hanselmann
    """
1554 37549316 Michael Hanselmann
    return self._SingleNodeCall(node, "x509_cert_remove", [name])
1555 1651d116 Michael Hanselmann
1556 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1557 6613661a Iustin Pop
  def call_import_start(self, node, opts, instance, component,
1558 6613661a Iustin Pop
                        dest, dest_args):
1559 1651d116 Michael Hanselmann
    """Starts a listener for an import.
1560 1651d116 Michael Hanselmann

1561 1651d116 Michael Hanselmann
    This is a single-node call.
1562 1651d116 Michael Hanselmann

1563 1651d116 Michael Hanselmann
    @type node: string
1564 1651d116 Michael Hanselmann
    @param node: Node name
1565 1651d116 Michael Hanselmann
    @type instance: C{objects.Instance}
1566 1651d116 Michael Hanselmann
    @param instance: Instance object
1567 6613661a Iustin Pop
    @type component: string
1568 6613661a Iustin Pop
    @param component: which part of the instance is being imported
1569 1651d116 Michael Hanselmann

1570 1651d116 Michael Hanselmann
    """
1571 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "import_start",
1572 eb630f50 Michael Hanselmann
                                [opts.ToDict(),
1573 6613661a Iustin Pop
                                 self._InstDict(instance), component, dest,
1574 1651d116 Michael Hanselmann
                                 _EncodeImportExportIO(dest, dest_args)])
1575 1651d116 Michael Hanselmann
1576 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1577 eb630f50 Michael Hanselmann
  def call_export_start(self, node, opts, host, port,
1578 6613661a Iustin Pop
                        instance, component, source, source_args):
1579 1651d116 Michael Hanselmann
    """Starts an export daemon.
1580 1651d116 Michael Hanselmann

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

1583 1651d116 Michael Hanselmann
    @type node: string
1584 1651d116 Michael Hanselmann
    @param node: Node name
1585 1651d116 Michael Hanselmann
    @type instance: C{objects.Instance}
1586 1651d116 Michael Hanselmann
    @param instance: Instance object
1587 6613661a Iustin Pop
    @type component: string
1588 6613661a Iustin Pop
    @param component: which part of the instance is being imported
1589 1651d116 Michael Hanselmann

1590 1651d116 Michael Hanselmann
    """
1591 ef40fbfb Michael Hanselmann
    return self._SingleNodeCall(node, "export_start",
1592 eb630f50 Michael Hanselmann
                                [opts.ToDict(), host, port,
1593 6613661a Iustin Pop
                                 self._InstDict(instance),
1594 6613661a Iustin Pop
                                 component, source,
1595 1651d116 Michael Hanselmann
                                 _EncodeImportExportIO(source, source_args)])
1596 1651d116 Michael Hanselmann
1597 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_FAST)
1598 ef40fbfb Michael Hanselmann
  def call_impexp_status(self, node, names):
1599 1651d116 Michael Hanselmann
    """Gets the status of an import or export.
1600 1651d116 Michael Hanselmann

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

1603 1651d116 Michael Hanselmann
    @type node: string
1604 1651d116 Michael Hanselmann
    @param node: Node name
1605 1651d116 Michael Hanselmann
    @type names: List of strings
1606 1651d116 Michael Hanselmann
    @param names: Import/export names
1607 1651d116 Michael Hanselmann
    @rtype: List of L{objects.ImportExportStatus} instances
1608 1651d116 Michael Hanselmann
    @return: Returns a list of the state of each named import/export or None if
1609 1651d116 Michael Hanselmann
             a status couldn't be retrieved
1610 1651d116 Michael Hanselmann

1611 1651d116 Michael Hanselmann
    """
1612 ef40fbfb Michael Hanselmann
    result = self._SingleNodeCall(node, "impexp_status", [names])
1613 1651d116 Michael Hanselmann
1614 1651d116 Michael Hanselmann
    if not result.fail_msg:
1615 1651d116 Michael Hanselmann
      decoded = []
1616 1651d116 Michael Hanselmann
1617 1651d116 Michael Hanselmann
      for i in result.payload:
1618 1651d116 Michael Hanselmann
        if i is None:
1619 1651d116 Michael Hanselmann
          decoded.append(None)
1620 1651d116 Michael Hanselmann
          continue
1621 1651d116 Michael Hanselmann
        decoded.append(objects.ImportExportStatus.FromDict(i))
1622 1651d116 Michael Hanselmann
1623 1651d116 Michael Hanselmann
      result.payload = decoded
1624 1651d116 Michael Hanselmann
1625 1651d116 Michael Hanselmann
    return result
1626 1651d116 Michael Hanselmann
1627 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1628 f81c4737 Michael Hanselmann
  def call_impexp_abort(self, node, name):
1629 f81c4737 Michael Hanselmann
    """Aborts an import or export.
1630 f81c4737 Michael Hanselmann

1631 f81c4737 Michael Hanselmann
    This is a single-node call.
1632 f81c4737 Michael Hanselmann

1633 f81c4737 Michael Hanselmann
    @type node: string
1634 f81c4737 Michael Hanselmann
    @param node: Node name
1635 f81c4737 Michael Hanselmann
    @type name: string
1636 f81c4737 Michael Hanselmann
    @param name: Import/export name
1637 f81c4737 Michael Hanselmann

1638 f81c4737 Michael Hanselmann
    """
1639 f81c4737 Michael Hanselmann
    return self._SingleNodeCall(node, "impexp_abort", [name])
1640 f81c4737 Michael Hanselmann
1641 92fd2250 Iustin Pop
  @_RpcTimeout(_TMO_NORMAL)
1642 ef40fbfb Michael Hanselmann
  def call_impexp_cleanup(self, node, name):
1643 1651d116 Michael Hanselmann
    """Cleans up after an import or export.
1644 1651d116 Michael Hanselmann

1645 1651d116 Michael Hanselmann
    This is a single-node call.
1646 1651d116 Michael Hanselmann

1647 1651d116 Michael Hanselmann
    @type node: string
1648 1651d116 Michael Hanselmann
    @param node: Node name
1649 1651d116 Michael Hanselmann
    @type name: string
1650 1651d116 Michael Hanselmann
    @param name: Import/export name
1651 1651d116 Michael Hanselmann

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