예제 #1
0
 def do_start_process_args(self, arg):
     """ Command to start a process with a strategy, rules
     and additional arguments. """
     if self._upcheck():
         args = arg.split()
         if len(args) < 3:
             self.ctl.output(
                 'ERROR: start_process_args requires a strategy, '
                 'a program name and extra arguments')
             self.help_start_process_args()
             return
         strategy = DeploymentStrategies._from_string(args[0])
         if strategy is None:
             self.ctl.output(
                 'ERROR: unknown strategy for start_process_args.'
                 ' use one of {}'.format(DeploymentStrategies._strings()))
             self.help_start_process_args()
             return
         namespec = args[1]
         try:
             result = self.supvisors().start_process(
                 strategy, namespec, ' '.join(args[2:]))
         except xmlrpclib.Fault, e:
             self.ctl.output('{}: ERROR ({})'.format(
                 namespec, e.faultString))
         else:
             self.ctl.output('{} started: {}'.format(namespec, result))
예제 #2
0
 def do_restart_application(self, arg):
     """ Command to restart Supvisors applications using a strategy and rules. """
     if self._upcheck():
         args = arg.split()
         if len(args) < 1:
             self.ctl.output(
                 'ERROR: restart_application requires at least a strategy')
             self.help_restart_application()
             return
         strategy = DeploymentStrategies._from_string(args[0])
         if strategy is None:
             self.ctl.output(
                 'ERROR: unknown strategy for restart_application.'
                 ' use one of {}'.format(DeploymentStrategies._strings()))
             self.help_restart_application()
             return
         applications = args[1:]
         if not applications or "all" in applications:
             try:
                 applications = [
                     application_info['application_name']
                     for application_info in
                     self.supvisors().get_all_applications_info()
                 ]
             except xmlrpclib.Fault, e:
                 self.ctl.output('ERROR ({})'.format(e.faultString))
                 applications = []
         for application in applications:
             try:
                 self.supvisors().restart_application(strategy, application)
             except xmlrpclib.Fault, e:
                 self.ctl.output('{}: ERROR ({})'.format(
                     application, e.faultString))
             else:
                 self.ctl.output('{} restarted'.format(application))
예제 #3
0
 def do_start_process(self, arg):
     """ Command to start processes with a strategy and rules. """
     if self._upcheck():
         args = arg.split()
         if len(args) < 1:
             self.ctl.output(
                 'ERROR: start_process requires at least a strategy')
             self.help_start_process()
             return
         strategy = DeploymentStrategies._from_string(args[0])
         if strategy is None:
             self.ctl.output(
                 'ERROR: unknown strategy for start_process. use one of {}'.
                 format(DeploymentStrategies._strings()))
             self.help_start_process()
             return
         processes = args[1:]
         if not processes or "all" in processes:
             try:
                 processes = [
                     '{}:*'.format(application_info['application_name'])
                     for application_info in
                     self.supvisors().get_all_applications_info()
                 ]
             except xmlrpclib.Fault, e:
                 self.ctl.output('ERROR ({})'.format(e.faultString))
                 processes = []
         for process in processes:
             try:
                 result = self.supvisors().start_process(strategy, process)
             except xmlrpclib.Fault, e:
                 self.ctl.output('{}: ERROR ({})'.format(
                     process, e.faultString))
             else:
                 self.ctl.output('{} started: {}'.format(process, result))
예제 #4
0
 def to_deployment_strategy(value):
     """ Convert a string into a DeploymentStrategies enum. """
     strategy = DeploymentStrategies._from_string(value)
     if strategy is None:
         raise ValueError(
             'invalid value for deployment_strategy: {}. expected in {}'.
             format(value, DeploymentStrategies._strings()))
     return strategy
예제 #5
0
 def test_DeploymentStrategies(self):
     """ Test the DeploymentStrategies enumeration. """
     from supvisors.ttypes import DeploymentStrategies
     self.assertEqual(
         'CONFIG',
         DeploymentStrategies._to_string(DeploymentStrategies.CONFIG))
     self.assertEqual(
         'LESS_LOADED',
         DeploymentStrategies._to_string(DeploymentStrategies.LESS_LOADED))
     self.assertEqual(
         'MOST_LOADED',
         DeploymentStrategies._to_string(DeploymentStrategies.MOST_LOADED))
