Statistics
| Branch: | Tag: | Revision:

root / lib / server / noded.py @ abd66bf8

History | View | Annotate | Download (27.2 kB)

1 69cf3abd Michael Hanselmann
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 c417e115 Iustin Pop
# Copyright (C) 2006, 2007, 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 a8083063 Iustin Pop
"""Ganeti node daemon"""
23 a8083063 Iustin Pop
24 7260cfbe Iustin Pop
# pylint: disable-msg=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 a8083063 Iustin Pop
37 a8083063 Iustin Pop
from optparse import OptionParser
38 a8083063 Iustin Pop
39 a8083063 Iustin Pop
from ganeti import backend
40 a8083063 Iustin Pop
from ganeti import constants
41 a8083063 Iustin Pop
from ganeti import objects
42 a8083063 Iustin Pop
from ganeti import errors
43 25d6d12a Michael Hanselmann
from ganeti import jstore
44 cc28af80 Michael Hanselmann
from ganeti import daemon
45 1df6506c Michael Hanselmann
from ganeti import http
46 16abfbc2 Alexander Schreiber
from ganeti import utils
47 e337de97 Michael Hanselmann
from ganeti import storage
48 ab221ddf Michael Hanselmann
from ganeti import serializer
49 a744b676 Manuel Franceschini
from ganeti import netutils
50 a8083063 Iustin Pop
51 30e4e741 Iustin Pop
import ganeti.http.server # pylint: disable-msg=W0611
52 19205c39 Michael Hanselmann
53 a8083063 Iustin Pop
54 25d6d12a Michael Hanselmann
queue_lock = None
55 25d6d12a Michael Hanselmann
56 25d6d12a Michael Hanselmann
57 81198f6e Iustin Pop
def _PrepareQueueLock():
58 81198f6e Iustin Pop
  """Try to prepare the queue lock.
59 81198f6e Iustin Pop

60 81198f6e Iustin Pop
  @return: None for success, otherwise an exception object
61 81198f6e Iustin Pop

62 81198f6e Iustin Pop
  """
63 81198f6e Iustin Pop
  global queue_lock # pylint: disable-msg=W0603
64 81198f6e Iustin Pop
65 81198f6e Iustin Pop
  if queue_lock is not None:
66 81198f6e Iustin Pop
    return None
67 81198f6e Iustin Pop
68 81198f6e Iustin Pop
  # Prepare job queue
69 81198f6e Iustin Pop
  try:
70 81198f6e Iustin Pop
    queue_lock = jstore.InitAndVerifyQueue(must_lock=False)
71 81198f6e Iustin Pop
    return None
72 81198f6e Iustin Pop
  except EnvironmentError, err:
73 81198f6e Iustin Pop
    return err
74 81198f6e Iustin Pop
75 81198f6e Iustin Pop
76 7f30777b Michael Hanselmann
def _RequireJobQueueLock(fn):
77 7f30777b Michael Hanselmann
  """Decorator for job queue manipulating functions.
78 7f30777b Michael Hanselmann

79 7f30777b Michael Hanselmann
  """
80 8785cb30 Michael Hanselmann
  QUEUE_LOCK_TIMEOUT = 10
81 8785cb30 Michael Hanselmann
82 7f30777b Michael Hanselmann
  def wrapper(*args, **kwargs):
83 7f30777b Michael Hanselmann
    # Locking in exclusive, blocking mode because there could be several
84 506cff12 Michael Hanselmann
    # children running at the same time. Waiting up to 10 seconds.
85 81198f6e Iustin Pop
    if _PrepareQueueLock() is not None:
86 81198f6e Iustin Pop
      raise errors.JobQueueError("Job queue failed initialization,"
87 81198f6e Iustin Pop
                                 " cannot update jobs")
88 8785cb30 Michael Hanselmann
    queue_lock.Exclusive(blocking=True, timeout=QUEUE_LOCK_TIMEOUT)
89 7f30777b Michael Hanselmann
    try:
90 7f30777b Michael Hanselmann
      return fn(*args, **kwargs)
91 7f30777b Michael Hanselmann
    finally:
92 7f30777b Michael Hanselmann
      queue_lock.Unlock()
93 8785cb30 Michael Hanselmann
94 7f30777b Michael Hanselmann
  return wrapper
95 7f30777b Michael Hanselmann
96 7f30777b Michael Hanselmann
97 1651d116 Michael Hanselmann
def _DecodeImportExportIO(ieio, ieioargs):
98 1651d116 Michael Hanselmann
  """Decodes import/export I/O information.
99 1651d116 Michael Hanselmann

100 1651d116 Michael Hanselmann
  """
101 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_RAW_DISK:
102 1651d116 Michael Hanselmann
    assert len(ieioargs) == 1
103 1651d116 Michael Hanselmann
    return (objects.Disk.FromDict(ieioargs[0]), )
104 1651d116 Michael Hanselmann
105 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_SCRIPT:
106 1651d116 Michael Hanselmann
    assert len(ieioargs) == 2
107 1651d116 Michael Hanselmann
    return (objects.Disk.FromDict(ieioargs[0]), ieioargs[1])
108 1651d116 Michael Hanselmann
109 1651d116 Michael Hanselmann
  return ieioargs
110 1651d116 Michael Hanselmann
111 1651d116 Michael Hanselmann
112 38b77287 Luca Bigliardi
class MlockallRequestExecutor(http.server.HttpServerRequestExecutor):
113 38b77287 Luca Bigliardi
  """Custom Request Executor class that ensures NodeHttpServer children are
114 38b77287 Luca Bigliardi
  locked in ram.
115 38b77287 Luca Bigliardi

116 38b77287 Luca Bigliardi
  """
117 38b77287 Luca Bigliardi
  def __init__(self, *args, **kwargs):
118 38b77287 Luca Bigliardi
    utils.Mlockall()
119 38b77287 Luca Bigliardi
120 38b77287 Luca Bigliardi
    http.server.HttpServerRequestExecutor.__init__(self, *args, **kwargs)
121 38b77287 Luca Bigliardi
122 38b77287 Luca Bigliardi
123 19205c39 Michael Hanselmann
class NodeHttpServer(http.server.HttpServer):
124 3ecf6786 Iustin Pop
  """The server implementation.
125 3ecf6786 Iustin Pop

126 3ecf6786 Iustin Pop
  This class holds all methods exposed over the RPC interface.
127 3ecf6786 Iustin Pop

128 3ecf6786 Iustin Pop
  """
129 2d54e29c Iustin Pop
  # too many public methods, and unused args - all methods get params
130 2d54e29c Iustin Pop
  # due to the API
131 2d54e29c Iustin Pop
  # pylint: disable-msg=R0904,W0613
132 cc28af80 Michael Hanselmann
  def __init__(self, *args, **kwargs):
133 19205c39 Michael Hanselmann
    http.server.HttpServer.__init__(self, *args, **kwargs)
134 cc28af80 Michael Hanselmann
    self.noded_pid = os.getpid()
135 cc28af80 Michael Hanselmann
136 cc28af80 Michael Hanselmann
  def HandleRequest(self, req):
137 1df6506c Michael Hanselmann
    """Handle a request.
138 a8083063 Iustin Pop

139 098c0958 Michael Hanselmann
    """
140 19205c39 Michael Hanselmann
    if req.request_method.upper() != http.HTTP_PUT:
141 84f2756e Michael Hanselmann
      raise http.HttpBadRequest()
142 1df6506c Michael Hanselmann
143 cc28af80 Michael Hanselmann
    path = req.request_path
144 81010134 Iustin Pop
    if path.startswith("/"):
145 81010134 Iustin Pop
      path = path[1:]
146 81010134 Iustin Pop
147 1df6506c Michael Hanselmann
    method = getattr(self, "perspective_%s" % path, None)
148 1df6506c Michael Hanselmann
    if method is None:
149 84f2756e Michael Hanselmann
      raise http.HttpNotFound()
150 a8083063 Iustin Pop
151 81010134 Iustin Pop
    try:
152 ab221ddf Michael Hanselmann
      result = (True, method(serializer.LoadJson(req.request_body)))
