Statistics
| Branch: | Tag: | Revision:

root / daemons / ganeti-noded @ 47f8a2d2

History | View | Annotate | Download (24.9 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 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 a8083063 Iustin Pop
50 30e4e741 Iustin Pop
import ganeti.http.server # pylint: disable-msg=W0611
51 19205c39 Michael Hanselmann
52 a8083063 Iustin Pop
53 25d6d12a Michael Hanselmann
queue_lock = None
54 25d6d12a Michael Hanselmann
55 25d6d12a Michael Hanselmann
56 81198f6e Iustin Pop
def _PrepareQueueLock():
57 81198f6e Iustin Pop
  """Try to prepare the queue lock.
58 81198f6e Iustin Pop
59 81198f6e Iustin Pop
  @return: None for success, otherwise an exception object
60 81198f6e Iustin Pop
61 81198f6e Iustin Pop
  """
62 81198f6e Iustin Pop
  global queue_lock # pylint: disable-msg=W0603
63 81198f6e Iustin Pop
64 81198f6e Iustin Pop
  if queue_lock is not None:
65 81198f6e Iustin Pop
    return None
66 81198f6e Iustin Pop
67 81198f6e Iustin Pop
  # Prepare job queue
68 81198f6e Iustin Pop
  try:
69 81198f6e Iustin Pop
    queue_lock = jstore.InitAndVerifyQueue(must_lock=False)
70 81198f6e Iustin Pop
    return None
71 81198f6e Iustin Pop
  except EnvironmentError, err:
72 81198f6e Iustin Pop
    return err
73 81198f6e Iustin Pop
74 81198f6e Iustin Pop
75 7f30777b Michael Hanselmann
def _RequireJobQueueLock(fn):
76 7f30777b Michael Hanselmann
  """Decorator for job queue manipulating functions.
77 7f30777b Michael Hanselmann
78 7f30777b Michael Hanselmann
  """
79 8785cb30 Michael Hanselmann
  QUEUE_LOCK_TIMEOUT = 10
80 8785cb30 Michael Hanselmann
81 7f30777b Michael Hanselmann
  def wrapper(*args, **kwargs):
82 7f30777b Michael Hanselmann
    # Locking in exclusive, blocking mode because there could be several
83 506cff12 Michael Hanselmann
    # children running at the same time. Waiting up to 10 seconds.
84 81198f6e Iustin Pop
    if _PrepareQueueLock() is not None:
85 81198f6e Iustin Pop
      raise errors.JobQueueError("Job queue failed initialization,"
86 81198f6e Iustin Pop
                                 " cannot update jobs")
87 8785cb30 Michael Hanselmann
    queue_lock.Exclusive(blocking=True, timeout=QUEUE_LOCK_TIMEOUT)
88 7f30777b Michael Hanselmann
    try:
89 7f30777b Michael Hanselmann
      return fn(*args, **kwargs)
90 7f30777b Michael Hanselmann
    finally:
91 7f30777b Michael Hanselmann
      queue_lock.Unlock()
92 8785cb30 Michael Hanselmann
93 7f30777b Michael Hanselmann
  return wrapper
94 7f30777b Michael Hanselmann
95 7f30777b Michael Hanselmann
96 1651d116 Michael Hanselmann
def _DecodeImportExportIO(ieio, ieioargs):
97 1651d116 Michael Hanselmann
  """Decodes import/export I/O information.
98 1651d116 Michael Hanselmann
99 1651d116 Michael Hanselmann
  """
100 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_RAW_DISK:
101 1651d116 Michael Hanselmann
    assert len(ieioargs) == 1
102 1651d116 Michael Hanselmann
    return (objects.Disk.FromDict(ieioargs[0]), )
103 1651d116 Michael Hanselmann
104 1651d116 Michael Hanselmann
  if ieio == constants.IEIO_SCRIPT:
105 1651d116 Michael Hanselmann
    assert len(ieioargs) == 2
106 1651d116 Michael Hanselmann
    return (objects.Disk.FromDict(ieioargs[0]), ieioargs[1])
107 1651d116 Michael Hanselmann
108 1651d116 Michael Hanselmann
  return ieioargs
109 1651d116 Michael Hanselmann
110 1651d116 Michael Hanselmann
111 19205c39 Michael Hanselmann
class NodeHttpServer(http.server.HttpServer):
112 3ecf6786 Iustin Pop
  """The server implementation.
113 3ecf6786 Iustin Pop
114 3ecf6786 Iustin Pop
  This class holds all methods exposed over the RPC interface.
115 3ecf6786 Iustin Pop
116 3ecf6786 Iustin Pop
  """
117 2d54e29c Iustin Pop
  # too many public methods, and unused args - all methods get params
118 2d54e29c Iustin Pop
  # due to the API
119 2d54e29c Iustin Pop
  # pylint: disable-msg=R0904,W0613
120 cc28af80 Michael Hanselmann
  def __init__(self, *args, **kwargs):
121 19205c39 Michael Hanselmann
    http.server.HttpServer.__init__(self, *args, **kwargs)
122 cc28af80 Michael Hanselmann
    self.noded_pid = os.getpid()
123 cc28af80 Michael Hanselmann
124 cc28af80 Michael Hanselmann
  def HandleRequest(self, req):
125 1df6506c Michael Hanselmann
    """Handle a request.
126 a8083063 Iustin Pop
127 098c0958 Michael Hanselmann
    """
128 19205c39 Michael Hanselmann
    if req.request_method.upper() != http.HTTP_PUT:
129 84f2756e Michael Hanselmann
      raise http.HttpBadRequest()
130 1df6506c Michael Hanselmann
131 cc28af80 Michael Hanselmann
    path = req.request_path
132 81010134 Iustin Pop
    if path.startswith("/"):
133 81010134 Iustin Pop
      path = path[1:]
134 81010134 Iustin Pop
135 1df6506c Michael Hanselmann
    method = getattr(self, "perspective_%s" % path, None)
136 1df6506c Michael Hanselmann
    if method is None:
137 84f2756e Michael Hanselmann
      raise http.HttpNotFound()
138 a8083063 Iustin Pop
139 81010134 Iustin Pop
    try:
140 ab221ddf Michael Hanselmann
      result = (True, method(serializer.LoadJson(req.request_body)))
141 4dd42c9d Iustin Pop
142 0623d351 Iustin Pop
    except backend.RPCFail, err:
143 0623d351 Iustin Pop
      # our custom failure exception; str(err) works fine if the
144 0623d351 Iustin Pop
      # exception was constructed with a single argument, and in
145 0623d351 Iustin Pop
      # this case, err.message == err.args[0] == str(err)
146 ab221ddf Michael Hanselmann
      result = (False, str(err))
147 9ae49f27 Guido Trotter
    except errors.QuitGanetiException, err:
148 84b58db2 Michael Hanselmann
      # Tell parent to quit
149 0623d351 Iustin Pop
      logging.info("Shutting down the node daemon, arguments: %s",
150 0623d351 Iustin Pop
                   str(err.args))
151 cc28af80 Michael Hanselmann
      os.kill(self.noded_pid, signal.SIGTERM)
152 0623d351 Iustin Pop
      # And return the error's arguments, which must be already in
153 0623d351 Iustin Pop
      # correct tuple format
154 ab221ddf Michael Hanselmann
      result = err.args
155 4dd42c9d Iustin Pop
    except Exception, err:
156 0623d351 Iustin Pop
      logging.exception("Error in RPC call")
157 ab221ddf Michael Hanselmann
      result = (False, "Error while executing backend function: %s" % str(err))
158 ab221ddf Michael Hanselmann
159 ab221ddf Michael Hanselmann
    return serializer.DumpJson(result, indent=False)
160 a8083063 Iustin Pop
161 a8083063 Iustin Pop
  # the new block devices  --------------------------
162 a8083063 Iustin Pop
163 3ecf6786 Iustin Pop
  @staticmethod
164 3ecf6786 Iustin Pop
  def perspective_blockdev_create(params):
165 3ecf6786 Iustin Pop
    """Create a block device.
166 3ecf6786 Iustin Pop
167 3ecf6786 Iustin Pop
    """
168 3f78eef2 Iustin Pop
    bdev_s, size, owner, on_primary, info = params
169 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
170 a8083063 Iustin Pop
    if bdev is None:
171 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
172 821d1bd1 Iustin Pop
    return backend.BlockdevCreate(bdev, size, owner, on_primary, info)
173 a8083063 Iustin Pop
174 3ecf6786 Iustin Pop
  @staticmethod
175 3ecf6786 Iustin Pop
  def perspective_blockdev_remove(params):
176 3ecf6786 Iustin Pop
    """Remove a block device.
177 3ecf6786 Iustin Pop
178 3ecf6786 Iustin Pop
    """
179 a8083063 Iustin Pop
    bdev_s = params[0]
180 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
181 821d1bd1 Iustin Pop
    return backend.BlockdevRemove(bdev)
182 a8083063 Iustin Pop
183 3ecf6786 Iustin Pop
  @staticmethod
184 f3e513ad Iustin Pop
  def perspective_blockdev_rename(params):
185 f3e513ad Iustin Pop
    """Remove a block device.
186 f3e513ad Iustin Pop
187 f3e513ad Iustin Pop
    """
188 f3e513ad Iustin Pop
    devlist = [(objects.Disk.FromDict(ds), uid) for ds, uid in params]
189 821d1bd1 Iustin Pop
    return backend.BlockdevRename(devlist)
190 f3e513ad Iustin Pop
191 f3e513ad Iustin Pop
  @staticmethod
192 3ecf6786 Iustin Pop
  def perspective_blockdev_assemble(params):
193 3ecf6786 Iustin Pop
    """Assemble a block device.
194 3ecf6786 Iustin Pop
195 3ecf6786 Iustin Pop
    """
196 3f78eef2 Iustin Pop
    bdev_s, owner, on_primary = params
197 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
198 a8083063 Iustin Pop
    if bdev is None:
199 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
200 821d1bd1 Iustin Pop
    return backend.BlockdevAssemble(bdev, owner, on_primary)
201 a8083063 Iustin Pop
202 3ecf6786 Iustin Pop
  @staticmethod
203 3ecf6786 Iustin Pop
  def perspective_blockdev_shutdown(params):
204 3ecf6786 Iustin Pop
    """Shutdown a block device.
205 3ecf6786 Iustin Pop
206 3ecf6786 Iustin Pop
    """
207 a8083063 Iustin Pop
    bdev_s = params[0]
208 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
209 a8083063 Iustin Pop
    if bdev is None:
210 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
211 821d1bd1 Iustin Pop
    return backend.BlockdevShutdown(bdev)
212 a8083063 Iustin Pop
213 3ecf6786 Iustin Pop
  @staticmethod
214 153d9724 Iustin Pop
  def perspective_blockdev_addchildren(params):
215 3ecf6786 Iustin Pop
    """Add a child to a mirror device.
216 3ecf6786 Iustin Pop
217 3ecf6786 Iustin Pop
    Note: this is only valid for mirror devices. It's the caller's duty
218 3ecf6786 Iustin Pop
    to send a correct disk, otherwise we raise an error.
219 3ecf6786 Iustin Pop
220 3ecf6786 Iustin Pop
    """
221 a8083063 Iustin Pop
    bdev_s, ndev_s = params
222 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
223 153d9724 Iustin Pop
    ndevs = [objects.Disk.FromDict(disk_s) for disk_s in ndev_s]
224 153d9724 Iustin Pop
    if bdev is None or ndevs.count(None) > 0:
225 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
226 821d1bd1 Iustin Pop
    return backend.BlockdevAddchildren(bdev, ndevs)
227 a8083063 Iustin Pop
228 3ecf6786 Iustin Pop
  @staticmethod
229 153d9724 Iustin Pop
  def perspective_blockdev_removechildren(params):
230 3ecf6786 Iustin Pop
    """Remove a child from a mirror device.
231 3ecf6786 Iustin Pop
232 3ecf6786 Iustin Pop
    This is only valid for mirror devices, of course. It's the callers
233 3ecf6786 Iustin Pop
    duty to send a correct disk, otherwise we raise an error.
234 3ecf6786 Iustin Pop
235 3ecf6786 Iustin Pop
    """
236 a8083063 Iustin Pop
    bdev_s, ndev_s = params
237 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
238 153d9724 Iustin Pop
    ndevs = [objects.Disk.FromDict(disk_s) for disk_s in ndev_s]
239 153d9724 Iustin Pop
    if bdev is None or ndevs.count(None) > 0:
240 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
241 821d1bd1 Iustin Pop
    return backend.BlockdevRemovechildren(bdev, ndevs)
242 a8083063 Iustin Pop
243 3ecf6786 Iustin Pop
  @staticmethod
244 3ecf6786 Iustin Pop
  def perspective_blockdev_getmirrorstatus(params):
245 3ecf6786 Iustin Pop
    """Return the mirror status for a list of disks.
246 3ecf6786 Iustin Pop
247 3ecf6786 Iustin Pop
    """
248 319856a9 Michael Hanselmann
    disks = [objects.Disk.FromDict(dsk_s)
249 36145b12 Michael Hanselmann
             for dsk_s in params]
250 36145b12 Michael Hanselmann
    return [status.ToDict()
251 36145b12 Michael Hanselmann
            for status in backend.BlockdevGetmirrorstatus(disks)]
252 a8083063 Iustin Pop
253 3ecf6786 Iustin Pop
  @staticmethod
254 3ecf6786 Iustin Pop
  def perspective_blockdev_find(params):
255 3ecf6786 Iustin Pop
    """Expose the FindBlockDevice functionality for a disk.
256 3ecf6786 Iustin Pop
257 3ecf6786 Iustin Pop
    This will try to find but not activate a disk.
258 3ecf6786 Iustin Pop
259 3ecf6786 Iustin Pop
    """
260 319856a9 Michael Hanselmann
    disk = objects.Disk.FromDict(params[0])
261 ddfe2228 Michael Hanselmann
262 ddfe2228 Michael Hanselmann
    result = backend.BlockdevFind(disk)
263 ddfe2228 Michael Hanselmann
    if result is None:
264 ddfe2228 Michael Hanselmann
      return None
265 ddfe2228 Michael Hanselmann
266 ddfe2228 Michael Hanselmann
    return result.ToDict()
267 a8083063 Iustin Pop
268 3ecf6786 Iustin Pop
  @staticmethod
269 3ecf6786 Iustin Pop
  def perspective_blockdev_snapshot(params):
270 3ecf6786 Iustin Pop
    """Create a snapshot device.
271 3ecf6786 Iustin Pop
272 3ecf6786 Iustin Pop
    Note that this is only valid for LVM disks, if we get passed
273 3ecf6786 Iustin Pop
    something else we raise an exception. The snapshot device can be
274 3ecf6786 Iustin Pop
    remove by calling the generic block device remove call.
275 3ecf6786 Iustin Pop
276 3ecf6786 Iustin Pop
    """
277 319856a9 Michael Hanselmann
    cfbd = objects.Disk.FromDict(params[0])
278 821d1bd1 Iustin Pop
    return backend.BlockdevSnapshot(cfbd)
279 a8083063 Iustin Pop
280 4c8ba8b3 Iustin Pop
  @staticmethod
281 4c8ba8b3 Iustin Pop
  def perspective_blockdev_grow(params):
282 4c8ba8b3 Iustin Pop
    """Grow a stack of devices.
283 4c8ba8b3 Iustin Pop
284 4c8ba8b3 Iustin Pop
    """
285 4c8ba8b3 Iustin Pop
    cfbd = objects.Disk.FromDict(params[0])
286 4c8ba8b3 Iustin Pop
    amount = params[1]
287 821d1bd1 Iustin Pop
    return backend.BlockdevGrow(cfbd, amount)
288 4c8ba8b3 Iustin Pop
289 d61cbe76 Iustin Pop
  @staticmethod
290 d61cbe76 Iustin Pop
  def perspective_blockdev_close(params):
291 d61cbe76 Iustin Pop
    """Closes the given block devices.
292 d61cbe76 Iustin Pop
293 d61cbe76 Iustin Pop
    """
294 b2e7666a Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in params[1]]
295 821d1bd1 Iustin Pop
    return backend.BlockdevClose(params[0], disks)
