Statistics
| Branch: | Tag: | Revision:

root / daemons / ganeti-noded @ e18def2a

History | View | Annotate | Download (20.6 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 a8083063 Iustin Pop
"""Ganeti node daemon"""
23 a8083063 Iustin Pop
24 3ecf6786 Iustin Pop
# functions in this module need to have a given name structure, so:
25 3ecf6786 Iustin Pop
# pylint: disable-msg=C0103
26 3ecf6786 Iustin Pop
27 a8083063 Iustin Pop
import os
28 a8083063 Iustin Pop
import sys
29 761ce945 Guido Trotter
import SocketServer
30 c89189b1 Iustin Pop
import logging
31 84b58db2 Michael Hanselmann
import signal
32 a8083063 Iustin Pop
33 a8083063 Iustin Pop
from optparse import OptionParser
34 a8083063 Iustin Pop
35 a8083063 Iustin Pop
from ganeti import backend
36 a8083063 Iustin Pop
from ganeti import constants
37 a8083063 Iustin Pop
from ganeti import objects
38 a8083063 Iustin Pop
from ganeti import errors
39 25d6d12a Michael Hanselmann
from ganeti import jstore
40 cc28af80 Michael Hanselmann
from ganeti import daemon
41 1df6506c Michael Hanselmann
from ganeti import http
42 16abfbc2 Alexander Schreiber
from ganeti import utils
43 a8083063 Iustin Pop
44 19205c39 Michael Hanselmann
import ganeti.http.server
45 19205c39 Michael Hanselmann
46 a8083063 Iustin Pop
47 25d6d12a Michael Hanselmann
queue_lock = None
48 25d6d12a Michael Hanselmann
49 25d6d12a Michael Hanselmann
50 7f30777b Michael Hanselmann
def _RequireJobQueueLock(fn):
51 7f30777b Michael Hanselmann
  """Decorator for job queue manipulating functions.
52 7f30777b Michael Hanselmann
53 7f30777b Michael Hanselmann
  """
54 8785cb30 Michael Hanselmann
  QUEUE_LOCK_TIMEOUT = 10
55 8785cb30 Michael Hanselmann
56 7f30777b Michael Hanselmann
  def wrapper(*args, **kwargs):
57 7f30777b Michael Hanselmann
    # Locking in exclusive, blocking mode because there could be several
58 506cff12 Michael Hanselmann
    # children running at the same time. Waiting up to 10 seconds.
59 8785cb30 Michael Hanselmann
    queue_lock.Exclusive(blocking=True, timeout=QUEUE_LOCK_TIMEOUT)
60 7f30777b Michael Hanselmann
    try:
61 7f30777b Michael Hanselmann
      return fn(*args, **kwargs)
62 7f30777b Michael Hanselmann
    finally:
63 7f30777b Michael Hanselmann
      queue_lock.Unlock()
64 8785cb30 Michael Hanselmann
65 7f30777b Michael Hanselmann
  return wrapper
66 7f30777b Michael Hanselmann
67 7f30777b Michael Hanselmann
68 19205c39 Michael Hanselmann
class NodeHttpServer(http.server.HttpServer):
69 3ecf6786 Iustin Pop
  """The server implementation.
70 3ecf6786 Iustin Pop
71 3ecf6786 Iustin Pop
  This class holds all methods exposed over the RPC interface.
72 3ecf6786 Iustin Pop
73 3ecf6786 Iustin Pop
  """
74 cc28af80 Michael Hanselmann
  def __init__(self, *args, **kwargs):
75 19205c39 Michael Hanselmann
    http.server.HttpServer.__init__(self, *args, **kwargs)
76 cc28af80 Michael Hanselmann
    self.noded_pid = os.getpid()
77 cc28af80 Michael Hanselmann
78 cc28af80 Michael Hanselmann
  def HandleRequest(self, req):
79 1df6506c Michael Hanselmann
    """Handle a request.
80 a8083063 Iustin Pop
81 098c0958 Michael Hanselmann
    """
82 19205c39 Michael Hanselmann
    if req.request_method.upper() != http.HTTP_PUT:
83 84f2756e Michael Hanselmann
      raise http.HttpBadRequest()
84 1df6506c Michael Hanselmann
85 cc28af80 Michael Hanselmann
    path = req.request_path
86 81010134 Iustin Pop
    if path.startswith("/"):
87 81010134 Iustin Pop
      path = path[1:]
88 81010134 Iustin Pop
89 1df6506c Michael Hanselmann
    method = getattr(self, "perspective_%s" % path, None)
90 1df6506c Michael Hanselmann
    if method is None:
91 84f2756e Michael Hanselmann
      raise http.HttpNotFound()
92 a8083063 Iustin Pop
93 81010134 Iustin Pop
    try:
94 aa9075c5 Michael Hanselmann
      try:
95 19205c39 Michael Hanselmann
        return method(req.request_body)
96 aa9075c5 Michael Hanselmann
      except:
97 aa9075c5 Michael Hanselmann
        logging.exception("Error in RPC call")
98 aa9075c5 Michael Hanselmann
        raise
99 9ae49f27 Guido Trotter
    except errors.QuitGanetiException, err:
100 84b58db2 Michael Hanselmann
      # Tell parent to quit
101 cc28af80 Michael Hanselmann
      os.kill(self.noded_pid, signal.SIGTERM)
102 a8083063 Iustin Pop
103 a8083063 Iustin Pop
  # the new block devices  --------------------------
104 a8083063 Iustin Pop
105 3ecf6786 Iustin Pop
  @staticmethod
106 3ecf6786 Iustin Pop
  def perspective_blockdev_create(params):
107 3ecf6786 Iustin Pop
    """Create a block device.
108 3ecf6786 Iustin Pop
109 3ecf6786 Iustin Pop
    """
110 3f78eef2 Iustin Pop
    bdev_s, size, owner, on_primary, info = params
111 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
112 a8083063 Iustin Pop
    if bdev is None:
113 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
114 821d1bd1 Iustin Pop
    return backend.BlockdevCreate(bdev, size, owner, on_primary, info)
115 a8083063 Iustin Pop
116 3ecf6786 Iustin Pop
  @staticmethod
117 3ecf6786 Iustin Pop
  def perspective_blockdev_remove(params):
118 3ecf6786 Iustin Pop
    """Remove a block device.
119 3ecf6786 Iustin Pop
120 3ecf6786 Iustin Pop
    """
121 a8083063 Iustin Pop
    bdev_s = params[0]
122 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
123 821d1bd1 Iustin Pop
    return backend.BlockdevRemove(bdev)
124 a8083063 Iustin Pop
125 3ecf6786 Iustin Pop
  @staticmethod
126 f3e513ad Iustin Pop
  def perspective_blockdev_rename(params):
127 f3e513ad Iustin Pop
    """Remove a block device.
128 f3e513ad Iustin Pop
129 f3e513ad Iustin Pop
    """
130 f3e513ad Iustin Pop
    devlist = [(objects.Disk.FromDict(ds), uid) for ds, uid in params]
131 821d1bd1 Iustin Pop
    return backend.BlockdevRename(devlist)
132 f3e513ad Iustin Pop
133 f3e513ad Iustin Pop
  @staticmethod
134 3ecf6786 Iustin Pop
  def perspective_blockdev_assemble(params):
135 3ecf6786 Iustin Pop
    """Assemble a block device.
136 3ecf6786 Iustin Pop
137 3ecf6786 Iustin Pop
    """
138 3f78eef2 Iustin Pop
    bdev_s, owner, on_primary = params
139 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
140 a8083063 Iustin Pop
    if bdev is None:
141 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
142 821d1bd1 Iustin Pop
    return backend.BlockdevAssemble(bdev, owner, on_primary)
143 a8083063 Iustin Pop
144 3ecf6786 Iustin Pop
  @staticmethod
145 3ecf6786 Iustin Pop
  def perspective_blockdev_shutdown(params):
146 3ecf6786 Iustin Pop
    """Shutdown a block device.
147 3ecf6786 Iustin Pop
148 3ecf6786 Iustin Pop
    """
149 a8083063 Iustin Pop
    bdev_s = params[0]
150 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
151 a8083063 Iustin Pop
    if bdev is None:
152 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
153 821d1bd1 Iustin Pop
    return backend.BlockdevShutdown(bdev)
154 a8083063 Iustin Pop
155 3ecf6786 Iustin Pop
  @staticmethod
156 153d9724 Iustin Pop
  def perspective_blockdev_addchildren(params):
157 3ecf6786 Iustin Pop
    """Add a child to a mirror device.
158 3ecf6786 Iustin Pop
159 3ecf6786 Iustin Pop
    Note: this is only valid for mirror devices. It's the caller's duty
160 3ecf6786 Iustin Pop
    to send a correct disk, otherwise we raise an error.
161 3ecf6786 Iustin Pop
162 3ecf6786 Iustin Pop
    """
163 a8083063 Iustin Pop
    bdev_s, ndev_s = params
164 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
165 153d9724 Iustin Pop
    ndevs = [objects.Disk.FromDict(disk_s) for disk_s in ndev_s]
166 153d9724 Iustin Pop
    if bdev is None or ndevs.count(None) > 0:
167 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
168 821d1bd1 Iustin Pop
    return backend.BlockdevAddchildren(bdev, ndevs)
169 a8083063 Iustin Pop
170 3ecf6786 Iustin Pop
  @staticmethod
171 153d9724 Iustin Pop
  def perspective_blockdev_removechildren(params):
172 3ecf6786 Iustin Pop
    """Remove a child from a mirror device.
173 3ecf6786 Iustin Pop
174 3ecf6786 Iustin Pop
    This is only valid for mirror devices, of course. It's the callers
175 3ecf6786 Iustin Pop
    duty to send a correct disk, otherwise we raise an error.
176 3ecf6786 Iustin Pop
177 3ecf6786 Iustin Pop
    """
178 a8083063 Iustin Pop
    bdev_s, ndev_s = params
179 319856a9 Michael Hanselmann
    bdev = objects.Disk.FromDict(bdev_s)
180 153d9724 Iustin Pop
    ndevs = [objects.Disk.FromDict(disk_s) for disk_s in ndev_s]
181 153d9724 Iustin Pop
    if bdev is None or ndevs.count(None) > 0:
182 a8083063 Iustin Pop
      raise ValueError("can't unserialize data!")
183 821d1bd1 Iustin Pop
    return backend.BlockdevRemovechildren(bdev, ndevs)
184 a8083063 Iustin Pop
185 3ecf6786 Iustin Pop
  @staticmethod
186 3ecf6786 Iustin Pop
  def perspective_blockdev_getmirrorstatus(params):
187 3ecf6786 Iustin Pop
    """Return the mirror status for a list of disks.
188 3ecf6786 Iustin Pop
189 3ecf6786 Iustin Pop
    """
190 319856a9 Michael Hanselmann
    disks = [objects.Disk.FromDict(dsk_s)
191 a8083063 Iustin Pop
            for dsk_s in params]
192 821d1bd1 Iustin Pop
    return backend.BlockdevGetmirrorstatus(disks)
193 a8083063 Iustin Pop
194 3ecf6786 Iustin Pop
  @staticmethod
195 3ecf6786 Iustin Pop
  def perspective_blockdev_find(params):
196 3ecf6786 Iustin Pop
    """Expose the FindBlockDevice functionality for a disk.
197 3ecf6786 Iustin Pop
198 3ecf6786 Iustin Pop
    This will try to find but not activate a disk.
199 3ecf6786 Iustin Pop
200 3ecf6786 Iustin Pop
    """
201 319856a9 Michael Hanselmann
    disk = objects.Disk.FromDict(params[0])
202 821d1bd1 Iustin Pop
    return backend.BlockdevFind(disk)
203 a8083063 Iustin Pop
204 3ecf6786 Iustin Pop
  @staticmethod
205 3ecf6786 Iustin Pop
  def perspective_blockdev_snapshot(params):
206 3ecf6786 Iustin Pop
    """Create a snapshot device.
207 3ecf6786 Iustin Pop
208 3ecf6786 Iustin Pop
    Note that this is only valid for LVM disks, if we get passed
209 3ecf6786 Iustin Pop
    something else we raise an exception. The snapshot device can be
210 3ecf6786 Iustin Pop
    remove by calling the generic block device remove call.
211 3ecf6786 Iustin Pop
212 3ecf6786 Iustin Pop
    """
213 319856a9 Michael Hanselmann
    cfbd = objects.Disk.FromDict(params[0])
214 821d1bd1 Iustin Pop
    return backend.BlockdevSnapshot(cfbd)
215 a8083063 Iustin Pop
216 4c8ba8b3 Iustin Pop
  @staticmethod
217 4c8ba8b3 Iustin Pop
  def perspective_blockdev_grow(params):
218 4c8ba8b3 Iustin Pop
    """Grow a stack of devices.
219 4c8ba8b3 Iustin Pop
220 4c8ba8b3 Iustin Pop
    """
221 4c8ba8b3 Iustin Pop
    cfbd = objects.Disk.FromDict(params[0])
222 4c8ba8b3 Iustin Pop
    amount = params[1]
223 821d1bd1 Iustin Pop
    return backend.BlockdevGrow(cfbd, amount)
224 4c8ba8b3 Iustin Pop
225 d61cbe76 Iustin Pop
  @staticmethod
226 d61cbe76 Iustin Pop
  def perspective_blockdev_close(params):
227 d61cbe76 Iustin Pop
    """Closes the given block devices.
228 d61cbe76 Iustin Pop
229 d61cbe76 Iustin Pop
    """
230 b2e7666a Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in params[1]]
231 821d1bd1 Iustin Pop
    return backend.BlockdevClose(params[0], disks)
