Statistics
| Branch: | Tag: | Revision:

root / lib / server / noded.py @ c6a9dffa

History | View | Annotate | Download (26.5 kB)

1 69cf3abd Michael Hanselmann
#
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 271b7cf9 Renรฉ Nussbaumer
  def perspective_blockdev_wipe(params):
188 271b7cf9 Renรฉ Nussbaumer
    """Wipe a block device.
189 271b7cf9 Renรฉ Nussbaumer

190 271b7cf9 Renรฉ Nussbaumer
    """
191 271b7cf9 Renรฉ Nussbaumer
    bdev_s, offset, size = params
192 271b7cf9 Renรฉ Nussbaumer
    bdev = objects.Disk.FromDict(bdev_s)
193 271b7cf9 Renรฉ Nussbaumer
    return backend.BlockdevWipe(bdev, offset, size)
194 271b7cf9 Renรฉ Nussbaumer
195 271b7cf9 Renรฉ Nussbaumer
  @staticmethod
196 3ecf6786 Iustin Pop
  def perspective_blockdev_remove(params):
197 3ecf6786 Iustin Pop
    """Remove a block device.
198 3ecf6786 Iustin Pop

199 3ecf6786 Iustin Pop
    """
200 a8083063 Iustin Pop
    bdev_s = params[0]
201 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
202 821d1bd1 Iustin Pop
    return backend.BlockdevRemove(bdev)
203 a8083063 Iustin Pop
204 3ecf6786 Iustin Pop
  @staticmethod
205 f3e513ad Iustin Pop
  def perspective_blockdev_rename(params):
206 f3e513ad Iustin Pop
    """Remove a block device.
207 f3e513ad Iustin Pop

208 f3e513ad Iustin Pop
    """
209 f3e513ad Iustin Pop
    devlist = [(objects.Disk.FromDict(ds), uid) for ds, uid in params]
210 821d1bd1 Iustin Pop
    return backend.BlockdevRename(devlist)
211 f3e513ad Iustin Pop
212 f3e513ad Iustin Pop
  @staticmethod
213 3ecf6786 Iustin Pop
  def perspective_blockdev_assemble(params):
214 3ecf6786 Iustin Pop
    """Assemble a block device.
215 3ecf6786 Iustin Pop

216 3ecf6786 Iustin Pop
    """
217 3f78eef2 Iustin Pop
    bdev_s, owner, on_primary = params
218 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
219 a8083063 Iustin Pop
    if bdev is None:
220 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
221 821d1bd1 Iustin Pop
    return backend.BlockdevAssemble(bdev, owner, on_primary)
222 a8083063 Iustin Pop
223 3ecf6786 Iustin Pop
  @staticmethod
224 3ecf6786 Iustin Pop
  def perspective_blockdev_shutdown(params):
225 3ecf6786 Iustin Pop
    """Shutdown a block device.
226 3ecf6786 Iustin Pop

227 3ecf6786 Iustin Pop
    """
228 a8083063 Iustin Pop
    bdev_s = params[0]
229 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
230 a8083063 Iustin Pop
    if bdev is None:
231 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
232 821d1bd1 Iustin Pop
    return backend.BlockdevShutdown(bdev)
233 a8083063 Iustin Pop
234 3ecf6786 Iustin Pop
  @staticmethod
235 153d9724 Iustin Pop
  def perspective_blockdev_addchildren(params):
236 3ecf6786 Iustin Pop
    """Add a child to a mirror device.
237 3ecf6786 Iustin Pop

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

241 3ecf6786 Iustin Pop
    """
242 a8083063 Iustin Pop
    bdev_s, ndev_s = params
243 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
244 153d9724 Iustin Pop
    ndevs = [objects.Disk.FromDict(disk_s) for disk_s in ndev_s]
245 153d9724 Iustin Pop
    if bdev is None or ndevs.count(None) > 0:
246 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
247 821d1bd1 Iustin Pop
    return backend.BlockdevAddchildren(bdev, ndevs)
248 a8083063 Iustin Pop
249 3ecf6786 Iustin Pop
  @staticmethod
250 153d9724 Iustin Pop
  def perspective_blockdev_removechildren(params):
251 3ecf6786 Iustin Pop
    """Remove a child from a mirror device.
252 3ecf6786 Iustin Pop

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

256 3ecf6786 Iustin Pop
    """
257 a8083063 Iustin Pop
    bdev_s, ndev_s = params
258 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
259 153d9724 Iustin Pop
    ndevs = [objects.Disk.FromDict(disk_s) for disk_s in ndev_s]
260 153d9724 Iustin Pop
    if bdev is None or ndevs.count(None) > 0:
261 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
262 821d1bd1 Iustin Pop
    return backend.BlockdevRemovechildren(bdev, ndevs)
263 a8083063 Iustin Pop
264 3ecf6786 Iustin Pop
  @staticmethod
265 3ecf6786 Iustin Pop
  def perspective_blockdev_getmirrorstatus(params):
266 3ecf6786 Iustin Pop
    """Return the mirror status for a list of disks.
267 3ecf6786 Iustin Pop

268 3ecf6786 Iustin Pop
    """
269 319856a9 Michael Hanselmann
    disks = [objects.Disk.FromDict(dsk_s)
270 36145b12 Michael Hanselmann
             for dsk_s in params]
271 36145b12 Michael Hanselmann
    return [status.ToDict()
272 36145b12 Michael Hanselmann
            for status in backend.BlockdevGetmirrorstatus(disks)]
273 a8083063 Iustin Pop
274 3ecf6786 Iustin Pop
  @staticmethod
275 b8d26c6e Michael Hanselmann
  def perspective_blockdev_getmirrorstatus_multi(params):
276 b8d26c6e Michael Hanselmann
    """Return the mirror status for a list of disks.
277 b8d26c6e Michael Hanselmann

278 b8d26c6e Michael Hanselmann
    """
279 b8d26c6e Michael Hanselmann
    (node_disks, ) = params
280 b8d26c6e Michael Hanselmann
281 b8d26c6e Michael Hanselmann
    node_name = netutils.Hostname.GetSysName()
282 b8d26c6e Michael Hanselmann
283 b8d26c6e Michael Hanselmann
    disks = [objects.Disk.FromDict(dsk_s)
284 b8d26c6e Michael Hanselmann
             for dsk_s in node_disks.get(node_name, [])]
285 b8d26c6e Michael Hanselmann
286 c6a9dffa Michael Hanselmann
    result = []
287 c6a9dffa Michael Hanselmann
288 c6a9dffa Michael Hanselmann
    for (success, status) in backend.BlockdevGetmirrorstatusMulti(disks):
