Exemple #1
0
def _testcases_for_task(task):
    if not task.is_finished():
        return
    yield E.testcase(
        E(u'system-out', _systemout_for_task(task)),
        classname=task.name)
    for result in task.results:
        testcase = E.testcase(
                classname=task.name,
                name=result.short_path.lstrip('/') or '(none)')
        if result.duration:
            testcase.set('time', '%.0f' % total_seconds(result.duration))
        # For Cancelled and Aborted, the final Warn is the reason message
        if (task.status == TaskStatus.cancelled and
                result == task.results[-1] and
                result.result == TaskResult.warn):
            testcase.append(E.skipped(message=result.log or u'', type=u'skipped'))
        elif (task.status == TaskStatus.aborted and
                result == task.results[-1] and
                result.result == TaskResult.warn):
            testcase.append(E.error(message=result.log or u'', type=u'error'))
        elif result.result in (TaskResult.warn, TaskResult.fail):
            testcase.append(E.failure(message=result.log or u'', type=u'failure'))
        testcase.append(E(u'system-out', _systemout_for_result(result)))
        yield testcase
Exemple #2
0
 def handle(self, command, predecessors):
     if command.get('delay'):
         # Before anything else, we need to wait for our delay period.
         # Instead of just doing time.sleep we do a timed wait on
         # shutting_down, so that our delay doesn't hold up the shutdown.
         logger.debug('Delaying %s seconds for command %s',
                      command['delay'], command['id'])
         if shutting_down.wait(timeout=command['delay']):
             return
     gevent.joinall(predecessors)
     if shutting_down.is_set():
         return
     quiescent_period = command.get('quiescent_period')
     if quiescent_period:
         system_fqdn = command.get('fqdn')
         last_command_finished_at = self.last_command_datetime.get(
             system_fqdn)
         if last_command_finished_at:
             # Get the difference between the time now and the number of
             # seconds until we can run another command
             seconds_to_wait = total_seconds(
                 (last_command_finished_at +
                  datetime.timedelta(seconds=quiescent_period)) -
                 datetime.datetime.utcnow())
         else:
             # Play it safe, wait for the whole period.
             seconds_to_wait = quiescent_period
         if seconds_to_wait > 0:
             logger.debug(
                 'Entering quiescent period, delaying %s seconds for'
                 ' command %s' % (seconds_to_wait, command['id']))
             if shutting_down.wait(timeout=seconds_to_wait):
                 return
     logger.debug('Handling command %r', command)
     self.mark_command_running(command['id'])
     try:
         if command['action'] in (u'on', u'off', 'interrupt'):
             handle_power(command)
         elif command['action'] == u'reboot':
             # For backwards compatibility only. The server now splits
             # reboots into 'off' followed by 'on'.
             handle_power(dict(command.items() + [('action', u'off')]))
             time.sleep(5)
             handle_power(dict(command.items() + [('action', u'on')]))
         elif command['action'] == u'clear_logs':
             handle_clear_logs(self.conf, command)
         elif command['action'] == u'configure_netboot':
             handle_configure_netboot(command)
         elif command['action'] == u'clear_netboot':
             handle_clear_netboot(command)
         else:
             raise ValueError('Unrecognised action %s' % command['action'])
             # XXX or should we just ignore it and leave it queued?
     except Exception, e:
         logger.exception('Error processing command %s', command['id'])
         self.last_command_datetime[
             command['fqdn']] = datetime.datetime.utcnow()
         self.mark_command_failed(command['id'],
                                  '%s: %s' % (e.__class__.__name__, e))
