def _scan(self): for pid in listProcesses(): try: AppProcess(Server(config.HOSTNAME), pid) except InvalidProcess: pass except IOError: pass #happens on linux when a pid dies except: err('process table scanning error') #scan for crashed instances for app in App.objects: if not app.__class__.isValid(app): continue for ai in app.localappinstances: if not ai.__class__.isValid(ai): continue if ai in self.tracking: continue if not self.first_run: #avoid process table races self.tracking.add(ai) config.reactor.callLater(SERVICECONFIG.recovery_period, self.tracking.discard, ai ) if not ai.enabled: continue #skip disabled result = None if ai.running and not ai.shouldBeRunning: ai.shouldBeRunning = True if ai.running: continue manager = AppManager(ai.app.name) if not manager.running: continue #skip managers that are not running if not manager.discover: continue #app manager claims to be ok #look for processes that we can assimilate d = manager.model.findProcesses() wfd = defer.waitForDeferred(d) yield wfd for (pid, result) in wfd.getResult(): d = manager.model.assimilateProcess(result) wfd2 = defer.waitForDeferred(d) yield wfd2 ai2 = wfd2.getResult() if ai2 and isinstance(ai2, AppInstance) and ai2 is ai: Event('instance-found').fire(instance=ai) manager.log('Sucessfully assimilated PID %d' % ai2.pid) if ai.running: continue #may have assimilated the app if not ai.crashed: continue if not ai.enabled: continue #disabled instances are not actionable if self.first_run: continue #avoid process table races Event('instance-crashed').fire(instance=ai) #cool off on eventing for a little while #keep the process objects up to date for process in AppProcess.objects: try: if not process.localInstall: continue if not process.running: AppProcess.delete(process) except: err('process book keeping error') d = defer.Deferred() config.reactor.callLater(0.01, d.callback, None) wfd = defer.waitForDeferred(d) yield wfd wfd.getResult() self.first_run = False yield 'done'
def findProcesses(self): """Attempt to find a process by an ASSIMILATION pattern. This is a relatively naive attempt to find an application that works in most cases. NOTE: If your ASSIMILATION pattern includes group matches the dictionary will be updated with the output of ``groupdict() from re.search``. If droned is able to read the environment settings from the application that will be inlcuded in the result dictionary as well. @callback (list) - sorted([(int('PID'), dict), ...]) @errback (twisted.python.failure.Failure()) @return defer.Deferred() """ candidates = {} def safe_process(pid): try: #because processes can be invalid return AppProcess(Server(config.HOSTNAME), pid) except: err('problem') return None if self.PROCESS_REGEX: #rescan the whole system for processes for process in (safe_process(pid) for pid in listProcesses()): try: if not process: continue if not process.__class__.isValid(process): continue if process.pid in candidates: continue if process.ppid != 1: continue #droned wants your daemons if not process.running: continue if not process.localInstall: continue if process.managed: continue #already managed cmd = ' '.join(process.cmdline) if not cmd: continue match = self.PROCESS_REGEX.search(cmd) if not match: continue #remember we tried to set some VARS on startInstance _result = dict(**process.environ) #allows us to set interesting parameters in the regex _result.update(match.groupdict()) _result.update({'pid': process.pid}) candidates[_result['pid']] = _result except: self.log('error searching for process check console log') err('error searching for process') return sorted([(pid, d) for (pid, d) in candidates.items() if pid > 1])
def findProcesses(self): """Attempt to find a process by an ASSIMILATION pattern. This is a relatively naive attempt to find an application that works in most cases. NOTE: If your ASSIMILATION pattern includes group matches the dictionary will be updated with the output of ``groupdict() from re.search``. If droned is able to read the environment settings from the application that will be inlcuded in the result dictionary as well. @callback (list) - sorted([(int('PID'), dict), ...]) @errback (twisted.python.failure.Failure()) @return defer.Deferred() """ candidates = {} def safe_process(pid): try: #because processes can be invalid return AppProcess(Server(config.HOSTNAME), pid) except: err('problem') return None if self.PROCESS_REGEX: #rescan the whole system for processes for process in ( safe_process(pid) for pid in listProcesses() ): try: if not process: continue if not process.__class__.isValid(process): continue if process.pid in candidates: continue if process.ppid != 1: continue #droned wants your daemons if not process.running: continue if not process.localInstall: continue if process.managed: continue #already managed cmd = ' '.join(process.cmdline) if not cmd: continue match = self.PROCESS_REGEX.search(cmd) if not match: continue #remember we tried to set some VARS on startInstance _result = dict(**process.environ) #allows us to set interesting parameters in the regex _result.update(match.groupdict()) _result.update({'pid': process.pid}) candidates[_result['pid']] = _result except: self.log('error searching for process check console log') err('error searching for process') return sorted([(pid, d) for (pid, d) in candidates.items() if pid > 1])
def _scan(self): #wait for assimilation to finish wfd = defer.waitForDeferred(self.assimilating) yield wfd try: wfd.getResult() except: err('assimilation had an error') #scan for all processes, hopefully we have seen them before for pid in listProcesses(): try: AppProcess(Server(config.HOSTNAME), pid) except InvalidProcess: pass except IOError: pass #happens on linux when a pid dies except: err('process table scanning error') #scan for crashed instances for app in App.objects: if not app.__class__.isValid(app): continue for ai in app.localappinstances: if not ai.__class__.isValid(ai): continue if ai.running and not ai.shouldBeRunning: ai.shouldBeRunning = True continue #work around first assimilated/never started if not ai.crashed: continue if not ai.enabled: continue #disabled instances are not actionable if ai in self.tracking: continue Event('instance-crashed').fire(instance=ai) #cool off on eventing for a little while self.tracking.add(ai) reactor.callLater(SERVICECONFIG.recovery_period, self.tracking.discard, ai ) #keep the process objects up to date for process in AppProcess.objects: try: if not process.localInstall: continue if not process.running: AppProcess.delete(process) except: err('process book keeping error') d = defer.Deferred() reactor.callLater(0.01, d.callback, None) wfd = defer.waitForDeferred(d) yield wfd wfd.getResult() yield 'done'
def _first_scan(self): for pid in listProcesses(): try: AppProcess(Server(config.HOSTNAME), pid) except InvalidProcess: pass
def _scan(self): for pid in listProcesses(): try: AppProcess(Server(config.HOSTNAME), pid) except InvalidProcess: pass except IOError: pass #happens on linux when a pid dies except: err('process table scanning error') #scan for crashed instances for app in App.objects: if not app.__class__.isValid(app): continue for ai in app.localappinstances: if not ai.__class__.isValid(ai): continue if ai in self.tracking: continue if not self.first_run: #avoid process table races self.tracking.add(ai) config.reactor.callLater(SERVICECONFIG.recovery_period, self.tracking.discard, ai) if not ai.enabled: continue #skip disabled result = None if ai.running and not ai.shouldBeRunning: ai.shouldBeRunning = True if ai.running: continue manager = AppManager(ai.app.name) if not manager.running: continue #skip managers that are not running if not manager.discover: continue #app manager claims to be ok #look for processes that we can assimilate d = manager.model.findProcesses() wfd = defer.waitForDeferred(d) yield wfd for (pid, result) in wfd.getResult(): d = manager.model.assimilateProcess(result) wfd2 = defer.waitForDeferred(d) yield wfd2 ai2 = wfd2.getResult() if ai2 and isinstance(ai2, AppInstance) and ai2 is ai: Event('instance-found').fire(instance=ai) manager.log('Sucessfully assimilated PID %d' % ai2.pid) if ai.running: continue #may have assimilated the app if not ai.crashed: continue if not ai.enabled: continue #disabled instances are not actionable if self.first_run: continue #avoid process table races Event('instance-crashed').fire(instance=ai) #cool off on eventing for a little while #keep the process objects up to date for process in AppProcess.objects: try: if not process.localInstall: continue if not process.running: AppProcess.delete(process) except: err('process book keeping error') d = defer.Deferred() config.reactor.callLater(0.01, d.callback, None) wfd = defer.waitForDeferred(d) yield wfd wfd.getResult() self.first_run = False yield 'done'