Statistics
| Branch: | Tag: | Revision:

root / lib / server / noded.py @ 178ad717

History | View | Annotate | Download (35.9 kB)

1 69cf3abd Michael Hanselmann
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 cad0723b Iustin Pop
# Copyright (C) 2006, 2007, 2010, 2011, 2012 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 a8083063 Iustin Pop
"""Ganeti node daemon"""
23 a8083063 Iustin Pop
24 b459a848 Andrea Spadaccini
# pylint: disable=C0103,W0142
25 7260cfbe Iustin Pop
26 7260cfbe Iustin Pop
# C0103: Functions in this module need to have a given name structure,
27 7260cfbe Iustin Pop
# and the name of the daemon doesn't match
28 7260cfbe Iustin Pop
29 7260cfbe Iustin Pop
# W0142: Used * or ** magic, since we do use it extensively in this
30 7260cfbe Iustin Pop
# module
31 3ecf6786 Iustin Pop
32 a8083063 Iustin Pop
import os
33 a8083063 Iustin Pop
import sys
34 c89189b1 Iustin Pop
import logging
35 84b58db2 Michael Hanselmann
import signal
36 f01738fc Iustin Pop
import codecs
37 a8083063 Iustin Pop
38 a8083063 Iustin Pop
from optparse import OptionParser
39 a8083063 Iustin Pop
40 a8083063 Iustin Pop
from ganeti import backend
41 a8083063 Iustin Pop
from ganeti import constants
42 a8083063 Iustin Pop
from ganeti import objects
43 a8083063 Iustin Pop
from ganeti import errors
44 25d6d12a Michael Hanselmann
from ganeti import jstore
45 cc28af80 Michael Hanselmann
from ganeti import daemon
46 1df6506c Michael Hanselmann
from ganeti import http
47 16abfbc2 Alexander Schreiber
from ganeti import utils
48 8f096849 Helga Velroyen
from ganeti.storage import container
49 ab221ddf Michael Hanselmann
from ganeti import serializer
50 a744b676 Manuel Franceschini
from ganeti import netutils
51 a5ce2ea2 Michael Hanselmann
from ganeti import pathutils
52 ee501db1 Michael Hanselmann
from ganeti import ssconf
53 a8083063 Iustin Pop
54 b459a848 Andrea Spadaccini
import ganeti.http.server # pylint: disable=W0611
55 19205c39 Michael Hanselmann
56 a8083063 Iustin Pop
57 25d6d12a Michael Hanselmann
queue_lock = None
58 25d6d12a Michael Hanselmann
59 25d6d12a Michael Hanselmann
60 8e00f36a Michele Tartara
def _extendReasonTrail(trail, source, reason=""):
61 8e00f36a Michele Tartara
  """Extend the reason trail with noded information
62 8e00f36a Michele Tartara

63 8e00f36a Michele Tartara
  The trail is extended by appending the name of the noded functionality
64 8e00f36a Michele Tartara
  """
65 8e00f36a Michele Tartara
  assert trail is not None
66 8e00f36a Michele Tartara
  trail_source = "%s:%s" % (constants.OPCODE_REASON_SRC_NODED, source)
67 8e00f36a Michele Tartara
  trail.append((trail_source, reason, utils.EpochNano()))
68 8e00f36a Michele Tartara
69 8e00f36a Michele Tartara
70 81198f6e Iustin Pop
def _PrepareQueueLock():
71 81198f6e Iustin Pop
  """Try to prepare the queue lock.
72 81198f6e Iustin Pop

73 81198f6e Iustin Pop
  @return: None for success, otherwise an exception object
74 81198f6e Iustin Pop

75 81198f6e Iustin Pop
  """
76 b459a848 Andrea Spadaccini
  global queue_lock # pylint: disable=W0603
77 81198f6e Iustin Pop
78 81198f6e Iustin Pop
  if queue_lock is not None:
79 81198f6e Iustin Pop
    return None
80 81198f6e Iustin Pop
81 81198f6e Iustin Pop
  # Prepare job queue
82 81198f6e Iustin Pop
  try:
83 81198f6e Iustin Pop
    queue_lock = jstore.InitAndVerifyQueue(must_lock=False)
84 81198f6e Iustin Pop
    return None
85 81198f6e Iustin Pop
  except EnvironmentError, err:
86 81198f6e Iustin Pop
    return err
87 81198f6e Iustin Pop
88 81198f6e Iustin Pop
89 7f30777b Michael Hanselmann
def _RequireJobQueueLock(fn):
90 7f30777b Michael Hanselmann
  """Decorator for job queue manipulating functions.
91 7f30777b Michael Hanselmann

92 7f30777b Michael Hanselmann
  """
93 8785cb30 Michael Hanselmann
  QUEUE_LOCK_TIMEOUT = 10
94 8785cb30 Michael Hanselmann
95 7f30777b Michael Hanselmann
  def wrapper(*args, **kwargs):
96 7f30777b Michael Hanselmann
    # Locking in exclusive, blocking mode because there could be several
97 506cff12 Michael Hanselmann
    # children running at the same time. Waiting up to 10 seconds.
98 81198f6e Iustin Pop
    if _PrepareQueueLock() is not None:
99 81198f6e Iustin Pop
      raise errors.JobQueueError("Job queue failed initialization,"
100 81198f6e Iustin Pop
                                 " cannot update jobs")
101 8785cb30 Michael Hanselmann
    queue_lock.Exclusive(blocking=True, timeout=QUEUE_LOCK_TIMEOUT)
102 7f30777b Michael Hanselmann
    try:
103 7f30777b Michael Hanselmann
      return fn(*args, **kwargs)
104 7f30777b Michael Hanselmann
    finally:
105 7f30777b Michael Hanselmann
      queue_lock.Unlock()
106 8785cb30 Michael Hanselmann
107 7f30777b Michael Hanselmann
  return wrapper
108 7f30777b Michael Hanselmann
109 7f30777b Michael Hanselmann
110 1651d116 Michael Hanselmann
def _DecodeImportExportIO(ieio, ieioargs):
111 1651d116 Michael Hanselmann
  """Decodes import/export I/O information.
112 1651d116 Michael Hanselmann

113 1651d116 Michael Hanselmann
  """
114 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_RAW_DISK:
115 1651d116 Michael Hanselmann
    assert len(ieioargs) == 1
116 1651d116 Michael Hanselmann
    return (objects.Disk.FromDict(ieioargs[0]), )
117 1651d116 Michael Hanselmann
118 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_SCRIPT:
119 1651d116 Michael Hanselmann
    assert len(ieioargs) == 2
120 1651d116 Michael Hanselmann
    return (objects.Disk.FromDict(ieioargs[0]), ieioargs[1])
121 1651d116 Michael Hanselmann
122 1651d116 Michael Hanselmann
  return ieioargs
123 1651d116 Michael Hanselmann
124 1651d116 Michael Hanselmann
125 4a90bd4f Michele Tartara
def _DefaultAlternative(value, default):
126 a82d9394 Michael Hanselmann
  """Returns value or, if evaluating to False, a default value.
127 4a90bd4f Michele Tartara

128 a82d9394 Michael Hanselmann
  Returns the given value, unless it evaluates to False. In the latter case the
129 a82d9394 Michael Hanselmann
  default value is returned.
130 a82d9394 Michael Hanselmann

131 a82d9394 Michael Hanselmann
  @param value: Value to return if it doesn't evaluate to False
132 a82d9394 Michael Hanselmann
  @param default: Default value
133 a82d9394 Michael Hanselmann
  @return: Given value or the default
134 4a90bd4f Michele Tartara

135 4a90bd4f Michele Tartara
  """
136 4a90bd4f Michele Tartara
  if value:
137 4a90bd4f Michele Tartara
    return value
138 4a90bd4f Michele Tartara
139 4a90bd4f Michele Tartara
  return default
140 4a90bd4f Michele Tartara
141 4a90bd4f Michele Tartara
142 38b77287 Luca Bigliardi
class MlockallRequestExecutor(http.server.HttpServerRequestExecutor):
143 cca5b3fc Michael Hanselmann
  """Subclass ensuring request handlers are locked in RAM.
144 38b77287 Luca Bigliardi

145 38b77287 Luca Bigliardi
  """
146 38b77287 Luca Bigliardi
  def __init__(self, *args, **kwargs):
147 38b77287 Luca Bigliardi
    utils.Mlockall()
148 38b77287 Luca Bigliardi
149 38b77287 Luca Bigliardi
    http.server.HttpServerRequestExecutor.__init__(self, *args, **kwargs)
150 38b77287 Luca Bigliardi
151 38b77287 Luca Bigliardi
152 e0003509 Michael Hanselmann
class NodeRequestHandler(http.server.HttpServerHandler):
153 3ecf6786 Iustin Pop
  """The server implementation.
154 3ecf6786 Iustin Pop

155 3ecf6786 Iustin Pop
  This class holds all methods exposed over the RPC interface.
156 3ecf6786 Iustin Pop

157 3ecf6786 Iustin Pop
  """
158 2d54e29c Iustin Pop
  # too many public methods, and unused args - all methods get params
159 2d54e29c Iustin Pop
  # due to the API
160 b459a848 Andrea Spadaccini
  # pylint: disable=R0904,W0613
161 e0003509 Michael Hanselmann
  def __init__(self):
162 e0003509 Michael Hanselmann
    http.server.HttpServerHandler.__init__(self)
163 cc28af80 Michael Hanselmann
    self.noded_pid = os.getpid()
164 cc28af80 Michael Hanselmann
165 cc28af80 Michael Hanselmann
  def HandleRequest(self, req):
166 1df6506c Michael Hanselmann
    """Handle a request.
167 a8083063 Iustin Pop

168 098c0958 Michael Hanselmann
    """
169 b9e12624 Hrvoje Ribicic
170 a7862455 Iustin Pop
    if req.request_method.upper() != http.HTTP_POST:
171 a7862455 Iustin Pop
      raise http.HttpBadRequest("Only the POST method is supported")
172 1df6506c Michael Hanselmann
173 cc28af80 Michael Hanselmann
    path = req.request_path
174 81010134 Iustin Pop
    if path.startswith("/"):
175 81010134 Iustin Pop
      path = path[1:]
176 81010134 Iustin Pop
177 1df6506c Michael Hanselmann
    method = getattr(self, "perspective_%s" % path, None)
178 1df6506c Michael Hanselmann
    if method is None:
179 84f2756e Michael Hanselmann
      raise http.HttpNotFound()
180 a8083063 Iustin Pop
181 81010134 Iustin Pop
    try:
182 ab221ddf Michael Hanselmann
      result = (True, method(serializer.LoadJson(req.request_body)))
183 4dd42c9d Iustin Pop
184 0623d351 Iustin Pop
    except backend.RPCFail, err:
185 0623d351 Iustin Pop
      # our custom failure exception; str(err) works fine if the
186 0623d351 Iustin Pop
      # exception was constructed with a single argument, and in
187 0623d351 Iustin Pop
      # this case, err.message == err.args[0] == str(err)