153 4dd42c9d Iustin Pop
154 0623d351 Iustin Pop
    except backend.RPCFail, err:
155 0623d351 Iustin Pop
      # our custom failure exception; str(err) works fine if the
156 0623d351 Iustin Pop
      # exception was constructed with a single argument, and in
157 0623d351 Iustin Pop
      # this case, err.message == err.args[0] == str(err)
158 ab221ddf Michael Hanselmann
      result = (False, str(err))
159 9ae49f27 Guido Trotter
    except errors.QuitGanetiException, err:
160 84b58db2 Michael Hanselmann
      # Tell parent to quit
161 0623d351 Iustin Pop
      logging.info("Shutting down the node daemon, arguments: %s",
162 0623d351 Iustin Pop
                   str(err.args))
163 cc28af80 Michael Hanselmann
      os.kill(self.noded_pid, signal.SIGTERM)
164 0623d351 Iustin Pop
      # And return the error's arguments, which must be already in
165 0623d351 Iustin Pop
      # correct tuple format
166 ab221ddf Michael Hanselmann
      result = err.args
167 4dd42c9d Iustin Pop
    except Exception, err:
168 0623d351 Iustin Pop
      logging.exception("Error in RPC call")
169 ab221ddf Michael Hanselmann
      result = (False, "Error while executing backend function: %s" % str(err))
170 ab221ddf Michael Hanselmann
171 ab221ddf Michael Hanselmann
    return serializer.DumpJson(result, indent=False)
172 a8083063 Iustin Pop
173 a8083063 Iustin Pop
  # the new block devices  --------------------------
174 a8083063 Iustin Pop
175 3ecf6786 Iustin Pop
  @staticmethod
176 3ecf6786 Iustin Pop
  def perspective_blockdev_create(params):
177 3ecf6786 Iustin Pop
    """Create a block device.
178 3ecf6786 Iustin Pop

179 3ecf6786 Iustin Pop
    """
180 3f78eef2 Iustin Pop
    bdev_s, size, owner, on_primary, info = params
181 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
182 a8083063 Iustin Pop
    if bdev is None:
183 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
184 821d1bd1 Iustin Pop
    return backend.BlockdevCreate(bdev, size, owner, on_primary, info)
185 a8083063 Iustin Pop
186 3ecf6786 Iustin Pop
  @staticmethod
187 9c007da8 René Nussbaumer
  def perspective_blockdev_pause_resume_sync(params):
188 9c007da8 René Nussbaumer
    """Pause/resume sync of a block device.
189 9c007da8 René Nussbaumer

190 9c007da8 René Nussbaumer
    """
191 9c007da8 René Nussbaumer
    disks_s, pause = params
192 9c007da8 René Nussbaumer
    disks = [objects.Disk.FromDict(bdev_s) for bdev_s in disks_s]
193 9c007da8 René Nussbaumer
    return backend.BlockdevPauseResumeSync(disks, pause)
194 9c007da8 René Nussbaumer
195 9c007da8 René Nussbaumer
  @staticmethod
196 271b7cf9 René Nussbaumer
  def perspective_blockdev_wipe(params):
197 271b7cf9 René Nussbaumer
    """Wipe a block device.
198 271b7cf9 René Nussbaumer

199 271b7cf9 René Nussbaumer
    """
200 271b7cf9 René Nussbaumer
    bdev_s, offset, size = params
201 271b7cf9 René Nussbaumer
    bdev = objects.Disk.FromDict(bdev_s)
202 271b7cf9 René Nussbaumer
    return backend.BlockdevWipe(bdev, offset, size)
203 271b7cf9 René Nussbaumer
204 271b7cf9 René Nussbaumer
  @staticmethod
205 3ecf6786 Iustin Pop
  def perspective_blockdev_remove(params):
206 3ecf6786 Iustin Pop
    """Remove a block device.
207 3ecf6786 Iustin Pop

208 3ecf6786 Iustin Pop
    """
209 a8083063 Iustin Pop
    bdev_s = params[0]
210 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
211 821d1bd1 Iustin Pop
    return backend.BlockdevRemove(bdev)
212 a8083063 Iustin Pop
213 3ecf6786 Iustin Pop
  @staticmethod
214 f3e513ad Iustin Pop
  def perspective_blockdev_rename(params):
215 f3e513ad Iustin Pop
    """Remove a block device.
216 f3e513ad Iustin Pop

217 f3e513ad Iustin Pop
    """
218 f3e513ad Iustin Pop
    devlist = [(objects.Disk.FromDict(ds), uid) for ds, uid in params]
219 821d1bd1 Iustin Pop
    return backend.BlockdevRename(devlist)
220 f3e513ad Iustin Pop
221 f3e513ad Iustin Pop
  @staticmethod
222 3ecf6786 Iustin Pop
  def perspective_blockdev_assemble(params):
223 3ecf6786 Iustin Pop
    """Assemble a block device.
224 3ecf6786 Iustin Pop

225 3ecf6786 Iustin Pop
    """
226 c417e115 Iustin Pop
    bdev_s, owner, on_primary, idx = params
227 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
228 a8083063 Iustin Pop
    if bdev is None:
229 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
230 c417e115 Iustin Pop
    return backend.BlockdevAssemble(bdev, owner, on_primary, idx)
231 a8083063 Iustin Pop
232 3ecf6786 Iustin Pop
  @staticmethod
233 3ecf6786 Iustin Pop
  def perspective_blockdev_shutdown(params):
234 3ecf6786 Iustin Pop
    """Shutdown a block device.
235 3ecf6786 Iustin Pop

236 3ecf6786 Iustin Pop
    """
237 a8083063 Iustin Pop
    bdev_s = params[0]
238 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
239 a8083063 Iustin Pop
    if bdev is None:
240 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
241 821d1bd1 Iustin Pop
    return backend.BlockdevShutdown(bdev)
242 a8083063 Iustin Pop
243 3ecf6786 Iustin Pop
  @staticmethod
244 153d9724 Iustin Pop
  def perspective_blockdev_addchildren(params):
245 3ecf6786 Iustin Pop
    """Add a child to a mirror device.
246 3ecf6786 Iustin Pop

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

250 3ecf6786 Iustin Pop
    """
251 a8083063 Iustin Pop
    bdev_s, ndev_s = params
252 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
253 153d9724 Iustin Pop
    ndevs = [objects.Disk.FromDict(disk_s) for disk_s in ndev_s]
254 153d9724 Iustin Pop
    if bdev is None or ndevs.count(None) > 0:
255 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
256 821d1bd1 Iustin Pop
    return backend.BlockdevAddchildren(bdev, ndevs)
257 a8083063 Iustin Pop
258 3ecf6786 Iustin Pop
  @staticmethod
259 153d9724 Iustin Pop
  def perspective_blockdev_removechildren(params):
260 3ecf6786 Iustin Pop
    """Remove a child from a mirror device.
261 3ecf6786 Iustin Pop

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

265 3ecf6786 Iustin Pop
    """
266 a8083063 Iustin Pop
    bdev_s, ndev_s = params
267 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
268 153d9724 Iustin Pop
    ndevs = [objects.Disk.FromDict(disk_s) for disk_s in ndev_s]
269 153d9724 Iustin Pop
    if bdev is None or ndevs.count(None) > 0:
270 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
271 821d1bd1 Iustin Pop
    return backend.BlockdevRemovechildren(bdev, ndevs)
272 a8083063 Iustin Pop
273 3ecf6786 Iustin Pop
  @staticmethod
274 3ecf6786 Iustin Pop
  def perspective_blockdev_getmirrorstatus(params):
275 3ecf6786 Iustin Pop
    """Return the mirror status for a list of disks.
276 3ecf6786 Iustin Pop

277 3ecf6786 Iustin Pop
    """
278 319856a9 Michael Hanselmann
    disks = [objects.Disk.FromDict(dsk_s)
279 36145b12 Michael Hanselmann
             for dsk_s in params]
280 36145b12 Michael Hanselmann
    return [status.ToDict()
281 36145b12 Michael Hanselmann
            for status in backend.BlockdevGetmirrorstatus(disks)]
