Statistics
| Branch: | Tag: | Revision:

root / lib / server / noded.py @ 5d0566de

History | View | Annotate | Download (28.3 kB)

1 69cf3abd Michael Hanselmann
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 c417e115 Iustin Pop
# Copyright (C) 2006, 2007, 2010, 2011 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 a8083063 Iustin Pop
"""Ganeti node daemon"""
23 a8083063 Iustin Pop
24 b459a848 Andrea Spadaccini
# pylint: disable=C0103,W0142
25 7260cfbe Iustin Pop
26 7260cfbe Iustin Pop
# C0103: Functions in this module need to have a given name structure,
27 7260cfbe Iustin Pop
# and the name of the daemon doesn't match
28 7260cfbe Iustin Pop
29 7260cfbe Iustin Pop
# W0142: Used * or ** magic, since we do use it extensively in this
30 7260cfbe Iustin Pop
# module
31 3ecf6786 Iustin Pop
32 a8083063 Iustin Pop
import os
33 a8083063 Iustin Pop
import sys
34 c89189b1 Iustin Pop
import logging
35 84b58db2 Michael Hanselmann
import signal
36 f01738fc Iustin Pop
import codecs
37 a8083063 Iustin Pop
38 a8083063 Iustin Pop
from optparse import OptionParser
39 a8083063 Iustin Pop
40 a8083063 Iustin Pop
from ganeti import backend
41 a8083063 Iustin Pop
from ganeti import constants
42 a8083063 Iustin Pop
from ganeti import objects
43 a8083063 Iustin Pop
from ganeti import errors
44 25d6d12a Michael Hanselmann
from ganeti import jstore
45 cc28af80 Michael Hanselmann
from ganeti import daemon
46 1df6506c Michael Hanselmann
from ganeti import http
47 16abfbc2 Alexander Schreiber
from ganeti import utils
48 e337de97 Michael Hanselmann
from ganeti import storage
49 ab221ddf Michael Hanselmann
from ganeti import serializer
50 a744b676 Manuel Franceschini
from ganeti import netutils
51 a8083063 Iustin Pop
52 b459a848 Andrea Spadaccini
import ganeti.http.server # pylint: disable=W0611
53 19205c39 Michael Hanselmann
54 a8083063 Iustin Pop
55 25d6d12a Michael Hanselmann
queue_lock = None
56 25d6d12a Michael Hanselmann
57 25d6d12a Michael Hanselmann
58 81198f6e Iustin Pop
def _PrepareQueueLock():
59 81198f6e Iustin Pop
  """Try to prepare the queue lock.
60 81198f6e Iustin Pop

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

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

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

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

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

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

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

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

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

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

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

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

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

227 3ecf6786 Iustin Pop
    """
228 c417e115 Iustin Pop
    bdev_s, owner, on_primary, idx = params
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 c417e115 Iustin Pop
    return backend.BlockdevAssemble(bdev, owner, on_primary, idx)
233 a8083063 Iustin Pop
234 3ecf6786 Iustin Pop
  @staticmethod
235 3ecf6786 Iustin Pop
  def perspective_blockdev_shutdown(params):
236 3ecf6786 Iustin Pop
    """Shutdown a block device.
237 3ecf6786 Iustin Pop

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

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

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

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

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

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

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

311 3ecf6786 Iustin Pop
    This will try to find but not activate a disk.
312 3ecf6786 Iustin Pop

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

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

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

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

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

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

364 858f3d18 Iustin Pop
    """
365 858f3d18 Iustin Pop
    disk = objects.Disk.FromDict(params[0])
366 858f3d18 Iustin Pop
    dest_node, dest_path, cluster_name = params[1:]
367 858f3d18 Iustin Pop
    return backend.BlockdevExport(disk, dest_node, dest_path, cluster_name)
368 858f3d18 Iustin Pop
369 6b93ec9d Iustin Pop
  # blockdev/drbd specific methods ----------
370 6b93ec9d Iustin Pop
371 6b93ec9d Iustin Pop
  @staticmethod
372 6b93ec9d Iustin Pop
  def perspective_drbd_disconnect_net(params):