232 d61cbe76 Iustin Pop
233 968a7623 Iustin Pop
  @staticmethod
234 968a7623 Iustin Pop
  def perspective_blockdev_getsize(params):
235 968a7623 Iustin Pop
    """Compute the sizes of the given block devices.
236 968a7623 Iustin Pop
237 968a7623 Iustin Pop
    """
238 968a7623 Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in params[0]]
239 968a7623 Iustin Pop
    return backend.BlockdevGetsize(disks)
240 968a7623 Iustin Pop
241 6b93ec9d Iustin Pop
  # blockdev/drbd specific methods ----------
242 6b93ec9d Iustin Pop
243 6b93ec9d Iustin Pop
  @staticmethod
244 6b93ec9d Iustin Pop
  def perspective_drbd_disconnect_net(params):
245 6b93ec9d Iustin Pop
    """Disconnects the network connection of drbd disks.
246 6b93ec9d Iustin Pop
247 6b93ec9d Iustin Pop
    Note that this is only valid for drbd disks, so the members of the
248 6b93ec9d Iustin Pop
    disk list must all be drbd devices.
249 6b93ec9d Iustin Pop
250 6b93ec9d Iustin Pop
    """
251 6b93ec9d Iustin Pop
    nodes_ip, disks = params
252 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
253 6b93ec9d Iustin Pop
    return backend.DrbdDisconnectNet(nodes_ip, disks)