282 a8083063 Iustin Pop
283 3ecf6786 Iustin Pop
  @staticmethod
284 b8d26c6e Michael Hanselmann
  def perspective_blockdev_getmirrorstatus_multi(params):
285 b8d26c6e Michael Hanselmann
    """Return the mirror status for a list of disks.
286 b8d26c6e Michael Hanselmann

287 b8d26c6e Michael Hanselmann
    """
288 b8d26c6e Michael Hanselmann
    (node_disks, ) = params
289 b8d26c6e Michael Hanselmann
290 b8d26c6e Michael Hanselmann
    node_name = netutils.Hostname.GetSysName()
291 b8d26c6e Michael Hanselmann
292 b8d26c6e Michael Hanselmann
    disks = [objects.Disk.FromDict(dsk_s)
293 b8d26c6e Michael Hanselmann
             for dsk_s in node_disks.get(node_name, [])]
294 b8d26c6e Michael Hanselmann
295 c6a9dffa Michael Hanselmann
    result = []
296 c6a9dffa Michael Hanselmann
297 c6a9dffa Michael Hanselmann
    for (success, status) in backend.BlockdevGetmirrorstatusMulti(disks):
298 c6a9dffa Michael Hanselmann
      if success:
299 c6a9dffa Michael Hanselmann
        result.append((success, status.ToDict()))
300 c6a9dffa Michael Hanselmann
      else:
301 c6a9dffa Michael Hanselmann
        result.append((success, status))
302 c6a9dffa Michael Hanselmann
303 c6a9dffa Michael Hanselmann
    return result
304 b8d26c6e Michael Hanselmann
305 b8d26c6e Michael Hanselmann
  @staticmethod
306 3ecf6786 Iustin Pop
  def perspective_blockdev_find(params):
307 3ecf6786 Iustin Pop
    """Expose the FindBlockDevice functionality for a disk.
308 3ecf6786 Iustin Pop

309 3ecf6786 Iustin Pop
    This will try to find but not activate a disk.
310 3ecf6786 Iustin Pop

311 3ecf6786 Iustin Pop
    """
312 319856a9 Michael Hanselmann
    disk = objects.Disk.FromDict(params[0])
313 ddfe2228 Michael Hanselmann
314 ddfe2228 Michael Hanselmann
    result = backend.BlockdevFind(disk)
315 ddfe2228 Michael Hanselmann
    if result is None:
316 ddfe2228 Michael Hanselmann
      return None
317 ddfe2228 Michael Hanselmann
318 ddfe2228 Michael Hanselmann
    return result.ToDict()
319 a8083063 Iustin Pop
320 3ecf6786 Iustin Pop
  @staticmethod
321 3ecf6786 Iustin Pop
  def perspective_blockdev_snapshot(params):
322 3ecf6786 Iustin Pop
    """Create a snapshot device.
323 3ecf6786 Iustin Pop

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

328 3ecf6786 Iustin Pop
    """
329 319856a9 Michael Hanselmann
    cfbd = objects.Disk.FromDict(params[0])
330 821d1bd1 Iustin Pop
    return backend.BlockdevSnapshot(cfbd)
331 a8083063 Iustin Pop
332 4c8ba8b3 Iustin Pop
  @staticmethod
333 4c8ba8b3 Iustin Pop
  def perspective_blockdev_grow(params):
334 4c8ba8b3 Iustin Pop
    """Grow a stack of devices.
335 4c8ba8b3 Iustin Pop

336 4c8ba8b3 Iustin Pop
    """
337 4c8ba8b3 Iustin Pop
    cfbd = objects.Disk.FromDict(params[0])
338 4c8ba8b3 Iustin Pop
    amount = params[1]
339 821d1bd1 Iustin Pop
    return backend.BlockdevGrow(cfbd, amount)
340 4c8ba8b3 Iustin Pop
341 d61cbe76 Iustin Pop
  @staticmethod
342 d61cbe76 Iustin Pop
  def perspective_blockdev_close(params):
343 d61cbe76 Iustin Pop
    """Closes the given block devices.
344 d61cbe76 Iustin Pop

345 d61cbe76 Iustin Pop
    """
346 b2e7666a Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in params[1]]
347 821d1bd1 Iustin Pop
    return backend.BlockdevClose(params[0], disks)
348 d61cbe76 Iustin Pop
349 968a7623 Iustin Pop
  @staticmethod
350 968a7623 Iustin Pop
  def perspective_blockdev_getsize(params):
351 968a7623 Iustin Pop
    """Compute the sizes of the given block devices.
352 968a7623 Iustin Pop

353 968a7623 Iustin Pop
    """
354 968a7623 Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in params[0]]
355 968a7623 Iustin Pop
    return backend.BlockdevGetsize(disks)
356 968a7623 Iustin Pop
357 858f3d18 Iustin Pop
  @staticmethod
358 858f3d18 Iustin Pop
  def perspective_blockdev_export(params):
359 858f3d18 Iustin Pop
    """Compute the sizes of the given block devices.
360 858f3d18 Iustin Pop

361 858f3d18 Iustin Pop
    """
362 858f3d18 Iustin Pop
    disk = objects.Disk.FromDict(params[0])
363 858f3d18 Iustin Pop
    dest_node, dest_path, cluster_name = params[1:]
364 858f3d18 Iustin Pop
    return backend.BlockdevExport(disk, dest_node, dest_path, cluster_name)
365 858f3d18 Iustin Pop
366 6b93ec9d Iustin Pop
  # blockdev/drbd specific methods ----------
367 6b93ec9d Iustin Pop
368 6b93ec9d Iustin Pop
  @staticmethod
369 6b93ec9d Iustin Pop
  def perspective_drbd_disconnect_net(params):
370 6b93ec9d Iustin Pop
    """Disconnects the network connection of drbd disks.
371 6b93ec9d Iustin Pop

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

375 6b93ec9d Iustin Pop
    """
376 6b93ec9d Iustin Pop
    nodes_ip, disks = params
377 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
378 6b93ec9d Iustin Pop
    return backend.DrbdDisconnectNet(nodes_ip, disks)
379 6b93ec9d Iustin Pop
380 6b93ec9d Iustin Pop
  @staticmethod
381 6b93ec9d Iustin Pop
  def perspective_drbd_attach_net(params):
382 6b93ec9d Iustin Pop
    """Attaches the network connection of drbd disks.
383 6b93ec9d Iustin Pop

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

387 6b93ec9d Iustin Pop
    """
388 6b93ec9d Iustin Pop
    nodes_ip, disks, instance_name, multimaster = params
389 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
390 821d1bd1 Iustin Pop
    return backend.DrbdAttachNet(nodes_ip, disks,
391 821d1bd1 Iustin Pop
                                     instance_name, multimaster)
392 6b93ec9d Iustin Pop
393 6b93ec9d Iustin Pop
  @staticmethod
394 6b93ec9d Iustin Pop
  def perspective_drbd_wait_sync(params):
395 6b93ec9d Iustin Pop
    """Wait until DRBD disks are synched.
396 6b93ec9d Iustin Pop

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

400 6b93ec9d Iustin Pop
    """
401 6b93ec9d Iustin Pop
    nodes_ip, disks = params
402 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
403 6b93ec9d Iustin Pop
    return backend.DrbdWaitSync(nodes_ip, disks)
404 6b93ec9d Iustin Pop
405 c46b9782 Luca Bigliardi
  @staticmethod
406 c46b9782 Luca Bigliardi
  def perspective_drbd_helper(params):
407 c46b9782 Luca Bigliardi
    """Query drbd helper.
408 c46b9782 Luca Bigliardi

409 c46b9782 Luca Bigliardi
    """
410 c46b9782 Luca Bigliardi
    return backend.GetDrbdUsermodeHelper()
411 c46b9782 Luca Bigliardi
412 a8083063 Iustin Pop
  # export/import  --------------------------
413 a8083063 Iustin Pop
414 3ecf6786 Iustin Pop
  @staticmethod
415 3ecf6786 Iustin Pop
  def perspective_finalize_export(params):