296 d61cbe76 Iustin Pop
297 968a7623 Iustin Pop
  @staticmethod
298 968a7623 Iustin Pop
  def perspective_blockdev_getsize(params):
299 968a7623 Iustin Pop
    """Compute the sizes of the given block devices.
300 968a7623 Iustin Pop
301 968a7623 Iustin Pop
    """
302 968a7623 Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in params[0]]
303 968a7623 Iustin Pop
    return backend.BlockdevGetsize(disks)
304 968a7623 Iustin Pop
305 858f3d18 Iustin Pop
  @staticmethod
306 858f3d18 Iustin Pop
  def perspective_blockdev_export(params):
307 858f3d18 Iustin Pop
    """Compute the sizes of the given block devices.
308 858f3d18 Iustin Pop
309 858f3d18 Iustin Pop
    """
310 858f3d18 Iustin Pop
    disk = objects.Disk.FromDict(params[0])
311 858f3d18 Iustin Pop
    dest_node, dest_path, cluster_name = params[1:]
312 858f3d18 Iustin Pop
    return backend.BlockdevExport(disk, dest_node, dest_path, cluster_name)
313 858f3d18 Iustin Pop
314 6b93ec9d Iustin Pop
  # blockdev/drbd specific methods ----------
315 6b93ec9d Iustin Pop
316 6b93ec9d Iustin Pop
  @staticmethod