188 ab221ddf Michael Hanselmann
      result = (False, str(err))
189 9ae49f27 Guido Trotter
    except errors.QuitGanetiException, err:
190 84b58db2 Michael Hanselmann
      # Tell parent to quit
191 0623d351 Iustin Pop
      logging.info("Shutting down the node daemon, arguments: %s",
192 0623d351 Iustin Pop
                   str(err.args))
193 cc28af80 Michael Hanselmann
      os.kill(self.noded_pid, signal.SIGTERM)
194 0623d351 Iustin Pop
      # And return the error's arguments, which must be already in
195 0623d351 Iustin Pop
      # correct tuple format
196 ab221ddf Michael Hanselmann
      result = err.args
197 4dd42c9d Iustin Pop
    except Exception, err:
198 0623d351 Iustin Pop
      logging.exception("Error in RPC call")
199 ab221ddf Michael Hanselmann
      result = (False, "Error while executing backend function: %s" % str(err))
200 ab221ddf Michael Hanselmann
201 a182a3ed Michael Hanselmann
    return serializer.DumpJson(result)
202 a8083063 Iustin Pop
203 a8083063 Iustin Pop
  # the new block devices  --------------------------
204 a8083063 Iustin Pop
205 3ecf6786 Iustin Pop
  @staticmethod
206 3ecf6786 Iustin Pop
  def perspective_blockdev_create(params):
207 3ecf6786 Iustin Pop
    """Create a block device.
208 3ecf6786 Iustin Pop

209 3ecf6786 Iustin Pop
    """
210 ee1478e5 Bernardo Dal Seno
    (bdev_s, size, owner, on_primary, info, excl_stor) = params
211 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
212 a8083063 Iustin Pop
    if bdev is None:
213 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
214 ee1478e5 Bernardo Dal Seno
    return backend.BlockdevCreate(bdev, size, owner, on_primary, info,
215 ee1478e5 Bernardo Dal Seno
                                  excl_stor)
216 a8083063 Iustin Pop
217 3ecf6786 Iustin Pop
  @staticmethod
218 9c007da8 Renรฉ Nussbaumer
  def perspective_blockdev_pause_resume_sync(params):
219 9c007da8 Renรฉ Nussbaumer
    """Pause/resume sync of a block device.
220 9c007da8 Renรฉ Nussbaumer

221 9c007da8 Renรฉ Nussbaumer
    """
222 9c007da8 Renรฉ Nussbaumer
    disks_s, pause = params
223 9c007da8 Renรฉ Nussbaumer
    disks = [objects.Disk.FromDict(bdev_s) for bdev_s in disks_s]
224 9c007da8 Renรฉ Nussbaumer
    return backend.BlockdevPauseResumeSync(disks, pause)
225 9c007da8 Renรฉ Nussbaumer
226 9c007da8 Renรฉ Nussbaumer
  @staticmethod
227 271b7cf9 Renรฉ Nussbaumer
  def perspective_blockdev_wipe(params):
228 271b7cf9 Renรฉ Nussbaumer
    """Wipe a block device.
229 271b7cf9 Renรฉ Nussbaumer

230 271b7cf9 Renรฉ Nussbaumer
    """
231 271b7cf9 Renรฉ Nussbaumer
    bdev_s, offset, size = params
232 271b7cf9 Renรฉ Nussbaumer
    bdev = objects.Disk.FromDict(bdev_s)
233 271b7cf9 Renรฉ Nussbaumer
    return backend.BlockdevWipe(bdev, offset, size)
234 271b7cf9 Renรฉ Nussbaumer
235 271b7cf9 Renรฉ Nussbaumer
  @staticmethod
236 3ecf6786 Iustin Pop
  def perspective_blockdev_remove(params):
237 3ecf6786 Iustin Pop
    """Remove a block device.
238 3ecf6786 Iustin Pop

239 3ecf6786 Iustin Pop
    """
240 a8083063 Iustin Pop
    bdev_s = params[0]
241 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
242 821d1bd1 Iustin Pop
    return backend.BlockdevRemove(bdev)
243 a8083063 Iustin Pop
244 3ecf6786 Iustin Pop
  @staticmethod
245 f3e513ad Iustin Pop
  def perspective_blockdev_rename(params):
246 f3e513ad Iustin Pop
    """Remove a block device.
247 f3e513ad Iustin Pop

248 f3e513ad Iustin Pop
    """
249 8a31717c Michael Hanselmann
    devlist = [(objects.Disk.FromDict(ds), uid) for ds, uid in params[0]]
250 821d1bd1 Iustin Pop
    return backend.BlockdevRename(devlist)
251 f3e513ad Iustin Pop
252 f3e513ad Iustin Pop
  @staticmethod
253 3ecf6786 Iustin Pop
  def perspective_blockdev_assemble(params):
254 3ecf6786 Iustin Pop
    """Assemble a block device.
255 3ecf6786 Iustin Pop

256 3ecf6786 Iustin Pop
    """
257 c417e115 Iustin Pop
    bdev_s, owner, on_primary, idx = params
258 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
259 a8083063 Iustin Pop
    if bdev is None:
260 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
261 c417e115 Iustin Pop
    return backend.BlockdevAssemble(bdev, owner, on_primary, idx)
262 a8083063 Iustin Pop
263 3ecf6786 Iustin Pop
  @staticmethod
264 3ecf6786 Iustin Pop
  def perspective_blockdev_shutdown(params):
265 3ecf6786 Iustin Pop
    """Shutdown a block device.
266 3ecf6786 Iustin Pop

267 3ecf6786 Iustin Pop
    """
268 a8083063 Iustin Pop
    bdev_s = params[0]
269 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
270 a8083063 Iustin Pop
    if bdev is None:
271 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
272 821d1bd1 Iustin Pop
    return backend.BlockdevShutdown(bdev)
273 a8083063 Iustin Pop
274 3ecf6786 Iustin Pop
  @staticmethod
275 153d9724 Iustin Pop
  def perspective_blockdev_addchildren(params):
276 3ecf6786 Iustin Pop
    """Add a child to a mirror device.
277 3ecf6786 Iustin Pop

278 3ecf6786 Iustin Pop
    Note: this is only valid for mirror devices. It's the caller's duty
279 3ecf6786 Iustin Pop
    to send a correct disk, otherwise we raise an error.
280 3ecf6786 Iustin Pop

281 3ecf6786 Iustin Pop
    """
282 a8083063 Iustin Pop
    bdev_s, ndev_s = params
283 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
284 153d9724 Iustin Pop
    ndevs = [objects.Disk.FromDict(disk_s) for disk_s in ndev_s]
285 153d9724 Iustin Pop
    if bdev is None or ndevs.count(None) > 0:
286 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
287 821d1bd1 Iustin Pop
    return backend.BlockdevAddchildren(bdev, ndevs)
288 a8083063 Iustin Pop
289 3ecf6786 Iustin Pop
  @staticmethod
290 153d9724 Iustin Pop
  def perspective_blockdev_removechildren(params):
291 3ecf6786 Iustin Pop
    """Remove a child from a mirror device.
292 3ecf6786 Iustin Pop

293 3ecf6786 Iustin Pop
    This is only valid for mirror devices, of course. It's the callers
294 3ecf6786 Iustin Pop
    duty to send a correct disk, otherwise we raise an error.
295 3ecf6786 Iustin Pop

296 3ecf6786 Iustin Pop
    """
297 a8083063 Iustin Pop
    bdev_s, ndev_s = params
298 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
299 153d9724 Iustin Pop
    ndevs = [objects.Disk.FromDict(disk_s) for disk_s in ndev_s]
300 153d9724 Iustin Pop
    if bdev is None or ndevs.count(None) > 0:
301 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
302 821d1bd1 Iustin Pop
    return backend.BlockdevRemovechildren(bdev, ndevs)
303 a8083063 Iustin Pop
304 3ecf6786 Iustin Pop
  @staticmethod
305 3ecf6786 Iustin Pop
  def perspective_blockdev_getmirrorstatus(params):
306 3ecf6786 Iustin Pop
    """Return the mirror status for a list of disks.
307 3ecf6786 Iustin Pop

308 3ecf6786 Iustin Pop
    """
309 319856a9 Michael Hanselmann
    disks = [objects.Disk.FromDict(dsk_s)
310 e437117f Michael Hanselmann
             for dsk_s in params[0]]
311 36145b12 Michael Hanselmann
    return [status.ToDict()
312 36145b12 Michael Hanselmann
            for status in backend.BlockdevGetmirrorstatus(disks)]
313 a8083063 Iustin Pop
314 3ecf6786 Iustin Pop
  @staticmethod
315 b8d26c6e Michael Hanselmann
  def perspective_blockdev_getmirrorstatus_multi(params):
316 b8d26c6e Michael Hanselmann
    """Return the mirror status for a list of disks.
317 b8d26c6e Michael Hanselmann

318 b8d26c6e Michael Hanselmann
    """
319 b8d26c6e Michael Hanselmann
    (node_disks, ) = params
320 b8d26c6e Michael Hanselmann
321 5449685e Iustin Pop
    disks = [objects.Disk.FromDict(dsk_s) for dsk_s in node_disks]
322 b8d26c6e Michael Hanselmann
323 c6a9dffa Michael Hanselmann
    result = []
324 c6a9dffa Michael Hanselmann
325 c6a9dffa Michael Hanselmann
    for (success, status) in backend.BlockdevGetmirrorstatusMulti(disks):
326 c6a9dffa Michael Hanselmann
      if success:
327 c6a9dffa Michael Hanselmann
        result.append((success, status.ToDict()))
328 c6a9dffa Michael Hanselmann
      else:
329 c6a9dffa Michael Hanselmann
        result.append((success, status))
330 c6a9dffa Michael Hanselmann
331 c6a9dffa Michael Hanselmann
    return result
332 b8d26c6e Michael Hanselmann
333 b8d26c6e Michael Hanselmann
  @staticmethod
334 3ecf6786 Iustin Pop
  def perspective_blockdev_find(params):
335 3ecf6786 Iustin Pop
    """Expose the FindBlockDevice functionality for a disk.
336 3ecf6786 Iustin Pop

337 3ecf6786 Iustin Pop
    This will try to find but not activate a disk.
338 3ecf6786 Iustin Pop

339 3ecf6786 Iustin Pop
    """
340 319856a9 Michael Hanselmann
    disk = objects.Disk.FromDict(params[0])
341 ddfe2228 Michael Hanselmann
342 ddfe2228 Michael Hanselmann
    result = backend.BlockdevFind(disk)
343 ddfe2228 Michael Hanselmann
    if result is None:
344 ddfe2228 Michael Hanselmann
      return None
345 ddfe2228 Michael Hanselmann
346 ddfe2228 Michael Hanselmann
    return result.ToDict()
347 a8083063 Iustin Pop
348 3ecf6786 Iustin Pop
  @staticmethod
349 3ecf6786 Iustin Pop
  def perspective_blockdev_snapshot(params):
