diff mbox

[nfs-utils,v3,05/17] mountstats: Convert existing option parsing to use the argparse module

Message ID 1418068645-10134-6-git-send-email-smayhew@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Scott Mayhew Dec. 8, 2014, 7:57 p.m. UTC
Also removed the --start and --end options since all they do is throw
exceptions.

Signed-off-by: Scott Mayhew <smayhew@redhat.com>
---
 tools/mountstats/mountstats.py | 240 +++++++++++++++++------------------------
 1 file changed, 98 insertions(+), 142 deletions(-)
diff mbox

Patch

diff --git a/tools/mountstats/mountstats.py b/tools/mountstats/mountstats.py
index 912d31a..384af99 100644
--- a/tools/mountstats/mountstats.py
+++ b/tools/mountstats/mountstats.py
@@ -25,6 +25,12 @@  MA 02110-1301 USA
 
 import sys, os, time
 from operator import itemgetter
+try:
+    import argparse
+except ImportError:
+    print('%s:  Failed to import argparse - make sure argparse is installed!'
+        % sys.argv[0])
+    sys.exit(1)
 
 Mountstats_version = '0.2'
 
@@ -533,66 +539,12 @@  def parse_stats_file(filename):
 
     return ms_dict
 
-def print_mountstats_help(name):
-    print('usage: %s [ options ] <mount point>' % name)
-    print()
-    print(' Version %s' % Mountstats_version)
-    print()
-    print(' Display NFS client per-mount statistics.')
-    print()
-    print('  --version    display the version of this command')
-    print('  --nfs        display only the NFS statistics')
-    print('  --rpc        display only the RPC statistics')
-    print('  --start      sample and save statistics')
-    print('  --end        resample statistics and compare them with saved')
-    print()
-
-def mountstats_command():
+def mountstats_command(args):
     """Mountstats command
     """
-    mountpoints = []
-    nfs_only = False
-    rpc_only = False
-
-    for arg in sys.argv:
-        if arg in ['-h', '--help', 'help', 'usage']:
-            print_mountstats_help(prog)
-            return
-
-        if arg in ['-v', '--version', 'version']:
-            print('%s version %s' % (sys.argv[0], Mountstats_version))
-            sys.exit(0)
-
-        if arg in ['-n', '--nfs']:
-            nfs_only = True
-            continue
-
-        if arg in ['-r', '--rpc']:
-            rpc_only = True
-            continue
-
-        if arg in ['-s', '--start']:
-            raise Exception('Sampling is not yet implemented')
-
-        if arg in ['-e', '--end']:
-            raise Exception('Sampling is not yet implemented')
-
-        if arg == sys.argv[0]:
-            continue
-
-        mountpoints += [arg]
-
-    if mountpoints == []:
-        print_mountstats_help(prog)
-        return
-
-    if rpc_only == True and nfs_only == True:
-        print_mountstats_help(prog)
-        return
-
     mountstats = parse_stats_file('/proc/self/mountstats')
 
-    for mp in mountpoints:
+    for mp in args.mountpoints:
         if mp not in mountstats:
             print('Statistics for mount point %s not found' % mp)
             continue
@@ -604,11 +556,11 @@  def mountstats_command():
             print('Mount point %s exists but is not an NFS mount' % mp)
             continue
 
-        if nfs_only:
+        if args.nfs_only:
            stats.display_nfs_options()
            stats.display_nfs_events()
            stats.display_nfs_bytes()
-        elif rpc_only:
+        elif args.rpc_only:
            stats.display_rpc_generic_stats()
            stats.display_rpc_op_stats()
         else:
@@ -617,38 +569,8 @@  def mountstats_command():
            stats.display_rpc_generic_stats()
            stats.display_rpc_op_stats()
 
-def print_nfsstat_help(name):
-    print('usage: %s [ options ]' % name)
-    print()
-    print(' Version %s' % Mountstats_version)
-    print()
-    print(' nfsstat-like program that uses NFS client per-mount statistics.')
-    print()
-
-def nfsstat_command():
-    print_nfsstat_help(prog)
-
-def print_iostat_help(name):
-    print('usage: %s [ <interval> [ <count> ] ] [ <mount point> ] ' % name)
-    print()
-    print(' Version %s' % Mountstats_version)
-    print()
-    print(' iostat-like program to display NFS client per-mount statistics.')
-    print()
-    print(' The <interval> parameter specifies the amount of time in seconds between')
-    print(' each report.  The first report contains statistics for the time since each')
-    print(' file system was mounted.  Each subsequent report contains statistics')
-    print(' collected during the interval since the previous report.')
-    print()
-    print(' If the <count> parameter is specified, the value of <count> determines the')
-    print(' number of reports generated at <interval> seconds apart.  If the interval')
-    print(' parameter is specified without the <count> parameter, the command generates')
-    print(' reports continuously.')
-    print()
-    print(' If one or more <mount point> names are specified, statistics for only these')
-    print(' mount points will be displayed.  Otherwise, all NFS mount points on the')
-    print(' client are listed.')
-    print()
+def nfsstat_command(args):
+    return
 
 def print_iostat_summary(old, new, devices, time):
     for device in devices:
@@ -662,42 +584,11 @@  def print_iostat_summary(old, new, devices, time):
             diff_stats = stats.compare_iostats(old_stats)
             diff_stats.display_iostats(time)
 
-def iostat_command():
+def iostat_command(args):
     """iostat-like command for NFS mount points
     """
     mountstats = parse_stats_file('/proc/self/mountstats')