373 6b93ec9d Iustin Pop
    """Disconnects 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 = params
380 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
381 6b93ec9d Iustin Pop
    return backend.DrbdDisconnectNet(nodes_ip, disks)
382 6b93ec9d Iustin Pop
383 6b93ec9d Iustin Pop
  @staticmethod
384 6b93ec9d Iustin Pop
  def perspective_drbd_attach_net(params):
385 6b93ec9d Iustin Pop
    """Attaches the network connection of drbd disks.
386 6b93ec9d Iustin Pop

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

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

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

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

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

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

437 3ecf6786 Iustin Pop
    The given path may not contain an export, in which case we return
438 3ecf6786 Iustin Pop
    None.
439 3ecf6786 Iustin Pop

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

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

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

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

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

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

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

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

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

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

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

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

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

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

560 3ecf6786 Iustin Pop
    """
561 323f9095 Stephen Shirley
    (instance_name, startup_paused) = params
562 323f9095 Stephen Shirley
    instance = objects.Instance.FromDict(instance_name)
563 323f9095 Stephen Shirley
    return backend.StartInstance(instance, startup_paused)
564 a8083063 Iustin Pop
565 3ecf6786 Iustin Pop
  @staticmethod
566 6906a9d8 Guido Trotter
  def perspective_migration_info(params):
567 6906a9d8 Guido Trotter
    """Gather information about an instance to be migrated.
568 6906a9d8 Guido Trotter

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

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

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

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

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

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

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

629 3ecf6786 Iustin Pop
    """
630 e69d05fd Iustin Pop
    return backend.GetAllInstancesInfo(params[0])
631 a8083063 Iustin Pop
632 3ecf6786 Iustin Pop
  @staticmethod
633 3ecf6786 Iustin Pop
  def perspective_instance_list(params):
634 3ecf6786 Iustin Pop
    """Query the list of running instances.
635 3ecf6786 Iustin Pop

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

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

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

660 3ecf6786 Iustin Pop
    """
661 e69d05fd Iustin Pop
    vgname, hypervisor_type = params
662 e69d05fd Iustin Pop
    return backend.GetNodeInfo(vgname, hypervisor_type)
663 a8083063 Iustin Pop
664 3ecf6786 Iustin Pop
  @staticmethod
665 19ddc57a Renรฉ Nussbaumer
  def perspective_etc_hosts_modify(params):
666 19ddc57a Renรฉ Nussbaumer
    """Modify a node entry in /etc/hosts.
667 19ddc57a Renรฉ Nussbaumer

668 19ddc57a Renรฉ Nussbaumer
    """
669 19ddc57a Renรฉ Nussbaumer
    backend.EtcHostsModify(params[0], params[1], params[2])
670 19ddc57a Renรฉ Nussbaumer
671 19ddc57a Renรฉ Nussbaumer
    return True
672 19ddc57a Renรฉ Nussbaumer
673 19ddc57a Renรฉ Nussbaumer
  @staticmethod
674 3ecf6786 Iustin Pop
  def perspective_node_verify(params):
675 3ecf6786 Iustin Pop
    """Run a verify sequence on this node.
676 3ecf6786 Iustin Pop

677 3ecf6786 Iustin Pop
    """
678 62c9ec92 Iustin Pop
    return backend.VerifyNode(params[0], params[1])
679 a8083063 Iustin Pop
680 3ecf6786 Iustin Pop
  @staticmethod
681 c06e0c83 Andrea Spadaccini
  def perspective_node_start_master_daemons(params):
682 c06e0c83 Andrea Spadaccini
    """Start the master daemons on this node.
683 3ecf6786 Iustin Pop

684 3ecf6786 Iustin Pop
    """
685 c06e0c83 Andrea Spadaccini
    return backend.StartMasterDaemons(params[0])
686 c06e0c83 Andrea Spadaccini
687 c06e0c83 Andrea Spadaccini
  @staticmethod
688 c06e0c83 Andrea Spadaccini
  def perspective_node_activate_master_ip(params):
689 c06e0c83 Andrea Spadaccini
    """Activate the master IP on this node.
690 c06e0c83 Andrea Spadaccini

