Statistics
| Branch: | Tag: | Revision:

root / daemons / ganeti-noded @ 073c31a5

History | View | Annotate | Download (25.8 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 8b312c1d Manuel Franceschini
# Copyright (C) 2006, 2007, 2010 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 3ecf6786 Iustin Pop
  def perspective_blockdev_remove(params):
188 3ecf6786 Iustin Pop
    """Remove a block device.
189 3ecf6786 Iustin Pop
190 3ecf6786 Iustin Pop
    """
191 a8083063 Iustin Pop
    bdev_s = params[0]
192 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
193 821d1bd1 Iustin Pop
    return backend.BlockdevRemove(bdev)
194 a8083063 Iustin Pop
195 3ecf6786 Iustin Pop
  @staticmethod
196 f3e513ad Iustin Pop
  def perspective_blockdev_rename(params):
197 f3e513ad Iustin Pop
    """Remove a block device.
198 f3e513ad Iustin Pop
199 f3e513ad Iustin Pop
    """
200 f3e513ad Iustin Pop
    devlist = [(objects.Disk.FromDict(ds), uid) for ds, uid in params]
201 821d1bd1 Iustin Pop
    return backend.BlockdevRename(devlist)
202 f3e513ad Iustin Pop
203 f3e513ad Iustin Pop
  @staticmethod
204 3ecf6786 Iustin Pop
  def perspective_blockdev_assemble(params):
205 3ecf6786 Iustin Pop
    """Assemble a block device.
206 3ecf6786 Iustin Pop
207 3ecf6786 Iustin Pop
    """
208 3f78eef2 Iustin Pop
    bdev_s, owner, on_primary = params
209 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
210 a8083063 Iustin Pop
    if bdev is None:
211 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
212 821d1bd1 Iustin Pop
    return backend.BlockdevAssemble(bdev, owner, on_primary)
213 a8083063 Iustin Pop
214 3ecf6786 Iustin Pop
  @staticmethod
215 3ecf6786 Iustin Pop
  def perspective_blockdev_shutdown(params):
216 3ecf6786 Iustin Pop
    """Shutdown a block device.
217 3ecf6786 Iustin Pop
218 3ecf6786 Iustin Pop
    """
219 a8083063 Iustin Pop
    bdev_s = params[0]
220 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
221 a8083063 Iustin Pop
    if bdev is None:
222 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
223 821d1bd1 Iustin Pop
    return backend.BlockdevShutdown(bdev)
224 a8083063 Iustin Pop
225 3ecf6786 Iustin Pop
  @staticmethod
226 153d9724 Iustin Pop
  def perspective_blockdev_addchildren(params):
227 3ecf6786 Iustin Pop
    """Add a child to a mirror device.
228 3ecf6786 Iustin Pop
229 3ecf6786 Iustin Pop
    Note: this is only valid for mirror devices. It's the caller's duty
230 3ecf6786 Iustin Pop
    to send a correct disk, otherwise we raise an error.
231 3ecf6786 Iustin Pop
232 3ecf6786 Iustin Pop
    """
233 a8083063 Iustin Pop
    bdev_s, ndev_s = params
234 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
235 153d9724 Iustin Pop
    ndevs = [objects.Disk.FromDict(disk_s) for disk_s in ndev_s]
236 153d9724 Iustin Pop
    if bdev is None or ndevs.count(None) > 0:
237 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
238 821d1bd1 Iustin Pop
    return backend.BlockdevAddchildren(bdev, ndevs)
239 a8083063 Iustin Pop
240 3ecf6786 Iustin Pop
  @staticmethod
241 153d9724 Iustin Pop
  def perspective_blockdev_removechildren(params):
242 3ecf6786 Iustin Pop
    """Remove a child from a mirror device.
243 3ecf6786 Iustin Pop
244 3ecf6786 Iustin Pop
    This is only valid for mirror devices, of course. It's the callers
245 3ecf6786 Iustin Pop
    duty to send a correct disk, otherwise we raise an error.
246 3ecf6786 Iustin Pop
247 3ecf6786 Iustin Pop
    """
248 a8083063 Iustin Pop
    bdev_s, ndev_s = params
249 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
250 153d9724 Iustin Pop
    ndevs = [objects.Disk.FromDict(disk_s) for disk_s in ndev_s]
251 153d9724 Iustin Pop
    if bdev is None or ndevs.count(None) > 0:
252 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
253 821d1bd1 Iustin Pop
    return backend.BlockdevRemovechildren(bdev, ndevs)
254 a8083063 Iustin Pop
255 3ecf6786 Iustin Pop
  @staticmethod
256 3ecf6786 Iustin Pop
  def perspective_blockdev_getmirrorstatus(params):
257 3ecf6786 Iustin Pop
    """Return the mirror status for a list of disks.
258 3ecf6786 Iustin Pop
259 3ecf6786 Iustin Pop
    """
260 319856a9 Michael Hanselmann
    disks = [objects.Disk.FromDict(dsk_s)
261 36145b12 Michael Hanselmann
             for dsk_s in params]
262 36145b12 Michael Hanselmann
    return [status.ToDict()
263 36145b12 Michael Hanselmann
            for status in backend.BlockdevGetmirrorstatus(disks)]
264 a8083063 Iustin Pop
265 3ecf6786 Iustin Pop
  @staticmethod
266 3ecf6786 Iustin Pop
  def perspective_blockdev_find(params):
267 3ecf6786 Iustin Pop
    """Expose the FindBlockDevice functionality for a disk.
268 3ecf6786 Iustin Pop
269 3ecf6786 Iustin Pop
    This will try to find but not activate a disk.
270 3ecf6786 Iustin Pop
271 3ecf6786 Iustin Pop
    """
272 319856a9 Michael Hanselmann
    disk = objects.Disk.FromDict(params[0])
273 ddfe2228 Michael Hanselmann
274 ddfe2228 Michael Hanselmann
    result = backend.BlockdevFind(disk)
275 ddfe2228 Michael Hanselmann
    if result is None:
276 ddfe2228 Michael Hanselmann
      return None
277 ddfe2228 Michael Hanselmann
278 ddfe2228 Michael Hanselmann
    return result.ToDict()
279 a8083063 Iustin Pop
280 3ecf6786 Iustin Pop
  @staticmethod
281 3ecf6786 Iustin Pop
  def perspective_blockdev_snapshot(params):
282 3ecf6786 Iustin Pop
    """Create a snapshot device.
283 3ecf6786 Iustin Pop
284 3ecf6786 Iustin Pop
    Note that this is only valid for LVM disks, if we get passed
285 3ecf6786 Iustin Pop
    something else we raise an exception. The snapshot device can be
286 3ecf6786 Iustin Pop
    remove by calling the generic block device remove call.
287 3ecf6786 Iustin Pop
288 3ecf6786 Iustin Pop
    """
289 319856a9 Michael Hanselmann
    cfbd = objects.Disk.FromDict(params[0])
290 821d1bd1 Iustin Pop
    return backend.BlockdevSnapshot(cfbd)
291 a8083063 Iustin Pop
292 4c8ba8b3 Iustin Pop
  @staticmethod
293 4c8ba8b3 Iustin Pop
  def perspective_blockdev_grow(params):
294 4c8ba8b3 Iustin Pop
    """Grow a stack of devices.
295 4c8ba8b3 Iustin Pop
296 4c8ba8b3 Iustin Pop
    """
297 4c8ba8b3 Iustin Pop
    cfbd = objects.Disk.FromDict(params[0])
298 4c8ba8b3 Iustin Pop
    amount = params[1]
299 821d1bd1 Iustin Pop
    return backend.BlockdevGrow(cfbd, amount)
300 4c8ba8b3 Iustin Pop
301 d61cbe76 Iustin Pop
  @staticmethod
302 d61cbe76 Iustin Pop
  def perspective_blockdev_close(params):
303 d61cbe76 Iustin Pop
    """Closes the given block devices.
304 d61cbe76 Iustin Pop
305 d61cbe76 Iustin Pop
    """
306 b2e7666a Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in params[1]]
307 821d1bd1 Iustin Pop
    return backend.BlockdevClose(params[0], disks)