317 6b93ec9d Iustin Pop
  def perspective_drbd_disconnect_net(params):
318 6b93ec9d Iustin Pop
    """Disconnects the network connection of drbd disks.
319 6b93ec9d Iustin Pop
320 6b93ec9d Iustin Pop
    Note that this is only valid for drbd disks, so the members of the
321 6b93ec9d Iustin Pop
    disk list must all be drbd devices.
322 6b93ec9d Iustin Pop
323 6b93ec9d Iustin Pop
    """
324 6b93ec9d Iustin Pop
    nodes_ip, disks = params
325 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
326 6b93ec9d Iustin Pop
    return backend.DrbdDisconnectNet(nodes_ip, disks)
327 6b93ec9d Iustin Pop
328 6b93ec9d Iustin Pop
  @staticmethod
329 6b93ec9d Iustin Pop
  def perspective_drbd_attach_net(params):
330 6b93ec9d Iustin Pop
    """Attaches the network connection of drbd disks.
331 6b93ec9d Iustin Pop
332 6b93ec9d Iustin Pop
    Note that this is only valid for drbd disks, so the members of the
333 6b93ec9d Iustin Pop
    disk list must all be drbd devices.
334 6b93ec9d Iustin Pop
335 6b93ec9d Iustin Pop
    """
336 6b93ec9d Iustin Pop
    nodes_ip, disks, instance_name, multimaster = params
337 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
338 821d1bd1 Iustin Pop
    return backend.DrbdAttachNet(nodes_ip, disks,
339 821d1bd1 Iustin Pop
                                     instance_name, multimaster)
340 6b93ec9d Iustin Pop
341 6b93ec9d Iustin Pop
  @staticmethod
342 6b93ec9d Iustin Pop
  def perspective_drbd_wait_sync(params):
343 6b93ec9d Iustin Pop
    """Wait until DRBD disks are synched.
344 6b93ec9d Iustin Pop
345 6b93ec9d Iustin Pop
    Note that this is only valid for drbd disks, so the members of the
346 6b93ec9d Iustin Pop
    disk list must all be drbd devices.
347 6b93ec9d Iustin Pop
348 6b93ec9d Iustin Pop
    """
349 6b93ec9d Iustin Pop
    nodes_ip, disks = params
350 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
351 6b93ec9d Iustin Pop
    return backend.DrbdWaitSync(nodes_ip, disks)
352 6b93ec9d Iustin Pop
353 a8083063 Iustin Pop
  # export/import  --------------------------
354 a8083063 Iustin Pop
355 3ecf6786 Iustin Pop
  @staticmethod
356 3ecf6786 Iustin Pop
  def perspective_finalize_export(params):
357 3ecf6786 Iustin Pop
    """Expose the finalize export functionality.
358 a8083063 Iustin Pop
359 3ecf6786 Iustin Pop
    """
360 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
361 7b651654 Michael Hanselmann
362 7b651654 Michael Hanselmann
    snap_disks = []
363 7b651654 Michael Hanselmann
    for disk in params[1]:
364 7b651654 Michael Hanselmann
      if isinstance(disk, bool):
365 7b651654 Michael Hanselmann
        snap_disks.append(disk)
366 7b651654 Michael Hanselmann
      else:
367 7b651654 Michael Hanselmann
        snap_disks.append(objects.Disk.FromDict(disk))
368 7b651654 Michael Hanselmann
369 a8083063 Iustin Pop
    return backend.FinalizeExport(instance, snap_disks)
370 a8083063 Iustin Pop
371 3ecf6786 Iustin Pop
  @staticmethod
372 3ecf6786 Iustin Pop
  def perspective_export_info(params):
373 3ecf6786 Iustin Pop
    """Query information about an existing export on this node.
374 3ecf6786 Iustin Pop
375 3ecf6786 Iustin Pop
    The given path may not contain an export, in which case we return
376 3ecf6786 Iustin Pop
    None.
377 3ecf6786 Iustin Pop
378 3ecf6786 Iustin Pop
    """
379 3ecf6786 Iustin Pop
    path = params[0]
