Exemple #1
0
    def create_hack(self, req, data, vars):
        import fcntl

        messages = []
        created = False
        have_lock = False
        lockfile = open(self.lockfile, "w")
        try:
            rv = fcntl.flock(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
            if rv:
                raise TracError('Failed to acquire lock, error: %i' % rv)
            have_lock = True
        except IOError:
            messages.append(
                'A hack is currently being created by another user. '
                'Please wait a few seconds, then click the "Create hack" '
                'button again.'
            )

        if have_lock:
            steps_done = []
            try:
                # Step 1: create repository paths
                from os import popen

                svn_path = 'file://%s' % \
                    self.env.config.get('trac', 'repository_dir')
                svn_path = svn_path.rstrip('/')
                page_name = vars['WIKINAME']
                hack_path = vars['LCNAME']
                paths = [ '%s/%s' % (svn_path, hack_path) ]
                selected_releases = data['selected_releases']
                if isinstance(selected_releases, (basestring, unicode)):
                    selected_releases = [ selected_releases, ]
                for release in selected_releases:
                    if release == 'anyrelease': continue
                    paths.append("%s/%s/%s" % \
                        (svn_path, hack_path, release))

                cmd  = '/usr/bin/op create-hack %s ' % req.authname
                cmd += '"New hack %s, created by %s" ' % \
                        (page_name, req.authname)
                cmd += '%s 2>&1' % ' '.join(paths)
                output = popen(cmd).readlines()
                if output:
                    raise Exception(
                        "Failed to create Subversion paths:\n%s" % \
                            '\n'.join(output)
                        )
                steps_done.append('repository')

                # Step 2: Add permissions
                from svnauthz.model import User, Path, PathAcl

                authz_file = self.env.config.get('trac', 'authz_file')
                authz = AuthzFileReader().read(authz_file)

                svn_path_acl = PathAcl(User(req.authname), r=True, w=True)
                authz.add_path(Path("/%s" % hack_path, acls = [svn_path_acl,]))
                AuthzFileWriter().write(authz_file, authz)
                steps_done.append('permissions')

                # Step 3: Add component
                component = TicketComponent(self.env)
                component.name = page_name
                component.owner = req.authname
                component.insert()
                steps_done.append('component')

                # Step 4: Create wiki page
                template_page = WikiPage(self.env, self.template)
                page = WikiPage(self.env, page_name)
                page.text = Template(template_page.text).substitute(vars)
                page.save(req.authname, 'New hack %s, created by %s' % \
                          (page_name, req.authname), '0.0.0.0')
                steps_done.append('wiki')

                # Step 5: Tag the new wiki page
                res = Resource('wiki', page_name)
                tags = data['tags'].split() + selected_releases + [data['type']]
                TagSystem(self.env).set_tags(req, res, tags)
                steps_done.append('tags')

                rv = fcntl.flock(lockfile, fcntl.LOCK_UN)
                created = True
            except Exception, e:
                try:
                    if 'tags' in steps_done:
                        res = Resource('wiki', page_name)
                        tags = data['tags'].split() + selected_releases
                        TagSystem(self.env).delete_tags(req, res, tags)
                    if 'wiki' in steps_done:
                        WikiPage(self.env, page_name).delete()
                    if 'component' in steps_done:
                        TicketComponent(self.env, page_name).delete()
                    if 'permissions' in steps_done:
                        authz_file = self.env.config.get('trac', 'authz_file')
                        authz = AuthzFileReader().read(authz_file)
                        authz.del_path(Path("/%s" % hack_path))
                        AuthzFileWriter().write(authz_file, authz)
                    # TODO: rollback subversion path creation
                    rv = fcntl.flock(lockfile, fcntl.LOCK_UN)
                except:
                    self.env.log.error("Rollback failed")
                    rv = fcntl.flock(lockfile, fcntl.LOCK_UN)
                self.env.log.error(e, exc_info=True)
                raise TracError(str(e))
Exemple #2
0
        if repos.has_node(path):
            raise ValidationError(
                'Resulting path "%s" already exists in repository.' % path
            )

        try:
            TicketComponent(self.env, page_name)
        except ResourceNotFound, e:
            pass
        else:
            raise ValidationError(
                'Resulting component "%s" already exists.' % page_name
            )

        authz_file = self.env.config.get('trac', 'authz_file')
        authz = AuthzFileReader().read(authz_file)
        authz_paths = [ p.get_path() for p in authz.get_paths() ]
        for ap in authz_paths:
            if ap.startswith(path):
                raise ValidationError(
                    'Resulting path "%s" already exists in authz file.' % path
                )

        return hack_name


class ReleasesExist(Aspect):
    """Validate that any of the selected releases exist."""
    def __init__(self, env):
        self.env = env