308 d61cbe76 Iustin Pop
309 968a7623 Iustin Pop
  @staticmethod
310 968a7623 Iustin Pop
  def perspective_blockdev_getsize(params):
311 968a7623 Iustin Pop
    """Compute the sizes of the given block devices.
312 968a7623 Iustin Pop
313 968a7623 Iustin Pop
    """
314 968a7623 Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in params[0]]
315 968a7623 Iustin Pop
    return backend.BlockdevGetsize(disks)
316 968a7623 Iustin Pop
317 858f3d18 Iustin Pop
  @staticmethod
318 858f3d18 Iustin Pop
  def perspective_blockdev_export(params):
319 858f3d18 Iustin Pop
    """Compute the sizes of the given block devices.
320 858f3d18 Iustin Pop
321 858f3d18 Iustin Pop
    """
322 858f3d18 Iustin Pop
    disk = objects.Disk.FromDict(params[0])
323 858f3d18 Iustin Pop
    dest_node, dest_path, cluster_name = params[1:]
324 858f3d18 Iustin Pop
    return backend.BlockdevExport(disk, dest_node, dest_path, cluster_name)
325 858f3d18 Iustin Pop
326 6b93ec9d Iustin Pop
  # blockdev/drbd specific methods ----------
327 6b93ec9d Iustin Pop
328 6b93ec9d Iustin Pop
  @staticmethod
329 6b93ec9d Iustin Pop
  def perspective_drbd_disconnect_net(params):
330 6b93ec9d Iustin Pop
    """Disconnects 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 = params
337 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
338 6b93ec9d Iustin Pop
    return backend.DrbdDisconnectNet(nodes_ip, disks)
339 6b93ec9d Iustin Pop
340 6b93ec9d Iustin Pop
  @staticmethod
341 6b93ec9d Iustin Pop
  def perspective_drbd_attach_net(params):
342 6b93ec9d Iustin Pop
    """Attaches the network connection of drbd disks.
343 6b93ec9d Iustin Pop
344 6b93ec9d Iustin Pop
    Note that this is only valid for drbd disks, so the members of the
345 6b93ec9d Iustin Pop
    disk list must all be drbd devices.
346 6b93ec9d Iustin Pop
347 6b93ec9d Iustin Pop
    """
348 6b93ec9d Iustin Pop
    nodes_ip, disks, instance_name, multimaster = params
349 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
350 821d1bd1 Iustin Pop
    return backend.DrbdAttachNet(nodes_ip, disks,
351 821d1bd1 Iustin Pop
                                     instance_name, multimaster)
352 6b93ec9d Iustin Pop
353 6b93ec9d Iustin Pop
  @staticmethod
354 6b93ec9d Iustin Pop
  def perspective_drbd_wait_sync(params):
355 6b93ec9d Iustin Pop
    """Wait until DRBD disks are synched.
356 6b93ec9d Iustin Pop
357 6b93ec9d Iustin Pop
    Note that this is only valid for drbd disks, so the members of the
358 6b93ec9d Iustin Pop
    disk list must all be drbd devices.
359 6b93ec9d Iustin Pop
360 6b93ec9d Iustin Pop
    """
361 6b93ec9d Iustin Pop
    nodes_ip, disks = params
362 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
363 6b93ec9d Iustin Pop
    return backend.DrbdWaitSync(nodes_ip, disks)
364 6b93ec9d Iustin Pop
365 c46b9782 Luca Bigliardi
  @staticmethod
366 c46b9782 Luca Bigliardi
  def perspective_drbd_helper(params):
367 c46b9782 Luca Bigliardi
    """Query drbd helper.
368 c46b9782 Luca Bigliardi
369 c46b9782 Luca Bigliardi
    """
370 c46b9782 Luca Bigliardi
    return backend.GetDrbdUsermodeHelper()
371 c46b9782 Luca Bigliardi
372 a8083063 Iustin Pop
  # export/import  --------------------------
373 a8083063 Iustin Pop
374 3ecf6786 Iustin Pop
  @staticmethod
375 3ecf6786 Iustin Pop
  def perspective_finalize_export(params):
376 3ecf6786 Iustin Pop
    """Expose the finalize export functionality.
377 a8083063 Iustin Pop
378 3ecf6786 Iustin Pop
    """
379 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
380 7b651654 Michael Hanselmann
381 7b651654 Michael Hanselmann
    snap_disks = []
382 7b651654 Michael Hanselmann
    for disk in params[1]:
383 7b651654 Michael Hanselmann
      if isinstance(disk, bool):
384 7b651654 Michael Hanselmann
        snap_disks.append(disk)
385 7b651654 Michael Hanselmann
      else:
386 7b651654 Michael Hanselmann
        snap_disks.append(objects.Disk.FromDict(disk))
387 7b651654 Michael Hanselmann
388 a8083063 Iustin Pop
    return backend.FinalizeExport(instance, snap_disks)
389 a8083063 Iustin Pop
390 3ecf6786 Iustin Pop
  @staticmethod
391 3ecf6786 Iustin Pop
  def perspective_export_info(params):
392 3ecf6786 Iustin Pop
    """Query information about an existing export on this node.