416 3ecf6786 Iustin Pop
    """Expose the finalize export functionality.
417 a8083063 Iustin Pop

418 3ecf6786 Iustin Pop
    """
419 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
420 7b651654 Michael Hanselmann
421 7b651654 Michael Hanselmann
    snap_disks = []
422 7b651654 Michael Hanselmann
    for disk in params[1]:
423 7b651654 Michael Hanselmann
      if isinstance(disk, bool):
424 7b651654 Michael Hanselmann
        snap_disks.append(disk)
425 7b651654 Michael Hanselmann
      else:
426 7b651654 Michael Hanselmann
        snap_disks.append(objects.Disk.FromDict(disk))
427 7b651654 Michael Hanselmann
428 a8083063 Iustin Pop
    return backend.FinalizeExport(instance, snap_disks)
429 a8083063 Iustin Pop
430 3ecf6786 Iustin Pop
  @staticmethod
431 3ecf6786 Iustin Pop
  def perspective_export_info(params):
432 3ecf6786 Iustin Pop
    """Query information about an existing export on this node.
433 3ecf6786 Iustin Pop

434 3ecf6786 Iustin Pop
    The given path may not contain an export, in which case we return
435 3ecf6786 Iustin Pop
    None.
436 3ecf6786 Iustin Pop

437 3ecf6786 Iustin Pop
    """
438 3ecf6786 Iustin Pop
    path = params[0]
439 3eccac06 Iustin Pop
    return backend.ExportInfo(path)
440 a8083063 Iustin Pop
441 3ecf6786 Iustin Pop
  @staticmethod
442 3ecf6786 Iustin Pop
  def perspective_export_list(params):
443 3ecf6786 Iustin Pop
    """List the available exports on this node.
444 3ecf6786 Iustin Pop

445 3ecf6786 Iustin Pop
    Note that as opposed to export_info, which may query data about an
446 3ecf6786 Iustin Pop
    export in any path, this only queries the standard Ganeti path
447 3ecf6786 Iustin Pop
    (constants.EXPORT_DIR).
448 3ecf6786 Iustin Pop

449 3ecf6786 Iustin Pop
    """
450 a8083063 Iustin Pop
    return backend.ListExports()
451 a8083063 Iustin Pop
452 3ecf6786 Iustin Pop
  @staticmethod
453 3ecf6786 Iustin Pop
  def perspective_export_remove(params):
454 3ecf6786 Iustin Pop
    """Remove an export.
455 3ecf6786 Iustin Pop

456 3ecf6786 Iustin Pop
    """
457 a8083063 Iustin Pop
    export = params[0]
458 a8083063 Iustin Pop
    return backend.RemoveExport(export)
459 a8083063 Iustin Pop
460 2be7273c Apollon Oikonomopoulos
  # block device ---------------------
461 2be7273c Apollon Oikonomopoulos
  @staticmethod
462 2be7273c Apollon Oikonomopoulos
  def perspective_bdev_sizes(params):
463 2be7273c Apollon Oikonomopoulos
    """Query the list of block devices
464 2be7273c Apollon Oikonomopoulos

465 2be7273c Apollon Oikonomopoulos
    """
466 2be7273c Apollon Oikonomopoulos
    devices = params[0]
467 2be7273c Apollon Oikonomopoulos
    return backend.GetBlockDevSizes(devices)
468 2be7273c Apollon Oikonomopoulos
469 a8083063 Iustin Pop
  # volume  --------------------------
470 a8083063 Iustin Pop
471 3ecf6786 Iustin Pop
  @staticmethod
472 b2a6ccd4 Iustin Pop
  def perspective_lv_list(params):
473 3ecf6786 Iustin Pop
    """Query the list of logical volumes in a given volume group.
474 3ecf6786 Iustin Pop

475 3ecf6786 Iustin Pop
    """
476 a8083063 Iustin Pop
    vgname = params[0]
477 c26a6bd2 Iustin Pop
    return backend.GetVolumeList(vgname)
478 a8083063 Iustin Pop
479 3ecf6786 Iustin Pop
  @staticmethod
480 3ecf6786 Iustin Pop
  def perspective_vg_list(params):
481 3ecf6786 Iustin Pop
    """Query the list of volume groups.
482 3ecf6786 Iustin Pop

483 3ecf6786 Iustin Pop
    """
484 a8083063 Iustin Pop
    return backend.ListVolumeGroups()
485 a8083063 Iustin Pop
486 e337de97 Michael Hanselmann
  # Storage --------------------------
487 e337de97 Michael Hanselmann
488 e337de97 Michael Hanselmann
  @staticmethod
489 e337de97 Michael Hanselmann
  def perspective_storage_list(params):
490 e337de97 Michael Hanselmann
    """Get list of storage units.
491 e337de97 Michael Hanselmann

492 e337de97 Michael Hanselmann
    """
493 e337de97 Michael Hanselmann
    (su_name, su_args, name, fields) = params
494 e337de97 Michael Hanselmann
    return storage.GetStorage(su_name, *su_args).List(name, fields)
495 e337de97 Michael Hanselmann
496 8979196a Michael Hanselmann
  @staticmethod
497 8979196a Michael Hanselmann
  def perspective_storage_modify(params):
498 8979196a Michael Hanselmann
    """Modify a storage unit.
499 8979196a Michael Hanselmann

500 8979196a Michael Hanselmann
    """
501 8979196a Michael Hanselmann
    (su_name, su_args, name, changes) = params
502 8979196a Michael Hanselmann
    return storage.GetStorage(su_name, *su_args).Modify(name, changes)
503 8979196a Michael Hanselmann
504 637b8d7e Michael Hanselmann
  @staticmethod
505 637b8d7e Michael Hanselmann
  def perspective_storage_execute(params):
506 637b8d7e Michael Hanselmann
    """Execute an operation on a storage unit.
507 637b8d7e Michael Hanselmann

508 637b8d7e Michael Hanselmann
    """
509 637b8d7e Michael Hanselmann
    (su_name, su_args, name, op) = params
510 637b8d7e Michael Hanselmann
    return storage.GetStorage(su_name, *su_args).Execute(name, op)
511 637b8d7e Michael Hanselmann
512 a8083063 Iustin Pop
  # bridge  --------------------------
513 a8083063 Iustin Pop
514 3ecf6786 Iustin Pop
  @staticmethod
515 3ecf6786 Iustin Pop
  def perspective_bridges_exist(params):
516 3ecf6786 Iustin Pop
    """Check if all bridges given exist on this node.
517 3ecf6786 Iustin Pop

518 3ecf6786 Iustin Pop
    """
519 a8083063 Iustin Pop
    bridges_list = params[0]
520 a8083063 Iustin Pop
    return backend.BridgesExist(bridges_list)
521 a8083063 Iustin Pop
522 a8083063 Iustin Pop
  # instance  --------------------------
523 a8083063 Iustin Pop
524 3ecf6786 Iustin Pop
  @staticmethod
525 3ecf6786 Iustin Pop
  def perspective_instance_os_add(params):
526 3ecf6786 Iustin Pop
    """Install an OS on a given instance.
527 3ecf6786 Iustin Pop

528 3ecf6786 Iustin Pop
    """
529 d15a9ad3 Guido Trotter
    inst_s = params[0]
530 319856a9 Michael Hanselmann
    inst = objects.Instance.FromDict(inst_s)
531 e557bae9 Guido Trotter
    reinstall = params[1]
532 4a0e011f Iustin Pop
    debug = params[2]
533 4a0e011f Iustin Pop
    return backend.InstanceOsAdd(inst, reinstall, debug)
534 a8083063 Iustin Pop
535 3ecf6786 Iustin Pop
  @staticmethod
536 decd5f45 Iustin Pop
  def perspective_instance_run_rename(params):
537 decd5f45 Iustin Pop
    """Runs the OS rename script for an instance.
538 decd5f45 Iustin Pop

539 decd5f45 Iustin Pop
    """
540 4a0e011f Iustin Pop
    inst_s, old_name, debug = params
541 319856a9 Michael Hanselmann
    inst = objects.Instance.FromDict(inst_s)
