Add generic daemon options support binding to interfaces
[ganeti-local] / lib / server / noded.py
index 203dc3c..aedd321 100644 (file)
@@ -45,7 +45,7 @@ from ganeti import jstore
 from ganeti import daemon
 from ganeti import http
 from ganeti import utils
-from ganeti import storage
+from ganeti.storage import container
 from ganeti import serializer
 from ganeti import netutils
 from ganeti import pathutils
@@ -57,6 +57,16 @@ import ganeti.http.server # pylint: disable=W0611
 queue_lock = None
 
 
+def _extendReasonTrail(trail, source, reason=""):
+  """Extend the reason trail with noded information
+
+  The trail is extended by appending the name of the noded functionality
+  """
+  assert trail is not None
+  trail_source = "%s:%s" % (constants.OPCODE_REASON_SRC_NODED, source)
+  trail.append((trail_source, reason, utils.EpochNano()))
+
+
 def _PrepareQueueLock():
   """Try to prepare the queue lock.
 
@@ -112,6 +122,23 @@ def _DecodeImportExportIO(ieio, ieioargs):
   return ieioargs
 
 
+def _DefaultAlternative(value, default):
+  """Returns value or, if evaluating to False, a default value.
+
+  Returns the given value, unless it evaluates to False. In the latter case the
+  default value is returned.
+
+  @param value: Value to return if it doesn't evaluate to False
+  @param default: Default value
+  @return: Given value or the default
+
+  """
+  if value:
+    return value
+
+  return default
+
+
 class MlockallRequestExecutor(http.server.HttpServerRequestExecutor):
   """Subclass ensuring request handlers are locked in RAM.
 
@@ -179,11 +206,12 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     """Create a block device.
 
     """
-    bdev_s, size, owner, on_primary, info = params
+    (bdev_s, size, owner, on_primary, info, excl_stor) = params
     bdev = objects.Disk.FromDict(bdev_s)
     if bdev is None:
       raise ValueError("can't unserialize data!")
-    return backend.BlockdevCreate(bdev, size, owner, on_primary, info)
+    return backend.BlockdevCreate(bdev, size, owner, on_primary, info,
+                                  excl_stor)
 
   @staticmethod
   def perspective_blockdev_pause_resume_sync(params):
@@ -351,12 +379,12 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     return backend.BlockdevClose(params[0], disks)
 
   @staticmethod
-  def perspective_blockdev_getsize(params):
+  def perspective_blockdev_getdimensions(params):
     """Compute the sizes of the given block devices.
 
     """
     disks = [objects.Disk.FromDict(cf) for cf in params[0]]
-    return backend.BlockdevGetsize(disks)
+    return backend.BlockdevGetdimensions(disks)
 
   @staticmethod
   def perspective_blockdev_export(params):
@@ -367,6 +395,15 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     dest_node, dest_path, cluster_name = params[1:]
     return backend.BlockdevExport(disk, dest_node, dest_path, cluster_name)
 
+  @staticmethod
+  def perspective_blockdev_setinfo(params):
+    """Sets metadata information on the given block device.
+
+    """
+    (disk, info) = params
+    disk = objects.Disk.FromDict(disk)
+    return backend.BlockdevSetInfo(disk, info)
+
   # blockdev/drbd specific methods ----------
 
   @staticmethod
@@ -495,7 +532,7 @@ class NodeRequestHandler(http.server.HttpServerHandler):
 
     """
     (su_name, su_args, name, fields) = params
-    return storage.GetStorage(su_name, *su_args).List(name, fields)
+    return container.GetStorage(su_name, *su_args).List(name, fields)
 
   @staticmethod
   def perspective_storage_modify(params):
@@ -503,7 +540,7 @@ class NodeRequestHandler(http.server.HttpServerHandler):
 
     """
     (su_name, su_args, name, changes) = params
-    return storage.GetStorage(su_name, *su_args).Modify(name, changes)
+    return container.GetStorage(su_name, *su_args).Modify(name, changes)
 
   @staticmethod
   def perspective_storage_execute(params):
@@ -511,7 +548,7 @@ class NodeRequestHandler(http.server.HttpServerHandler):
 
     """
     (su_name, su_args, name, op) = params
-    return storage.GetStorage(su_name, *su_args).Execute(name, op)
+    return container.GetStorage(su_name, *su_args).Execute(name, op)
 
   # bridge  --------------------------
 
@@ -552,16 +589,19 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     """
     instance = objects.Instance.FromDict(params[0])
     timeout = params[1]
