Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (29.2 kB)

1 69cf3abd Michael Hanselmann
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 cad0723b Iustin Pop
# Copyright (C) 2006, 2007, 2010, 2011, 2012 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 cca5b3fc Michael Hanselmann
  """Subclass ensuring request handlers are 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 e0003509 Michael Hanselmann
class NodeRequestHandler(http.server.HttpServerHandler):
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 b459a848 Andrea Spadaccini
  # pylint: disable=R0904,W0613
132 e0003509 Michael Hanselmann
  def __init__(self):
133 e0003509 Michael Hanselmann
    http.server.HttpServerHandler.__init__(self)
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 7530364d Iustin Pop
    # FIXME: Remove HTTP_PUT in Ganeti 2.7
141 7530364d Iustin Pop
    if req.request_method.upper() not in (http.HTTP_PUT, http.HTTP_POST):
142 7530364d Iustin Pop
      raise http.HttpBadRequest("Only PUT and POST methods are supported")
143 1df6506c Michael Hanselmann
144 cc28af80 Michael Hanselmann
    path = req.request_path
145 81010134 Iustin Pop
    if path.startswith("/"):
146 81010134 Iustin Pop
      path = path[1:]
147 81010134 Iustin Pop
148 1df6506c Michael Hanselmann
    method = getattr(self, "perspective_%s" % path, None)
149 1df6506c Michael Hanselmann
    if method is None:
150 84f2756e Michael Hanselmann
      raise http.HttpNotFound()
151 a8083063 Iustin Pop
152 81010134 Iustin Pop
    try:
153 ab221ddf Michael Hanselmann
      result = (True, method(serializer.LoadJson(req.request_body)))
154 4dd42c9d Iustin Pop
155 0623d351 Iustin Pop
    except backend.RPCFail, err:
156 0623d351 Iustin Pop
      # our custom failure exception; str(err) works fine if the
157 0623d351 Iustin Pop
      # exception was constructed with a single argument, and in
158 0623d351 Iustin Pop
      # this case, err.message == err.args[0] == str(err)
159 ab221ddf Michael Hanselmann
      result = (False, str(err))
160 9ae49f27 Guido Trotter
    except errors.QuitGanetiException, err:
161 84b58db2 Michael Hanselmann
      # Tell parent to quit
162 0623d351 Iustin Pop
      logging.info("Shutting down the node daemon, arguments: %s",
163 0623d351 Iustin Pop
                   str(err.args))
164 cc28af80 Michael Hanselmann
      os.kill(self.noded_pid, signal.SIGTERM)
165 0623d351 Iustin Pop
      # And return the error's arguments, which must be already in
166 0623d351 Iustin Pop
      # correct tuple format
167 ab221ddf Michael Hanselmann
      result = err.args
168 4dd42c9d Iustin Pop
    except Exception, err:
169 0623d351 Iustin Pop
      logging.exception("Error in RPC call")
170 ab221ddf Michael Hanselmann
      result = (False, "Error while executing backend function: %s" % str(err))
171 ab221ddf Michael Hanselmann
172 a182a3ed Michael Hanselmann
    return serializer.DumpJson(result)
173 a8083063 Iustin Pop
174 a8083063 Iustin Pop
  # the new block devices  --------------------------
175 a8083063 Iustin Pop
176 3ecf6786 Iustin Pop
  @staticmethod
177 3ecf6786 Iustin Pop
  def perspective_blockdev_create(params):
178 3ecf6786 Iustin Pop
    """Create a block device.
179 3ecf6786 Iustin Pop

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

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

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

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

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

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

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

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

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

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

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

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

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

307 3ecf6786 Iustin Pop
    This will try to find but not activate a disk.
308 3ecf6786 Iustin Pop

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

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

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

334 4c8ba8b3 Iustin Pop
    """
335 cad0723b Iustin Pop
    if len(params) < 4:
336 cad0723b Iustin Pop
      raise ValueError("Received only 3 parameters in blockdev_grow,"
337 cad0723b Iustin Pop
                       " old master?")
338 4c8ba8b3 Iustin Pop
    cfbd = objects.Disk.FromDict(params[0])
339 4c8ba8b3 Iustin Pop
    amount = params[1]
340 a59faf4b Iustin Pop
    dryrun = params[2]
341 cad0723b Iustin Pop
    backingstore = params[3]
342 cad0723b Iustin Pop
    return backend.BlockdevGrow(cfbd, amount, dryrun, backingstore)
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 6a1434d7 Andrea Spadaccini
  def perspective_instance_finalize_migration_dst(params):
584 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the destination node.
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 6a1434d7 Andrea Spadaccini
    return backend.FinalizeMigrationDst(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 6a1434d7 Andrea Spadaccini
  def perspective_instance_finalize_migration_src(params):
602 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the source node.
603 6a1434d7 Andrea Spadaccini

604 6a1434d7 Andrea Spadaccini
    """