542 4a0e011f Iustin Pop
    return backend.RunRenameInstance(inst, old_name, debug)
543 decd5f45 Iustin Pop
544 decd5f45 Iustin Pop
  @staticmethod
545 3ecf6786 Iustin Pop
  def perspective_instance_shutdown(params):
546 3ecf6786 Iustin Pop
    """Shutdown an instance.
547 3ecf6786 Iustin Pop

548 3ecf6786 Iustin Pop
    """
549 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
550 6263189c Guido Trotter
    timeout = params[1]
551 6263189c Guido Trotter
    return backend.InstanceShutdown(instance, timeout)
552 a8083063 Iustin Pop
553 3ecf6786 Iustin Pop
  @staticmethod
554 3ecf6786 Iustin Pop
  def perspective_instance_start(params):
555 3ecf6786 Iustin Pop
    """Start an instance.
556 3ecf6786 Iustin Pop

557 3ecf6786 Iustin Pop
    """
558 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
559 07813a9e Iustin Pop
    return backend.StartInstance(instance)
560 a8083063 Iustin Pop
561 3ecf6786 Iustin Pop
  @staticmethod
562 6906a9d8 Guido Trotter
  def perspective_migration_info(params):
563 6906a9d8 Guido Trotter
    """Gather information about an instance to be migrated.
564 6906a9d8 Guido Trotter

565 6906a9d8 Guido Trotter
    """
566 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(params[0])
567 6906a9d8 Guido Trotter
    return backend.MigrationInfo(instance)
568 6906a9d8 Guido Trotter
569 6906a9d8 Guido Trotter
  @staticmethod
570 6906a9d8 Guido Trotter
  def perspective_accept_instance(params):
571 6906a9d8 Guido Trotter
    """Prepare the node to accept an instance.
572 6906a9d8 Guido Trotter

573 6906a9d8 Guido Trotter
    """
574 6906a9d8 Guido Trotter
    instance, info, target = params
575 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(instance)
576 6906a9d8 Guido Trotter
    return backend.AcceptInstance(instance, info, target)
577 6906a9d8 Guido Trotter
578 6906a9d8 Guido Trotter
  @staticmethod
579 6906a9d8 Guido Trotter
  def perspective_finalize_migration(params):
580 6906a9d8 Guido Trotter
    """Finalize the instance migration.
581 6906a9d8 Guido Trotter

582 6906a9d8 Guido Trotter
    """
583 6906a9d8 Guido Trotter
    instance, info, success = params
584 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(instance)
585 6906a9d8 Guido Trotter
    return backend.FinalizeMigration(instance, info, success)
586 6906a9d8 Guido Trotter
587 6906a9d8 Guido Trotter
  @staticmethod
588 2a10865c Iustin Pop
  def perspective_instance_migrate(params):
589 2a10865c Iustin Pop
    """Migrates an instance.
590 2a10865c Iustin Pop

591 2a10865c Iustin Pop
    """
592 2a10865c Iustin Pop
    instance, target, live = params
593 9f0e6b37 Iustin Pop
    instance = objects.Instance.FromDict(instance)
594 2a10865c Iustin Pop
    return backend.MigrateInstance(instance, target, live)
595 2a10865c Iustin Pop
596 2a10865c Iustin Pop
  @staticmethod
597 007a2f3e Alexander Schreiber
  def perspective_instance_reboot(params):
598 007a2f3e Alexander Schreiber
    """Reboot an instance.
599 007a2f3e Alexander Schreiber

600 007a2f3e Alexander Schreiber
    """
601 007a2f3e Alexander Schreiber
    instance = objects.Instance.FromDict(params[0])
602 007a2f3e Alexander Schreiber
    reboot_type = params[1]
603 17c3f802 Guido Trotter
    shutdown_timeout = params[2]
604 17c3f802 Guido Trotter
    return backend.InstanceReboot(instance, reboot_type, shutdown_timeout)
605 007a2f3e Alexander Schreiber
606 007a2f3e Alexander Schreiber
  @staticmethod
607 3ecf6786 Iustin Pop
  def perspective_instance_info(params):
608 3ecf6786 Iustin Pop
    """Query instance information.
609 3ecf6786 Iustin Pop

610 3ecf6786 Iustin Pop
    """
611 16ad1a83 Iustin Pop
    return backend.GetInstanceInfo(params[0], params[1])
612 a8083063 Iustin Pop
613 3ecf6786 Iustin Pop
  @staticmethod
614 56e7640c Iustin Pop
  def perspective_instance_migratable(params):
615 56e7640c Iustin Pop
    """Query whether the specified instance can be migrated.
616 56e7640c Iustin Pop

617 56e7640c Iustin Pop
    """
618 56e7640c Iustin Pop
    instance = objects.Instance.FromDict(params[0])
619 56e7640c Iustin Pop
    return backend.GetInstanceMigratable(instance)
620 56e7640c Iustin Pop
621 56e7640c Iustin Pop
  @staticmethod
622 3ecf6786 Iustin Pop
  def perspective_all_instances_info(params):
623 3ecf6786 Iustin Pop
    """Query information about all instances.
624 3ecf6786 Iustin Pop

625 3ecf6786 Iustin Pop
    """
626 e69d05fd Iustin Pop
    return backend.GetAllInstancesInfo(params[0])
627 a8083063 Iustin Pop
628 3ecf6786 Iustin Pop
  @staticmethod
629 3ecf6786 Iustin Pop
  def perspective_instance_list(params):
630 3ecf6786 Iustin Pop
    """Query the list of running instances.
631 3ecf6786 Iustin Pop

632 3ecf6786 Iustin Pop
    """
633 c26a6bd2 Iustin Pop
    return backend.GetInstanceList(params[0])
634 a8083063 Iustin Pop
635 a8083063 Iustin Pop
  # node --------------------------
636 a8083063 Iustin Pop
637 3ecf6786 Iustin Pop
  @staticmethod
638 16abfbc2 Alexander Schreiber
  def perspective_node_tcp_ping(params):
639 16abfbc2 Alexander Schreiber
    """Do a TcpPing on the remote node.
640 16abfbc2 Alexander Schreiber

641 16abfbc2 Alexander Schreiber
    """
642 a744b676 Manuel Franceschini
    return netutils.TcpPing(params[1], params[2], timeout=params[3],
643 a744b676 Manuel Franceschini
                            live_port_needed=params[4], source=params[0])
644 16abfbc2 Alexander Schreiber
645 16abfbc2 Alexander Schreiber
  @staticmethod
646 caad16e2 Iustin Pop
  def perspective_node_has_ip_address(params):
647 caad16e2 Iustin Pop
    """Checks if a node has the given ip address.
648 caad16e2 Iustin Pop

649 caad16e2 Iustin Pop
    """
650 8b312c1d Manuel Franceschini
    return netutils.IPAddress.Own(params[0])
651 caad16e2 Iustin Pop
652 caad16e2 Iustin Pop
  @staticmethod
653 3ecf6786 Iustin Pop
  def perspective_node_info(params):
654 3ecf6786 Iustin Pop
    """Query node information.
655 3ecf6786 Iustin Pop

656 3ecf6786 Iustin Pop
    """
657 e69d05fd Iustin Pop
    vgname, hypervisor_type = params
658 e69d05fd Iustin Pop
    return backend.GetNodeInfo(vgname, hypervisor_type)
659 a8083063 Iustin Pop
660 3ecf6786 Iustin Pop
  @staticmethod
661 19ddc57a René Nussbaumer
  def perspective_etc_hosts_modify(params):
662 19ddc57a René Nussbaumer
    """Modify a node entry in /etc/hosts.
663 19ddc57a René Nussbaumer

664 19ddc57a René Nussbaumer
    """
665 19ddc57a René Nussbaumer
    backend.EtcHostsModify(params[0], params[1], params[2])
666 19ddc57a René Nussbaumer
667 19ddc57a René Nussbaumer
    return True
668 19ddc57a René Nussbaumer
669 19ddc57a René Nussbaumer
  @staticmethod
670 3ecf6786 Iustin Pop
  def perspective_node_verify(params):