691 c06e0c83 Andrea Spadaccini
    """
692 c06e0c83 Andrea Spadaccini
    return backend.ActivateMasterIp()
693 c06e0c83 Andrea Spadaccini
694 c06e0c83 Andrea Spadaccini
  @staticmethod
695 c06e0c83 Andrea Spadaccini
  def perspective_node_deactivate_master_ip(params):
696 c06e0c83 Andrea Spadaccini
    """Deactivate the master IP on this node.
697 c06e0c83 Andrea Spadaccini

698 c06e0c83 Andrea Spadaccini
    """
699 c06e0c83 Andrea Spadaccini
    return backend.DeactivateMasterIp()
700 a8083063 Iustin Pop
701 3ecf6786 Iustin Pop
  @staticmethod
702 3ecf6786 Iustin Pop
  def perspective_node_stop_master(params):
703 c06e0c83 Andrea Spadaccini
    """Deactivate the master IP and stops master daemons on this node.
704 c06e0c83 Andrea Spadaccini

705 c06e0c83 Andrea Spadaccini
    Sometimes both operations need to be executed at the same time (doing one of
706 c06e0c83 Andrea Spadaccini
    the two would make impossible to do the other one).
707 3ecf6786 Iustin Pop

708 3ecf6786 Iustin Pop
    """
709 c06e0c83 Andrea Spadaccini
    backend.DeactivateMasterIp()
710 c06e0c83 Andrea Spadaccini
    return backend.StopMasterDaemons()
711 a8083063 Iustin Pop
712 3ecf6786 Iustin Pop
  @staticmethod
713 3ecf6786 Iustin Pop
  def perspective_node_leave_cluster(params):
714 3ecf6786 Iustin Pop
    """Cleanup after leaving a cluster.
715 3ecf6786 Iustin Pop

716 3ecf6786 Iustin Pop
    """
717 b989b9d9 Ken Wehr
    return backend.LeaveCluster(params[0])
718 a8083063 Iustin Pop
719 3ecf6786 Iustin Pop
  @staticmethod
720 3ecf6786 Iustin Pop
  def perspective_node_volumes(params):
721 3ecf6786 Iustin Pop
    """Query the list of all logical volume groups.
722 3ecf6786 Iustin Pop

723 3ecf6786 Iustin Pop
    """
724 dcb93971 Michael Hanselmann
    return backend.NodeVolumes()
725 dcb93971 Michael Hanselmann
726 56aa9fd5 Iustin Pop
  @staticmethod
727 56aa9fd5 Iustin Pop
  def perspective_node_demote_from_mc(params):
728 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
729 56aa9fd5 Iustin Pop

730 56aa9fd5 Iustin Pop
    """
731 56aa9fd5 Iustin Pop
    return backend.DemoteFromMC()
732 56aa9fd5 Iustin Pop
733 f5118ade Iustin Pop
  @staticmethod
734 f5118ade Iustin Pop
  def perspective_node_powercycle(params):
735 f5118ade Iustin Pop
    """Tries to powercycle the nod.
736 f5118ade Iustin Pop

737 f5118ade Iustin Pop
    """
738 f5118ade Iustin Pop
    hypervisor_type = params[0]
739 f5118ade Iustin Pop
    return backend.PowercycleNode(hypervisor_type)
740 f5118ade Iustin Pop
741 a8083063 Iustin Pop
  # cluster --------------------------
742 a8083063 Iustin Pop
743 3ecf6786 Iustin Pop
  @staticmethod
744 3ecf6786 Iustin Pop
  def perspective_version(params):
745 3ecf6786 Iustin Pop
    """Query version information.
746 3ecf6786 Iustin Pop

747 3ecf6786 Iustin Pop
    """
748 c26a6bd2 Iustin Pop
    return constants.PROTOCOL_VERSION
749 a8083063 Iustin Pop
750 3ecf6786 Iustin Pop
  @staticmethod
751 3ecf6786 Iustin Pop
  def perspective_upload_file(params):
752 3ecf6786 Iustin Pop
    """Upload a file.
753 3ecf6786 Iustin Pop

754 3ecf6786 Iustin Pop
    Note that the backend implementation imposes strict rules on which
755 3ecf6786 Iustin Pop
    files are accepted.
756 3ecf6786 Iustin Pop

757 3ecf6786 Iustin Pop
    """
758 a8083063 Iustin Pop
    return backend.UploadFile(*params)