350 3ecf6786 Iustin Pop
    """Create a snapshot device.
351 3ecf6786 Iustin Pop

352 3ecf6786 Iustin Pop
    Note that this is only valid for LVM disks, if we get passed
353 3ecf6786 Iustin Pop
    something else we raise an exception. The snapshot device can be
354 3ecf6786 Iustin Pop
    remove by calling the generic block device remove call.
355 3ecf6786 Iustin Pop

356 3ecf6786 Iustin Pop
    """
357 319856a9 Michael Hanselmann
    cfbd = objects.Disk.FromDict(params[0])
358 821d1bd1 Iustin Pop
    return backend.BlockdevSnapshot(cfbd)
359 a8083063 Iustin Pop
360 4c8ba8b3 Iustin Pop
  @staticmethod
361 4c8ba8b3 Iustin Pop
  def perspective_blockdev_grow(params):
362 4c8ba8b3 Iustin Pop
    """Grow a stack of devices.
363 4c8ba8b3 Iustin Pop

364 4c8ba8b3 Iustin Pop
    """
365 e43a624e Bernardo Dal Seno
    if len(params) < 5:
366 e43a624e Bernardo Dal Seno
      raise ValueError("Received only %s parameters in blockdev_grow,"
367 e43a624e Bernardo Dal Seno
                       " old master?" % len(params))
368 4c8ba8b3 Iustin Pop
    cfbd = objects.Disk.FromDict(params[0])
369 4c8ba8b3 Iustin Pop
    amount = params[1]
370 a59faf4b Iustin Pop
    dryrun = params[2]
371 cad0723b Iustin Pop
    backingstore = params[3]
372 be9150ea Bernardo Dal Seno
    excl_stor = params[4]
373 be9150ea Bernardo Dal Seno
    return backend.BlockdevGrow(cfbd, amount, dryrun, backingstore, excl_stor)
374 4c8ba8b3 Iustin Pop
375 d61cbe76 Iustin Pop
  @staticmethod
376 d61cbe76 Iustin Pop
  def perspective_blockdev_close(params):
377 d61cbe76 Iustin Pop
    """Closes the given block devices.
378 d61cbe76 Iustin Pop

379 d61cbe76 Iustin Pop
    """
380 b2e7666a Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in params[1]]
381 821d1bd1 Iustin Pop
    return backend.BlockdevClose(params[0], disks)
382 d61cbe76 Iustin Pop
383 968a7623 Iustin Pop
  @staticmethod
384 6ef8077e Bernardo Dal Seno
  def perspective_blockdev_getdimensions(params):
385 968a7623 Iustin Pop
    """Compute the sizes of the given block devices.
386 968a7623 Iustin Pop

387 968a7623 Iustin Pop
    """
388 968a7623 Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in params[0]]
389 6ef8077e Bernardo Dal Seno
    return backend.BlockdevGetdimensions(disks)
390 968a7623 Iustin Pop
391 858f3d18 Iustin Pop
  @staticmethod
392 48e175a2 Iustin Pop
  def perspective_blockdev_setinfo(params):
393 48e175a2 Iustin Pop
    """Sets metadata information on the given block device.
394 48e175a2 Iustin Pop

395 48e175a2 Iustin Pop
    """
396 48e175a2 Iustin Pop
    (disk, info) = params
397 48e175a2 Iustin Pop
    disk = objects.Disk.FromDict(disk)
398 48e175a2 Iustin Pop
    return backend.BlockdevSetInfo(disk, info)
399 48e175a2 Iustin Pop
400 6b93ec9d Iustin Pop
  # blockdev/drbd specific methods ----------
401 6b93ec9d Iustin Pop
402 6b93ec9d Iustin Pop
  @staticmethod
403 6b93ec9d Iustin Pop
  def perspective_drbd_disconnect_net(params):
404 6b93ec9d Iustin Pop
    """Disconnects the network connection of drbd disks.
405 6b93ec9d Iustin Pop

406 6b93ec9d Iustin Pop
    Note that this is only valid for drbd disks, so the members of the
407 6b93ec9d Iustin Pop
    disk list must all be drbd devices.
408 6b93ec9d Iustin Pop

409 6b93ec9d Iustin Pop
    """
410 0c3d9c7c Thomas Thrainer
    (disks,) = params
411 0c3d9c7c Thomas Thrainer
    disks = [objects.Disk.FromDict(disk) for disk in disks]
412 0c3d9c7c Thomas Thrainer
    return backend.DrbdDisconnectNet(disks)
413 6b93ec9d Iustin Pop
414 6b93ec9d Iustin Pop
  @staticmethod
415 6b93ec9d Iustin Pop
  def perspective_drbd_attach_net(params):
416 6b93ec9d Iustin Pop
    """Attaches the network connection of drbd disks.
417 6b93ec9d Iustin Pop

418 6b93ec9d Iustin Pop
    Note that this is only valid for drbd disks, so the members of the
419 6b93ec9d Iustin Pop
    disk list must all be drbd devices.
420 6b93ec9d Iustin Pop

421 6b93ec9d Iustin Pop
    """
422 0c3d9c7c Thomas Thrainer
    disks, instance_name, multimaster = params
423 0c3d9c7c Thomas Thrainer
    disks = [objects.Disk.FromDict(disk) for disk in disks]
424 0c3d9c7c Thomas Thrainer
    return backend.DrbdAttachNet(disks, instance_name, multimaster)
425 6b93ec9d Iustin Pop
426 6b93ec9d Iustin Pop
  @staticmethod
427 6b93ec9d Iustin Pop
  def perspective_drbd_wait_sync(params):
428 6b93ec9d Iustin Pop
    """Wait until DRBD disks are synched.
429 6b93ec9d Iustin Pop

430 6b93ec9d Iustin Pop
    Note that this is only valid for drbd disks, so the members of the
431 6b93ec9d Iustin Pop
    disk list must all be drbd devices.
432 6b93ec9d Iustin Pop

433 6b93ec9d Iustin Pop
    """
434 0c3d9c7c Thomas Thrainer
    (disks,) = params
435 0c3d9c7c Thomas Thrainer
    disks = [objects.Disk.FromDict(disk) for disk in disks]
436 0c3d9c7c Thomas Thrainer
    return backend.DrbdWaitSync(disks)
437 6b93ec9d Iustin Pop
438 c46b9782 Luca Bigliardi
  @staticmethod
439 235a6b29 Thomas Thrainer
  def perspective_drbd_needs_activation(params):
440 235a6b29 Thomas Thrainer
    """Checks if the drbd devices need activation
441 235a6b29 Thomas Thrainer

442 235a6b29 Thomas Thrainer
    Note that this is only valid for drbd disks, so the members of the
443 235a6b29 Thomas Thrainer
    disk list must all be drbd devices.
444 235a6b29 Thomas Thrainer

445 235a6b29 Thomas Thrainer
    """
446 0c3d9c7c Thomas Thrainer
    (disks,) = params
447 0c3d9c7c Thomas Thrainer
    disks = [objects.Disk.FromDict(disk) for disk in disks]
448 0c3d9c7c Thomas Thrainer
    return backend.DrbdNeedsActivation(disks)
449 235a6b29 Thomas Thrainer
450 235a6b29 Thomas Thrainer
  @staticmethod
451 0c3d9c7c Thomas Thrainer
  def perspective_drbd_helper(_):
452 c46b9782 Luca Bigliardi
    """Query drbd helper.
453 c46b9782 Luca Bigliardi

454 c46b9782 Luca Bigliardi
    """
455 c46b9782 Luca Bigliardi
    return backend.GetDrbdUsermodeHelper()
456 c46b9782 Luca Bigliardi
457 a8083063 Iustin Pop
  # export/import  --------------------------
458 a8083063 Iustin Pop
459 3ecf6786 Iustin Pop
  @staticmethod
460 3ecf6786 Iustin Pop
  def perspective_finalize_export(params):
461 3ecf6786 Iustin Pop
    """Expose the finalize export functionality.
462 a8083063 Iustin Pop

463 3ecf6786 Iustin Pop
    """
464 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
465 7b651654 Michael Hanselmann
466 7b651654 Michael Hanselmann
    snap_disks = []
467 7b651654 Michael Hanselmann
    for disk in params[1]:
468 7b651654 Michael Hanselmann
      if isinstance(disk, bool):
469 7b651654 Michael Hanselmann
        snap_disks.append(disk)
470 7b651654 Michael Hanselmann
      else:
471 7b651654 Michael Hanselmann
        snap_disks.append(objects.Disk.FromDict(disk))
472 7b651654 Michael Hanselmann
473 a8083063 Iustin Pop
    return backend.FinalizeExport(instance, snap_disks)
474 a8083063 Iustin Pop
475 3ecf6786 Iustin Pop
  @staticmethod
476 3ecf6786 Iustin Pop
  def perspective_export_info(params):
477 3ecf6786 Iustin Pop
    """Query information about an existing export on this node.
478 3ecf6786 Iustin Pop

479 3ecf6786 Iustin Pop
    The given path may not contain an export, in which case we return
480 3ecf6786 Iustin Pop
    None.
481 3ecf6786 Iustin Pop

482 3ecf6786 Iustin Pop
    """
483 3ecf6786 Iustin Pop
    path = params[0]
484 3eccac06 Iustin Pop
    return backend.ExportInfo(path)
485 a8083063 Iustin Pop
486 3ecf6786 Iustin Pop
  @staticmethod
487 3ecf6786 Iustin Pop
  def perspective_export_list(params):
488 3ecf6786 Iustin Pop
    """List the available exports on this node.
489 3ecf6786 Iustin Pop

490 3ecf6786 Iustin Pop
    Note that as opposed to export_info, which may query data about an
491 3ecf6786 Iustin Pop
    export in any path, this only queries the standard Ganeti path
492 a5ce2ea2 Michael Hanselmann
    (pathutils.EXPORT_DIR).
493 3ecf6786 Iustin Pop

494 3ecf6786 Iustin Pop
    """
495 a8083063 Iustin Pop
    return backend.ListExports()
496 a8083063 Iustin Pop
497 3ecf6786 Iustin Pop
  @staticmethod
498 3ecf6786 Iustin Pop
  def perspective_export_remove(params):
499 3ecf6786 Iustin Pop
    """Remove an export.
500 3ecf6786 Iustin Pop

501 3ecf6786 Iustin Pop
    """
502 a8083063 Iustin Pop
    export = params[0]
503 a8083063 Iustin Pop
    return backend.RemoveExport(export)
504 a8083063 Iustin Pop
505 2be7273c Apollon Oikonomopoulos
  # block device ---------------------
506 2be7273c Apollon Oikonomopoulos
  @staticmethod
507 2be7273c Apollon Oikonomopoulos
  def perspective_bdev_sizes(params):
508 2be7273c Apollon Oikonomopoulos
    """Query the list of block devices
509 2be7273c Apollon Oikonomopoulos

510 2be7273c Apollon Oikonomopoulos
    """
511 2be7273c Apollon Oikonomopoulos
    devices = params[0]
512 2be7273c Apollon Oikonomopoulos
    return backend.GetBlockDevSizes(devices)
