Exemple #1
0
    def should_delete_build(self, build, repos):
        # Ignore pending builds for deactived build configs
        config = BuildConfig.fetch(self.env, build.config)
        if not config.active:
            target_platform = TargetPlatform.fetch(self.env, build.platform)
            if target_platform:
                target_platform_name = '"%s"' % (target_platform.name,)
            else:
                target_platform_name = 'unknown platform "%s"' % (build.platform,)
            log.info('Dropping build of configuration "%s" at '
                     'revision [%s] on %s because the configuration is '
                     'deactivated', config.name, build.rev,
                     target_platform_name)
            return True

        # Stay within the revision limits of the build config
        if (config.min_rev and repos.rev_older_than(build.rev,
                                                    config.min_rev)) \
        or (config.max_rev and repos.rev_older_than(config.max_rev,
                                                    build.rev)):
            # This minimum and/or maximum revision has changed since
            # this build was enqueued, so drop it
            log.info('Dropping build of configuration "%s" at revision [%s] on '
                     '"%s" because it is outside of the revision range of the '
                     'configuration', config.name, build.rev,
                     TargetPlatform.fetch(self.env, build.platform).name)
            return True

        return False
Exemple #2
0
def _get_build_data(env, req, build):
    platform = TargetPlatform.fetch(env, build.platform)
    data = {'id': build.id, 'name': build.slave, 'rev': build.rev,
            'status': _status_label[build.status],
            'platform': getattr(platform, 'name', 'unknown'),
            'cls': _status_label[build.status].replace(' ', '-'),
            'href': req.href.build(build.config, build.id),
            'chgset_href': req.href.changeset(build.rev)}
    if build.started:
        data['started'] = format_datetime(build.started)
        data['started_delta'] = pretty_timedelta(build.started)
        data['duration'] = pretty_timedelta(build.started)
    if build.stopped:
        data['stopped'] = format_datetime(build.stopped)
        data['stopped_delta'] = pretty_timedelta(build.stopped)
        data['duration'] = pretty_timedelta(build.stopped, build.started)
    data['slave'] = {
        'name': build.slave,
        'ipnr': build.slave_info.get(Build.IP_ADDRESS),
        'os_name': build.slave_info.get(Build.OS_NAME),
        'os_family': build.slave_info.get(Build.OS_FAMILY),
        'os_version': build.slave_info.get(Build.OS_VERSION),
        'machine': build.slave_info.get(Build.MACHINE),
        'processor': build.slave_info.get(Build.PROCESSOR)
    }
    return data
Exemple #3
0
    def _process_build_initiation(self, req, config, build):
        self.log.info('Build slave %r initiated build %d', build.slave,
                      build.id)
        build.started = int(time.time())
        build.update()

        for listener in BuildSystem(self.env).listeners:
            listener.build_started(build)

        xml = xmlio.parse(config.recipe)
        xml.attr['branch'] = config.branch
        xml.attr['revision'] = build.rev
        xml.attr['config'] = config.name
        xml.attr['build'] = str(build.id)
        target_platform = TargetPlatform.fetch(self.env, build.platform)
        xml.attr['platform'] = target_platform.name
        xml.attr['name'] = build.slave
        body = str(xml)

        self.log.info('Build slave %r initiated build %d', build.slave,
                      build.id)

        self._send_response(req, 200, body, headers={
                    'Content-Type': 'application/x-bitten+xml',
                    'Content-Length': str(len(body)),
                    'Content-Disposition':
                        'attachment; filename=recipe_%s_r%s.xml' %
                        (config.name, build.rev)})
Exemple #4
0
def _get_build_data(env, req, build):
    platform = TargetPlatform.fetch(env, build.platform)
    data = {
        'id': build.id,
        'name': build.slave,
        'rev': build.rev,
        'status': _status_label[build.status],
        'platform': getattr(platform, 'name', 'unknown'),
        'cls': _status_label[build.status].replace(' ', '-'),
        'href': req.href.build(build.config, build.id),
        'chgset_href': req.href.changeset(build.rev)
    }
    if build.started:
        data['started'] = format_datetime(build.started)
        data['started_delta'] = pretty_timedelta(build.started)
        data['duration'] = pretty_timedelta(build.started)
    if build.stopped:
        data['stopped'] = format_datetime(build.stopped)
        data['stopped_delta'] = pretty_timedelta(build.stopped)
        data['duration'] = pretty_timedelta(build.stopped, build.started)
    data['slave'] = {
        'name': build.slave,
        'ipnr': build.slave_info.get(Build.IP_ADDRESS),
        'os_name': build.slave_info.get(Build.OS_NAME),
        'os_family': build.slave_info.get(Build.OS_FAMILY),
        'os_version': build.slave_info.get(Build.OS_VERSION),
        'machine': build.slave_info.get(Build.MACHINE),
        'processor': build.slave_info.get(Build.PROCESSOR)
    }
    return data