380 3eccac06 Iustin Pop
    return backend.ExportInfo(path)
381 a8083063 Iustin Pop
382 3ecf6786 Iustin Pop
  @staticmethod
383 3ecf6786 Iustin Pop
  def perspective_export_list(params):
384 3ecf6786 Iustin Pop
    """List the available exports on this node.
385 3ecf6786 Iustin Pop
386 3ecf6786 Iustin Pop
    Note that as opposed to export_info, which may query data about an
387 3ecf6786 Iustin Pop
    export in any path, this only queries the standard Ganeti path
388 3ecf6786 Iustin Pop
    (constants.EXPORT_DIR).
389 3ecf6786 Iustin Pop
390 3ecf6786 Iustin Pop
    """
391 a8083063 Iustin Pop
    return backend.ListExports()
392 a8083063 Iustin Pop
393 3ecf6786 Iustin Pop
  @staticmethod
394 3ecf6786 Iustin Pop
  def perspective_export_remove(params):
395 3ecf6786 Iustin Pop
    """Remove an export.
396 3ecf6786 Iustin Pop
397 3ecf6786 Iustin Pop
    """
398 a8083063 Iustin Pop
    export = params[0]
399 a8083063 Iustin Pop
    return backend.RemoveExport(export)
400 a8083063 Iustin Pop
401 a8083063 Iustin Pop
  # volume  --------------------------
402 a8083063 Iustin Pop
403 3ecf6786 Iustin Pop
  @staticmethod
404 b2a6ccd4 Iustin Pop
  def perspective_lv_list(params):
405 3ecf6786 Iustin Pop
    """Query the list of logical volumes in a given volume group.
406 3ecf6786 Iustin Pop
407 3ecf6786 Iustin Pop
    """
408 a8083063 Iustin Pop
    vgname = params[0]
409 c26a6bd2 Iustin Pop
    return backend.GetVolumeList(vgname)
410 a8083063 Iustin Pop
411 3ecf6786 Iustin Pop
  @staticmethod
412 3ecf6786 Iustin Pop
  def perspective_vg_list(params):
413 3ecf6786 Iustin Pop
    """Query the list of volume groups.
414 3ecf6786 Iustin Pop
415 3ecf6786 Iustin Pop
    """
416 a8083063 Iustin Pop
    return backend.ListVolumeGroups()
417 a8083063 Iustin Pop
418 e337de97 Michael Hanselmann
  # Storage --------------------------
419 e337de97 Michael Hanselmann
420 e337de97 Michael Hanselmann
  @staticmethod
421 e337de97 Michael Hanselmann
  def perspective_storage_list(params):
422 e337de97 Michael Hanselmann
    """Get list of storage units.
423 e337de97 Michael Hanselmann
424 e337de97 Michael Hanselmann
    """
425 e337de97 Michael Hanselmann
    (su_name, su_args, name, fields) = params
426 e337de97 Michael Hanselmann
    return storage.GetStorage(su_name, *su_args).List(name, fields)
427 e337de97 Michael Hanselmann
428 8979196a Michael Hanselmann
  @staticmethod
429 8979196a Michael Hanselmann
  def perspective_storage_modify(params):
430 8979196a Michael Hanselmann
    """Modify a storage unit.
431 8979196a Michael Hanselmann
432 8979196a Michael Hanselmann
    """
433 8979196a Michael Hanselmann
    (su_name, su_args, name, changes) = params
434 8979196a Michael Hanselmann
    return storage.GetStorage(su_name, *su_args).Modify(name, changes)
435 8979196a Michael Hanselmann
436 637b8d7e Michael Hanselmann
  @staticmethod
437 637b8d7e Michael Hanselmann
  def perspective_storage_execute(params):
438 637b8d7e Michael Hanselmann
    """Execute an operation on a storage unit.
439 637b8d7e Michael Hanselmann
440 637b8d7e Michael Hanselmann
    """
441 637b8d7e Michael Hanselmann
    (su_name, su_args, name, op) = params
442 637b8d7e Michael Hanselmann
    return storage.GetStorage(su_name, *su_args).Execute(name, op)
443 637b8d7e Michael Hanselmann
444 a8083063 Iustin Pop
  # bridge  --------------------------
445 a8083063 Iustin Pop
446 3ecf6786 Iustin Pop
  @staticmethod
447 3ecf6786 Iustin Pop
  def perspective_bridges_exist(params):
448 3ecf6786 Iustin Pop
    """Check if all bridges given exist on this node.
449 3ecf6786 Iustin Pop
450 3ecf6786 Iustin Pop
    """
451 a8083063 Iustin Pop
    bridges_list = params[0]
452 a8083063 Iustin Pop
    return backend.BridgesExist(bridges_list)
453 a8083063 Iustin Pop
454 a8083063 Iustin Pop
  # instance  --------------------------
455 a8083063 Iustin Pop
456 3ecf6786 Iustin Pop
  @staticmethod
457 3ecf6786 Iustin Pop
  def perspective_instance_os_add(params):
458 3ecf6786 Iustin Pop
    """Install an OS on a given instance.
459 3ecf6786 Iustin Pop
460 3ecf6786 Iustin Pop
    """
461 d15a9ad3 Guido Trotter
    inst_s = params[0]
462 319856a9 Michael Hanselmann
    inst = objects.Instance.FromDict(inst_s)
463 e557bae9 Guido Trotter
    reinstall = params[1]
464 4a0e011f Iustin Pop
    debug = params[2]
465 4a0e011f Iustin Pop
    return backend.InstanceOsAdd(inst, reinstall, debug)
466 a8083063 Iustin Pop
467 3ecf6786 Iustin Pop
  @staticmethod
468 decd5f45 Iustin Pop
  def perspective_instance_run_rename(params):
469 decd5f45 Iustin Pop
    """Runs the OS rename script for an instance.
470 decd5f45 Iustin Pop
471 decd5f45 Iustin Pop
    """
472 4a0e011f Iustin Pop
    inst_s, old_name, debug = params
473 319856a9 Michael Hanselmann
    inst = objects.Instance.FromDict(inst_s)
474 4a0e011f Iustin Pop
    return backend.RunRenameInstance(inst, old_name, debug)
475 decd5f45 Iustin Pop
476 decd5f45 Iustin Pop
  @staticmethod
477 3ecf6786 Iustin Pop
  def perspective_instance_shutdown(params):
478 3ecf6786 Iustin Pop
    """Shutdown an instance.
479 3ecf6786 Iustin Pop
480 3ecf6786 Iustin Pop
    """
481 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
482 6263189c Guido Trotter
    timeout = params[1]
483 6263189c Guido Trotter
    return backend.InstanceShutdown(instance, timeout)
484 a8083063 Iustin Pop
485 3ecf6786 Iustin Pop
  @staticmethod
486 3ecf6786 Iustin Pop
  def perspective_instance_start(params):
487 3ecf6786 Iustin Pop
    """Start an instance.
488 3ecf6786 Iustin Pop
489 3ecf6786 Iustin Pop
    """
490 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
491 07813a9e Iustin Pop
    return backend.StartInstance(instance)
492 a8083063 Iustin Pop
493 3ecf6786 Iustin Pop
  @staticmethod
494 6906a9d8 Guido Trotter
  def perspective_migration_info(params):
