Inline simple "alias" variables
[ganeti-local] / lib / daemon.py
index 1e41b80..0ef1f6e 100644 (file)
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2006, 2007, 2008, 2010, 2011 Google Inc.
+# Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -382,7 +382,7 @@ class AsyncUDPSocket(GanetiBaseAsyncoreDispatcher):
 
     """
     if len(payload) > constants.MAX_UDP_DATA_SIZE:
-      raise errors.UdpDataSizeError('Packet too big: %s > %s' % (len(payload),
+      raise errors.UdpDataSizeError("Packet too big: %s > %s" % (len(payload),
                                     constants.MAX_UDP_DATA_SIZE))
     self._out_queue.append((ip, port, payload))
 
@@ -420,7 +420,7 @@ class AsyncAwaker(GanetiBaseAsyncoreDispatcher):
 
     """
     GanetiBaseAsyncoreDispatcher.__init__(self)
-    assert signal_fn == None or callable(signal_fn)
+    assert signal_fn is None or callable(signal_fn)
     (self.in_socket, self.out_socket) = socket.socketpair(socket.AF_UNIX,
                                                           socket.SOCK_STREAM)
     self.in_socket.setblocking(0)
@@ -621,6 +621,7 @@ def _VerifyDaemonUser(daemon_name):
     constants.NODED: getents.noded_uid,
     constants.CONFD: getents.confd_uid,
     }
+  assert daemon_name in daemon_uids, "Invalid daemon %s" % daemon_name
 
   return (daemon_uids[daemon_name] == running_uid, running_uid,
           daemon_uids[daemon_name])
@@ -711,12 +712,12 @@ def GenericMain(daemon_name, optionparser,
                           default=constants.SYSLOG_USAGE,
                           choices=["no", "yes", "only"])
 
+  family = ssconf.SimpleStore().GetPrimaryIPFamily()
+  # family will default to AF_INET if there is no ssconf file (e.g. when
+  # upgrading a cluster from 2.2 -> 2.3. This is intended, as Ganeti clusters
+  # <= 2.2 can not be AF_INET6
   if daemon_name in constants.DAEMONS_PORTS:
     default_bind_address = constants.IP4_ADDRESS_ANY
-    family = ssconf.SimpleStore().GetPrimaryIPFamily()
-    # family will default to AF_INET if there is no ssconf file (e.g. when
-    # upgrading a cluster from 2.2 -> 2.3. This is intended, as Ganeti clusters
-    # <= 2.2 can not be AF_INET6
     if family == netutils.IP6Address.family:
       default_bind_address = constants.IP6_ADDRESS_ANY
 
@@ -730,6 +731,8 @@ def GenericMain(daemon_name, optionparser,
                             help=("Bind address (default: '%s')" %
                                   default_bind_address),
                             default=default_bind_address, metavar="ADDRESS")
+    optionparser.add_option("-i", "--interface", dest="bind_interface",
+                            help=("Bind interface"), metavar="INTERFACE")
 
   if default_ssl_key is not None and default_ssl_cert is not None:
     optionparser.add_option("--no-ssl", dest="ssl",
@@ -752,6 +755,24 @@ def GenericMain(daemon_name, optionparser,
 
   options, args = optionparser.parse_args()
 
+  if getattr(options, "bind_interface", None) is not None:
+    if options.bind_address != default_bind_address:
+      msg = ("Can't specify both, bind address (%s) and bind interface (%s)" %
+             (options.bind_address, options.bind_interface))
+      print >> sys.stderr, msg
+      sys.exit(constants.EXIT_FAILURE)
+    interface_ip_addresses = \
+      netutils.GetInterfaceIpAddresses(options.bind_interface)
+    if family == netutils.IP6Address.family:
+      if_addresses = interface_ip_addresses[constants.IP6_VERSION]
+    else:
+      if_addresses = interface_ip_addresses[constants.IP4_VERSION]
+    if len(if_addresses) < 1:
+      msg = "Failed to find IP for interface %s" % options.bind_interace
+      print >> sys.stderr, msg
+      sys.exit(constants.EXIT_FAILURE)
+    options.bind_address = if_addresses[0]
+
   if getattr(options, "ssl", False):
     ssl_paths = {
       "certificate": options.ssl_cert,
@@ -777,15 +798,16 @@ def GenericMain(daemon_name, optionparser,
   if check_fn is not None:
     check_fn(options, args)
 
+  log_filename = constants.DAEMONS_LOGFILES[daemon_name]
+
   if options.fork:
     utils.CloseFDs()
-    (wpipe, stdio_reopen_fn) = \
-      utils.Daemonize(logfile=constants.DAEMONS_LOGFILES[daemon_name])
+    (wpipe, stdio_reopen_fn) = utils.Daemonize(logfile=log_filename)
   else:
     (wpipe, stdio_reopen_fn) = (None, None)
 
   log_reopen_fn = \
-    utils.SetupLogging(constants.DAEMONS_LOGFILES[daemon_name], daemon_name,
+    utils.SetupLogging(log_filename, daemon_name,
                        debug=options.debug,
                        stderr_logging=not options.fork,
                        multithreaded=multithreaded,