Exemple #5
0
    def _process_build_initiation(self, req, config, build):
        self.log.info('Build slave %r initiated build %d', build.slave,
                      build.id)
        build.started = int(time.time())
        build.update()

        for listener in BuildSystem(self.env).listeners:
            listener.build_started(build)

        xml = xmlio.parse(config.recipe)
        xml.attr['path'] = config.path
        xml.attr['revision'] = build.rev
        xml.attr['config'] = config.name
        xml.attr['build'] = str(build.id)
        target_platform = TargetPlatform.fetch(self.env, build.platform)
        xml.attr['platform'] = target_platform.name
        body = str(xml)

        self.log.info('Build slave %r initiated build %d', build.slave,
                      build.id)

        req.send_response(200)
        req.send_header('Content-Type', 'application/x-bitten+xml')
        req.send_header('Content-Length', str(len(body)))
        req.send_header('Content-Disposition',
                        'attachment; filename=recipe_%s_r%s.xml' %
                        (config.name, build.rev))
        req.write(body)
        raise RequestDone
Exemple #6
0
    def _process_build_initiation(self, req, config, build):
        self.log.info('Build slave %r initiated build %d', build.slave,
                      build.id)
        build.started = int(time.time())
        build.update()

        for listener in BuildSystem(self.env).listeners:
            listener.build_started(build)

        xml = xmlio.parse(config.recipe)
        xml.attr['branch'] = config.branch
        xml.attr['revision'] = build.rev
        xml.attr['config'] = config.name
        xml.attr['build'] = str(build.id)
        target_platform = TargetPlatform.fetch(self.env, build.platform)
        xml.attr['platform'] = target_platform.name
        xml.attr['name'] = build.slave
        body = str(xml)

        self.log.info('Build slave %r initiated build %d', build.slave,
                      build.id)

        self._send_response(req,
                            200,
                            body,
                            headers={
                                'Content-Type':
                                'application/x-bitten+xml',
                                'Content-Length':
                                str(len(body)),
                                'Content-Disposition':
                                'attachment; filename=recipe_%s_r%s.xml' %
                                (config.name, build.rev)
                            })
Exemple #7
0
    def should_delete_build(self, build, repos):
        config = BuildConfig.fetch(self.env, build.config)

        platform = TargetPlatform.fetch(self.env, build.platform)
        # Platform may or may not exist anymore - get safe name for logging
        platform_name = platform and platform.name \
                        or 'unknown platform "%s"' % build.platform

        # Drop build if platform no longer exists
        if not platform:
            self.log.info(
                'Dropping build of configuration "%s" at '
                'revision [%s] on %s because the platform no longer '
                'exists', config.name, build.rev, platform_name)
            return True

        # Ignore pending builds for deactived build configs
        if not config.active:
            self.log.info(
                'Dropping build of configuration "%s" at '
                'revision [%s] on %s because the configuration is '
                'deactivated', config.name, build.rev, platform_name)
            return True

        # If not 'build_all', drop if a more recent revision is available
        if not self.build_all and \
                len(list(Build.select(self.env, config=build.config,
                min_rev_time=build.rev_time, platform=build.platform))) > 1:
            self.log.info(
                'Dropping build of configuration "%s" at revision [%s] '
                'on "%s" because a more recent build exists', config.name,
                build.rev, platform_name)
            return True

        return False
Exemple #8
0
    def should_delete_build(self, build, repos):
        config = BuildConfig.fetch(self.env, build.config)

        platform = TargetPlatform.fetch(self.env, build.platform)
        # Platform may or may not exist anymore - get safe name for logging
        platform_name = platform and platform.name \
                        or 'unknown platform "%s"' % build.platform

        # Drop build if platform no longer exists
        if not platform:
            self.log.info('Dropping build of configuration "%s" at '
                     'revision [%s] on %s because the platform no longer '
                     'exists', config.name, build.rev, platform_name)
            return True

        # Ignore pending builds for deactived build configs
        if not config.active:
            self.log.info('Dropping build of configuration "%s" at '
                     'revision [%s] on %s because the configuration is '
                     'deactivated', config.name, build.rev, platform_name)
            return True

        # If not 'build_all', drop if a more recent revision is available
        if not self.build_all and \
                len(list(Build.select(self.env, config=build.config,
                min_rev_time=build.rev_time, platform=build.platform))) > 1:
            self.log.info('Dropping build of configuration "%s" at revision [%s] '
                     'on "%s" because a more recent build exists',
                         config.name, build.rev, platform_name)
            return True

        return False
Exemple #9
0
 def template_data(self):
     failed_steps = BuildStep.select(self.env, build=self.build.id,
                                     status=BuildStep.FAILURE)
     platform = TargetPlatform.fetch(self.env, id=self.build.platform)
     reposname, repos, change = self.get_change()
     return {
         'build': {
             'id': self.build.id,
             'status': self.readable_states[self.build.status],
             'link': self.build_link(),
             'config': self.build.config,
             'platform': getattr(platform, 'name', 'unknown'),
             'slave': self.build.slave,
             'failed_steps': [{
                 'name': step.name,
                 'description': step.description,
                 'errors': step.errors,
                 'log_messages': self.get_all_log_messages_for_step(step),
             } for step in failed_steps],
         },
         'change': {
             'rev': display_rev(repos, change.rev),
             'link': self.env.abs_href.changeset(change.rev,
                         reposname != '(default)' and reposname or None),
             'author': change.author,
         },
     }
Exemple #10
0
 def test_fetch(self):
     db = self.env.get_db_cnx()
     cursor = db.cursor()
     cursor.execute("INSERT INTO bitten_platform (config,name) "
                    "VALUES (%s,%s)", ('test', 'Windows'))
     id = db.get_last_id(cursor, 'bitten_platform')
     platform = TargetPlatform.fetch(self.env, id)
     assert platform.exists
     self.assertEqual('test', platform.config)
     self.assertEqual('Windows', platform.name)
Exemple #11
0
    def _remove_platforms(self, req):
        req.perm.assert_permission('BUILD_MODIFY')

        sel = req.args.get('sel')
        if not sel:
            raise TracError('No platform selected')
        sel = isinstance(sel, list) and sel or [sel]

        db = self.env.get_db_cnx()
        for platform_id in sel:
            platform = TargetPlatform.fetch(self.env, platform_id, db=db)
            if not platform:
                raise TracError('Target platform %r not found' % platform_id)
            platform.delete(db=db)
        db.commit()
Exemple #12
0
    def _remove_platforms(self, req):
        req.perm.assert_permission('BUILD_MODIFY')

        sel = req.args.get('sel')
        if not sel:
            raise TracError('No platform selected')
        sel = isinstance(sel, list) and sel or [sel]

        db = self.env.get_db_cnx()
        for platform_id in sel:
            platform = TargetPlatform.fetch(self.env, platform_id, db=db)
            if not platform:
                raise TracError('Target platform %r not found' % platform_id)
            platform.delete(db=db)
        db.commit()
Exemple #13
0
    def should_delete_build(self, build, repos):
        config = BuildConfig.fetch(self.env, build.config)
        config_name = config and config.name \
                        or 'unknown config "%s"' % build.config

        platform = TargetPlatform.fetch(self.env, build.platform)
        # Platform may or may not exist anymore - get safe name for logging
        platform_name = platform and platform.name \
                        or 'unknown platform "%s"' % build.platform

        # Drop build if platform no longer exists
        if not platform:
            self.log.info(
                'Dropping build of configuration "%s" at '
                'revision [%s] on %s because the platform no longer '
                'exists', config.name, build.rev, platform_name)
            return True

        # Ignore pending builds for deactived build configs
        if not (config and config.active):
            self.log.info(
                'Dropping build of configuration "%s" at '
                'revision [%s] on %s because the configuration is '
                'deactivated', config_name, build.rev, platform_name)
            return True

        # Stay within the revision limits of the build config
        if (config.min_rev and repos.rev_older_than(build.rev,
                                                    config.min_rev)) \
        or (config.max_rev and repos.rev_older_than(config.max_rev,
                                                    build.rev)):
            self.log.info(
                'Dropping build of configuration "%s" at revision [%s] on '
                '"%s" because it is outside of the revision range of the '
                'configuration', config.name, build.rev, platform_name)
            return True

        # If not 'build_all', drop if a more recent revision is available
        if not self.build_all and \
                len(list(Build.select(self.env, config=build.config,
                min_rev_time=build.rev_time, platform=build.platform))) > 1:
            self.log.info(
                'Dropping build of configuration "%s" at revision [%s] '
                'on "%s" because a more recent build exists', config.name,
                build.rev, platform_name)
            return True

        return False
Exemple #14
0
    def _process_build_initiation(self, req, config, build):
        self.log.info('Build slave %r initiated build %d', build.slave,
                      build.id)
        build.started = int(time.time())
        build.last_activity = build.started
        build.update()

        for listener in BuildSystem(self.env).listeners:
            listener.build_started(build)

        repos_name, repos, repos_path = get_repos(self.env, config.path,
                                                  req.authname)
        xml = xmlio.parse(config.recipe)
        xml.attr['path'] = config.path
        xml.attr['revision'] = build.rev
        xml.attr['config'] = config.name
        xml.attr['build'] = str(build.id)
        target_platform = TargetPlatform.fetch(self.env, build.platform)
        xml.attr['platform'] = target_platform.name
        xml.attr['name'] = build.slave
        xml.attr['form_token'] = req.form_token  # For posting attachments
        xml.attr['reponame'] = repos_name != '(default)' and repos_name or ''
        xml.attr['repopath'] = repos_path.strip('/')
        body = str(xml)

        self.log.info('Build slave %r initiated build %d', build.slave,
                      build.id)

        # create the first step, mark it as in-progress.

        recipe = Recipe(xmlio.parse(config.recipe))
        stepname = recipe.__iter__().next().id

        step = self._start_new_step(build, stepname)
        step.insert()

        self._send_response(req,
                            200,
                            body,
                            headers={
                                'Content-Type':
                                'application/x-bitten+xml',
                                'Content-Length':
                                str(len(body)),
                                'Content-Disposition':
                                'attachment; filename=recipe_%s_r%s.xml' %
                                (config.name, build.rev)
                            })
Exemple #15
0
    def should_delete_build(self, build, repos):
        config = BuildConfig.fetch(self.env, build.config)
        config_name = config and config.name \
                        or 'unknown config "%s"' % build.config

        platform = TargetPlatform.fetch(self.env, build.platform)
        # Platform may or may not exist anymore - get safe name for logging
        platform_name = platform and platform.name \
                        or 'unknown platform "%s"' % build.platform

        # Drop build if platform no longer exists
        if not platform:
            self.log.info('Dropping build of configuration "%s" at '
                     'revision [%s] on %s because the platform no longer '
                     'exists', config.name, build.rev, platform_name)
            return True

        # Ignore pending builds for deactived build configs
        if not (config and config.active):
            self.log.info('Dropping build of configuration "%s" at '
                     'revision [%s] on %s because the configuration is '
                     'deactivated', config_name, build.rev, platform_name)
            return True

        # Stay within the revision limits of the build config
        if (config.min_rev and repos.rev_older_than(build.rev,
                                                    config.min_rev)) \
        or (config.max_rev and repos.rev_older_than(config.max_rev,
                                                    build.rev)):
            self.log.info('Dropping build of configuration "%s" at revision [%s] on '
                     '"%s" because it is outside of the revision range of the '
                     'configuration', config.name, build.rev, platform_name)
            return True

        # If not 'build_all', drop if a more recent revision is available
        if not self.build_all and \
                len(list(Build.select(self.env, config=build.config,
                min_rev_time=build.rev_time, platform=build.platform))) > 1:
            self.log.info('Dropping build of configuration "%s" at revision [%s] '
                     'on "%s" because a more recent build exists',
                         config.name, build.rev, platform_name)
            return True

        return False
Exemple #16
0
 def template_data(self):
     failed_steps = BuildStep.select(self.env,
                                     build=self.build.id,
                                     status=BuildStep.FAILURE)
     platform = TargetPlatform.fetch(self.env, id=self.build.platform)
     reposname, repos, change = self.get_change()
     return {
         'build': {
             'id':
             self.build.id,
             'status':
             self.readable_states[self.build.status],
             'link':
             self.build_link(),
             'config':
             self.build.config,
             'platform':
             getattr(platform, 'name', 'unknown'),
             'slave':
             self.build.slave,
             'failed_steps': [{
                 'name':
                 step.name,
                 'description':
                 step.description,
                 'errors':
                 step.errors,
                 'log_messages':
                 self.get_all_log_messages_for_step(step),
             } for step in failed_steps],
         },
         'change': {
             'rev':
             display_rev(repos, change.rev),
             'link':
             self.env.abs_href.changeset(
                 change.rev, reposname != '(default)' and reposname
                 or None),
             'author':
             change.author,
         },
     }
Exemple #17
0
    def _process_build_initiation(self, req, config, build):
        self.log.info('Build slave %r initiated build %d', build.slave,
                      build.id)
        build.started = int(time.time())
        build.last_activity = build.started
        build.update()

        for listener in BuildSystem(self.env).listeners:
            listener.build_started(build)

        xml = xmlio.parse(config.recipe)
        xml.attr['path'] = config.path
        xml.attr['revision'] = build.rev
        xml.attr['config'] = config.name
        xml.attr['build'] = str(build.id)
        target_platform = TargetPlatform.fetch(self.env, build.platform)
        xml.attr['platform'] = target_platform.name
        xml.attr['name'] = build.slave
        xml.attr['form_token'] = req.form_token # For posting attachments
        body = str(xml)

        self.log.info('Build slave %r initiated build %d', build.slave,
                      build.id)

        # create the first step, mark it as in-progress.

        recipe = Recipe(xmlio.parse(config.recipe))
        stepname = recipe.__iter__().next().id

        step = self._start_new_step(build, stepname)
        step.insert()

        self._send_response(req, 200, body, headers={
                    'Content-Type': 'application/x-bitten+xml',
                    'Content-Length': str(len(body)),
                    'Content-Disposition':
                        'attachment; filename=recipe_%s_r%s.xml' %
                        (config.name, build.rev)})
