def running(self): """called when the reactor is running""" # signals go to the new child, need to do this once the reactor is # running to override it's default signal handlers. for signum, signame in self.SIGNALS.items(): if signame in ("SIGKILL",): continue try: signal.signal(signum, self.routeSignal) except RuntimeError: pass # tried to set an invalid signal from droned.clients import command self.log("Starting %s [%s]" % (self.name, self.label)) pargs = (self.name, self.label, self.reactor) pkwargs = {} global usetty global path self.deferred = command( self.fqcmd, self.args, self.env, path, usetty, {0: "w", 1: "r", 2: "r"}, DaemonProtocol, *pargs, **pkwargs ) self.deferred.addBoth(self.processResult) return self.deferred
def stopInstance(self, label): """Stops an Application Instances based on our models rules @param label: (string) - app instance label @return defer.Deferred - be prepared for Failures() """ stop = dictwrapper(self.SHUTDOWN_INFO) #configure our protocol if 'debug' not in self.stopProtoKwargs: self.stopProtoKwargs['debug'] = False if 'timeout' not in self.stopProtoKwargs: self.stopProtoKwargs['timeout'] = self.DEFAULT_TIMEOUT if 'logger' not in self.stopProtoKwargs: self.stopProtoKwargs['logger'] = self.log return command(stop.STOP_CMD, stop.STOP_ARGS, stop.STOP_ENV, stop.STOP_PATH, stop.STOP_USEPTY, stop.STOP_CHILDFD, self.stopProtocol, *self.stopProtoArgs, **self.stopProtoKwargs)
def running(self): """called when the reactor is running""" #signals go to the new child, need to do this once the reactor is #running to override it's default signal handlers. global masksignals if masksignals: for signum, signame in self.SIGNALS.items(): if signame in ('SIGKILL', ): continue try: signal.signal(signum, self.routeSignal) except RuntimeError: pass #tried to set an invalid signal from droned.clients import command self.log('Starting %s [%s]' % (self.name, self.label)) pargs = (self.name, self.label, self.reactor) pkwargs = {} global usetty global path self.deferred = command(self.fqcmd, self.args, self.env, path, usetty, {}, DaemonProtocol, *pargs, **pkwargs) self.deferred.addBoth(self.processResult) return self.deferred
def startInstance(self, label): """Starts an Application Instances based on our models rules @param label: (string) - app instance label @return defer.Deferred - be prepared for Failures() """ start = dictwrapper(copy.deepcopy(self.STARTUP_INFO)) #configure our protocol if 'debug' not in self.startProtoKwargs: self.startProtoKwargs['debug'] = False if 'timeout' not in self.startProtoKwargs: self.startProtoKwargs['timeout'] = self.DEFAULT_TIMEOUT if 'logger' not in self.startProtoKwargs: self.startProtoKwargs['logger'] = self.log #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # # !! READ THIS COMMENT BLOCK !! # # the callback result from your protocol should return a dictionary # with a KEY 'pid' included and 'pid' should be an integer otherwise # the injected callback immediately following 'command' will fail to # update your instance state. You have been warned. #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! result = None try: thisInst = self.getInstance(label) TIME = str(time.time()) anchor = DIGEST_INIT() anchor.update(self.name) anchor.update(label) anchor.update(TIME) #add some randomness anchor = str(anchor.hexdigest()) #inject some env variables that we may want to retrieve later ENV = { 'DRONED_IDENTIFIER': anchor, 'DRONED_STARTTIME': TIME, 'DRONED_LABEL': label, 'DRONED_APPLICATION': self.name, 'DRONED_LOGDIR': config.LOG_DIR, } if thisInst.version: ENV['DRONED_VERSION'] = thisInst.version #add these vars to the start env of the contained application start.START_ENV.update(ENV) d = command(start.START_CMD, start.START_ARGS, start.START_ENV, start.START_PATH, start.START_USEPTY, start.START_CHILDFD, self.startProtocol, *self.startProtoArgs, **self.startProtoKwargs) wfd = defer.waitForDeferred(d) yield wfd result = wfd.getResult() #we probably might not know the pid yet #if allowed by config search for the instance after some delay pid = result.get('pid', 0) #just in case the protocol knows it if isinstance(self.SEARCH_DELAY, (int, float)) and not pid: d = defer.Deferred() self.reactor.callLater(self.SEARCH_DELAY, d.callback, None) wfd = defer.waitForDeferred(d) yield wfd wfd.getResult() #don't care about this result d = self.findProcesses() wfd = defer.waitForDeferred(d) yield wfd data = wfd.getResult() if data: data = data.pop(0)[1] #we are just going to take the first result.update(data) #we should have the pid captured thisInst.pid = int(result.get('pid', 0)) except: result = Failure() yield result
def startInstance(self, label): """Starts an Application Instances based on our models rules @param label: (string) - app instance label @return defer.Deferred - be prepared for Failures() """ start = dictwrapper(copy.deepcopy(self.STARTUP_INFO)) #configure our protocol if 'debug' not in self.startProtoKwargs: self.startProtoKwargs['debug'] = False if 'timeout' not in self.startProtoKwargs: self.startProtoKwargs['timeout'] = self.DEFAULT_TIMEOUT if 'logger' not in self.startProtoKwargs: self.startProtoKwargs['logger'] = self.log #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # # !! READ THIS COMMENT BLOCK !! # # the callback result from your protocol should return a dictionary # with a KEY 'pid' included and 'pid' should be an integer otherwise # the injected callback immediately following 'command' will fail to # update your instance state. You have been warned. #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! result = None try: thisInst = self.getInstance(label) TIME = str(time.time()) anchor = DIGEST_INIT() anchor.update(self.name) anchor.update(label) anchor.update(TIME) #add some randomness anchor = str(anchor.hexdigest()) #inject some env variables that we may want to retrieve later ENV = { 'DRONED_IDENTIFIER': anchor, 'DRONED_STARTTIME': TIME, 'DRONED_LABEL': label, 'DRONED_APPLICATION': self.name, 'DRONED_LOGDIR': config.LOG_DIR, } if thisInst.version: ENV['DRONED_VERSION'] = thisInst.version #add these vars to the start env of the contained application start.START_ENV.update(ENV) d = command(start.START_CMD, start.START_ARGS, start.START_ENV, start.START_PATH, start.START_USEPTY, start.START_CHILDFD, self.startProtocol, *self.startProtoArgs, **self.startProtoKwargs) wfd = defer.waitForDeferred(d) yield wfd result = wfd.getResult() #we probably might not know the pid yet #if allowed by config search for the instance after some delay pid = result.get('pid', 0) #just in case the protocol knows it if isinstance(self.SEARCH_DELAY, (int, float)) and not pid: d = defer.Deferred() self.reactor.callLater(self.SEARCH_DELAY, d.callback, None) wfd = defer.waitForDeferred(d) yield wfd wfd.getResult() #don't care about this result d = self.findProcesses() wfd = defer.waitForDeferred(d) yield wfd data = wfd.getResult() if data: data = data.pop(0)[1] #we are just going to take the first result.update(data) #we should have the pid captured #this is the proper way to notify the AppInstance that we are running thisInst.pid = int(result.get('pid', 0)) except: result = Failure() yield result