513 2be7273c Apollon Oikonomopoulos
514 a8083063 Iustin Pop
  # volume  --------------------------
515 a8083063 Iustin Pop
516 3ecf6786 Iustin Pop
  @staticmethod
517 b2a6ccd4 Iustin Pop
  def perspective_lv_list(params):
518 3ecf6786 Iustin Pop
    """Query the list of logical volumes in a given volume group.
519 3ecf6786 Iustin Pop

520 3ecf6786 Iustin Pop
    """
521 a8083063 Iustin Pop
    vgname = params[0]
522 c26a6bd2 Iustin Pop
    return backend.GetVolumeList(vgname)
523 a8083063 Iustin Pop
524 3ecf6786 Iustin Pop
  @staticmethod
525 3ecf6786 Iustin Pop
  def perspective_vg_list(params):
526 3ecf6786 Iustin Pop
    """Query the list of volume groups.
527 3ecf6786 Iustin Pop

528 3ecf6786 Iustin Pop
    """
529 a8083063 Iustin Pop
    return backend.ListVolumeGroups()
530 a8083063 Iustin Pop
531 e337de97 Michael Hanselmann
  # Storage --------------------------
532 e337de97 Michael Hanselmann
533 e337de97 Michael Hanselmann
  @staticmethod
534 e337de97 Michael Hanselmann
  def perspective_storage_list(params):
535 e337de97 Michael Hanselmann
    """Get list of storage units.
536 e337de97 Michael Hanselmann

537 e337de97 Michael Hanselmann
    """
538 e337de97 Michael Hanselmann
    (su_name, su_args, name, fields) = params
539 c23bb217 Helga Velroyen
    return container.GetStorage(su_name, *su_args).List(name, fields)
540 e337de97 Michael Hanselmann
541 8979196a Michael Hanselmann
  @staticmethod
542 8979196a Michael Hanselmann
  def perspective_storage_modify(params):
543 8979196a Michael Hanselmann
    """Modify a storage unit.
544 8979196a Michael Hanselmann

545 8979196a Michael Hanselmann
    """
546 8979196a Michael Hanselmann
    (su_name, su_args, name, changes) = params
547 c23bb217 Helga Velroyen
    return container.GetStorage(su_name, *su_args).Modify(name, changes)
548 8979196a Michael Hanselmann
549 637b8d7e Michael Hanselmann
  @staticmethod
550 637b8d7e Michael Hanselmann
  def perspective_storage_execute(params):
551 637b8d7e Michael Hanselmann
    """Execute an operation on a storage unit.
552 637b8d7e Michael Hanselmann

553 637b8d7e Michael Hanselmann
    """
554 637b8d7e Michael Hanselmann
    (su_name, su_args, name, op) = params
555 c23bb217 Helga Velroyen
    return container.GetStorage(su_name, *su_args).Execute(name, op)
556 637b8d7e Michael Hanselmann
557 a8083063 Iustin Pop
  # bridge  --------------------------
558 a8083063 Iustin Pop
559 3ecf6786 Iustin Pop
  @staticmethod
560 3ecf6786 Iustin Pop
  def perspective_bridges_exist(params):
561 3ecf6786 Iustin Pop
    """Check if all bridges given exist on this node.
562 3ecf6786 Iustin Pop

563 3ecf6786 Iustin Pop
    """
564 a8083063 Iustin Pop
    bridges_list = params[0]
565 a8083063 Iustin Pop
    return backend.BridgesExist(bridges_list)
566 a8083063 Iustin Pop
567 a8083063 Iustin Pop
  # instance  --------------------------
568 a8083063 Iustin Pop
569 3ecf6786 Iustin Pop
  @staticmethod
570 3ecf6786 Iustin Pop
  def perspective_instance_os_add(params):
571 3ecf6786 Iustin Pop
    """Install an OS on a given instance.
572 3ecf6786 Iustin Pop

573 3ecf6786 Iustin Pop
    """
574 d15a9ad3 Guido Trotter
    inst_s = params[0]
575 319856a9 Michael Hanselmann
    inst = objects.Instance.FromDict(inst_s)
576 e557bae9 Guido Trotter
    reinstall = params[1]
577 4a0e011f Iustin Pop
    debug = params[2]
578 4a0e011f Iustin Pop
    return backend.InstanceOsAdd(inst, reinstall, debug)
579 a8083063 Iustin Pop
580 3ecf6786 Iustin Pop
  @staticmethod
581 decd5f45 Iustin Pop
  def perspective_instance_run_rename(params):
582 decd5f45 Iustin Pop
    """Runs the OS rename script for an instance.
583 decd5f45 Iustin Pop

584 decd5f45 Iustin Pop
    """
585 4a0e011f Iustin Pop
    inst_s, old_name, debug = params
586 319856a9 Michael Hanselmann
    inst = objects.Instance.FromDict(inst_s)
587 4a0e011f Iustin Pop
    return backend.RunRenameInstance(inst, old_name, debug)
588 decd5f45 Iustin Pop
589 decd5f45 Iustin Pop
  @staticmethod
590 3ecf6786 Iustin Pop
  def perspective_instance_shutdown(params):
591 3ecf6786 Iustin Pop
    """Shutdown an instance.
592 3ecf6786 Iustin Pop

593 3ecf6786 Iustin Pop
    """
594 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
595 6263189c Guido Trotter
    timeout = params[1]
596 1f350e0f Michele Tartara
    trail = params[2]
597 1f350e0f Michele Tartara
    _extendReasonTrail(trail, "shutdown")
598 1f350e0f Michele Tartara
    return backend.InstanceShutdown(instance, timeout, trail)
599 a8083063 Iustin Pop
600 3ecf6786 Iustin Pop
  @staticmethod
601 3ecf6786 Iustin Pop
  def perspective_instance_start(params):
602 3ecf6786 Iustin Pop
    """Start an instance.
603 3ecf6786 Iustin Pop

604 3ecf6786 Iustin Pop
    """
605 1fa6fcba Michele Tartara
    (instance_name, startup_paused, trail) = params
606 323f9095 Stephen Shirley
    instance = objects.Instance.FromDict(instance_name)
607 1fa6fcba Michele Tartara
    _extendReasonTrail(trail, "start")
608 1fa6fcba Michele Tartara
    return backend.StartInstance(instance, startup_paused, trail)
609 a8083063 Iustin Pop
610 3ecf6786 Iustin Pop
  @staticmethod
611 c5708931 Dimitris Aragiorgis
  def perspective_hotplug_device(params):
612 c5708931 Dimitris Aragiorgis
    """Hotplugs device to a running instance.
613 c5708931 Dimitris Aragiorgis

614 c5708931 Dimitris Aragiorgis
    """
615 c5708931 Dimitris Aragiorgis
    (idict, action, dev_type, ddict, extra, seq) = params
616 c5708931 Dimitris Aragiorgis
    instance = objects.Instance.FromDict(idict)
617 c5708931 Dimitris Aragiorgis
    if dev_type == constants.HOTPLUG_TARGET_DISK:
618 c5708931 Dimitris Aragiorgis
      device = objects.Disk.FromDict(ddict)
619 c5708931 Dimitris Aragiorgis
    elif dev_type == constants.HOTPLUG_TARGET_NIC:
620 c5708931 Dimitris Aragiorgis
      device = objects.NIC.FromDict(ddict)
621 c5708931 Dimitris Aragiorgis
    else:
622 c5708931 Dimitris Aragiorgis
      assert dev_type in constants.HOTPLUG_ALL_TARGETS
623 c5708931 Dimitris Aragiorgis
    return backend.HotplugDevice(instance, action, dev_type, device, extra, seq)
624 c5708931 Dimitris Aragiorgis
625 c5708931 Dimitris Aragiorgis
  @staticmethod
626 24711492 Dimitris Aragiorgis
  def perspective_hotplug_supported(params):
627 24711492 Dimitris Aragiorgis
    """Checks if hotplug is supported.
628 24711492 Dimitris Aragiorgis

629 24711492 Dimitris Aragiorgis
    """
630 24711492 Dimitris Aragiorgis
    instance = objects.Instance.FromDict(params[0])
631 24711492 Dimitris Aragiorgis
    return backend.HotplugSupported(instance)
632 24711492 Dimitris Aragiorgis
633 24711492 Dimitris Aragiorgis
  @staticmethod
634 6906a9d8 Guido Trotter
  def perspective_migration_info(params):
635 6906a9d8 Guido Trotter
    """Gather information about an instance to be migrated.
636 6906a9d8 Guido Trotter

637 6906a9d8 Guido Trotter
    """
638 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(params[0])
639 6906a9d8 Guido Trotter
    return backend.MigrationInfo(instance)
640 6906a9d8 Guido Trotter
641 6906a9d8 Guido Trotter
  @staticmethod
642 6906a9d8 Guido Trotter
  def perspective_accept_instance(params):
643 6906a9d8 Guido Trotter
    """Prepare the node to accept an instance.
644 6906a9d8 Guido Trotter

645 6906a9d8 Guido Trotter
    """
646 6906a9d8 Guido Trotter
    instance, info, target = params
647 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(instance)
648 6906a9d8 Guido Trotter
    return backend.AcceptInstance(instance, info, target)
649 6906a9d8 Guido Trotter
650 6906a9d8 Guido Trotter
  @staticmethod
651 6a1434d7 Andrea Spadaccini
  def perspective_instance_finalize_migration_dst(params):
652 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the destination node.
653 6906a9d8 Guido Trotter

654 6906a9d8 Guido Trotter
    """
655 6906a9d8 Guido Trotter
    instance, info, success = params
656 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(instance)
657 6a1434d7 Andrea Spadaccini
    return backend.FinalizeMigrationDst(instance, info, success)
658 6906a9d8 Guido Trotter
659 6906a9d8 Guido Trotter
  @staticmethod
660 2a10865c Iustin Pop
  def perspective_instance_migrate(params):
661 2a10865c Iustin Pop
    """Migrates an instance.
662 2a10865c Iustin Pop

663 2a10865c Iustin Pop
    """
664 bc0a2284 Helga Velroyen
    cluster_name, instance, target, live = params
665 9f0e6b37 Iustin Pop
    instance = objects.Instance.FromDict(instance)
666 bc0a2284 Helga Velroyen
    return backend.MigrateInstance(cluster_name, instance, target, live)
667 2a10865c Iustin Pop
668 2a10865c Iustin Pop
  @staticmethod
669 6a1434d7 Andrea Spadaccini
  def perspective_instance_finalize_migration_src(params):
670 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the source node.
671 6a1434d7 Andrea Spadaccini

672 6a1434d7 Andrea Spadaccini
    """
673 6a1434d7 Andrea Spadaccini
    instance, success, live = params
674 6a1434d7 Andrea Spadaccini
    instance = objects.Instance.FromDict(instance)
675 6a1434d7 Andrea Spadaccini
    return backend.FinalizeMigrationSource(instance, success, live)
