Пример #1
0
    def run(self):
        """
        Called by daemon in the agent's thread to perform the thread main
        """
        self.logfile = os.path.join(config.getLogDir(), '%s_%s.log' % (self.name, time.strftime("%Y-%m-%d_%H:%M:%S")))
        
        if database.isDBEnabled():
            log.info("Database enabled. Creating collection instance.")
            self.collection = database.getCollection(self.name)
            
        while not self.done:
            try:
                msg = self.messenger.next(True, max(self.nextrun - time.time(), 0))
                if isinstance(msg, MAGIMessage):
                    doMessageAction(self, msg, self.messenger)

            except Queue.Empty:
                pass

            if not self.running or time.time() < self.nextrun:
                continue  # message received, not yet time to launch, reloop
            
            self.nextrun = time.time() + eval(self.interval)
            
            try:
                # TODO: Check memory here to avoid overload?
                self.oneClient()
            except Exception:
                log.error("error in client process", exc_info=1)
Пример #2
0
    def run(self):
        """
        Called by daemon in the agent's thread to perform the thread main
        """
        self.logfile = os.path.join(
            config.getLogDir(),
            '%s_%s.log' % (self.name, time.strftime("%Y-%m-%d_%H:%M:%S")))

        if database.isDBEnabled():
            log.info("Database enabled. Creating collection instance.")
            self.collection = database.getCollection(self.name)

        while not self.done:
            try:
                msg = self.messenger.next(True,
                                          max(self.nextrun - time.time(), 0))
                if isinstance(msg, MAGIMessage):
                    doMessageAction(self, msg, self.messenger)

            except Queue.Empty:
                pass

            if not self.running or time.time() < self.nextrun:
                continue  # message received, not yet time to launch, reloop

            self.nextrun = time.time() + eval(self.interval)

            try:
                # TODO: Check memory here to avoid overload?
                self.oneClient()
            except Exception:
                log.error("error in client process", exc_info=1)
Пример #3
0
def startShardServer(configHost=getConfigHost(), timeout=TIMEOUT):
    """
        Function to start a database config server on the node
    """
    return Server.startShardServer(
        logPath=os.path.join(config.getLogDir(), "mongos.log"),
        configHost=helpers.toControlPlaneNodeName(configHost),
        timeout=timeout)
Пример #4
0
def startConfigServer(timeout=TIMEOUT):
    """
        Function to start a database config server on the node
    """
    return Server.startConfigServer(
        dbPath=os.path.join(config.getDbDir(), "configdb"),
        logPath=os.path.join(config.getLogDir(), "mongoc.log"),
        timeout=timeout)
Пример #5
0
 def doAndLogCommand(self, command, name):
     '''Run the given command and dump stdout and stderr to the log directory.'''
     # TODO: replace hardcoded file name with magi.util.config.MAGILOG 
     filename = os.path.join(config.getLogDir(), '%s-%s.log' % (self.TYPE, name))
     try:
         with open(filename, 'a') as fd: 
             return run(command, stdout=fd, stderr=subprocess.STDOUT, shell=True) == 0
     except Exception, e:
         self.log.warning('%s failed %s: %s. Check %s for details.', self.TYPE, name, e, filename)
         return False
Пример #6
0
def startDBServer(configfile=None, timeout=TIMEOUT):
    """
        Function to start a database server on the node
    """
    helpers.makeDir(config.getDbDir())
    return Server.startDBServer(configfile=configfile,
                                configDir=config.getConfigDir(),
                                dbPath=os.path.join(config.getDbDir(),
                                                    "mongodb"),
                                logPath=os.path.join(config.getLogDir(),
                                                     "mongodb.log"),
                                timeout=timeout)
Пример #7
0
	def archive(self, msg, destinationDir=config.getTempDir()):
		""" 
            Tars the log directory" 
        """ 
		functionName = self.archive.__name__
		helpers.entrylog(log, functionName, locals())
		logDir = config.getLogDir()
		logTar = tarfile.open(name=os.path.join(destinationDir, 
								"logs_%s.tar.gz"%(datetime.datetime.now()
												.strftime("%Y%m%d_%H%M%S"))), 
							  mode='w:gz')
		logTar.add(logDir, arcname=os.path.basename(logDir))
		logTar.close()
		helpers.exitlog(log, functionName)
Пример #8
0
	def getLogsArchive(self, msg):
		""" 
            Tars the log directory and sends it to the requester as a message" 
        """ 
		functionName = self.archive.__name__
		helpers.entrylog(log, functionName, locals())
		logDir = config.getLogDir()
		store = cStringIO.StringIO()
		logTar = tarfile.open(fileobj=store, mode='w:gz')
		logTar.add(logDir, arcname=os.path.basename(logDir))
		logTar.close()
		result = base64.encodestring(store.getvalue())
		self.messaging.send(MAGIMessage(nodes=msg.src, docks=msg.srcdock, 
									    contenttype=MAGIMessage.YAML, 
									    data=yaml.safe_dump(result)))
		helpers.exitlog(log, functionName)
