#!/usr/bin/env python """ core-daemon: the CORE daemon is a server process that receives CORE API messages and instantiates emulated nodes and networks within the kernel. Various message handlers are defined and some support for sending messages. """ import ConfigParser import logging import optparse import sys import threading import time from core import constants from core import enumerations from core import load_logging_config from core.corehandlers import CoreHandler, CoreUdpHandler from core.coreserver import CoreServer, CoreUdpServer from core.misc.utils import close_onexec load_logging_config() def banner(): """ Output the program banner printed to the terminal or log file. :return: nothing """ logging.info("CORE daemon v.%s started %s", constants.COREDPY_VERSION, time.ctime()) def start_udp(mainserver, server_address): """ Start a thread running a UDP server on the same host,port for connectionless requests. :param CoreServer mainserver: main core tcp server to piggy back off of :param server_address: :return: CoreUdpServer """ mainserver.udpserver = CoreUdpServer(server_address, CoreUdpHandler, mainserver) mainserver.udpthread = threading.Thread(target=mainserver.udpserver.start) mainserver.udpthread.daemon = True mainserver.udpthread.start() def cored(cfg, use_ovs): """ Start the CoreServer object and enter the server loop. :param dict cfg: core configuration :param bool use_ovs: flag to determine if ovs nodes should be used :return: nothing """ host = cfg["listenaddr"] port = int(cfg["port"]) if host == "" or host is None: host = "localhost" try: address = (host, port) server = CoreServer(address, CoreHandler, cfg) if use_ovs: from core.netns.openvswitch import OVS_NODES server.coreemu.update_nodes(OVS_NODES) except: logging.exception("error starting main server on: %s:%s", host, port) sys.exit(1) # start udp server start_udp(server, address) # close handlers close_onexec(server.fileno()) logging.info("tcp/udp servers started, listening on: %s:%s", host, port) server.serve_forever() def get_merged_config(filename): """ Return a configuration after merging config file and command-line arguments. :param str filename: file name to merge configuration settings with :return: merged configuration :rtype: dict """ # these are the defaults used in the config file defaults = { "port": "%d" % enumerations.CORE_API_PORT, "listenaddr": "localhost", "xmlfilever": "1.0", "numthreads": "1", } usagestr = "usage: %prog [-h] [options] [args]\n\n" + \ "CORE daemon v.%s instantiates Linux network namespace " \ "nodes." % constants.COREDPY_VERSION parser = optparse.OptionParser(usage=usagestr) parser.add_option("-f", "--configfile", dest="configfile", type="string", help="read config from specified file; default = %s" % filename) parser.add_option("-p", "--port", dest="port", type=int, help="port number to listen on; default = %s" % defaults["port"]) parser.add_option("-t", "--numthreads", dest="numthreads", type=int, help="number of server threads; default = %s" % defaults["numthreads"]) # parse command line options options, args = parser.parse_args() # read the config file if options.configfile is not None: filename = options.configfile del options.configfile cfg = ConfigParser.SafeConfigParser(defaults) cfg.read(filename) section = "core-daemon" if not cfg.has_section(section): cfg.add_section(section) # merge command line with config file for opt in options.__dict__: val = options.__dict__[opt] if val is not None: cfg.set(section, opt, val.__str__()) return dict(cfg.items(section)), args def main(): """ Main program startup. :return: nothing """ # get a configuration merged from config file and command-line arguments cfg, args = get_merged_config("%s/core.conf" % constants.CORE_CONF_DIR) for a in args: logging.error("ignoring command line argument: %s", a) banner() # check if ovs flag was provided use_ovs = len(sys.argv) == 2 and sys.argv[1] == "ovs" try: cored(cfg, use_ovs) except KeyboardInterrupt: logging.info("keyboard interrupt, stopping core daemon") sys.exit(0) if __name__ == "__main__": main()