289 c6a9dffa Michael Hanselmann
      if success:
290 c6a9dffa Michael Hanselmann
        result.append((success, status.ToDict()))
291 c6a9dffa Michael Hanselmann
      else:
292 c6a9dffa Michael Hanselmann
        result.append((success, status))
293 c6a9dffa Michael Hanselmann
294 c6a9dffa Michael Hanselmann
    return result
295 b8d26c6e Michael Hanselmann
296 b8d26c6e Michael Hanselmann
  @staticmethod
297 3ecf6786 Iustin Pop
  def perspective_blockdev_find(params):
298 3ecf6786 Iustin Pop
    """Expose the FindBlockDevice functionality for a disk.
299 3ecf6786 Iustin Pop

300 3ecf6786 Iustin Pop
    This will try to find but not activate a disk.
301 3ecf6786 Iustin Pop

302 3ecf6786 Iustin Pop
    """
303 319856a9 Michael Hanselmann
    disk = objects.Disk.FromDict(params[0])
304 ddfe2228 Michael Hanselmann
305 ddfe2228 Michael Hanselmann
    result = backend.BlockdevFind(disk)
306 ddfe2228 Michael Hanselmann
    if result is None:
307 ddfe2228 Michael Hanselmann
      return None
308 ddfe2228 Michael Hanselmann
309 ddfe2228 Michael Hanselmann
    return result.ToDict()
310 a8083063 Iustin Pop
311 3ecf6786 Iustin Pop
  @staticmethod
312 3ecf6786 Iustin Pop
  def perspective_blockdev_snapshot(params):
313 3ecf6786 Iustin Pop
    """Create a snapshot device.
314 3ecf6786 Iustin Pop

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

319 3ecf6786 Iustin Pop
    """
320 319856a9 Michael Hanselmann
    cfbd = objects.Disk.FromDict(params[0])
321 821d1bd1 Iustin Pop
    return backend.BlockdevSnapshot(cfbd)
322 a8083063 Iustin Pop
323 4c8ba8b3 Iustin Pop
  @staticmethod
324 4c8ba8b3 Iustin Pop
  def perspective_blockdev_grow(params):
325 4c8ba8b3 Iustin Pop
    """Grow a stack of devices.
326 4c8ba8b3 Iustin Pop

327 4c8ba8b3 Iustin Pop
    """
328 4c8ba8b3 Iustin Pop
    cfbd = objects.Disk.FromDict(params[0])
329 4c8ba8b3 Iustin Pop
    amount = params[1]
330 821d1bd1 Iustin Pop
    return backend.BlockdevGrow(cfbd, amount)
331 4c8ba8b3 Iustin Pop
332 d61cbe76 Iustin Pop
  @staticmethod
333 d61cbe76 Iustin Pop
  def perspective_blockdev_close(params):
334 d61cbe76 Iustin Pop
    """Closes the given block devices.
335 d61cbe76 Iustin Pop

336 d61cbe76 Iustin Pop
    """
337 b2e7666a Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in params[1]]
338 821d1bd1 Iustin Pop
    return backend.BlockdevClose(params[0], disks)
339 d61cbe76 Iustin Pop
340 968a7623 Iustin Pop
  @staticmethod
341 968a7623 Iustin Pop
  def perspective_blockdev_getsize(params):
342 968a7623 Iustin Pop
    """Compute the sizes of the given block devices.
343 968a7623 Iustin Pop

344 968a7623 Iustin Pop
    """
345 968a7623 Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in params[0]]
346 968a7623 Iustin Pop
    return backend.BlockdevGetsize(disks)
347 968a7623 Iustin Pop
348 858f3d18 Iustin Pop
  @staticmethod
349 858f3d18 Iustin Pop
  def perspective_blockdev_export(params):
350 858f3d18 Iustin Pop
    """Compute the sizes of the given block devices.
351 858f3d18 Iustin Pop

352 858f3d18 Iustin Pop
    """
353 858f3d18 Iustin Pop
    disk = objects.Disk.FromDict(params[0])
354 858f3d18 Iustin Pop
    dest_node, dest_path, cluster_name = params[1:]
355 858f3d18 Iustin Pop
    return backend.BlockdevExport(disk, dest_node, dest_path, cluster_name)
356 858f3d18 Iustin Pop
357 6b93ec9d Iustin Pop
  # blockdev/drbd specific methods ----------
358 6b93ec9d Iustin Pop
359 6b93ec9d Iustin Pop
  @staticmethod
360 6b93ec9d Iustin Pop
  def perspective_drbd_disconnect_net(params):
361 6b93ec9d Iustin Pop
    """Disconnects the network connection of drbd disks.
362 6b93ec9d Iustin Pop

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

366 6b93ec9d Iustin Pop
    """
367 6b93ec9d Iustin Pop
    nodes_ip, disks = params
368 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
369 6b93ec9d Iustin Pop
    return backend.DrbdDisconnectNet(nodes_ip, disks)
370 6b93ec9d Iustin Pop
371 6b93ec9d Iustin Pop
  @staticmethod
372 6b93ec9d Iustin Pop
  def perspective_drbd_attach_net(params):
373 6b93ec9d Iustin Pop
    """Attaches the network connection of drbd disks.
374 6b93ec9d Iustin Pop

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

378 6b93ec9d Iustin Pop
    """
379 6b93ec9d Iustin Pop
    nodes_ip, disks, instance_name, multimaster = params
380 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
381 821d1bd1 Iustin Pop
    return backend.DrbdAttachNet(nodes_ip, disks,
382 821d1bd1 Iustin Pop
                                     instance_name, multimaster)
383 6b93ec9d Iustin Pop
384 6b93ec9d Iustin Pop
  @staticmethod
385 6b93ec9d Iustin Pop
  def perspective_drbd_wait_sync(params):
386 6b93ec9d Iustin Pop
    """Wait until DRBD disks are synched.
387 6b93ec9d Iustin Pop

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

391 6b93ec9d Iustin Pop
    """
392 6b93ec9d Iustin Pop
    nodes_ip, disks = params
393 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
394 6b93ec9d Iustin Pop
    return backend.DrbdWaitSync(nodes_ip, disks)
395 6b93ec9d Iustin Pop
396 c46b9782 Luca Bigliardi
  @staticmethod
397 c46b9782 Luca Bigliardi
  def perspective_drbd_helper(params):
398 c46b9782 Luca Bigliardi
    """Query drbd helper.
399 c46b9782 Luca Bigliardi

400 c46b9782 Luca Bigliardi
    """