254 6b93ec9d Iustin Pop
255 6b93ec9d Iustin Pop
  @staticmethod
256 6b93ec9d Iustin Pop
  def perspective_drbd_attach_net(params):
257 6b93ec9d Iustin Pop
    """Attaches the network connection of drbd disks.
258 6b93ec9d Iustin Pop
259 6b93ec9d Iustin Pop
    Note that this is only valid for drbd disks, so the members of the
260 6b93ec9d Iustin Pop
    disk list must all be drbd devices.
261 6b93ec9d Iustin Pop
262 6b93ec9d Iustin Pop
    """
263 6b93ec9d Iustin Pop
    nodes_ip, disks, instance_name, multimaster = params
264 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
265 821d1bd1 Iustin Pop
    return backend.DrbdAttachNet(nodes_ip, disks,
266 821d1bd1 Iustin Pop
                                     instance_name, multimaster)
267 6b93ec9d Iustin Pop
268 6b93ec9d Iustin Pop
  @staticmethod
269 6b93ec9d Iustin Pop
  def perspective_drbd_wait_sync(params):
270 6b93ec9d Iustin Pop
    """Wait until DRBD disks are synched.
271 6b93ec9d Iustin Pop
272 6b93ec9d Iustin Pop
    Note that this is only valid for drbd disks, so the members of the
273 6b93ec9d Iustin Pop
    disk list must all be drbd devices.
274 6b93ec9d Iustin Pop
275 6b93ec9d Iustin Pop
    """
276 6b93ec9d Iustin Pop
    nodes_ip, disks = params
277 6b93ec9d Iustin Pop
    disks = [objects.Disk.FromDict(cf) for cf in disks]
278 6b93ec9d Iustin Pop
    return backend.DrbdWaitSync(nodes_ip, disks)
279 6b93ec9d Iustin Pop
280 a8083063 Iustin Pop
  # export/import  --------------------------
281 a8083063 Iustin Pop
282 3ecf6786 Iustin Pop
  @staticmethod
283 3ecf6786 Iustin Pop
  def perspective_snapshot_export(params):
284 3ecf6786 Iustin Pop
    """Export a given snapshot.
285 3ecf6786 Iustin Pop
286 3ecf6786 Iustin Pop
    """
287 319856a9 Michael Hanselmann
    disk = objects.Disk.FromDict(params[0])
288 a8083063 Iustin Pop
    dest_node = params[1]
289 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[2])
290 62c9ec92 Iustin Pop
    cluster_name = params[3]
291 74c47259 Iustin Pop
    dev_idx = params[4]
292 74c47259 Iustin Pop
    return backend.ExportSnapshot(disk, dest_node, instance,
293 74c47259 Iustin Pop
                                  cluster_name, dev_idx)
294 3ecf6786 Iustin Pop
295 3ecf6786 Iustin Pop
  @staticmethod
296 3ecf6786 Iustin Pop
  def perspective_finalize_export(params):
297 3ecf6786 Iustin Pop
    """Expose the finalize export functionality.
298 a8083063 Iustin Pop
299 3ecf6786 Iustin Pop
    """
300 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
301 319856a9 Michael Hanselmann
    snap_disks = [objects.Disk.FromDict(str_data)
302 a8083063 Iustin Pop
                  for str_data in params[1]]
303 a8083063 Iustin Pop
    return backend.FinalizeExport(instance, snap_disks)
304 a8083063 Iustin Pop
305 3ecf6786 Iustin Pop
  @staticmethod
306 3ecf6786 Iustin Pop
  def perspective_export_info(params):
307 3ecf6786 Iustin Pop
    """Query information about an existing export on this node.
308 3ecf6786 Iustin Pop
309 3ecf6786 Iustin Pop
    The given path may not contain an export, in which case we return
310 3ecf6786 Iustin Pop
    None.
311 3ecf6786 Iustin Pop
312 3ecf6786 Iustin Pop
    """
