def test_checkPidRunning(self): # we should be running pid = os.getpid() self.failUnless(checkPidRunning(pid)) # so should init as pid 1, but run as root self.failUnless(checkPidRunning(1))
def disable(self, args): if len(args) < 1: raise errors.FatalError, 'Please specify what to disable' which = args[0] if which not in ['manager', 'worker']: raise errors.FatalError, 'Please specify either manager or worker' if len(args) < 2: raise errors.FatalError, 'Please specify which %s to %s' % ( which, 'enable') name = args[1] if which == 'manager': managers = self.getManagers() if not name in managers: raise errors.FatalError, 'No manager "%s"' % name pid = getPid('manager', name) if pid: if checkPidRunning(pid): raise errors.FatalError, "Manager %s is running" % name self.disableManager(name) elif which == 'worker': workers = self.getWorkers() if not name in workers: raise errors.FatalError, 'No worker with name %s' % name pid = getPid('worker', name) if pid: if checkPidRunning(pid): raise errors.FatalError, "Worker %s is running" % name self.disableWorker(name) return
def testTermPid(self): ret = os.fork() if ret == 0: # child time.sleep(4) os._exit(0) else: # parent self.failUnless(checkPidRunning(ret)) self.failUnless(termPid(ret)) os.waitpid(ret, 0) # now that it's gone, it should fail self.failIf(checkPidRunning(ret)) self.failIf(termPid(ret))
def stopWorker(self, name): """ Stop the given worker if it is running. """ self.info("Stopping worker %s" % name) pid = getPid('worker', name) if not pid: self.info("worker %s was not running" % name) return True # FIXME: ensure a correct process is running this pid if not checkPidRunning(pid): self.info("Worker %s is dead (stale pid %d), " "cleaning up" % (name, pid)) deletePidFile('worker', name) return False self.debug('Stopping worker %s with pid %d' % (name, pid)) ret = self.stopProcess(pid) # we may need to remove the pid file ourselves, in case the process # failed to do it deletePidFile('worker', name, force=True) if ret: self.info('Stopped worker %s with pid %d' % (name, pid)) return ret
def stopProcess(self, pid): """ Stop the process with the given pid. Wait until the pid has disappeared. """ startClock = time.clock() termClock = startClock + configure.processTermWait killClock = termClock + configure.processKillWait self.debug('stopping process with pid %d' % pid) if not termPid(pid): self.warning('No process with pid %d' % pid) return False # wait for the kill while (checkPidRunning(pid)): if time.clock() > termClock: self.warning("Process with pid %d has not responded to TERM " \ "for %d seconds, killing" % (pid, configure.processTermWait)) killPid(pid) # so it does not get triggered again termClock = killClock + 1.0 if time.clock() > killClock: self.warning("Process with pid %d has not responded to KILL " \ "for %d seconds, stopping" % (pid, configure.processKillWait)) return False # busy loop until kill is done return True
def stopProcess(self, pid): """ Stop the process with the given pid. Wait until the pid has disappeared. """ startClock = time.clock() termClock = startClock + configure.processTermWait killClock = termClock + configure.processKillWait self.debug("stopping process with pid %d" % pid) if not termPid(pid): self.warning("No process with pid %d" % pid) return False # wait for the kill while checkPidRunning(pid): if time.clock() > termClock: self.warning( "Process with pid %d has not responded to TERM " "for %d seconds, killing" % (pid, configure.processTermWait) ) killPid(pid) # so it does not get triggered again termClock = killClock + 1.0 if time.clock() > killClock: self.warning( "Process with pid %d has not responded to KILL " "for %d seconds, stopping" % (pid, configure.processKillWait) ) return False # busy loop until kill is done return True
def possess(daemonizeTo=None): fileutils.ensureDirExists(configure.logdir, "log file") fileutils.ensureDirExists(configure.rundir, "run file") if not daemonizeTo: daemonizeTo = '/' pid = process.getPid('transcoder-admin') if pid: if process.checkPidRunning(pid): raise iherrors.SystemError( 'A flumotion-transcoder-admin is already running ' + 'as pid %d' % pid) else: log.warning("flumotion-transcoder-admin should have been " "running with pid %s. Restarting", str(pid)) process.deletePidFile('transcoder-admin') logPath = os.path.join(configure.logdir, 'transcoder-admin.log') # here we daemonize; so we also change our pid if not daemonizeTo: daemonizeTo = '/' process.daemonize(stdout=logPath, stderr=logPath, directory=daemonizeTo) log.info('Started daemon') # from now on I should keep running, whatever happens log.debug('writing pid file') process.writePidFile('transcoder-admin')
def startManager(self, name, flowNames): """ Start the manager as configured in the manager directory for the given manager name, together with the given flows. @returns: whether or not the manager daemon started """ self.info("Starting manager %s" % name) self.debug("Starting manager with flows %r" % flowNames) managerDir = os.path.join(self.managersDir, name) planetFile = os.path.join(managerDir, 'planet.xml') if not os.path.exists(planetFile): raise errors.FatalError, \ "Planet file %s does not exist" % planetFile self.info("Loading planet %s" % planetFile) flowsDir = os.path.join(managerDir, 'flows') flowFiles = [] for flowName in flowNames: flowFile = os.path.join(flowsDir, "%s.xml" % flowName) if not os.path.exists(flowFile): raise errors.FatalError, \ "Flow file %s does not exist" % flowFile flowFiles.append(flowFile) self.info("Loading flow %s" % flowFile) pid = getPid('manager', name) if pid: if checkPidRunning(pid): raise errors.FatalError, \ "Manager %s is already running (with pid %d)" % (name, pid) else: # there is a stale PID file, warn about it, remove it and # continue self.warning("Removing stale pid file %d for manager %s", pid, name) deletePidFile('manager', name) dirOptions = self._getDirOptions() command = "flumotion-manager %s -D --daemonize-to %s " \ "--service-name %s %s %s" % ( dirOptions, configure.daemondir, name, planetFile, " ".join(flowFiles)) self.debug("starting process %s" % command) retval = self.startProcess(command) if retval == 0: self.debug("Waiting for pid for manager %s" % name) pid = waitPidFile('manager', name) if pid: self.info("Started manager %s with pid %d" % (name, pid)) return True else: self.warning("manager %s could not start" % name) return False self.warning("manager %s could not start (return value %d)" % ( name, retval)) return False
def startWorker(self, name): """ Start the worker as configured in the worker directory for the given worker name. @returns: whether or not the worker daemon started """ self.info("Starting worker %s" % name) if self.checkDisabled('worker', name): print "worker %s is disabled, cannot start" % name return workerFile = os.path.join(self.workersDir, "%s.xml" % name) if not os.path.exists(workerFile): raise errors.FatalError, \ "Worker file %s does not exist" % workerFile pid = getPid('worker', name) if pid: if checkPidRunning(pid): raise errors.FatalError, \ "Worker %s is already running (with pid %d)" % (name, pid) else: # there is a stale PID file, warn about it, remove it and # continue self.warning("Removing stale pid file %d for worker %s", pid, name) deletePidFile('worker', name) # we are sure the worker is not running and there's no pid file self.info("Loading worker %s" % workerFile) dirOptions = self._getDirOptions() command = "flumotion-worker %s -D --daemonize-to %s " \ "--service-name %s %s" % ( dirOptions, configure.daemondir, name, workerFile) self.debug("Running %s" % command) retval = self.startProcess(command) if retval == 0: self.debug("Waiting for pid for worker %s" % name) pid = waitPidFile('worker', name) if pid: self.info("Started worker %s with pid %d" % (name, pid)) return True else: self.warning("worker %s could not start" % name) return False self.warning("worker %s could not start (return value %d)" % (name, retval)) return False
def startWorker(self, name): """ Start the worker as configured in the worker directory for the given worker name. @returns: whether or not the worker daemon started """ self.info("Starting worker %s" % name) if self.checkDisabled('worker', name): print "worker %s is disabled, cannot start" % name return workerFile = os.path.join(self.workersDir, "%s.xml" % name) if not os.path.exists(workerFile): raise errors.FatalError, \ "Worker file %s does not exist" % workerFile pid = getPid('worker', name) if pid: if checkPidRunning(pid): raise errors.FatalError, \ "Worker %s is already running (with pid %d)" % (name, pid) else: # there is a stale PID file, warn about it, remove it and # continue self.warning("Removing stale pid file %d for worker %s", pid, name) deletePidFile('worker', name) # we are sure the worker is not running and there's no pid file self.info("Loading worker %s" % workerFile) dirOptions = self._getDirOptions() command = "flumotion-worker %s -D --daemonize-to %s " \ "--service-name %s %s" % ( dirOptions, configure.daemondir, name, workerFile) self.debug("Running %s" % command) retval = self.startProcess(command) if retval == 0: self.debug("Waiting for pid for worker %s" % name) pid = waitPidFile('worker', name) if pid: self.info("Started worker %s with pid %d" % (name, pid)) return True else: self.warning("worker %s could not start" % name) return False self.warning("worker %s could not start (return value %d)" % ( name, retval)) return False
def status(self, args): """ Give status on processes as given in the args. """ (managers, workers) = self._parseManagersWorkers("status", args) self.debug("Status managers %r and workers %r" % (managers, workers)) for kind, names in [("manager", managers), ("worker", workers)]: for name in names: pid = getPid(kind, name) if not pid: print "%s %s not running" % (kind, name) continue if checkPidRunning(pid): print "%s %s is running with pid %d" % (kind, name, pid) else: print "%s %s dead (stale pid %d)" % (kind, name, pid)
def status(self, args): """ Give status on processes as given in the args. """ (managers, workers) = self._parseManagersWorkers('status', args) self.debug("Status managers %r and workers %r" % (managers, workers)) for kind, names in [('manager', managers), ('worker', workers)]: for name in names: pid = getPid(kind, name) if not pid: if self.checkDisabled(kind, name): print "%s %s is disabled" % (kind, name) else: print "%s %s not running" % (kind, name) continue if checkPidRunning(pid): print "%s %s is running with pid %d" % (kind, name, pid) else: print "%s %s dead (stale pid %d)" % (kind, name, pid)
def stopManager(self, name): """ Stop the given manager if it is running. """ self.info("Stopping manager %s" % name) pid = getPid("manager", name) if not pid: return True # FIXME: ensure a correct process is running this pid if not checkPidRunning(pid): self.info("Manager %s is dead (stale pid %d)" % (name, pid)) return False self.debug("Stopping manager %s with pid %d" % (name, pid)) if not self.stopProcess(pid): return False self.info("Stopped manager %s with pid %d" % (name, pid)) return True
def clean(self, args): """ Clean up dead process pid files as given in the args. """ (managers, workers) = self._parseManagersWorkers("clean", args) self.debug("Clean managers %r and workers %r" % (managers, workers)) for kind, names in [("manager", managers), ("worker", workers)]: for name in names: pid = getPid(kind, name) if not pid: # may be a file that contains bogus data try: deletePidFile(kind, name) print "deleted bogus pid file for %s %s" % (kind, name) except OSError: print ("failed to delete pid file for %s %s " "- ignoring" % (kind, name)) continue if not checkPidRunning(pid): self.debug("Cleaning up stale pid %d for %s %s" % (pid, kind, name)) print "deleting stale pid file for %s %s" % (kind, name) deletePidFile(kind, name)
def condrestart(self, args): """ Restart running processes as given in the args. If nothing specified, condrestart all managers and workers. If first argument is "manager", condrestart given manager. If first argument is "worker", condrestart given worker. @returns: an exit value reflecting the number of processes that failed to start """ (managers, workers) = self._parseManagersWorkers('condrestart', args) self.debug("condrestart managers %r and workers %r" % (managers, workers)) managersDict = self.getManagers() exitvalue = 0 for kind, names in [('manager', managers), ('worker', workers)]: for name in names: pid = getPid(kind, name) if not pid: continue if checkPidRunning(pid): if kind == 'manager': if not self.stopManager(name): exitvalue += 1 continue if not self.startManager(name, managersDict[name]): exitvalue += 1 elif kind == 'worker': if not self.stopWorker(name): exitvalue += 1 continue if not self.startWorker(name): exitvalue += 1 else: print "%s %s dead (stale pid %d)" % (kind, name, pid) return exitvalue
def condrestart(self, args): """ Restart running processes as given in the args. If nothing specified, condrestart all managers and workers. If first argument is "manager", condrestart given manager. If first argument is "worker", condrestart given worker. @returns: an exit value reflecting the number of processes that failed to start """ (managers, workers) = self._parseManagersWorkers('condrestart', args) self.debug("condrestart managers %r and workers %r" % ( managers, workers)) managersDict = self.getManagers() exitvalue = 0 for kind, names in [('manager', managers), ('worker', workers)]: for name in names: pid = getPid(kind, name) if not pid: continue if checkPidRunning(pid): if kind == 'manager': if not self.stopManager(name): exitvalue += 1 continue if not self.startManager(name, managersDict[name]): exitvalue += 1 elif kind == 'worker': if not self.stopWorker(name): exitvalue += 1 continue if not self.startWorker(name): exitvalue += 1 else: print "%s %s dead (stale pid %d)" % (kind, name, pid) return exitvalue
def clean(self, args): """ Clean up dead process pid files as given in the args. """ (managers, workers) = self._parseManagersWorkers('clean', args) self.debug("Clean managers %r and workers %r" % (managers, workers)) for kind, names in [('manager', managers), ('worker', workers)]: for name in names: pid = getPid(kind, name) if not pid: # may be a file that contains bogus data try: deletePidFile(kind, name) print "deleted bogus pid file for %s %s" % (kind, name) except OSError: print( "failed to delete pid file for %s %s " "- ignoring" % (kind, name)) continue if not checkPidRunning(pid): self.debug("Cleaning up stale pid %d for %s %s" % (pid, kind, name)) print "deleting stale pid file for %s %s" % (kind, name) deletePidFile(kind, name)
def startManager(self, name, flowNames): """ Start the manager as configured in the manager directory for the given manager name, together with the given flows. @returns: whether or not the manager daemon started """ self.info("Starting manager %s" % name) if self.checkDisabled('manager', name): print "manager %s is disabled, cannot start" % name return self.debug("Starting manager with flows %r" % flowNames) managerDir = os.path.join(self.managersDir, name) planetFile = os.path.join(managerDir, 'planet.xml') if not os.path.exists(planetFile): raise errors.FatalError, \ "Planet file %s does not exist" % planetFile self.info("Loading planet %s" % planetFile) flowsDir = os.path.join(managerDir, 'flows') flowFiles = [] for flowName in flowNames: flowFile = os.path.join(flowsDir, "%s.xml" % flowName) if not os.path.exists(flowFile): raise errors.FatalError, \ "Flow file %s does not exist" % flowFile flowFiles.append(flowFile) self.info("Loading flow %s" % flowFile) pid = getPid('manager', name) if pid: if checkPidRunning(pid): raise errors.FatalError, \ "Manager %s is already running (with pid %d)" % (name, pid) else: # there is a stale PID file, warn about it, remove it and # continue self.warning("Removing stale pid file %d for manager %s", pid, name) deletePidFile('manager', name) dirOptions = self._getDirOptions() command = "flumotion-manager %s -D --daemonize-to %s " \ "--service-name %s %s %s" % ( dirOptions, configure.daemondir, name, planetFile, " ".join(flowFiles)) self.debug("starting process %s" % command) retval = self.startProcess(command) if retval == 0: self.debug("Waiting for pid for manager %s" % name) pid = waitPidFile('manager', name) if pid: self.info("Started manager %s with pid %d" % (name, pid)) return True else: self.warning("manager %s could not start" % name) return False self.warning("manager %s could not start (return value %d)" % (name, retval)) return False