def getSystemInformation(): """ Returns some system information, regarding the hardware, os, and the application (the server) @since: 1.0 @rtype: a dict[string] of string @returns: a dict with some supposedly interesting info """ import platform ret = {} # Platform ret['machine'] = platform.machine() ret['node'] = platform.node() ret['system'] = platform.system() ret['architecture'] = platform.architecture()[0] ret['release'] = platform.system() ret['python-version'] = platform.python_version() # Physical # TODO # Application (low-level) ret['ws-version'] = Versions.getWsVersion() ret['xc-version'] = Versions.getXcVersion() ret['server-version'] = Versions.getServerVersion() return ret
def kill(self, channel, agentUri): req = Messages.Request(method = "KILL", uri = agentUri, protocol = "XA", version = Versions.getXaVersion()) resp = self.executeRequest(channel, req) if not resp: raise XaException("Timeout while waiting for KILL response from agent %s" % req.getUri()) if resp.getStatusCode() != 200: raise XaException("KILL from agent %s returned %d %s" % (req.getUri(), resp.getStatusCode(), resp.getReasonPhrase()))
def _notify(self, path, backendType, event): """ We notify the filesystem:/directory URI subscribers whenever a new entry is created/deleted or a file in this dir is modified. WARNING/FIXME: the application type may not be correctly identified in all case, especially when creating a package forlder, as the package.xml is created after the directory... """ if path.endswith('/'): path = path[:-1] objectpath, objectname = os.path.split(path) if not objectpath: objectpath = '/' applicationType = self.getApplicationType(objectname, objectpath, backendType) getLogger().debug("notifying fs change: %s:%s %s (%s)" % (objectpath, objectname, event, applicationType)) if applicationType: uri = 'filesystem:%s' % objectpath notification = Messages.Notification("FILE-EVENT", uri, "Xc", Versions.getXcVersion()) notification.setHeader('File-Type', applicationType) notification.setHeader('File-Path', objectpath) notification.setHeader('File-Name', objectname) notification.setHeader('Reason', event) EventManager.instance().dispatchNotification(notification)
def triUnmap(self, channel, uri): """ Constructs a reset request, execute it. """ req = Messages.Request(method = "TRI-UNMAP", uri = uri, protocol = "XA", version = Versions.getXaVersion()) resp = self.executeRequest(channel, req) if not resp: raise XaException("Timeout while waiting for TRI-UNMAP response from probe %s" % req.getUri()) if resp.getStatusCode() != 200: raise XaException("TRI-UNMAP from probe %s returned %d %s" % (req.getUri(), resp.getStatusCode(), resp.getReasonPhrase()))
def getXcVersion(): """ Returns the Xc interface API version. Format A.B: - A += 1 if not backward compatible. - B += 1 if enriched API, but still backward compatible. @rtype: string @returns: the Xc API version """ return Versions.getXcVersion()
def __init__(self, db): ''' General description: This function initializes the database variables and \ index to refer in functions. ''' DBUtil.__init__(self, db) self.collection = db.Tool self.versionsDB = Versions.Versions(db) self.tagDB = Tags.Tags() # indexes self.collection.create_index([('name', ASCENDING)], unique=True) self.collection.create_index([('tag', ASCENDING)], unique=False)
def getVersion(): """ Returns the Testerman Server implementation version. Format A.B.C: - A = main version - B = new features - C = fixes / small enhancements @rtype: string @returns: the server implementation version """ return Versions.getServerVersion()
def __init__(self, db): ''' General description: This function initializes the database variables and \ index to refer in functions. ''' DBUtil.__init__(self, db) self.collection = db.DeploymentRequest self.machineDB = Machine.Machine(db) self.versionsDB = Versions.Versions(db) self.toolDB = Tool.Tool(db) self.passHelper = PasswordHelper.PasswordHelper(key) self.statedb = State.State(db)
def initialise(sortProject=None, dbHost=None, dbName=None, dbUser=None, dbPass=None, outputDir=None, outputFilePath=None, charset=None): """ Initialise DB connection and read the whole darn anatomy database into memory. """ if dbHost != None: # Only create connection if connection params provided. # If not provided then we assume we already have an open # connection. DbAccess.initialise( dbHost = dbHost, dbName = dbName, dbUser = dbUser, dbPass = dbPass, outputDir = outputDir, outputFilePath = outputFilePath, charset = charset) # Read in every table we care about. # Base tables Oids.initialise() Versions.initialise() Stages.initialise() Nodes.initialise() TimedNodes.initialise() Relationships.initialise(sortProject) Synonyms.initialise() Perspectives.initialise() PerspectiveAmbits.initialise() # Derived tables RelationshipsTransitive.initialise() PartOfs.initialise() PartOfPerspectives.initialise() connectTheDots() return None
def __init__(self, db): ''' General description : This function initializes the database variables and \ index to refer in functions. ''' DBUtil.__init__(self, db) self.collection = db.DeploymentRequestGroup self.deploymentRequestDb = DeploymentRequest.DeploymentRequest(db) self.machineDB = Machine.Machine(db) self.versionsDB = Versions.Versions(db) self.toolDB = Tool.Tool(db) self.deploymentUnitDB = DeploymentUnit.DeploymentUnit() self.deploymentRequestDbCollection = db.DeploymentRequest self.statedb = State.State(db)
def _notifyFileRenamed(self, filename, newName): """ Filename is the path+name to the previous name, before renaming. """ if filename.endswith('/'): filename = filename[:-1] objectpath, objectname = os.path.split(filename) if not objectpath: objectpath = '/' applicationType = self.getApplicationType(newName, objectpath, 'file') if applicationType: uri = 'filesystem:%s' % objectpath notification = Messages.Notification("FILE-EVENT", uri, "Xc", Versions.getXcVersion()) notification.setHeader('File-Type', applicationType) notification.setHeader('File-Path', objectpath) notification.setHeader('File-Name', objectname) notification.setHeader('Reason', 'renamed') notification.setHeader('File-New-Name', newName) EventManager.instance().dispatchNotification(notification)
def __init__(self, controller, iaAddress): Nodes.ListeningNode.__init__(self, "TACS/Ia", "IaServer/%s" % Versions.getAgentControllerVersion()) self._controller = controller self.initialize(iaAddress)
def undeploy(self, channel, agentUri, probeName): req = Messages.Request(method = "UNDEPLOY", uri = agentUri, protocol = "XA", version = Versions.getXaVersion()) req.setApplicationBody({'probe-name': probeName}) resp = self.executeRequest(channel, req) if not resp: raise XaException("Timeout while waiting for UNDEPLOY response from agent %s" % req.getUri()) if resp.getStatusCode() != 200: raise XaException("UNDEPLOY from agent %s returned %d %s" % (req.getUri(), resp.getStatusCode(), resp.getReasonPhrase()))
def main(): server_root = os.path.abspath(os.path.dirname(sys.modules[globals()['__name__']].__file__)) testerman_home = os.path.abspath("%s/.." % server_root) # Set transient values cm.set_transient("testerman.testerman_home", testerman_home) cm.set_transient("ts.server_root", server_root) # standard paths within the document root. cm.set_transient("constants.repository", "repository") cm.set_transient("constants.archives", "archives") cm.set_transient("constants.modules", "modules") cm.set_transient("constants.components", "components") cm.set_transient("ts.version", Versions.getServerVersion()) # Register persistent variables expandPath = lambda x: x and os.path.abspath(os.path.expandvars(os.path.expanduser(x))) splitPaths = lambda paths: [ expandPath(x) for x in paths.split(',')] cm.register("interface.ws.ip", "0.0.0.0") cm.register("interface.ws.port", 8080) cm.register("interface.xc.ip", "0.0.0.0") cm.register("interface.xc.port", 8081) cm.register("interface.il.ip", "0.0.0.0") cm.register("interface.il.port", 8082) cm.register("interface.ih.ip", "0.0.0.0") cm.register("interface.ih.port", 8083) cm.register("interface.xa.ip", "0.0.0.0") cm.register("interface.xa.port", 40000) cm.register("tacs.ip", "127.0.0.1") cm.register("tacs.port", 8087) cm.register("ts.daemonize", False) cm.register("ts.debug", False) cm.register("ts.log_filename", "") cm.register("ts.pid_filename", "") cm.register("ts.name", socket.gethostname(), dynamic = True) cm.register("ts.jobscheduler.interval", 1000, dynamic = True) cm.register("testerman.document_root", "/tmp", xform = expandPath, dynamic = True) cm.register("testerman.var_root", "", xform = expandPath) cm.register("testerman.web.document_root", "%s/web" % testerman_home, xform = expandPath, dynamic = False) cm.register("testerman.webclient.document_root", "%s/webclient" % testerman_home, xform = expandPath, dynamic = False) cm.register("testerman.administrator.name", "administrator", dynamic = True) cm.register("testerman.administrator.email", "testerman-admin@localhost", dynamic = True) # testerman.te.*: test executable-related variables cm.register("testerman.te.codec_paths", "%s/plugins/codecs" % testerman_home, xform = splitPaths) cm.register("testerman.te.probe_paths", "%s/plugins/probes" % testerman_home, xform = splitPaths) cm.register("testerman.te.python.interpreter", "/usr/bin/python", dynamic = True) cm.register("testerman.te.python.ttcn3module", "TestermanTTCN3", dynamic = True) # TTCN3 adaptation lib (enable the easy use of previous versions to keep script compatibility) cm.register("testerman.te.python.additional_pythonpath", "", dynamic = True) # Additional search paths for system-wide modules (non-userland/in repository) cm.register("testerman.te.log.max_payload_size", 64*1024, dynamic = True) # the maximum dumpable payload in log (as a single value). Bigger payloads are truncated to this size, in bytes. cm.register("ts.webui.theme", "default", dynamic = True) cm.register("wcs.webui.theme", "default", dynamic = True) parser = optparse.OptionParser(version = getVersion()) group = optparse.OptionGroup(parser, "Basic Options") group.add_option("--debug", dest = "debug", action = "store_true", help = "turn debug traces on") group.add_option("-d", dest = "daemonize", action = "store_true", help = "daemonize") group.add_option("-r", dest = "docRoot", metavar = "PATH", help = "use PATH as document root (default: %s)" % cm.get("testerman.document_root")) group.add_option("--log-filename", dest = "logFilename", metavar = "FILENAME", help = "write logs to FILENAME instead of stdout") group.add_option("--pid-filename", dest = "pidFilename", metavar = "FILENAME", help = "write the process PID to FILENAME when daemonizing (default: no pidfile)") parser.add_option_group(group) group = optparse.OptionGroup(parser, "IPs and Ports Options") group.add_option("--ws-ip", dest = "wsIp", metavar = "ADDRESS", help = "set listening Ws IP address to ADDRESS (default: listening on all interfaces)") group.add_option("--ws-port", dest = "wsPort", metavar = "PORT", help = "set listening Ws port to PORT (default: %s)" % cm.get("interface.ws.port"), type = "int") group.add_option("--xc-ip", dest = "xcIp", metavar = "ADDRESS", help = "set Xc service IP address to ADDRESS (default: Ws IP if set, fallback to hostname resolution)") group.add_option("--xc-port", dest = "xcPort", metavar = "PORT", help = "set Xc service port to PORT (default: %s)" % cm.get("interface.xc.port"), type = "int") group.add_option("--il-ip", dest = "ilIp", metavar = "ADDRESS", help = "set Il IP address to ADDRESS (default: listening on all interfaces)") group.add_option("--il-port", dest = "ilPort", metavar = "PORT", help = "set Il port address to PORT (default: %s)" % cm.get("interface.il.port"), type = "int") group.add_option("--ih-ip", dest = "ihIp", metavar = "ADDRESS", help = "set Ih IP address to ADDRESS (default: listening o all interfaces)") group.add_option("--ih-port", dest = "ihPort", metavar = "PORT", help = "set Ih port address to PORT (default: %s)" % cm.get("interface.ih.port"), type = "int") group.add_option("--tacs-ip", dest = "tacsIp", metavar = "ADDRESS", help = "set TACS Ia target IP address to ADDRESS (default: %s)" % cm.get("tacs.ip")) group.add_option("--tacs-port", dest = "tacsPort", metavar = "PORT", help = "set TACS Ia target port address to PORT (default: %s)" % cm.get("tacs.port"), type = "int") parser.add_option_group(group) group = optparse.OptionGroup(parser, "Advanced Options") group.add_option("-V", dest = "varDir", metavar = "PATH", help = "use PATH to persist Testerman Server runtime variables, such as the job queue. If not provided, no persistence occurs between restarts.") group.add_option("-C", "--conf-file", dest = "configurationFile", metavar = "FILENAME", help = "path to a configuration file. You may still use the command line options to override the values it contains.") group.add_option("-U", "--users-file", dest = "usersFile", metavar = "FILENAME", help = "path to the configuration file that contains authorized webclient users.") group.add_option("-A", "--apis-file", dest = "apisFile", metavar = "FILENAME", help = "path to the configuration file that contains supported language apis.") group.add_option("--codec-path", dest = "codecPaths", metavar = "PATHS", help = "search for codec modules in PATHS, which is a comma-separated list of paths") group.add_option("--probe-path", dest = "probePaths", metavar = "PATHS", help = "search for probe modules in PATHS, which is a comma-separated list of paths") group.add_option("--var", dest = "variables", metavar = "VARS", help = "set additional variables as VARS (format: key=value[,key=value]*)") parser.add_option_group(group) (options, args) = parser.parse_args() # Configuration # Read the settings from the saved configuration, if any configFile = None # Provided on the command line ? if options.configurationFile is not None: configFile = options.configurationFile # No config file provided - fallback to $TESTERMAN_HOME/conf/testerman.conf if set and exists elif Tools.fileExists("%s/conf/testerman.conf" % testerman_home): configFile = "%s/conf/testerman.conf" % testerman_home cm.set_transient("ts.configuration_filename", configFile) usersFile = None # Provided on the command line ? if options.usersFile is not None: usersFile = options.usersFile # No config file provided - fallback to $TESTERMAN_HOME/conf/webclient-users.conf if set and exists elif Tools.fileExists("%s/conf/webclient-users.conf" % testerman_home): usersFile = "%s/conf/webclient-users.conf" % testerman_home cm.set_transient("wcs.users_filename", usersFile) apisFile = None # Provided on the command line ? if options.apisFile is not None: apisFile = options.apisFile # No config file provided - fallback to $TESTERMAN_HOME/conf/language-apis.conf if set and exists elif Tools.fileExists("%s/conf/language-apis.conf" % testerman_home): apisFile = "%s/conf/language-apis.conf" % testerman_home cm.set_transient("ts.apis_filename", apisFile) try: if configFile: cm.read(configFile) if usersFile: cm.read(usersFile, autoRegister = True) if apisFile: cm.read(apisFile, autoRegister = True) except Exception, e: print str(e) return 1
def getVersion(): ret = "Testerman Server %s" % Versions.getServerVersion() + "\n" + \ "API versions:\n Ws: %s\n Xc: %s" % (Versions.getWsVersion(), Versions.getXcVersion()) return ret
def __init__(self, manager, xcAddress): Nodes.ListeningNode.__init__( self, "TS/Xc", "XcServer/%s" % Versions.getServerVersion()) self._manager = manager self.initialize(xcAddress)
def __init__(self, manager, ilAddress): Nodes.ListeningNode.__init__(self, "TS/Il", "IlServer/%s" % Versions.getServerVersion()) self._manager = manager self.initialize(ilAddress)
if not pidfile and cm.get("testerman.var_root"): # Set an actual value pidfile = cm.get("testerman.var_root") + "/ts.pid" cm.set_actual("ts.pid_filename", pidfile) # print Tools.formatTable([ ('key', 'Name'), ('format', 'Type'), ('dynamic', 'Dynamic'), ('default', 'Default value'), ('user', 'User value'), ('actual', 'Actual value')], cm.getVariables(), order = "key") # Logger initialization if cm.get("ts.debug"): level = logging.DEBUG else: level = logging.INFO logging.basicConfig(level = level, format = '%(asctime)s.%(msecs)03d %(thread)d %(levelname)-8s %(name)-20s %(message)s', datefmt = '%Y%m%d %H:%M:%S', filename = cm.get("ts.log_filename")) # Display startup info getLogger().info("Starting Testerman Server %s" % (Versions.getServerVersion())) getLogger().info("Web Service (Ws) listening on tcp://%s:%s" % (cm.get("interface.ws.ip"), cm.get("interface.ws.port"))) getLogger().info("Client events (Xc) listening on tcp://%s:%s" % (cm.get("interface.xc.ip"), cm.get("interface.xc.port"))) getLogger().info("Log manager (Il) listening on tcp://%s:%s" % (cm.get("interface.il.ip"), cm.get("interface.il.port"))) getLogger().info("Component manager (Ih) listening on tcp://%s:%s" % (cm.get("interface.ih.ip"), cm.get("interface.ih.port"))) getLogger().info("Using TACS at tcp://%s:%s" % (cm.get("tacs.ip"), cm.get("tacs.port"))) items = cm.getKeys() items.sort() for k in items: getLogger().info("Using %s = %s" % (str(k), cm.get(k))) # Now we can daemonize if needed if cm.get("ts.daemonize"): if pidfile: getLogger().info("Daemonizing, using pid file %s..." % pidfile) else:
def __init__(self, manager, ilAddress): Nodes.ListeningNode.__init__( self, "TS/Il", "IlServer/%s" % Versions.getServerVersion()) self._manager = manager self.initialize(ilAddress)
# If an explicit pid file was provided, use it. Otherwise, fallback to the var_root/ts.pid if possible. pidfile = cm.get("tacs.pid_filename") if not pidfile and cm.get("testerman.var_root"): # Set an actual value pidfile = cm.get("testerman.var_root") + "/ts.pid" cm.set_actual("tacs.pid_filename", pidfile) # print Tools.formatTable([ ('key', 'Name'), ('format', 'Type'), ('dynamic', 'Dynamic'), ('default', 'Default value'), ('user', 'User value'), ('actual', 'Actual value')], cm.getVariables(), order = "key") # Logger initialization level = cm.get("tacs.debug") and logging.DEBUG or logging.INFO logging.basicConfig(level = level, format = '%(asctime)s.%(msecs)03d %(thread)d %(levelname)-8s %(name)-20s %(message)s', datefmt = '%Y%m%d %H:%M:%S', filename = cm.get("tacs.log_filename")) # Display startup info getLogger().info("Starting Testerman Agent Controller Server %s" % (Versions.getAgentControllerVersion())) getLogger().info("Agent interface (Xa) listening on tcp://%s:%s" % (cm.get("interface.xa.ip"), cm.get("interface.xa.port"))) getLogger().info("Internal interface (Ia) listening on tcp://%s:%s" % (cm.get("interface.ia.ip"), cm.get("interface.ia.port"))) # Now we can daemonize if needed if cm.get("tacs.daemonize"): if pidfile: getLogger().info("Daemonizing, using pid file %s..." % pidfile) else: getLogger().info("Daemonizing...") Tools.daemonize(pidFilename = pidfile, displayPid = True) # Main start cm.set_transient("tacs.pid", os.getpid()) controller = None
# Logger initialization if cm.get("ts.debug"): level = logging.DEBUG else: level = logging.INFO logging.basicConfig( level=level, format= '%(asctime)s.%(msecs)03d %(thread)d %(levelname)-8s %(name)-20s %(message)s', datefmt='%Y%m%d %H:%M:%S', filename=cm.get("ts.log_filename")) # Display startup info getLogger().info("Starting Testerman Server %s" % (Versions.getServerVersion())) getLogger().info("Web Service (Ws) listening on tcp://%s:%s" % (cm.get("interface.ws.ip"), cm.get("interface.ws.port"))) getLogger().info("Client events (Xc) listening on tcp://%s:%s" % (cm.get("interface.xc.ip"), cm.get("interface.xc.port"))) getLogger().info("Log manager (Il) listening on tcp://%s:%s" % (cm.get("interface.il.ip"), cm.get("interface.il.port"))) getLogger().info("Component manager (Ih) listening on tcp://%s:%s" % (cm.get("interface.ih.ip"), cm.get("interface.ih.port"))) getLogger().info("Using TACS at tcp://%s:%s" % (cm.get("tacs.ip"), cm.get("tacs.port"))) items = cm.getKeys() items.sort() for k in items: getLogger().info("Using %s = %s" % (str(k), cm.get(k)))
def getVersion(): ret = "Testerman Agent Controller Server %s" % Versions.getAgentControllerVersion() return ret
def main(): server_root = os.path.abspath( os.path.dirname(sys.modules[globals()['__name__']].__file__)) testerman_home = os.path.abspath("%s/.." % server_root) # Set transient values cm.set_transient("testerman.testerman_home", testerman_home) cm.set_transient("ts.server_root", server_root) # standard paths within the document root. cm.set_transient("constants.repository", "repository") cm.set_transient("constants.archives", "archives") cm.set_transient("constants.modules", "modules") cm.set_transient("constants.components", "components") cm.set_transient("ts.version", Versions.getServerVersion()) # Register persistent variables expandPath = lambda x: x and os.path.abspath( os.path.expandvars(os.path.expanduser(x))) splitPaths = lambda paths: [expandPath(x) for x in paths.split(',')] cm.register("interface.ws.ip", "0.0.0.0") cm.register("interface.ws.port", 8080) cm.register("interface.xc.ip", "0.0.0.0") cm.register("interface.xc.port", 8081) cm.register("interface.il.ip", "0.0.0.0") cm.register("interface.il.port", 8082) cm.register("interface.ih.ip", "0.0.0.0") cm.register("interface.ih.port", 8083) cm.register("interface.xa.ip", "0.0.0.0") cm.register("interface.xa.port", 40000) cm.register("tacs.ip", "127.0.0.1") cm.register("tacs.port", 8087) cm.register("ts.daemonize", False) cm.register("ts.debug", False) cm.register("ts.log_filename", "") cm.register("ts.pid_filename", "") cm.register("ts.name", socket.gethostname(), dynamic=True) cm.register("ts.jobscheduler.interval", 1000, dynamic=True) cm.register("testerman.document_root", "/tmp", xform=expandPath, dynamic=True) cm.register("testerman.var_root", "", xform=expandPath) cm.register("testerman.web.document_root", "%s/web" % testerman_home, xform=expandPath, dynamic=False) cm.register("testerman.webclient.document_root", "%s/webclient" % testerman_home, xform=expandPath, dynamic=False) cm.register("testerman.administrator.name", "administrator", dynamic=True) cm.register("testerman.administrator.email", "testerman-admin@localhost", dynamic=True) # testerman.te.*: test executable-related variables cm.register("testerman.te.codec_paths", "%s/plugins/codecs" % testerman_home, xform=splitPaths) cm.register("testerman.te.probe_paths", "%s/plugins/probes" % testerman_home, xform=splitPaths) cm.register("testerman.te.python.interpreter", "/usr/bin/python", dynamic=True) cm.register( "testerman.te.python.ttcn3module", "TestermanTTCN3", dynamic=True ) # TTCN3 adaptation lib (enable the easy use of previous versions to keep script compatibility) cm.register( "testerman.te.python.additional_pythonpath", "", dynamic=True ) # Additional search paths for system-wide modules (non-userland/in repository) cm.register( "testerman.te.log.max_payload_size", 64 * 1024, dynamic=True ) # the maximum dumpable payload in log (as a single value). Bigger payloads are truncated to this size, in bytes. cm.register("ts.webui.theme", "default", dynamic=True) cm.register("wcs.webui.theme", "default", dynamic=True) parser = optparse.OptionParser(version=getVersion()) group = optparse.OptionGroup(parser, "Basic Options") group.add_option("--debug", dest="debug", action="store_true", help="turn debug traces on") group.add_option("-d", dest="daemonize", action="store_true", help="daemonize") group.add_option("-r", dest="docRoot", metavar="PATH", help="use PATH as document root (default: %s)" % cm.get("testerman.document_root")) group.add_option("--log-filename", dest="logFilename", metavar="FILENAME", help="write logs to FILENAME instead of stdout") group.add_option( "--pid-filename", dest="pidFilename", metavar="FILENAME", help= "write the process PID to FILENAME when daemonizing (default: no pidfile)" ) parser.add_option_group(group) group = optparse.OptionGroup(parser, "IPs and Ports Options") group.add_option( "--ws-ip", dest="wsIp", metavar="ADDRESS", help= "set listening Ws IP address to ADDRESS (default: listening on all interfaces)" ) group.add_option("--ws-port", dest="wsPort", metavar="PORT", help="set listening Ws port to PORT (default: %s)" % cm.get("interface.ws.port"), type="int") group.add_option( "--xc-ip", dest="xcIp", metavar="ADDRESS", help= "set Xc service IP address to ADDRESS (default: Ws IP if set, fallback to hostname resolution)" ) group.add_option("--xc-port", dest="xcPort", metavar="PORT", help="set Xc service port to PORT (default: %s)" % cm.get("interface.xc.port"), type="int") group.add_option( "--il-ip", dest="ilIp", metavar="ADDRESS", help= "set Il IP address to ADDRESS (default: listening on all interfaces)") group.add_option("--il-port", dest="ilPort", metavar="PORT", help="set Il port address to PORT (default: %s)" % cm.get("interface.il.port"), type="int") group.add_option( "--ih-ip", dest="ihIp", metavar="ADDRESS", help= "set Ih IP address to ADDRESS (default: listening o all interfaces)") group.add_option("--ih-port", dest="ihPort", metavar="PORT", help="set Ih port address to PORT (default: %s)" % cm.get("interface.ih.port"), type="int") group.add_option( "--tacs-ip", dest="tacsIp", metavar="ADDRESS", help="set TACS Ia target IP address to ADDRESS (default: %s)" % cm.get("tacs.ip")) group.add_option( "--tacs-port", dest="tacsPort", metavar="PORT", help="set TACS Ia target port address to PORT (default: %s)" % cm.get("tacs.port"), type="int") parser.add_option_group(group) group = optparse.OptionGroup(parser, "Advanced Options") group.add_option( "-V", dest="varDir", metavar="PATH", help= "use PATH to persist Testerman Server runtime variables, such as the job queue. If not provided, no persistence occurs between restarts." ) group.add_option( "-C", "--conf-file", dest="configurationFile", metavar="FILENAME", help= "path to a configuration file. You may still use the command line options to override the values it contains." ) group.add_option( "-U", "--users-file", dest="usersFile", metavar="FILENAME", help= "path to the configuration file that contains authorized webclient users." ) group.add_option( "-A", "--apis-file", dest="apisFile", metavar="FILENAME", help= "path to the configuration file that contains supported language apis." ) group.add_option( "--codec-path", dest="codecPaths", metavar="PATHS", help= "search for codec modules in PATHS, which is a comma-separated list of paths" ) group.add_option( "--probe-path", dest="probePaths", metavar="PATHS", help= "search for probe modules in PATHS, which is a comma-separated list of paths" ) group.add_option( "--var", dest="variables", metavar="VARS", help="set additional variables as VARS (format: key=value[,key=value]*)" ) parser.add_option_group(group) (options, args) = parser.parse_args() # Configuration # Read the settings from the saved configuration, if any configFile = None # Provided on the command line ? if options.configurationFile is not None: configFile = options.configurationFile # No config file provided - fallback to $TESTERMAN_HOME/conf/testerman.conf if set and exists elif Tools.fileExists("%s/conf/testerman.conf" % testerman_home): configFile = "%s/conf/testerman.conf" % testerman_home cm.set_transient("ts.configuration_filename", configFile) usersFile = None # Provided on the command line ? if options.usersFile is not None: usersFile = options.usersFile # No config file provided - fallback to $TESTERMAN_HOME/conf/webclient-users.conf if set and exists elif Tools.fileExists("%s/conf/webclient-users.conf" % testerman_home): usersFile = "%s/conf/webclient-users.conf" % testerman_home cm.set_transient("wcs.users_filename", usersFile) apisFile = None # Provided on the command line ? if options.apisFile is not None: apisFile = options.apisFile # No config file provided - fallback to $TESTERMAN_HOME/conf/language-apis.conf if set and exists elif Tools.fileExists("%s/conf/language-apis.conf" % testerman_home): apisFile = "%s/conf/language-apis.conf" % testerman_home cm.set_transient("ts.apis_filename", apisFile) try: if configFile: cm.read(configFile) if usersFile: cm.read(usersFile, autoRegister=True) if apisFile: cm.read(apisFile, autoRegister=True) except Exception, e: print str(e) return 1
def __init__(self, manager, xcAddress): Nodes.ListeningNode.__init__(self, "TS/Xc", "XcServer/%s" % Versions.getServerVersion()) self._manager = manager self.initialize(xcAddress)
def main(): server_root = os.path.abspath( os.path.dirname(sys.modules[globals()['__name__']].__file__)) testerman_home = os.path.abspath("%s/.." % server_root) # Set transient values cm.set_transient("testerman.testerman_home", testerman_home) cm.set_transient("ts.server_root", server_root) # standard paths within the document root. cm.set_transient("constants.repository", "repository") cm.set_transient("constants.archives", "archives") cm.set_transient("constants.modules", "modules") cm.set_transient("constants.components", "components") cm.set_transient("ts.version", Versions.getServerVersion()) # Register persistent variables expandPath = lambda x: x and os.path.abspath( os.path.expandvars(os.path.expanduser(x))) splitPaths = lambda paths: [expandPath(x) for x in paths.split(',')] cm.register("interface.ws.ip", "0.0.0.0") cm.register("interface.ws.port", 8080) cm.register("interface.xc.ip", "0.0.0.0") cm.register("interface.xc.port", 8081) cm.register("interface.il.ip", "0.0.0.0") cm.register("interface.il.port", 8082) cm.register("interface.ih.ip", "0.0.0.0") cm.register("interface.ih.port", 8083) cm.register("interface.xa.ip", "0.0.0.0") cm.register("interface.xa.port", 40000) cm.register("tacs.ip", "127.0.0.1") cm.register("tacs.port", 8087) cm.register("ts.daemonize", False) cm.register("ts.debug", False) cm.register("ts.log_filename", "") cm.register("ts.pid_filename", "") cm.register("ts.name", socket.gethostname(), dynamic=True) cm.register("ts.jobscheduler.interval", 1000, dynamic=True) cm.register("testerman.document_root", "/tmp", xform=expandPath, dynamic=True) cm.register("testerman.var_root", "", xform=expandPath) cm.register("testerman.web.document_root", "%s/web" % testerman_home, xform=expandPath, dynamic=False) cm.register("testerman.webclient.document_root", "%s/webclient" % testerman_home, xform=expandPath, dynamic=False) cm.register("testerman.administrator.name", "administrator", dynamic=True) cm.register("testerman.administrator.email", "testerman-admin@localhost", dynamic=True) # testerman.te.*: test executable-related variables cm.register("testerman.te.codec_paths", "%s/plugins/codecs" % testerman_home, xform=splitPaths) cm.register("testerman.te.probe_paths", "%s/plugins/probes" % testerman_home, xform=splitPaths) cm.register("testerman.te.python.interpreter", "/usr/bin/python", dynamic=True) cm.register( "testerman.te.python.ttcn3module", "TestermanTTCN3", dynamic=True ) # TTCN3 adaptation lib (enable the easy use of previous versions to keep script compatibility) cm.register( "testerman.te.python.additional_pythonpath", "", dynamic=True ) # Additional search paths for system-wide modules (non-userland/in repository) cm.register( "testerman.te.log.max_payload_size", 64 * 1024, dynamic=True ) # the maximum dumpable payload in log (as a single value). Bigger payloads are truncated to this size, in bytes. cm.register("ts.webui.theme", "default", dynamic=True) cm.register("wcs.webui.theme", "default", dynamic=True) parser = optparse.OptionParser(version=getVersion()) group = optparse.OptionGroup(parser, "Basic Options") group.add_option("--debug", dest="debug", action="store_true", help="turn debug traces on") group.add_option("-d", dest="daemonize", action="store_true", help="daemonize") group.add_option("-r", dest="docRoot", metavar="PATH", help="use PATH as document root (default: %s)" % cm.get("testerman.document_root")) group.add_option("--log-filename", dest="logFilename", metavar="FILENAME", help="write logs to FILENAME instead of stdout") group.add_option( "--pid-filename", dest="pidFilename", metavar="FILENAME", help= "write the process PID to FILENAME when daemonizing (default: no pidfile)" ) parser.add_option_group(group) group = optparse.OptionGroup(parser, "IPs and Ports Options") group.add_option( "--ws-ip", dest="wsIp", metavar="ADDRESS", help= "set listening Ws IP address to ADDRESS (default: listening on all interfaces)" ) group.add_option("--ws-port", dest="wsPort", metavar="PORT", help="set listening Ws port to PORT (default: %s)" % cm.get("interface.ws.port"), type="int") group.add_option( "--xc-ip", dest="xcIp", metavar="ADDRESS", help= "set Xc service IP address to ADDRESS (default: Ws IP if set, fallback to hostname resolution)" ) group.add_option("--xc-port", dest="xcPort", metavar="PORT", help="set Xc service port to PORT (default: %s)" % cm.get("interface.xc.port"), type="int") group.add_option( "--il-ip", dest="ilIp", metavar="ADDRESS", help= "set Il IP address to ADDRESS (default: listening on all interfaces)") group.add_option("--il-port", dest="ilPort", metavar="PORT", help="set Il port address to PORT (default: %s)" % cm.get("interface.il.port"), type="int") group.add_option( "--ih-ip", dest="ihIp", metavar="ADDRESS", help= "set Ih IP address to ADDRESS (default: listening o all interfaces)") group.add_option("--ih-port", dest="ihPort", metavar="PORT", help="set Ih port address to PORT (default: %s)" % cm.get("interface.ih.port"), type="int") group.add_option( "--tacs-ip", dest="tacsIp", metavar="ADDRESS", help="set TACS Ia target IP address to ADDRESS (default: %s)" % cm.get("tacs.ip")) group.add_option( "--tacs-port", dest="tacsPort", metavar="PORT", help="set TACS Ia target port address to PORT (default: %s)" % cm.get("tacs.port"), type="int") parser.add_option_group(group) group = optparse.OptionGroup(parser, "Advanced Options") group.add_option( "-V", dest="varDir", metavar="PATH", help= "use PATH to persist Testerman Server runtime variables, such as the job queue. If not provided, no persistence occurs between restarts." ) group.add_option( "-C", "--conf-file", dest="configurationFile", metavar="FILENAME", help= "path to a configuration file. You may still use the command line options to override the values it contains." ) group.add_option( "-U", "--users-file", dest="usersFile", metavar="FILENAME", help= "path to the configuration file that contains authorized webclient users." ) group.add_option( "-A", "--apis-file", dest="apisFile", metavar="FILENAME", help= "path to the configuration file that contains supported language apis." ) group.add_option( "--codec-path", dest="codecPaths", metavar="PATHS", help= "search for codec modules in PATHS, which is a comma-separated list of paths" ) group.add_option( "--probe-path", dest="probePaths", metavar="PATHS", help= "search for probe modules in PATHS, which is a comma-separated list of paths" ) group.add_option( "--var", dest="variables", metavar="VARS", help="set additional variables as VARS (format: key=value[,key=value]*)" ) parser.add_option_group(group) (options, args) = parser.parse_args() # Configuration # Read the settings from the saved configuration, if any configFile = None # Provided on the command line ? if options.configurationFile is not None: configFile = options.configurationFile # No config file provided - fallback to $TESTERMAN_HOME/conf/testerman.conf if set and exists elif Tools.fileExists("%s/conf/testerman.conf" % testerman_home): configFile = "%s/conf/testerman.conf" % testerman_home cm.set_transient("ts.configuration_filename", configFile) usersFile = None # Provided on the command line ? if options.usersFile is not None: usersFile = options.usersFile # No config file provided - fallback to $TESTERMAN_HOME/conf/webclient-users.conf if set and exists elif Tools.fileExists("%s/conf/webclient-users.conf" % testerman_home): usersFile = "%s/conf/webclient-users.conf" % testerman_home cm.set_transient("wcs.users_filename", usersFile) apisFile = None # Provided on the command line ? if options.apisFile is not None: apisFile = options.apisFile # No config file provided - fallback to $TESTERMAN_HOME/conf/language-apis.conf if set and exists elif Tools.fileExists("%s/conf/language-apis.conf" % testerman_home): apisFile = "%s/conf/language-apis.conf" % testerman_home cm.set_transient("ts.apis_filename", apisFile) try: if configFile: cm.read(configFile) if usersFile: cm.read(usersFile, autoRegister=True) if apisFile: cm.read(apisFile, autoRegister=True) except Exception as e: print(str(e)) return 1 # Now, override read settings with those set on explicit command line flags # (or their default values inherited from the ConfigManager default values) cm.set_user("interface.ws.ip", options.wsIp) cm.set_user("interface.ws.port", options.wsPort) cm.set_user("interface.xc.ip", options.xcIp) cm.set_user("interface.xc.port", options.xcPort) cm.set_user("interface.il.ip", options.ilIp) cm.set_user("interface.il.port", options.ilPort) cm.set_user("interface.ih.ip", options.ihIp) cm.set_user("interface.ih.port", options.ihPort) cm.set_user("tacs.ip", options.tacsIp) cm.set_user("tacs.port", options.tacsPort) cm.set_user("ts.daemonize", options.daemonize) cm.set_user("ts.debug", options.debug) cm.set_user("ts.log_filename", options.logFilename) cm.set_user("ts.pid_filename", options.pidFilename) cm.set_user("testerman.document_root", options.docRoot) cm.set_user("testerman.te.codec_paths", options.codecPaths) cm.set_user("testerman.te.probe_paths", options.probePaths) cm.set_user("testerman.var_root", options.varDir) if options.variables: for var in options.variables.split(','): try: (key, val) = var.split('=') cm.set_user(key, val) except: pass # Commit all provided values (construct actual values via registered xforms) cm.commit() # Compute/adjust actual variables where applies # Actual Xc IP address: if not explictly set, fallback to ws.ip, then to hostname(). ip = cm.get("interface.xc.ip") if not ip or ip == '0.0.0.0': ip = cm.get("interface.ws.ip") cm.set_actual("interface.xc.ip", ip) if not ip or ip == '0.0.0.0': cm.set_actual( "interface.xc.ip", socket.gethostbyname(socket.gethostname( ))) # Not fully qualified ? defaults to the hostname resolution. # Set the TACS IP address that can be used by agents # Normally, we should ask the TACS the server is connected to to get this value. tacs = cm.get("interface.xa.ip") if not tacs or tacs == '0.0.0.0': # We'll publish the XC as XA IP address. If it was also set to localhost, it's unlikely agents are deployed outside localhost too. cm.set_actual("interface.xa.ip", cm.get("interface.xc.ip")) # If an explicit pid file was provided, use it. Otherwise, fallback to the var_root/ts.pid if possible. pidfile = cm.get("ts.pid_filename") if not pidfile and cm.get("testerman.var_root"): # Set an actual value pidfile = cm.get("testerman.var_root") + "/ts.pid" cm.set_actual("ts.pid_filename", pidfile) # print (Tools.formatTable([ ('key', 'Name'), ('format', 'Type'), ('dynamic', 'Dynamic'), ('default', 'Default value'), ('user', 'User value'), ('actual', 'Actual value')], cm.getVariables(), order = "key")) # Logger initialization if cm.get("ts.debug"): level = logging.DEBUG else: level = logging.INFO logging.basicConfig( level=level, format= '%(asctime)s.%(msecs)03d %(thread)d %(levelname)-8s %(name)-20s %(message)s', datefmt='%Y%m%d %H:%M:%S', filename=cm.get("ts.log_filename")) # Display startup info getLogger().info("Starting Testerman Server %s" % (Versions.getServerVersion())) getLogger().info("Web Service (Ws) listening on tcp://%s:%s" % (cm.get("interface.ws.ip"), cm.get("interface.ws.port"))) getLogger().info("Client events (Xc) listening on tcp://%s:%s" % (cm.get("interface.xc.ip"), cm.get("interface.xc.port"))) getLogger().info("Log manager (Il) listening on tcp://%s:%s" % (cm.get("interface.il.ip"), cm.get("interface.il.port"))) getLogger().info("Component manager (Ih) listening on tcp://%s:%s" % (cm.get("interface.ih.ip"), cm.get("interface.ih.port"))) getLogger().info("Using TACS at tcp://%s:%s" % (cm.get("tacs.ip"), cm.get("tacs.port"))) items = cm.getKeys() items.sort() for k in items: getLogger().info("Using %s = %s" % (str(k), cm.get(k))) # Now we can daemonize if needed if cm.get("ts.daemonize"): if pidfile: getLogger().info("Daemonizing, using pid file %s..." % pidfile) else: getLogger().info("Daemonizing...") Tools.daemonize(pidFilename=pidfile, displayPid=True) # Main start cm.set_transient("ts.pid", os.getpid()) try: serverThread = XmlRpcServerThread() # Ws server FileSystemManager.initialize() EventManager.initialize( ) # Xc server, Ih server [TSE:CH], Il server [TSE:TL] ProbeManager.initialize() # Ia client JobManager.initialize() # Job scheduler serverThread.start() getLogger().info("Started.") while 1: time.sleep(1) except KeyboardInterrupt: getLogger().info("Shutting down Testerman Server...") except Exception as e: sys.stderr.write("Unable to start server: %s\n" % str(e)) getLogger().critical("Unable to start server: " + str(e)) serverThread.stop() JobManager.finalize() ProbeManager.finalize() EventManager.finalize() FileSystemManager.finalize() getLogger().info("Shut down.") logging.shutdown() Tools.cleanup(cm.get("ts.pid_filename"))