Exemple #18
0
    def render_admin_panel(self, req, cat, page, path_info):
        data = {}

        # Analyze url
        try:
            config_name, platform_id = path_info.split('/', 1)
        except:
            config_name = path_info
            platform_id = None

        if config_name:  # Existing build config
            warnings = []
            if platform_id or (
                    # Editing or creating one of the config's target platforms
                    req.method == 'POST' and 'new' in req.args):

                if platform_id:  # Editing target platform
                    platform_id = int(platform_id)
                    platform = TargetPlatform.fetch(self.env, platform_id)

                    if req.method == 'POST':
                        if 'cancel' in req.args or \
                                self._update_platform(req, platform):
                            req.redirect(
                                req.abs_href.admin(cat, page, config_name))
                else:  # creating target platform
                    platform = self._create_platform(req, config_name)
                    req.redirect(
                        req.abs_href.admin(cat, page, config_name,
                                           platform.id))

                # Set up template variables
                data['platform'] = {
                    'id':
                    platform.id,
                    'name':
                    platform.name,
                    'exists':
                    platform.exists,
                    'rules': [{
                        'property': propname,
                        'pattern': pattern
                    } for propname, pattern in platform.rules] or [('', '')]
                }

            else:  # Editing existing build config itself
                config = BuildConfig.fetch(self.env, config_name)
                platforms = list(
                    TargetPlatform.select(self.env, config=config.name))

                if req.method == 'POST':
                    if 'remove' in req.args:  # Remove selected platforms
                        self._remove_platforms(req)
                        add_notice(req, "Target Platform(s) Removed.")
                        req.redirect(req.abs_href.admin(
                            cat, page, config.name))

                    elif 'save' in req.args:  # Save this build config
                        warnings = self._update_config(req, config)

                    if not warnings:
                        add_notice(req, "Configuration Saved.")
                        req.redirect(req.abs_href.admin(
                            cat, page, config.name))

                    for warning in warnings:
                        add_warning(req, warning)

                # FIXME: Deprecation notice for old namespace.
                # Remove notice code when migration to new namespace is complete
                if 'http://bitten.cmlenz.net/tools/' in config.recipe:
                    add_notice(
                        req, "Recipe uses a deprecated namespace. "
                        "Replace 'http://bitten.cmlenz.net/tools/' with "
                        "'http://bitten.edgewall.org/tools/'.")

                # Add a notice if configuration is not active
                if not warnings and not config.active and config.recipe:
                    add_notice(
                        req, "Configuration is not active. Activate "
                        "from main 'Configurations' listing to enable it.")

                # Prepare template variables
                data['config'] = {
                    'name':
                    config.name,
                    'label':
                    config.label or config.name,
                    'active':
                    config.active,
                    'branch':
                    config.branch,
                    'description':
                    config.description,
                    'recipe':
                    config.recipe,
                    'platforms': [{
                        'name':
                        platform.name,
                        'id':
                        platform.id,
                        'href':
                        req.href.admin('bitten', 'configs', config.name,
                                       platform.id),
                        'rules': [{
                            'property': propname,
                            'pattern': pattern
                        } for propname, pattern in platform.rules]
                    } for platform in platforms]
                }

        else:  # At the top level build config list
            if req.method == 'POST':
                if 'add' in req.args:  # Add build config
                    config = self._create_config(req)
                    req.redirect(req.abs_href.admin(cat, page, config.name))

                elif 'remove' in req.args:  # Remove selected build configs
                    self._remove_configs(req)

                elif 'apply' in req.args:  # Update active state of configs
                    self._activate_configs(req)
                req.redirect(req.abs_href.admin(cat, page))

            # Prepare template variables
            configs = []
            for config in BuildConfig.select(self.env, include_inactive=True):
                configs.append({
                    'name':
                    config.name,
                    'label':
                    config.label or config.name,
                    'active':
                    config.active,
                    'branch':
                    config.branch,
                    'href':
                    req.href.admin('bitten', 'configs', config.name),
                    'recipe':
                    config.recipe and True or False
                })
            data['configs'] = configs

        add_stylesheet(req, 'bitten/admin.css')
        add_script(req, 'common/js/suggest.js')
        return 'bitten_admin_configs.html', data
Exemple #19
0
    def _render_inprogress(self, req):
        data = {'title': 'In Progress Builds', 'page_mode': 'view-inprogress'}

        db = self.env.get_db_cnx()

        repos = self.env.get_repository(authname=req.authname)
        assert repos, 'No "(default)" Repository: Add a repository or alias ' \
                      'named "(default)" to Trac.'

        configs = []
        for config in BuildConfig.select(self.env, include_inactive=False):
            rev = config.max_rev or repos.youngest_rev
            try:
                if not _has_permission(req.perm, repos, config.path, rev=rev):
                    continue
            except NoSuchNode:
                add_warning(req, "Configuration '%s' points to non-existing "
                        "path '/%s' at revision '%s'. Configuration skipped." \
                                    % (config.name, config.path, rev))
                continue

            self.log.debug(config.name)
            if not config.active:
                continue

            in_progress_builds = Build.select(self.env,
                                              config=config.name,
                                              status=Build.IN_PROGRESS,
                                              db=db)

            current_builds = 0
            builds = []
            # sort correctly by revision.
            for build in sorted(
                    in_progress_builds,
                    cmp=lambda x, y: int(y.rev_time) - int(x.rev_time)):
                rev = build.rev
                build_data = _get_build_data(self.env, req, build)
                build_data['rev'] = rev
                build_data['rev_href'] = req.href.changeset(rev)
                platform = TargetPlatform.fetch(self.env, build.platform)
                build_data['platform'] = platform.name
                build_data['steps'] = []

                for step in BuildStep.select(self.env, build=build.id, db=db):
                    build_data['steps'].append({
                        'name': step.name,
                        'description': step.description,
                        'duration': to_datetime(step.stopped or int(time.time()), utc) - \
                                    to_datetime(step.started, utc),
                        'status': _step_status_label[step.status],
                        'cls': _step_status_label[step.status].replace(' ', '-'),
                        'errors': step.errors,
                        'href': build_data['href'] + '#step_' + step.name
                    })

                builds.append(build_data)
                current_builds += 1

            if current_builds == 0:
                continue

            description = config.description
            if description:
                description = wiki_to_html(description, self.env, req)
            configs.append({
                'name': config.name,
                'label': config.label or config.name,
                'active': config.active,
                'path': config.path,
                'description': description,
                'href': req.href.build(config.name),
                'builds': builds
            })

        data['configs'] = sorted(configs, key=lambda x: x['label'].lower())
        return data
