Ejemplo n.º 1
0
    def start(self):
        """Starts SimpleRouterReqService.

        Format of received messages: ['address', '', 'packed_payload']
        Format of responses being sent: ['address', '', 'packed_response']
        """
        if not self.bound:
            self.bind()

        while True:
            response = None
            try:
                data = self.receive()
            except KeyboardInterrupt:
                break
            if not data:
                continue
            address, message = data
            # log.debug('Request: %s' % binascii.hexlify(address))
            # noinspection PyBroadException
            try:
                response = self.process(message)
            except MercuryClientException as mce:
                self.send_error(address,
                                'Encountered client error: {}'.format(mce))
                continue
            except Exception:
                exec_dict = parse_exception()
                log.error('process raised an exception and should not have.')
                log.error(fancy_traceback_short(exec_dict))
                self.send_error(address, 'Encountered server error, sorry')
                continue
            # log.debug('Response: %s' % binascii.hexlify(address))
            self.send(address, response)
        self.cleanup()
Ejemplo n.º 2
0
    async def start(self):
        while not self._kill:
            if not await self.in_poller.poll(self.poll_timeout * 1000):
                log.debug('Receive Poll Timeout')
                continue
            try:
                address, msg = await self.receive()
            except MercuryClientException:
                continue
            # noinspection PyBroadException
            try:
                response = await self.process(msg)
            except MercuryClientException as mce:
                await self.send_error(
                    address, 'Encountered client error: {}'.format(mce))
                continue

            except Exception:
                exec_dict = parse_exception()
                log.error('process raised an exception and should not have.')
                log.error(fancy_traceback_short(exec_dict))
                await self.send_error(address,
                                      'Encountered server error, sorry')
                continue
            await self.send(address, response)

        log.info('Goodbye Cruel World')
        self.cleanup()
Ejemplo n.º 3
0
def entry(press_configuration):
    set_environment(agent_configuration.get('press_environment', {}))

    log.info('Initializing plugins')
    init_plugins(press_configuration)

    return_data = {}

    p = None
    try:
        p = Press(press_configuration)
    except Exception:
        exec_dict = parse_exception()
        log.error('Error during initialization: {}'.format(
            fancy_traceback_short(exec_dict)))
        return_data = {
            'error': True,
            'message': 'Error during initialization',
            'exception': exec_dict
        }

    if p:
        try:
            p.run()
        except Exception:
            exec_dict = parse_exception()
            log.error('Error during deployment: {}'.format(
                fancy_traceback_short(exec_dict)))
            return_data = {
                'error': True,
                'message': 'Error during initialization',
                'exception': exec_dict
            }
        finally:
            if p.layout.committed:
                time.sleep(2)
                p.teardown()

            # Clear logging handlers!
            del logging.getLogger(
                'press').handlers[:]  # python2 doesn't have list.clear()

            # Clear hooks
            clear_hooks()

    return return_data
Ejemplo n.º 4
0
    async def message_handler(self, address, message):
        await self.send(address, self.RESPONSE_OBJECT)

        # noinspection PyBroadException
        try:
            # Await message processing, but drop result
            await self.process(message)
        except Exception:
            exec_dict = parse_exception()
            log.error('process raised an exception and should not have.')
            log.error(fancy_traceback_short(exec_dict))
Ejemplo n.º 5
0
def inspect():
    """
    Runs inspectors and associates collection with a mercury_id
    :return:
    """
    collected = _collect()
    dmi = collected.get('dmi') or {}
    interfaces = collected.get('interfaces') or {}

    collected['mercury_id'] = generate_mercury_id(dmi, interfaces)

    # populate_drivers

    for driver in registered_drivers:
        _wants = driver['class'].wants

        # noinspection PyBroadException
        try:
            devices = driver['class'].probe(
                _wants and collected[_wants] or collected)
        except Exception:
            # probe is implemented in each driver and is not wrapped
            # handle probe errors gracefully and soldier on
            log.error(fancy_traceback_short(
                parse_exception(),
                preamble='Probe function failed for driver {}'.format(
                    driver['name']
                )))
            continue
        if devices:
            set_driver_cache(driver, devices)

    # TODO: Sort RAID drivers based on devices

    for inspector, f in late_inspectors:
        collected[inspector] = f(collected)

    global global_device_info
    global_device_info.update(**collected)

    return global_device_info