759 a8083063 Iustin Pop
760 4e071d3b Iustin Pop
  @staticmethod
761 4e071d3b Iustin Pop
  def perspective_master_info(params):
762 4e071d3b Iustin Pop
    """Query master information.
763 4e071d3b Iustin Pop

764 4e071d3b Iustin Pop
    """
765 4e071d3b Iustin Pop
    return backend.GetMasterInfo()
766 a8083063 Iustin Pop
767 6ddc95ec Michael Hanselmann
  @staticmethod
768 4f6014d4 Renรฉ Nussbaumer
  def perspective_run_oob(params):
769 4f6014d4 Renรฉ Nussbaumer
    """Runs oob on node.
770 4f6014d4 Renรฉ Nussbaumer

771 4f6014d4 Renรฉ Nussbaumer
    """
772 1aa88d95 Renรฉ Nussbaumer
    output = backend.RunOob(params[0], params[1], params[2], params[3])
773 1aa88d95 Renรฉ Nussbaumer
    if output:
774 1aa88d95 Renรฉ Nussbaumer
      result = serializer.LoadJson(output)
775 1aa88d95 Renรฉ Nussbaumer
    else:
776 1aa88d95 Renรฉ Nussbaumer
      result = None
777 1aa88d95 Renรฉ Nussbaumer
    return result
778 4f6014d4 Renรฉ Nussbaumer
779 4f6014d4 Renรฉ Nussbaumer
  @staticmethod
780 6ddc95ec Michael Hanselmann
  def perspective_write_ssconf_files(params):
781 6ddc95ec Michael Hanselmann
    """Write ssconf files.
782 6ddc95ec Michael Hanselmann

783 6ddc95ec Michael Hanselmann
    """
784 03d1dba2 Michael Hanselmann
    (values,) = params
785 03d1dba2 Michael Hanselmann
    return backend.WriteSsconfFiles(values)
786 6ddc95ec Michael Hanselmann
787 a8083063 Iustin Pop
  # os -----------------------
788 a8083063 Iustin Pop
789 3ecf6786 Iustin Pop
  @staticmethod
790 3ecf6786 Iustin Pop
  def perspective_os_diagnose(params):
791 3ecf6786 Iustin Pop
    """Query detailed information about existing OSes.
792 3ecf6786 Iustin Pop

793 3ecf6786 Iustin Pop
    """
794 255dcebd Iustin Pop
    return backend.DiagnoseOS()
795 a8083063 Iustin Pop
796 3ecf6786 Iustin Pop
  @staticmethod
797 3ecf6786 Iustin Pop
  def perspective_os_get(params):
798 3ecf6786 Iustin Pop
    """Query information about a given OS.
799 3ecf6786 Iustin Pop

800 3ecf6786 Iustin Pop
    """
801 a8083063 Iustin Pop
    name = params[0]
802 255dcebd Iustin Pop
    os_obj = backend.OSFromDisk(name)
803 c26a6bd2 Iustin Pop
    return os_obj.ToDict()
804 a8083063 Iustin Pop
805 acd9ff9e Iustin Pop
  @staticmethod
806 acd9ff9e Iustin Pop
  def perspective_os_validate(params):
807 acd9ff9e Iustin Pop
    """Run a given OS' validation routine.
808 acd9ff9e Iustin Pop

809 acd9ff9e Iustin Pop
    """
810 acd9ff9e Iustin Pop
    required, name, checks, params = params
811 acd9ff9e Iustin Pop
    return backend.ValidateOS(required, name, checks, params)
812 acd9ff9e Iustin Pop
813 a8083063 Iustin Pop
  # hooks -----------------------
814 a8083063 Iustin Pop
815 3ecf6786 Iustin Pop
  @staticmethod
816 3ecf6786 Iustin Pop
  def perspective_hooks_runner(params):
817 3ecf6786 Iustin Pop
    """Run hook scripts.
818 3ecf6786 Iustin Pop

819 3ecf6786 Iustin Pop
    """
820 a8083063 Iustin Pop
    hpath, phase, env = params
821 a8083063 Iustin Pop
    hr = backend.HooksRunner()
822 a8083063 Iustin Pop
    return hr.RunHooks(hpath, phase, env)
823 a8083063 Iustin Pop
824 8d528b7c Iustin Pop
  # iallocator -----------------
