Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 21 Jul 2012 00:05:46 +0000
From:      tzabal@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r239631 - soc2012/tzabal/server-side/akcrs-release/9.0.0/usr.sbin/crashreportd
Message-ID:  <20120721000546.253D01065670@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tzabal
Date: Sat Jul 21 00:05:45 2012
New Revision: 239631
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=239631

Log:
  Upload changes of crashreportd.

Modified:
  soc2012/tzabal/server-side/akcrs-release/9.0.0/usr.sbin/crashreportd/crashreportd.py

Modified: soc2012/tzabal/server-side/akcrs-release/9.0.0/usr.sbin/crashreportd/crashreportd.py
==============================================================================
--- soc2012/tzabal/server-side/akcrs-release/9.0.0/usr.sbin/crashreportd/crashreportd.py	Fri Jul 20 23:56:23 2012	(r239630)
+++ soc2012/tzabal/server-side/akcrs-release/9.0.0/usr.sbin/crashreportd/crashreportd.py	Sat Jul 21 00:05:45 2012	(r239631)
@@ -5,141 +5,211 @@
 import time
 import tarfile
 
+import argparse
+import logging
 
-# Check if the filename matches the pattern of a valid crash report name
-# Return False in failure and True in success
-def check_report_name(filename):
-    match_obj = re.match('^crashreport\.[A-Za-z0-9]{6}\.tar\.gz$', filename)
-
-    if not match_obj:
-        print "debug1"
-        return False
-    
-    return True
 
+# Module Variables
+_interval_time = 10
+_pid_file = '/var/run/crashreportd.pid'
+_crashreports_dir = '/var/spool/crashreports'
+_logging_file = ''
 
-# Check if the filename matches the pattern of a valid crash data name
-# Return False in failure and True in success
-def check_data_name(filename):
-    match_obj = re.match('^crashreport\.[A-Za-z0-9]{6}\.xml$', filename)
 
+def valid_report_name(report):
+    """Checks if the filename matches the pattern of a valid crash report name."""
+    filename = os.path.basename(report)
+    match_obj = re.match('^crashreport\.[A-Za-z0-9]{6}\.tar\.gz$', filename)
+    
     if not match_obj:
-        print "debug2"
-        return False
+        logging.info('Invalid crash report name: %s' % filename)
+        return
     
     return True
 
 
-# Check if the report is a tar.gz file and if it has only one file inside
-# with a valid name.
-# Return False in failure and True in success
-def check_report_contents(filename):
-    report = crashreports_dir + "/" + filename
-    
+def valid_report_type(report):
+    """Check if the report's file type matches the file type of a valid crash report."""
     if not tarfile.is_tarfile(report):
-        print "debug3"
-        return False
+        logging.info('Report %s is not a tar file.' % report)
+        return
     
     try:
         tarfile_obj = tarfile.open(report, 'r:gz')
-        contents_list = tarfile_obj.getnames()
     except ReadError:
-        print "debug4"
-        return False
+        logging.info('ReadError exception.')
+        return
     except CompressionError:
-        print "debug5"
-        return False
-    
-    if not len(contents_list) == 1:
-        print "debug6"
-        return False
-    
-    if not check_data_name(contents_list[0]):
-        print "debug7"
-        return False
+        logging.info('CompressionError exception')
+        return
+    finally:
+        tarfile_obj.close()
     
     return True
 
 
-def extract_report(filename):
-    if not os.path.isdir(extraction_dir):
-        print "debug11"
-        return False
+def valid_contents_number(report):
+    """Checks if the report contains the same number of files as a valid report."""
+    try:
+        tarfile_obj = tarfile.open(report, 'r:gz')
+    except ReadError:
+        logging.info('ReadError exception.')
+        return
+    except CompressionError:
+        logging.info('CompressionError exception')
+        return
+    else:
+        contents_list = tarfile_obj.getnames()
+        if not len(contents_list) == 1:
+            logging.info('Invalid number of files inside the crash report.')
+            return
+    finally:
+        tarfile_obj.close()
     
+    return True
+
+
+def valid_data_name(report):
+    """Checks if the filename matches the pattern of a valid crash data name."""
     try:
-        report = crashreports_dir + "/" + filename
         tarfile_obj = tarfile.open(report, 'r:gz')
-        tarfile_obj.extractall(extraction_dir);
     except ReadError:
-        print "debug12"
-        return False
+        logging.info('ReadError exception.')
+        return
     except CompressionError:
-        print "debug13"
-        return False
+        logging.info('CompressionError exception')
+        return
+    else:
+        contents_list = tarfile_obj.getnames()
+        match_obj = re.match('^crashreport\.[A-Za-z0-9]{6}\.xml$', contents_list[0])
+    finally:
+        tarfile_obj.close()
     
-    dirlist = os.listdir(extraction_dir)
-    if not len(dirlist) == 1:
-        print "debug14"
-        return False
+    if not match_obj:
+        logging.info('Invalid crash data name: %s' % contents_list[0])
+        return
     
-    data_name = dirlist[0]
-    #print "data_name: ", data_name
-
     return True
 
 
-# Container function that call all the check related functions
-# Return False in failure and True in success
-def check_report(filename):
-    if not check_report_name(filename):
-        print "debug8"
-        return False
+def discard_report(report):
+    """Discard a crash report from the system."""
+    os.remove(report)
+
+
+def check_report(report):
+    """Container function that calls all the functions related to validity."""
+    if not valid_report_name(report):
+        discard_report(report)
+        return
+    
+    if not valid_report_type(report):
+        discard_report(report)
+        return
     
-    if not check_report_contents(filename):
-        print "debug9"
-        return False
+    if not valid_contents_number(report):
+        discard_report(report)
+        return
     
-    if not extract_report(filename):
-        print "debug10"
-        return False
+    if not valid_data_name(report):
+        discard_report(report)
+        return
     
     return True
 
 
-# Create the Process ID file that contains the PID of crashreportd.
-# It used from the rc.d script to stop the program normally.
 def create_pid_file():
+    """Creates the Process ID file that contains the PID of crashreportd.
+    
+    It used from the rc.d script to stop the program normally.
+    """
     pid = os.getpid()
-
-    pid_file = '/var/run/crashreportd.pid'
     try:
-        file_obj = open(pid_file, 'w')
+        file_obj = open(_pid_file, 'w')
         file_obj.write(str(pid))
         file_obj.close()
     except IOError:
-        return False
+        return
     finally:
         file_obj.close()
     
     return True
 
 
+def parse_arguments():
+    """Parse the command line arguments provided."""
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-d', help='the directory where crash reports arrive in the system', dest='crashreports_dir')
+    parser.add_argument('-p', help='the file that stores the process id of crashreportd', dest='pid_file')
+    parser.add_argument('-t', type=int, help='the minimum delay between two checks of the crash reports directory', dest='interval_time')
+    parser.add_argument('-l', help='the file that various log messages will be stored (enables logging)', dest='logging_file')
+    args = parser.parse_args()
+    
+    if args.crashreports_dir:
+        global _crashreports_dir
+        _crashreports_dir = args.crashreports_dir
+    if args.pid_file:
+        global _pid_file
+        _pid_file = args.pid_file
+    if args.interval_time:
+        global _interval_time
+        _interval_time = args.interval_time
+    if args.logging_file:
+        global _logging_file
+        _logging_file = args.logging_file
+
+
+def log():
+    """Turns on or off the logging facility."""
+    global _logging_file
+    if _logging_file:
+        logging.basicConfig(level=logging.DEBUG, filename=_logging_file,
+                            format='%(asctime)s %(funcName)s() %(levelname)s: %(message)s',
+                            datefmt='%Y-%m-%d %H:%M:%S')
+
+
 def main():
-    # The infinite loop of the daemon
-    interval = 10
-    crashreports_dir = '/var/spool/crashreports'
-    extraction_dir = '/tmp/crashreports'
-    counter = 1
+    """The infinite loop of the daemon.
+    
+    It is the starting point of the program when it is invoked directly. Here
+    lives the infinite loop that checks the directory that crash reports arrive
+    in the server. For every new crash report, a number of actions are executed.
+    """
+    parse_arguments()
+    log()
     create_pid_file()
     while True:
-        print "== Pass: " + counter + " =="
-        dirlist = os.listdir(crashreports_dir)
+        dirlist = os.listdir(_crashreports_dir)
         for filename in dirlist:
-            print "Report: " + filename
-            check_report(filename)
-        counter += 1
-        time.sleep(interval)
+            report = _crashreports_dir + '/' + filename
+            check_report(report)
+        time.sleep(_interval_time)
 
 
 if __name__ == '__main__':
-    main()
\ No newline at end of file
+    main()
+    
+#def extract_report(filename):
+#    if not os.path.isdir(extraction_dir):
+#        logging.debug()
+#        return False
+#    
+#    try:
+#        tarfile_obj = tarfile.open(report, 'r:gz')
+#        tarfile_obj.extractall(extraction_dir);
+#        except ReadError:
+#        logging.debug()
+#        return
+#    except CompressionError:
+#       logging.debug()
+#       return
+#    
+#    dirlist = os.listdir(extraction_dir)
+#    if not len(dirlist) == 1:
+#       logging.debug()
+#       return False
+#    
+#    data_name = dirlist[0]
+#    #print "data_name: ", data_name
+#    
+#    return True
\ No newline at end of file



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120721000546.253D01065670>