495 6906a9d8 Guido Trotter
    """Gather information about an instance to be migrated.
496 6906a9d8 Guido Trotter
497 6906a9d8 Guido Trotter
    """
498 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(params[0])
499 6906a9d8 Guido Trotter
    return backend.MigrationInfo(instance)
500 6906a9d8 Guido Trotter
501 6906a9d8 Guido Trotter
  @staticmethod
502 6906a9d8 Guido Trotter
  def perspective_accept_instance(params):
503 6906a9d8 Guido Trotter
    """Prepare the node to accept an instance.
504 6906a9d8 Guido Trotter
505 6906a9d8 Guido Trotter
    """
506 6906a9d8 Guido Trotter
    instance, info, target = params
507 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(instance)
508 6906a9d8 Guido Trotter
    return backend.AcceptInstance(instance, info, target)
509 6906a9d8 Guido Trotter
510 6906a9d8 Guido Trotter
  @staticmethod
511 6906a9d8 Guido Trotter
  def perspective_finalize_migration(params):
512 6906a9d8 Guido Trotter
    """Finalize the instance migration.
513 6906a9d8 Guido Trotter
514 6906a9d8 Guido Trotter
    """
515 6906a9d8 Guido Trotter
    instance, info, success = params
516 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(instance)
517 6906a9d8 Guido Trotter
    return backend.FinalizeMigration(instance, info, success)
518 6906a9d8 Guido Trotter
519 6906a9d8 Guido Trotter
  @staticmethod
520 2a10865c Iustin Pop
  def perspective_instance_migrate(params):
521 2a10865c Iustin Pop
    """Migrates an instance.
522 2a10865c Iustin Pop
523 2a10865c Iustin Pop
    """
524 2a10865c Iustin Pop
    instance, target, live = params
525 9f0e6b37 Iustin Pop
    instance = objects.Instance.FromDict(instance)
526 2a10865c Iustin Pop
    return backend.MigrateInstance(instance, target, live)
527 2a10865c Iustin Pop
528 2a10865c Iustin Pop
  @staticmethod
529 007a2f3e Alexander Schreiber
  def perspective_instance_reboot(params):
530 007a2f3e Alexander Schreiber
    """Reboot an instance.
531 007a2f3e Alexander Schreiber
532 007a2f3e Alexander Schreiber
    """
533 007a2f3e Alexander Schreiber
    instance = objects.Instance.FromDict(params[0])
534 007a2f3e Alexander Schreiber
    reboot_type = params[1]
535 17c3f802 Guido Trotter
    shutdown_timeout = params[2]
536 17c3f802 Guido Trotter
    return backend.InstanceReboot(instance, reboot_type, shutdown_timeout)
537 007a2f3e Alexander Schreiber
538 007a2f3e Alexander Schreiber
  @staticmethod
539 3ecf6786 Iustin Pop
  def perspective_instance_info(params):
540 3ecf6786 Iustin Pop
    """Query instance information.
541 3ecf6786 Iustin Pop
542 3ecf6786 Iustin Pop
    """
543 16ad1a83 Iustin Pop
    return backend.GetInstanceInfo(params[0], params[1])
544 a8083063 Iustin Pop
545 3ecf6786 Iustin Pop
  @staticmethod
546 56e7640c Iustin Pop
  def perspective_instance_migratable(params):
547 56e7640c Iustin Pop
    """Query whether the specified instance can be migrated.
548 56e7640c Iustin Pop
549 56e7640c Iustin Pop
    """
550 56e7640c Iustin Pop
    instance = objects.Instance.FromDict(params[0])
551 56e7640c Iustin Pop
    return backend.GetInstanceMigratable(instance)
552 56e7640c Iustin Pop
553 56e7640c Iustin Pop
  @staticmethod
554 3ecf6786 Iustin Pop
  def perspective_all_instances_info(params):
555 3ecf6786 Iustin Pop
    """Query information about all instances.
556 3ecf6786 Iustin Pop
557 3ecf6786 Iustin Pop
    """
558 e69d05fd Iustin Pop
    return backend.GetAllInstancesInfo(params[0])
559 a8083063 Iustin Pop
560 3ecf6786 Iustin Pop
  @staticmethod
561 3ecf6786 Iustin Pop
  def perspective_instance_list(params):
562 3ecf6786 Iustin Pop
    """Query the list of running instances.
563 3ecf6786 Iustin Pop
564 3ecf6786 Iustin Pop
    """
565 c26a6bd2 Iustin Pop
    return backend.GetInstanceList(params[0])
566 a8083063 Iustin Pop
567 a8083063 Iustin Pop
  # node --------------------------
568 a8083063 Iustin Pop
569 3ecf6786 Iustin Pop
  @staticmethod
570 16abfbc2 Alexander Schreiber
  def perspective_node_tcp_ping(params):
571 16abfbc2 Alexander Schreiber
    """Do a TcpPing on the remote node.
572 16abfbc2 Alexander Schreiber
573 16abfbc2 Alexander Schreiber
    """
574 b15d625f Iustin Pop
    return utils.TcpPing(params[1], params[2], timeout=params[3],
575 b15d625f Iustin Pop
                         live_port_needed=params[4], source=params[0])
576 16abfbc2 Alexander Schreiber
577 16abfbc2 Alexander Schreiber
  @staticmethod
578 caad16e2 Iustin Pop
  def perspective_node_has_ip_address(params):
579 caad16e2 Iustin Pop
    """Checks if a node has the given ip address.
580 caad16e2 Iustin Pop
581 caad16e2 Iustin Pop
    """
582 c26a6bd2 Iustin Pop
    return utils.OwnIpAddress(params[0])
583 caad16e2 Iustin Pop
584 caad16e2 Iustin Pop
  @staticmethod
585 3ecf6786 Iustin Pop
  def perspective_node_info(params):
586 3ecf6786 Iustin Pop
    """Query node information.
587 3ecf6786 Iustin Pop
588 3ecf6786 Iustin Pop
    """
589 e69d05fd Iustin Pop
    vgname, hypervisor_type = params
590 e69d05fd Iustin Pop
    return backend.GetNodeInfo(vgname, hypervisor_type)
591 a8083063 Iustin Pop
592 3ecf6786 Iustin Pop
  @staticmethod
593 3ecf6786 Iustin Pop
  def perspective_node_add(params):
594 3ecf6786 Iustin Pop
    """Complete the registration of this node in the cluster.
595 3ecf6786 Iustin Pop
596 3ecf6786 Iustin Pop
    """
597 a8083063 Iustin Pop
    return backend.AddNode(params[0], params[1], params[2],
598 a8083063 Iustin Pop
                           params[3], params[4], params[5])
599 a8083063 Iustin Pop
600 3ecf6786 Iustin Pop
  @staticmethod
601 3ecf6786 Iustin Pop
  def perspective_node_verify(params):
602 3ecf6786 Iustin Pop
    """Run a verify sequence on this node.
603 3ecf6786 Iustin Pop
604 3ecf6786 Iustin Pop
    """
605 62c9ec92 Iustin Pop
    return backend.VerifyNode(params[0], params[1])
606 a8083063 Iustin Pop
607 3ecf6786 Iustin Pop
  @staticmethod
608 3ecf6786 Iustin Pop
  def perspective_node_start_master(params):