825 8d528b7c Iustin Pop
826 8d528b7c Iustin Pop
  @staticmethod
827 8d528b7c Iustin Pop
  def perspective_iallocator_runner(params):
828 8d528b7c Iustin Pop
    """Run an iallocator script.
829 8d528b7c Iustin Pop

830 8d528b7c Iustin Pop
    """
831 8d528b7c Iustin Pop
    name, idata = params
832 8d528b7c Iustin Pop
    iar = backend.IAllocatorRunner()
833 8d528b7c Iustin Pop
    return iar.Run(name, idata)
834 8d528b7c Iustin Pop
835 06009e27 Iustin Pop
  # test -----------------------
836 06009e27 Iustin Pop
837 06009e27 Iustin Pop
  @staticmethod
838 06009e27 Iustin Pop
  def perspective_test_delay(params):
839 06009e27 Iustin Pop
    """Run test delay.
840 06009e27 Iustin Pop

841 06009e27 Iustin Pop
    """
842 06009e27 Iustin Pop
    duration = params[0]
843 c26a6bd2 Iustin Pop
    status, rval = utils.TestDelay(duration)
844 c26a6bd2 Iustin Pop
    if not status:
845 c26a6bd2 Iustin Pop
      raise backend.RPCFail(rval)
846 c26a6bd2 Iustin Pop
    return rval
847 06009e27 Iustin Pop
848 4e071d3b Iustin Pop
  # file storage ---------------
849 4e071d3b Iustin Pop
850 a5d7fb43 Manuel Franceschini
  @staticmethod
851 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_create(params):
852 a5d7fb43 Manuel Franceschini
    """Create the file storage directory.
853 a5d7fb43 Manuel Franceschini

854 a5d7fb43 Manuel Franceschini
    """
855 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
856 a5d7fb43 Manuel Franceschini
    return backend.CreateFileStorageDir(file_storage_dir)
857 a5d7fb43 Manuel Franceschini
858 a5d7fb43 Manuel Franceschini
  @staticmethod
859 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_remove(params):
860 a5d7fb43 Manuel Franceschini
    """Remove the file storage directory.
861 a5d7fb43 Manuel Franceschini

862 a5d7fb43 Manuel Franceschini
    """
863 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
864 a5d7fb43 Manuel Franceschini
    return backend.RemoveFileStorageDir(file_storage_dir)
865 a5d7fb43 Manuel Franceschini
866 a5d7fb43 Manuel Franceschini
  @staticmethod
867 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_rename(params):
868 a5d7fb43 Manuel Franceschini
    """Rename the file storage directory.
869 a5d7fb43 Manuel Franceschini

870 a5d7fb43 Manuel Franceschini
    """
871 a5d7fb43 Manuel Franceschini
    old_file_storage_dir = params[0]
872 a5d7fb43 Manuel Franceschini
    new_file_storage_dir = params[1]
873 a5d7fb43 Manuel Franceschini
    return backend.RenameFileStorageDir(old_file_storage_dir,
874 a5d7fb43 Manuel Franceschini
                                        new_file_storage_dir)
875 a5d7fb43 Manuel Franceschini
876 4e071d3b Iustin Pop
  # jobs ------------------------
877 4e071d3b Iustin Pop
878 ca52cdeb Michael Hanselmann
  @staticmethod
879 7f30777b Michael Hanselmann
  @_RequireJobQueueLock
880 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_update(params):
881 ca52cdeb Michael Hanselmann
    """Update job queue.
882 ca52cdeb Michael Hanselmann

883 ca52cdeb Michael Hanselmann
    """
884 ca52cdeb Michael Hanselmann
    (file_name, content) = params
885 7f30777b Michael Hanselmann
    return backend.JobQueueUpdate(file_name, content)
886 ca52cdeb Michael Hanselmann
887 ca52cdeb Michael Hanselmann
  @staticmethod
888 f1f3f45c Michael Hanselmann
  @_RequireJobQueueLock
889 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_purge(params):
890 ca52cdeb Michael Hanselmann
    """Purge job queue.
891 ca52cdeb Michael Hanselmann

892 ca52cdeb Michael Hanselmann
    """
893 ca52cdeb Michael Hanselmann
    return backend.JobQueuePurge()