671 3ecf6786 Iustin Pop
    """Run a verify sequence on this node.
672 3ecf6786 Iustin Pop

673 3ecf6786 Iustin Pop
    """
674 62c9ec92 Iustin Pop
    return backend.VerifyNode(params[0], params[1])
675 a8083063 Iustin Pop
676 3ecf6786 Iustin Pop
  @staticmethod
677 3ecf6786 Iustin Pop
  def perspective_node_start_master(params):
678 3ecf6786 Iustin Pop
    """Promote this node to master status.
679 3ecf6786 Iustin Pop

680 3ecf6786 Iustin Pop
    """
681 3583908a Guido Trotter
    return backend.StartMaster(params[0], params[1])
682 a8083063 Iustin Pop
683 3ecf6786 Iustin Pop
  @staticmethod
684 3ecf6786 Iustin Pop
  def perspective_node_stop_master(params):
685 3ecf6786 Iustin Pop
    """Demote this node from master status.
686 3ecf6786 Iustin Pop

687 3ecf6786 Iustin Pop
    """
688 1c65840b Iustin Pop
    return backend.StopMaster(params[0])
689 a8083063 Iustin Pop
690 3ecf6786 Iustin Pop
  @staticmethod
691 3ecf6786 Iustin Pop
  def perspective_node_leave_cluster(params):
692 3ecf6786 Iustin Pop
    """Cleanup after leaving a cluster.
693 3ecf6786 Iustin Pop

694 3ecf6786 Iustin Pop
    """
695 b989b9d9 Ken Wehr
    return backend.LeaveCluster(params[0])
696 a8083063 Iustin Pop
697 3ecf6786 Iustin Pop
  @staticmethod
698 3ecf6786 Iustin Pop
  def perspective_node_volumes(params):
699 3ecf6786 Iustin Pop
    """Query the list of all logical volume groups.
700 3ecf6786 Iustin Pop

701 3ecf6786 Iustin Pop
    """
702 dcb93971 Michael Hanselmann
    return backend.NodeVolumes()
703 dcb93971 Michael Hanselmann
704 56aa9fd5 Iustin Pop
  @staticmethod
705 56aa9fd5 Iustin Pop
  def perspective_node_demote_from_mc(params):
706 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
707 56aa9fd5 Iustin Pop

708 56aa9fd5 Iustin Pop
    """
709 56aa9fd5 Iustin Pop
    return backend.DemoteFromMC()
710 56aa9fd5 Iustin Pop
711 56aa9fd5 Iustin Pop
712 f5118ade Iustin Pop
  @staticmethod
713 f5118ade Iustin Pop
  def perspective_node_powercycle(params):
714 f5118ade Iustin Pop
    """Tries to powercycle the nod.
715 f5118ade Iustin Pop

716 f5118ade Iustin Pop
    """
717 f5118ade Iustin Pop
    hypervisor_type = params[0]
718 f5118ade Iustin Pop
    return backend.PowercycleNode(hypervisor_type)
719 f5118ade Iustin Pop
720 f5118ade Iustin Pop
721 a8083063 Iustin Pop
  # cluster --------------------------
722 a8083063 Iustin Pop
723 3ecf6786 Iustin Pop
  @staticmethod
724 3ecf6786 Iustin Pop
  def perspective_version(params):
725 3ecf6786 Iustin Pop
    """Query version information.
726 3ecf6786 Iustin Pop

727 3ecf6786 Iustin Pop
    """
728 c26a6bd2 Iustin Pop
    return constants.PROTOCOL_VERSION
729 a8083063 Iustin Pop
730 3ecf6786 Iustin Pop
  @staticmethod
731 3ecf6786 Iustin Pop
  def perspective_upload_file(params):
732 3ecf6786 Iustin Pop
    """Upload a file.
733 3ecf6786 Iustin Pop

734 3ecf6786 Iustin Pop
    Note that the backend implementation imposes strict rules on which
735 3ecf6786 Iustin Pop
    files are accepted.
736 3ecf6786 Iustin Pop

737 3ecf6786 Iustin Pop
    """
738 a8083063 Iustin Pop
    return backend.UploadFile(*params)
739 a8083063 Iustin Pop
740 4e071d3b Iustin Pop
  @staticmethod
741 4e071d3b Iustin Pop
  def perspective_master_info(params):
742 4e071d3b Iustin Pop
    """Query master information.
743 4e071d3b Iustin Pop

744 4e071d3b Iustin Pop
    """
745 4e071d3b Iustin Pop
    return backend.GetMasterInfo()
746 a8083063 Iustin Pop
747 6ddc95ec Michael Hanselmann
  @staticmethod
748 4f6014d4 René Nussbaumer
  def perspective_run_oob(params):
749 4f6014d4 René Nussbaumer
    """Runs oob on node.
750 4f6014d4 René Nussbaumer

751 4f6014d4 René Nussbaumer
    """
752 1aa88d95 René Nussbaumer
    output = backend.RunOob(params[0], params[1], params[2], params[3])
753 1aa88d95 René Nussbaumer
    if output:
754 1aa88d95 René Nussbaumer
      result = serializer.LoadJson(output)
755 1aa88d95 René Nussbaumer
    else:
756 1aa88d95 René Nussbaumer
      result = None
757 1aa88d95 René Nussbaumer
    return result
758 4f6014d4 René Nussbaumer
759 4f6014d4 René Nussbaumer
  @staticmethod
760 6ddc95ec Michael Hanselmann
  def perspective_write_ssconf_files(params):
761 6ddc95ec Michael Hanselmann
    """Write ssconf files.
762 6ddc95ec Michael Hanselmann

763 6ddc95ec Michael Hanselmann
    """
764 03d1dba2 Michael Hanselmann
    (values,) = params
765 03d1dba2 Michael Hanselmann
    return backend.WriteSsconfFiles(values)
766 6ddc95ec Michael Hanselmann
767 a8083063 Iustin Pop
  # os -----------------------
768 a8083063 Iustin Pop
769 3ecf6786 Iustin Pop
  @staticmethod
770 3ecf6786 Iustin Pop
  def perspective_os_diagnose(params):
771 3ecf6786 Iustin Pop
    """Query detailed information about existing OSes.
772 3ecf6786 Iustin Pop

773 3ecf6786 Iustin Pop
    """
774 255dcebd Iustin Pop
    return backend.DiagnoseOS()
775 a8083063 Iustin Pop
776 3ecf6786 Iustin Pop
  @staticmethod
777 3ecf6786 Iustin Pop
  def perspective_os_get(params):
778 3ecf6786 Iustin Pop
    """Query information about a given OS.
779 3ecf6786 Iustin Pop

780 3ecf6786 Iustin Pop
    """
781 a8083063 Iustin Pop
    name = params[0]
782 255dcebd Iustin Pop
    os_obj = backend.OSFromDisk(name)
783 c26a6bd2 Iustin Pop
    return os_obj.ToDict()
784 a8083063 Iustin Pop
785 acd9ff9e Iustin Pop
  @staticmethod
786 acd9ff9e Iustin Pop
  def perspective_os_validate(params):
787 acd9ff9e Iustin Pop
    """Run a given OS' validation routine.
788 acd9ff9e Iustin Pop

789 acd9ff9e Iustin Pop
    """
790 acd9ff9e Iustin Pop
    required, name, checks, params = params
791 acd9ff9e Iustin Pop
    return backend.ValidateOS(required, name, checks, params)
792 acd9ff9e Iustin Pop
793 a8083063 Iustin Pop
  # hooks -----------------------
794 a8083063 Iustin Pop
795 3ecf6786 Iustin Pop
  @staticmethod
796 3ecf6786 Iustin Pop
  def perspective_hooks_runner(params):
797 3ecf6786 Iustin Pop
    """Run hook scripts.
798 3ecf6786 Iustin Pop