401 c46b9782 Luca Bigliardi
    return backend.GetDrbdUsermodeHelper()
402 c46b9782 Luca Bigliardi
403 a8083063 Iustin Pop
  # export/import  --------------------------
404 a8083063 Iustin Pop
405 3ecf6786 Iustin Pop
  @staticmethod
406 3ecf6786 Iustin Pop
  def perspective_finalize_export(params):
407 3ecf6786 Iustin Pop
    """Expose the finalize export functionality.
408 a8083063 Iustin Pop

409 3ecf6786 Iustin Pop
    """
410 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
411 7b651654 Michael Hanselmann
412 7b651654 Michael Hanselmann
    snap_disks = []
413 7b651654 Michael Hanselmann
    for disk in params[1]:
414 7b651654 Michael Hanselmann
      if isinstance(disk, bool):
415 7b651654 Michael Hanselmann
        snap_disks.append(disk)
416 7b651654 Michael Hanselmann
      else:
417 7b651654 Michael Hanselmann
        snap_disks.append(objects.Disk.FromDict(disk))
418 7b651654 Michael Hanselmann
419 a8083063 Iustin Pop
    return backend.FinalizeExport(instance, snap_disks)
420 a8083063 Iustin Pop
421 3ecf6786 Iustin Pop
  @staticmethod
422 3ecf6786 Iustin Pop
  def perspective_export_info(params):
423 3ecf6786 Iustin Pop
    """Query information about an existing export on this node.
424 3ecf6786 Iustin Pop

425 3ecf6786 Iustin Pop
    The given path may not contain an export, in which case we return
426 3ecf6786 Iustin Pop
    None.
427 3ecf6786 Iustin Pop

428 3ecf6786 Iustin Pop
    """
429 3ecf6786 Iustin Pop
    path = params[0]
430 3eccac06 Iustin Pop
    return backend.ExportInfo(path)
431 a8083063 Iustin Pop
432 3ecf6786 Iustin Pop
  @staticmethod
433 3ecf6786 Iustin Pop
  def perspective_export_list(params):
434 3ecf6786 Iustin Pop
    """List the available exports on this node.
435 3ecf6786 Iustin Pop

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

440 3ecf6786 Iustin Pop
    """
441 a8083063 Iustin Pop
    return backend.ListExports()
442 a8083063 Iustin Pop
443 3ecf6786 Iustin Pop
  @staticmethod
444 3ecf6786 Iustin Pop
  def perspective_export_remove(params):
445 3ecf6786 Iustin Pop
    """Remove an export.
446 3ecf6786 Iustin Pop

447 3ecf6786 Iustin Pop
    """
448 a8083063 Iustin Pop
    export = params[0]
449 a8083063 Iustin Pop
    return backend.RemoveExport(export)
450 a8083063 Iustin Pop
451 a8083063 Iustin Pop
  # volume  --------------------------
452 a8083063 Iustin Pop
453 3ecf6786 Iustin Pop
  @staticmethod
454 b2a6ccd4 Iustin Pop
  def perspective_lv_list(params):
455 3ecf6786 Iustin Pop
    """Query the list of logical volumes in a given volume group.
456 3ecf6786 Iustin Pop

457 3ecf6786 Iustin Pop
    """
458 a8083063 Iustin Pop
    vgname = params[0]
459 c26a6bd2 Iustin Pop
    return backend.GetVolumeList(vgname)
460 a8083063 Iustin Pop
461 3ecf6786 Iustin Pop
  @staticmethod
462 3ecf6786 Iustin Pop
  def perspective_vg_list(params):
463 3ecf6786 Iustin Pop
    """Query the list of volume groups.
464 3ecf6786 Iustin Pop

465 3ecf6786 Iustin Pop
    """
466 a8083063 Iustin Pop
    return backend.ListVolumeGroups()
467 a8083063 Iustin Pop
468 e337de97 Michael Hanselmann
  # Storage --------------------------
469 e337de97 Michael Hanselmann
470 e337de97 Michael Hanselmann
  @staticmethod
471 e337de97 Michael Hanselmann
  def perspective_storage_list(params):
472 e337de97 Michael Hanselmann
    """Get list of storage units.
473 e337de97 Michael Hanselmann

474 e337de97 Michael Hanselmann
    """
475 e337de97 Michael Hanselmann
    (su_name, su_args, name, fields) = params
476 e337de97 Michael Hanselmann
    return storage.GetStorage(su_name, *su_args).List(name, fields)
477 e337de97 Michael Hanselmann
478 8979196a Michael Hanselmann
  @staticmethod
479 8979196a Michael Hanselmann
  def perspective_storage_modify(params):
480 8979196a Michael Hanselmann
    """Modify a storage unit.
481 8979196a Michael Hanselmann

482 8979196a Michael Hanselmann
    """
483 8979196a Michael Hanselmann
    (su_name, su_args, name, changes) = params
484 8979196a Michael Hanselmann
    return storage.GetStorage(su_name, *su_args).Modify(name, changes)
485 8979196a Michael Hanselmann
486 637b8d7e Michael Hanselmann
  @staticmethod
487 637b8d7e Michael Hanselmann
  def perspective_storage_execute(params):
488 637b8d7e Michael Hanselmann
    """Execute an operation on a storage unit.
489 637b8d7e Michael Hanselmann

490 637b8d7e Michael Hanselmann
    """
491 637b8d7e Michael Hanselmann
    (su_name, su_args, name, op) = params
492 637b8d7e Michael Hanselmann
    return storage.GetStorage(su_name, *su_args).Execute(name, op)
493 637b8d7e Michael Hanselmann
494 a8083063 Iustin Pop
  # bridge  --------------------------
495 a8083063 Iustin Pop
496 3ecf6786 Iustin Pop
  @staticmethod
497 3ecf6786 Iustin Pop
  def perspective_bridges_exist(params):
498 3ecf6786 Iustin Pop
    """Check if all bridges given exist on this node.
499 3ecf6786 Iustin Pop

500 3ecf6786 Iustin Pop
    """
501 a8083063 Iustin Pop
    bridges_list = params[0]
502 a8083063 Iustin Pop
    return backend.BridgesExist(bridges_list)
503 a8083063 Iustin Pop
504 a8083063 Iustin Pop
  # instance  --------------------------
505 a8083063 Iustin Pop
506 3ecf6786 Iustin Pop
  @staticmethod
507 3ecf6786 Iustin Pop
  def perspective_instance_os_add(params):
508 3ecf6786 Iustin Pop
    """Install an OS on a given instance.
509 3ecf6786 Iustin Pop

510 3ecf6786 Iustin Pop
    """