313 3ecf6786 Iustin Pop
    path = params[0]
314 3ecf6786 Iustin Pop
    einfo = backend.ExportInfo(path)
315 a8083063 Iustin Pop
    if einfo is None:
316 a8083063 Iustin Pop
      return einfo
317 a8083063 Iustin Pop
    return einfo.Dumps()
318 a8083063 Iustin Pop
319 3ecf6786 Iustin Pop
  @staticmethod
320 3ecf6786 Iustin Pop
  def perspective_export_list(params):
321 3ecf6786 Iustin Pop
    """List the available exports on this node.
322 3ecf6786 Iustin Pop
323 3ecf6786 Iustin Pop
    Note that as opposed to export_info, which may query data about an
324 3ecf6786 Iustin Pop
    export in any path, this only queries the standard Ganeti path
325 3ecf6786 Iustin Pop
    (constants.EXPORT_DIR).
326 3ecf6786 Iustin Pop
327 3ecf6786 Iustin Pop
    """
328 a8083063 Iustin Pop
    return backend.ListExports()
329 a8083063 Iustin Pop
330 3ecf6786 Iustin Pop
  @staticmethod
331 3ecf6786 Iustin Pop
  def perspective_export_remove(params):
332 3ecf6786 Iustin Pop
    """Remove an export.
333 3ecf6786 Iustin Pop
334 3ecf6786 Iustin Pop
    """
335 a8083063 Iustin Pop
    export = params[0]
336 a8083063 Iustin Pop
    return backend.RemoveExport(export)
337 a8083063 Iustin Pop
338 a8083063 Iustin Pop
  # volume  --------------------------
339 a8083063 Iustin Pop
340 3ecf6786 Iustin Pop
  @staticmethod
341 3ecf6786 Iustin Pop
  def perspective_volume_list(params):
342 3ecf6786 Iustin Pop
    """Query the list of logical volumes in a given volume group.
343 3ecf6786 Iustin Pop
344 3ecf6786 Iustin Pop
    """
345 a8083063 Iustin Pop
    vgname = params[0]
346 a8083063 Iustin Pop
    return backend.GetVolumeList(vgname)
347 a8083063 Iustin Pop
348 3ecf6786 Iustin Pop
  @staticmethod
349 3ecf6786 Iustin Pop
  def perspective_vg_list(params):
350 3ecf6786 Iustin Pop
    """Query the list of volume groups.
351 3ecf6786 Iustin Pop
352 3ecf6786 Iustin Pop
    """
353 a8083063 Iustin Pop
    return backend.ListVolumeGroups()
354 a8083063 Iustin Pop
355 a8083063 Iustin Pop
  # bridge  --------------------------
356 a8083063 Iustin Pop
357 3ecf6786 Iustin Pop
  @staticmethod
358 3ecf6786 Iustin Pop
  def perspective_bridges_exist(params):
359 3ecf6786 Iustin Pop
    """Check if all bridges given exist on this node.
360 3ecf6786 Iustin Pop
361 3ecf6786 Iustin Pop
    """
362 a8083063 Iustin Pop
    bridges_list = params[0]
363 a8083063 Iustin Pop
    return backend.BridgesExist(bridges_list)
364 a8083063 Iustin Pop
365 a8083063 Iustin Pop
  # instance  --------------------------
366 a8083063 Iustin Pop
367 3ecf6786 Iustin Pop
  @staticmethod
368 3ecf6786 Iustin Pop
  def perspective_instance_os_add(params):
369 3ecf6786 Iustin Pop
    """Install an OS on a given instance.
370 3ecf6786 Iustin Pop
371 3ecf6786 Iustin Pop
    """
372 d15a9ad3 Guido Trotter
    inst_s = params[0]
373 319856a9 Michael Hanselmann
    inst = objects.Instance.FromDict(inst_s)
374 1268d6fd Iustin Pop
    return backend.InstanceOsAdd(inst)
375 a8083063 Iustin Pop
376 3ecf6786 Iustin Pop
  @staticmethod
377 decd5f45 Iustin Pop
  def perspective_instance_run_rename(params):
378 decd5f45 Iustin Pop
    """Runs the OS rename script for an instance.
379 decd5f45 Iustin Pop
380 decd5f45 Iustin Pop
    """
381 d15a9ad3 Guido Trotter
    inst_s, old_name = params
382 319856a9 Michael Hanselmann
    inst = objects.Instance.FromDict(inst_s)
383 d15a9ad3 Guido Trotter
    return backend.RunRenameInstance(inst, old_name)
384 decd5f45 Iustin Pop
385 decd5f45 Iustin Pop
  @staticmethod
386 3ecf6786 Iustin Pop
  def perspective_instance_os_import(params):
387 3ecf6786 Iustin Pop
    """Run the import function of an OS onto a given instance.
388 3ecf6786 Iustin Pop
389 3ecf6786 Iustin Pop
    """
390 6c0af70e Guido Trotter
    inst_s, src_node, src_images, cluster_name = params
391 319856a9 Michael Hanselmann
    inst = objects.Instance.FromDict(inst_s)
392 6c0af70e Guido Trotter
    return backend.ImportOSIntoInstance(inst, src_node, src_images,
393 6c0af70e Guido Trotter
                                        cluster_name)
394 a8083063 Iustin Pop
395 3ecf6786 Iustin Pop
  @staticmethod
396 3ecf6786 Iustin Pop
  def perspective_instance_shutdown(params):
397 3ecf6786 Iustin Pop
    """Shutdown an instance.
398 3ecf6786 Iustin Pop
399 3ecf6786 Iustin Pop
    """
400 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
401 1fae010f Iustin Pop
    return backend.InstanceShutdown(instance)
402 a8083063 Iustin Pop
403 3ecf6786 Iustin Pop
  @staticmethod
404 3ecf6786 Iustin Pop
  def perspective_instance_start(params):
405 3ecf6786 Iustin Pop
    """Start an instance.
406 3ecf6786 Iustin Pop
407 3ecf6786 Iustin Pop
    """
408 319856a9 Michael Hanselmann
    instance = objects.Instance.FromDict(params[0])
409 07813a9e Iustin Pop
    return backend.StartInstance(instance)