605 6a1434d7 Andrea Spadaccini
    instance, success, live = params
606 6a1434d7 Andrea Spadaccini
    instance = objects.Instance.FromDict(instance)
607 6a1434d7 Andrea Spadaccini
    return backend.FinalizeMigrationSource(instance, success, live)
608 6a1434d7 Andrea Spadaccini
609 6a1434d7 Andrea Spadaccini
  @staticmethod
610 6a1434d7 Andrea Spadaccini
  def perspective_instance_get_migration_status(params):
611 6a1434d7 Andrea Spadaccini
    """Reports migration status.
612 6a1434d7 Andrea Spadaccini

613 6a1434d7 Andrea Spadaccini
    """
614 6a1434d7 Andrea Spadaccini
    instance = objects.Instance.FromDict(params[0])
615 6a1434d7 Andrea Spadaccini
    return backend.GetMigrationStatus(instance).ToDict()
616 6a1434d7 Andrea Spadaccini
617 6a1434d7 Andrea Spadaccini
  @staticmethod
618 007a2f3e Alexander Schreiber
  def perspective_instance_reboot(params):
619 007a2f3e Alexander Schreiber
    """Reboot an instance.
620 007a2f3e Alexander Schreiber

621 007a2f3e Alexander Schreiber
    """
622 007a2f3e Alexander Schreiber
    instance = objects.Instance.FromDict(params[0])
623 007a2f3e Alexander Schreiber
    reboot_type = params[1]
624 17c3f802 Guido Trotter
    shutdown_timeout = params[2]
625 17c3f802 Guido Trotter
    return backend.InstanceReboot(instance, reboot_type, shutdown_timeout)
626 007a2f3e Alexander Schreiber
627 007a2f3e Alexander Schreiber
  @staticmethod
628 ebe466d8 Guido Trotter
  def perspective_instance_balloon_memory(params):
629 ebe466d8 Guido Trotter
    """Modify instance runtime memory.
630 ebe466d8 Guido Trotter

631 ebe466d8 Guido Trotter
    """
632 ebe466d8 Guido Trotter
    instance_dict, memory = params
633 ebe466d8 Guido Trotter
    instance = objects.Instance.FromDict(instance_dict)
634 ebe466d8 Guido Trotter
    return backend.InstanceBalloonMemory(instance, memory)
635 ebe466d8 Guido Trotter
636 ebe466d8 Guido Trotter
  @staticmethod
637 3ecf6786 Iustin Pop
  def perspective_instance_info(params):
638 3ecf6786 Iustin Pop
    """Query instance information.
639 3ecf6786 Iustin Pop

640 3ecf6786 Iustin Pop
    """
641 16ad1a83 Iustin Pop
    return backend.GetInstanceInfo(params[0], params[1])
642 a8083063 Iustin Pop
643 3ecf6786 Iustin Pop
  @staticmethod
644 56e7640c Iustin Pop
  def perspective_instance_migratable(params):
645 56e7640c Iustin Pop
    """Query whether the specified instance can be migrated.
646 56e7640c Iustin Pop

647 56e7640c Iustin Pop
    """
648 56e7640c Iustin Pop
    instance = objects.Instance.FromDict(params[0])
649 56e7640c Iustin Pop
    return backend.GetInstanceMigratable(instance)
650 56e7640c Iustin Pop
651 56e7640c Iustin Pop
  @staticmethod
652 3ecf6786 Iustin Pop
  def perspective_all_instances_info(params):
653 3ecf6786 Iustin Pop
    """Query information about all instances.
654 3ecf6786 Iustin Pop

655 3ecf6786 Iustin Pop
    """
656 e69d05fd Iustin Pop
    return backend.GetAllInstancesInfo(params[0])
657 a8083063 Iustin Pop
658 3ecf6786 Iustin Pop
  @staticmethod
659 3ecf6786 Iustin Pop
  def perspective_instance_list(params):
660 3ecf6786 Iustin Pop
    """Query the list of running instances.
661 3ecf6786 Iustin Pop

662 3ecf6786 Iustin Pop
    """
663 c26a6bd2 Iustin Pop
    return backend.GetInstanceList(params[0])
664 a8083063 Iustin Pop
665 a8083063 Iustin Pop
  # node --------------------------
666 a8083063 Iustin Pop
667 3ecf6786 Iustin Pop
  @staticmethod
668 caad16e2 Iustin Pop
  def perspective_node_has_ip_address(params):
669 caad16e2 Iustin Pop
    """Checks if a node has the given ip address.
670 caad16e2 Iustin Pop

671 caad16e2 Iustin Pop
    """
672 8b312c1d Manuel Franceschini
    return netutils.IPAddress.Own(params[0])