393 3ecf6786 Iustin Pop
394 3ecf6786 Iustin Pop
    The given path may not contain an export, in which case we return
395 3ecf6786 Iustin Pop
    None.
396 3ecf6786 Iustin Pop
397 3ecf6786 Iustin Pop
    """
398 3ecf6786 Iustin Pop
    path = params[0]
399 3eccac06 Iustin Pop
    return backend.ExportInfo(path)
400 a8083063 Iustin Pop
401 3ecf6786 Iustin Pop
  @staticmethod
402 3ecf6786 Iustin Pop
  def perspective_export_list(params):
403 3ecf6786 Iustin Pop
    """List the available exports on this node.
404 3ecf6786 Iustin Pop
405 3ecf6786 Iustin Pop
    Note that as opposed to export_info, which may query data about an
406 3ecf6786 Iustin Pop
    export in any path, this only queries the standard Ganeti path
407 3ecf6786 Iustin Pop
    (constants.EXPORT_DIR).
408 3ecf6786 Iustin Pop
409 3ecf6786 Iustin Pop
    """
410 a8083063 Iustin Pop
    return backend.ListExports()
411 a8083063 Iustin Pop
412 3ecf6786 Iustin Pop
  @staticmethod
413 3ecf6786 Iustin Pop
  def perspective_export_remove(params):
414 3ecf6786 Iustin Pop
    """Remove an export.
415 3ecf6786 Iustin Pop
416 3ecf6786 Iustin Pop
    """
417 a8083063 Iustin Pop
    export = params[0]
418 a8083063 Iustin Pop
    return backend.RemoveExport(export)
419 a8083063 Iustin Pop
420 a8083063 Iustin Pop
  # volume  --------------------------
421 a8083063 Iustin Pop
422 3ecf6786 Iustin Pop
  @staticmethod
423 b2a6ccd4 Iustin Pop
  def perspective_lv_list(params):
424 3ecf6786 Iustin Pop
    """Query the list of logical volumes in a given volume group.
425 3ecf6786 Iustin Pop
426 3ecf6786 Iustin Pop
    """
427 a8083063 Iustin Pop
    vgname = params[0]
428 c26a6bd2 Iustin Pop
    return backend.GetVolumeList(vgname)
429 a8083063 Iustin Pop
430 3ecf6786 Iustin Pop
  @staticmethod
431 3ecf6786 Iustin Pop
  def perspective_vg_list(params):
432 3ecf6786 Iustin Pop
    """Query the list of volume groups.
433 3ecf6786 Iustin Pop
434 3ecf6786 Iustin Pop
    """
435 a8083063 Iustin Pop
    return backend.ListVolumeGroups()
436 a8083063 Iustin Pop
437 e337de97 Michael Hanselmann
  # Storage --------------------------
438 e337de97 Michael Hanselmann
439 e337de97 Michael Hanselmann
  @staticmethod
440 e337de97 Michael Hanselmann
  def perspective_storage_list(params):
441 e337de97 Michael Hanselmann
    """Get list of storage units.
442 e337de97 Michael Hanselmann
443 e337de97 Michael Hanselmann
    """
444 e337de97 Michael Hanselmann
    (su_name, su_args, name, fields) = params
445 e337de97 Michael Hanselmann
    return storage.GetStorage(su_name, *su_args).List(name, fields)
446 e337de97 Michael Hanselmann
447 8979196a Michael Hanselmann
  @staticmethod
448 8979196a Michael Hanselmann
  def perspective_storage_modify(params):
449 8979196a Michael Hanselmann
    """Modify a storage unit.
450 8979196a Michael Hanselmann
451 8979196a Michael Hanselmann
    """
452 8979196a Michael Hanselmann
    (su_name, su_args, name, changes) = params
453 8979196a Michael Hanselmann
    return storage.GetStorage(su_name, *su_args).Modify(name, changes)
454 8979196a Michael Hanselmann
455 637b8d7e Michael Hanselmann
  @staticmethod
456 637b8d7e Michael Hanselmann
  def perspective_storage_execute(params):
457 637b8d7e Michael Hanselmann
    """Execute an operation on a storage unit.
458 637b8d7e Michael Hanselmann
459 637b8d7e Michael Hanselmann
    """
460 637b8d7e Michael Hanselmann
    (su_name, su_args, name, op) = params
461 637b8d7e Michael Hanselmann
    return storage.GetStorage(su_name, *su_args).Execute(name, op)
462 637b8d7e Michael Hanselmann
463 a8083063 Iustin Pop
  # bridge  --------------------------
464 a8083063 Iustin Pop
465 3ecf6786 Iustin Pop
  @staticmethod
466 3ecf6786 Iustin Pop
  def perspective_bridges_exist(params):
467 3ecf6786 Iustin Pop
    """Check if all bridges given exist on this node.
468 3ecf6786 Iustin Pop
469 3ecf6786 Iustin Pop
    """
470 a8083063 Iustin Pop
    bridges_list = params[0]
471 a8083063 Iustin Pop
    return backend.BridgesExist(bridges_list)
472 a8083063 Iustin Pop
473 a8083063 Iustin Pop
  # instance  --------------------------
474 a8083063 Iustin Pop
475 3ecf6786 Iustin Pop
  @staticmethod
476 3ecf6786 Iustin Pop
  def perspective_instance_os_add(params):
477 3ecf6786 Iustin Pop
    """Install an OS on a given instance.
478 3ecf6786 Iustin Pop
479 3ecf6786 Iustin Pop
    """
480 d15a9ad3 Guido Trotter
    inst_s = params[0]
481 319856a9 Michael Hanselmann
    inst = objects.Instance.FromDict(inst_s)
482 e557bae9 Guido Trotter
    reinstall = params[1]
483 4a0e011f Iustin Pop
    debug = params[2]
484 4a0e011f Iustin Pop
    return backend.InstanceOsAdd(inst, reinstall, debug)
485 a8083063 Iustin Pop
486 3ecf6786 Iustin Pop
  @staticmethod
487 decd5f45 Iustin Pop
  def perspective_instance_run_rename(params):
488 decd5f45 Iustin Pop
    """Runs the OS rename script for an instance.