676 6a1434d7 Andrea Spadaccini
677 6a1434d7 Andrea Spadaccini
  @staticmethod
678 6a1434d7 Andrea Spadaccini
  def perspective_instance_get_migration_status(params):
679 6a1434d7 Andrea Spadaccini
    """Reports migration status.
680 6a1434d7 Andrea Spadaccini

681 6a1434d7 Andrea Spadaccini
    """
682 6a1434d7 Andrea Spadaccini
    instance = objects.Instance.FromDict(params[0])
683 6a1434d7 Andrea Spadaccini
    return backend.GetMigrationStatus(instance).ToDict()
684 6a1434d7 Andrea Spadaccini
685 6a1434d7 Andrea Spadaccini
  @staticmethod
686 007a2f3e Alexander Schreiber
  def perspective_instance_reboot(params):
687 007a2f3e Alexander Schreiber
    """Reboot an instance.
688 007a2f3e Alexander Schreiber

689 007a2f3e Alexander Schreiber
    """
690 007a2f3e Alexander Schreiber
    instance = objects.Instance.FromDict(params[0])
691 007a2f3e Alexander Schreiber
    reboot_type = params[1]
692 17c3f802 Guido Trotter
    shutdown_timeout = params[2]
693 55cec070 Michele Tartara
    trail = params[3]
694 55cec070 Michele Tartara
    _extendReasonTrail(trail, "reboot")
695 55cec070 Michele Tartara
    return backend.InstanceReboot(instance, reboot_type, shutdown_timeout,
696 55cec070 Michele Tartara
                                  trail)
697 007a2f3e Alexander Schreiber
698 007a2f3e Alexander Schreiber
  @staticmethod
699 ebe466d8 Guido Trotter
  def perspective_instance_balloon_memory(params):
700 ebe466d8 Guido Trotter
    """Modify instance runtime memory.
701 ebe466d8 Guido Trotter

702 ebe466d8 Guido Trotter
    """
703 ebe466d8 Guido Trotter
    instance_dict, memory = params
704 ebe466d8 Guido Trotter
    instance = objects.Instance.FromDict(instance_dict)
705 ebe466d8 Guido Trotter
    return backend.InstanceBalloonMemory(instance, memory)
706 ebe466d8 Guido Trotter
707 ebe466d8 Guido Trotter
  @staticmethod
708 3ecf6786 Iustin Pop
  def perspective_instance_info(params):
709 3ecf6786 Iustin Pop
    """Query instance information.
710 3ecf6786 Iustin Pop

711 3ecf6786 Iustin Pop
    """
712 0bbec3af Helga Velroyen
    (instance_name, hypervisor_name, hvparams) = params
713 0bbec3af Helga Velroyen
    return backend.GetInstanceInfo(instance_name, hypervisor_name, hvparams)
714 a8083063 Iustin Pop
715 3ecf6786 Iustin Pop
  @staticmethod
716 56e7640c Iustin Pop
  def perspective_instance_migratable(params):
717 56e7640c Iustin Pop
    """Query whether the specified instance can be migrated.
718 56e7640c Iustin Pop

719 56e7640c Iustin Pop
    """
720 56e7640c Iustin Pop
    instance = objects.Instance.FromDict(params[0])
721 56e7640c Iustin Pop
    return backend.GetInstanceMigratable(instance)
722 56e7640c Iustin Pop
723 56e7640c Iustin Pop
  @staticmethod
724 3ecf6786 Iustin Pop
  def perspective_all_instances_info(params):
725 3ecf6786 Iustin Pop
    """Query information about all instances.
726 3ecf6786 Iustin Pop

727 3ecf6786 Iustin Pop
    """
728 0200a1af Helga Velroyen
    (hypervisor_list, all_hvparams) = params
729 0200a1af Helga Velroyen
    return backend.GetAllInstancesInfo(hypervisor_list, all_hvparams)
730 a8083063 Iustin Pop
731 3ecf6786 Iustin Pop
  @staticmethod
732 b9e12624 Hrvoje Ribicic
  def perspective_instance_console_info(params):
733 b9e12624 Hrvoje Ribicic
    """Query information on how to get console access to instances
734 b9e12624 Hrvoje Ribicic

735 b9e12624 Hrvoje Ribicic
    """
736 b9e12624 Hrvoje Ribicic
    return backend.GetInstanceConsoleInfo(params)
737 b9e12624 Hrvoje Ribicic
738 b9e12624 Hrvoje Ribicic
  @staticmethod
739 3ecf6786 Iustin Pop
  def perspective_instance_list(params):
740 3ecf6786 Iustin Pop
    """Query the list of running instances.
741 3ecf6786 Iustin Pop

742 3ecf6786 Iustin Pop
    """
743 8ac806e6 Helga Velroyen
    (hypervisor_list, hvparams) = params
744 8ac806e6 Helga Velroyen
    return backend.GetInstanceList(hypervisor_list, hvparams)
745 a8083063 Iustin Pop
746 a8083063 Iustin Pop
  # node --------------------------
747 a8083063 Iustin Pop
748 3ecf6786 Iustin Pop
  @staticmethod
749 caad16e2 Iustin Pop
  def perspective_node_has_ip_address(params):
750 caad16e2 Iustin Pop
    """Checks if a node has the given ip address.
751 caad16e2 Iustin Pop

752 caad16e2 Iustin Pop
    """
753 8b312c1d Manuel Franceschini
    return netutils.IPAddress.Own(params[0])
754 caad16e2 Iustin Pop
755 caad16e2 Iustin Pop
  @staticmethod
756 3ecf6786 Iustin Pop
  def perspective_node_info(params):
757 3ecf6786 Iustin Pop
    """Query node information.
758 3ecf6786 Iustin Pop

759 3ecf6786 Iustin Pop
    """
760 a59c31ca Helga Velroyen
    (storage_units, hv_specs) = params
761 152759e4 Helga Velroyen
    return backend.GetNodeInfo(storage_units, hv_specs)
762 152759e4 Helga Velroyen
763 152759e4 Helga Velroyen
  @staticmethod
764 19ddc57a Renรฉ Nussbaumer
  def perspective_etc_hosts_modify(params):
765 19ddc57a Renรฉ Nussbaumer
    """Modify a node entry in /etc/hosts.
766 19ddc57a Renรฉ Nussbaumer

767 19ddc57a Renรฉ Nussbaumer
    """
768 19ddc57a Renรฉ Nussbaumer
    backend.EtcHostsModify(params[0], params[1], params[2])
769 19ddc57a Renรฉ Nussbaumer
770 19ddc57a Renรฉ Nussbaumer
    return True
771 19ddc57a Renรฉ Nussbaumer
772 19ddc57a Renรฉ Nussbaumer
  @staticmethod
773 3ecf6786 Iustin Pop
  def perspective_node_verify(params):
774 3ecf6786 Iustin Pop
    """Run a verify sequence on this node.
775 3ecf6786 Iustin Pop

776 3ecf6786 Iustin Pop
    """
777 a9f33339 Petr Pudlak
    (what, cluster_name, hvparams, node_groups, groups_cfg) = params
778 a9f33339 Petr Pudlak
    return backend.VerifyNode(what, cluster_name, hvparams,
779 a9f33339 Petr Pudlak
                              node_groups, groups_cfg)
780 a8083063 Iustin Pop
781 14fe92c7 Bernardo Dal Seno
  @classmethod
782 14fe92c7 Bernardo Dal Seno
  def perspective_node_verify_light(cls, params):
783 14fe92c7 Bernardo Dal Seno
    """Run a light verify sequence on this node.
784 14fe92c7 Bernardo Dal Seno

785 a9f33339 Petr Pudlak
    This call is meant to perform a less strict verification of the node in
786 a9f33339 Petr Pudlak
    certain situations. Right now, it is invoked only when a node is just about
787 a9f33339 Petr Pudlak
    to be added to a cluster, and even then, it performs the same checks as
788 a9f33339 Petr Pudlak
    L{perspective_node_verify}.
789 14fe92c7 Bernardo Dal Seno
    """
790 14fe92c7 Bernardo Dal Seno
    return cls.perspective_node_verify(params)
791 14fe92c7 Bernardo Dal Seno
792 3ecf6786 Iustin Pop
  @staticmethod
793 fb460cf7 Andrea Spadaccini
  def perspective_node_start_master_daemons(params):
794 fb460cf7 Andrea Spadaccini
    """Start the master daemons on this node.
795 3ecf6786 Iustin Pop

796 3ecf6786 Iustin Pop
    """
797 fb460cf7 Andrea Spadaccini
    return backend.StartMasterDaemons(params[0])
798 fb460cf7 Andrea Spadaccini
799 fb460cf7 Andrea Spadaccini
  @staticmethod
800 fb460cf7 Andrea Spadaccini
  def perspective_node_activate_master_ip(params):
801 fb460cf7 Andrea Spadaccini
    """Activate the master IP on this node.
802 fb460cf7 Andrea Spadaccini

803 fb460cf7 Andrea Spadaccini
    """
804 c79198a0 Andrea Spadaccini
    master_params = objects.MasterNetworkParameters.FromDict(params[0])
805 57c7bc57 Andrea Spadaccini
    return backend.ActivateMasterIp(master_params, params[1])
806 fb460cf7 Andrea Spadaccini
807 fb460cf7 Andrea Spadaccini
  @staticmethod
808 fb460cf7 Andrea Spadaccini
  def perspective_node_deactivate_master_ip(params):
809 fb460cf7 Andrea Spadaccini
    """Deactivate the master IP on this node.
810 fb460cf7 Andrea Spadaccini

811 fb460cf7 Andrea Spadaccini
    """
812 c79198a0 Andrea Spadaccini
    master_params = objects.MasterNetworkParameters.FromDict(params[0])
813 57c7bc57 Andrea Spadaccini
    return backend.DeactivateMasterIp(master_params, params[1])
814 a8083063 Iustin Pop
815 3ecf6786 Iustin Pop
  @staticmethod
816 3ecf6786 Iustin Pop
  def perspective_node_stop_master(params):
817 7c74bbe0 Andrea Spadaccini
    """Stops master daemons on this node.
818 3ecf6786 Iustin Pop

819 3ecf6786 Iustin Pop
    """
820 fb460cf7 Andrea Spadaccini
    return backend.StopMasterDaemons()
821 a8083063 Iustin Pop
822 3ecf6786 Iustin Pop
  @staticmethod
823 5a8648eb Andrea Spadaccini
  def perspective_node_change_master_netmask(params):
824 5a8648eb Andrea Spadaccini
    """Change the master IP netmask.
825 5a8648eb Andrea Spadaccini

826 5a8648eb Andrea Spadaccini
    """
827 41e079ce Andrea Spadaccini
    return backend.ChangeMasterNetmask(params[0], params[1], params[2],
828 41e079ce Andrea Spadaccini
                                       params[3])
829 5a8648eb Andrea Spadaccini
830 5a8648eb Andrea Spadaccini
  @staticmethod
831 3ecf6786 Iustin Pop
  def perspective_node_leave_cluster(params):