894 ca52cdeb Michael Hanselmann
895 af5ebcb1 Michael Hanselmann
  @staticmethod
896 af5ebcb1 Michael Hanselmann
  @_RequireJobQueueLock
897 af5ebcb1 Michael Hanselmann
  def perspective_jobqueue_rename(params):
898 af5ebcb1 Michael Hanselmann
    """Rename a job queue file.
899 af5ebcb1 Michael Hanselmann

900 af5ebcb1 Michael Hanselmann
    """
901 dd875d32 Michael Hanselmann
    # TODO: What if a file fails to rename?
902 c26a6bd2 Iustin Pop
    return [backend.JobQueueRename(old, new) for old, new in params]
903 af5ebcb1 Michael Hanselmann
904 6217e295 Iustin Pop
  # hypervisor ---------------
905 6217e295 Iustin Pop
906 6217e295 Iustin Pop
  @staticmethod
907 6217e295 Iustin Pop
  def perspective_hypervisor_validate_params(params):
908 6217e295 Iustin Pop
    """Validate the hypervisor parameters.
909 6217e295 Iustin Pop

910 6217e295 Iustin Pop
    """
911 6217e295 Iustin Pop
    (hvname, hvparams) = params
912 6217e295 Iustin Pop
    return backend.ValidateHVParams(hvname, hvparams)
913 6217e295 Iustin Pop
914 f942a838 Michael Hanselmann
  # Crypto
915 f942a838 Michael Hanselmann
916 f942a838 Michael Hanselmann
  @staticmethod
917 ef40fbfb Michael Hanselmann
  def perspective_x509_cert_create(params):
918 f942a838 Michael Hanselmann
    """Creates a new X509 certificate for SSL/TLS.
919 f942a838 Michael Hanselmann

920 f942a838 Michael Hanselmann
    """
921 f942a838 Michael Hanselmann
    (validity, ) = params
922 f942a838 Michael Hanselmann
    return backend.CreateX509Certificate(validity)
923 f942a838 Michael Hanselmann
924 f942a838 Michael Hanselmann
  @staticmethod
925 ef40fbfb Michael Hanselmann
  def perspective_x509_cert_remove(params):
926 f942a838 Michael Hanselmann
    """Removes a X509 certificate.
927 f942a838 Michael Hanselmann

928 f942a838 Michael Hanselmann
    """
929 f942a838 Michael Hanselmann
    (name, ) = params
930 f942a838 Michael Hanselmann
    return backend.RemoveX509Certificate(name)
931 f942a838 Michael Hanselmann
932 1651d116 Michael Hanselmann
  # Import and export
933 1651d116 Michael Hanselmann
934 1651d116 Michael Hanselmann
  @staticmethod
935 ef40fbfb Michael Hanselmann
  def perspective_import_start(params):
936 1651d116 Michael Hanselmann
    """Starts an import daemon.
937 1651d116 Michael Hanselmann

938 1651d116 Michael Hanselmann
    """
939 6613661a Iustin Pop
    (opts_s, instance, component, dest, dest_args) = params
940 eb630f50 Michael Hanselmann
941 eb630f50 Michael Hanselmann
    opts = objects.ImportExportOptions.FromDict(opts_s)
942 eb630f50 Michael Hanselmann
943 eb630f50 Michael Hanselmann
    return backend.StartImportExportDaemon(constants.IEM_IMPORT, opts,
944 1651d116 Michael Hanselmann
                                           None, None,
945 1651d116 Michael Hanselmann
                                           objects.Instance.FromDict(instance),
946 6613661a Iustin Pop
                                           component, dest,
947 1651d116 Michael Hanselmann
                                           _DecodeImportExportIO(dest,
948 1651d116 Michael Hanselmann
                                                                 dest_args))
949 eb630f50 Michael Hanselmann
950 1651d116 Michael Hanselmann
  @staticmethod
951 ef40fbfb Michael Hanselmann
  def perspective_export_start(params):
952 1651d116 Michael Hanselmann
    """Starts an export daemon.
953 1651d116 Michael Hanselmann

954 1651d116 Michael Hanselmann
    """
955 6613661a Iustin Pop
    (opts_s, host, port, instance, component, source, source_args) = params