Exemple #3
0
 def handle(self, command, predecessors):
     if command.get('delay'):
         # Before anything else, we need to wait for our delay period.
         # Instead of just doing time.sleep we do a timed wait on
         # shutting_down, so that our delay doesn't hold up the shutdown.
         logger.debug('Delaying %s seconds for command %s',
                 command['delay'], command['id'])
         if shutting_down.wait(timeout=command['delay']):
             return
     gevent.joinall(predecessors)
     if shutting_down.is_set():
         return
     quiescent_period = command.get('quiescent_period')
     if quiescent_period:
         system_fqdn = command.get('fqdn')
         last_command_finished_at = self.last_command_datetime.get(system_fqdn)
         if last_command_finished_at:
             # Get the difference between the time now and the number of
             # seconds until we can run another command
             seconds_to_wait = total_seconds((last_command_finished_at +
                     datetime.timedelta(seconds=quiescent_period)) - 
                 datetime.datetime.utcnow())
         else:
             # Play it safe, wait for the whole period.
             seconds_to_wait = quiescent_period
         if seconds_to_wait > 0:
             logger.debug('Entering quiescent period, delaying %s seconds for'
                 ' command %s' % (seconds_to_wait, command['id']))
             if shutting_down.wait(timeout=seconds_to_wait):
                 return
     logger.debug('Handling command %r', command)
     self.mark_command_running(command['id'])
     try:
         if command['action'] in (u'on', u'off', 'interrupt'):
             handle_power(self.conf, command)
         elif command['action'] == u'reboot':
             # For backwards compatibility only. The server now splits 
             # reboots into 'off' followed by 'on'.
             handle_power(self.conf, dict(command.items() + [('action', u'off')]))
             time.sleep(5)
             handle_power(self.conf, dict(command.items() + [('action', u'on')]))
         elif command['action'] == u'clear_logs':
             handle_clear_logs(self.conf, command)
         elif command['action'] == u'configure_netboot':
             handle_configure_netboot(command)
         elif command['action'] == u'clear_netboot':
             handle_clear_netboot(command)
         else:
             raise ValueError('Unrecognised action %s' % command['action'])
             # XXX or should we just ignore it and leave it queued?
     except netboot.ImageFetchingError as e:
         logger.exception('Error processing command %s', command['id'])
         # It's not the system's fault so don't mark it as broken
         self.mark_command_failed(command['id'], unicode(e), False)
     except Exception, e:
         logger.exception('Error processing command %s', command['id'])
         self.mark_command_failed(command['id'],
                 '%s: %s' % (e.__class__.__name__, e), True)
Exemple #4
0
    def get_queued_command_details(self):
        lab_controller = identity.current.user.lab_controller
        max_running_commands = config.get('beaker.max_running_commands')
        if max_running_commands:
            running_commands = Command.query\
                    .join(Command.system)\
                    .filter(System.lab_controller == lab_controller)\
                    .filter(Command.status == CommandStatus.running)\
                    .count()
            if running_commands >= max_running_commands:
                return []
        query = Command.query\
                .join(Command.system)\
                .options(contains_eager(Command.system))\
                .filter(System.lab_controller == lab_controller)\
                .filter(Command.status == CommandStatus.queued)\
                .order_by(Command.id)
        if max_running_commands:
            query = query.limit(max_running_commands - running_commands)
        result = []
        for cmd in query:
            d = {
                'id': cmd.id,
                'action': cmd.action,
                'fqdn': cmd.system.fqdn,
                'delay': 0,
                'quiescent_period': cmd.quiescent_period
            }
            if cmd.delay_until:
                d['delay'] = max(
                    0, total_seconds(cmd.delay_until - datetime.utcnow()))
            # Fill in details specific to the type of command
            if cmd.action in (u'on', u'off', u'reboot', u'interrupt'):
                if not cmd.system.power:
                    cmd.abort(u'Power control unavailable for %s' % cmd.system)
                    continue
                d['power'] = {
                    'type': cmd.system.power.power_type.name,
                    'address': cmd.system.power.power_address,
                    'id': cmd.system.power.power_id,
                    'user': cmd.system.power.power_user,
                    'passwd': cmd.system.power.power_passwd,
                }
            elif cmd.action == u'configure_netboot':
                installation = cmd.installation
                distro_tree = cmd.installation.distro_tree
                if distro_tree:
                    schemes = ['http', 'ftp']
                    if distro_tree.arch.arch == 's390' or distro_tree.arch.arch == 's390x':
                        # zPXE needs FTP URLs for the images, it has no HTTP client.
                        # It would be nicer if we could leave this decision up to
                        # beaker-provision, but the API doesn't work like that...
                        schemes = ['ftp']
                    distro_tree_url = distro_tree.url_in_lab(lab_controller,
                                                             scheme=schemes)
                else:
                    distro_tree_url = installation.tree_url
                if not distro_tree_url:
                    cmd.abort(
                        u'No usable URL found for distro tree %s in lab %s' %
                        (distro_tree.id, lab_controller.fqdn))
                    continue

                d['netboot'] = {
                    'kernel_url':
                    urlparse.urljoin(distro_tree_url,
                                     installation.kernel_path),
                    'initrd_url':
                    urlparse.urljoin(distro_tree_url,
                                     installation.initrd_path),
                    'kernel_options':
                    installation.kernel_options or '',
                }
                if distro_tree:
                    d['netboot']['distro_tree_id'] = distro_tree.id
                else:
                    d['netboot']['distro_tree_id'] = None
                if installation.arch:
                    d['netboot']['arch'] = installation.arch.arch
                else:
                    # It must be a queued command left over after migrating from Beaker < 25.
                    d['netboot']['arch'] = distro_tree.arch.arch
            result.append(d)
        return result