-    devices = []
-    interval_seen = False
-    count_seen = False
-
-    for arg in sys.argv:
-        if arg in ['-h', '--help', 'help', 'usage']:
-            print_iostat_help(prog)
-            return
-
-        if arg in ['-v', '--version', 'version']:
-            print('%s version %s' % (sys.argv[0], Mountstats_version))
-            return
-
-        if arg == sys.argv[0]:
-            continue
-
-        if arg in mountstats:
-            devices += [arg]
-        elif not interval_seen:
-            interval = int(arg)
-            if interval > 0:
-                interval_seen = True
-            else:
-                print('Illegal <interval> value')
-                return
-        elif not count_seen:
-            count = int(arg)
-            if count > 0:
-                count_seen = True
-            else:
-                print('Illegal <count> value')
-                return
+    devices = args.mountpoints
 
     # make certain devices contains only NFS mount points
     if len(devices) > 0:
@@ -721,44 +612,109 @@  def iostat_command():
     old_mountstats = None
     sample_time = 0
 
-    if not interval_seen:
+    if args.interval is None:
         print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
         return
 
-    if count_seen:
+    if args.count is not None:
+        count = args.count
         while count != 0:
             print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
             old_mountstats = mountstats
-            time.sleep(interval)
-            sample_time = interval
+            time.sleep(args.interval)
+            sample_time = args.interval
             mountstats = parse_stats_file('/proc/self/mountstats')
             count -= 1
     else: 
         while True:
             print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
             old_mountstats = mountstats
-            time.sleep(interval)
-            sample_time = interval
+            time.sleep(args.interval)
+            sample_time = args.interval
             mountstats = parse_stats_file('/proc/self/mountstats')
 
-#
-# Main
-#
-prog = os.path.basename(sys.argv[0])
+class ICMAction(argparse.Action):
+    """Custom action to deal with interval, count, and mountpoints.
+    """
+    def __call__(self, parser, namespace, values, option_string=None):
+        if namespace.mountpoints is None:
+            namespace.mountpoints = []
+        if values is None:
+            return
+        elif (type(values) == type([])):
+            for value in values:
+                self._handle_one(namespace, value)
+        else:
+            self._handle_one(namespace, values)
+
+    def _handle_one(self, namespace, value):
+        try:
+            intval = int(value)
+            self._handle_int(namespace, intval)
+        except ValueError:
+            namespace.mountpoints.append(value)
+
+    def _handle_int(self, namespace, value):
+        if namespace.interval is None:
+            namespace.interval = value
+        elif namespace.count is None:
+            namespace.count = value
+        else:
+            raise argparse.ArgumentError(self, "too many ints")
+
+def main():
+    parser = argparse.ArgumentParser(add_help=False)
+    parser.add_argument('-v', '--version', action='version', version='%(prog)s ' + Mountstats_version)
+
+    prog = os.path.basename(sys.argv[0])
 
-try:
     if prog == 'mountstats':
-        mountstats_command()
+        mountstats_parser = argparse.ArgumentParser(
+            description='Display NFS client per-mount statistics.',
+            parents=[parser])
+        group = mountstats_parser.add_mutually_exclusive_group()
+        group.add_argument('-n', '--nfs', action='store_true', dest='nfs_only',
+            help='Display only the NFS statistics')
+        group.add_argument('-r', '--rpc', action='store_true', dest='rpc_only',
+            help='Display only the RPC statistics')
+        mountstats_parser.add_argument('mountpoints', nargs='+', metavar='mountpoint',
+            help='Display statistics for this mountpoint. More than one may be specified.')
+        mountstats_parser.set_defaults(func=mountstats_command)
+        args = mountstats_parser.parse_args()
+
     elif prog == 'ms-nfsstat':
-        nfsstat_command()
+        nfsstat_parser = argparse.ArgumentParser(
+            description='nfsstat-like program that uses NFS client per-mount statistics.',
+            parents=[parser])
+        nfsstat_parser.set_defaults(func=nfsstat_command)
+        args = nfsstat_parser.parse_args()
+        nfsstat_parser.print_help()
+
     elif prog == 'ms-iostat':
-        iostat_command()
-    sys.stdout.close()
-    sys.stderr.close()
-except KeyboardInterrupt:
-    print('Caught ^C... exiting')
+        iostat_parser = argparse.ArgumentParser(
+            description='iostat-like program to display NFS client per-mount statistics.',
+            parents=[parser])
+        iostat_parser.add_argument('interval', nargs='?', action=ICMAction,
+            help='Number of seconds between reports. If absent, only one report will '
+                'be generated.')
+        iostat_parser.add_argument('count', nargs='?', action=ICMAction,
+            help='Number of reports generated at <interval> seconds apart. If absent, '
+                'reports will be generated continuously.')
+        iostat_parser.add_argument('mountpoints', nargs='*', action=ICMAction, metavar='mountpoint',
+            help='Display statsistics for this mountpoint. More than one may be specified. '
+                'If absent, statistics for all NFS mountpoints will be generated.')
+        iostat_parser.set_defaults(func=iostat_command)
+        args = iostat_parser.parse_args()
+    return args.func(args)
+
+try:
+    if __name__ == '__main__':
+        res = main()
+        sys.stdout.close()
+        sys.stderr.close()
+        sys.exit(res)
+except (SystemExit, KeyboardInterrupt, RuntimeError):
     sys.exit(1)
 except IOError:
     pass
 
-sys.exit(0)