609 3ecf6786 Iustin Pop
    """Promote this node to master status.
610 3ecf6786 Iustin Pop
611 3ecf6786 Iustin Pop
    """
612 3583908a Guido Trotter
    return backend.StartMaster(params[0], params[1])
613 a8083063 Iustin Pop
614 3ecf6786 Iustin Pop
  @staticmethod
615 3ecf6786 Iustin Pop
  def perspective_node_stop_master(params):
616 3ecf6786 Iustin Pop
    """Demote this node from master status.
617 3ecf6786 Iustin Pop
618 3ecf6786 Iustin Pop
    """
619 1c65840b Iustin Pop
    return backend.StopMaster(params[0])
620 a8083063 Iustin Pop
621 3ecf6786 Iustin Pop
  @staticmethod
622 3ecf6786 Iustin Pop
  def perspective_node_leave_cluster(params):
623 3ecf6786 Iustin Pop
    """Cleanup after leaving a cluster.
624 3ecf6786 Iustin Pop
625 3ecf6786 Iustin Pop
    """
626 b989b9d9 Ken Wehr
    return backend.LeaveCluster(params[0])
627 a8083063 Iustin Pop
628 3ecf6786 Iustin Pop
  @staticmethod
629 3ecf6786 Iustin Pop
  def perspective_node_volumes(params):
630 3ecf6786 Iustin Pop
    """Query the list of all logical volume groups.
631 3ecf6786 Iustin Pop
632 3ecf6786 Iustin Pop
    """
633 dcb93971 Michael Hanselmann
    return backend.NodeVolumes()
634 dcb93971 Michael Hanselmann
635 56aa9fd5 Iustin Pop
  @staticmethod
636 56aa9fd5 Iustin Pop
  def perspective_node_demote_from_mc(params):
637 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
638 56aa9fd5 Iustin Pop
639 56aa9fd5 Iustin Pop
    """
640 56aa9fd5 Iustin Pop
    return backend.DemoteFromMC()
641 56aa9fd5 Iustin Pop
642 56aa9fd5 Iustin Pop
643 f5118ade Iustin Pop
  @staticmethod
644 f5118ade Iustin Pop
  def perspective_node_powercycle(params):
645 f5118ade Iustin Pop
    """Tries to powercycle the nod.
646 f5118ade Iustin Pop
647 f5118ade Iustin Pop
    """
648 f5118ade Iustin Pop
    hypervisor_type = params[0]
649 f5118ade Iustin Pop
    return backend.PowercycleNode(hypervisor_type)
650 f5118ade Iustin Pop
651 f5118ade Iustin Pop
652 a8083063 Iustin Pop
  # cluster --------------------------
653 a8083063 Iustin Pop
654 3ecf6786 Iustin Pop
  @staticmethod
655 3ecf6786 Iustin Pop
  def perspective_version(params):
656 3ecf6786 Iustin Pop
    """Query version information.
657 3ecf6786 Iustin Pop
658 3ecf6786 Iustin Pop
    """
659 c26a6bd2 Iustin Pop
    return constants.PROTOCOL_VERSION
660 a8083063 Iustin Pop
661 3ecf6786 Iustin Pop
  @staticmethod
662 3ecf6786 Iustin Pop
  def perspective_upload_file(params):
663 3ecf6786 Iustin Pop
    """Upload a file.
664 3ecf6786 Iustin Pop
665 3ecf6786 Iustin Pop
    Note that the backend implementation imposes strict rules on which
666 3ecf6786 Iustin Pop
    files are accepted.
667 3ecf6786 Iustin Pop
668 3ecf6786 Iustin Pop
    """
669 a8083063 Iustin Pop
    return backend.UploadFile(*params)
670 a8083063 Iustin Pop
671 4e071d3b Iustin Pop
  @staticmethod
672 4e071d3b Iustin Pop
  def perspective_master_info(params):
673 4e071d3b Iustin Pop
    """Query master information.
674 4e071d3b Iustin Pop
675 4e071d3b Iustin Pop
    """
676 4e071d3b Iustin Pop
    return backend.GetMasterInfo()
677 a8083063 Iustin Pop
678 6ddc95ec Michael Hanselmann
  @staticmethod
679 6ddc95ec Michael Hanselmann
  def perspective_write_ssconf_files(params):
680 6ddc95ec Michael Hanselmann
    """Write ssconf files.
681 6ddc95ec Michael Hanselmann
682 6ddc95ec Michael Hanselmann
    """
683 03d1dba2 Michael Hanselmann
    (values,) = params
684 03d1dba2 Michael Hanselmann
    return backend.WriteSsconfFiles(values)
685 6ddc95ec Michael Hanselmann
686 a8083063 Iustin Pop
  # os -----------------------
687 a8083063 Iustin Pop
688 3ecf6786 Iustin Pop
  @staticmethod
689 3ecf6786 Iustin Pop
  def perspective_os_diagnose(params):
690 3ecf6786 Iustin Pop
    """Query detailed information about existing OSes.
691 3ecf6786 Iustin Pop
692 3ecf6786 Iustin Pop
    """
693 255dcebd Iustin Pop
    return backend.DiagnoseOS()
694 a8083063 Iustin Pop
695 3ecf6786 Iustin Pop
  @staticmethod
696 3ecf6786 Iustin Pop
  def perspective_os_get(params):
697 3ecf6786 Iustin Pop
    """Query information about a given OS.
698 3ecf6786 Iustin Pop
699 3ecf6786 Iustin Pop
    """
700 a8083063 Iustin Pop
    name = params[0]
701 255dcebd Iustin Pop
    os_obj = backend.OSFromDisk(name)
702 c26a6bd2 Iustin Pop
    return os_obj.ToDict()
703 a8083063 Iustin Pop
704 a8083063 Iustin Pop
  # hooks -----------------------
705 a8083063 Iustin Pop
706 3ecf6786 Iustin Pop
  @staticmethod
707 3ecf6786 Iustin Pop
  def perspective_hooks_runner(params):
708 3ecf6786 Iustin Pop
    """Run hook scripts.
709 3ecf6786 Iustin Pop
710 3ecf6786 Iustin Pop
    """
711 a8083063 Iustin Pop
    hpath, phase, env = params
712 a8083063 Iustin Pop
    hr = backend.HooksRunner()
713 a8083063 Iustin Pop
    return hr.RunHooks(hpath, phase, env)
714 a8083063 Iustin Pop
715 8d528b7c Iustin Pop
  # iallocator -----------------
716 8d528b7c Iustin Pop
717 8d528b7c Iustin Pop
  @staticmethod
718 8d528b7c Iustin Pop
  def perspective_iallocator_runner(params):
719 8d528b7c Iustin Pop
    """Run an iallocator script.
720 8d528b7c Iustin Pop
721 8d528b7c Iustin Pop
    """
722 8d528b7c Iustin Pop
    name, idata = params
723 8d528b7c Iustin Pop
    iar = backend.IAllocatorRunner()
724 8d528b7c Iustin Pop
    return iar.Run(name, idata)
725 8d528b7c Iustin Pop
726 06009e27 Iustin Pop
  # test -----------------------
727 06009e27 Iustin Pop
728 06009e27 Iustin Pop
  @staticmethod
729 06009e27 Iustin Pop
  def perspective_test_delay(params):
730 06009e27 Iustin Pop
    """Run test delay.