Exemple #5
0
    def get_queued_command_details(self):
        lab_controller = identity.current.user.lab_controller
        max_running_commands = config.get('beaker.max_running_commands')
        if max_running_commands:
            running_commands = CommandActivity.query\
                    .join(CommandActivity.system)\
                    .filter(System.lab_controller == lab_controller)\
                    .filter(CommandActivity.status == CommandStatus.running)\
                    .count()
            if running_commands >= max_running_commands:
                return []
        query = CommandActivity.query\
                .join(CommandActivity.system)\
                .options(contains_eager(CommandActivity.system))\
                .filter(System.lab_controller == lab_controller)\
                .filter(CommandActivity.status == CommandStatus.queued)\
                .order_by(CommandActivity.id)
        if max_running_commands:
            query = query.limit(max_running_commands - running_commands)
        result = []
        for cmd in query:
            d = {
                'id': cmd.id,
                'action': cmd.action,
                'fqdn': cmd.system.fqdn,
                'delay': 0,
                'quiescent_period': cmd.quiescent_period
            }
            if cmd.delay_until:
                d['delay'] = max(
                    0, total_seconds(cmd.delay_until - datetime.utcnow()))
            # Fill in details specific to the type of command
            if cmd.action in (u'on', u'off', u'reboot', u'interrupt'):
                if not cmd.system.power:
                    cmd.abort(u'Power control unavailable for %s' % cmd.system)
                    continue
                d['power'] = {
                    'type': cmd.system.power.power_type.name,
                    'address': cmd.system.power.power_address,
                    'id': cmd.system.power.power_id,
                    'user': cmd.system.power.power_user,
                    'passwd': cmd.system.power.power_passwd,
                }
            elif cmd.action == u'configure_netboot':
                distro_tree_url = cmd.distro_tree.url_in_lab(
                    lab_controller, scheme=['http', 'ftp'])
                if not distro_tree_url:
                    cmd.abort(
                        u'No usable URL found for distro tree %s in lab %s' %
                        (cmd.distro_tree.id, lab_controller.fqdn))
                    continue

                if cmd.system.kernel_type.uboot:
                    by_kernel = ImageType.uimage
                    by_initrd = ImageType.uinitrd
                else:
                    by_kernel = ImageType.kernel
                    by_initrd = ImageType.initrd

                kernel = cmd.distro_tree.image_by_type(by_kernel,
                                                       cmd.system.kernel_type)
                if not kernel:
                    cmd.abort(u'Kernel image not found for distro tree %s' %
                              cmd.distro_tree.id)
                    continue
                initrd = cmd.distro_tree.image_by_type(by_initrd,
                                                       cmd.system.kernel_type)
                if not initrd:
                    cmd.abort(u'Initrd image not found for distro tree %s' %
                              cmd.distro_tree.id)
                    continue
                d['netboot'] = {
                    'arch': cmd.distro_tree.arch.arch,
                    'distro_tree_id': cmd.distro_tree.id,
                    'kernel_url': urlparse.urljoin(distro_tree_url,
                                                   kernel.path),
                    'initrd_url': urlparse.urljoin(distro_tree_url,
                                                   initrd.path),
                    'kernel_options': cmd.kernel_options or '',
                }
            result.append(d)
        return result