673 caad16e2 Iustin Pop
674 caad16e2 Iustin Pop
  @staticmethod
675 3ecf6786 Iustin Pop
  def perspective_node_info(params):
676 3ecf6786 Iustin Pop
    """Query node information.
677 3ecf6786 Iustin Pop

678 3ecf6786 Iustin Pop
    """
679 78519c10 Michael Hanselmann
    (vg_names, hv_names) = params
680 78519c10 Michael Hanselmann
    return backend.GetNodeInfo(vg_names, hv_names)
681 a8083063 Iustin Pop
682 3ecf6786 Iustin Pop
  @staticmethod
683 19ddc57a René Nussbaumer
  def perspective_etc_hosts_modify(params):
684 19ddc57a René Nussbaumer
    """Modify a node entry in /etc/hosts.
685 19ddc57a René Nussbaumer

686 19ddc57a René Nussbaumer
    """
687 19ddc57a René Nussbaumer
    backend.EtcHostsModify(params[0], params[1], params[2])
688 19ddc57a René Nussbaumer
689 19ddc57a René Nussbaumer
    return True
690 19ddc57a René Nussbaumer
691 19ddc57a René Nussbaumer
  @staticmethod
692 3ecf6786 Iustin Pop
  def perspective_node_verify(params):
693 3ecf6786 Iustin Pop
    """Run a verify sequence on this node.
694 3ecf6786 Iustin Pop

695 3ecf6786 Iustin Pop
    """
696 62c9ec92 Iustin Pop
    return backend.VerifyNode(params[0], params[1])
697 a8083063 Iustin Pop
698 3ecf6786 Iustin Pop
  @staticmethod
699 fb460cf7 Andrea Spadaccini
  def perspective_node_start_master_daemons(params):
700 fb460cf7 Andrea Spadaccini
    """Start the master daemons on this node.
701 3ecf6786 Iustin Pop

702 3ecf6786 Iustin Pop
    """
703 fb460cf7 Andrea Spadaccini
    return backend.StartMasterDaemons(params[0])
704 fb460cf7 Andrea Spadaccini
705 fb460cf7 Andrea Spadaccini
  @staticmethod
706 fb460cf7 Andrea Spadaccini
  def perspective_node_activate_master_ip(params):
707 fb460cf7 Andrea Spadaccini
    """Activate the master IP on this node.
708 fb460cf7 Andrea Spadaccini

709 fb460cf7 Andrea Spadaccini
    """
710 c79198a0 Andrea Spadaccini
    master_params = objects.MasterNetworkParameters.FromDict(params[0])
711 57c7bc57 Andrea Spadaccini
    return backend.ActivateMasterIp(master_params, params[1])
712 fb460cf7 Andrea Spadaccini
713 fb460cf7 Andrea Spadaccini
  @staticmethod
714 fb460cf7 Andrea Spadaccini
  def perspective_node_deactivate_master_ip(params):
715 fb460cf7 Andrea Spadaccini
    """Deactivate the master IP on this node.
716 fb460cf7 Andrea Spadaccini

717 fb460cf7 Andrea Spadaccini
    """
718 c79198a0 Andrea Spadaccini
    master_params = objects.MasterNetworkParameters.FromDict(params[0])
719 57c7bc57 Andrea Spadaccini
    return backend.DeactivateMasterIp(master_params, params[1])
720 a8083063 Iustin Pop
721 3ecf6786 Iustin Pop
  @staticmethod
722 3ecf6786 Iustin Pop
  def perspective_node_stop_master(params):
723 7c74bbe0 Andrea Spadaccini
    """Stops master daemons on this node.
724 3ecf6786 Iustin Pop

725 3ecf6786 Iustin Pop
    """
726 fb460cf7 Andrea Spadaccini
    return backend.StopMasterDaemons()
727 a8083063 Iustin Pop
728 3ecf6786 Iustin Pop
  @staticmethod
729 5a8648eb Andrea Spadaccini
  def perspective_node_change_master_netmask(params):
730 5a8648eb Andrea Spadaccini
    """Change the master IP netmask.
731 5a8648eb Andrea Spadaccini

732 5a8648eb Andrea Spadaccini
    """
733 41e079ce Andrea Spadaccini
    return backend.ChangeMasterNetmask(params[0], params[1], params[2],
734 41e079ce Andrea Spadaccini
                                       params[3])
735 5a8648eb Andrea Spadaccini
736 5a8648eb Andrea Spadaccini
  @staticmethod
737 3ecf6786 Iustin Pop
  def perspective_node_leave_cluster(params):
738 3ecf6786 Iustin Pop
    """Cleanup after leaving a cluster.
739 3ecf6786 Iustin Pop

740 3ecf6786 Iustin Pop
    """