511 d15a9ad3 Guido Trotter
    inst_s = params[0]
512 319856a9 Michael Hanselmann
    inst = objects.Instance.FromDict(inst_s)
513 e557bae9 Guido Trotter
    reinstall = params[1]
514 4a0e011f Iustin Pop
    debug = params[2]
515 4a0e011f Iustin Pop
    return backend.InstanceOsAdd(inst, reinstall, debug)
516 a8083063 Iustin Pop
517 3ecf6786 Iustin Pop
  @staticmethod
518 decd5f45 Iustin Pop
  def perspective_instance_run_rename(params):
519 decd5f45 Iustin Pop
    """Runs the OS rename script for an instance.
520 decd5f45 Iustin Pop

521 decd5f45 Iustin Pop
    """
522 4a0e011f Iustin Pop
    inst_s, old_name, debug = params
523 319856a9 Michael Hanselmann
    inst = objects.Instance.FromDict(inst_s)
524 4a0e011f Iustin Pop
    return backend.RunRenameInstance(inst, old_name, debug)
525 decd5f45 Iustin Pop
526 decd5f45 Iustin Pop
  @staticmethod
527 3ecf6786 Iustin Pop
  def perspective_instance_shutdown(params):
528 3ecf6786 Iustin Pop
    """Shutdown an instance.
529 3ecf6786 Iustin Pop

530 3ecf6786 Iustin Pop
    """
531 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
532 6263189c Guido Trotter
    timeout = params[1]
533 6263189c Guido Trotter
    return backend.InstanceShutdown(instance, timeout)
534 a8083063 Iustin Pop
535 3ecf6786 Iustin Pop
  @staticmethod
536 3ecf6786 Iustin Pop
  def perspective_instance_start(params):
537 3ecf6786 Iustin Pop
    """Start an instance.
538 3ecf6786 Iustin Pop

539 3ecf6786 Iustin Pop
    """
540 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
541 07813a9e Iustin Pop
    return backend.StartInstance(instance)
542 a8083063 Iustin Pop
543 3ecf6786 Iustin Pop
  @staticmethod
544 6906a9d8 Guido Trotter
  def perspective_migration_info(params):
545 6906a9d8 Guido Trotter
    """Gather information about an instance to be migrated.
546 6906a9d8 Guido Trotter

547 6906a9d8 Guido Trotter
    """
548 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(params[0])
549 6906a9d8 Guido Trotter
    return backend.MigrationInfo(instance)
550 6906a9d8 Guido Trotter
551 6906a9d8 Guido Trotter
  @staticmethod
552 6906a9d8 Guido Trotter
  def perspective_accept_instance(params):
553 6906a9d8 Guido Trotter
    """Prepare the node to accept an instance.
554 6906a9d8 Guido Trotter

555 6906a9d8 Guido Trotter
    """
556 6906a9d8 Guido Trotter
    instance, info, target = params
557 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(instance)
558 6906a9d8 Guido Trotter
    return backend.AcceptInstance(instance, info, target)
559 6906a9d8 Guido Trotter
560 6906a9d8 Guido Trotter
  @staticmethod
561 6906a9d8 Guido Trotter
  def perspective_finalize_migration(params):
562 6906a9d8 Guido Trotter
    """Finalize the instance migration.
563 6906a9d8 Guido Trotter

564 6906a9d8 Guido Trotter
    """
565 6906a9d8 Guido Trotter
    instance, info, success = params
566 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(instance)
567 6906a9d8 Guido Trotter
    return backend.FinalizeMigration(instance, info, success)
568 6906a9d8 Guido Trotter
569 6906a9d8 Guido Trotter
  @staticmethod
570 2a10865c Iustin Pop
  def perspective_instance_migrate(params):
571 2a10865c Iustin Pop
    """Migrates an instance.
572 2a10865c Iustin Pop

573 2a10865c Iustin Pop
    """
574 2a10865c Iustin Pop
    instance, target, live = params
575 9f0e6b37 Iustin Pop
    instance = objects.Instance.FromDict(instance)
576 2a10865c Iustin Pop
    return backend.MigrateInstance(instance, target, live)
577 2a10865c Iustin Pop
578 2a10865c Iustin Pop
  @staticmethod
579 007a2f3e Alexander Schreiber
  def perspective_instance_reboot(params):
580 007a2f3e Alexander Schreiber
    """Reboot an instance.
581 007a2f3e Alexander Schreiber

582 007a2f3e Alexander Schreiber
    """
583 007a2f3e Alexander Schreiber
    instance = objects.Instance.FromDict(params[0])
584 007a2f3e Alexander Schreiber
    reboot_type = params[1]
585 17c3f802 Guido Trotter
    shutdown_timeout = params[2]
586 17c3f802 Guido Trotter
    return backend.InstanceReboot(instance, reboot_type, shutdown_timeout)
587 007a2f3e Alexander Schreiber
588 007a2f3e Alexander Schreiber
  @staticmethod
589 3ecf6786 Iustin Pop
  def perspective_instance_info(params):
590 3ecf6786 Iustin Pop
    """Query instance information.
591 3ecf6786 Iustin Pop

592 3ecf6786 Iustin Pop
    """
593 16ad1a83 Iustin Pop
    return backend.GetInstanceInfo(params[0], params[1])
594 a8083063 Iustin Pop
595 3ecf6786 Iustin Pop
  @staticmethod
596 56e7640c Iustin Pop
  def perspective_instance_migratable(params):
597 56e7640c Iustin Pop
    """Query whether the specified instance can be migrated.
598 56e7640c Iustin Pop

599 56e7640c Iustin Pop
    """
600 56e7640c Iustin Pop
    instance = objects.Instance.FromDict(params[0])
601 56e7640c Iustin Pop
    return backend.GetInstanceMigratable(instance)
602 56e7640c Iustin Pop
603 56e7640c Iustin Pop
  @staticmethod
604 3ecf6786 Iustin Pop
  def perspective_all_instances_info(params):
605 3ecf6786 Iustin Pop
    """Query information about all instances.
606 3ecf6786 Iustin Pop

607 3ecf6786 Iustin Pop
    """
608 e69d05fd Iustin Pop
    return backend.GetAllInstancesInfo(params[0])
609 a8083063 Iustin Pop
610 3ecf6786 Iustin Pop
  @staticmethod
611 3ecf6786 Iustin Pop
  def perspective_instance_list(params):
612 3ecf6786 Iustin Pop
    """Query the list of running instances.
613 3ecf6786 Iustin Pop

614 3ecf6786 Iustin Pop
    """