Exemple #6
0
    def get_queued_command_details(self):
        lab_controller = identity.current.user.lab_controller
        max_running_commands = config.get('beaker.max_running_commands')
        if max_running_commands:
            running_commands = CommandActivity.query\
                    .join(CommandActivity.system)\
                    .filter(System.lab_controller == lab_controller)\
                    .filter(CommandActivity.status == CommandStatus.running)\
                    .count()
            if running_commands >= max_running_commands:
                return []
        query = CommandActivity.query\
                .join(CommandActivity.system)\
                .options(contains_eager(CommandActivity.system))\
                .filter(System.lab_controller == lab_controller)\
                .filter(CommandActivity.status == CommandStatus.queued)\
                .order_by(CommandActivity.id)
        if max_running_commands:
            query = query.limit(max_running_commands - running_commands)
        result = []
        for cmd in query:
            d = {
                'id': cmd.id,
                'action': cmd.action,
                'fqdn': cmd.system.fqdn,
                'delay': 0,
                'quiescent_period': cmd.quiescent_period
            }
            if cmd.delay_until:
                d['delay'] = max(0, total_seconds(cmd.delay_until - datetime.utcnow()))
            # Fill in details specific to the type of command
            if cmd.action in (u'on', u'off', u'reboot', u'interrupt'):
                if not cmd.system.power:
                    cmd.abort(u'Power control unavailable for %s' % cmd.system)
                    continue
                d['power'] = {
                    'type': cmd.system.power.power_type.name,
                    'address': cmd.system.power.power_address,
                    'id': cmd.system.power.power_id,
                    'user': cmd.system.power.power_user,
                    'passwd': cmd.system.power.power_passwd,
                }
            elif cmd.action == u'configure_netboot':
                installation = cmd.installation
                distro_tree = cmd.installation.distro_tree
                distro_tree_url = distro_tree.url_in_lab(lab_controller,
                        scheme=['http', 'ftp'])
                if not distro_tree_url:
                    cmd.abort(u'No usable URL found for distro tree %s in lab %s'
                            % (distro_tree.id, lab_controller.fqdn))
                    continue

                if cmd.system.kernel_type.uboot:
                    by_kernel = ImageType.uimage
                    by_initrd = ImageType.uinitrd
                else:
                    by_kernel = ImageType.kernel
                    by_initrd = ImageType.initrd

                kernel = distro_tree.image_by_type(by_kernel, cmd.system.kernel_type)
                if not kernel:
                    cmd.abort(u'Kernel image not found for distro tree %s' % distro_tree.id)
                    continue
                initrd = distro_tree.image_by_type(by_initrd, cmd.system.kernel_type)
                if not initrd:
                    cmd.abort(u'Initrd image not found for distro tree %s' % distro_tree.id)
                    continue
                d['netboot'] = {
                    'arch': distro_tree.arch.arch,
                    'distro_tree_id': distro_tree.id,
                    'kernel_url': urlparse.urljoin(distro_tree_url, kernel.path),
                    'initrd_url': urlparse.urljoin(distro_tree_url, initrd.path),
                    'kernel_options': installation.kernel_options or '',
                }
            result.append(d)
        return result