Пример #9
0
	def startAgent(self, code=None, name=None, dock=None, execargs=None, idl=None, static=False):
		"""
			Internal function to invoke an agent
		"""
		# Now find the interface definition and load it
		try:
			log.debug('startAgent code: %s, idl: %s' % (code, idl))
			dirname = code
			if idl:
				idlFile = dirname+'/%s.idl' % idl
			else:
				idlFile = glob.glob(dirname+'/*.idl')[0]
		except IndexError:
			log.debug("No valid interface file in %s", dirname) 
			raise OSError(errno.ENOENT, "No valid interface file found in %s" % dirname)

		log.debug('reading interface file %s...' % idlFile)

		fp = open(idlFile)
		interface = fp.read()
		fp.close()
		interface = yaml.load(interface)

		# If there are software dependencies, load them before loading the agent
		if 'software' in interface:
			for package in interface['software']:
				log.info('Loading required package %s for agent %s.', package, name)
				requireSoftware(package)
				
		compileCmd = interface.get('compileCmd')
		if compileCmd:
			log.info("Running specified compilation command: '%s' under directory '%s'" %(compileCmd, dirname))
			p = Popen(compileCmd.split(), cwd=dirname, stdout=PIPE, stderr=PIPE)
			if p.wait():
				raise OSError("Exception while running the specified compilation command. %s", p.communicate())

		# Based on the interface execution method, execute the agent
		execstyle = interface['execute']
		mainfile = os.path.join(dirname, interface['mainfile'])

		log.info('Running agent from file %s' % mainfile)
		
		# GTL TODO: handle exceptions from threaded agents by removing
		# the agents and freeing up the dock(s) for the agent.
		try:
			if execstyle == 'thread':
				# A agent should know the hostname and its own name  
				from magi.daemon.threadInterface import ThreadedAgent
				agent = ThreadedAgent(self.hostname, name, mainfile, dock, execargs, self.messaging)
				agent.start()
				log.info("Started threaded agent %s", agent)
				if static:
					self.staticAgents.append(agent)
				else:
					self.threadAgents.append(agent)
				#2/13/14 Moved it to threadInterface
				#self.messaging.trigger(event='AgentLoadDone', agent=name, nodes=[self.hostname])
				
			else:
				# Process agent, use the file as written to disk
				if (not execargs) or (type(execargs) != dict):
					execargs = dict()
					
				# Process agent need to know hostname 
				execargs['hostname'] = self.hostname
				
				# I apologize for this abuse
				args = ['%s=%s' % (str(k), yaml.dump(v)) for k,v in execargs.iteritems()]
				
				os.chmod(mainfile, 00777)
				stderrname = os.path.join(config.getLogDir(), name + '.stderr')
				stderr = open(stderrname, 'w')		# GTL should this be closed? If so, when?
				log.info("Starting %s, stderr sent to %s", name, stderrname)
				
				if execstyle == 'pipe':
					args.append('execute=pipe')
					cmdList = [mainfile, name, dock, config.getNodeConfFile(), config.getExperimentConfFile()] + args
					log.info('running: %s', ' '.join(cmdList))
					agent = Popen(cmdList, close_fds=True, stdin=PIPE, stdout=PIPE, stderr=stderr)
					self.extAgentsThread.fromNetwork.put(PipeTuple([dock], InputPipe(fileobj=agent.stdout), OutputPipe(fileobj=agent.stdin)))
	
				elif execstyle == 'socket':
					args.append('execute=socket')
					cmdList = [mainfile, name, dock, config.getNodeConfFile(), config.getExperimentConfFile()] + args
					log.info('running: %s', ' '.join(cmdList))
					agent = Popen(cmdList, close_fds=True, stderr=stderr)
	
				else:
					log.critical("unknown launch style '%s'", interface['execute'])
					return False
				
				self.pAgentPids[name] = agent.pid
				#Process agent once up, sends the AgentLoadDone message itself
				#self.messaging.trigger(event='AgentLoadDone', agent=name, nodes=[self.hostname] )
				
		except Exception, e:
				log.error("Agent %s on %s threw an exception %s during agent load.", name, self.hostname, e, exc_info=1)
				log.error("Sending back a RunTimeException event. This may cause the receiver to exit.")
				exc_type, exc_value, exc_tb = sys.exc_info()
				filename, line_num, func_name, text = traceback.extract_tb(exc_tb)[-1]
				filename = basename(filename)
				self.messaging.trigger(event='RuntimeException', type=exc_type.__name__, error=str(e), nodes=[self.hostname], 
									agent=self.name, func_name=func_name, filename=filename, line_num=line_num)
				return False