741 b989b9d9 Ken Wehr
    return backend.LeaveCluster(params[0])
742 a8083063 Iustin Pop
743 3ecf6786 Iustin Pop
  @staticmethod
744 3ecf6786 Iustin Pop
  def perspective_node_volumes(params):
745 3ecf6786 Iustin Pop
    """Query the list of all logical volume groups.
746 3ecf6786 Iustin Pop

747 3ecf6786 Iustin Pop
    """
748 dcb93971 Michael Hanselmann
    return backend.NodeVolumes()
749 dcb93971 Michael Hanselmann
750 56aa9fd5 Iustin Pop
  @staticmethod
751 56aa9fd5 Iustin Pop
  def perspective_node_demote_from_mc(params):
752 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
753 56aa9fd5 Iustin Pop

754 56aa9fd5 Iustin Pop
    """
755 56aa9fd5 Iustin Pop
    return backend.DemoteFromMC()
756 56aa9fd5 Iustin Pop
757 f5118ade Iustin Pop
  @staticmethod
758 f5118ade Iustin Pop
  def perspective_node_powercycle(params):
759 f5118ade Iustin Pop
    """Tries to powercycle the nod.
760 f5118ade Iustin Pop

761 f5118ade Iustin Pop
    """
762 f5118ade Iustin Pop
    hypervisor_type = params[0]
763 f5118ade Iustin Pop
    return backend.PowercycleNode(hypervisor_type)
764 f5118ade Iustin Pop
765 a8083063 Iustin Pop
  # cluster --------------------------
766 a8083063 Iustin Pop
767 3ecf6786 Iustin Pop
  @staticmethod
768 3ecf6786 Iustin Pop
  def perspective_version(params):
769 3ecf6786 Iustin Pop
    """Query version information.
770 3ecf6786 Iustin Pop

771 3ecf6786 Iustin Pop
    """
772 c26a6bd2 Iustin Pop
    return constants.PROTOCOL_VERSION
773 a8083063 Iustin Pop
774 3ecf6786 Iustin Pop
  @staticmethod
775 3ecf6786 Iustin Pop
  def perspective_upload_file(params):
776 3ecf6786 Iustin Pop
    """Upload a file.
777 3ecf6786 Iustin Pop

778 3ecf6786 Iustin Pop
    Note that the backend implementation imposes strict rules on which
779 3ecf6786 Iustin Pop
    files are accepted.
780 3ecf6786 Iustin Pop

781 3ecf6786 Iustin Pop
    """
782 415a7304 Michael Hanselmann
    return backend.UploadFile(*(params[0]))
783 a8083063 Iustin Pop
784 4e071d3b Iustin Pop
  @staticmethod
785 4e071d3b Iustin Pop
  def perspective_master_info(params):
786 4e071d3b Iustin Pop
    """Query master information.
787 4e071d3b Iustin Pop

788 4e071d3b Iustin Pop
    """
789 4e071d3b Iustin Pop
    return backend.GetMasterInfo()
790 a8083063 Iustin Pop
791 6ddc95ec Michael Hanselmann
  @staticmethod
792 4f6014d4 René Nussbaumer
  def perspective_run_oob(params):
793 4f6014d4 René Nussbaumer
    """Runs oob on node.
794 4f6014d4 René Nussbaumer

795 4f6014d4 René Nussbaumer
    """
796 1aa88d95 René Nussbaumer
    output = backend.RunOob(params[0], params[1], params[2], params[3])
797 1aa88d95 René Nussbaumer
    if output:
798 1aa88d95 René Nussbaumer
      result = serializer.LoadJson(output)
799 1aa88d95 René Nussbaumer
    else:
800 1aa88d95 René Nussbaumer
      result = None
801 1aa88d95 René Nussbaumer
    return result
802 4f6014d4 René Nussbaumer
803 4f6014d4 René Nussbaumer
  @staticmethod
804 6ddc95ec Michael Hanselmann
  def perspective_write_ssconf_files(params):
805 6ddc95ec Michael Hanselmann
    """Write ssconf files.
806 6ddc95ec Michael Hanselmann

807 6ddc95ec Michael Hanselmann
    """
808 03d1dba2 Michael Hanselmann
    (values,) = params
809 03d1dba2 Michael Hanselmann
    return backend.WriteSsconfFiles(values)
810 6ddc95ec Michael Hanselmann
811 a8083063 Iustin Pop
  # os -----------------------
812 a8083063 Iustin Pop
813 3ecf6786 Iustin Pop
  @staticmethod
814 3ecf6786 Iustin Pop
  def perspective_os_diagnose(params):
815 3ecf6786 Iustin Pop
    """Query detailed information about existing OSes.
816 3ecf6786 Iustin Pop

817 3ecf6786 Iustin Pop
    """
818 255dcebd Iustin Pop
    return backend.DiagnoseOS()
819 a8083063 Iustin Pop
820 3ecf6786 Iustin Pop
  @staticmethod
821 3ecf6786 Iustin Pop
  def perspective_os_get(params):
822 3ecf6786 Iustin Pop
    """Query information about a given OS.
823 3ecf6786 Iustin Pop

824 3ecf6786 Iustin Pop
    """
825 a8083063 Iustin Pop
    name = params[0]
826 255dcebd Iustin Pop
    os_obj = backend.OSFromDisk(name)
827 c26a6bd2 Iustin Pop
    return os_obj.ToDict()
828 a8083063 Iustin Pop
829 acd9ff9e Iustin Pop
  @staticmethod
830 acd9ff9e Iustin Pop
  def perspective_os_validate(params):
831 acd9ff9e Iustin Pop
    """Run a given OS' validation routine.
832 acd9ff9e Iustin Pop

833 acd9ff9e Iustin Pop
    """
834 acd9ff9e Iustin Pop
    required, name, checks, params = params
835 acd9ff9e Iustin Pop
    return backend.ValidateOS(required, name, checks, params)
836 acd9ff9e Iustin Pop
837 a8083063 Iustin Pop
  # hooks -----------------------
838 a8083063 Iustin Pop
839 3ecf6786 Iustin Pop
  @staticmethod
840 3ecf6786 Iustin Pop
  def perspective_hooks_runner(params):
841 3ecf6786 Iustin Pop
    """Run hook scripts.
842 3ecf6786 Iustin Pop

843 3ecf6786 Iustin Pop
    """
844 a8083063 Iustin Pop
    hpath, phase, env = params
845 a8083063 Iustin Pop
    hr = backend.HooksRunner()
846 a8083063 Iustin Pop
    return hr.RunHooks(hpath, phase, env)
847 a8083063 Iustin Pop
848 8d528b7c Iustin Pop
  # iallocator -----------------
849 8d528b7c Iustin Pop
850 8d528b7c Iustin Pop
  @staticmethod
851 8d528b7c Iustin Pop
  def perspective_iallocator_runner(params):
852 8d528b7c Iustin Pop
    """Run an iallocator script.
853 8d528b7c Iustin Pop

854 8d528b7c Iustin Pop
    """
855 8d528b7c Iustin Pop
    name, idata = params
856 8d528b7c Iustin Pop
    iar = backend.IAllocatorRunner()
857 8d528b7c Iustin Pop
    return iar.Run(name, idata)
858 8d528b7c Iustin Pop
859 06009e27 Iustin Pop
  # test -----------------------
860 06009e27 Iustin Pop
861 06009e27 Iustin Pop
  @staticmethod
862 06009e27 Iustin Pop
  def perspective_test_delay(params):
863 06009e27 Iustin Pop
    """Run test delay.
864 06009e27 Iustin Pop

865 06009e27 Iustin Pop
    """
866 06009e27 Iustin Pop
    duration = params[0]
867 c26a6bd2 Iustin Pop
    status, rval = utils.TestDelay(duration)
868 c26a6bd2 Iustin Pop
    if not status:
869 c26a6bd2 Iustin Pop
      raise backend.RPCFail(rval)
870 c26a6bd2 Iustin Pop
    return rval
871 06009e27 Iustin Pop
872 4e071d3b Iustin Pop
  # file storage ---------------
873 4e071d3b Iustin Pop
874 a5d7fb43 Manuel Franceschini
  @staticmethod
875 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_create(params):
876 a5d7fb43 Manuel Franceschini
    """Create the file storage directory.
877 a5d7fb43 Manuel Franceschini

878 a5d7fb43 Manuel Franceschini
    """
879 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
880 a5d7fb43 Manuel Franceschini
    return backend.CreateFileStorageDir(file_storage_dir)
881 a5d7fb43 Manuel Franceschini
882 a5d7fb43 Manuel Franceschini
  @staticmethod
883 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_remove(params):
884 a5d7fb43 Manuel Franceschini
    """Remove the file storage directory.
885 a5d7fb43 Manuel Franceschini

886 a5d7fb43 Manuel Franceschini
    """
887 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
888 a5d7fb43 Manuel Franceschini
    return backend.RemoveFileStorageDir(file_storage_dir)
889 a5d7fb43 Manuel Franceschini
890 a5d7fb43 Manuel Franceschini
  @staticmethod
891 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_rename(params):
892 a5d7fb43 Manuel Franceschini
    """Rename the file storage directory.
893 a5d7fb43 Manuel Franceschini

