예제 #1
0
    def create(self):
        """Create a new test environment.
        This sets up Trac, calls :meth:`create_repo` and sets up
        authentication.
        """
        os.mkdir(self.dirname)
        # testing.log gets any unused output from subprocesses
        self.logfile = open(os.path.join(self.dirname, 'testing.log'), 'w')
        self.create_repo()

        config_file = os.path.join(self.dirname, 'config.ini')
        config = Configuration(config_file)
        config.set('repositories', '.dir', self.repo_path_for_initenv())
        config.set('repositories', '.type', self.repotype)
        config.save()
        self._tracadmin('initenv', self.tracdir, self.dburi,
                        '--config=%s' % config_file)
        if call([
                sys.executable,
                os.path.join(self.trac_src, 'contrib', 'htpasswd.py'), "-c",
                "-b", self.htpasswd, "admin", "admin"
        ],
                close_fds=close_fds,
                cwd=self.command_cwd):
            raise Exception('Unable to setup admin password')
        self.adduser('user')
        self.adduser('joe')
        self.grant_perm('admin', 'TRAC_ADMIN')
        env = self.get_trac_environment()
        for component in self.get_enabled_components():
            env.config.set('components', component, 'enabled')
        env.config.save()
        self.post_create(env)
예제 #2
0
파일: __init__.py 프로젝트: akuendig/cydra
    def cli_command(self, project, args):
        """Manipulate the trac environment for a project
        
        Supported arguments:
        - create: creates an environment
        - sync: Synchronizes the configuration with Cydra's requirements
        - addrepo <type> <name> [tracname]: adds the repository to trac, identified by tracname
        - updatedefaults <file>: Adds trac's default options to config"""

        if len(args) < 1 or args[0] not in ['create', 'addrepo', 'sync', 'updatedefaults']:
            print self.cli_command.__doc__
            return

        if args[0] == 'create':
            if self.has_env(project):
                print "Project already has a Trac environment!"
                return

            if self.create(project):
                print "Environment created"
            else:
                print "Creation failed!"

        elif args[0] == 'sync':
            self.sync(project)

            print project.name, "synced"

        elif args[0] == 'addrepo':
            if len(args) < 3:
                print self.cli_command.__doc__
                return

            repository = project.get_repository(args[1], args[2])

            if not repository:
                print "Unknown repository"
                return

            ret = False
            if len(args) == 4:
                ret = self.register_repository(repository, args[3])
            else:
                ret = self.register_repository(repository)

            if ret:
                print "Successfully added repository"
            else:
                print "Adding repository failed!"

        elif args[0] == 'updatedefaults':
            if len(args) < 2:
                print self.cli_command.__doc__
                return

            config = Configuration(args[1])
            # load defaults
            config.set_defaults()
            config.save()
예제 #3
0
    def create(self, options=[], default_data=True):
        """Create the basic directory structure of the environment,
        initialize the database and populate the configuration file
        with default values.

        If options contains ('inherit', 'file'), default values will
        not be loaded; they are expected to be provided by that file
        or other options.

        :raises TracError: if the base directory of `path` does not exist.
        :raises TracError: if `path` exists and is not empty.
        """
        base_dir = os.path.dirname(self.path)
        if not os.path.exists(base_dir):
            raise TracError(
                _(
                    "Base directory '%(env)s' does not exist. Please create it "
                    "and retry.",
                    env=base_dir))

        if os.path.exists(self.path) and os.listdir(self.path):
            raise TracError(_("Directory exists and is not empty."))

        # Create the directory structure
        if not os.path.exists(self.path):
            os.mkdir(self.path)
        os.mkdir(self.htdocs_dir)
        os.mkdir(self.log_dir)
        os.mkdir(self.plugins_dir)
        os.mkdir(self.templates_dir)

        # Create a few files
        create_file(os.path.join(self.path, 'VERSION'), _VERSION + '\n')
        create_file(
            os.path.join(self.path, 'README'),
            'This directory contains a Trac environment.\n'
            'Visit https://trac.edgewall.org/ for more information.\n')

        # Setup the default configuration
        os.mkdir(self.conf_dir)
        config = Configuration(self.config_file_path)
        for section, name, value in options:
            config.set(section, name, value)
        config.save()
        self.setup_config()
        if not any((section, option) == ('inherit', 'file')
                   for section, option, value in options):
            self.config.set_defaults(self)
            self.config.save()

        # Create the sample configuration
        create_file(self.config_file_path + '.sample')
        self._update_sample_config()

        # Create the database
        dbm = DatabaseManager(self)
        dbm.init_db()
        if default_data:
            dbm.insert_default_data()