615 c26a6bd2 Iustin Pop
    return backend.GetInstanceList(params[0])
616 a8083063 Iustin Pop
617 a8083063 Iustin Pop
  # node --------------------------
618 a8083063 Iustin Pop
619 3ecf6786 Iustin Pop
  @staticmethod
620 16abfbc2 Alexander Schreiber
  def perspective_node_tcp_ping(params):
621 16abfbc2 Alexander Schreiber
    """Do a TcpPing on the remote node.
622 16abfbc2 Alexander Schreiber

623 16abfbc2 Alexander Schreiber
    """
624 a744b676 Manuel Franceschini
    return netutils.TcpPing(params[1], params[2], timeout=params[3],
625 a744b676 Manuel Franceschini
                            live_port_needed=params[4], source=params[0])
626 16abfbc2 Alexander Schreiber
627 16abfbc2 Alexander Schreiber
  @staticmethod
628 caad16e2 Iustin Pop
  def perspective_node_has_ip_address(params):
629 caad16e2 Iustin Pop
    """Checks if a node has the given ip address.
630 caad16e2 Iustin Pop

631 caad16e2 Iustin Pop
    """
632 8b312c1d Manuel Franceschini
    return netutils.IPAddress.Own(params[0])
633 caad16e2 Iustin Pop
634 caad16e2 Iustin Pop
  @staticmethod
635 3ecf6786 Iustin Pop
  def perspective_node_info(params):
636 3ecf6786 Iustin Pop
    """Query node information.
637 3ecf6786 Iustin Pop

638 3ecf6786 Iustin Pop
    """
639 e69d05fd Iustin Pop
    vgname, hypervisor_type = params
640 e69d05fd Iustin Pop
    return backend.GetNodeInfo(vgname, hypervisor_type)
641 a8083063 Iustin Pop
642 3ecf6786 Iustin Pop
  @staticmethod
643 19ddc57a Renรฉ Nussbaumer
  def perspective_etc_hosts_modify(params):
644 19ddc57a Renรฉ Nussbaumer
    """Modify a node entry in /etc/hosts.
645 19ddc57a Renรฉ Nussbaumer

646 19ddc57a Renรฉ Nussbaumer
    """
647 19ddc57a Renรฉ Nussbaumer
    backend.EtcHostsModify(params[0], params[1], params[2])
648 19ddc57a Renรฉ Nussbaumer
649 19ddc57a Renรฉ Nussbaumer
    return True
650 19ddc57a Renรฉ Nussbaumer
651 19ddc57a Renรฉ Nussbaumer
  @staticmethod
652 3ecf6786 Iustin Pop
  def perspective_node_verify(params):
653 3ecf6786 Iustin Pop
    """Run a verify sequence on this node.
654 3ecf6786 Iustin Pop

655 3ecf6786 Iustin Pop
    """
656 62c9ec92 Iustin Pop
    return backend.VerifyNode(params[0], params[1])
657 a8083063 Iustin Pop
658 3ecf6786 Iustin Pop
  @staticmethod
659 3ecf6786 Iustin Pop
  def perspective_node_start_master(params):
660 3ecf6786 Iustin Pop
    """Promote this node to master status.
661 3ecf6786 Iustin Pop

662 3ecf6786 Iustin Pop
    """
663 3583908a Guido Trotter
    return backend.StartMaster(params[0], params[1])
664 a8083063 Iustin Pop
665 3ecf6786 Iustin Pop
  @staticmethod
666 3ecf6786 Iustin Pop
  def perspective_node_stop_master(params):
667 3ecf6786 Iustin Pop
    """Demote this node from master status.
668 3ecf6786 Iustin Pop

669 3ecf6786 Iustin Pop
    """
670 1c65840b Iustin Pop
    return backend.StopMaster(params[0])
671 a8083063 Iustin Pop
672 3ecf6786 Iustin Pop
  @staticmethod
673 3ecf6786 Iustin Pop
  def perspective_node_leave_cluster(params):
674 3ecf6786 Iustin Pop
    """Cleanup after leaving a cluster.
675 3ecf6786 Iustin Pop

676 3ecf6786 Iustin Pop
    """
677 b989b9d9 Ken Wehr
    return backend.LeaveCluster(params[0])
678 a8083063 Iustin Pop
679 3ecf6786 Iustin Pop
  @staticmethod
680 3ecf6786 Iustin Pop
  def perspective_node_volumes(params):
681 3ecf6786 Iustin Pop
    """Query the list of all logical volume groups.
682 3ecf6786 Iustin Pop

683 3ecf6786 Iustin Pop
    """
684 dcb93971 Michael Hanselmann
    return backend.NodeVolumes()
685 dcb93971 Michael Hanselmann
686 56aa9fd5 Iustin Pop
  @staticmethod
687 56aa9fd5 Iustin Pop
  def perspective_node_demote_from_mc(params):
688 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
689 56aa9fd5 Iustin Pop

690 56aa9fd5 Iustin Pop
    """
691 56aa9fd5 Iustin Pop
    return backend.DemoteFromMC()
692 56aa9fd5 Iustin Pop
693 56aa9fd5 Iustin Pop
694 f5118ade Iustin Pop
  @staticmethod
695 f5118ade Iustin Pop
  def perspective_node_powercycle(params):
696 f5118ade Iustin Pop
    """Tries to powercycle the nod.
697 f5118ade Iustin Pop

698 f5118ade Iustin Pop
    """
699 f5118ade Iustin Pop
    hypervisor_type = params[0]
700 f5118ade Iustin Pop
    return backend.PowercycleNode(hypervisor_type)
701 f5118ade Iustin Pop
702 f5118ade Iustin Pop
703 a8083063 Iustin Pop
  # cluster --------------------------
704 a8083063 Iustin Pop
705 3ecf6786 Iustin Pop
  @staticmethod
706 3ecf6786 Iustin Pop
  def perspective_version(params):
707 3ecf6786 Iustin Pop
    """Query version information.
708 3ecf6786 Iustin Pop

709 3ecf6786 Iustin Pop
    """
710 c26a6bd2 Iustin Pop
    return constants.PROTOCOL_VERSION
711 a8083063 Iustin Pop
712 3ecf6786 Iustin Pop
  @staticmethod
713 3ecf6786 Iustin Pop
  def perspective_upload_file(params):
714 3ecf6786 Iustin Pop
    """Upload a file.
715 3ecf6786 Iustin Pop

716 3ecf6786 Iustin Pop
    Note that the backend implementation imposes strict rules on which
