Refactor to support OVS insted of prepopulate tagged interfaces and linux briges
[osm/openvim.git] / openvimd.py
index 220c90a..573ce27 100755 (executable)
@@ -3,7 +3,7 @@
 
 ##
 # Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
-# This file is part of openmano
+# This file is part of openvim
 # All Rights Reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -30,12 +30,12 @@ and host controllers
 
 __author__="Alfonso Tierno"
 __date__ ="$10-jul-2014 12:07:15$"
-__version__="0.4.6-r466"
-version_date="Jul 2016"
-database_version="0.7"      #expected database schema version
+__version__="0.5.0-r506"
+version_date="Oct 2016"
+database_version="0.8"      #expected database schema version
 
 import httpserver
-from utils import auxiliary_functions as af
+import auxiliary_functions as af
 import sys
 import getopt
 import time
@@ -49,12 +49,17 @@ import openflow_thread as oft
 import threading
 from vim_schema import config_schema
 import logging
+import logging.handlers as log_handlers
 import imp
+import socket
 
 global config_dic
 global logger
 logger = logging.getLogger('vim')
 
+class LoadConfigurationException(Exception):
+    pass
+
 def load_configuration(configuration_file):
     default_tokens ={'http_port':9080, 'http_host':'localhost', 
                      'of_controller_nets_with_same_vlan':True,
@@ -64,6 +69,8 @@ def load_configuration(configuration_file):
                      'log_level': "DEBUG",
                      'log_level_db': "ERROR",
                      'log_level_of': 'ERROR',
+                     'bridge_ifaces': {},
+                     'network_type': 'ovs',
             }
     try:
         #First load configuration from configuration file
@@ -114,20 +121,31 @@ def create_database_connection(config_dic):
 def usage():
     print "Usage: ", sys.argv[0], "[options]"
     print "      -v|--version: prints current version"
-    print "      -c|--config [configuration_file]: loads the configuration file (default: openvimd.cfg)"
+    print "      -c|--config FILE: loads the configuration file (default: openvimd.cfg)"
     print "      -h|--help: shows this help"
-    print "      -p|--port [port_number]: changes port number and overrides the port number in the configuration file (default: 9090)"
-    print "      -P|--adminport [port_number]: changes admin port number and overrides the port number in the configuration file (default: 9095)"
+    print "      -p|--port PORT: changes port number and overrides the port number in the configuration file (default: 908)"
+    print "      -P|--adminport PORT: changes admin port number and overrides the port number in the configuration file (default: not listen)"
+    print "      --dbname NAME: changes db_name and overrides the db_name in the configuration file"
+    #print( "      --log-socket-host HOST: send logs to this host")
+    #print( "      --log-socket-port PORT: send logs using this port (default: 9022)")
+    print( "      --log-file FILE: send logs to this file")
     return
 
 
 if __name__=="__main__":
+    hostname = socket.gethostname()
     #streamformat = "%(levelname)s (%(module)s:%(lineno)d) %(message)s"
-    streamformat = "%(asctime)s %(name)s %(levelname)s: %(message)s"
-    logging.basicConfig(format=streamformat, level= logging.DEBUG)
+    log_formatter_complete = logging.Formatter(
+        '%(asctime)s.%(msecs)03d00Z[{host}@openmanod] %(filename)s:%(lineno)s severity:%(levelname)s logger:%(name)s log:%(message)s'.format(host=hostname),
+        datefmt='%Y-%m-%dT%H:%M:%S',
+    )
+    log_format_simple =  "%(asctime)s %(levelname)s  %(name)s %(filename)s:%(lineno)s %(message)s"
+    log_formatter_simple = logging.Formatter(log_format_simple, datefmt='%Y-%m-%dT%H:%M:%S')
+    logging.basicConfig(format=log_format_simple, level= logging.DEBUG)
+    logger = logging.getLogger('openmano')
     logger.setLevel(logging.DEBUG)
     try:
-        opts, args = getopt.getopt(sys.argv[1:], "hvc:p:P:", ["config", "help", "version", "port", "adminport"])
+        opts, args = getopt.getopt(sys.argv[1:], "hvc:p:P:", ["config=", "help", "version", "port=", "adminport=", "log-file=", "dbname="])
     except getopt.GetoptError, err:
         # print help information and exit:
         logger.error("%s. Type -h for help", err) # will print something like "option -a not recognized"
@@ -137,6 +155,8 @@ if __name__=="__main__":
     port=None
     port_admin = None
     config_file = 'openvimd.cfg'
+    log_file = None
+    db_name = None
 
     for o, a in opts:
         if o in ("-v", "--version"):
@@ -152,6 +172,10 @@ if __name__=="__main__":
             port = a
         elif o in ("-P", "--adminport"):
             port_admin = a
+        elif o in ("-P", "--dbname"):
+            db_name = a
+        elif o == "--log-file":
+            log_file = a
         else:
             assert False, "Unhandled option"
 
@@ -164,11 +188,27 @@ if __name__=="__main__":
             logger.error(config_dic)
             config_dic={}
             exit(-1)
-        logging.basicConfig(level = getattr(logging, config_dic['log_level']))
+        if log_file:
+            try:
+                file_handler= logging.handlers.RotatingFileHandler(log_file, maxBytes=100e6, backupCount=9, delay=0)
+                file_handler.setFormatter(log_formatter_simple)
+                logger.addHandler(file_handler)
+                #logger.debug("moving logs to '%s'", global_config["log_file"])
+                #remove initial stream handler
+                logging.root.removeHandler(logging.root.handlers[0])
+                print ("logging on '{}'".format(log_file))
+            except IOError as e:
+                raise LoadConfigurationException("Cannot open logging file '{}': {}. Check folder exist and permissions".format(log_file, str(e)) ) 
+
         logger.setLevel(getattr(logging, config_dic['log_level']))
+        logger.critical("Starting openvim server command: '%s'", sys.argv[0])
         #override parameters obtained by command line
-        if port is not None: config_dic['http_port'] = port
-        if port_admin is not None: config_dic['http_admin_port'] = port_admin
+        if port: 
+            config_dic['http_port'] = port
+        if port_admin:
+            config_dic['http_admin_port'] = port_admin
+        if db_name: 
+            config_dic['db_name'] = db_name
         
         #check mode
         if 'mode' not in config_dic:
@@ -176,7 +216,8 @@ if __name__=="__main__":
             #allow backward compatibility of test_mode option
             if 'test_mode' in config_dic and config_dic['test_mode']==True:
                 config_dic['mode'] = 'test' 
-        if config_dic['mode'] == 'development' and ( 'development_bridge' not in config_dic or config_dic['development_bridge'] not in config_dic.get("bridge_ifaces",None) ):
+        if config_dic['mode'] == 'development' and config_dic['network_type'] == 'bridge' and \
+                ( 'development_bridge' not in config_dic or config_dic['development_bridge'] not in config_dic.get("bridge_ifaces",None) ):
             logger.error("'%s' is not a valid 'development_bridge', not one of the 'bridge_ifaces'", config_file)
             exit(-1)
             
@@ -337,6 +378,15 @@ if __name__=="__main__":
 
     except (KeyboardInterrupt, SystemExit):
         pass
+    except SystemExit:
+        pass
+    except getopt.GetoptError as e:
+        logger.critical(str(e)) # will print something like "option -a not recognized"
+        #usage()
+        exit(-1)
+    except LoadConfigurationException as e:
+        logger.critical(str(e))
+        exit(-1)
 
     logger.info('Exiting openvimd')
     threads = config_dic.get('host_threads', {})