489 decd5f45 Iustin Pop
490 decd5f45 Iustin Pop
    """
491 4a0e011f Iustin Pop
    inst_s, old_name, debug = params
492 319856a9 Michael Hanselmann
    inst = objects.Instance.FromDict(inst_s)
493 4a0e011f Iustin Pop
    return backend.RunRenameInstance(inst, old_name, debug)
494 decd5f45 Iustin Pop
495 decd5f45 Iustin Pop
  @staticmethod
496 3ecf6786 Iustin Pop
  def perspective_instance_shutdown(params):
497 3ecf6786 Iustin Pop
    """Shutdown an instance.
498 3ecf6786 Iustin Pop
499 3ecf6786 Iustin Pop
    """
500 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
501 6263189c Guido Trotter
    timeout = params[1]
502 6263189c Guido Trotter
    return backend.InstanceShutdown(instance, timeout)
503 a8083063 Iustin Pop
504 3ecf6786 Iustin Pop
  @staticmethod
505 3ecf6786 Iustin Pop
  def perspective_instance_start(params):
506 3ecf6786 Iustin Pop
    """Start an instance.
507 3ecf6786 Iustin Pop
508 3ecf6786 Iustin Pop
    """
509 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
510 07813a9e Iustin Pop
    return backend.StartInstance(instance)
511 a8083063 Iustin Pop
512 3ecf6786 Iustin Pop
  @staticmethod
513 6906a9d8 Guido Trotter
  def perspective_migration_info(params):
514 6906a9d8 Guido Trotter
    """Gather information about an instance to be migrated.
515 6906a9d8 Guido Trotter
516 6906a9d8 Guido Trotter
    """
517 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(params[0])
518 6906a9d8 Guido Trotter
    return backend.MigrationInfo(instance)
519 6906a9d8 Guido Trotter
520 6906a9d8 Guido Trotter
  @staticmethod
521 6906a9d8 Guido Trotter
  def perspective_accept_instance(params):
522 6906a9d8 Guido Trotter
    """Prepare the node to accept an instance.
523 6906a9d8 Guido Trotter
524 6906a9d8 Guido Trotter
    """
525 6906a9d8 Guido Trotter
    instance, info, target = params
526 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(instance)
527 6906a9d8 Guido Trotter
    return backend.AcceptInstance(instance, info, target)
528 6906a9d8 Guido Trotter
529 6906a9d8 Guido Trotter
  @staticmethod
530 6906a9d8 Guido Trotter
  def perspective_finalize_migration(params):
531 6906a9d8 Guido Trotter
    """Finalize the instance migration.
532 6906a9d8 Guido Trotter
533 6906a9d8 Guido Trotter
    """
534 6906a9d8 Guido Trotter
    instance, info, success = params
535 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(instance)
536 6906a9d8 Guido Trotter
    return backend.FinalizeMigration(instance, info, success)
537 6906a9d8 Guido Trotter
538 6906a9d8 Guido Trotter
  @staticmethod
539 2a10865c Iustin Pop
  def perspective_instance_migrate(params):
540 2a10865c Iustin Pop
    """Migrates an instance.
541 2a10865c Iustin Pop
542 2a10865c Iustin Pop
    """
543 2a10865c Iustin Pop
    instance, target, live = params
544 9f0e6b37 Iustin Pop
    instance = objects.Instance.FromDict(instance)
545 2a10865c Iustin Pop
    return backend.MigrateInstance(instance, target, live)
546 2a10865c Iustin Pop
547 2a10865c Iustin Pop
  @staticmethod
548 007a2f3e Alexander Schreiber
  def perspective_instance_reboot(params):
549 007a2f3e Alexander Schreiber
    """Reboot an instance.
550 007a2f3e Alexander Schreiber
551 007a2f3e Alexander Schreiber
    """
552 007a2f3e Alexander Schreiber
    instance = objects.Instance.FromDict(params[0])
553 007a2f3e Alexander Schreiber
    reboot_type = params[1]
554 17c3f802 Guido Trotter
    shutdown_timeout = params[2]
555 17c3f802 Guido Trotter
    return backend.InstanceReboot(instance, reboot_type, shutdown_timeout)
556 007a2f3e Alexander Schreiber
557 007a2f3e Alexander Schreiber
  @staticmethod
558 3ecf6786 Iustin Pop
  def perspective_instance_info(params):
559 3ecf6786 Iustin Pop
    """Query instance information.
560 3ecf6786 Iustin Pop
561 3ecf6786 Iustin Pop
    """
562 16ad1a83 Iustin Pop
    return backend.GetInstanceInfo(params[0], params[1])
563 a8083063 Iustin Pop
564 3ecf6786 Iustin Pop
  @staticmethod
565 56e7640c Iustin Pop
  def perspective_instance_migratable(params):
566 56e7640c Iustin Pop
    """Query whether the specified instance can be migrated.
567 56e7640c Iustin Pop
568 56e7640c Iustin Pop
    """
569 56e7640c Iustin Pop
    instance = objects.Instance.FromDict(params[0])
570 56e7640c Iustin Pop
    return backend.GetInstanceMigratable(instance)
571 56e7640c Iustin Pop
572 56e7640c Iustin Pop
  @staticmethod
573 3ecf6786 Iustin Pop
  def perspective_all_instances_info(params):
574 3ecf6786 Iustin Pop
    """Query information about all instances.
575 3ecf6786 Iustin Pop
576 3ecf6786 Iustin Pop
    """
577 e69d05fd Iustin Pop
    return backend.GetAllInstancesInfo(params[0])
578 a8083063 Iustin Pop
579 3ecf6786 Iustin Pop
  @staticmethod
580 3ecf6786 Iustin Pop
  def perspective_instance_list(params):
581 3ecf6786 Iustin Pop
    """Query the list of running instances.
582 3ecf6786 Iustin Pop
583 3ecf6786 Iustin Pop
    """
584 c26a6bd2 Iustin Pop
    return backend.GetInstanceList(params[0])
585 a8083063 Iustin Pop
586 a8083063 Iustin Pop
  # node --------------------------
587 a8083063 Iustin Pop
588 3ecf6786 Iustin Pop
  @staticmethod
589 16abfbc2 Alexander Schreiber
  def perspective_node_tcp_ping(params):
590 16abfbc2 Alexander Schreiber
    """Do a TcpPing on the remote node.