예제 #4
0
 def set_home_config(self, values):
     syspath = self.conf.getEnvironmentSysPath("home")
     setconf = Configuration(syspath + '/conf/trac.ini')
     try:
         for (main, sub, value) in values:
             setconf.set(main, sub, value)
         setconf.save()
     except:
         return False
     return True
예제 #5
0
 def set_home_config(self, values):
     syspath = self.conf.getEnvironmentSysPath("home")
     setconf = Configuration(syspath + '/conf/trac.ini')
     try:
         for (main, sub, value) in values:
             setconf.set(main, sub, value)
         setconf.save()
     except:
         return False
     return True
예제 #6
0
    def test_set_and_save(self):
        configfile = open(self.filename, 'w')
        configfile.close()

        config = Configuration(self.filename)
        config.set('a', 'option', 'x')
        self.assertEquals('x', config.get('a', 'option'))
        config.save()

        configfile = open(self.filename, 'r')
        self.assertEquals(['[a]\n', 'option = x\n', '\n'],
                          configfile.readlines())
        configfile.close()
예제 #7
0
 def _update_sample_config(self):
     filename = os.path.join(self.env.config_file_path + ".sample")
     if not os.path.isfile(filename):
         return
     config = Configuration(filename)
     for (section, name), option in Option.get_registry().iteritems():
         config.set(section, name, option.dumps(option.default))
     try:
         config.save()
         self.log.info(
             "Wrote sample configuration file with the new " "settings and their default values: %s", filename
         )
     except IOError as e:
         self.log.warn("Couldn't write sample configuration file (%s)", e, exc_info=True)
예제 #8
0
파일: env.py 프로젝트: hanotch/trac
 def _update_sample_config(self):
     filename = os.path.join(self.config_file_path + '.sample')
     if not os.path.isfile(filename):
         return
     config = Configuration(filename)
     config.set_defaults()
     try:
         config.save()
     except EnvironmentError as e:
         self.log.warning("Couldn't write sample configuration file (%s)%s",
                          e, exception_to_unicode(e, traceback=True))
     else:
         self.log.info(
             "Wrote sample configuration file with the new "
             "settings and their default values: %s", filename)
예제 #9
0
파일: env.py 프로젝트: t2y/trac
 def _update_sample_config(self):
     filename = os.path.join(self.env.path, 'conf', 'trac.ini.sample')
     if not os.path.isfile(filename):
         return
     config = Configuration(filename)
     for (section, name), option in Option.get_registry().iteritems():
         config.set(section, name, option.dumps(option.default))
     try:
         config.save()
         self.log.info("Wrote sample configuration file with the new "
                       "settings and their default values: %s",
                       filename)
     except IOError as e:
         self.log.warn("Couldn't write sample configuration file (%s)", e,
                       exc_info=True)
예제 #10
0
    def do(self):
        # Make backup of trac.ini before configuring it
        try:
            shutil.copy(self.conf_file, self.conf_file_back)
        except Exception:
            conf.log.exception("Could not create trac.ini backup")
            return False

        # Open trac.ini for configuration
        config = None
        try:
            config = Configuration(self.conf_file)
        except Exception:
            conf.log.exception("Error while reading config file!")
            return False

        # Enable correct plugin for repository
        try:
            vcs_plugin = self.__vcs_plugin()
            if vcs_plugin:
                config.set('components', vcs_plugin, 'enabled')

            config.set('trac', 'repository_type', self.vcs_type)
        except Exception:
            conf.log.exception("Could not set static settings for trac")
            return False

        try:
            config.set('project', 'descr', self.project.description)
        except Exception:
            conf.log.exception("Couldn't set description")
            return False

        # Remove attachment size (to enable global setting)
        try:
            config.remove("attachment", "max_size")
        except Exception:
            conf.log.exception("Could not remove attachment config property for a new project")

        # Save configuration
        try:
            config.save()
        except Exception:
            conf.log.exception("Failed to save configuration")
            return False

        self.success = True
        return True
