python: Upgrade daemon module to argparse.
[sliver-openvswitch.git] / python / ovs / daemon.py
index a14be82..864a163 100644 (file)
@@ -141,23 +141,23 @@ def _make_pidfile():
         # unlock the lock for us, and we don't want that.
         global file
 
-        file = open(tmpfile, "w")
+        file_handle = open(tmpfile, "w")
     except IOError, e:
         _fatal("%s: create failed (%s)" % (tmpfile, e.strerror))
 
     try:
-        s = os.fstat(file.fileno())
+        s = os.fstat(file_handle.fileno())
     except IOError, e:
         _fatal("%s: fstat failed (%s)" % (tmpfile, e.strerror))
 
     try:
-        file.write("%s\n" % pid)
-        file.flush()
+        file_handle.write("%s\n" % pid)
+        file_handle.flush()
     except OSError, e:
         _fatal("%s: write failed: %s" % (tmpfile, e.strerror))
 
     try:
-        fcntl.lockf(file, fcntl.LOCK_EX | fcntl.LOCK_NB)
+        fcntl.lockf(file_handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
     except IOError, e:
         _fatal("%s: fcntl failed: %s" % (tmpfile, e.strerror))
 
@@ -407,7 +407,7 @@ def __read_pidfile(pidfile, delete_if_stale):
             pass
 
     try:
-        file = open(pidfile, "r+")
+        file_handle = open(pidfile, "r+")
     except IOError, e:
         if e.errno == errno.ENOENT and delete_if_stale:
             return 0
@@ -417,11 +417,11 @@ def __read_pidfile(pidfile, delete_if_stale):
     # Python fcntl doesn't directly support F_GETLK so we have to just try
     # to lock it.
     try:
-        fcntl.lockf(file, fcntl.LOCK_EX | fcntl.LOCK_NB)
+        fcntl.lockf(file_handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
 
         # pidfile exists but wasn't locked by anyone.  Now we have the lock.
         if not delete_if_stale:
-            file.close()
+            file_handle.close()
             logging.warning("%s: pid file is stale" % pidfile)
             return -errno.ESRCH
 
@@ -429,7 +429,7 @@ def __read_pidfile(pidfile, delete_if_stale):
         try:
             raced = False
             s = os.stat(pidfile)
-            s2 = os.fstat(file.fileno())
+            s2 = os.fstat(file_handle.fileno())
             if s.st_ino != s2.st_ino or s.st_dev != s2.st_dev:
                 raced = True
         except IOError:
@@ -447,7 +447,7 @@ def __read_pidfile(pidfile, delete_if_stale):
             return -e.errno
         else:
             logging.debug("%s: deleted stale pidfile" % pidfile)
-            file.close()
+            file_handle.close()
             return 0
     except IOError, e:
         if e.errno not in [errno.EACCES, errno.EAGAIN]:
@@ -457,16 +457,18 @@ def __read_pidfile(pidfile, delete_if_stale):
     # Someone else has the pidfile locked.
     try:
         try:
-            return int(file.readline())
+            error = int(file_handle.readline())
         except IOError, e:
             logging.warning("%s: read: %s" % (pidfile, e.strerror))
-            return -e.errno
+            error = -e.errno
         except ValueError:
             logging.warning("%s does not contain a pid" % pidfile)
-            return -errno.EINVAL
+            error = -errno.EINVAL
+
+        return error
     finally:
         try:
-            file.close()
+            file_handle.close()
         except IOError:
             pass
 
@@ -485,26 +487,43 @@ def _check_already_running():
         _fatal("%s: pidfile check failed (%s), aborting"
                % (_pidfile, os.strerror(pid)))
 
-# XXX Python's getopt does not support options with optional arguments, so we
-# have to separate --pidfile (with no argument) from --pidfile-name (with an
-# argument).  Need to write our own getopt I guess.
-LONG_OPTIONS = ["detach", "no-chdir", "pidfile", "pidfile-name=",
-                "overwrite-pidfile", "monitor"]
 
+def add_args(parser):
+    """Populates 'parser', an ArgumentParser allocated using the argparse
+    module, with the command line arguments required by the daemon module."""
+
+    pidfile = make_pidfile_name(None)
+
+    group = parser.add_argument_group(title="Daemon Options")
+    group.add_argument("--detach", action="store_true",
+            help="Run in background as a daemon.")
+    group.add_argument("--no-chdir", action="store_true",
+            help="Do not chdir to '/'.")
+    group.add_argument("--monitor", action="store_true",
+            help="Monitor %s process." % ovs.util.PROGRAM_NAME)
+    group.add_argument("--pidfile", nargs="?", default=pidfile,
+            help="Create pidfile (default %s)." % pidfile)
+    group.add_argument("--overwrite-pidfile", action="store_true",
+            help="With --pidfile, start even if already running.")
+
+
+def handle_args(args):
+    """Handles daemon module settings in 'args'.  'args' is an object
+    containing values parsed by the parse_args() method of ArgumentParser.  The
+    parent ArgumentParser should have been prepared by add_args() before
+    calling parse_args()."""
 
-def parse_opt(option, arg):
-    if option == '--detach':
+    if args.detach:
         set_detach()
-    elif option == '--no-chdir':
+
+    if args.no_chdir:
         set_no_chdir()
-    elif option == '--pidfile':
-        set_pidfile(None)
-    elif option == '--pidfile-name':
-        set_pidfile(arg)
-    elif option == '--overwrite-pidfile':
+
+    if args.pidfile:
+        set_pidfile(args.pidfile)
+
+    if args.overwrite_pidfile:
         ignore_existing_pidfile()
-    elif option == '--monitor':
+
+    if args.monitor:
         set_monitor()
-    else:
-        return False
-    return True