def run(self, src_config_file, apache_config, new_name=None): (uid, gid, mode) = fileutils.get_file_permissions(apache_config.config_file) if new_name: target_path = os.path.join(apache_config.additional_config_dir, new_name) else: target_path = os.path.join(apache_config.additional_config_dir, os.path.basename(src_config_file)) iuprocess.sudo_copy([src_config_file, target_path], self.ctx._get_sudo_password(self), self.ctx.logger) iuprocess.sudo_set_file_permissions(target_path, uid, gid, mode, self.ctx.logger, self.ctx._get_sudo_password(self))
def _update_and_copy_fcgi_file(self, sudo_password): # Run during install. # We need to update the fcgi file to refer to the virtualenv copy # of python fcgi_src_file = os.path.abspath(os.path.join(self.config.projecthome, "www/cgi-bin/trac.fcgi")) rc = iufile.subst_in_file(fcgi_src_file, [('\\#\\!\\/usr\\/bin\\/python', '#!' + self.config.input_ports.trachome.python_exe)]) if (rc != 1) and (rc != 0): raise UserError(errors[ERR_TRAC_FCGI_SETUP], developer_msg="Unable to substitute python executable %s in fcgi script %s" % (self.config.input_ports.trachome.python_exe, fcgi_src_file)) # cp fcgi file to cgi-executables directory iuprocess.sudo_copy([fcgi_src_file, os.path.join(self.config.cgi_dir, self.config.projectname + ".fcgi")], sudo_password, logger) iuprocess.sudo_chmod("+x", [os.path.join(self.config.cgi_dir, self.config.projectname + ".fcgi")], sudo_password, logger)
def install(self, download_url): logger.debug("installing trac project %s" % self.config.projectname ) # get the passwords that we will need from the repository sudo_password = \ install_context.password_repository.get_value(self.config.sudo_password) admin_password = \ install_context.password_repository.get_value(self.config.admin_password) try: trac_admin_exe = os.path.join(self.config.trachome, "bin/trac-admin") rc = iuprocess.run_and_log_program([trac_admin_exe, self.config.projecthome, "initenv", self.config.projectname, self.config.projectdb, self.config.version_control, self.config.repository], {}, logger, None, None) if rc != 0: raise UserError(errors[ERR_TRACADMIN_FAILURE]) logger.debug("trac-admin ran successfully.") permissions = [ "BROWSER_VIEW", "CHANGESET_VIEW", "FILE_VIEW", "LOG_VIEW", "MILESTONE_VIEW", "REPORT_SQL_VIEW", "REPORT_VIEW", "ROADMAP_VIEW", "SEARCH_VIEW", "TICKET_CREATE", "TICKET_APPEND", "TICKET_MODIFY", "TICKET_VIEW", "TIMELINE_VIEW", "WIKI_CREATE", "WIKI_MODIFY", "WIKI_DELETE", "WIKI_VIEW" ] # drop permissions for anonymous rc = iuprocess.run_and_log_program([trac_admin_exe, self.config.projecthome, "permission", "remove", "anonymous"] + permissions, {}, logger, None, None) if rc != 0: raise UserError(errors[ERR_TRACADMIN_FAILURE]) logger.debug("trac-admin removed permissions for anonymous.") # add permissions for authenticated rc = iuprocess.run_and_log_program([trac_admin_exe, self.config.projecthome, "permission", "remove", "authenticated", '*'], {}, logger, None, None) rc = iuprocess.run_and_log_program([trac_admin_exe, self.config.projecthome, "permission", "add", "authenticated"] + permissions, {}, logger, None, None) if rc != 0: raise UserError(errors[ERR_TRACADMIN_FAILURE]) logger.debug("trac-admin added permissions for authenticated.") # now add permission for admin user rc = iuprocess.run_and_log_program([trac_admin_exe, self.config.projecthome, "permission", "add", self.config.administrator, "TRAC_ADMIN"], {}, logger, None, None) logger.debug("trac-admin added permissions successfully.") if os.path.exists(self.config.password_file) == False: # set up the password file and add admin with initial password logger.debug("about to make password file") # TODO: htpasswd_exe is the program installed with Apache to create/update passwords. # This causes us to have an implicit dependency on apache. Need to figure out # a way to remove this dependency. Perhaps we can provide generic methods on the webserver # service class or in the engage.utils package. htpasswd_exe = self.config.input_ports.webserver.htpasswd_exe rc = iuprocess.run_and_log_program([htpasswd_exe, "-cbm", self.config.password_file, self.config.administrator, admin_password], {}, logger, None, None) else: pass # XXX: check user administrator exists trac_ini_file = os.path.abspath(os.path.join(self.config.projecthome, "conf/trac.ini")) logger.debug("Looking for ini file " + trac_ini_file) if os.path.exists(trac_ini_file) == False: raise UserError(errors[ERR_TRAC_INI_NOT_FOUND]) # now hack the trac.ini file for git plugin if self.config.version_control == "git": trac_ini_file_changed = trac_ini_file + ".changed" git_bin = self.config.input_ports.repository.git_exe escaped_git_bin = string.replace(git_bin, "/", "\/") logger.debug("git path is " + git_bin) f = open(trac_ini_file, "r") (tmpf, tmpn) = tempfile.mkstemp() for line in f : cline = line.replace("cached_repository = false", "cached_repository = true") cline = cline.replace("persistent_cache = false", "persistent_cache = true") cline = re.sub("git_bin = .*$", "git_bin = " + git_bin, cline) os.write(tmpf, cline) os.write(tmpf, "[components]\ntracext.git.* = enabled\n"); f.close() os.close(tmpf) shutil.copyfile(tmpn, trac_ini_file) cfg = TracConfig(trac_ini_file) # basic setup # set base_url cfg.update("trac", "base_url", self.config.get_base_url()) # set up notification # By default, use SMTP # See http://trac.edgewall.org/wiki/TracNotification notification_string = self.config.get_smtp_notification_string() cfg.set_config(json.loads(notification_string)) #plugins logger.debug(self.config.acctmgrconf) conf = json.loads((self.config.acctmgrconf).__str__()) logger.debug(conf) cfg.set_config(conf) cfg.update("account-manager", "password_file", self.config.password_file) # disable new users registering on the web cfg.update("components", "acct_mgr.web_ui.registrationmodule", "disabled") logger.debug(self.config.gitpluginconf) conf = json.loads((self.config.gitpluginconf).__str__()) cfg.set_config(conf) logger.debug(self.config.iniadminconf) conf = json.loads((self.config.iniadminconf).__str__()) cfg.set_config(conf) logger.debug(self.config.themeengineconf) conf = json.loads((self.config.themeengineconf).__str__()) cfg.set_config(conf) logger.debug(self.config.gfappconf) conf = json.loads((self.config.gfappconf).__str__()) cfg.set_config(conf) cfg.update("gfapp", "tracbin", self.config.trachome) cfg.update("gfapp", "trachome", self.config.projecthome) logger.debug(self.config.permredirectconf) conf = json.loads((self.config.permredirectconf).__str__()) cfg.set_config(conf) logger.debug(self.config.gfdownloadconf) conf = json.loads((self.config.gfdownloadconf).__str__()) cfg.set_config(conf) # enable logging cfg.update("logging", "log_file", os.path.join(self.config.projecthome, "trac.log")) cfg.update("logging", "log_type", "file") cfg.update("logging", "log_level", "DEBUG") cfg.update("trac", "mainnav", "wiki,genforma,search") menu_string = self.config.get_menu_string() menu_f = cStringIO.StringIO(menu_string) menu_cfg = ConfigParser.SafeConfigParser() menu_cfg.readfp(menu_f) menu_f.close() for section in menu_cfg.sections(): for (menuname, menuval) in menu_cfg.items(section): cfg.update(section, menuname, menuval) cfg.writeback() logger.debug("Done updating trac.ini file") # upgrade trac environment rc = iuprocess.run_and_log_program([trac_admin_exe, self.config.projecthome, "upgrade"], {}, logger, None, None) if rc != 0: raise UserError(errors[ERR_TRAC_DEPLOY]) # set up Apache + Fastcgi if self.config.webserver == "apache-fastcgi" : logger.debug("setting up apache fastcgi") # trac deploy # make fastcgi config file rc = iuprocess.run_and_log_program([trac_admin_exe, self.config.projecthome, "deploy", os.path.join(self.config.projecthome, "www")], {}, logger, None, None) if rc != 0: raise UserError(errors[ERR_TRAC_DEPLOY]) fcgi_config_file_path = os.path.join(self.config.additional_config_dir, self.config.projectname + ".conf") if os.path.exists(fcgi_config_file_path): logger.warn("Apache configuration file already exists. Will be overwritten.") httpd_config_string = self.config.get_httpd_config_string([("TRAC_ENV", self.config.projecthome), ("TRAC_ENV_PARENT_DIR", "%s/../" % self.config.projecthome)]) (tmpf, tmpn) = tempfile.mkstemp() os.write(tmpf, httpd_config_string) if self.config.protocol == "https": https_config_string = self.config.get_https_config_string() os.write(tmpf, https_config_string) os.close(tmpf) iuprocess.sudo_copy([tmpn, fcgi_config_file_path], sudo_password, logger) self._update_and_copy_fcgi_file(sudo_password) # make sure the project directory is writeable by apache user iuprocess.sudo_chown(self.config.input_ports.webserver.apache_user, [self.config.projecthome], sudo_password, logger, recursive=True) # XXX: hack: need to fix. tracd runs as current user and needs access to log directory # but apache does not iuprocess.sudo_chown(os.environ["LOGNAME"], [self.config.logdir], sudo_password, logger, recursive=True) logger.debug("Done installing httpd configuration files") except iuprocess.SudoError, e: exc_info = sys.exc_info() sys.exc_clear() raise convert_exc_to_user_error(exc_info, errors[ERR_TRAC_SUDO_CALL], nested_exc_info=e.get_nested_exc_info())