예제 #11
0
    def do(self):
        # Make backup of trac.ini before configuring it
        try:
            shutil.copy(self.conf_file, self.conf_file_back)
        except Exception:
            conf.log.exception("Could not create trac.ini backup")
            return False

        # Open trac.ini for configuration
        config = None
        try:
            config = Configuration(self.conf_file)
        except Exception:
            conf.log.exception("Error while reading config file!")
            return False

        # Enable correct plugin for repository
        try:
            vcs_plugin = self.__vcs_plugin()
            if vcs_plugin:
                config.set('components', vcs_plugin, 'enabled')

            config.set('trac', 'repository_type', self.vcs_type)
        except Exception:
            conf.log.exception("Could not set static settings for trac")
            return False

        try:
            config.set('project', 'descr', self.project.description)
        except Exception:
            conf.log.exception("Couldn't set description")
            return False

        # Remove attachment size (to enable global setting)
        try:
            config.remove("attachment", "max_size")
        except Exception:
            conf.log.exception("Could not remove attachment config property for a new project")

        # Save configuration
        try:
            config.save()
        except Exception:
            conf.log.exception("Failed to save configuration")
            return False

        self.success = True
        return True
예제 #12
0
 def writeconfig(self, filepath, dicts=[]):
     """Writes or updates a config file. A list of dictionaries is used so
     that options for different aspects of the configuration can be kept
     separate while being able to update the same sections. Note that the
     result is order dependent where two dictionaries update the same option.
     """
     config = Configuration(filepath)
     file_changed = False
     for data in dicts:
         for section, options in data.iteritems():
             for key, value in options.iteritems():
                 if config.get(section, key, None) != value:
                     # This should be expected to generate a false positive
                     # when two dictionaries update the same option
                     file_changed = True
                 config.set(section, key, value)
     if file_changed:
         if os.path.exists(filepath):
             backupfile(filepath)
         config.save()
예제 #13
0
 def writeconfig(self, filepath, dicts=[]):
     """Writes or updates a config file. A list of dictionaries is used so
     that options for different aspects of the configuration can be kept
     separate while being able to update the same sections. Note that the
     result is order dependent where two dictionaries update the same option.
     """
     config = Configuration(filepath)
     file_changed = False
     for data in dicts:
         for section, options in data.iteritems():
             for key, value in options.iteritems():
                 if config.get(section, key, None) != value:
                     # This should be expected to generate a false positive
                     # when two dictionaries update the same option
                     file_changed = True
                 config.set(section, key, value)
     if file_changed:
         if os.path.exists(filepath):
             backupfile(filepath)
         config.save()
예제 #14
0
    def create(self, options=[]):
        """Create the basic directory structure of the environment,
        initialize the database and populate the configuration file
        with default values.

        If options contains ('inherit', 'file'), default values will
        not be loaded; they are expected to be provided by that file
        or other options.
        """
        # Create the directory structure
        if not os.path.exists(self.path):
            os.mkdir(self.path)
        os.mkdir(self.get_log_dir())
        os.mkdir(self.get_htdocs_dir())
        os.mkdir(os.path.join(self.path, 'plugins'))

        # Create a few files
        create_file(os.path.join(self.path, 'VERSION'), _VERSION + '\n')
        create_file(
            os.path.join(self.path, 'README'),
            'This directory contains a Trac environment.\n'
            'Visit http://trac.edgewall.org/ for more information.\n')

        # Setup the default configuration
        os.mkdir(os.path.join(self.path, 'conf'))
        create_file(os.path.join(self.path, 'conf', 'trac.ini.sample'))
        config = Configuration(os.path.join(self.path, 'conf', 'trac.ini'))
        for section, name, value in options:
            config.set(section, name, value)
        config.save()
        self.setup_config()
        if not any((section, option) == ('inherit', 'file')
                   for section, option, value in options):
            self.config.set_defaults(self)
            self.config.save()

        # Create the database
        DatabaseManager(self).init_db()