956 eb630f50 Michael Hanselmann
957 eb630f50 Michael Hanselmann
    opts = objects.ImportExportOptions.FromDict(opts_s)
958 eb630f50 Michael Hanselmann
959 eb630f50 Michael Hanselmann
    return backend.StartImportExportDaemon(constants.IEM_EXPORT, opts,
960 1651d116 Michael Hanselmann
                                           host, port,
961 1651d116 Michael Hanselmann
                                           objects.Instance.FromDict(instance),
962 6613661a Iustin Pop
                                           component, source,
963 1651d116 Michael Hanselmann
                                           _DecodeImportExportIO(source,
964 1651d116 Michael Hanselmann
                                                                 source_args))
965 1651d116 Michael Hanselmann
966 1651d116 Michael Hanselmann
  @staticmethod
967 ef40fbfb Michael Hanselmann
  def perspective_impexp_status(params):
968 1651d116 Michael Hanselmann
    """Retrieves the status of an import or export daemon.
969 1651d116 Michael Hanselmann

970 1651d116 Michael Hanselmann
    """
971 1651d116 Michael Hanselmann
    return backend.GetImportExportStatus(params[0])
972 1651d116 Michael Hanselmann
973 1651d116 Michael Hanselmann
  @staticmethod
974 f81c4737 Michael Hanselmann
  def perspective_impexp_abort(params):
975 f81c4737 Michael Hanselmann
    """Aborts an import or export.
976 f81c4737 Michael Hanselmann

977 f81c4737 Michael Hanselmann
    """
978 f81c4737 Michael Hanselmann
    return backend.AbortImportExport(params[0])
979 f81c4737 Michael Hanselmann
980 f81c4737 Michael Hanselmann
  @staticmethod
981 ef40fbfb Michael Hanselmann
  def perspective_impexp_cleanup(params):
982 1651d116 Michael Hanselmann
    """Cleans up after an import or export.
983 1651d116 Michael Hanselmann

984 1651d116 Michael Hanselmann
    """
985 1651d116 Michael Hanselmann
    return backend.CleanupImportExport(params[0])
986 1651d116 Michael Hanselmann
987 a8083063 Iustin Pop
988 f93427cd Iustin Pop
def CheckNoded(_, args):
989 f93427cd Iustin Pop
  """Initial checks whether to run or exit with a failure.
990 f93427cd Iustin Pop

991 f93427cd Iustin Pop
  """
992 f93427cd Iustin Pop
  if args: # noded doesn't take any arguments
993 f93427cd Iustin Pop
    print >> sys.stderr, ("Usage: %s [-f] [-d] [-p port] [-b ADDRESS]" %
994 f93427cd Iustin Pop
                          sys.argv[0])
995 f93427cd Iustin Pop
    sys.exit(constants.EXIT_FAILURE)
996 f01738fc Iustin Pop
  try:
997 f01738fc Iustin Pop
    codecs.lookup("string-escape")
998 f01738fc Iustin Pop
  except LookupError:
999 f01738fc Iustin Pop
    print >> sys.stderr, ("Can't load the string-escape code which is part"
1000 f01738fc Iustin Pop
                          " of the Python installation. Is your installation"
1001 f01738fc Iustin Pop
                          " complete/correct? Aborting.")
1002 f01738fc Iustin Pop
    sys.exit(constants.EXIT_FAILURE)
1003 f93427cd Iustin Pop
1004 f93427cd Iustin Pop
1005 3ee53f1f Iustin Pop
def PrepNoded(options, _):
1006 3ee53f1f Iustin Pop
  """Preparation node daemon function, executed with the PID file held.
1007 3ecf6786 Iustin Pop

1008 3ecf6786 Iustin Pop
  """
1009 bebf68d3 Guido Trotter
  if options.mlock:
1010 bebf68d3 Guido Trotter
    request_executor_class = MlockallRequestExecutor
1011 4c32a8bd Luca Bigliardi
    try:
1012 4c32a8bd Luca Bigliardi
      utils.Mlockall()
1013 4c32a8bd Luca Bigliardi
    except errors.NoCtypesError:
1014 4c32a8bd Luca Bigliardi
      logging.warning("Cannot set memory lock, ctypes module not found")