717 3ecf6786 Iustin Pop
    files are accepted.
718 3ecf6786 Iustin Pop

719 3ecf6786 Iustin Pop
    """
720 a8083063 Iustin Pop
    return backend.UploadFile(*params)
721 a8083063 Iustin Pop
722 4e071d3b Iustin Pop
  @staticmethod
723 4e071d3b Iustin Pop
  def perspective_master_info(params):
724 4e071d3b Iustin Pop
    """Query master information.
725 4e071d3b Iustin Pop

726 4e071d3b Iustin Pop
    """
727 4e071d3b Iustin Pop
    return backend.GetMasterInfo()
728 a8083063 Iustin Pop
729 6ddc95ec Michael Hanselmann
  @staticmethod
730 6ddc95ec Michael Hanselmann
  def perspective_write_ssconf_files(params):
731 6ddc95ec Michael Hanselmann
    """Write ssconf files.
732 6ddc95ec Michael Hanselmann

733 6ddc95ec Michael Hanselmann
    """
734 03d1dba2 Michael Hanselmann
    (values,) = params
735 03d1dba2 Michael Hanselmann
    return backend.WriteSsconfFiles(values)
736 6ddc95ec Michael Hanselmann
737 a8083063 Iustin Pop
  # os -----------------------
738 a8083063 Iustin Pop
739 3ecf6786 Iustin Pop
  @staticmethod
740 3ecf6786 Iustin Pop
  def perspective_os_diagnose(params):
741 3ecf6786 Iustin Pop
    """Query detailed information about existing OSes.
742 3ecf6786 Iustin Pop

743 3ecf6786 Iustin Pop
    """
744 255dcebd Iustin Pop
    return backend.DiagnoseOS()
745 a8083063 Iustin Pop
746 3ecf6786 Iustin Pop
  @staticmethod
747 3ecf6786 Iustin Pop
  def perspective_os_get(params):
748 3ecf6786 Iustin Pop
    """Query information about a given OS.
749 3ecf6786 Iustin Pop

750 3ecf6786 Iustin Pop
    """
751 a8083063 Iustin Pop
    name = params[0]
752 255dcebd Iustin Pop
    os_obj = backend.OSFromDisk(name)
753 c26a6bd2 Iustin Pop
    return os_obj.ToDict()
754 a8083063 Iustin Pop
755 acd9ff9e Iustin Pop
  @staticmethod
756 acd9ff9e Iustin Pop
  def perspective_os_validate(params):
757 acd9ff9e Iustin Pop
    """Run a given OS' validation routine.
758 acd9ff9e Iustin Pop

759 acd9ff9e Iustin Pop
    """
760 acd9ff9e Iustin Pop
    required, name, checks, params = params
761 acd9ff9e Iustin Pop
    return backend.ValidateOS(required, name, checks, params)
762 acd9ff9e Iustin Pop
763 a8083063 Iustin Pop
  # hooks -----------------------
764 a8083063 Iustin Pop
765 3ecf6786 Iustin Pop
  @staticmethod
766 3ecf6786 Iustin Pop
  def perspective_hooks_runner(params):
767 3ecf6786 Iustin Pop
    """Run hook scripts.
768 3ecf6786 Iustin Pop

769 3ecf6786 Iustin Pop
    """
770 a8083063 Iustin Pop
    hpath, phase, env = params
771 a8083063 Iustin Pop
    hr = backend.HooksRunner()
772 a8083063 Iustin Pop
    return hr.RunHooks(hpath, phase, env)
773 a8083063 Iustin Pop
774 8d528b7c Iustin Pop
  # iallocator -----------------
775 8d528b7c Iustin Pop
776 8d528b7c Iustin Pop
  @staticmethod
777 8d528b7c Iustin Pop
  def perspective_iallocator_runner(params):
778 8d528b7c Iustin Pop
    """Run an iallocator script.
779 8d528b7c Iustin Pop

780 8d528b7c Iustin Pop
    """
781 8d528b7c Iustin Pop
    name, idata = params
782 8d528b7c Iustin Pop
    iar = backend.IAllocatorRunner()
783 8d528b7c Iustin Pop
    return iar.Run(name, idata)
784 8d528b7c Iustin Pop
785 06009e27 Iustin Pop
  # test -----------------------
786 06009e27 Iustin Pop
787 06009e27 Iustin Pop
  @staticmethod
788 06009e27 Iustin Pop
  def perspective_test_delay(params):
789 06009e27 Iustin Pop
    """Run test delay.
790 06009e27 Iustin Pop

791 06009e27 Iustin Pop
    """
792 06009e27 Iustin Pop
    duration = params[0]
793 c26a6bd2 Iustin Pop
    status, rval = utils.TestDelay(duration)
794 c26a6bd2 Iustin Pop
    if not status:
795 c26a6bd2 Iustin Pop
      raise backend.RPCFail(rval)
796 c26a6bd2 Iustin Pop
    return rval
797 06009e27 Iustin Pop
798 4e071d3b Iustin Pop
  # file storage ---------------
799 4e071d3b Iustin Pop
800 a5d7fb43 Manuel Franceschini
  @staticmethod
801 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_create(params):
802 a5d7fb43 Manuel Franceschini
    """Create the file storage directory.
803 a5d7fb43 Manuel Franceschini

804 a5d7fb43 Manuel Franceschini
    """
805 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
806 a5d7fb43 Manuel Franceschini
    return backend.CreateFileStorageDir(file_storage_dir)
807 a5d7fb43 Manuel Franceschini
808 a5d7fb43 Manuel Franceschini
  @staticmethod
809 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_remove(params):
810 a5d7fb43 Manuel Franceschini
    """Remove the file storage directory.
811 a5d7fb43 Manuel Franceschini

812 a5d7fb43 Manuel Franceschini
    """
813 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
814 a5d7fb43 Manuel Franceschini
    return backend.RemoveFileStorageDir(file_storage_dir)
815 a5d7fb43 Manuel Franceschini
816 a5d7fb43 Manuel Franceschini
  @staticmethod
817 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_rename(params):
818 a5d7fb43 Manuel Franceschini
    """Rename the file storage directory.
819 a5d7fb43 Manuel Franceschini