894 a5d7fb43 Manuel Franceschini
    """
895 a5d7fb43 Manuel Franceschini
    old_file_storage_dir = params[0]
896 a5d7fb43 Manuel Franceschini
    new_file_storage_dir = params[1]
897 a5d7fb43 Manuel Franceschini
    return backend.RenameFileStorageDir(old_file_storage_dir,
898 a5d7fb43 Manuel Franceschini
                                        new_file_storage_dir)
899 a5d7fb43 Manuel Franceschini
900 4e071d3b Iustin Pop
  # jobs ------------------------
901 4e071d3b Iustin Pop
902 ca52cdeb Michael Hanselmann
  @staticmethod
903 7f30777b Michael Hanselmann
  @_RequireJobQueueLock
904 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_update(params):
905 ca52cdeb Michael Hanselmann
    """Update job queue.
906 ca52cdeb Michael Hanselmann

907 ca52cdeb Michael Hanselmann
    """
908 ca52cdeb Michael Hanselmann
    (file_name, content) = params
909 7f30777b Michael Hanselmann
    return backend.JobQueueUpdate(file_name, content)
910 ca52cdeb Michael Hanselmann
911 ca52cdeb Michael Hanselmann
  @staticmethod
912 f1f3f45c Michael Hanselmann
  @_RequireJobQueueLock
913 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_purge(params):
914 ca52cdeb Michael Hanselmann
    """Purge job queue.
915 ca52cdeb Michael Hanselmann

916 ca52cdeb Michael Hanselmann
    """
917 ca52cdeb Michael Hanselmann
    return backend.JobQueuePurge()
918 ca52cdeb Michael Hanselmann
919 af5ebcb1 Michael Hanselmann
  @staticmethod
920 af5ebcb1 Michael Hanselmann
  @_RequireJobQueueLock
921 af5ebcb1 Michael Hanselmann
  def perspective_jobqueue_rename(params):
922 af5ebcb1 Michael Hanselmann
    """Rename a job queue file.
923 af5ebcb1 Michael Hanselmann

924 af5ebcb1 Michael Hanselmann
    """
925 dd875d32 Michael Hanselmann
    # TODO: What if a file fails to rename?
926 fb1ffbca Michael Hanselmann
    return [backend.JobQueueRename(old, new) for old, new in params[0]]
927 af5ebcb1 Michael Hanselmann
928 6217e295 Iustin Pop
  # hypervisor ---------------
929 6217e295 Iustin Pop
930 6217e295 Iustin Pop
  @staticmethod
931 6217e295 Iustin Pop
  def perspective_hypervisor_validate_params(params):
932 6217e295 Iustin Pop
    """Validate the hypervisor parameters.
933 6217e295 Iustin Pop

934 6217e295 Iustin Pop
    """
935 6217e295 Iustin Pop
    (hvname, hvparams) = params
936 6217e295 Iustin Pop
    return backend.ValidateHVParams(hvname, hvparams)
937 6217e295 Iustin Pop
938 f942a838 Michael Hanselmann
  # Crypto
939 f942a838 Michael Hanselmann
940 f942a838 Michael Hanselmann
  @staticmethod
941 ef40fbfb Michael Hanselmann
  def perspective_x509_cert_create(params):
942 f942a838 Michael Hanselmann
    """Creates a new X509 certificate for SSL/TLS.
943 f942a838 Michael Hanselmann

944 f942a838 Michael Hanselmann
    """
945 f942a838 Michael Hanselmann
    (validity, ) = params
946 f942a838 Michael Hanselmann
    return backend.CreateX509Certificate(validity)
947 f942a838 Michael Hanselmann
948 f942a838 Michael Hanselmann
  @staticmethod
949 ef40fbfb Michael Hanselmann
  def perspective_x509_cert_remove(params):
950 f942a838 Michael Hanselmann
    """Removes a X509 certificate.
951 f942a838 Michael Hanselmann

952 f942a838 Michael Hanselmann
    """
953 f942a838 Michael Hanselmann
    (name, ) = params
954 f942a838 Michael Hanselmann
    return backend.RemoveX509Certificate(name)
955 f942a838 Michael Hanselmann
956 1651d116 Michael Hanselmann
  # Import and export
957 1651d116 Michael Hanselmann
958 1651d116 Michael Hanselmann
  @staticmethod
959 ef40fbfb Michael Hanselmann
  def perspective_import_start(params):
960 1651d116 Michael Hanselmann
    """Starts an import daemon.
961 1651d116 Michael Hanselmann