1015 4c32a8bd Luca Bigliardi
      request_executor_class = http.server.HttpServerRequestExecutor
1016 bebf68d3 Guido Trotter
  else:
1017 bebf68d3 Guido Trotter
    request_executor_class = http.server.HttpServerRequestExecutor
1018 02bea2fc Luca Bigliardi
1019 04ccf5e9 Guido Trotter
  # Read SSL certificate
1020 3b1b0cb6 Guido Trotter
  if options.ssl:
1021 3b1b0cb6 Guido Trotter
    ssl_params = http.HttpSslParams(ssl_key_path=options.ssl_key,
1022 3b1b0cb6 Guido Trotter
                                    ssl_cert_path=options.ssl_cert)
1023 3b1b0cb6 Guido Trotter
  else:
1024 3b1b0cb6 Guido Trotter
    ssl_params = None
1025 7d88772a Iustin Pop
1026 81198f6e Iustin Pop
  err = _PrepareQueueLock()
1027 81198f6e Iustin Pop
  if err is not None:
1028 81198f6e Iustin Pop
    # this might be some kind of file-system/permission error; while
1029 81198f6e Iustin Pop
    # this breaks the job queue functionality, we shouldn't prevent
1030 81198f6e Iustin Pop
    # startup of the whole node daemon because of this
1031 81198f6e Iustin Pop
    logging.critical("Can't init/verify the queue, proceeding anyway: %s", err)
1032 7d88772a Iustin Pop
1033 04ccf5e9 Guido Trotter
  mainloop = daemon.Mainloop()
1034 04ccf5e9 Guido Trotter
  server = NodeHttpServer(mainloop, options.bind_address, options.port,
1035 38b77287 Luca Bigliardi
                          ssl_params=ssl_params, ssl_verify_peer=True,
1036 bebf68d3 Guido Trotter
                          request_executor_class=request_executor_class)
1037 04ccf5e9 Guido Trotter
  server.Start()
1038 3ee53f1f Iustin Pop
  return (mainloop, server)
1039 3ee53f1f Iustin Pop
1040 5119f2ec Michael Hanselmann
1041 b459a848 Andrea Spadaccini
def ExecNoded(options, args, prep_data): # pylint: disable=W0613
1042 3ee53f1f Iustin Pop
  """Main node daemon function, executed with the PID file held.
1043 3ee53f1f Iustin Pop

1044 3ee53f1f Iustin Pop
  """
1045 3ee53f1f Iustin Pop
  (mainloop, server) = prep_data
1046 04ccf5e9 Guido Trotter
  try:
1047 04ccf5e9 Guido Trotter
    mainloop.Run()
1048 04ccf5e9 Guido Trotter
  finally:
1049 04ccf5e9 Guido Trotter
    server.Stop()
1050 a8083063 Iustin Pop
1051 a8083063 Iustin Pop
1052 5119f2ec Michael Hanselmann
def Main():
1053 04ccf5e9 Guido Trotter
  """Main function for the node daemon.
1054 04ccf5e9 Guido Trotter

1055 04ccf5e9 Guido Trotter
  """
1056 04ccf5e9 Guido Trotter
  parser = OptionParser(description="Ganeti node daemon",
1057 04ccf5e9 Guido Trotter
                        usage="%prog [-f] [-d] [-p port] [-b ADDRESS]",
1058 04ccf5e9 Guido Trotter
                        version="%%prog (ganeti) %s" %
1059 04ccf5e9 Guido Trotter
                        constants.RELEASE_VERSION)
1060 bebf68d3 Guido Trotter
  parser.add_option("--no-mlock", dest="mlock",
1061 bebf68d3 Guido Trotter
                    help="Do not mlock the node memory in ram",
1062 bebf68d3 Guido Trotter
                    default=True, action="store_false")
1063 bebf68d3 Guido Trotter
1064 3ee53f1f Iustin Pop
  daemon.GenericMain(constants.NODED, parser, CheckNoded, PrepNoded, ExecNoded,
1065 084aba47 Michael Hanselmann
                     default_ssl_cert=constants.NODED_CERT_FILE,
1066 1c54156d Luca Bigliardi
                     default_ssl_key=constants.NODED_CERT_FILE,
1067 565083ef Luca Bigliardi
                     console_logging=True)