410 a8083063 Iustin Pop
411 3ecf6786 Iustin Pop
  @staticmethod
412 6906a9d8 Guido Trotter
  def perspective_migration_info(params):
413 6906a9d8 Guido Trotter
    """Gather information about an instance to be migrated.
414 6906a9d8 Guido Trotter
415 6906a9d8 Guido Trotter
    """
416 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(params[0])
417 6906a9d8 Guido Trotter
    return backend.MigrationInfo(instance)
418 6906a9d8 Guido Trotter
419 6906a9d8 Guido Trotter
  @staticmethod
420 6906a9d8 Guido Trotter
  def perspective_accept_instance(params):
421 6906a9d8 Guido Trotter
    """Prepare the node to accept an instance.
422 6906a9d8 Guido Trotter
423 6906a9d8 Guido Trotter
    """
424 6906a9d8 Guido Trotter
    instance, info, target = params
425 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(instance)
426 6906a9d8 Guido Trotter
    return backend.AcceptInstance(instance, info, target)
427 6906a9d8 Guido Trotter
428 6906a9d8 Guido Trotter
  @staticmethod
429 6906a9d8 Guido Trotter
  def perspective_finalize_migration(params):
430 6906a9d8 Guido Trotter
    """Finalize the instance migration.
431 6906a9d8 Guido Trotter
432 6906a9d8 Guido Trotter
    """
433 6906a9d8 Guido Trotter
    instance, info, success = params
434 6906a9d8 Guido Trotter
    instance = objects.Instance.FromDict(instance)
435 6906a9d8 Guido Trotter
    return backend.FinalizeMigration(instance, info, success)
436 6906a9d8 Guido Trotter
437 6906a9d8 Guido Trotter
  @staticmethod
438 2a10865c Iustin Pop
  def perspective_instance_migrate(params):
439 2a10865c Iustin Pop
    """Migrates an instance.
440 2a10865c Iustin Pop
441 2a10865c Iustin Pop
    """
442 2a10865c Iustin Pop
    instance, target, live = params
443 9f0e6b37 Iustin Pop
    instance = objects.Instance.FromDict(instance)
444 2a10865c Iustin Pop
    return backend.MigrateInstance(instance, target, live)
445 2a10865c Iustin Pop
446 2a10865c Iustin Pop
  @staticmethod
447 007a2f3e Alexander Schreiber
  def perspective_instance_reboot(params):
448 007a2f3e Alexander Schreiber
    """Reboot an instance.
449 007a2f3e Alexander Schreiber
450 007a2f3e Alexander Schreiber
    """
451 007a2f3e Alexander Schreiber
    instance = objects.Instance.FromDict(params[0])
452 007a2f3e Alexander Schreiber
    reboot_type = params[1]
453 07813a9e Iustin Pop
    return backend.InstanceReboot(instance, reboot_type)
454 007a2f3e Alexander Schreiber
455 007a2f3e Alexander Schreiber
  @staticmethod
456 3ecf6786 Iustin Pop
  def perspective_instance_info(params):
457 3ecf6786 Iustin Pop
    """Query instance information.
458 3ecf6786 Iustin Pop
459 3ecf6786 Iustin Pop
    """
460 16ad1a83 Iustin Pop
    return backend.GetInstanceInfo(params[0], params[1])
461 a8083063 Iustin Pop
462 3ecf6786 Iustin Pop
  @staticmethod
463 56e7640c Iustin Pop
  def perspective_instance_migratable(params):
464 56e7640c Iustin Pop
    """Query whether the specified instance can be migrated.
465 56e7640c Iustin Pop
466 56e7640c Iustin Pop
    """
467 56e7640c Iustin Pop
    instance = objects.Instance.FromDict(params[0])
468 56e7640c Iustin Pop
    return backend.GetInstanceMigratable(instance)
469 56e7640c Iustin Pop
470 56e7640c Iustin Pop
  @staticmethod
471 3ecf6786 Iustin Pop
  def perspective_all_instances_info(params):
472 3ecf6786 Iustin Pop
    """Query information about all instances.
473 3ecf6786 Iustin Pop
474 3ecf6786 Iustin Pop
    """
475 e69d05fd Iustin Pop
    return backend.GetAllInstancesInfo(params[0])
476 a8083063 Iustin Pop
477 3ecf6786 Iustin Pop
  @staticmethod
478 3ecf6786 Iustin Pop
  def perspective_instance_list(params):
479 3ecf6786 Iustin Pop
    """Query the list of running instances.
480 3ecf6786 Iustin Pop
481 3ecf6786 Iustin Pop
    """
482 e69d05fd Iustin Pop
    return backend.GetInstanceList(params[0])
483 a8083063 Iustin Pop
484 a8083063 Iustin Pop
  # node --------------------------
485 a8083063 Iustin Pop
486 3ecf6786 Iustin Pop
  @staticmethod
487 16abfbc2 Alexander Schreiber
  def perspective_node_tcp_ping(params):
488 16abfbc2 Alexander Schreiber
    """Do a TcpPing on the remote node.
489 16abfbc2 Alexander Schreiber
490 16abfbc2 Alexander Schreiber
    """
491 b15d625f Iustin Pop
    return utils.TcpPing(params[1], params[2], timeout=params[3],
492 b15d625f Iustin Pop
                         live_port_needed=params[4], source=params[0])
493 16abfbc2 Alexander Schreiber
494 16abfbc2 Alexander Schreiber
  @staticmethod
495 caad16e2 Iustin Pop
  def perspective_node_has_ip_address(params):
496 caad16e2 Iustin Pop
    """Checks if a node has the given ip address.
497 caad16e2 Iustin Pop
498 caad16e2 Iustin Pop
    """
499 caad16e2 Iustin Pop
    return utils.OwnIpAddress(params[0])
500 caad16e2 Iustin Pop
501 caad16e2 Iustin Pop
  @staticmethod
502 3ecf6786 Iustin Pop
  def perspective_node_info(params):
503 3ecf6786 Iustin Pop
    """Query node information.
504 3ecf6786 Iustin Pop
505 3ecf6786 Iustin Pop
    """
506 e69d05fd Iustin Pop
    vgname, hypervisor_type = params
507 e69d05fd Iustin Pop
    return backend.GetNodeInfo(vgname, hypervisor_type)
508 a8083063 Iustin Pop
509 3ecf6786 Iustin Pop
  @staticmethod