832 3ecf6786 Iustin Pop
    """Cleanup after leaving a cluster.
833 3ecf6786 Iustin Pop

834 3ecf6786 Iustin Pop
    """
835 b989b9d9 Ken Wehr
    return backend.LeaveCluster(params[0])
836 a8083063 Iustin Pop
837 3ecf6786 Iustin Pop
  @staticmethod
838 3ecf6786 Iustin Pop
  def perspective_node_volumes(params):
839 3ecf6786 Iustin Pop
    """Query the list of all logical volume groups.
840 3ecf6786 Iustin Pop

841 3ecf6786 Iustin Pop
    """
842 dcb93971 Michael Hanselmann
    return backend.NodeVolumes()
843 dcb93971 Michael Hanselmann
844 56aa9fd5 Iustin Pop
  @staticmethod
845 56aa9fd5 Iustin Pop
  def perspective_node_demote_from_mc(params):
846 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
847 56aa9fd5 Iustin Pop

848 56aa9fd5 Iustin Pop
    """
849 56aa9fd5 Iustin Pop
    return backend.DemoteFromMC()
850 56aa9fd5 Iustin Pop
851 f5118ade Iustin Pop
  @staticmethod
852 f5118ade Iustin Pop
  def perspective_node_powercycle(params):
853 37f56360 Sebastian Gebhard
    """Tries to powercycle the node.
854 f5118ade Iustin Pop

855 f5118ade Iustin Pop
    """
856 8ef418bb Helga Velroyen
    (hypervisor_type, hvparams) = params
857 8ef418bb Helga Velroyen
    return backend.PowercycleNode(hypervisor_type, hvparams)
858 f5118ade Iustin Pop
859 90d8d4d1 Sebastian Gebhard
  @staticmethod
860 90d8d4d1 Sebastian Gebhard
  def perspective_node_configure_ovs(params):
861 90d8d4d1 Sebastian Gebhard
    """Sets up OpenvSwitch on the node.
862 90d8d4d1 Sebastian Gebhard

863 90d8d4d1 Sebastian Gebhard
    """
864 90d8d4d1 Sebastian Gebhard
    (ovs_name, ovs_link) = params
865 90d8d4d1 Sebastian Gebhard
    return backend.ConfigureOVS(ovs_name, ovs_link)
866 90d8d4d1 Sebastian Gebhard
867 b544a3c2 Helga Velroyen
  @staticmethod
868 b544a3c2 Helga Velroyen
  def perspective_node_crypto_tokens(params):
869 b544a3c2 Helga Velroyen
    """Gets the node's public crypto tokens.
870 b544a3c2 Helga Velroyen

871 b544a3c2 Helga Velroyen
    """
872 d722af8b Helga Velroyen
    token_requests = params[0]
873 d722af8b Helga Velroyen
    return backend.GetCryptoTokens(token_requests)
874 b544a3c2 Helga Velroyen
875 a8083063 Iustin Pop
  # cluster --------------------------
876 a8083063 Iustin Pop
877 3ecf6786 Iustin Pop
  @staticmethod
878 3ecf6786 Iustin Pop
  def perspective_version(params):
879 3ecf6786 Iustin Pop
    """Query version information.
880 3ecf6786 Iustin Pop

881 3ecf6786 Iustin Pop
    """
882 c26a6bd2 Iustin Pop
    return constants.PROTOCOL_VERSION
883 a8083063 Iustin Pop
884 3ecf6786 Iustin Pop
  @staticmethod
885 3ecf6786 Iustin Pop
  def perspective_upload_file(params):
886 3ecf6786 Iustin Pop
    """Upload a file.
887 3ecf6786 Iustin Pop

888 3ecf6786 Iustin Pop
    Note that the backend implementation imposes strict rules on which
889 3ecf6786 Iustin Pop
    files are accepted.
890 3ecf6786 Iustin Pop

891 3ecf6786 Iustin Pop
    """
892 415a7304 Michael Hanselmann
    return backend.UploadFile(*(params[0]))
893 a8083063 Iustin Pop
894 4e071d3b Iustin Pop
  @staticmethod
895 cb8028f3 Jose A. Lopes
  def perspective_master_node_name(params):
896 cb8028f3 Jose A. Lopes
    """Returns the master node name.
897 4e071d3b Iustin Pop

898 4e071d3b Iustin Pop
    """
899 cb8028f3 Jose A. Lopes
    return backend.GetMasterNodeName()
900 a8083063 Iustin Pop
901 6ddc95ec Michael Hanselmann
  @staticmethod
902 4f6014d4 Renรฉ Nussbaumer
  def perspective_run_oob(params):
903 4f6014d4 Renรฉ Nussbaumer
    """Runs oob on node.
904 4f6014d4 Renรฉ Nussbaumer

905 4f6014d4 Renรฉ Nussbaumer
    """
906 1aa88d95 Renรฉ Nussbaumer
    output = backend.RunOob(params[0], params[1], params[2], params[3])
907 1aa88d95 Renรฉ Nussbaumer
    if output:
908 1aa88d95 Renรฉ Nussbaumer
      result = serializer.LoadJson(output)
909 1aa88d95 Renรฉ Nussbaumer
    else:
910 1aa88d95 Renรฉ Nussbaumer
      result = None
911 1aa88d95 Renรฉ Nussbaumer
    return result
912 4f6014d4 Renรฉ Nussbaumer
913 4f6014d4 Renรฉ Nussbaumer
  @staticmethod
914 db2203e0 Michael Hanselmann
  def perspective_restricted_command(params):
915 db2203e0 Michael Hanselmann
    """Runs a restricted command.
916 db2203e0 Michael Hanselmann

917 db2203e0 Michael Hanselmann
    """
918 db2203e0 Michael Hanselmann
    (cmd, ) = params
919 db2203e0 Michael Hanselmann
920 42bd26e8 Michael Hanselmann
    return backend.RunRestrictedCmd(cmd)
921 db2203e0 Michael Hanselmann
922 db2203e0 Michael Hanselmann
  @staticmethod
923 6ddc95ec Michael Hanselmann
  def perspective_write_ssconf_files(params):
924 6ddc95ec Michael Hanselmann
    """Write ssconf files.
925 6ddc95ec Michael Hanselmann

926 6ddc95ec Michael Hanselmann
    """
927 03d1dba2 Michael Hanselmann
    (values,) = params
928 ee501db1 Michael Hanselmann
    return ssconf.WriteSsconfFiles(values)
929 6ddc95ec Michael Hanselmann
930 99e222b1 Michael Hanselmann
  @staticmethod
931 ec5af888 Michael Hanselmann
  def perspective_get_watcher_pause(params):
932 ec5af888 Michael Hanselmann
    """Get watcher pause end.
933 ec5af888 Michael Hanselmann

934 ec5af888 Michael Hanselmann
    """
935 ec5af888 Michael Hanselmann
    return utils.ReadWatcherPauseFile(pathutils.WATCHER_PAUSEFILE)
936 ec5af888 Michael Hanselmann
937 ec5af888 Michael Hanselmann
  @staticmethod
938 99e222b1 Michael Hanselmann
  def perspective_set_watcher_pause(params):
939 99e222b1 Michael Hanselmann
    """Set watcher pause.
940 99e222b1 Michael Hanselmann

941 99e222b1 Michael Hanselmann
    """
942 99e222b1 Michael Hanselmann
    (until, ) = params
943 99e222b1 Michael Hanselmann
    return backend.SetWatcherPause(until)
944 99e222b1 Michael Hanselmann
945 a8083063 Iustin Pop
  # os -----------------------
946 a8083063 Iustin Pop
947 3ecf6786 Iustin Pop
  @staticmethod
948 3ecf6786 Iustin Pop
  def perspective_os_diagnose(params):
949 3ecf6786 Iustin Pop
    """Query detailed information about existing OSes.
950 3ecf6786 Iustin Pop

951 3ecf6786 Iustin Pop
    """
952 255dcebd Iustin Pop
    return backend.DiagnoseOS()
953 a8083063 Iustin Pop
954 3ecf6786 Iustin Pop
  @staticmethod
955 3ecf6786 Iustin Pop
  def perspective_os_get(params):
956 3ecf6786 Iustin Pop
    """Query information about a given OS.
957 3ecf6786 Iustin Pop

958 3ecf6786 Iustin Pop
    """
959 a8083063 Iustin Pop
    name = params[0]
960 255dcebd Iustin Pop
    os_obj = backend.OSFromDisk(name)
961 c26a6bd2 Iustin Pop
    return os_obj.ToDict()
962 a8083063 Iustin Pop
963 acd9ff9e Iustin Pop
  @staticmethod
964 acd9ff9e Iustin Pop
  def perspective_os_validate(params):
965 acd9ff9e Iustin Pop
    """Run a given OS' validation routine.
966 acd9ff9e Iustin Pop

967 acd9ff9e Iustin Pop
    """
968 acd9ff9e Iustin Pop
    required, name, checks, params = params
969 acd9ff9e Iustin Pop
    return backend.ValidateOS(required, name, checks, params)
970 acd9ff9e Iustin Pop
971 b954f097 Constantinos Venetsanopoulos
  # extstorage -----------------------
972 b954f097 Constantinos Venetsanopoulos
973 b954f097 Constantinos Venetsanopoulos
  @staticmethod
974 b954f097 Constantinos Venetsanopoulos
  def perspective_extstorage_diagnose(params):
975 b954f097 Constantinos Venetsanopoulos
    """Query detailed information about existing extstorage providers.
976 b954f097 Constantinos Venetsanopoulos

977 b954f097 Constantinos Venetsanopoulos
    """
978 b954f097 Constantinos Venetsanopoulos
    return backend.DiagnoseExtStorage()
979 b954f097 Constantinos Venetsanopoulos
980 a8083063 Iustin Pop
  # hooks -----------------------
981 a8083063 Iustin Pop
982 3ecf6786 Iustin Pop
  @staticmethod
983 3ecf6786 Iustin Pop
  def perspective_hooks_runner(params):
984 3ecf6786 Iustin Pop
    """Run hook scripts.
985 3ecf6786 Iustin Pop

986 3ecf6786 Iustin Pop
    """
987 a8083063 Iustin Pop
    hpath, phase, env = params
988 a8083063 Iustin Pop
    hr = backend.HooksRunner()
989 a8083063 Iustin Pop
    return hr.RunHooks(hpath, phase, env)
990 a8083063 Iustin Pop
991 8d528b7c Iustin Pop
  # iallocator -----------------
992 8d528b7c Iustin Pop
993 8d528b7c Iustin Pop
  @staticmethod
994 8d528b7c Iustin Pop
  def perspective_iallocator_runner(params):
995 8d528b7c Iustin Pop
    """Run an iallocator script.
996 8d528b7c Iustin Pop