예제 #15
0
파일: env.py 프로젝트: pkdevbox/trac
    def create(self, options=[]):
        """Create the basic directory structure of the environment,
        initialize the database and populate the configuration file
        with default values.

        If options contains ('inherit', 'file'), default values will
        not be loaded; they are expected to be provided by that file
        or other options.
        """
        # Create the directory structure
        if not os.path.exists(self.path):
            os.mkdir(self.path)
        os.mkdir(self.get_log_dir())
        os.mkdir(self.get_htdocs_dir())
        os.mkdir(os.path.join(self.path, 'plugins'))

        # Create a few files
        create_file(os.path.join(self.path, 'VERSION'), _VERSION + '\n')
        create_file(os.path.join(self.path, 'README'),
                    'This directory contains a Trac environment.\n'
                    'Visit http://trac.edgewall.org/ for more information.\n')

        # Setup the default configuration
        os.mkdir(os.path.join(self.path, 'conf'))
        create_file(self.config_file_path + '.sample')
        config = Configuration(self.config_file_path)
        for section, name, value in options:
            config.set(section, name, value)
        config.save()
        self.setup_config()
        if not any((section, option) == ('inherit', 'file')
                   for section, option, value in options):
            self.config.set_defaults(self)
            self.config.save()

        # Create the database
        DatabaseManager(self).init_db()
예제 #16
0
파일: __init__.py 프로젝트: akuendig/cydra
    def sync(self, project):
        """Sync the trac environment with cydra
        
        This sets the options returned by ``get_default_options`` and adds Trac's own defaults if necessary"""
        if not self.has_env(project):
            logger.warning('Project %s has no Trac Environment to sync', project.name)
            return

        tracini = os.path.join(self.get_env_path(project), 'conf', 'trac.ini')
        options = self.get_default_options(project)

        # if inherit is enabled, the default values are supposed to be in
        # the inherited file. Thus, we can truncate the config file to get a bare minimum
        if 'inherit_config' in self.component_config:
            options.append(('inherit', 'file', self.component_config['inherit_config']))
            with open(tracini, 'w') as f:
                f.truncate()

        # re-create the configuration file
        config = Configuration(tracini)
        for section, name, value in options:
            config.set(section, name, value)
        config.save()

        # load defaults
        if not any((section, option) == ('inherit', 'file') for section, option, value in options):
            config.set_defaults()
            config.save()

        # check if repositories in cydra match repositories in trac
        env = Environment(self.get_env_path(project))
        rm = RepositoryManager(env)
        trac_repos = rm.get_real_repositories()
        trac_repo_names = [r.reponame for r in trac_repos]

        for repotype, repos in project.data.get('plugins', {}).get('trac', {}).items():
            for repo, tracname in (repos or {}).items():
                if tracname not in trac_repo_names:
                    logger.warning("Removing trac mapping from cydra for %s repo %s", repo, tracname)
                    del repos[repo]
                    if not repos:
                        del project.data.get('plugins', {}).get('trac', {})[repotype]

        # Now do the reverse
        revmap = dict([(y, x) for (x, y) in self.typemap.items()])

        for repo in trac_repos:
            logger.debug('Looking at trac repo %s', repo.reponame)

            try:
                baseparts = repo.get_base().split(':') # This is extremely naiive and possibly breaks some time
                repotype, path = baseparts[0], baseparts[-1]
            except:
                logger.error("Unable to parse: " + repo.get_base())

            reponame = os.path.basename(path)
            if repotype == 'git':
                reponame = reponame[:-4]

            try:
                repository = project.get_repository(revmap[repotype], reponame)
            except:
                logger.error("Unable to locate %s %s (%s)", repotype, reponame, path)
                repository = None

            logger.debug('Cydra repo %r', repository)

            if repository:
                # set this mapping if not there already
                project.data.setdefault('plugins', {}).setdefault('trac', {}).setdefault(repository.type, {})[repository.name] = repo.reponame
                logger.info('Setting trac mapping for %s %s -> %s', repository.type, repository.name, repo.reponame)
            else:
                logger.error("Unable to load %s %s (%s)", revmap[repotype], reponame, path)

        project.save()