591 16abfbc2 Alexander Schreiber
592 16abfbc2 Alexander Schreiber
    """
593 a744b676 Manuel Franceschini
    return netutils.TcpPing(params[1], params[2], timeout=params[3],
594 a744b676 Manuel Franceschini
                            live_port_needed=params[4], source=params[0])
595 16abfbc2 Alexander Schreiber
596 16abfbc2 Alexander Schreiber
  @staticmethod
597 caad16e2 Iustin Pop
  def perspective_node_has_ip_address(params):
598 caad16e2 Iustin Pop
    """Checks if a node has the given ip address.
599 caad16e2 Iustin Pop
600 caad16e2 Iustin Pop
    """
601 8b312c1d Manuel Franceschini
    return netutils.IPAddress.Own(params[0])
602 caad16e2 Iustin Pop
603 caad16e2 Iustin Pop
  @staticmethod
604 3ecf6786 Iustin Pop
  def perspective_node_info(params):
605 3ecf6786 Iustin Pop
    """Query node information.
606 3ecf6786 Iustin Pop
607 3ecf6786 Iustin Pop
    """
608 e69d05fd Iustin Pop
    vgname, hypervisor_type = params
609 e69d05fd Iustin Pop
    return backend.GetNodeInfo(vgname, hypervisor_type)
610 a8083063 Iustin Pop
611 3ecf6786 Iustin Pop
  @staticmethod
612 19ddc57a Renรฉ Nussbaumer
  def perspective_etc_hosts_modify(params):
613 19ddc57a Renรฉ Nussbaumer
    """Modify a node entry in /etc/hosts.
614 19ddc57a Renรฉ Nussbaumer
615 19ddc57a Renรฉ Nussbaumer
    """
616 19ddc57a Renรฉ Nussbaumer
    backend.EtcHostsModify(params[0], params[1], params[2])
617 19ddc57a Renรฉ Nussbaumer
618 19ddc57a Renรฉ Nussbaumer
    return True
619 19ddc57a Renรฉ Nussbaumer
620 19ddc57a Renรฉ Nussbaumer
  @staticmethod
621 3ecf6786 Iustin Pop
  def perspective_node_verify(params):
622 3ecf6786 Iustin Pop
    """Run a verify sequence on this node.
623 3ecf6786 Iustin Pop
624 3ecf6786 Iustin Pop
    """
625 62c9ec92 Iustin Pop
    return backend.VerifyNode(params[0], params[1])
626 a8083063 Iustin Pop
627 3ecf6786 Iustin Pop
  @staticmethod
628 3ecf6786 Iustin Pop
  def perspective_node_start_master(params):
629 3ecf6786 Iustin Pop
    """Promote this node to master status.
630 3ecf6786 Iustin Pop
631 3ecf6786 Iustin Pop
    """
632 3583908a Guido Trotter
    return backend.StartMaster(params[0], params[1])
633 a8083063 Iustin Pop
634 3ecf6786 Iustin Pop
  @staticmethod
635 3ecf6786 Iustin Pop
  def perspective_node_stop_master(params):
636 3ecf6786 Iustin Pop
    """Demote this node from master status.
637 3ecf6786 Iustin Pop
638 3ecf6786 Iustin Pop
    """
639 1c65840b Iustin Pop
    return backend.StopMaster(params[0])
640 a8083063 Iustin Pop
641 3ecf6786 Iustin Pop
  @staticmethod
642 3ecf6786 Iustin Pop
  def perspective_node_leave_cluster(params):
643 3ecf6786 Iustin Pop
    """Cleanup after leaving a cluster.
644 3ecf6786 Iustin Pop
645 3ecf6786 Iustin Pop
    """
646 b989b9d9 Ken Wehr
    return backend.LeaveCluster(params[0])
647 a8083063 Iustin Pop
648 3ecf6786 Iustin Pop
  @staticmethod
649 3ecf6786 Iustin Pop
  def perspective_node_volumes(params):
650 3ecf6786 Iustin Pop
    """Query the list of all logical volume groups.
651 3ecf6786 Iustin Pop
652 3ecf6786 Iustin Pop
    """
653 dcb93971 Michael Hanselmann
    return backend.NodeVolumes()
654 dcb93971 Michael Hanselmann
655 56aa9fd5 Iustin Pop
  @staticmethod
656 56aa9fd5 Iustin Pop
  def perspective_node_demote_from_mc(params):
657 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
658 56aa9fd5 Iustin Pop
659 56aa9fd5 Iustin Pop
    """
660 56aa9fd5 Iustin Pop
    return backend.DemoteFromMC()
661 56aa9fd5 Iustin Pop
662 56aa9fd5 Iustin Pop
663 f5118ade Iustin Pop
  @staticmethod
664 f5118ade Iustin Pop
  def perspective_node_powercycle(params):
665 f5118ade Iustin Pop
    """Tries to powercycle the nod.
666 f5118ade Iustin Pop
667 f5118ade Iustin Pop
    """
668 f5118ade Iustin Pop
    hypervisor_type = params[0]
669 f5118ade Iustin Pop
    return backend.PowercycleNode(hypervisor_type)
670 f5118ade Iustin Pop
671 f5118ade Iustin Pop
672 a8083063 Iustin Pop
  # cluster --------------------------
673 a8083063 Iustin Pop
674 3ecf6786 Iustin Pop
  @staticmethod
675 3ecf6786 Iustin Pop
  def perspective_version(params):
676 3ecf6786 Iustin Pop
    """Query version information.
677 3ecf6786 Iustin Pop
678 3ecf6786 Iustin Pop
    """
679 c26a6bd2 Iustin Pop
    return constants.PROTOCOL_VERSION
680 a8083063 Iustin Pop
681 3ecf6786 Iustin Pop
  @staticmethod
682 3ecf6786 Iustin Pop
  def perspective_upload_file(params):
683 3ecf6786 Iustin Pop
    """Upload a file.
684 3ecf6786 Iustin Pop
685 3ecf6786 Iustin Pop
    Note that the backend implementation imposes strict rules on which
686 3ecf6786 Iustin Pop
    files are accepted.
687 3ecf6786 Iustin Pop
688 3ecf6786 Iustin Pop
    """
689 a8083063 Iustin Pop
    return backend.UploadFile(*params)
690 a8083063 Iustin Pop
691 4e071d3b Iustin Pop
  @staticmethod
692 4e071d3b Iustin Pop
  def perspective_master_info(params):