510 3ecf6786 Iustin Pop
  def perspective_node_add(params):
511 3ecf6786 Iustin Pop
    """Complete the registration of this node in the cluster.
512 3ecf6786 Iustin Pop
513 3ecf6786 Iustin Pop
    """
514 a8083063 Iustin Pop
    return backend.AddNode(params[0], params[1], params[2],
515 a8083063 Iustin Pop
                           params[3], params[4], params[5])
516 a8083063 Iustin Pop
517 3ecf6786 Iustin Pop
  @staticmethod
518 3ecf6786 Iustin Pop
  def perspective_node_verify(params):
519 3ecf6786 Iustin Pop
    """Run a verify sequence on this node.
520 3ecf6786 Iustin Pop
521 3ecf6786 Iustin Pop
    """
522 62c9ec92 Iustin Pop
    return backend.VerifyNode(params[0], params[1])
523 a8083063 Iustin Pop
524 3ecf6786 Iustin Pop
  @staticmethod
525 3ecf6786 Iustin Pop
  def perspective_node_start_master(params):
526 3ecf6786 Iustin Pop
    """Promote this node to master status.
527 3ecf6786 Iustin Pop
528 3ecf6786 Iustin Pop
    """
529 2503680f Guido Trotter
    return backend.StartMaster(params[0], params[1])
530 a8083063 Iustin Pop
531 3ecf6786 Iustin Pop
  @staticmethod
532 3ecf6786 Iustin Pop
  def perspective_node_stop_master(params):
533 3ecf6786 Iustin Pop
    """Demote this node from master status.
534 3ecf6786 Iustin Pop
535 3ecf6786 Iustin Pop
    """
536 1c65840b Iustin Pop
    return backend.StopMaster(params[0])
537 a8083063 Iustin Pop
538 3ecf6786 Iustin Pop
  @staticmethod
539 3ecf6786 Iustin Pop
  def perspective_node_leave_cluster(params):
540 3ecf6786 Iustin Pop
    """Cleanup after leaving a cluster.
541 3ecf6786 Iustin Pop
542 3ecf6786 Iustin Pop
    """
543 a8083063 Iustin Pop
    return backend.LeaveCluster()
544 a8083063 Iustin Pop
545 3ecf6786 Iustin Pop
  @staticmethod
546 3ecf6786 Iustin Pop
  def perspective_node_volumes(params):
547 3ecf6786 Iustin Pop
    """Query the list of all logical volume groups.
548 3ecf6786 Iustin Pop
549 3ecf6786 Iustin Pop
    """
550 dcb93971 Michael Hanselmann
    return backend.NodeVolumes()
551 dcb93971 Michael Hanselmann
552 56aa9fd5 Iustin Pop
  @staticmethod
553 56aa9fd5 Iustin Pop
  def perspective_node_demote_from_mc(params):
554 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
555 56aa9fd5 Iustin Pop
556 56aa9fd5 Iustin Pop
    """
557 56aa9fd5 Iustin Pop
    return backend.DemoteFromMC()
558 56aa9fd5 Iustin Pop
559 56aa9fd5 Iustin Pop
560 a8083063 Iustin Pop
  # cluster --------------------------
561 a8083063 Iustin Pop
562 3ecf6786 Iustin Pop
  @staticmethod
563 3ecf6786 Iustin Pop
  def perspective_version(params):
564 3ecf6786 Iustin Pop
    """Query version information.
565 3ecf6786 Iustin Pop
566 3ecf6786 Iustin Pop
    """
567 a8083063 Iustin Pop
    return constants.PROTOCOL_VERSION
568 a8083063 Iustin Pop
569 3ecf6786 Iustin Pop
  @staticmethod
570 3ecf6786 Iustin Pop
  def perspective_upload_file(params):
571 3ecf6786 Iustin Pop
    """Upload a file.
572 3ecf6786 Iustin Pop
573 3ecf6786 Iustin Pop
    Note that the backend implementation imposes strict rules on which
574 3ecf6786 Iustin Pop
    files are accepted.
575 3ecf6786 Iustin Pop
576 3ecf6786 Iustin Pop
    """
577 a8083063 Iustin Pop
    return backend.UploadFile(*params)
578 a8083063 Iustin Pop
579 4e071d3b Iustin Pop
  @staticmethod
580 4e071d3b Iustin Pop
  def perspective_master_info(params):
581 4e071d3b Iustin Pop
    """Query master information.
582 4e071d3b Iustin Pop
583 4e071d3b Iustin Pop
    """
584 4e071d3b Iustin Pop
    return backend.GetMasterInfo()
585 a8083063 Iustin Pop
586 6ddc95ec Michael Hanselmann
  @staticmethod
587 6ddc95ec Michael Hanselmann
  def perspective_write_ssconf_files(params):
588 6ddc95ec Michael Hanselmann
    """Write ssconf files.
589 6ddc95ec Michael Hanselmann
590 6ddc95ec Michael Hanselmann
    """
591 03d1dba2 Michael Hanselmann
    (values,) = params
592 03d1dba2 Michael Hanselmann
    return backend.WriteSsconfFiles(values)
593 6ddc95ec Michael Hanselmann
594 a8083063 Iustin Pop
  # os -----------------------
595 a8083063 Iustin Pop
596 3ecf6786 Iustin Pop
  @staticmethod
597 3ecf6786 Iustin Pop
  def perspective_os_diagnose(params):
598 3ecf6786 Iustin Pop
    """Query detailed information about existing OSes.
599 3ecf6786 Iustin Pop
600 3ecf6786 Iustin Pop
    """
601 821d1bd1 Iustin Pop
    return [os_obj.ToDict() for os_obj in backend.DiagnoseOS()]
602 a8083063 Iustin Pop
603 3ecf6786 Iustin Pop
  @staticmethod
604 3ecf6786 Iustin Pop
  def perspective_os_get(params):
605 3ecf6786 Iustin Pop
    """Query information about a given OS.