예제 #17
0
    def _do_update(self, req):
        """Update component enablement."""
        components = req.args.getlist('component')
        oenabled = req.args.getlist('enable')
        penabled = req.args.getlist('prjenable')

        changes = False
        changed = {}

        # Set global project configuration
        prjconf = Configuration(conf.global_conf_path)

        for component in components:
            c_state = self.get_project_component_state(component, self.config)
            c_activated = (component in oenabled)

            if self.is_plugin_changed(c_state, c_activated):
                self.config.set('components', component,
                                c_activated and 'enabled' or 'disabled')
                self.log.info('%sabling component %s', c_activated and 'En'
                              or 'Dis', component)
                changes = True

            if prjconf:
                cip_state = self.get_project_component_state(
                    component, prjconf)
                cip_activated = (component in penabled)

                if self.is_plugin_changed(cip_state, cip_activated):
                    self.log.info('%sabling project component %s',
                                  cip_activated and 'En' or 'Dis', component)
                    changed[
                        component] = cip_activated and 'enabled' or 'disabled'
                    changes = True

        if prjconf:
            scomponents = req.args.getlist('setting')
            static_items = req.args.getlist('static_setting')

            for scomponent in scomponents:
                values = self.get_project_component_value(
                    scomponent, None, prjconf)
                saved_value = self.parse_value(0, values)
                saved_static = self.parse_value(1, values)

                current_value = req.args.get(scomponent + '.value').replace(
                    '|', '')
                current_static = (scomponent in static_items)

                if saved_value != current_value or saved_static != current_static:
                    if current_static:
                        final_value = current_value
                    else:
                        final_value = current_value + '|no'

                    prjconf.set('settings', scomponent, final_value)
                    changes = True

        if changes:
            self.config.save()

            if prjconf:
                for key in changed.keys():
                    prjconf.set('components', key, changed[key])
                prjconf.save()
예제 #18
0
    def cli_command(self, project, args):
        """Manipulate the trac environment for a project
        
        Supported arguments:
        - create: creates an environment
        - sync: Synchronizes the configuration with Cydra's requirements
        - addrepo <type> <name> [tracname]: adds the repository to trac, identified by tracname
        - updatedefaults <file>: Adds trac's default options to config"""

        if len(args) < 1 or args[0] not in [
                'create', 'addrepo', 'sync', 'updatedefaults'
        ]:
            print self.cli_command.__doc__
            return

        if args[0] == 'create':
            if self.has_env(project):
                print "Project already has a Trac environment!"
                return

            if self.create(project):
                print "Environment created"
            else:
                print "Creation failed!"

        elif args[0] == 'sync':
            self.sync(project)

            print project.name, "synced"

        elif args[0] == 'addrepo':
            if len(args) < 3:
                print self.cli_command.__doc__
                return

            repository = project.get_repository(args[1], args[2])

            if not repository:
                print "Unknown repository"
                return

            ret = False
            if len(args) == 4:
                ret = self.register_repository(repository, args[3])
            else:
                ret = self.register_repository(repository)

            if ret:
                print "Successfully added repository"
            else:
                print "Adding repository failed!"

        elif args[0] == 'updatedefaults':
            if len(args) < 2:
                print self.cli_command.__doc__
                return

            config = Configuration(args[1])
            # load defaults
            config.set_defaults()
            config.save()