-    return backend.InstanceShutdown(instance, timeout)
+    trail = params[2]
+    _extendReasonTrail(trail, "shutdown")
+    return backend.InstanceShutdown(instance, timeout, trail)
 
   @staticmethod
   def perspective_instance_start(params):
     """Start an instance.
 
     """
-    (instance_name, startup_paused) = params
+    (instance_name, startup_paused, trail) = params
     instance = objects.Instance.FromDict(instance_name)
-    return backend.StartInstance(instance, startup_paused)
+    _extendReasonTrail(trail, "start")
+    return backend.StartInstance(instance, startup_paused, trail)
 
   @staticmethod
   def perspective_migration_info(params):
@@ -623,7 +663,10 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     instance = objects.Instance.FromDict(params[0])
     reboot_type = params[1]
     shutdown_timeout = params[2]
-    return backend.InstanceReboot(instance, reboot_type, shutdown_timeout)
+    trail = params[3]
+    _extendReasonTrail(trail, "reboot")
+    return backend.InstanceReboot(instance, reboot_type, shutdown_timeout,
+                                  trail)
 
   @staticmethod
   def perspective_instance_balloon_memory(params):
@@ -677,8 +720,8 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     """Query node information.
 
     """
-    (vg_names, hv_names) = params
-    return backend.GetNodeInfo(vg_names, hv_names)
+    (storage_units, hv_names, excl_stor) = params
+    return backend.GetNodeInfo(storage_units, hv_names, excl_stor)
 
   @staticmethod
   def perspective_etc_hosts_modify(params):
@@ -696,6 +739,14 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     """
     return backend.VerifyNode(params[0], params[1])
 
+  @classmethod
+  def perspective_node_verify_light(cls, params):
+    """Run a light verify sequence on this node.
+
+    """
+    # So far it's the same as the normal node_verify
+    return cls.perspective_node_verify(params)
+
   @staticmethod
   def perspective_node_start_master_daemons(params):
     """Start the master daemons on this node.
@@ -802,6 +853,15 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     return result
 
   @staticmethod
+  def perspective_restricted_command(params):
+    """Runs a restricted command.
+
+    """
+    (cmd, ) = params
+
+    return backend.RunRestrictedCmd(cmd)
+
+  @staticmethod
   def perspective_write_ssconf_files(params):
     """Write ssconf files.
 
@@ -809,6 +869,21 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     (values,) = params
     return ssconf.WriteSsconfFiles(values)
 
+  @staticmethod
+  def perspective_get_watcher_pause(params):
+    """Get watcher pause end.
+
+    """
+    return utils.ReadWatcherPauseFile(pathutils.WATCHER_PAUSEFILE)
+
+  @staticmethod
+  def perspective_set_watcher_pause(params):
+    """Set watcher pause.
+
+    """
+    (until, ) = params
+    return backend.SetWatcherPause(until)
+
   # os -----------------------
 
   @staticmethod
@@ -835,6 +910,15 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     required, name, checks, params = params
     return backend.ValidateOS(required, name, checks, params)
 
+  # extstorage -----------------------
+
+  @staticmethod
+  def perspective_extstorage_diagnose(params):
+    """Query detailed information about existing extstorage providers.
+
+    """
+    return backend.DiagnoseExtStorage()
+
   # hooks -----------------------
 
   @staticmethod
@@ -926,6 +1010,16 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     # TODO: What if a file fails to rename?
     return [backend.JobQueueRename(old, new) for old, new in params[0]]
 
+  @staticmethod
+  @_RequireJobQueueLock
+  def perspective_jobqueue_set_drain_flag(params):
+    """Set job queue's drain flag.
+
+    """
+    (flag, ) = params
+
+    return jstore.SetDrainFlag(flag)
+
   # hypervisor ---------------
 
   @staticmethod
@@ -1083,7 +1177,8 @@ def Main():
 
   """
   parser = OptionParser(description="Ganeti node daemon",
-                        usage="%prog [-f] [-d] [-p port] [-b ADDRESS]",
+                        usage="%prog [-f] [-d] [-p port] [-b ADDRESS]\
+                              \ [-i INTERFACE]",
                         version="%%prog (ganeti) %s" %
                         constants.RELEASE_VERSION)
   parser.add_option("--no-mlock", dest="mlock",