820 a5d7fb43 Manuel Franceschini
    """
821 a5d7fb43 Manuel Franceschini
    old_file_storage_dir = params[0]
822 a5d7fb43 Manuel Franceschini
    new_file_storage_dir = params[1]
823 a5d7fb43 Manuel Franceschini
    return backend.RenameFileStorageDir(old_file_storage_dir,
824 a5d7fb43 Manuel Franceschini
                                        new_file_storage_dir)
825 a5d7fb43 Manuel Franceschini
826 4e071d3b Iustin Pop
  # jobs ------------------------
827 4e071d3b Iustin Pop
828 ca52cdeb Michael Hanselmann
  @staticmethod
829 7f30777b Michael Hanselmann
  @_RequireJobQueueLock
830 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_update(params):
831 ca52cdeb Michael Hanselmann
    """Update job queue.
832 ca52cdeb Michael Hanselmann

833 ca52cdeb Michael Hanselmann
    """
834 ca52cdeb Michael Hanselmann
    (file_name, content) = params
835 7f30777b Michael Hanselmann
    return backend.JobQueueUpdate(file_name, content)
836 ca52cdeb Michael Hanselmann
837 ca52cdeb Michael Hanselmann
  @staticmethod
838 f1f3f45c Michael Hanselmann
  @_RequireJobQueueLock
839 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_purge(params):
840 ca52cdeb Michael Hanselmann
    """Purge job queue.
841 ca52cdeb Michael Hanselmann

842 ca52cdeb Michael Hanselmann
    """
843 ca52cdeb Michael Hanselmann
    return backend.JobQueuePurge()
844 ca52cdeb Michael Hanselmann
845 af5ebcb1 Michael Hanselmann
  @staticmethod
846 af5ebcb1 Michael Hanselmann
  @_RequireJobQueueLock
847 af5ebcb1 Michael Hanselmann
  def perspective_jobqueue_rename(params):
848 af5ebcb1 Michael Hanselmann
    """Rename a job queue file.
849 af5ebcb1 Michael Hanselmann

850 af5ebcb1 Michael Hanselmann
    """
851 dd875d32 Michael Hanselmann
    # TODO: What if a file fails to rename?
852 c26a6bd2 Iustin Pop
    return [backend.JobQueueRename(old, new) for old, new in params]
853 af5ebcb1 Michael Hanselmann
854 6217e295 Iustin Pop
  # hypervisor ---------------
855 6217e295 Iustin Pop
856 6217e295 Iustin Pop
  @staticmethod
857 6217e295 Iustin Pop
  def perspective_hypervisor_validate_params(params):
858 6217e295 Iustin Pop
    """Validate the hypervisor parameters.
859 6217e295 Iustin Pop

860 6217e295 Iustin Pop
    """
861 6217e295 Iustin Pop
    (hvname, hvparams) = params
862 6217e295 Iustin Pop
    return backend.ValidateHVParams(hvname, hvparams)
863 6217e295 Iustin Pop
864 f942a838 Michael Hanselmann
  # Crypto
865 f942a838 Michael Hanselmann
866 f942a838 Michael Hanselmann
  @staticmethod
867 ef40fbfb Michael Hanselmann
  def perspective_x509_cert_create(params):
868 f942a838 Michael Hanselmann
    """Creates a new X509 certificate for SSL/TLS.
869 f942a838 Michael Hanselmann

870 f942a838 Michael Hanselmann
    """
871 f942a838 Michael Hanselmann
    (validity, ) = params
872 f942a838 Michael Hanselmann
    return backend.CreateX509Certificate(validity)
873 f942a838 Michael Hanselmann
874 f942a838 Michael Hanselmann
  @staticmethod
875 ef40fbfb Michael Hanselmann
  def perspective_x509_cert_remove(params):
876 f942a838 Michael Hanselmann
    """Removes a X509 certificate.
877 f942a838 Michael Hanselmann

878 f942a838 Michael Hanselmann
    """
879 f942a838 Michael Hanselmann
    (name, ) = params
880 f942a838 Michael Hanselmann
    return backend.RemoveX509Certificate(name)
881 f942a838 Michael Hanselmann
882 1651d116 Michael Hanselmann
  # Import and export
883 1651d116 Michael Hanselmann
884 1651d116 Michael Hanselmann
  @staticmethod
885 ef40fbfb Michael Hanselmann
  def perspective_import_start(params):
886 1651d116 Michael Hanselmann
    """Starts an import daemon.
887 1651d116 Michael Hanselmann

888 1651d116 Michael Hanselmann
    """
889 eb630f50 Michael Hanselmann
    (opts_s, instance, dest, dest_args) = params
890 eb630f50 Michael Hanselmann
891 eb630f50 Michael Hanselmann
    opts = objects.ImportExportOptions.FromDict(opts_s)
892 eb630f50 Michael Hanselmann
893 eb630f50 Michael Hanselmann
    return backend.StartImportExportDaemon(constants.IEM_IMPORT, opts,
894 1651d116 Michael Hanselmann
                                           None, None,
895 1651d116 Michael Hanselmann
                                           objects.Instance.FromDict(instance),
896 1651d116 Michael Hanselmann
                                           dest,
897 1651d116 Michael Hanselmann
                                           _DecodeImportExportIO(dest,
898 1651d116 Michael Hanselmann
                                                                 dest_args))
899 eb630f50 Michael Hanselmann
900 1651d116 Michael Hanselmann
  @staticmethod
901 ef40fbfb Michael Hanselmann
  def perspective_export_start(params):
902 1651d116 Michael Hanselmann
    """Starts an export daemon.
903 1651d116 Michael Hanselmann

904 1651d116 Michael Hanselmann
    """
905 eb630f50 Michael Hanselmann
    (opts_s, host, port, instance, source, source_args) = params
906 eb630f50 Michael Hanselmann
907 eb630f50 Michael Hanselmann
    opts = objects.ImportExportOptions.FromDict(opts_s)
908 eb630f50 Michael Hanselmann
909 eb630f50 Michael Hanselmann
    return backend.StartImportExportDaemon(constants.IEM_EXPORT, opts,
910 1651d116 Michael Hanselmann
                                           host, port,
911 1651d116 Michael Hanselmann
                                           objects.Instance.FromDict(instance),
912 1651d116 Michael Hanselmann
                                           source,
913 1651d116 Michael Hanselmann
                                           _DecodeImportExportIO(source,
914 1651d116 Michael Hanselmann
                                                                 source_args))
915 1651d116 Michael Hanselmann
916 1651d116 Michael Hanselmann
  @staticmethod
917 ef40fbfb Michael Hanselmann
  def perspective_impexp_status(params):
918 1651d116 Michael Hanselmann
    """Retrieves the status of an import or export daemon.
919 1651d116 Michael Hanselmann