Exemple #20
0
    def render_admin_panel(self, req, cat, page, path_info):
        data = {}

        # Analyze url
        try:
            config_name, platform_id = path_info.split('/', 1)
        except:
            config_name = path_info
            platform_id = None

        if config_name: # Existing build config
            if platform_id or (
                    # Editing or creating one of the config's target platforms
                    req.method == 'POST' and 'new' in req.args):

                if platform_id: # Editing target platform
                    platform_id = int(platform_id)
                    platform = TargetPlatform.fetch(self.env, platform_id)

                    if req.method == 'POST':
                        if 'cancel' in req.args or \
                                self._update_platform(req, platform):
                            req.redirect(req.abs_href.admin(cat, page,
                                                            config_name))
                else: # creating target platform
                    if req.method == 'POST':
                        if 'add' in req.args:
                            self._create_platform(req, config_name)
                            req.redirect(req.abs_href.admin(cat, page,
                                                            config_name))
                        elif 'cancel' in req.args:
                            req.redirect(req.abs_href.admin(cat, page,
                                                            config_name))

                    platform = TargetPlatform(self.env, config=config_name)

                # Set up template variables
                data['platform'] = {
                    'id': platform.id, 'name': platform.name,
                    'exists': platform.exists,
                    'rules': [
                        {'property': propname, 'pattern': pattern}
                        for propname, pattern in platform.rules
                    ] or [('', '')]
                }

            else: # Editing existing build config itself
                config = BuildConfig.fetch(self.env, config_name)
                platforms = list(TargetPlatform.select(self.env,
                                                       config=config.name))

                if req.method == 'POST':
                    if 'add' in req.args: # Add target platform
                        platform = self._create_platform(req, config)
                        req.redirect(req.abs_href.admin(cat, page, config.name))

                    elif 'remove' in req.args: # Remove selected platforms
                        self._remove_platforms(req)
                        req.redirect(req.abs_href.admin(cat, page, config.name))

                    elif 'save' in req.args: # Save this build config
                        self._update_config(req, config)

                    req.redirect(req.abs_href.admin(cat, page))

                # Prepare template variables
                data['config'] = {
                    'name': config.name, 'label': config.label or config.name,
                    'active': config.active, 'path': config.path,
                    'min_rev': config.min_rev, 'max_rev': config.max_rev,
                    'description': config.description,
                    'recipe': config.recipe,
                    'platforms': [{
                        'name': platform.name,
                        'id': platform.id,
                        'href': req.href.admin('bitten', 'configs', config.name,
                                               platform.id),
                        'rules': [{'property': propname, 'pattern': pattern}
                                   for propname, pattern in platform.rules]
                    } for platform in platforms]
                }

        else: # At the top level build config list
            if req.method == 'POST':
                if 'add' in req.args: # Add build config
                    config = self._create_config(req)
                    req.redirect(req.abs_href.admin(cat, page, config.name))

                elif 'remove' in req.args: # Remove selected build configs
                    self._remove_configs(req)

                elif 'apply' in req.args: # Update active state of configs
                    self._activate_configs(req)
                req.redirect(req.abs_href.admin(cat, page))

            # Prepare template variables
            configs = []
            for config in BuildConfig.select(self.env, include_inactive=True):
                configs.append({
                    'name': config.name, 'label': config.label or config.name,
                    'active': config.active, 'path': config.path,
                    'min_rev': config.min_rev, 'max_rev': config.max_rev,
                    'href': req.href.admin('bitten', 'configs', config.name),
                })
            data['configs'] = configs

        add_stylesheet(req, 'bitten/admin.css')
        add_script(req, 'common/js/suggest.js')
        return 'bitten_admin_configs.html', data