693 4e071d3b Iustin Pop
    """Query master information.
694 4e071d3b Iustin Pop
695 4e071d3b Iustin Pop
    """
696 4e071d3b Iustin Pop
    return backend.GetMasterInfo()
697 a8083063 Iustin Pop
698 6ddc95ec Michael Hanselmann
  @staticmethod
699 6ddc95ec Michael Hanselmann
  def perspective_write_ssconf_files(params):
700 6ddc95ec Michael Hanselmann
    """Write ssconf files.
701 6ddc95ec Michael Hanselmann
702 6ddc95ec Michael Hanselmann
    """
703 03d1dba2 Michael Hanselmann
    (values,) = params
704 03d1dba2 Michael Hanselmann
    return backend.WriteSsconfFiles(values)
705 6ddc95ec Michael Hanselmann
706 a8083063 Iustin Pop
  # os -----------------------
707 a8083063 Iustin Pop
708 3ecf6786 Iustin Pop
  @staticmethod
709 3ecf6786 Iustin Pop
  def perspective_os_diagnose(params):
710 3ecf6786 Iustin Pop
    """Query detailed information about existing OSes.
711 3ecf6786 Iustin Pop
712 3ecf6786 Iustin Pop
    """
713 255dcebd Iustin Pop
    return backend.DiagnoseOS()
714 a8083063 Iustin Pop
715 3ecf6786 Iustin Pop
  @staticmethod
716 3ecf6786 Iustin Pop
  def perspective_os_get(params):
717 3ecf6786 Iustin Pop
    """Query information about a given OS.
718 3ecf6786 Iustin Pop
719 3ecf6786 Iustin Pop
    """
720 a8083063 Iustin Pop
    name = params[0]
721 255dcebd Iustin Pop
    os_obj = backend.OSFromDisk(name)
722 c26a6bd2 Iustin Pop
    return os_obj.ToDict()
723 a8083063 Iustin Pop
724 acd9ff9e Iustin Pop
  @staticmethod
725 acd9ff9e Iustin Pop
  def perspective_os_validate(params):
726 acd9ff9e Iustin Pop
    """Run a given OS' validation routine.
727 acd9ff9e Iustin Pop
728 acd9ff9e Iustin Pop
    """
729 acd9ff9e Iustin Pop
    required, name, checks, params = params
730 acd9ff9e Iustin Pop
    return backend.ValidateOS(required, name, checks, params)
731 acd9ff9e Iustin Pop
732 a8083063 Iustin Pop
  # hooks -----------------------
733 a8083063 Iustin Pop
734 3ecf6786 Iustin Pop
  @staticmethod
735 3ecf6786 Iustin Pop
  def perspective_hooks_runner(params):
736 3ecf6786 Iustin Pop
    """Run hook scripts.
737 3ecf6786 Iustin Pop
738 3ecf6786 Iustin Pop
    """
739 a8083063 Iustin Pop
    hpath, phase, env = params
740 a8083063 Iustin Pop
    hr = backend.HooksRunner()
741 a8083063 Iustin Pop
    return hr.RunHooks(hpath, phase, env)
742 a8083063 Iustin Pop
743 8d528b7c Iustin Pop
  # iallocator -----------------
744 8d528b7c Iustin Pop
745 8d528b7c Iustin Pop
  @staticmethod
746 8d528b7c Iustin Pop
  def perspective_iallocator_runner(params):
747 8d528b7c Iustin Pop
    """Run an iallocator script.
748 8d528b7c Iustin Pop
749 8d528b7c Iustin Pop
    """
750 8d528b7c Iustin Pop
    name, idata = params
751 8d528b7c Iustin Pop
    iar = backend.IAllocatorRunner()
752 8d528b7c Iustin Pop
    return iar.Run(name, idata)
753 8d528b7c Iustin Pop
754 06009e27 Iustin Pop
  # test -----------------------
755 06009e27 Iustin Pop
756 06009e27 Iustin Pop
  @staticmethod
757 06009e27 Iustin Pop
  def perspective_test_delay(params):
758 06009e27 Iustin Pop
    """Run test delay.
759 06009e27 Iustin Pop
760 06009e27 Iustin Pop
    """
761 06009e27 Iustin Pop
    duration = params[0]
762 c26a6bd2 Iustin Pop
    status, rval = utils.TestDelay(duration)
763 c26a6bd2 Iustin Pop
    if not status:
764 c26a6bd2 Iustin Pop
      raise backend.RPCFail(rval)
765 c26a6bd2 Iustin Pop
    return rval
766 06009e27 Iustin Pop
767 4e071d3b Iustin Pop
  # file storage ---------------
768 4e071d3b Iustin Pop
769 a5d7fb43 Manuel Franceschini
  @staticmethod
770 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_create(params):
771 a5d7fb43 Manuel Franceschini
    """Create the file storage directory.
772 a5d7fb43 Manuel Franceschini
773 a5d7fb43 Manuel Franceschini
    """
774 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
775 a5d7fb43 Manuel Franceschini
    return backend.CreateFileStorageDir(file_storage_dir)
776 a5d7fb43 Manuel Franceschini
777 a5d7fb43 Manuel Franceschini
  @staticmethod
778 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_remove(params):
779 a5d7fb43 Manuel Franceschini
    """Remove the file storage directory.
780 a5d7fb43 Manuel Franceschini
781 a5d7fb43 Manuel Franceschini
    """
782 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
783 a5d7fb43 Manuel Franceschini
    return backend.RemoveFileStorageDir(file_storage_dir)
784 a5d7fb43 Manuel Franceschini
785 a5d7fb43 Manuel Franceschini
  @staticmethod
786 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_rename(params):
787 a5d7fb43 Manuel Franceschini
    """Rename the file storage directory.
788 a5d7fb43 Manuel Franceschini
789 a5d7fb43 Manuel Franceschini
    """
790 a5d7fb43 Manuel Franceschini
    old_file_storage_dir = params[0]
791 a5d7fb43 Manuel Franceschini
    new_file_storage_dir = params[1]
792 a5d7fb43 Manuel Franceschini
    return backend.RenameFileStorageDir(old_file_storage_dir,
793 a5d7fb43 Manuel Franceschini
                                        new_file_storage_dir)
794 a5d7fb43 Manuel Franceschini
795 4e071d3b Iustin Pop
  # jobs ------------------------
796 4e071d3b Iustin Pop
797 ca52cdeb Michael Hanselmann
  @staticmethod
798 7f30777b Michael Hanselmann
  @_RequireJobQueueLock