920 1651d116 Michael Hanselmann
    """
921 1651d116 Michael Hanselmann
    return backend.GetImportExportStatus(params[0])
922 1651d116 Michael Hanselmann
923 1651d116 Michael Hanselmann
  @staticmethod
924 f81c4737 Michael Hanselmann
  def perspective_impexp_abort(params):
925 f81c4737 Michael Hanselmann
    """Aborts an import or export.
926 f81c4737 Michael Hanselmann

927 f81c4737 Michael Hanselmann
    """
928 f81c4737 Michael Hanselmann
    return backend.AbortImportExport(params[0])
929 f81c4737 Michael Hanselmann
930 f81c4737 Michael Hanselmann
  @staticmethod
931 ef40fbfb Michael Hanselmann
  def perspective_impexp_cleanup(params):
932 1651d116 Michael Hanselmann
    """Cleans up after an import or export.
933 1651d116 Michael Hanselmann

934 1651d116 Michael Hanselmann
    """
935 1651d116 Michael Hanselmann
    return backend.CleanupImportExport(params[0])
936 1651d116 Michael Hanselmann
937 a8083063 Iustin Pop
938 f93427cd Iustin Pop
def CheckNoded(_, args):
939 f93427cd Iustin Pop
  """Initial checks whether to run or exit with a failure.
940 f93427cd Iustin Pop

941 f93427cd Iustin Pop
  """
942 f93427cd Iustin Pop
  if args: # noded doesn't take any arguments
943 f93427cd Iustin Pop
    print >> sys.stderr, ("Usage: %s [-f] [-d] [-p port] [-b ADDRESS]" %
944 f93427cd Iustin Pop
                          sys.argv[0])
945 f93427cd Iustin Pop
    sys.exit(constants.EXIT_FAILURE)
946 f93427cd Iustin Pop
947 f93427cd Iustin Pop
948 3ee53f1f Iustin Pop
def PrepNoded(options, _):
949 3ee53f1f Iustin Pop
  """Preparation node daemon function, executed with the PID file held.
950 3ecf6786 Iustin Pop

951 3ecf6786 Iustin Pop
  """
952 bebf68d3 Guido Trotter
  if options.mlock:
953 bebf68d3 Guido Trotter
    request_executor_class = MlockallRequestExecutor
954 4c32a8bd Luca Bigliardi
    try:
955 4c32a8bd Luca Bigliardi
      utils.Mlockall()
956 4c32a8bd Luca Bigliardi
    except errors.NoCtypesError:
957 4c32a8bd Luca Bigliardi
      logging.warning("Cannot set memory lock, ctypes module not found")
958 4c32a8bd Luca Bigliardi
      request_executor_class = http.server.HttpServerRequestExecutor
959 bebf68d3 Guido Trotter
  else:
960 bebf68d3 Guido Trotter
    request_executor_class = http.server.HttpServerRequestExecutor
961 02bea2fc Luca Bigliardi
962 04ccf5e9 Guido Trotter
  # Read SSL certificate
963 3b1b0cb6 Guido Trotter
  if options.ssl:
964 3b1b0cb6 Guido Trotter
    ssl_params = http.HttpSslParams(ssl_key_path=options.ssl_key,
965 3b1b0cb6 Guido Trotter
                                    ssl_cert_path=options.ssl_cert)
966 3b1b0cb6 Guido Trotter
  else:
967 3b1b0cb6 Guido Trotter
    ssl_params = None
968 7d88772a Iustin Pop
969 81198f6e Iustin Pop
  err = _PrepareQueueLock()
970 81198f6e Iustin Pop
  if err is not None:
971 81198f6e Iustin Pop
    # this might be some kind of file-system/permission error; while
972 81198f6e Iustin Pop
    # this breaks the job queue functionality, we shouldn't prevent
973 81198f6e Iustin Pop
    # startup of the whole node daemon because of this
974 81198f6e Iustin Pop
    logging.critical("Can't init/verify the queue, proceeding anyway: %s", err)
975 7d88772a Iustin Pop
976 04ccf5e9 Guido Trotter
  mainloop = daemon.Mainloop()
977 04ccf5e9 Guido Trotter
  server = NodeHttpServer(mainloop, options.bind_address, options.port,
978 38b77287 Luca Bigliardi
                          ssl_params=ssl_params, ssl_verify_peer=True,
979 bebf68d3 Guido Trotter
                          request_executor_class=request_executor_class)
980 04ccf5e9 Guido Trotter
  server.Start()
981 3ee53f1f Iustin Pop
  return (mainloop, server)
982 3ee53f1f Iustin Pop
983 5119f2ec Michael Hanselmann
984 3ee53f1f Iustin Pop
def ExecNoded(options, args, prep_data): # pylint: disable-msg=W0613
985 3ee53f1f Iustin Pop
  """Main node daemon function, executed with the PID file held.
986 3ee53f1f Iustin Pop

987 3ee53f1f Iustin Pop
  """
988 3ee53f1f Iustin Pop
  (mainloop, server) = prep_data
989 04ccf5e9 Guido Trotter
  try:
990 04ccf5e9 Guido Trotter
    mainloop.Run()
991 04ccf5e9 Guido Trotter
  finally:
992 04ccf5e9 Guido Trotter
    server.Stop()
993 a8083063 Iustin Pop
994 a8083063 Iustin Pop
995 5119f2ec Michael Hanselmann
def Main():
996 04ccf5e9 Guido Trotter
  """Main function for the node daemon.
997 04ccf5e9 Guido Trotter

998 04ccf5e9 Guido Trotter
  """
999 04ccf5e9 Guido Trotter
  parser = OptionParser(description="Ganeti node daemon",
1000 04ccf5e9 Guido Trotter
                        usage="%prog [-f] [-d] [-p port] [-b ADDRESS]",
1001 04ccf5e9 Guido Trotter
                        version="%%prog (ganeti) %s" %
1002 04ccf5e9 Guido Trotter
                        constants.RELEASE_VERSION)
1003 bebf68d3 Guido Trotter
  parser.add_option("--no-mlock", dest="mlock",
1004 bebf68d3 Guido Trotter
                    help="Do not mlock the node memory in ram",
1005 bebf68d3 Guido Trotter
                    default=True, action="store_false")
1006 bebf68d3 Guido Trotter
1007 3ee53f1f Iustin Pop
  daemon.GenericMain(constants.NODED, parser, CheckNoded, PrepNoded, ExecNoded,
1008 084aba47 Michael Hanselmann
                     default_ssl_cert=constants.NODED_CERT_FILE,
1009 1c54156d Luca Bigliardi
                     default_ssl_key=constants.NODED_CERT_FILE,
1010 565083ef Luca Bigliardi
                     console_logging=True)