731 06009e27 Iustin Pop
732 06009e27 Iustin Pop
    """
733 06009e27 Iustin Pop
    duration = params[0]
734 c26a6bd2 Iustin Pop
    status, rval = utils.TestDelay(duration)
735 c26a6bd2 Iustin Pop
    if not status:
736 c26a6bd2 Iustin Pop
      raise backend.RPCFail(rval)
737 c26a6bd2 Iustin Pop
    return rval
738 06009e27 Iustin Pop
739 4e071d3b Iustin Pop
  # file storage ---------------
740 4e071d3b Iustin Pop
741 a5d7fb43 Manuel Franceschini
  @staticmethod
742 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_create(params):
743 a5d7fb43 Manuel Franceschini
    """Create the file storage directory.
744 a5d7fb43 Manuel Franceschini
745 a5d7fb43 Manuel Franceschini
    """
746 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
747 a5d7fb43 Manuel Franceschini
    return backend.CreateFileStorageDir(file_storage_dir)
748 a5d7fb43 Manuel Franceschini
749 a5d7fb43 Manuel Franceschini
  @staticmethod
750 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_remove(params):
751 a5d7fb43 Manuel Franceschini
    """Remove the file storage directory.
752 a5d7fb43 Manuel Franceschini
753 a5d7fb43 Manuel Franceschini
    """
754 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
755 a5d7fb43 Manuel Franceschini
    return backend.RemoveFileStorageDir(file_storage_dir)
756 a5d7fb43 Manuel Franceschini
757 a5d7fb43 Manuel Franceschini
  @staticmethod
758 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_rename(params):
759 a5d7fb43 Manuel Franceschini
    """Rename the file storage directory.
760 a5d7fb43 Manuel Franceschini
761 a5d7fb43 Manuel Franceschini
    """
762 a5d7fb43 Manuel Franceschini
    old_file_storage_dir = params[0]
763 a5d7fb43 Manuel Franceschini
    new_file_storage_dir = params[1]
764 a5d7fb43 Manuel Franceschini
    return backend.RenameFileStorageDir(old_file_storage_dir,
765 a5d7fb43 Manuel Franceschini
                                        new_file_storage_dir)
766 a5d7fb43 Manuel Franceschini
767 4e071d3b Iustin Pop
  # jobs ------------------------
768 4e071d3b Iustin Pop
769 ca52cdeb Michael Hanselmann
  @staticmethod
770 7f30777b Michael Hanselmann
  @_RequireJobQueueLock
771 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_update(params):
772 ca52cdeb Michael Hanselmann
    """Update job queue.
773 ca52cdeb Michael Hanselmann
774 ca52cdeb Michael Hanselmann
    """
775 ca52cdeb Michael Hanselmann
    (file_name, content) = params
776 7f30777b Michael Hanselmann
    return backend.JobQueueUpdate(file_name, content)
777 ca52cdeb Michael Hanselmann
778 ca52cdeb Michael Hanselmann
  @staticmethod
779 f1f3f45c Michael Hanselmann
  @_RequireJobQueueLock
780 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_purge(params):
781 ca52cdeb Michael Hanselmann
    """Purge job queue.
782 ca52cdeb Michael Hanselmann
783 ca52cdeb Michael Hanselmann
    """
784 ca52cdeb Michael Hanselmann
    return backend.JobQueuePurge()
785 ca52cdeb Michael Hanselmann
786 af5ebcb1 Michael Hanselmann
  @staticmethod
787 af5ebcb1 Michael Hanselmann
  @_RequireJobQueueLock
788 af5ebcb1 Michael Hanselmann
  def perspective_jobqueue_rename(params):
789 af5ebcb1 Michael Hanselmann
    """Rename a job queue file.
790 af5ebcb1 Michael Hanselmann
791 af5ebcb1 Michael Hanselmann
    """
792 dd875d32 Michael Hanselmann
    # TODO: What if a file fails to rename?
793 c26a6bd2 Iustin Pop
    return [backend.JobQueueRename(old, new) for old, new in params]
794 af5ebcb1 Michael Hanselmann
795 5d672980 Iustin Pop
  @staticmethod
796 5d672980 Iustin Pop
  def perspective_jobqueue_set_drain(params):
797 5d672980 Iustin Pop
    """Set/unset the queue drain flag.
798 5d672980 Iustin Pop
799 5d672980 Iustin Pop
    """
800 5d672980 Iustin Pop
    drain_flag = params[0]
801 5d672980 Iustin Pop
    return backend.JobQueueSetDrainFlag(drain_flag)
802 5d672980 Iustin Pop
803 5d672980 Iustin Pop
804 6217e295 Iustin Pop
  # hypervisor ---------------
805 6217e295 Iustin Pop
806 6217e295 Iustin Pop
  @staticmethod
807 6217e295 Iustin Pop
  def perspective_hypervisor_validate_params(params):
808 6217e295 Iustin Pop
    """Validate the hypervisor parameters.
809 6217e295 Iustin Pop
810 6217e295 Iustin Pop
    """
811 6217e295 Iustin Pop
    (hvname, hvparams) = params
812 6217e295 Iustin Pop
    return backend.ValidateHVParams(hvname, hvparams)
813 6217e295 Iustin Pop
814 f942a838 Michael Hanselmann
  # Crypto
815 f942a838 Michael Hanselmann
816 f942a838 Michael Hanselmann
  @staticmethod
817 ef40fbfb Michael Hanselmann
  def perspective_x509_cert_create(params):
818 f942a838 Michael Hanselmann
    """Creates a new X509 certificate for SSL/TLS.
819 f942a838 Michael Hanselmann
820 f942a838 Michael Hanselmann
    """
821 f942a838 Michael Hanselmann
    (validity, ) = params
822 f942a838 Michael Hanselmann
    return backend.CreateX509Certificate(validity)
823 f942a838 Michael Hanselmann
824 f942a838 Michael Hanselmann
  @staticmethod
825 ef40fbfb Michael Hanselmann
  def perspective_x509_cert_remove(params):
826 f942a838 Michael Hanselmann
    """Removes a X509 certificate.
827 f942a838 Michael Hanselmann
828 f942a838 Michael Hanselmann
    """
829 f942a838 Michael Hanselmann
    (name, ) = params
830 f942a838 Michael Hanselmann
    return backend.RemoveX509Certificate(name)
831 f942a838 Michael Hanselmann
832 1651d116 Michael Hanselmann
  # Import and export
833 1651d116 Michael Hanselmann
834 1651d116 Michael Hanselmann
  @staticmethod
835 ef40fbfb Michael Hanselmann
  def perspective_import_start(params):
836 1651d116 Michael Hanselmann
    """Starts an import daemon.
837 1651d116 Michael Hanselmann
838 1651d116 Michael Hanselmann
    """
839 1651d116 Michael Hanselmann
    (x509_key_name, source_x509_ca, instance, dest, dest_args) = params
840 1651d116 Michael Hanselmann
    return backend.StartImportExportDaemon(constants.IEM_IMPORT,
841 1651d116 Michael Hanselmann
                                           x509_key_name, source_x509_ca,
842 1651d116 Michael Hanselmann
                                           None, None,
843 1651d116 Michael Hanselmann
                                           objects.Instance.FromDict(instance),
844 1651d116 Michael Hanselmann
                                           dest,
845 1651d116 Michael Hanselmann
                                           _DecodeImportExportIO(dest,
846 1651d116 Michael Hanselmann
                                                                 dest_args))
847 1651d116 Michael Hanselmann
  @staticmethod
848 ef40fbfb Michael Hanselmann
  def perspective_export_start(params):
849 1651d116 Michael Hanselmann
    """Starts an export daemon.