606 3ecf6786 Iustin Pop
607 3ecf6786 Iustin Pop
    """
608 a8083063 Iustin Pop
    name = params[0]
609 a8083063 Iustin Pop
    try:
610 dfa96ded Guido Trotter
      os_obj = backend.OSFromDisk(name)
611 a8083063 Iustin Pop
    except errors.InvalidOS, err:
612 dfa96ded Guido Trotter
      os_obj = objects.OS.FromInvalidOS(err)
613 dfa96ded Guido Trotter
    return os_obj.ToDict()
614 a8083063 Iustin Pop
615 a8083063 Iustin Pop
  # hooks -----------------------
616 a8083063 Iustin Pop
617 3ecf6786 Iustin Pop
  @staticmethod
618 3ecf6786 Iustin Pop
  def perspective_hooks_runner(params):
619 3ecf6786 Iustin Pop
    """Run hook scripts.
620 3ecf6786 Iustin Pop
621 3ecf6786 Iustin Pop
    """
622 a8083063 Iustin Pop
    hpath, phase, env = params
623 a8083063 Iustin Pop
    hr = backend.HooksRunner()
624 a8083063 Iustin Pop
    return hr.RunHooks(hpath, phase, env)
625 a8083063 Iustin Pop
626 8d528b7c Iustin Pop
  # iallocator -----------------
627 8d528b7c Iustin Pop
628 8d528b7c Iustin Pop
  @staticmethod
629 8d528b7c Iustin Pop
  def perspective_iallocator_runner(params):
630 8d528b7c Iustin Pop
    """Run an iallocator script.
631 8d528b7c Iustin Pop
632 8d528b7c Iustin Pop
    """
633 8d528b7c Iustin Pop
    name, idata = params
634 8d528b7c Iustin Pop
    iar = backend.IAllocatorRunner()
635 8d528b7c Iustin Pop
    return iar.Run(name, idata)
636 8d528b7c Iustin Pop
637 06009e27 Iustin Pop
  # test -----------------------
638 06009e27 Iustin Pop
639 06009e27 Iustin Pop
  @staticmethod
640 06009e27 Iustin Pop
  def perspective_test_delay(params):
641 06009e27 Iustin Pop
    """Run test delay.
642 06009e27 Iustin Pop
643 06009e27 Iustin Pop
    """
644 06009e27 Iustin Pop
    duration = params[0]
645 06009e27 Iustin Pop
    return utils.TestDelay(duration)
646 06009e27 Iustin Pop
647 4e071d3b Iustin Pop
  # file storage ---------------
648 4e071d3b Iustin Pop
649 a5d7fb43 Manuel Franceschini
  @staticmethod
650 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_create(params):
651 a5d7fb43 Manuel Franceschini
    """Create the file storage directory.
652 a5d7fb43 Manuel Franceschini
653 a5d7fb43 Manuel Franceschini
    """
654 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
655 a5d7fb43 Manuel Franceschini
    return backend.CreateFileStorageDir(file_storage_dir)
656 a5d7fb43 Manuel Franceschini
657 a5d7fb43 Manuel Franceschini
  @staticmethod
658 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_remove(params):
659 a5d7fb43 Manuel Franceschini
    """Remove the file storage directory.
660 a5d7fb43 Manuel Franceschini
661 a5d7fb43 Manuel Franceschini
    """
662 a5d7fb43 Manuel Franceschini
    file_storage_dir = params[0]
663 a5d7fb43 Manuel Franceschini
    return backend.RemoveFileStorageDir(file_storage_dir)
664 a5d7fb43 Manuel Franceschini
665 a5d7fb43 Manuel Franceschini
  @staticmethod
666 a5d7fb43 Manuel Franceschini
  def perspective_file_storage_dir_rename(params):
667 a5d7fb43 Manuel Franceschini
    """Rename the file storage directory.
668 a5d7fb43 Manuel Franceschini
669 a5d7fb43 Manuel Franceschini
    """
670 a5d7fb43 Manuel Franceschini
    old_file_storage_dir = params[0]
671 a5d7fb43 Manuel Franceschini
    new_file_storage_dir = params[1]
672 a5d7fb43 Manuel Franceschini
    return backend.RenameFileStorageDir(old_file_storage_dir,
673 a5d7fb43 Manuel Franceschini
                                        new_file_storage_dir)
674 a5d7fb43 Manuel Franceschini
675 4e071d3b Iustin Pop
  # jobs ------------------------
676 4e071d3b Iustin Pop
677 ca52cdeb Michael Hanselmann
  @staticmethod
678 7f30777b Michael Hanselmann
  @_RequireJobQueueLock
679 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_update(params):
680 ca52cdeb Michael Hanselmann
    """Update job queue.
681 ca52cdeb Michael Hanselmann
682 ca52cdeb Michael Hanselmann
    """
683 ca52cdeb Michael Hanselmann
    (file_name, content) = params
684 7f30777b Michael Hanselmann
    return backend.JobQueueUpdate(file_name, content)
685 ca52cdeb Michael Hanselmann
686 ca52cdeb Michael Hanselmann
  @staticmethod
687 f1f3f45c Michael Hanselmann
  @_RequireJobQueueLock
688 ca52cdeb Michael Hanselmann
  def perspective_jobqueue_purge(params):
689 ca52cdeb Michael Hanselmann
    """Purge job queue.
690 ca52cdeb Michael Hanselmann
691 ca52cdeb Michael Hanselmann
    """
692 ca52cdeb Michael Hanselmann
    return backend.JobQueuePurge()
693 ca52cdeb Michael Hanselmann
694 af5ebcb1 Michael Hanselmann
  @staticmethod
695 af5ebcb1 Michael Hanselmann
  @_RequireJobQueueLock
696 af5ebcb1 Michael Hanselmann
  def perspective_jobqueue_rename(params):
697 af5ebcb1 Michael Hanselmann
    """Rename a job queue file.
698 af5ebcb1 Michael Hanselmann
699 af5ebcb1 Michael Hanselmann
    """
700 dd875d32 Michael Hanselmann
    # TODO: What if a file fails to rename?
701 dd875d32 Michael Hanselmann
    return [backend.JobQueueRename(old, new) for old, new in params]
702 af5ebcb1 Michael Hanselmann
703 5d672980 Iustin Pop
  @staticmethod
704 5d672980 Iustin Pop
  def perspective_jobqueue_set_drain(params):
705 5d672980 Iustin Pop
    """Set/unset the queue drain flag.
