Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
*@param* ``bool wait``: wait for the application to be fully started.
*@throws* ``RPCError``:
* with code ``Faults.BAD_SUPVISORS_STATE`` if **Supvisors** is not in state ``OPERATION``,
* with code ``Faults.BAD_STRATEGY`` if strategy is unknown to **Supvisors**,
* with code ``Faults.BAD_NAME`` if application_name is unknown to **Supvisors**,
* with code ``Faults.ALREADY_STARTED`` if application is ``STARTING``, ``STOPPING`` or ``RUNNING``,
* with code ``Faults.ABNORMAL_TERMINATION`` if application could not be started.
*@return* ``bool``: always ``True`` unless error or nothing to start.
"""
self._check_operating()
# check strategy
if strategy not in StartingStrategies._values():
raise RPCError(Faults.BAD_STRATEGY, '{}'.format(strategy))
# check application is known
if application_name not in self.context.applications.keys():
raise RPCError(Faults.BAD_NAME, application_name)
# check application is not already RUNNING
application = self.context.applications[application_name]
if application.state != ApplicationStates.STOPPED:
raise RPCError(Faults.ALREADY_STARTED, application_name)
# TODO: develop a predictive model to check if starting can be achieved
# if impossible due to a lack of resources, second try without optionals
# return false if still impossible
done = self.starter.start_application(strategy, application)
self.logger.debug('start_application {} done={}'.format(application_name, done))
# wait until application fully RUNNING or (failed)
if wait and not done:
def onwait():
# check starter
*@throws* ``RPCError``:
* with code ``Faults.BAD_SUPVISORS_STATE`` if **Supvisors** is not in state ``OPERATION`` or ``CONCILIATION``,
* with code ``Faults.BAD_NAME`` if application_name is unknown to **Supvisors**.
* with code ``Faults.NOT_RUNNING`` if application is ``STOPPED``,
*@return* ``bool``: always ``True`` unless error.
"""
self._check_operating_conciliation()
# check application is known
if application_name not in self.context.applications.keys():
raise RPCError(Faults.BAD_NAME, application_name)
# check application is not already STOPPED
application = self.context.applications[application_name]
if application.state == ApplicationStates.STOPPED:
raise RPCError(Faults.NOT_RUNNING, application_name)
# stop the application
done = self.stopper.stop_application(application)
self.logger.debug('stop_application {} done={}'.format(application_name, done))
# wait until application fully STOPPED
if wait and not done:
def onwait():
# check stopper
if self.stopper.in_progress():
return NOT_DONE_YET
if application.state != ApplicationStates.STOPPED:
raise RPCError(Faults.ABNORMAL_TERMINATION, application_name)
return True
onwait.delay = 0.5
return onwait # deferred
# if done is True, nothing to do
return not done
def _makeConfigParser(self, section_name, options):
""" Populate a new UnhosedConfigParser instance with a
section built from an options dict.
"""
config = UnhosedConfigParser()
try:
config.add_section(section_name)
for k, v in dict(options).items():
config.set(section_name, k, v)
except (TypeError, ValueError):
raise RPCError(SupervisorFaults.INCORRECT_PARAMETERS)
return config
def _get_process(self, namespec):
""" Return the ProcessStatus corresponding to the namespec.
A BAD_NAME exception is raised if the process is not found. """
try:
process = self.context.processes[namespec]
except KeyError:
raise RPCError(Faults.BAD_NAME,
'process {} unknown in Supvisors'.format(namespec))
return process
def stopProcessGroup(self, name, wait=True):
""" Stop all processes in the process group named 'name'
@param string name The group name
@param boolean wait Wait for each process to be fully stopped
@return boolean result Always return true unless error.
"""
self._update('stopProcessGroup')
group = self.supervisord.process_groups.get(name)
if group is None:
raise RPCError(Faults.BAD_NAME, name)
processes = group.processes.values()
processes.sort()
processes = [ (group, process) for process in processes ]
killall = make_allfunc(processes, isRunning, self.stopProcess,
wait=wait)
killall.delay = 0.05
killall.rpcinterface = self
return killall # deferred
def log(self, message, level=supervisor.loggers.LevelsByName.INFO):
""" Write an arbitrary message to the main supervisord log. This is
useful for recording information about your twiddling.
@param string message Message to write to the log
@param string|int level Log level name (INFO) or code (20)
@return boolean Always True unless error
"""
self._update('log')
if isinstance(level, str):
level = getattr(supervisor.loggers.LevelsByName,
level.upper(), None)
if supervisor.loggers.LOG_LEVELS_BY_NUM.get(level, None) is None:
raise RPCError(SupervisorFaults.INCORRECT_PARAMETERS)
self.supervisord.options.logger.log(level, message)
return True
def _readProcessLog(self, name, offset, length, channel):
group, process = self._getGroupAndProcess(name)
if process is None:
raise RPCError(Faults.BAD_NAME, name)
logfile = getattr(process.config, '%s_logfile' % channel)
if logfile is None or not os.path.exists(logfile):
raise RPCError(Faults.NO_FILE, logfile)
try:
return as_string(readFile(logfile, int(offset), int(length)))
except ValueError as inst:
why = inst.args[0]
raise RPCError(getattr(Faults, why))
def _readProcessLog(self, name, offset, length, channel):
group, process = self._getGroupAndProcess(name)
logfile = getattr(process.config, '%s_logfile' % channel)
if logfile is None or not os.path.exists(logfile):
raise RPCError(Faults.NO_FILE, logfile)
try:
return readFile(logfile, int(offset), int(length))
except ValueError, inst:
why = inst.args[0]
raise RPCError(getattr(Faults, why))
@param string signal Signal to send, as name ('HUP') or number ('1')
@return boolean
"""
self._update('signalProcess')
group, process = self._getGroupAndProcess(name)
if process is None:
group_name, process_name = split_namespec(name)
return self.signalProcessGroup(group_name, signal=signal)
try:
sig = signal_number(signal)
except ValueError:
raise RPCError(Faults.BAD_SIGNAL, signal)
if process.get_state() not in RUNNING_STATES:
raise RPCError(Faults.NOT_RUNNING, name)
msg = process.signal(sig)
if not msg is None:
raise RPCError(Faults.FAILED, msg)
return True
def methodHelp(self, name):
""" Return a string showing the method's documentation
@param string name The name of the method.
@return string result The documentation for the method name.
"""
methods = self._listMethods()
for methodname in methods.keys():
if methodname == name:
return methods[methodname]
raise RPCError(Faults.SIGNATURE_UNSUPPORTED)