799 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_update(params):
800 ca52cdeb Michael Hanselmann
    """Update job queue.
801 ca52cdeb Michael Hanselmann
802 ca52cdeb Michael Hanselmann
    """
803 ca52cdeb Michael Hanselmann
    (file_name, content) = params
804 7f30777b Michael Hanselmann
    return backend.JobQueueUpdate(file_name, content)
805 ca52cdeb Michael Hanselmann
806 ca52cdeb Michael Hanselmann
  @staticmethod
807 f1f3f45c Michael Hanselmann
  @_RequireJobQueueLock
808 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_purge(params):
809 ca52cdeb Michael Hanselmann
    """Purge job queue.
810 ca52cdeb Michael Hanselmann
811 ca52cdeb Michael Hanselmann
    """
812 ca52cdeb Michael Hanselmann
    return backend.JobQueuePurge()
813 ca52cdeb Michael Hanselmann
814 af5ebcb1 Michael Hanselmann
  @staticmethod
815 af5ebcb1 Michael Hanselmann
  @_RequireJobQueueLock
816 af5ebcb1 Michael Hanselmann
  def perspective_jobqueue_rename(params):
817 af5ebcb1 Michael Hanselmann
    """Rename a job queue file.
818 af5ebcb1 Michael Hanselmann
819 af5ebcb1 Michael Hanselmann
    """
820 dd875d32 Michael Hanselmann
    # TODO: What if a file fails to rename?
821 c26a6bd2 Iustin Pop
    return [backend.JobQueueRename(old, new) for old, new in params]
822 af5ebcb1 Michael Hanselmann
823 6217e295 Iustin Pop
  # hypervisor ---------------
824 6217e295 Iustin Pop
825 6217e295 Iustin Pop
  @staticmethod
826 6217e295 Iustin Pop
  def perspective_hypervisor_validate_params(params):
827 6217e295 Iustin Pop
    """Validate the hypervisor parameters.
828 6217e295 Iustin Pop
829 6217e295 Iustin Pop
    """
830 6217e295 Iustin Pop
    (hvname, hvparams) = params
831 6217e295 Iustin Pop
    return backend.ValidateHVParams(hvname, hvparams)
832 6217e295 Iustin Pop
833 f942a838 Michael Hanselmann
  # Crypto
834 f942a838 Michael Hanselmann
835 f942a838 Michael Hanselmann
  @staticmethod
836 ef40fbfb Michael Hanselmann
  def perspective_x509_cert_create(params):
837 f942a838 Michael Hanselmann
    """Creates a new X509 certificate for SSL/TLS.
838 f942a838 Michael Hanselmann
839 f942a838 Michael Hanselmann
    """
840 f942a838 Michael Hanselmann
    (validity, ) = params
841 f942a838 Michael Hanselmann
    return backend.CreateX509Certificate(validity)
842 f942a838 Michael Hanselmann
843 f942a838 Michael Hanselmann
  @staticmethod
844 ef40fbfb Michael Hanselmann
  def perspective_x509_cert_remove(params):
845 f942a838 Michael Hanselmann
    """Removes a X509 certificate.
846 f942a838 Michael Hanselmann
847 f942a838 Michael Hanselmann
    """
848 f942a838 Michael Hanselmann
    (name, ) = params
849 f942a838 Michael Hanselmann
    return backend.RemoveX509Certificate(name)
850 f942a838 Michael Hanselmann
851 1651d116 Michael Hanselmann
  # Import and export
852 1651d116 Michael Hanselmann
853 1651d116 Michael Hanselmann
  @staticmethod
854 ef40fbfb Michael Hanselmann
  def perspective_import_start(params):
855 1651d116 Michael Hanselmann
    """Starts an import daemon.
856 1651d116 Michael Hanselmann
857 1651d116 Michael Hanselmann
    """
858 eb630f50 Michael Hanselmann
    (opts_s, instance, dest, dest_args) = params
859 eb630f50 Michael Hanselmann
860 eb630f50 Michael Hanselmann
    opts = objects.ImportExportOptions.FromDict(opts_s)
861 eb630f50 Michael Hanselmann
862 eb630f50 Michael Hanselmann
    return backend.StartImportExportDaemon(constants.IEM_IMPORT, opts,
863 1651d116 Michael Hanselmann
                                           None, None,
864 1651d116 Michael Hanselmann
                                           objects.Instance.FromDict(instance),
865 1651d116 Michael Hanselmann
                                           dest,
866 1651d116 Michael Hanselmann
                                           _DecodeImportExportIO(dest,
867 1651d116 Michael Hanselmann
                                                                 dest_args))
868 eb630f50 Michael Hanselmann
869 1651d116 Michael Hanselmann
  @staticmethod
870 ef40fbfb Michael Hanselmann
  def perspective_export_start(params):
871 1651d116 Michael Hanselmann
    """Starts an export daemon.
872 1651d116 Michael Hanselmann
873 1651d116 Michael Hanselmann
    """
874 eb630f50 Michael Hanselmann
    (opts_s, host, port, instance, source, source_args) = params
875 eb630f50 Michael Hanselmann
876 eb630f50 Michael Hanselmann
    opts = objects.ImportExportOptions.FromDict(opts_s)
877 eb630f50 Michael Hanselmann
878 eb630f50 Michael Hanselmann
    return backend.StartImportExportDaemon(constants.IEM_EXPORT, opts,
879 1651d116 Michael Hanselmann
                                           host, port,
880 1651d116 Michael Hanselmann
                                           objects.Instance.FromDict(instance),
881 1651d116 Michael Hanselmann
                                           source,
882 1651d116 Michael Hanselmann
                                           _DecodeImportExportIO(source,
883 1651d116 Michael Hanselmann
                                                                 source_args))
884 1651d116 Michael Hanselmann
885 1651d116 Michael Hanselmann
  @staticmethod
886 ef40fbfb Michael Hanselmann
  def perspective_impexp_status(params):
887 1651d116 Michael Hanselmann
    """Retrieves the status of an import or export daemon.
888 1651d116 Michael Hanselmann
889 1651d116 Michael Hanselmann
    """
890 1651d116 Michael Hanselmann
    return backend.GetImportExportStatus(params[0])
891 1651d116 Michael Hanselmann
892 1651d116 Michael Hanselmann
  @staticmethod
893 f81c4737 Michael Hanselmann
  def perspective_impexp_abort(params):