Exemple #21
0
    def _render_inprogress(self, req):
        data = {'title': 'In Progress Builds', 'page_mode': 'view-inprogress'}

        db = self.env.get_db_cnx()

        repos = self.env.get_repository(req.authname)

        configs = []
        for config in BuildConfig.select(self.env, include_inactive=False):
            if not repos.authz.has_permission(config.branch):
                continue

            self.log.debug(config.name)
            if not config.active:
                continue

            in_progress_builds = Build.select(self.env,
                                              config=config.name,
                                              status=Build.IN_PROGRESS,
                                              db=db)

            current_builds = 0
            builds = []
            # sort correctly by revision.
            for build in sorted(in_progress_builds,
                                cmp=lambda x, y: int(y.rev) - int(x.rev)):
                rev = build.rev
                build_data = _get_build_data(self.env, req, build)
                build_data['rev'] = rev
                build_data['rev_href'] = req.href.changeset(rev)
                platform = TargetPlatform.fetch(self.env, build.platform)
                build_data['platform'] = platform.name
                build_data['steps'] = []

                for step in BuildStep.select(self.env, build=build.id, db=db):
                    build_data['steps'].append({
                        'name': step.name,
                        'description': step.description,
                        'duration': to_datetime(step.stopped, utc) - \
                                    to_datetime(step.started, utc),
                        'failed': not step.successful,
                        'errors': step.errors,
                        'href': build_data['href'] + '#step_' + step.name
                    })

                builds.append(build_data)
                current_builds += 1

            if current_builds == 0:
                continue

            description = config.description
            if description:
                description = wiki_to_html(description, self.env, req)
            configs.append({
                'name': config.name,
                'label': config.label or config.name,
                'active': config.active,
                'branch': config.branch,
                'description': description,
                'href': req.href.build(config.name),
                'builds': builds
            })

        data['configs'] = configs
        return data
Exemple #22
0
    def _render_inprogress(self, req):
        data = {'title': 'In Progress Builds',
                'page_mode': 'view-inprogress'}

        db = self.env.get_db_cnx()

        repos = self.env.get_repository(authname=req.authname)
        assert repos, 'No "(default)" Repository: Add a repository or alias ' \
                      'named "(default)" to Trac.'

        configs = []
        for config in BuildConfig.select(self.env, include_inactive=False):
            rev = config.max_rev or repos.youngest_rev
            try:
                if not _has_permission(req.perm, repos, config.path, rev=rev):
                    continue
            except NoSuchNode:
                add_warning(req, "Configuration '%s' points to non-existing "
                        "path '/%s' at revision '%s'. Configuration skipped." \
                                    % (config.name, config.path, rev))
                continue

            self.log.debug(config.name)
            if not config.active:
                continue

            in_progress_builds = Build.select(self.env, config=config.name,
                                              status=Build.IN_PROGRESS, db=db)

            current_builds = 0
            builds = []
            # sort correctly by revision.
            for build in sorted(in_progress_builds,
                                cmp=lambda x, y: int(y.rev_time) - int(x.rev_time)):
                rev = build.rev
                build_data = _get_build_data(self.env, req, build)
                build_data['rev'] = rev
                build_data['rev_href'] = req.href.changeset(rev)
                platform = TargetPlatform.fetch(self.env, build.platform)
                build_data['platform'] = platform.name
                build_data['steps'] = []

                for step in BuildStep.select(self.env, build=build.id, db=db):
                    build_data['steps'].append({
                        'name': step.name,
                        'description': step.description,
                        'duration': to_datetime(step.stopped or int(time.time()), utc) - \
                                    to_datetime(step.started, utc),
                        'status': _step_status_label[step.status],
                        'cls': _step_status_label[step.status].replace(' ', '-'),
                        'errors': step.errors,
                        'href': build_data['href'] + '#step_' + step.name
                    })

                builds.append(build_data)
                current_builds += 1

            if current_builds == 0:
                continue

            description = config.description
            if description:
                description = wiki_to_html(description, self.env, req)
            configs.append({
                'name': config.name, 'label': config.label or config.name,
                'active': config.active, 'path': config.path,
                'description': description,
                'href': req.href.build(config.name),
                'builds': builds
            })

        data['configs'] = sorted(configs, key=lambda x:x['label'].lower())
        return data