Пример #10
0
def initializeProcessAgent(agent, argv):
    '''argv is assumed to have the following format. (This is usually set by the
    Magi daemon):

        agent_name agent_dock execute=[pipe|socket] (logfile=path)

    Where agent_name and agent_dock are strings and the key in the key=value
    pairs is literally the key given. The value may be restricted.
    '''
    if len(argv) < 3:
        log.critical('command line must start with name and dock')
        sys.exit(2)

    agent.name, dock, nodeConfigFile, experimentConfigFile = argv[1:5]
    args = argv_to_dict(argv[5:])

    config.loadNodeConfig(nodeConfigFile, experimentConfigFile)

    setAttributes(
        agent, {
            'hostname':
            config.getNodeName(),
            'execute':
            'socket',
            'logfile':
            os.path.join(config.getLogDir(), agent.name + '.log'),
            'loglevel':
            'DEBUG',
            'commHost':
            'localhost',
            'commPort':
            config.getConfig()['localInfo'].get('processAgentsCommPort',
                                                18809),
            'commGroup':
            None
        }, args)

    agent.docklist.add(dock)

    helpers.makeDir(os.path.dirname(agent.logfile))

    handler = logging.FileHandler(agent.logfile, 'w')
    handler.setFormatter(
        logging.Formatter(helpers.LOG_FORMAT_MSECS, helpers.LOG_DATEFMT))
    root = logging.getLogger()
    root.setLevel(helpers.logLevels.get(agent.loglevel.lower(), logging.INFO))
    root.handlers = []
    root.addHandler(handler)

    log.info('argv: %s', argv)
    log.info('agent attributes: %s', agent.__dict__)

    log.info("Setting up agent messaging interface")
    inTransport, outTransport = _getIOHandles(agent)
    agent.messenger = AgentMessenger(inTransport, outTransport, agent)
    agent.messenger.start()
    log.info("Agent messaging interface initialized and running")

    # Tell the daemon we want to listen on the dock.
    # GTL - why doesn't the Daemon just associate the dock
    # with this process?
    agent.messenger.listenDock(dock)

    if agent.commGroup:
        agent.messenger.joinGroup(agent.commGroup)
        #TODO: In ideal condition wait from the node to join group before proceeding further

    # now that we're connected, send an AgentLoaded message.
    agent.messenger.trigger(event='AgentLoadDone',
                            agent=agent.name,
                            nodes=[agent.hostname])

    return args
Пример #11
0
                         help="Specify location of the experiment " +
                         "configuration file, ex: -c experiment.conf ")
    optparser.add_option("-c", "--nodeconf", dest="nodeconf", 
                         help="Specify location of the node " +
                         "configuration file, ex: -c localnode.conf ")

    (options, args) = optparser.parse_args()
    
    expConfig = config.loadExperimentConfig(options.expconf)
    nodeConfig = config.loadNodeConfig(options.nodeconf)
    
    #import once the system is cofigured
    from magi.daemon.daemon import Daemon

    if not options.logfile:
        options.logfile = os.path.join(config.getLogDir(), "daemon.log")
    
    helpers.makeDir(os.path.dirname(options.logfile))
    helpers.makeDir(config.getTempDir())
            
    # Roll over the old log and create a new one
    # Note here that we will have at most 5 logs 
    # Need to check existence of file before creating the handler instance
    # This is because handler creation creates the file if not existent 
    if os.path.isfile(options.logfile):
        needroll = True
    else:
        needroll = False
    handler = logging.handlers.RotatingFileHandler(options.logfile, backupCount=5)
    if needroll:
        handler.doRollover()
Пример #12
0
    optparser.add_option("-c",
                         "--nodeconf",
                         dest="nodeconf",
                         help="Specify location of the node " +
                         "configuration file, ex: -c localnode.conf ")

    (options, args) = optparser.parse_args()

    expConfig = config.loadExperimentConfig(options.expconf)
    nodeConfig = config.loadNodeConfig(options.nodeconf)

    #import once the system is cofigured
    from magi.daemon.daemon import Daemon

    if not options.logfile:
        options.logfile = os.path.join(config.getLogDir(), "daemon.log")

    helpers.makeDir(os.path.dirname(options.logfile))
    helpers.makeDir(config.getTempDir())

    # Roll over the old log and create a new one
    # Note here that we will have at most 5 logs
    # Need to check existence of file before creating the handler instance
    # This is because handler creation creates the file if not existent
    if os.path.isfile(options.logfile):
        needroll = True
    else:
        needroll = False
    handler = logging.handlers.RotatingFileHandler(options.logfile,
                                                   backupCount=5)
    if needroll: