F:/thesis_austausch/dissertation/code_docu_doxygen/Server/start_server.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 '''
00003 This module is the log file parser server start script.
00004 
00005 Reading University
00006 MSc in Network Centered Computing
00007 a.weise - a.weise@reading.ac.uk - December 2005
00008 '''
00009 
00010 import server_classes
00011 import sys, os, time, getopt
00012 import socket
00013 import fcntl
00014 import struct
00015 from utils_server import LoadConfig, check_ip, usage_exit
00016 
00017 class WorkingServer:
00018     '''
00019     This is the main class for the server.
00020     '''
00021     
00022     def __init__(self, config_data, config_dir, verb):
00023         '''
00024         Constructor
00025         '''
00026         self._verbose = verb
00027         config = config_data
00028         self._workingpath = os.getcwd()
00029 
00030         self._server_certificate = config.get("files.server_certificate")
00031         self._server_certificate_path = config.get("path.path_server_certificate")
00032         self._server_certificate_path = self._server_certificate_path.rstrip("/")
00033         if(self._server_certificate_path == '' or self._server_certificate_path == None):
00034             self._server_certificate_path = self._workingpath
00035         else:
00036             self._server_certificate = self._server_certificate.strip()
00037             if (-1 != self._server_certificate_path.find("/", 0, 1)):
00038                 # first character "/"
00039                 pass
00040             else:
00041                 self._server_certificate_path = self._workingpath+"/"+self._server_certificate_path
00042             
00043         self._server_ca = config.get("files.server_ca")
00044         self._server_ca_path = config.get("path.path_server_ca")
00045         self._server_ca_path = self._server_ca_path.rstrip("/")
00046         if(self._server_ca_path == '' or self._server_ca_path == None):
00047             self._server_ca_path = self._workingpath
00048         else:
00049             self._server_ca = self._server_ca.strip()
00050             if (-1 != self._server_ca_path.find("/", 0, 1)):
00051                 # first character "/"
00052                 pass
00053             else:
00054                 self._server_ca_path = self._workingpath+"/"+self._server_ca_path        
00055             
00056         self._srb_log = config.get("files.srb_log")
00057         self._srb_log_path = config.get("path.path_srb_log")
00058         self._srb_log_path = self._srb_log_path.rstrip("/")
00059         if(self._srb_log_path == '' or self._srb_log_path == None):
00060             self._srb_log_path = self._workingpath
00061         else:
00062             self._srb_log = self._srb_log.strip()
00063             if (-1 != self._srb_log_path.find("/", 0, 1)):
00064                 # first character "/"
00065                 pass
00066             else:
00067                 self._srb_log_path = self._workingpath+"/"+self._srb_log_path
00068                 
00069         self._gz_path = config.get("path.path_gz")
00070         self._gz_path = self._gz_path.rstrip("/")
00071         if(self._gz_path == '' or self._gz_path == None):
00072             self._gz_path = self._workingpath
00073         else:
00074             if (-1 != self._gz_path.find("/", 0, 1)):
00075                 # first character "/"
00076                 pass
00077             else:
00078                 self._gz_path = self._workingpath+"/"+self._gz_path                
00079                 
00080         self._keyword_name = config.get("files.keyword")
00081         self._keyword_path = config.get("path.path_keyword")
00082         self._keyword_path = self._keyword_path.rstrip("/")
00083         if(self._keyword_path == '' or self._keyword_path == None):
00084             self._keyword_path = self._workingpath
00085         else:
00086             self._keyword_name = self._keyword_name.strip()
00087             if (-1 != self._keyword_path.find("/", 0, 1)):
00088                 # first character "/"
00089                 pass
00090             else:
00091                 self._keyword_path = self._workingpath+"/"+self._keyword_path               
00092         
00093         self._xml_file = "client_log.xml"
00094         self._xml_file_path = os.getcwd()+"/xml_client"
00095 
00096         try:
00097             self._interval = int(config.get("misc.minute"))
00098         except ValueError:
00099             print "Please check the configuration in the config file (section: misc, item: minute). It should have the following pattern:\nminute = <int>"
00100             os._exit(-1)
00101         try:
00102             self._port = int(config.get("misc.port"))
00103         except ValueError:
00104             print "Please check the configuration in the config file (section: misc, item: port). It should have the following pattern:\nport = <int>"
00105             os._exit(-1)            
00106         if (self._port < 1024 or self._port > 50001):
00107             print "A server port is out of range. \nPlease check the configuration file and make sure the server port lies between 1025 (inclusive) and 50000 (inclusive)!\n\n"
00108             os._exit(-1)        
00109 
00110          #check if the configuration if correct
00111         if(0 == os.path.exists(self._server_certificate_path+"/"+self._server_certificate)):
00112             print "Could not locate server certifiate under %s !\nMaybe change configuration file and try again!\n\n" % self._server_certificate_path
00113             os._exit(-1)
00114 
00115         if(0 == os.path.exists(self._server_ca_path+"/"+self._server_ca)):
00116             print "Could not locate server ca certificate under %s !\nMaybe change configuration file and try again!\n\n" % self._server_ca_path
00117             os._exit(-1)
00118         
00119         if(0 == os.access((self._srb_log_path+"/"+self._srb_log), 4)):    # 4 R_OK
00120             print "Could not access SRB server log file under %s !\nMaybe change configuration file and try again!\n\n" % self._srb_log_path
00121             os._exit(-1)
00122         
00123         if(0 == os.path.exists(self._xml_file_path)):
00124             print "Creating path \"%s\"\n\n" % self._xml_file_path
00125             os.mkdir(self._xml_file_path)
00126 
00127         self._share = server_classes.Mutex()
00128         
00129         self._keyword = server_classes.get_keywords(self._keyword_path+"/"+self._keyword_name)
00130         
00131         error = config.get("misc.ignore_error")
00132         
00133         self._ip = config.get("misc.interface")
00134 
00135         error = error.strip()
00136         error = error.strip(",")
00137         self._ignore_error = error.split(",")
00138         for i in range(len(self._ignore_error)):
00139             if self._ignore_error[i] != '':
00140                 try:
00141                     self._ignore_error[i] = int(self._ignore_error[i].strip())
00142                 except ValueError:
00143                     print "Please check the \"ignore_error\" list in the config file (section: misc). It should have the following pattern (comma separeted list of integer):\nignore_error = <int>,<int> "
00144                     os._exit(-1)
00145             else:
00146                 del self._ignore_error[i]
00147 
00148         self._configfile = config_dir
00149         
00150         self._rpc = server_classes.RPC(self._verbose, self._share, self._configfile, self._interval, self._keyword_path, self._keyword_name, self._xml_file_path)
00151                 
00152     def establish_connection(self):
00153         '''
00154         establish a working connection using MySSLServer
00155         '''
00156         cert = self._server_certificate_path+"/"+self._server_certificate
00157         ca = self._server_ca_path+"/"+self._server_ca
00158         self._serverobject = server_classes.My_SSL_Server(cert, ca, self._verbose)
00159         ip = self.get_ip_address(self._ip)
00160         if (0 == check_ip(ip)):
00161             self._serv = self._serverobject.start_server(ip, self._port)
00162         else:
00163             print "Could not start the server. (IP: \"%s\")" % ip
00164             os._exit(-1)
00165 
00166         # start thread for parsing log file
00167         workerthread = server_classes.MyParserThread(self._share, self._interval, self._gz_path, self._srb_log_path, self._srb_log, self._keyword, self._ignore_error, self._xml_file_path, self._xml_file, self._configfile, (self._keyword_path+"/"+self._keyword_name), self._verbose)
00168         workerthread.setName("parser")
00169         workerthread.start()
00170         print "Started!\n\n"
00171         
00172     def get_ip_address(self, network_interface):
00173         '''
00174         Uses the Linux SIOCGIFADDR ioctl to find the IP address associated with a network interface, given the name of that interface, e.g. "eth0".
00175         
00176         source: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/439094
00177         
00178         modified by a.weise (December 2005)
00179         '''
00180         s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
00181         try:
00182             ip = socket.inet_ntoa(fcntl.ioctl(
00183                 s.fileno(),
00184                 0x8915,  # SIOCGIFADDR
00185                 struct.pack('256s', network_interface[:15])
00186             )[20:24])
00187             return ip
00188         except IOError, e:
00189             return e
00190 
00191     def register_functions(self):
00192         '''
00193         register all the rpc - functions
00194         '''
00195         self._serv.register_function(self._rpc.rpc_stop_server, 'stop_server')
00196         self._serv.register_function(self._rpc.rpc_status, 'rpc_status')
00197         self._serv.register_function(self._rpc.rpc_disable_rpc_calls, 'disable_rpc_calls')
00198         self._serv.register_function(self._rpc.rpc_enable_rpc_calls, 'enable_rpc_calls')
00199         self._serv.register_function(self._rpc.rpc_get_my_xml_file, 'get_my_xml_file')
00200         self._serv.register_function(self._rpc.rpc_get_file_list, 'get_file_list')
00201         self._serv.register_function(self._rpc.rpc_update_configuration, 'rpc_update_configuration')
00202         self._serv.register_function(self._rpc.rpc_update_keyword_file, 'rpc_update_keyword_file')
00203         self._serv.register_function(self._rpc.rpc_check_availabitity, 'rpc_check_availabitity')
00204         self._serv.register_function(self._rpc.rpc_interval_status, 'rpc_interval_status')
00205         
00206     def run_server(self):
00207         '''
00208         handle all client requests
00209         '''
00210         try:
00211             #serv.serve_forever()
00212             if self._verbose == 1:
00213                 print "\nSimple SSL XML RPC Server is running ....\n"
00214             while (1):
00215                 if self._verbose == 1:
00216                     print "%s -> waiting for request ...." % time.ctime()
00217                 self._serv.handle_request(self._serv)
00218         except KeyboardInterrupt:
00219             # if the server is not running as a daemon shutdown with Ctrl+c is possible
00220             if self._verbose == 1:
00221                 sys.stdout.write("\n\nShutdown !!!\n\n")
00222             
00223             command = "./stop_server"
00224             os.system(command)
00225 
00226         
00227 #############################################################################
00228 
00229 
00230 def daemonize(verbose, stdout = '/dev/null', stderr = None, stdin = '/dev/null', pidfile = None, startmsg = 'Server daemon started with pid %s'):
00231 
00232     '''
00233     This function creates a daemon by forking the current process. The parameters stdin, stdout, and stderr are file names which substitute the standard err-, in-, out- output. This parameters are optional and point normally to /dev/null. Note that stderr is opened unbuffered, so if it shares a file with stdout then interleaved output may not appear in the order that you expect.
00234     
00235     source: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012
00236     modified by a.weise November 2005
00237     '''
00238 
00239     # first fork => fork creates first child-process
00240     try: 
00241         pid = os.fork() 
00242         if (pid > 0):
00243             sys.exit(0) # close first parent-process
00244     except OSError, e: 
00245         sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
00246         sys.exit(1)
00247 
00248     os.umask(0) 
00249     os.setsid() 
00250 
00251     # second fork
00252     try: 
00253         pid = os.fork() 
00254         if (pid > 0):
00255             sys.exit(0) # close second parent-process
00256     except OSError, e: 
00257 
00258         sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
00259         sys.exit(1)
00260 
00261     # open standard in and out and print standard message
00262     if (not stderr):# if not stderr given => take stdout-path
00263         stderr = stdout
00264 
00265     if verbose == 1:
00266         si = file(stdin, 'r')
00267         so = file(stdout, 'w+') # w -> overwrite old log content
00268         se = file(stderr, 'w+', 0)
00269         pid = str(os.getpid())
00270         sys.stderr.write("\n%s\n" % startmsg % pid)
00271         sys.stderr.flush()
00272         if pidfile:
00273             file(pidfile,'w+').write("%s\n" % pid)
00274 
00275         # redirect standard in and out to files
00276         os.dup2(si.fileno(), sys.stdin.fileno())
00277         os.dup2(so.fileno(), sys.stdout.fileno())
00278         os.dup2(se.fileno(), sys.stderr.fileno())
00279 
00280 ###################################################################
00281 
00282 def start():
00283     
00284     '''
00285     START THE APPLICATION
00286     '''
00287     configfile = ""
00288     verbose = 0
00289     daemon = 0
00290     
00291     try:
00292         opts, args = getopt.getopt(sys.argv[1:], 'c:vhd', ['config=', 'verbose', 'help', 'daemon'])
00293         for opt, value in opts:
00294             if opt in ('-h','--help'):
00295                 msg = "\n\t\t-----------   Help   ----------\n\n\n"\
00296                       "-c or --config\t->  defines config file, if no config file given, default values are used\n"\
00297                       "-v or --verbose\t->  activates printing of messages [debug option]\n"\
00298                       "-d or --daemon\t->  daemonize the server\n"\
00299                       "-h or --help\t->  print this help\n\n"
00300                 usage_exit(sys.argv[0], msg)
00301             if opt in ('-c','--config'):
00302                 value = value.replace("=", "")
00303                 configfile = os.getcwd()+"/"+value
00304             if opt in ('-v','--verbose'):
00305                 verbose = 1
00306             if opt in ('-d', '--daemon'):
00307                 daemon = 1                
00308     except getopt.error, e:
00309         usage_exit(sys.argv[0], e)
00310         
00311     # load config file or default values
00312     if (configfile != ""):
00313         # check if file exists
00314         if(1 == os.path.exists(configfile)):
00315             config = LoadConfig(configfile)
00316         else:
00317             # if file NOT exists terminate program
00318             print "Sorry, the given file does NOT exist !\nPlease try again!\n\n"
00319             os._exit(-1)
00320     else:
00321         msg = "\nNo configuration file spezified !\n"
00322         usage_exit(sys.argv[0], msg)
00323 
00324     print "\n\n--------------------- SRB LOG FILE PARSER [ SERVER ] ------------------ \n\n"
00325     print "Starting ..."
00326 
00327     worker = WorkingServer(config, configfile, verbose)
00328 
00329     if daemon == 1:
00330         if verbose == 1:
00331             #if verbose then write messages in log file
00332             daemonize(verbose, stdout = 'daemonize.log')
00333         else:
00334             # quit mode
00335             daemonize(verbose)
00336     else:
00337         pass
00338     
00339     worker.establish_connection()
00340     worker.register_functions()
00341     worker.run_server()
00342 
00343 
00344 if __name__ == '__main__':
00345 
00346     start()
00347 
00348 
00349 
00350 
00351 
00352 

Generated on Sun Mar 5 18:06:11 2006 for Server by  doxygen 1.4.6-NO