997 8d528b7c Iustin Pop
    """
998 0359e5d0 Spyros Trigazis
    name, idata, ial_params_dict = params
999 0359e5d0 Spyros Trigazis
    ial_params = []
1000 0359e5d0 Spyros Trigazis
    for ial_param in ial_params_dict.items():
1001 0359e5d0 Spyros Trigazis
      ial_params.append("--" + ial_param[0] + "=" + ial_param[1])
1002 8d528b7c Iustin Pop
    iar = backend.IAllocatorRunner()
1003 0359e5d0 Spyros Trigazis
    return iar.Run(name, idata, ial_params)
1004 8d528b7c Iustin Pop
1005 06009e27 Iustin Pop
  # test -----------------------
1006 06009e27 Iustin Pop
1007 06009e27 Iustin Pop
  @staticmethod
1008 06009e27 Iustin Pop
  def perspective_test_delay(params):
1009 06009e27 Iustin Pop
    """Run test delay.
1010 06009e27 Iustin Pop

1011 06009e27 Iustin Pop
    """
1012 06009e27 Iustin Pop
    duration = params[0]
1013 c26a6bd2 Iustin Pop
    status, rval = utils.TestDelay(duration)
1014 c26a6bd2 Iustin Pop
    if not status:
1015 c26a6bd2 Iustin Pop
      raise backend.RPCFail(rval)
1016 c26a6bd2 Iustin Pop
    return rval
1017 06009e27 Iustin Pop
1018 4e071d3b Iustin Pop
  # file storage ---------------
1019 4e071d3b Iustin Pop
1020 a5d7fb43 Manuel Franceschini
  @staticmethod
1021 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_create(params):
1022 a5d7fb43 Manuel Franceschini
    """Create the file storage directory.
1023 a5d7fb43 Manuel Franceschini

1024 a5d7fb43 Manuel Franceschini
    """
1025 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
1026 a5d7fb43 Manuel Franceschini
    return backend.CreateFileStorageDir(file_storage_dir)
1027 a5d7fb43 Manuel Franceschini
1028 a5d7fb43 Manuel Franceschini
  @staticmethod
1029 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_remove(params):
1030 a5d7fb43 Manuel Franceschini
    """Remove the file storage directory.
1031 a5d7fb43 Manuel Franceschini

1032 a5d7fb43 Manuel Franceschini
    """
1033 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
1034 a5d7fb43 Manuel Franceschini
    return backend.RemoveFileStorageDir(file_storage_dir)
1035 a5d7fb43 Manuel Franceschini
1036 a5d7fb43 Manuel Franceschini
  @staticmethod
1037 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_rename(params):
1038 a5d7fb43 Manuel Franceschini
    """Rename the file storage directory.
1039 a5d7fb43 Manuel Franceschini

1040 a5d7fb43 Manuel Franceschini
    """
1041 a5d7fb43 Manuel Franceschini
    old_file_storage_dir = params[0]
1042 a5d7fb43 Manuel Franceschini
    new_file_storage_dir = params[1]
1043 a5d7fb43 Manuel Franceschini
    return backend.RenameFileStorageDir(old_file_storage_dir,
1044 a5d7fb43 Manuel Franceschini
                                        new_file_storage_dir)
1045 a5d7fb43 Manuel Franceschini
1046 4e071d3b Iustin Pop
  # jobs ------------------------
1047 4e071d3b Iustin Pop
1048 ca52cdeb Michael Hanselmann
  @staticmethod
1049 7f30777b Michael Hanselmann
  @_RequireJobQueueLock
1050 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_update(params):
1051 ca52cdeb Michael Hanselmann
    """Update job queue.
1052 ca52cdeb Michael Hanselmann

1053 ca52cdeb Michael Hanselmann
    """
1054 ca52cdeb Michael Hanselmann
    (file_name, content) = params
1055 7f30777b Michael Hanselmann
    return backend.JobQueueUpdate(file_name, content)
1056 ca52cdeb Michael Hanselmann
1057 ca52cdeb Michael Hanselmann
  @staticmethod
1058 f1f3f45c Michael Hanselmann
  @_RequireJobQueueLock
1059 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_purge(params):
1060 ca52cdeb Michael Hanselmann
    """Purge job queue.
1061 ca52cdeb Michael Hanselmann

1062 ca52cdeb Michael Hanselmann
    """
1063 ca52cdeb Michael Hanselmann
    return backend.JobQueuePurge()
1064 ca52cdeb Michael Hanselmann
1065 af5ebcb1 Michael Hanselmann
  @staticmethod
1066 af5ebcb1 Michael Hanselmann
  @_RequireJobQueueLock
1067 af5ebcb1 Michael Hanselmann
  def perspective_jobqueue_rename(params):
1068 af5ebcb1 Michael Hanselmann
    """Rename a job queue file.
1069 af5ebcb1 Michael Hanselmann

1070 af5ebcb1 Michael Hanselmann
    """
1071 dd875d32 Michael Hanselmann
    # TODO: What if a file fails to rename?
1072 fb1ffbca Michael Hanselmann
    return [backend.JobQueueRename(old, new) for old, new in params[0]]
1073 af5ebcb1 Michael Hanselmann
1074 be6c403e Michael Hanselmann
  @staticmethod
1075 be6c403e Michael Hanselmann
  @_RequireJobQueueLock
1076 be6c403e Michael Hanselmann
  def perspective_jobqueue_set_drain_flag(params):
1077 be6c403e Michael Hanselmann
    """Set job queue's drain flag.
1078 be6c403e Michael Hanselmann

1079 be6c403e Michael Hanselmann
    """
1080 be6c403e Michael Hanselmann
    (flag, ) = params
1081 be6c403e Michael Hanselmann
1082 be6c403e Michael Hanselmann
    return jstore.SetDrainFlag(flag)
1083 be6c403e Michael Hanselmann
1084 6217e295 Iustin Pop
  # hypervisor ---------------
1085 6217e295 Iustin Pop
1086 6217e295 Iustin Pop
  @staticmethod
1087 6217e295 Iustin Pop
  def perspective_hypervisor_validate_params(params):
1088 6217e295 Iustin Pop
    """Validate the hypervisor parameters.
1089 6217e295 Iustin Pop

1090 6217e295 Iustin Pop
    """
1091 6217e295 Iustin Pop
    (hvname, hvparams) = params
1092 6217e295 Iustin Pop
    return backend.ValidateHVParams(hvname, hvparams)
1093 6217e295 Iustin Pop
1094 f942a838 Michael Hanselmann
  # Crypto
1095 f942a838 Michael Hanselmann
1096 f942a838 Michael Hanselmann
  @staticmethod
1097 ef40fbfb Michael Hanselmann
  def perspective_x509_cert_create(params):
1098 f942a838 Michael Hanselmann
    """Creates a new X509 certificate for SSL/TLS.
1099 f942a838 Michael Hanselmann

1100 f942a838 Michael Hanselmann
    """
1101 f942a838 Michael Hanselmann
    (validity, ) = params
1102 f942a838 Michael Hanselmann
    return backend.CreateX509Certificate(validity)
1103 f942a838 Michael Hanselmann
1104 f942a838 Michael Hanselmann
  @staticmethod
1105 ef40fbfb Michael Hanselmann
  def perspective_x509_cert_remove(params):
1106 f942a838 Michael Hanselmann
    """Removes a X509 certificate.
1107 f942a838 Michael Hanselmann

1108 f942a838 Michael Hanselmann
    """
1109 f942a838 Michael Hanselmann
    (name, ) = params
1110 f942a838 Michael Hanselmann
    return backend.RemoveX509Certificate(name)
1111 f942a838 Michael Hanselmann
1112 1651d116 Michael Hanselmann
  # Import and export
1113 1651d116 Michael Hanselmann
1114 1651d116 Michael Hanselmann
  @staticmethod
1115 ef40fbfb Michael Hanselmann
  def perspective_import_start(params):
1116 1651d116 Michael Hanselmann
    """Starts an import daemon.
1117 1651d116 Michael Hanselmann

1118 1651d116 Michael Hanselmann
    """
1119 b8c160c1 Michael Hanselmann
    (opts_s, instance, component, (dest, dest_args)) = params
1120 eb630f50 Michael Hanselmann
1121 eb630f50 Michael Hanselmann
    opts = objects.ImportExportOptions.FromDict(opts_s)
1122 eb630f50 Michael Hanselmann
1123 eb630f50 Michael Hanselmann
    return backend.StartImportExportDaemon(constants.IEM_IMPORT, opts,
1124 1651d116 Michael Hanselmann
                                           None, None,
1125 1651d116 Michael Hanselmann
                                           objects.Instance.FromDict(instance),
1126 6613661a Iustin Pop
                                           component, dest,
1127 1651d116 Michael Hanselmann
                                           _DecodeImportExportIO(dest,
1128 1651d116 Michael Hanselmann
                                                                 dest_args))
1129 eb630f50 Michael Hanselmann
1130 1651d116 Michael Hanselmann
  @staticmethod
1131 ef40fbfb Michael Hanselmann
  def perspective_export_start(params):
1132 1651d116 Michael Hanselmann
    """Starts an export daemon.
1133 1651d116 Michael Hanselmann

1134 1651d116 Michael Hanselmann
    """
1135 b8c160c1 Michael Hanselmann
    (opts_s, host, port, instance, component, (source, source_args)) = params
1136 eb630f50 Michael Hanselmann
1137 eb630f50 Michael Hanselmann
    opts = objects.ImportExportOptions.FromDict(opts_s)
1138 eb630f50 Michael Hanselmann
1139 eb630f50 Michael Hanselmann
    return backend.StartImportExportDaemon(constants.IEM_EXPORT, opts,
1140 1651d116 Michael Hanselmann
                                           host, port,
1141 1651d116 Michael Hanselmann
                                           objects.Instance.FromDict(instance),
1142 6613661a Iustin Pop
                                           component, source,
1143 1651d116 Michael Hanselmann
                                           _DecodeImportExportIO(source,
1144 1651d116 Michael Hanselmann
                                                                 source_args))
1145 1651d116 Michael Hanselmann
1146 1651d116 Michael Hanselmann
  @staticmethod
1147 ef40fbfb Michael Hanselmann
  def perspective_impexp_status(params):
1148 1651d116 Michael Hanselmann
    """Retrieves the status of an import or export daemon.
1149 1651d116 Michael Hanselmann

1150 1651d116 Michael Hanselmann
    """
1151 1651d116 Michael Hanselmann
    return backend.GetImportExportStatus(params[0])
1152 1651d116 Michael Hanselmann
1153 1651d116 Michael Hanselmann
  @staticmethod
1154 f81c4737 Michael Hanselmann
  def perspective_impexp_abort(params):
1155 f81c4737 Michael Hanselmann
    """Aborts an import or export.
1156 f81c4737 Michael Hanselmann

1157 f81c4737 Michael Hanselmann
    """
1158 f81c4737 Michael Hanselmann
    return backend.AbortImportExport(params[0])
1159 f81c4737 Michael Hanselmann
1160 f81c4737 Michael Hanselmann
  @staticmethod
1161 ef40fbfb Michael Hanselmann
  def perspective_impexp_cleanup(params):
1162 1651d116 Michael Hanselmann
    """Cleans up after an import or export.
1163 1651d116 Michael Hanselmann