예제 #6
0
    def start_process(self, strategy, namespec, extra_args='', wait=True):
        """ Start a process named namespec iaw the strategy and some of the rules file.
        WARN: the 'wait_exit' rule is not considered here.

        *@param* ``DeploymentStrategies strategy``: the strategy used to choose addresses.

        *@param* ``str namespec``: the process namespec (``name``, ``group:name``, or ``group:*``).

        *@param* ``str extra_args``: extra arguments to be passed to command line.

        *@param* ``bool wait``: wait for the process 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 namespec is unknown to **Supvisors**,
            * with code ``Faults.ALREADY_STARTED`` if process is in a running state,
            * with code ``Faults.ABNORMAL_TERMINATION`` if process could not be started.

        *@return* ``bool``: always ``True`` unless error.
        """
        self._check_operating()
        # check strategy
        if strategy not in DeploymentStrategies._values():
            raise RPCError(Faults.BAD_STRATEGY, '{}'.format(strategy))
        # check names
        application, process = self._get_application_process(namespec)
        processes = [process] if process else application.processes.values()
        # check processes are not already running
        for process in processes:
            if process.running():
                raise RPCError(Faults.ALREADY_STARTED, process.namespec())
        # start all processes
        done = True
        for process in processes:
            done &= self.starter.start_process(strategy, process, extra_args)
        self.logger.debug('startProcess {} done={}'.format(
            process.namespec(), done))
        # wait until application fully RUNNING or (failed)
        if wait and not done:

            def onwait():
                # check starter
                if self.starter.in_progress():
                    return NOT_DONE_YET
                for process in processes:
                    if process.stopped():
                        raise RPCError(Faults.ABNORMAL_TERMINATION,
                                       process.namespec())
                return True

            onwait.delay = 0.1
            return onwait  # deferred
        return True
예제 #7
0
    def start_application(self, strategy, application_name, wait=True):
        """ Start the application named application_name iaw the strategy and the rules file.

        *@param* ``DeploymentStrategies strategy``: the strategy used to choose addresses.

        *@param* ``str application_name``: the name of the application.

        *@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 DeploymentStrategies._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 deployment 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
                if self.starter.in_progress():
                    return NOT_DONE_YET
                if application.state != ApplicationStates.RUNNING:
                    raise RPCError(Faults.ABNORMAL_TERMINATION,
                                   application_name)
                return True

            onwait.delay = 0.5
            return onwait  # deferred
        # if done is True, nothing to do (no deployment or impossible to deploy)
        return not done
예제 #8
0
 def do_start_application(self, arg):
     if self._upcheck():
         args = arg.split()
         if len(args) < 2:
             self.ctl.output('ERROR: start_application requires a strategy and an application name')
             self.help_start_application()
             return
         strategy = DeploymentStrategies._from_string(args[0])
         if strategy is None:
             self.ctl.output('ERROR: unknown strategy for start_application. use one of {}'.format(DeploymentStrategies._strings()))
             self.help_start_application()
             return
         applications = args[1:]
         if not applications or "all" in applications:
             applications = [application_info['application_name'] for application_info in self.supvisors().get_all_applications_info()]
         for application in applications:
             try:
                 result = self.supvisors().start_application(strategy, application)
             except xmlrpclib.Fault, e:
                 self.ctl.output('{}: ERROR ({})'.format(application, e.faultString))
             else:
                 self.ctl.output('{} started: {}'.format(application, result))
예제 #9
0
 def set_deployment_strategy(self, strategy):
     """ Update deployment strategy. """
     self.supvisors.starter.strategy = strategy
     return delayed_info('Deployment strategy set to {}'.format(
         DeploymentStrategies._to_string(strategy)))
예제 #10
0
 def strategy(self, strategy):
     self.logger.info('start processes using strategy {}'.format(
         DeploymentStrategies._to_string(strategy)))
     self._strategy = strategy