706 5d672980 Iustin Pop
707 5d672980 Iustin Pop
    """
708 5d672980 Iustin Pop
    drain_flag = params[0]
709 5d672980 Iustin Pop
    return backend.JobQueueSetDrainFlag(drain_flag)
710 5d672980 Iustin Pop
711 5d672980 Iustin Pop
712 6217e295 Iustin Pop
  # hypervisor ---------------
713 6217e295 Iustin Pop
714 6217e295 Iustin Pop
  @staticmethod
715 6217e295 Iustin Pop
  def perspective_hypervisor_validate_params(params):
716 6217e295 Iustin Pop
    """Validate the hypervisor parameters.
717 6217e295 Iustin Pop
718 6217e295 Iustin Pop
    """
719 6217e295 Iustin Pop
    (hvname, hvparams) = params
720 6217e295 Iustin Pop
    return backend.ValidateHVParams(hvname, hvparams)
721 6217e295 Iustin Pop
722 a8083063 Iustin Pop
723 a8083063 Iustin Pop
def ParseOptions():
724 a8083063 Iustin Pop
  """Parse the command line options.
725 a8083063 Iustin Pop
726 c41eea6e Iustin Pop
  @return: (options, args) as from OptionParser.parse_args()
727 a8083063 Iustin Pop
728 a8083063 Iustin Pop
  """
729 a8083063 Iustin Pop
  parser = OptionParser(description="Ganeti node daemon",
730 cf192249 Guido Trotter
                        usage="%prog [-f] [-d] [-b ADDRESS]",
731 a8083063 Iustin Pop
                        version="%%prog (ganeti) %s" %
732 a8083063 Iustin Pop
                        constants.RELEASE_VERSION)
733 a8083063 Iustin Pop
734 a8083063 Iustin Pop
  parser.add_option("-f", "--foreground", dest="fork",
735 a8083063 Iustin Pop
                    help="Don't detach from the current terminal",
736 a8083063 Iustin Pop
                    default=True, action="store_false")
737 a8083063 Iustin Pop
  parser.add_option("-d", "--debug", dest="debug",
738 a8083063 Iustin Pop
                    help="Enable some debug messages",
739 a8083063 Iustin Pop
                    default=False, action="store_true")
740 cf192249 Guido Trotter
  parser.add_option("-b", "--bind", dest="bind_address",
741 cf192249 Guido Trotter
                    help="Bind address",
742 cf192249 Guido Trotter
                    default="", metavar="ADDRESS")
743 cf192249 Guido Trotter
744 a8083063 Iustin Pop
  options, args = parser.parse_args()
745 a8083063 Iustin Pop
  return options, args
746 a8083063 Iustin Pop
747 a8083063 Iustin Pop
748 a8083063 Iustin Pop
def main():
749 3ecf6786 Iustin Pop
  """Main function for the node daemon.
750 3ecf6786 Iustin Pop
751 3ecf6786 Iustin Pop
  """
752 25d6d12a Michael Hanselmann
  global queue_lock
753 25d6d12a Michael Hanselmann
754 a8083063 Iustin Pop
  options, args = ParseOptions()
755 7d88772a Iustin Pop
756 7d88772a Iustin Pop
  if options.fork:
757 7d88772a Iustin Pop
    utils.CloseFDs()
758 7d88772a Iustin Pop
759 a8083063 Iustin Pop
  for fname in (constants.SSL_CERT_FILE,):
760 a8083063 Iustin Pop
    if not os.path.isfile(fname):
761 a8083063 Iustin Pop
      print "config %s not there, will not run." % fname
762 46479775 Guido Trotter
      sys.exit(constants.EXIT_NOTCLUSTER)
763 a8083063 Iustin Pop
764 46479775 Guido Trotter
  port = utils.GetNodeDaemonPort()
765 a8083063 Iustin Pop
766 9dae41ad Guido Trotter
  dirs = [(val, constants.RUN_DIRS_MODE) for val in constants.SUB_RUN_DIRS]
767 9dae41ad Guido Trotter
  dirs.append((constants.LOG_OS_DIR, 0750))
768 9dae41ad Guido Trotter
  dirs.append((constants.LOCK_DIR, 1777))
769 9dae41ad Guido Trotter
  utils.EnsureDirs(dirs)
770 0214b0c0 Iustin Pop
771 a8083063 Iustin Pop
  # become a daemon
772 a8083063 Iustin Pop
  if options.fork:
773 8f765069 Iustin Pop
    utils.Daemonize(logfile=constants.LOG_NODESERVER)
774 a8083063 Iustin Pop
775 99e88451 Iustin Pop
  utils.WritePidFile(constants.NODED_PID)
776 cc28af80 Michael Hanselmann
  try:
777 82d9caef Iustin Pop
    utils.SetupLogging(logfile=constants.LOG_NODESERVER, debug=options.debug,
778 82d9caef Iustin Pop
                       stderr_logging=not options.fork)
779 cc28af80 Michael Hanselmann
    logging.info("ganeti node daemon startup")
780 73d927a2 Guido Trotter
781 eafd8762 Michael Hanselmann
    # Read SSL certificate
782 eafd8762 Michael Hanselmann
    ssl_params = http.HttpSslParams(ssl_key_path=constants.SSL_CERT_FILE,
783 eafd8762 Michael Hanselmann
                                    ssl_cert_path=constants.SSL_CERT_FILE)
784 eafd8762 Michael Hanselmann
785 cc28af80 Michael Hanselmann
    # Prepare job queue
786 cc28af80 Michael Hanselmann
    queue_lock = jstore.InitAndVerifyQueue(must_lock=False)
787 a8083063 Iustin Pop
788 cc28af80 Michael Hanselmann
    mainloop = daemon.Mainloop()
789 cf192249 Guido Trotter
    server = NodeHttpServer(mainloop, options.bind_address, port,
790 eafd8762 Michael Hanselmann
                            ssl_params=ssl_params, ssl_verify_peer=True)
791 cc28af80 Michael Hanselmann
    server.Start()
792 cc28af80 Michael Hanselmann
    try:
793 cc28af80 Michael Hanselmann
      mainloop.Run()
794 cc28af80 Michael Hanselmann
    finally:
795 cc28af80 Michael Hanselmann
      server.Stop()
796 73d927a2 Guido Trotter
  finally:
797 99e88451 Iustin Pop
    utils.RemovePidFile(constants.NODED_PID)
798 73d927a2 Guido Trotter
799 a8083063 Iustin Pop
800 3ecf6786 Iustin Pop
if __name__ == '__main__':
801 a8083063 Iustin Pop
  main()