850 1651d116 Michael Hanselmann
851 1651d116 Michael Hanselmann
    """
852 1651d116 Michael Hanselmann
    (x509_key_name, dest_x509_ca, host, port, instance,
853 1651d116 Michael Hanselmann
     source, source_args) = params
854 1651d116 Michael Hanselmann
    return backend.StartImportExportDaemon(constants.IEM_EXPORT,
855 1651d116 Michael Hanselmann
                                           x509_key_name, dest_x509_ca,
856 1651d116 Michael Hanselmann
                                           host, port,
857 1651d116 Michael Hanselmann
                                           objects.Instance.FromDict(instance),
858 1651d116 Michael Hanselmann
                                           source,
859 1651d116 Michael Hanselmann
                                           _DecodeImportExportIO(source,
860 1651d116 Michael Hanselmann
                                                                 source_args))
861 1651d116 Michael Hanselmann
862 1651d116 Michael Hanselmann
  @staticmethod
863 ef40fbfb Michael Hanselmann
  def perspective_impexp_status(params):
864 1651d116 Michael Hanselmann
    """Retrieves the status of an import or export daemon.
865 1651d116 Michael Hanselmann
866 1651d116 Michael Hanselmann
    """
867 1651d116 Michael Hanselmann
    return backend.GetImportExportStatus(params[0])
868 1651d116 Michael Hanselmann
869 1651d116 Michael Hanselmann
  @staticmethod
870 f81c4737 Michael Hanselmann
  def perspective_impexp_abort(params):
871 f81c4737 Michael Hanselmann
    """Aborts an import or export.
872 f81c4737 Michael Hanselmann
873 f81c4737 Michael Hanselmann
    """
874 f81c4737 Michael Hanselmann
    return backend.AbortImportExport(params[0])
875 f81c4737 Michael Hanselmann
876 f81c4737 Michael Hanselmann
  @staticmethod
877 ef40fbfb Michael Hanselmann
  def perspective_impexp_cleanup(params):
878 1651d116 Michael Hanselmann
    """Cleans up after an import or export.
879 1651d116 Michael Hanselmann
880 1651d116 Michael Hanselmann
    """
881 1651d116 Michael Hanselmann
    return backend.CleanupImportExport(params[0])
882 1651d116 Michael Hanselmann
883 a8083063 Iustin Pop
884 f93427cd Iustin Pop
def CheckNoded(_, args):
885 f93427cd Iustin Pop
  """Initial checks whether to run or exit with a failure.
886 f93427cd Iustin Pop
887 f93427cd Iustin Pop
  """
888 f93427cd Iustin Pop
  if args: # noded doesn't take any arguments
889 f93427cd Iustin Pop
    print >> sys.stderr, ("Usage: %s [-f] [-d] [-p port] [-b ADDRESS]" %
890 f93427cd Iustin Pop
                          sys.argv[0])
891 f93427cd Iustin Pop
    sys.exit(constants.EXIT_FAILURE)
892 f93427cd Iustin Pop
893 f93427cd Iustin Pop
894 2d54e29c Iustin Pop
def ExecNoded(options, _):
895 6c948699 Michael Hanselmann
  """Main node daemon function, executed with the PID file held.
896 3ecf6786 Iustin Pop
897 3ecf6786 Iustin Pop
  """
898 04ccf5e9 Guido Trotter
  # Read SSL certificate
899 3b1b0cb6 Guido Trotter
  if options.ssl:
900 3b1b0cb6 Guido Trotter
    ssl_params = http.HttpSslParams(ssl_key_path=options.ssl_key,
901 3b1b0cb6 Guido Trotter
                                    ssl_cert_path=options.ssl_cert)
902 3b1b0cb6 Guido Trotter
  else:
903 3b1b0cb6 Guido Trotter
    ssl_params = None
904 7d88772a Iustin Pop
905 81198f6e Iustin Pop
  err = _PrepareQueueLock()
906 81198f6e Iustin Pop
  if err is not None:
907 81198f6e Iustin Pop
    # this might be some kind of file-system/permission error; while
908 81198f6e Iustin Pop
    # this breaks the job queue functionality, we shouldn't prevent
909 81198f6e Iustin Pop
    # startup of the whole node daemon because of this
910 81198f6e Iustin Pop
    logging.critical("Can't init/verify the queue, proceeding anyway: %s", err)
911 7d88772a Iustin Pop
912 04ccf5e9 Guido Trotter
  mainloop = daemon.Mainloop()
913 04ccf5e9 Guido Trotter
  server = NodeHttpServer(mainloop, options.bind_address, options.port,
914 04ccf5e9 Guido Trotter
                          ssl_params=ssl_params, ssl_verify_peer=True)
915 04ccf5e9 Guido Trotter
  server.Start()
916 04ccf5e9 Guido Trotter
  try:
917 04ccf5e9 Guido Trotter
    mainloop.Run()
918 04ccf5e9 Guido Trotter
  finally:
919 04ccf5e9 Guido Trotter
    server.Stop()
920 a8083063 Iustin Pop
921 a8083063 Iustin Pop
922 04ccf5e9 Guido Trotter
def main():
923 04ccf5e9 Guido Trotter
  """Main function for the node daemon.
924 04ccf5e9 Guido Trotter
925 04ccf5e9 Guido Trotter
  """
926 04ccf5e9 Guido Trotter
  parser = OptionParser(description="Ganeti node daemon",
927 04ccf5e9 Guido Trotter
                        usage="%prog [-f] [-d] [-p port] [-b ADDRESS]",
928 04ccf5e9 Guido Trotter
                        version="%%prog (ganeti) %s" %
929 04ccf5e9 Guido Trotter
                        constants.RELEASE_VERSION)
930 9dae41ad Guido Trotter
  dirs = [(val, constants.RUN_DIRS_MODE) for val in constants.SUB_RUN_DIRS]
931 9dae41ad Guido Trotter
  dirs.append((constants.LOG_OS_DIR, 0750))
932 9dae41ad Guido Trotter
  dirs.append((constants.LOCK_DIR, 1777))
933 f942a838 Michael Hanselmann
  dirs.append((constants.CRYPTO_KEYS_DIR, constants.CRYPTO_KEYS_DIR_MODE))
934 1651d116 Michael Hanselmann
  dirs.append((constants.IMPORT_EXPORT_DIR, constants.IMPORT_EXPORT_DIR_MODE))
935 24cd3744 Iustin Pop
  daemon.GenericMain(constants.NODED, parser, dirs, CheckNoded, ExecNoded,
936 084aba47 Michael Hanselmann
                     default_ssl_cert=constants.NODED_CERT_FILE,
937 084aba47 Michael Hanselmann
                     default_ssl_key=constants.NODED_CERT_FILE)
938 73d927a2 Guido Trotter
939 a8083063 Iustin Pop
940 3ecf6786 Iustin Pop
if __name__ == '__main__':
941 a8083063 Iustin Pop
  main()