Exemple #23
0
    def render_admin_panel(self, req, cat, page, path_info):
        data = {}

        # Analyze url
        try:
            config_name, platform_id = path_info.split('/', 1)
        except:
            config_name = path_info
            platform_id = None

        if config_name: # Existing build config
            warnings = []
            if platform_id or (
                    # Editing or creating one of the config's target platforms
                    req.method == 'POST' and 'new' in req.args):

                if platform_id: # Editing target platform
                    platform_id = int(platform_id)
                    platform = TargetPlatform.fetch(self.env, platform_id)

                    if req.method == 'POST':
                        if 'cancel' in req.args or \
                                self._update_platform(req, platform):
                            req.redirect(req.abs_href.admin(cat, page,
                                                            config_name))
                else: # creating target platform
                    platform = self._create_platform(req, config_name)
                    req.redirect(req.abs_href.admin(cat, page,
                                            config_name, platform.id))

                # Set up template variables
                data['platform'] = {
                    'id': platform.id, 'name': platform.name,
                    'exists': platform.exists,
                    'rules': [
                        {'property': propname, 'pattern': pattern}
                        for propname, pattern in platform.rules
                    ] or [('', '')]
                }

            else: # Editing existing build config itself
                config = BuildConfig.fetch(self.env, config_name)
                platforms = list(TargetPlatform.select(self.env,
                                                       config=config.name))

                if req.method == 'POST':
                    if 'remove' in req.args: # Remove selected platforms
                        self._remove_platforms(req)
                        add_notice(req, "Target Platform(s) Removed.")
                        req.redirect(req.abs_href.admin(cat, page, config.name))

                    elif 'save' in req.args: # Save this build config
                        warnings = self._update_config(req, config)

                    if not warnings:
                        add_notice(req, "Configuration Saved.")
                        req.redirect(req.abs_href.admin(cat, page, config.name))

                    for warning in warnings:
                        add_warning(req, warning)

                # FIXME: Deprecation notice for old namespace.
                # Remove notice code when migration to new namespace is complete
                if 'http://bitten.cmlenz.net/tools/' in config.recipe:
                    add_notice(req, "Recipe uses a deprecated namespace. "
                        "Replace 'http://bitten.cmlenz.net/tools/' with "
                        "'http://bitten.edgewall.org/tools/'.")

                # Add a notice if configuration is not active
                if not warnings and not config.active and config.recipe:
                    add_notice(req, "Configuration is not active. Activate "
                        "from main 'Configurations' listing to enable it.")

                # Prepare template variables
                data['config'] = {
                    'name': config.name, 'label': config.label or config.name,
                    'active': config.active, 'path': config.path,
                    'min_rev': config.min_rev, 'max_rev': config.max_rev,
                    'description': config.description,
                    'recipe': config.recipe,
                    'platforms': [{
                        'name': platform.name,
                        'id': platform.id,
                        'href': req.href.admin('bitten', 'configs', config.name,
                                               platform.id),
                        'rules': [{'property': propname, 'pattern': pattern}
                                   for propname, pattern in platform.rules]
                    } for platform in platforms]
                }

        else: # At the top level build config list
            if req.method == 'POST':
                if 'add' in req.args: # Add build config
                    config = self._create_config(req)
                    req.redirect(req.abs_href.admin(cat, page, config.name))

                elif 'remove' in req.args: # Remove selected build configs
                    self._remove_configs(req)

                elif 'apply' in req.args: # Update active state of configs
                    self._activate_configs(req)
                req.redirect(req.abs_href.admin(cat, page))

            # Prepare template variables
            configs = []
            for config in BuildConfig.select(self.env, include_inactive=True):
                configs.append({
                    'name': config.name, 'label': config.label or config.name,
                    'active': config.active, 'path': config.path,
                    'min_rev': config.min_rev, 'max_rev': config.max_rev,
                    'href': req.href.admin('bitten', 'configs', config.name),
                    'recipe': config.recipe and True or False
                })
            data['configs'] = sorted(configs, key=lambda x:x['label'].lower())

        add_stylesheet(req, 'bitten/admin.css')
        add_script(req, 'common/js/suggest.js')
        return 'bitten_admin_configs.html', data
Exemple #24
0
    def _render_inprogress(self, req):
        data = {'title': 'In Progress Builds',
                'page_mode': 'view-inprogress'}

        db = self.env.get_db_cnx()

        repos = self.env.get_repository(req.authname)
        if hasattr(repos, 'sync'):
            repos.sync()

        configs = []
        for config in BuildConfig.select(self.env, include_inactive=False):
            if not repos.authz.has_permission(config.path):
                continue

            self.log.debug(config.name)
            if not config.active:
                continue

            in_progress_builds = Build.select(self.env, config=config.name,
                                              status=Build.IN_PROGRESS, db=db)

            current_builds = 0
            builds = []
            # sort correctly by revision.
            for build in sorted(in_progress_builds,
                                cmp=lambda x, y: int(y.rev) - int(x.rev)):
                rev = build.rev
                build_data = _get_build_data(self.env, req, build)
                build_data['rev'] = rev
                build_data['rev_href'] = req.href.changeset(rev)
                platform = TargetPlatform.fetch(self.env, build.platform)
                build_data['platform'] = platform.name
                build_data['steps'] = []

                for step in BuildStep.select(self.env, build=build.id, db=db):
                    build_data['steps'].append({
                        'name': step.name,
                        'description': step.description,
                        'duration': datetime.fromtimestamp(step.stopped) - \
                                    datetime.fromtimestamp(step.started),
                        'failed': not step.successful,
                        'errors': step.errors,
                        'href': build_data['href'] + '#step_' + step.name
                    })

                builds.append(build_data)
                current_builds += 1

            if current_builds == 0: 
                continue

            description = config.description
            if description:
                description = wiki_to_html(description, self.env, req)
            configs.append({
                'name': config.name, 'label': config.label or config.name,
                'active': config.active, 'path': config.path,
                'description': description,
                'href': req.href.build(config.name),
                'builds': builds
            })

        data['configs'] = configs
        return data