962 1651d116 Michael Hanselmann
    """
963 b8c160c1 Michael Hanselmann
    (opts_s, instance, component, (dest, dest_args)) = params
964 eb630f50 Michael Hanselmann
965 eb630f50 Michael Hanselmann
    opts = objects.ImportExportOptions.FromDict(opts_s)
966 eb630f50 Michael Hanselmann
967 eb630f50 Michael Hanselmann
    return backend.StartImportExportDaemon(constants.IEM_IMPORT, opts,
968 1651d116 Michael Hanselmann
                                           None, None,
969 1651d116 Michael Hanselmann
                                           objects.Instance.FromDict(instance),
970 6613661a Iustin Pop
                                           component, dest,
971 1651d116 Michael Hanselmann
                                           _DecodeImportExportIO(dest,
972 1651d116 Michael Hanselmann
                                                                 dest_args))
973 eb630f50 Michael Hanselmann
974 1651d116 Michael Hanselmann
  @staticmethod
975 ef40fbfb Michael Hanselmann
  def perspective_export_start(params):
976 1651d116 Michael Hanselmann
    """Starts an export daemon.
977 1651d116 Michael Hanselmann

978 1651d116 Michael Hanselmann
    """
979 b8c160c1 Michael Hanselmann
    (opts_s, host, port, instance, component, (source, source_args)) = params
980 eb630f50 Michael Hanselmann
981 eb630f50 Michael Hanselmann
    opts = objects.ImportExportOptions.FromDict(opts_s)
982 eb630f50 Michael Hanselmann
983 eb630f50 Michael Hanselmann
    return backend.StartImportExportDaemon(constants.IEM_EXPORT, opts,
984 1651d116 Michael Hanselmann
                                           host, port,
985 1651d116 Michael Hanselmann
                                           objects.Instance.FromDict(instance),
986 6613661a Iustin Pop
                                           component, source,
987 1651d116 Michael Hanselmann
                                           _DecodeImportExportIO(source,
988 1651d116 Michael Hanselmann
                                                                 source_args))
989 1651d116 Michael Hanselmann
990 1651d116 Michael Hanselmann
  @staticmethod
991 ef40fbfb Michael Hanselmann
  def perspective_impexp_status(params):
992 1651d116 Michael Hanselmann
    """Retrieves the status of an import or export daemon.
993 1651d116 Michael Hanselmann

994 1651d116 Michael Hanselmann
    """
995 1651d116 Michael Hanselmann
    return backend.GetImportExportStatus(params[0])
996 1651d116 Michael Hanselmann
997 1651d116 Michael Hanselmann
  @staticmethod
998 f81c4737 Michael Hanselmann
  def perspective_impexp_abort(params):
999 f81c4737 Michael Hanselmann
    """Aborts an import or export.
1000 f81c4737 Michael Hanselmann

1001 f81c4737 Michael Hanselmann
    """
1002 f81c4737 Michael Hanselmann
    return backend.AbortImportExport(params[0])
1003 f81c4737 Michael Hanselmann
1004 f81c4737 Michael Hanselmann
  @staticmethod
1005 ef40fbfb Michael Hanselmann
  def perspective_impexp_cleanup(params):
1006 1651d116 Michael Hanselmann
    """Cleans up after an import or export.
1007 1651d116 Michael Hanselmann

1008 1651d116 Michael Hanselmann
    """
1009 1651d116 Michael Hanselmann
    return backend.CleanupImportExport(params[0])
1010 1651d116 Michael Hanselmann
1011 a8083063 Iustin Pop
1012 f93427cd Iustin Pop
def CheckNoded(_, args):
1013 f93427cd Iustin Pop
  """Initial checks whether to run or exit with a failure.
1014 f93427cd Iustin Pop

1015 f93427cd Iustin Pop
  """
1016 f93427cd Iustin Pop
  if args: # noded doesn't take any arguments
1017 f93427cd Iustin Pop
    print >> sys.stderr, ("Usage: %s [-f] [-d] [-p port] [-b ADDRESS]" %
1018 f93427cd Iustin Pop
                          sys.argv[0])
1019 f93427cd Iustin Pop
    sys.exit(constants.EXIT_FAILURE)
1020 f01738fc Iustin Pop
  try:
1021 f01738fc Iustin Pop
    codecs.lookup("string-escape")
1022 f01738fc Iustin Pop
  except LookupError:
1023 f01738fc Iustin Pop
    print >> sys.stderr, ("Can't load the string-escape code which is part"
1024 f01738fc Iustin Pop
                          " of the Python installation. Is your installation"
1025 f01738fc Iustin Pop
                          " complete/correct? Aborting.")
1026 f01738fc Iustin Pop
    sys.exit(constants.EXIT_FAILURE)
1027 f93427cd Iustin Pop
1028 f93427cd Iustin Pop
1029 3ee53f1f Iustin Pop
def PrepNoded(options, _):
1030 3ee53f1f Iustin Pop
  """Preparation node daemon function, executed with the PID file held.
1031 3ecf6786 Iustin Pop

