def _setup_mysql_config_files(self): if not( os.path.exists(self.config.bin_dir)): # configure, make, and install mysql locally config_filename = os.path.join(self.config.bin_dir, "mysql_config") path_pat = "\\'\\/usr\\/local\\/mysql\\/" new_path = self.config.home_path + os.sep cnt = iufile.subst_in_file(config_filename, [(path_pat, new_path)]) if cnt==0: raise MysqlError(ERR_CONFIG_FILE, "Install", self.config, {"file":config_filename}) access_filename = os.path.join(self.config.bin_dir, "mysqlaccess") cnt = iufile.subst_in_file(access_filename, [(path_pat, new_path)]) if cnt==0: raise MysqlError(ERR_CONFIG_FILE, "Install", self.config, {"file":access_filename})
def setup_runtime_properties(config): cnt = \ iufile.subst_in_file(config.runtime_properties, [('\\{database\\_user\\}', config.config_port.database_user), ('\\{database\\_password\\}', config.config_port.database_password), ('\\{db\\_hostname\\}', config.input_ports.mysql.host), ('\\{db\\_port\\}', config.input_ports.mysql.port.__str__())]) if cnt != 4: raise OpenmrsError(ERR_RUNTIME_PROPS, "Install", config, msg_args={"file":config.runtime_properties})
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 add_moin_config_settings(self, config_file, settings, imports=None): # add the specified settings to the moinmoin config # file. The settings parameter should be a list of (name, value) # pairs. start_str = "# Add your configuration items here.\n" replacement = start_str + "\n".join([" %s = %s" % (name, value) for (name, value) in settings]) + "\n" pattern_list = [(re.escape(start_str), replacement)] if imports: import_start_str = "from MoinMoin.config import multiconfig, url_prefix_static" additional_imports = import_start_str + "\n" + "\n".join(imports) + "\n" pattern_list += [(re.escape(import_start_str), additional_imports),] expected_substitutions = 2 else: expected_substitutions = 1 cnt = fileutils.subst_in_file(config_file, pattern_list) if cnt != expected_substitutions: raise UserError(errors[ERR_MOIN_ADD_SETTINGS], msg_args={"file":config_file, "id":self.ctx.props.id}, developer_msg="Expected %d substitution(s), got %d instead" % (expected_substitutions, cnt))
def install(self, package, upgrade=False): # verify that the django-admin.py utility was installed (as a part of the # Django package) if not os.path.exists(self.config.django_admin_script): raise UserError(errors[ERR_NO_DJANGO_ADMIN_SCRIPT], msg_args={"file":self.config.django_admin_script}) (file_layout, django_config) = self._extract_package(package) # if present, install any pip requirements requirements_file_path = os.path.join(file_layout.get_app_dir_path(), "requirements.txt") if os.path.exists(requirements_file_path): assert hasattr(self.config.input_ports, "pip") and hasattr(self.config.input_ports.pip, "pipbin"), \ "%s has a requirements file, but resource is not configured for installing dependencies via pip" % self.config.package_name self._install_pip_requirements(requirements_file_path) else: logger.debug("Requirements file '%s' not found, skipping requirements step" % requirements_file_path) if file_layout.has_static_url_mapping(): (static_url, static_root) = file_layout.get_static_url_mapping() else: static_url = static_root = None # Instantiate the settings file substitutions = { gs.INSTALL_PATH: self.config.home_path, gs.HOSTNAME: self.config.config_port.websvr_hostname, gs.PRIVATE_IP_ADDRESS: (lambda x: "'%s'" % x if x else "None")(self.config.input_ports.host.private_ip), gs.PORT: self.config.config_port.websvr_port, gs.SECRET_KEY: gen_password(50, chars=string.digits+string.letters+"!#%&()*+,-./:;<=>?@[]^_`{|}~"), gs.EMAIL_HOST:self.config.config_port.email_host, gs.EMAIL_HOST_USER:self.config.config_port.email_host_user, gs.EMAIL_FROM:self.config.config_port.email_from, gs.EMAIL_HOST_PASSWORD:self.config.config_port.email_password, gs.EMAIL_PORT:self.config.config_port.email_port, gs.ADMIN_NAME:self.config.config_port.admin_name, gs.ADMIN_EMAIL:self.config.config_port.admin_email, gs.TIME_ZONE:self.config.config_port.time_zone, gs.LOG_DIRECTORY:self.config.config_port.log_directory, gs.DATABASE_ENGINE:self.config.input_ports.django_db.ENGINE, gs.DATABASE_NAME:self.config.input_ports.django_db.NAME, gs.DATABASE_USER:self.config.input_ports.django_db.USER, gs.DATABASE_PASSWORD: self.install_context.password_repository.get_value(self.config.input_ports.django_db.PASSWORD) \ if self.config.input_ports.django_db.PASSWORD else '', gs.DATABASE_HOST:self.config.input_ports.django_db.HOST, gs.DATABASE_PORT:self.config.input_ports.django_db.PORT, gs.CACHE_BACKEND:'memcached', gs.CACHE_LOCATION:'localhost:11211', gs.CELERY_CONFIG_BROKER_HOST:'None', gs.CELERY_CONFIG_BROKER_PORT:0, gs.CELERY_CONFIG_BROKER_USER:'******', gs.CELERY_CONFIG_BROKER_PASSWORD:'******', gs.CELERY_CONFIG_BROKER_VHOST:'None', gs.CELERY_CONFIG_CELERY_RESULT_BACKEND:'amqp', gs.REDIS_HOST:"localhost", gs.REDIS_PORT:6379, gs.STATIC_ROOT:static_root } # we need to check that the cache input port is present (it isn't if this is # the gfwebsite resource). if hasattr(self.config.input_ports, "ocache") and self.config.input_ports.ocache.provider == 'memcached': substitutions[gs.CACHE_BACKEND] = 'memcached' substitutions[gs.CACHE_LOCATION] = '%s:%s' % (self.config.input_ports.ocache.host, self.config.input_ports.ocache.port) else: # Dummy substitutions[gs.CACHE_BACKEND] = 'django.core.cache.backends.dummy.DummyCache' substitutions[gs.CACHE_LOCATION] = '' # set up with django-celery if hasattr(self.config.input_ports, "celery") and self.config.input_ports.celery.provider == "celery": # celery configuration logger.info('Adding celery config!') substitutions[gs.CELERY_CONFIG_BROKER_HOST] = self.config.input_ports.celery.BROKER_HOST substitutions[gs.CELERY_CONFIG_BROKER_PORT] = self.config.input_ports.celery.BROKER_PORT substitutions[gs.CELERY_CONFIG_BROKER_USER] = self.config.input_ports.celery.BROKER_USER substitutions[gs.CELERY_CONFIG_BROKER_PASSWORD] = self.config.input_ports.celery.BROKER_PASSWORD substitutions[gs.CELERY_CONFIG_BROKER_VHOST] = self.config.input_ports.celery.BROKER_VHOST substitutions[gs.CELERY_CONFIG_CELERY_RESULT_BACKEND] = 'amqp' else: logger.info('No input port for celery') gs.generate_settings_file(file_layout.get_app_dir_path(), file_layout.get_app_settings_module(), django_config.components, properties=substitutions) # Validate the settings file. We run the validation script as an external program, have the results # written to an external file, and then parse that file to get detailed results. validate_results = \ engage_django_sdk.packager.run_installed_tests_as_subprocess(file_layout.get_app_dir_path(), file_layout.get_app_settings_module(), python_exe_path=self.config.input_ports.python.home, use_logger=logger) rc = validate_results.get_return_code() if validate_results.run_was_successful(): logger.info("Django settings file validation successful") else: raise UserError(errors[ERR_DJANGO_VALIDATE_FAILED], msg_args={"rc":validate_results.get_return_code_desc()}, developer_msg=validate_results.format_messages()) # instantiate the admin script (startup/shutdown/status) from a template substitutions = { "app_short_name": self.config.app_short_name, "install_dir": self.config.home_path, "settings_file_dir": file_layout.get_settings_file_directory(), "python_path": file_layout.get_python_path(), "django_settings_module": file_layout.get_deployed_settings_module(), "python_bin_dir": self.config.python_bin_dir, "websvr_hostname": self.config.input_ports.webserver_config.listen_host, "port": self.config.input_ports.webserver_config.listen_port, "log_directory": self.config.config_port.log_directory } admin_script_tmpl_path = iufile.get_data_file_path(__file__, "django.sh.tmpl") iufile.instantiate_template_file(admin_script_tmpl_path, self.config.app_admin_script, substitutions, logger=logger) os.chmod(self.config.app_admin_script, 0755) # modify manage.py to point at the our local python version and to have the right PYTHONPATH manage_py_file = os.path.join(file_layout.get_settings_file_directory(), "manage.py") if os.path.exists(manage_py_file): logger.debug("Updating manage.py file with correct python path and python executable") # default first line is "#!/usr/bin/env python", but user could # replace this with a different path shbang_pattern = '^\\#\\!.+$' # python.home is the python executable # home_path is where any local modules should go shbang_replacement = "#!%s\nimport sys\nsys.path.extend(%s)" % \ (self.config.input_ports.python.home, file_layout.get_python_path().split(":").__repr__()) import_pattern = re.escape("import settings") import_replacement = "import deployed_settings" call_pattern = re.escape("execute_manager(settings)") call_replacement = "execute_manager(deployed_settings)" cnt = iufile.subst_in_file(manage_py_file, [(shbang_pattern, shbang_replacement), (import_pattern, import_replacement), (call_pattern, call_replacement)]) if cnt != 3: logger.warning("Substitutions for %s did not match expected number (got %d, expecting 3). Your manage.py script might not be usable without hand-modifying it." % (manage_py_file, cnt)) else: logger.debug("No manage.py file, skipping shbang replacement") # make the log directory if not os.path.exists(self.config.config_port.log_directory): logger.action("mkdir -p %s" % self.config.config_port.log_directory) os.makedirs(self.config.config_port.log_directory) # setup the database if self.config.input_ports.django_db.ENGINE=='django.db.backends.sqlite3': database_dir = os.path.dirname(self.config.input_ports.django_db.NAME) if not os.path.exists(database_dir): logger.action("mkdir -p %s" % database_dir) os.makedirs(database_dir) file_layout.run_admin_command("syncdb", ["--noinput"]) if "south" in django_config.installed_apps: # We use the presence of South in INSTALLED_APPS to indicate that # we should run migrations. If South isn't there, migrate will fail. if upgrade: file_layout.run_admin_command("migrate", ["--no-initial-data"]) else: file_layout.run_admin_command("migrate", []) # if we have fixtures and this is the initial install, load them if len(django_config.fixtures)>0 and not upgrade: file_layout.run_admin_command("loaddata", django_config.fixtures) # gather static files, if requested if static_url and \ ('django.contrib.staticfiles' in django_config.installed_apps): if not os.path.exists(static_root): logger.debug("mkdir -p %s" % static_root) os.makedirs(static_root) file_layout.run_admin_command("collectstatic", ["--noinput"]) # See if this application includes the admin password parameter. # If so, we set the password by running a script. try: app_pw = self.config.config_port.app_admin_password except: app_pw = None if app_pw: self._run_python_script("django_set_password.py", ["-c", "-e", self.config.config_port.admin_email, "-s"], file_layout, input=self.config.config_port.app_admin_password) # setup the webserver hooks if self.config.input_ports.webserver_config.webserver_type == "apache": self._wsgi_setup(file_layout) self.ctx.r(apache_utils.restart_apache, self.ctx.props.input_ports.webserver_config)