799 3ecf6786 Iustin Pop
    """
800 a8083063 Iustin Pop
    hpath, phase, env = params
801 a8083063 Iustin Pop
    hr = backend.HooksRunner()
802 a8083063 Iustin Pop
    return hr.RunHooks(hpath, phase, env)
803 a8083063 Iustin Pop
804 8d528b7c Iustin Pop
  # iallocator -----------------
805 8d528b7c Iustin Pop
806 8d528b7c Iustin Pop
  @staticmethod
807 8d528b7c Iustin Pop
  def perspective_iallocator_runner(params):
808 8d528b7c Iustin Pop
    """Run an iallocator script.
809 8d528b7c Iustin Pop

810 8d528b7c Iustin Pop
    """
811 8d528b7c Iustin Pop
    name, idata = params
812 8d528b7c Iustin Pop
    iar = backend.IAllocatorRunner()
813 8d528b7c Iustin Pop
    return iar.Run(name, idata)
814 8d528b7c Iustin Pop
815 06009e27 Iustin Pop
  # test -----------------------
816 06009e27 Iustin Pop
817 06009e27 Iustin Pop
  @staticmethod
818 06009e27 Iustin Pop
  def perspective_test_delay(params):
819 06009e27 Iustin Pop
    """Run test delay.
820 06009e27 Iustin Pop

821 06009e27 Iustin Pop
    """
822 06009e27 Iustin Pop
    duration = params[0]
823 c26a6bd2 Iustin Pop
    status, rval = utils.TestDelay(duration)
824 c26a6bd2 Iustin Pop
    if not status:
825 c26a6bd2 Iustin Pop
      raise backend.RPCFail(rval)
826 c26a6bd2 Iustin Pop
    return rval
827 06009e27 Iustin Pop
828 4e071d3b Iustin Pop
  # file storage ---------------
829 4e071d3b Iustin Pop
830 a5d7fb43 Manuel Franceschini
  @staticmethod
831 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_create(params):
832 a5d7fb43 Manuel Franceschini
    """Create the file storage directory.
833 a5d7fb43 Manuel Franceschini

834 a5d7fb43 Manuel Franceschini
    """
835 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
836 a5d7fb43 Manuel Franceschini
    return backend.CreateFileStorageDir(file_storage_dir)
837 a5d7fb43 Manuel Franceschini
838 a5d7fb43 Manuel Franceschini
  @staticmethod
839 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_remove(params):
840 a5d7fb43 Manuel Franceschini
    """Remove the file storage directory.
841 a5d7fb43 Manuel Franceschini

842 a5d7fb43 Manuel Franceschini
    """
843 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
844 a5d7fb43 Manuel Franceschini
    return backend.RemoveFileStorageDir(file_storage_dir)
845 a5d7fb43 Manuel Franceschini
846 a5d7fb43 Manuel Franceschini
  @staticmethod
847 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_rename(params):
848 a5d7fb43 Manuel Franceschini
    """Rename the file storage directory.
849 a5d7fb43 Manuel Franceschini

850 a5d7fb43 Manuel Franceschini
    """
851 a5d7fb43 Manuel Franceschini
    old_file_storage_dir = params[0]
852 a5d7fb43 Manuel Franceschini
    new_file_storage_dir = params[1]
853 a5d7fb43 Manuel Franceschini
    return backend.RenameFileStorageDir(old_file_storage_dir,
854 a5d7fb43 Manuel Franceschini
                                        new_file_storage_dir)
855 a5d7fb43 Manuel Franceschini
856 4e071d3b Iustin Pop
  # jobs ------------------------
857 4e071d3b Iustin Pop
858 ca52cdeb Michael Hanselmann
  @staticmethod
859 7f30777b Michael Hanselmann
  @_RequireJobQueueLock
860 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_update(params):
861 ca52cdeb Michael Hanselmann
    """Update job queue.
862 ca52cdeb Michael Hanselmann

863 ca52cdeb Michael Hanselmann
    """
864 ca52cdeb Michael Hanselmann
    (file_name, content) = params
865 7f30777b Michael Hanselmann
    return backend.JobQueueUpdate(file_name, content)
866 ca52cdeb Michael Hanselmann
867 ca52cdeb Michael Hanselmann
  @staticmethod
868 f1f3f45c Michael Hanselmann
  @_RequireJobQueueLock
869 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_purge(params):
870 ca52cdeb Michael Hanselmann
    """Purge job queue.
871 ca52cdeb Michael Hanselmann

872 ca52cdeb Michael Hanselmann
    """
873 ca52cdeb Michael Hanselmann
    return backend.JobQueuePurge()
874 ca52cdeb Michael Hanselmann
875 af5ebcb1 Michael Hanselmann
  @staticmethod
876 af5ebcb1 Michael Hanselmann
  @_RequireJobQueueLock
877 af5ebcb1 Michael Hanselmann
  def perspective_jobqueue_rename(params):
878 af5ebcb1 Michael Hanselmann
    """Rename a job queue file.
879 af5ebcb1 Michael Hanselmann

880 af5ebcb1 Michael Hanselmann
    """
881 dd875d32 Michael Hanselmann
    # TODO: What if a file fails to rename?
882 c26a6bd2 Iustin Pop
    return [backend.JobQueueRename(old, new) for old, new in params]
883 af5ebcb1 Michael Hanselmann
884 6217e295 Iustin Pop
  # hypervisor ---------------
885 6217e295 Iustin Pop
886 6217e295 Iustin Pop
  @staticmethod
887 6217e295 Iustin Pop
  def perspective_hypervisor_validate_params(params):
888 6217e295 Iustin Pop
    """Validate the hypervisor parameters.
889 6217e295 Iustin Pop

890 6217e295 Iustin Pop
    """
891 6217e295 Iustin Pop
    (hvname, hvparams) = params
892 6217e295 Iustin Pop
    return backend.ValidateHVParams(hvname, hvparams)
893 6217e295 Iustin Pop
894 f942a838 Michael Hanselmann
  # Crypto
895 f942a838 Michael Hanselmann
896 f942a838 Michael Hanselmann
  @staticmethod
897 ef40fbfb Michael Hanselmann
  def perspective_x509_cert_create(params):
898 f942a838 Michael Hanselmann
    """Creates a new X509 certificate for SSL/TLS.
899 f942a838 Michael Hanselmann

900 f942a838 Michael Hanselmann
    """
901 f942a838 Michael Hanselmann
    (validity, ) = params
902 f942a838 Michael Hanselmann
    return backend.CreateX509Certificate(validity)
903 f942a838 Michael Hanselmann
904 f942a838 Michael Hanselmann
  @staticmethod
905 ef40fbfb Michael Hanselmann
  def perspective_x509_cert_remove(params):
906 f942a838 Michael Hanselmann
    """Removes a X509 certificate.
907 f942a838 Michael Hanselmann

908 f942a838 Michael Hanselmann
    """
909 f942a838 Michael Hanselmann
    (name, ) = params
910 f942a838 Michael Hanselmann
    return backend.RemoveX509Certificate(name)
911 f942a838 Michael Hanselmann
912 1651d116 Michael Hanselmann
  # Import and export
913 1651d116 Michael Hanselmann
914 1651d116 Michael Hanselmann
  @staticmethod
915 ef40fbfb Michael Hanselmann
  def perspective_import_start(params):
916 1651d116 Michael Hanselmann
    """Starts an import daemon.
917 1651d116 Michael Hanselmann

918 1651d116 Michael Hanselmann
    """
919 eb630f50 Michael Hanselmann
    (opts_s, instance, dest, dest_args) = params
920 eb630f50 Michael Hanselmann
921 eb630f50 Michael Hanselmann
    opts = objects.ImportExportOptions.FromDict(opts_s)
922 eb630f50 Michael Hanselmann
923 eb630f50 Michael Hanselmann
    return backend.StartImportExportDaemon(constants.IEM_IMPORT, opts,
924 1651d116 Michael Hanselmann
                                           None, None,
925 1651d116 Michael Hanselmann
                                           objects.Instance.FromDict(instance),
926 1651d116 Michael Hanselmann
                                           dest,
927 1651d116 Michael Hanselmann
                                           _DecodeImportExportIO(dest,
928 1651d116 Michael Hanselmann
                                                                 dest_args))
929 eb630f50 Michael Hanselmann
930 1651d116 Michael Hanselmann
  @staticmethod
931 ef40fbfb Michael Hanselmann
  def perspective_export_start(params):
932 1651d116 Michael Hanselmann
    """Starts an export daemon.