예제 #19
0
    def sync(self, project):
        """Sync the trac environment with cydra
        
        This sets the options returned by ``get_default_options`` and adds Trac's own defaults if necessary"""
        if not self.has_env(project):
            logger.warning('Project %s has no Trac Environment to sync',
                           project.name)
            return

        tracini = os.path.join(self.get_env_path(project), 'conf', 'trac.ini')
        options = self.get_default_options(project)

        # if inherit is enabled, the default values are supposed to be in
        # the inherited file. Thus, we can truncate the config file to get a bare minimum
        if 'inherit_config' in self.component_config:
            options.append(
                ('inherit', 'file', self.component_config['inherit_config']))
            with open(tracini, 'w') as f:
                f.truncate()

        # re-create the configuration file
        config = Configuration(tracini)
        for section, name, value in options:
            config.set(section, name, value)
        config.save()

        # load defaults
        if not any((section, option) == ('inherit', 'file')
                   for section, option, value in options):
            config.set_defaults()
            config.save()

        # check if repositories in cydra match repositories in trac
        env = Environment(self.get_env_path(project))
        rm = RepositoryManager(env)
        trac_repos = rm.get_real_repositories()
        trac_repo_names = [r.reponame for r in trac_repos]

        for repotype, repos in project.data.get('plugins', {}).get('trac',
                                                                   {}).items():
            for repo, tracname in (repos or {}).items():
                if tracname not in trac_repo_names:
                    logger.warning(
                        "Removing trac mapping from cydra for %s repo %s",
                        repo, tracname)
                    del repos[repo]
                    if not repos:
                        del project.data.get('plugins', {}).get('trac',
                                                                {})[repotype]

        # Now do the reverse
        revmap = dict([(y, x) for (x, y) in self.typemap.items()])

        for repo in trac_repos:
            logger.debug('Looking at trac repo %s', repo.reponame)

            try:
                baseparts = repo.get_base().split(
                    ':'
                )  # This is extremely naiive and possibly breaks some time
                repotype, path = baseparts[0], baseparts[-1]
            except:
                logger.error("Unable to parse: " + repo.get_base())

            reponame = os.path.basename(path)
            if repotype == 'git':
                reponame = reponame[:-4]

            try:
                repository = project.get_repository(revmap[repotype], reponame)
            except:
                logger.error("Unable to locate %s %s (%s)", repotype, reponame,
                             path)
                repository = None

            logger.debug('Cydra repo %r', repository)

            if repository:
                # set this mapping if not there already
                project.data.setdefault('plugins', {}).setdefault(
                    'trac', {}).setdefault(repository.type,
                                           {})[repository.name] = repo.reponame
                logger.info('Setting trac mapping for %s %s -> %s',
                            repository.type, repository.name, repo.reponame)
            else:
                logger.error("Unable to load %s %s (%s)", revmap[repotype],
                             reponame, path)

        project.save()
예제 #20
0
    def _do_update(self, req):
        """Update component enablement."""
        components = req.args.getlist('component')
        oenabled = req.args.getlist('enable')
        penabled = req.args.getlist('prjenable')

        changes = False
        changed = {}

        # Set global project configuration
        prjconf = Configuration(conf.global_conf_path)

        for component in components:
            c_state = self.get_project_component_state(component, self.config)
            c_activated = (component in oenabled)

            if self.is_plugin_changed(c_state, c_activated):
                self.config.set('components', component,
                                c_activated and 'enabled' or 'disabled')
                self.log.info('%sabling component %s',
                                c_activated and 'En' or 'Dis', component)
                changes = True

            if prjconf:
                cip_state = self.get_project_component_state(component, prjconf)
                cip_activated = (component in penabled)

                if self.is_plugin_changed(cip_state, cip_activated):
                    self.log.info('%sabling project component %s',
                                    cip_activated and 'En' or 'Dis', component)
                    changed[component] = cip_activated and 'enabled' or 'disabled'
                    changes = True

        if prjconf:
            scomponents = req.args.getlist('setting')
            static_items = req.args.getlist('static_setting')

            for scomponent in scomponents:
                values = self.get_project_component_value(scomponent, None, prjconf)
                saved_value = self.parse_value(0, values)
                saved_static = self.parse_value(1, values)

                current_value = req.args.get(scomponent + '.value').replace('|', '')
                current_static = (scomponent in static_items)

                if saved_value != current_value or saved_static != current_static:
                    if current_static:
                        final_value = current_value
                    else:
                        final_value = current_value + '|no'

                    prjconf.set('settings', scomponent, final_value)
                    changes = True

        if changes:
            self.config.save()

            if prjconf:
                for key in changed.keys():
                    prjconf.set('components', key, changed[key])
                prjconf.save()