1032 3ecf6786 Iustin Pop
  """
1033 bebf68d3 Guido Trotter
  if options.mlock:
1034 bebf68d3 Guido Trotter
    request_executor_class = MlockallRequestExecutor
1035 4c32a8bd Luca Bigliardi
    try:
1036 4c32a8bd Luca Bigliardi
      utils.Mlockall()
1037 4c32a8bd Luca Bigliardi
    except errors.NoCtypesError:
1038 4c32a8bd Luca Bigliardi
      logging.warning("Cannot set memory lock, ctypes module not found")
1039 4c32a8bd Luca Bigliardi
      request_executor_class = http.server.HttpServerRequestExecutor
1040 bebf68d3 Guido Trotter
  else:
1041 bebf68d3 Guido Trotter
    request_executor_class = http.server.HttpServerRequestExecutor
1042 02bea2fc Luca Bigliardi
1043 04ccf5e9 Guido Trotter
  # Read SSL certificate
1044 3b1b0cb6 Guido Trotter
  if options.ssl:
1045 3b1b0cb6 Guido Trotter
    ssl_params = http.HttpSslParams(ssl_key_path=options.ssl_key,
1046 3b1b0cb6 Guido Trotter
                                    ssl_cert_path=options.ssl_cert)
1047 3b1b0cb6 Guido Trotter
  else:
1048 3b1b0cb6 Guido Trotter
    ssl_params = None
1049 7d88772a Iustin Pop
1050 81198f6e Iustin Pop
  err = _PrepareQueueLock()
1051 81198f6e Iustin Pop
  if err is not None:
1052 81198f6e Iustin Pop
    # this might be some kind of file-system/permission error; while
1053 81198f6e Iustin Pop
    # this breaks the job queue functionality, we shouldn't prevent
1054 81198f6e Iustin Pop
    # startup of the whole node daemon because of this
1055 81198f6e Iustin Pop
    logging.critical("Can't init/verify the queue, proceeding anyway: %s", err)
1056 7d88772a Iustin Pop
1057 e0003509 Michael Hanselmann
  handler = NodeRequestHandler()
1058 e0003509 Michael Hanselmann
1059 04ccf5e9 Guido Trotter
  mainloop = daemon.Mainloop()
1060 e0003509 Michael Hanselmann
  server = \
1061 e0003509 Michael Hanselmann
    http.server.HttpServer(mainloop, options.bind_address, options.port,
1062 5ae4945a Iustin Pop
                           handler, ssl_params=ssl_params, ssl_verify_peer=True,
1063 5ae4945a Iustin Pop
                           request_executor_class=request_executor_class)
1064 04ccf5e9 Guido Trotter
  server.Start()
1065 e0003509 Michael Hanselmann
1066 3ee53f1f Iustin Pop
  return (mainloop, server)
1067 3ee53f1f Iustin Pop
1068 5119f2ec Michael Hanselmann
1069 b459a848 Andrea Spadaccini
def ExecNoded(options, args, prep_data): # pylint: disable=W0613
1070 3ee53f1f Iustin Pop
  """Main node daemon function, executed with the PID file held.
1071 3ee53f1f Iustin Pop

1072 3ee53f1f Iustin Pop
  """
1073 3ee53f1f Iustin Pop
  (mainloop, server) = prep_data
1074 04ccf5e9 Guido Trotter
  try:
1075 04ccf5e9 Guido Trotter
    mainloop.Run()
1076 04ccf5e9 Guido Trotter
  finally:
1077 04ccf5e9 Guido Trotter
    server.Stop()
1078 a8083063 Iustin Pop
1079 a8083063 Iustin Pop
1080 5119f2ec Michael Hanselmann
def Main():
1081 04ccf5e9 Guido Trotter
  """Main function for the node daemon.
1082 04ccf5e9 Guido Trotter

1083 04ccf5e9 Guido Trotter
  """
1084 04ccf5e9 Guido Trotter
  parser = OptionParser(description="Ganeti node daemon",
1085 04ccf5e9 Guido Trotter
                        usage="%prog [-f] [-d] [-p port] [-b ADDRESS]",
1086 04ccf5e9 Guido Trotter
                        version="%%prog (ganeti) %s" %
1087 04ccf5e9 Guido Trotter
                        constants.RELEASE_VERSION)
1088 bebf68d3 Guido Trotter
  parser.add_option("--no-mlock", dest="mlock",
1089 bebf68d3 Guido Trotter
                    help="Do not mlock the node memory in ram",
1090 bebf68d3 Guido Trotter
                    default=True, action="store_false")
1091 bebf68d3 Guido Trotter
1092 3ee53f1f Iustin Pop
  daemon.GenericMain(constants.NODED, parser, CheckNoded, PrepNoded, ExecNoded,
1093 084aba47 Michael Hanselmann
                     default_ssl_cert=constants.NODED_CERT_FILE,
1094 1c54156d Luca Bigliardi
                     default_ssl_key=constants.NODED_CERT_FILE,
1095 565083ef Luca Bigliardi
                     console_logging=True)