933 1651d116 Michael Hanselmann

934 1651d116 Michael Hanselmann
    """
935 eb630f50 Michael Hanselmann
    (opts_s, host, port, instance, source, source_args) = params
936 eb630f50 Michael Hanselmann
937 eb630f50 Michael Hanselmann
    opts = objects.ImportExportOptions.FromDict(opts_s)
938 eb630f50 Michael Hanselmann
939 eb630f50 Michael Hanselmann
    return backend.StartImportExportDaemon(constants.IEM_EXPORT, opts,
940 1651d116 Michael Hanselmann
                                           host, port,
941 1651d116 Michael Hanselmann
                                           objects.Instance.FromDict(instance),
942 1651d116 Michael Hanselmann
                                           source,
943 1651d116 Michael Hanselmann
                                           _DecodeImportExportIO(source,
944 1651d116 Michael Hanselmann
                                                                 source_args))
945 1651d116 Michael Hanselmann
946 1651d116 Michael Hanselmann
  @staticmethod
947 ef40fbfb Michael Hanselmann
  def perspective_impexp_status(params):
948 1651d116 Michael Hanselmann
    """Retrieves the status of an import or export daemon.
949 1651d116 Michael Hanselmann

950 1651d116 Michael Hanselmann
    """
951 1651d116 Michael Hanselmann
    return backend.GetImportExportStatus(params[0])
952 1651d116 Michael Hanselmann
953 1651d116 Michael Hanselmann
  @staticmethod
954 f81c4737 Michael Hanselmann
  def perspective_impexp_abort(params):
955 f81c4737 Michael Hanselmann
    """Aborts an import or export.
956 f81c4737 Michael Hanselmann

957 f81c4737 Michael Hanselmann
    """
958 f81c4737 Michael Hanselmann
    return backend.AbortImportExport(params[0])
959 f81c4737 Michael Hanselmann
960 f81c4737 Michael Hanselmann
  @staticmethod
961 ef40fbfb Michael Hanselmann
  def perspective_impexp_cleanup(params):
962 1651d116 Michael Hanselmann
    """Cleans up after an import or export.
963 1651d116 Michael Hanselmann

964 1651d116 Michael Hanselmann
    """
965 1651d116 Michael Hanselmann
    return backend.CleanupImportExport(params[0])
966 1651d116 Michael Hanselmann
967 a8083063 Iustin Pop
968 f93427cd Iustin Pop
def CheckNoded(_, args):
969 f93427cd Iustin Pop
  """Initial checks whether to run or exit with a failure.
970 f93427cd Iustin Pop

971 f93427cd Iustin Pop
  """
972 f93427cd Iustin Pop
  if args: # noded doesn't take any arguments
973 f93427cd Iustin Pop
    print >> sys.stderr, ("Usage: %s [-f] [-d] [-p port] [-b ADDRESS]" %
974 f93427cd Iustin Pop
                          sys.argv[0])
975 f93427cd Iustin Pop
    sys.exit(constants.EXIT_FAILURE)
976 f93427cd Iustin Pop
977 f93427cd Iustin Pop
978 3ee53f1f Iustin Pop
def PrepNoded(options, _):
979 3ee53f1f Iustin Pop
  """Preparation node daemon function, executed with the PID file held.
980 3ecf6786 Iustin Pop

981 3ecf6786 Iustin Pop
  """
982 bebf68d3 Guido Trotter
  if options.mlock:
983 bebf68d3 Guido Trotter
    request_executor_class = MlockallRequestExecutor
984 4c32a8bd Luca Bigliardi
    try:
985 4c32a8bd Luca Bigliardi
      utils.Mlockall()
986 4c32a8bd Luca Bigliardi
    except errors.NoCtypesError:
987 4c32a8bd Luca Bigliardi
      logging.warning("Cannot set memory lock, ctypes module not found")
988 4c32a8bd Luca Bigliardi
      request_executor_class = http.server.HttpServerRequestExecutor
989 bebf68d3 Guido Trotter
  else:
990 bebf68d3 Guido Trotter
    request_executor_class = http.server.HttpServerRequestExecutor
991 02bea2fc Luca Bigliardi
992 04ccf5e9 Guido Trotter
  # Read SSL certificate
993 3b1b0cb6 Guido Trotter
  if options.ssl:
994 3b1b0cb6 Guido Trotter
    ssl_params = http.HttpSslParams(ssl_key_path=options.ssl_key,
995 3b1b0cb6 Guido Trotter
                                    ssl_cert_path=options.ssl_cert)
996 3b1b0cb6 Guido Trotter
  else:
997 3b1b0cb6 Guido Trotter
    ssl_params = None
998 7d88772a Iustin Pop
999 81198f6e Iustin Pop
  err = _PrepareQueueLock()
1000 81198f6e Iustin Pop
  if err is not None:
1001 81198f6e Iustin Pop
    # this might be some kind of file-system/permission error; while
1002 81198f6e Iustin Pop
    # this breaks the job queue functionality, we shouldn't prevent
1003 81198f6e Iustin Pop
    # startup of the whole node daemon because of this
1004 81198f6e Iustin Pop
    logging.critical("Can't init/verify the queue, proceeding anyway: %s", err)
1005 7d88772a Iustin Pop
1006 04ccf5e9 Guido Trotter
  mainloop = daemon.Mainloop()
1007 04ccf5e9 Guido Trotter
  server = NodeHttpServer(mainloop, options.bind_address, options.port,
1008 38b77287 Luca Bigliardi
                          ssl_params=ssl_params, ssl_verify_peer=True,
1009 bebf68d3 Guido Trotter
                          request_executor_class=request_executor_class)
1010 04ccf5e9 Guido Trotter
  server.Start()
1011 3ee53f1f Iustin Pop
  return (mainloop, server)
1012 3ee53f1f Iustin Pop
1013 5119f2ec Michael Hanselmann
1014 3ee53f1f Iustin Pop
def ExecNoded(options, args, prep_data): # pylint: disable-msg=W0613
1015 3ee53f1f Iustin Pop
  """Main node daemon function, executed with the PID file held.
1016 3ee53f1f Iustin Pop

1017 3ee53f1f Iustin Pop
  """
1018 3ee53f1f Iustin Pop
  (mainloop, server) = prep_data
1019 04ccf5e9 Guido Trotter
  try:
1020 04ccf5e9 Guido Trotter
    mainloop.Run()
1021 04ccf5e9 Guido Trotter
  finally:
1022 04ccf5e9 Guido Trotter
    server.Stop()
1023 a8083063 Iustin Pop
1024 a8083063 Iustin Pop
1025 5119f2ec Michael Hanselmann
def Main():
1026 04ccf5e9 Guido Trotter
  """Main function for the node daemon.
1027 04ccf5e9 Guido Trotter

1028 04ccf5e9 Guido Trotter
  """
1029 04ccf5e9 Guido Trotter
  parser = OptionParser(description="Ganeti node daemon",
1030 04ccf5e9 Guido Trotter
                        usage="%prog [-f] [-d] [-p port] [-b ADDRESS]",
1031 04ccf5e9 Guido Trotter
                        version="%%prog (ganeti) %s" %
1032 04ccf5e9 Guido Trotter
                        constants.RELEASE_VERSION)
1033 bebf68d3 Guido Trotter
  parser.add_option("--no-mlock", dest="mlock",
1034 bebf68d3 Guido Trotter
                    help="Do not mlock the node memory in ram",
1035 bebf68d3 Guido Trotter
                    default=True, action="store_false")
1036 bebf68d3 Guido Trotter
1037 3ee53f1f Iustin Pop
  daemon.GenericMain(constants.NODED, parser, CheckNoded, PrepNoded, ExecNoded,
1038 084aba47 Michael Hanselmann
                     default_ssl_cert=constants.NODED_CERT_FILE,
1039 1c54156d Luca Bigliardi
                     default_ssl_key=constants.NODED_CERT_FILE,
1040 565083ef Luca Bigliardi
                     console_logging=True)