Ejemplo n.º 6
0
    async def start(self):
        while True:
            try:
                address, msg = await self.receive()
            except MercuryClientException:
                continue
            # noinspection PyBroadException
            try:
                response = await self.process(msg)
            except MercuryClientException as mce:
                await self.send_error(
                    address, 'Encountered client error: {}'.format(mce))
                continue

            except Exception:
                exec_dict = parse_exception()
                log.error('process raised an exception and should not have.')
                log.error(fancy_traceback_short(exec_dict))
                await self.send_error(address,
                                      'Encountered server error, sorry')
                continue
            await self.send(address, response)
Ejemplo n.º 7
0
    async def message_handler(self, address, message):
        if message.get('_protocol_message') == 'keep_alive':
            log.debug('Keep alive received from {}'.format(address))
            response = {'_protocol_message': 'keep_alive_confirmed'}
        else:
            # noinspection PyBroadException
            try:
                response = await self.process(message)
            except MercuryClientException as mce:
                return await self.send_error(
                    address,
                    'Encountered client error: {}'.format(
                        mce))
            except Exception:
                exec_dict = parse_exception()
                log.error('process raised an exception and should not have.')
                log.error(fancy_traceback_short(exec_dict))
                return await self.send_error(address,
                                             'Encountered server error, sorry')

        await self.send(address, response)
        log.debug('Sent {}'.format(address))
Ejemplo n.º 8
0
def entry(run_configuration, mercury_press_configuration):
    """

    :param run_configuration: The press state file
    :param mercury_press_configuration: press environment configuration from
    mercury-agent.yaml
    :return:
    """
    log.info('Initializing plugins')
    init_plugins(
        run_configuration,
        mercury_press_configuration.get('plugins', {}).get('scan_directories'),
        mercury_press_configuration.get('plugins', {}).get('enabled'))

    return_data = {}

    p = None
    try:
        p = PressOrchestrator(
            run_configuration,
            mercury_press_configuration.get('paths',
                                            {}).get('parted', 'parted'),
            mercury_press_configuration.get('deployment_root', '/mnt/press'),
            mercury_press_configuration.get('staging_directory', '/.press'),
            mercury_press_configuration.get('layout',
                                            {}).get('use_fibre_channel',
                                                    False),
            mercury_press_configuration.get('layout',
                                            {}).get('loop_only', False),
            mercury_press_configuration.get('partition_table',
                                            {}).get('partition_start',
                                                    1048576),
            mercury_press_configuration.get('partition_table',
                                            {}).get('alignment', 1048576),
            mercury_press_configuration.get('volume_group',
                                            {}).get('pe_size', '4MiB'))
    except Exception:
        exec_dict = parse_exception()
        log.error('Error during initialization: {}'.format(
            fancy_traceback_short(exec_dict)))
        return_data = {
            'error': True,
            'message': 'Error during initialization',
            'exception': exec_dict
        }
        cleanup_thread()

    if p:
        try:
            p.run()
        except Exception:
            exec_dict = parse_exception()
            log.error('Error during deployment: {}'.format(
                fancy_traceback_short(exec_dict)))
            return_data = {
                'error': True,
                'message': 'Error during initialization',
                'exception': exec_dict
            }
        finally:
            if p.layout.committed:
                time.sleep(2)
                p.teardown()

            cleanup_thread()

    return return_data