1164 1651d116 Michael Hanselmann
    """
1165 1651d116 Michael Hanselmann
    return backend.CleanupImportExport(params[0])
1166 1651d116 Michael Hanselmann
1167 a8083063 Iustin Pop
1168 f93427cd Iustin Pop
def CheckNoded(_, args):
1169 f93427cd Iustin Pop
  """Initial checks whether to run or exit with a failure.
1170 f93427cd Iustin Pop

1171 f93427cd Iustin Pop
  """
1172 f93427cd Iustin Pop
  if args: # noded doesn't take any arguments
1173 f93427cd Iustin Pop
    print >> sys.stderr, ("Usage: %s [-f] [-d] [-p port] [-b ADDRESS]" %
1174 f93427cd Iustin Pop
                          sys.argv[0])
1175 f93427cd Iustin Pop
    sys.exit(constants.EXIT_FAILURE)
1176 f01738fc Iustin Pop
  try:
1177 f01738fc Iustin Pop
    codecs.lookup("string-escape")
1178 f01738fc Iustin Pop
  except LookupError:
1179 f01738fc Iustin Pop
    print >> sys.stderr, ("Can't load the string-escape code which is part"
1180 f01738fc Iustin Pop
                          " of the Python installation. Is your installation"
1181 f01738fc Iustin Pop
                          " complete/correct? Aborting.")
1182 f01738fc Iustin Pop
    sys.exit(constants.EXIT_FAILURE)
1183 f93427cd Iustin Pop
1184 f93427cd Iustin Pop
1185 b3cc1646 Helga Velroyen
def SSLVerifyPeer(conn, cert, errnum, errdepth, ok):
1186 b3cc1646 Helga Velroyen
  """Callback function to verify a peer against the candidate cert map.
1187 b3cc1646 Helga Velroyen

1188 b3cc1646 Helga Velroyen
  Note that we have a chicken-and-egg problem during cluster init and upgrade.
1189 b3cc1646 Helga Velroyen
  This method checks whether the incoming connection comes from a master
1190 b3cc1646 Helga Velroyen
  candidate by comparing it to the master certificate map in the cluster
1191 b3cc1646 Helga Velroyen
  configuration. However, during cluster init and cluster upgrade there
1192 b3cc1646 Helga Velroyen
  are various RPC calls done to the master node itself, before the candidate
1193 b3cc1646 Helga Velroyen
  certificate list is established and the cluster configuration is written.
1194 b3cc1646 Helga Velroyen
  In this case, we cannot check against the master candidate map.
1195 b3cc1646 Helga Velroyen

1196 b3cc1646 Helga Velroyen
  This problem is solved by checking whether the candidate map is empty. An
1197 b3cc1646 Helga Velroyen
  initialized 2.11 or higher cluster has at least one entry for the master
1198 b3cc1646 Helga Velroyen
  node in the candidate map. If the map is empty, we know that we are still
1199 b3cc1646 Helga Velroyen
  in the bootstrap/upgrade phase. In this case, we read the server certificate
1200 b3cc1646 Helga Velroyen
  digest and compare it to the incoming request.
1201 b3cc1646 Helga Velroyen

1202 b3cc1646 Helga Velroyen
  This means that after an upgrade of Ganeti, the system continues to operate
1203 b3cc1646 Helga Velroyen
  like before, using server certificates only. After the client certificates
1204 b3cc1646 Helga Velroyen
  are generated with ``gnt-cluster renew-crypto --new-node-certificates``,
1205 b3cc1646 Helga Velroyen
  RPC communication is switched to using client certificates and the trick of
1206 b3cc1646 Helga Velroyen
  using server certificates does not work anymore.
1207 b3cc1646 Helga Velroyen

1208 b3cc1646 Helga Velroyen
  @type conn: C{OpenSSL.SSL.Connection}
1209 b3cc1646 Helga Velroyen
  @param conn: the OpenSSL connection object
1210 b3cc1646 Helga Velroyen
  @type cert: C{OpenSSL.X509}
1211 b3cc1646 Helga Velroyen
  @param cert: the peer's SSL certificate
1212 b3cc1646 Helga Velroyen

1213 b3cc1646 Helga Velroyen
  """
1214 b3cc1646 Helga Velroyen
  # some parameters are unused, but this is the API
1215 b3cc1646 Helga Velroyen
  # pylint: disable=W0613
1216 b3cc1646 Helga Velroyen
  _BOOTSTRAP = "bootstrap"
1217 b3cc1646 Helga Velroyen
  sstore = ssconf.SimpleStore()
1218 b3cc1646 Helga Velroyen
  try:
1219 b3cc1646 Helga Velroyen
    candidate_certs = sstore.GetMasterCandidatesCertMap()
1220 ed748771 Helga Velroyen
  except errors.ConfigurationError:
1221 b3cc1646 Helga Velroyen
    logging.info("No candidate certificates found. Switching to "
1222 b3cc1646 Helga Velroyen
                 "bootstrap/update mode.")
1223 b3cc1646 Helga Velroyen
    candidate_certs = None
1224 b3cc1646 Helga Velroyen
  if not candidate_certs:
1225 b3cc1646 Helga Velroyen
    candidate_certs = {
1226 b3cc1646 Helga Velroyen
      _BOOTSTRAP: utils.GetCertificateDigest(
1227 b3cc1646 Helga Velroyen
        cert_filename=pathutils.NODED_CERT_FILE)}
1228 b3cc1646 Helga Velroyen
  return cert.digest("sha1") in candidate_certs.values()
1229 b3cc1646 Helga Velroyen
  # pylint: enable=W0613
1230 b3cc1646 Helga Velroyen
1231 b3cc1646 Helga Velroyen
1232 3ee53f1f Iustin Pop
def PrepNoded(options, _):
1233 3ee53f1f Iustin Pop
  """Preparation node daemon function, executed with the PID file held.
1234 3ecf6786 Iustin Pop

1235 3ecf6786 Iustin Pop
  """
1236 bebf68d3 Guido Trotter
  if options.mlock:
1237 bebf68d3 Guido Trotter
    request_executor_class = MlockallRequestExecutor
1238 4c32a8bd Luca Bigliardi
    try:
1239 4c32a8bd Luca Bigliardi
      utils.Mlockall()
1240 4c32a8bd Luca Bigliardi
    except errors.NoCtypesError:
1241 4c32a8bd Luca Bigliardi
      logging.warning("Cannot set memory lock, ctypes module not found")
1242 4c32a8bd Luca Bigliardi
      request_executor_class = http.server.HttpServerRequestExecutor
1243 bebf68d3 Guido Trotter
  else:
1244 bebf68d3 Guido Trotter
    request_executor_class = http.server.HttpServerRequestExecutor
1245 02bea2fc Luca Bigliardi
1246 04ccf5e9 Guido Trotter
  # Read SSL certificate
1247 3b1b0cb6 Guido Trotter
  if options.ssl:
1248 3b1b0cb6 Guido Trotter
    ssl_params = http.HttpSslParams(ssl_key_path=options.ssl_key,
1249 3b1b0cb6 Guido Trotter
                                    ssl_cert_path=options.ssl_cert)
1250 3b1b0cb6 Guido Trotter
  else:
1251 3b1b0cb6 Guido Trotter
    ssl_params = None
1252 7d88772a Iustin Pop
1253 81198f6e Iustin Pop
  err = _PrepareQueueLock()
1254 81198f6e Iustin Pop
  if err is not None:
1255 81198f6e Iustin Pop
    # this might be some kind of file-system/permission error; while
1256 81198f6e Iustin Pop
    # this breaks the job queue functionality, we shouldn't prevent
1257 81198f6e Iustin Pop
    # startup of the whole node daemon because of this
1258 81198f6e Iustin Pop
    logging.critical("Can't init/verify the queue, proceeding anyway: %s", err)
1259 7d88772a Iustin Pop
1260 e0003509 Michael Hanselmann
  handler = NodeRequestHandler()
1261 e0003509 Michael Hanselmann
1262 04ccf5e9 Guido Trotter
  mainloop = daemon.Mainloop()
1263 e0003509 Michael Hanselmann
  server = \
1264 e0003509 Michael Hanselmann
    http.server.HttpServer(mainloop, options.bind_address, options.port,
1265 5ae4945a Iustin Pop
                           handler, ssl_params=ssl_params, ssl_verify_peer=True,
1266 b3cc1646 Helga Velroyen
                           request_executor_class=request_executor_class,
1267 b3cc1646 Helga Velroyen
                           ssl_verify_callback=SSLVerifyPeer)
1268 04ccf5e9 Guido Trotter
  server.Start()
1269 e0003509 Michael Hanselmann
1270 3ee53f1f Iustin Pop
  return (mainloop, server)
1271 3ee53f1f Iustin Pop
1272 5119f2ec Michael Hanselmann
1273 b459a848 Andrea Spadaccini
def ExecNoded(options, args, prep_data): # pylint: disable=W0613
1274 3ee53f1f Iustin Pop
  """Main node daemon function, executed with the PID file held.
1275 3ee53f1f Iustin Pop

1276 3ee53f1f Iustin Pop
  """
1277 3ee53f1f Iustin Pop
  (mainloop, server) = prep_data
1278 04ccf5e9 Guido Trotter
  try:
1279 04ccf5e9 Guido Trotter
    mainloop.Run()
1280 04ccf5e9 Guido Trotter
  finally:
1281 04ccf5e9 Guido Trotter
    server.Stop()
1282 a8083063 Iustin Pop
1283 a8083063 Iustin Pop
1284 5119f2ec Michael Hanselmann
def Main():
1285 04ccf5e9 Guido Trotter
  """Main function for the node daemon.
1286 04ccf5e9 Guido Trotter

1287 04ccf5e9 Guido Trotter
  """
1288 04ccf5e9 Guido Trotter
  parser = OptionParser(description="Ganeti node daemon",
1289 b01d9504 Michele Tartara
                        usage=("%prog [-f] [-d] [-p port] [-b ADDRESS]"
1290 b01d9504 Michele Tartara
                               " [-i INTERFACE]"),
1291 04ccf5e9 Guido Trotter
                        version="%%prog (ganeti) %s" %
1292 04ccf5e9 Guido Trotter
                        constants.RELEASE_VERSION)
1293 bebf68d3 Guido Trotter
  parser.add_option("--no-mlock", dest="mlock",
1294 bebf68d3 Guido Trotter
                    help="Do not mlock the node memory in ram",
1295 bebf68d3 Guido Trotter
                    default=True, action="store_false")
1296 bebf68d3 Guido Trotter
1297 3ee53f1f Iustin Pop
  daemon.GenericMain(constants.NODED, parser, CheckNoded, PrepNoded, ExecNoded,
1298 a5ce2ea2 Michael Hanselmann
                     default_ssl_cert=pathutils.NODED_CERT_FILE,
1299 a5ce2ea2 Michael Hanselmann
                     default_ssl_key=pathutils.NODED_CERT_FILE,
1300 565083ef Luca Bigliardi
                     console_logging=True)