894 f81c4737 Michael Hanselmann
    """Aborts an import or export.
895 f81c4737 Michael Hanselmann
896 f81c4737 Michael Hanselmann
    """
897 f81c4737 Michael Hanselmann
    return backend.AbortImportExport(params[0])
898 f81c4737 Michael Hanselmann
899 f81c4737 Michael Hanselmann
  @staticmethod
900 ef40fbfb Michael Hanselmann
  def perspective_impexp_cleanup(params):
901 1651d116 Michael Hanselmann
    """Cleans up after an import or export.
902 1651d116 Michael Hanselmann
903 1651d116 Michael Hanselmann
    """
904 1651d116 Michael Hanselmann
    return backend.CleanupImportExport(params[0])
905 1651d116 Michael Hanselmann
906 a8083063 Iustin Pop
907 f93427cd Iustin Pop
def CheckNoded(_, args):
908 f93427cd Iustin Pop
  """Initial checks whether to run or exit with a failure.
909 f93427cd Iustin Pop
910 f93427cd Iustin Pop
  """
911 f93427cd Iustin Pop
  if args: # noded doesn't take any arguments
912 f93427cd Iustin Pop
    print >> sys.stderr, ("Usage: %s [-f] [-d] [-p port] [-b ADDRESS]" %
913 f93427cd Iustin Pop
                          sys.argv[0])
914 f93427cd Iustin Pop
    sys.exit(constants.EXIT_FAILURE)
915 f93427cd Iustin Pop
916 f93427cd Iustin Pop
917 3ee53f1f Iustin Pop
def PrepNoded(options, _):
918 3ee53f1f Iustin Pop
  """Preparation node daemon function, executed with the PID file held.
919 3ecf6786 Iustin Pop
920 3ecf6786 Iustin Pop
  """
921 bebf68d3 Guido Trotter
  if options.mlock:
922 bebf68d3 Guido Trotter
    request_executor_class = MlockallRequestExecutor
923 4c32a8bd Luca Bigliardi
    try:
924 4c32a8bd Luca Bigliardi
      utils.Mlockall()
925 4c32a8bd Luca Bigliardi
    except errors.NoCtypesError:
926 4c32a8bd Luca Bigliardi
      logging.warning("Cannot set memory lock, ctypes module not found")
927 4c32a8bd Luca Bigliardi
      request_executor_class = http.server.HttpServerRequestExecutor
928 bebf68d3 Guido Trotter
  else:
929 bebf68d3 Guido Trotter
    request_executor_class = http.server.HttpServerRequestExecutor
930 02bea2fc Luca Bigliardi
931 04ccf5e9 Guido Trotter
  # Read SSL certificate
932 3b1b0cb6 Guido Trotter
  if options.ssl:
933 3b1b0cb6 Guido Trotter
    ssl_params = http.HttpSslParams(ssl_key_path=options.ssl_key,
934 3b1b0cb6 Guido Trotter
                                    ssl_cert_path=options.ssl_cert)
935 3b1b0cb6 Guido Trotter
  else:
936 3b1b0cb6 Guido Trotter
    ssl_params = None
937 7d88772a Iustin Pop
938 81198f6e Iustin Pop
  err = _PrepareQueueLock()
939 81198f6e Iustin Pop
  if err is not None:
940 81198f6e Iustin Pop
    # this might be some kind of file-system/permission error; while
941 81198f6e Iustin Pop
    # this breaks the job queue functionality, we shouldn't prevent
942 81198f6e Iustin Pop
    # startup of the whole node daemon because of this
943 81198f6e Iustin Pop
    logging.critical("Can't init/verify the queue, proceeding anyway: %s", err)
944 7d88772a Iustin Pop
945 04ccf5e9 Guido Trotter
  mainloop = daemon.Mainloop()
946 04ccf5e9 Guido Trotter
  server = NodeHttpServer(mainloop, options.bind_address, options.port,
947 38b77287 Luca Bigliardi
                          ssl_params=ssl_params, ssl_verify_peer=True,
948 bebf68d3 Guido Trotter
                          request_executor_class=request_executor_class)
949 04ccf5e9 Guido Trotter
  server.Start()
950 3ee53f1f Iustin Pop
  return (mainloop, server)
951 3ee53f1f Iustin Pop
952 3ee53f1f Iustin Pop
def ExecNoded(options, args, prep_data): # pylint: disable-msg=W0613
953 3ee53f1f Iustin Pop
  """Main node daemon function, executed with the PID file held.
954 3ee53f1f Iustin Pop
955 3ee53f1f Iustin Pop
  """
956 3ee53f1f Iustin Pop
  (mainloop, server) = prep_data
957 04ccf5e9 Guido Trotter
  try:
958 04ccf5e9 Guido Trotter
    mainloop.Run()
959 04ccf5e9 Guido Trotter
  finally:
960 04ccf5e9 Guido Trotter
    server.Stop()
961 a8083063 Iustin Pop
962 a8083063 Iustin Pop
963 04ccf5e9 Guido Trotter
def main():
964 04ccf5e9 Guido Trotter
  """Main function for the node daemon.
965 04ccf5e9 Guido Trotter
966 04ccf5e9 Guido Trotter
  """
967 04ccf5e9 Guido Trotter
  parser = OptionParser(description="Ganeti node daemon",
968 04ccf5e9 Guido Trotter
                        usage="%prog [-f] [-d] [-p port] [-b ADDRESS]",
969 04ccf5e9 Guido Trotter
                        version="%%prog (ganeti) %s" %
970 04ccf5e9 Guido Trotter
                        constants.RELEASE_VERSION)
971 bebf68d3 Guido Trotter
  parser.add_option("--no-mlock", dest="mlock",
972 bebf68d3 Guido Trotter
                    help="Do not mlock the node memory in ram",
973 bebf68d3 Guido Trotter
                    default=True, action="store_false")
974 bebf68d3 Guido Trotter
975 3ee53f1f Iustin Pop
  daemon.GenericMain(constants.NODED, parser, CheckNoded, PrepNoded, ExecNoded,
976 084aba47 Michael Hanselmann
                     default_ssl_cert=constants.NODED_CERT_FILE,
977 1c54156d Luca Bigliardi
                     default_ssl_key=constants.NODED_CERT_FILE,
978 565083ef Luca Bigliardi
                     console_logging=True)
979 73d927a2 Guido Trotter
980 a8083063 Iustin Pop
981 3ecf6786 Iustin Pop
if __name__ == '__main__':
982 a8083063 Iustin Pop
  main()