Ejemplo n.º 9
0
    def __management_thread(self):
        """
        Async thread to support shared locking. Forks the entry into it's own memory space
        so that we can use signals to trigger timeouts
        :return:
        """
        self.time_started = time.time()
        traceback_info = None
        # noinspection PyBroadException
        try:
            return_data = self.entry(*self.args, **self.kwargs)
            # TODO: Create response contract for procedures
            if isinstance(return_data, dict) and return_data.get('error'):
                status = 'ERROR'
            else:
                status = 'SUCCESS'
        except Exception:
            exc_dict = parse_exception()
            log.error(fancy_traceback_short(
                exc_dict,
                'Critical error while running task: %s [%s], elapsed' %
                (self.entry.__name__, self.task_id)),
                      extra={
                          'task_id': self.task_id,
                          'job_id': self.job_id
                      })
            traceback_info = parse_exception()
            status = 'ERROR'
            return_data = None
        finally:
            if self.lock:
                log.debug('Releasing lock for %s' % self.lock.task_id,
                          extra={
                              'task_id': self.task_id,
                              'job_id': self.job_id
                          })
                self.lock.release()

        self.time_completed = time.time()
        log.info('Task completed: %s [%s], elapsed %s' %
                 (self.entry.__name__, self.task_id,
                  self.time_completed - self.time_started),
                 extra={
                     'task_id': self.task_id,
                     'job_id': self.job_id
                 })
        log.debug('Publishing response to: %s' % self.backend.zmq_url,
                  extra={
                      'task_id': self.task_id,
                      'job_id': self.job_id
                  })

        response = self.backend.complete_task({
            'status': status,
            'message': return_data,
            'traceback_info': traceback_info,
            'job_id': self.job_id,
            'task_id': self.task_id,
            'time_started': self.time_started,
            'time_completed': self.time_completed,
            'action': 'Completed'
        })
        log.debug('Dispatch successful : %s' % response,
                  extra={
                      'task_id': self.task_id,
                      'job_id': self.job_id
                  })
Ejemplo n.º 10
0
    def __management_thread(self):
        """
        Thread to support shared locking.
        :return:
        """
        self.time_started = time.time()

        # Set task to STARTED status
        self.backend.update_task({
            'task_id': self.task_id,
            'status': 'STARTED',
            'time_started': self.time_started
        })

        traceback = None
        # noinspection PyBroadException
        try:
            return_data = self.entry(*self.args, **self.kwargs)
            # TODO: Create response contract for procedures
            if isinstance(return_data, dict) and return_data.get('error'):
                status = 'ERROR'
            else:
                status = 'SUCCESS'
        except Exception:
            exc_dict = parse_exception()
            log.error(fancy_traceback_short(
                exc_dict, 'Critical error while running task:'
                ' %s [%s], elapsed' % (self.entry.__name__, self.task_id)),
                      extra={
                          'task_id': self.task_id,
                          'job_id': self.job_id
                      })
            traceback = parse_exception()
            status = 'ERROR'
            return_data = None
        finally:
            if self.lock:
                log.debug('Releasing lock for %s' % self.lock.task_id,
                          extra={
                              'task_id': self.task_id,
                              'job_id': self.job_id
                          })
                self.lock.release()

        self.time_completed = time.time()
        log.info('Task completed: %s [%s], elapsed %s' %
                 (self.entry.__name__, self.task_id,
                  self.time_completed - self.time_started),
                 extra={
                     'task_id': self.task_id,
                     'job_id': self.job_id
                 })
        log.debug('Publishing response to: %s' % self.backend.zmq_url,
                  extra={
                      'task_id': self.task_id,
                      'job_id': self.job_id
                  })

        response = self.backend.complete_task({
            'status': status,
            'message': return_data,
            'traceback': traceback,
            'job_id': self.job_id,
            'task_id': self.task_id,
            'time_started': self.time_started,
            'time_completed': self.time_completed,
            'action': 'Completed'
        })
        if response.get('error'):
            log.error('Error dispatching message. [timeout]',
                      extra={
                          'task_id': self.task_id,
                          'job_id': self.job_id
                      })
        else:
            log.info('Dispatch successful : %s' % response,
                     extra={
                         'task_id': self.task_id,
                         'job_id': self.job_id
                     })