def activate_license(): prefs_dir = os.path.expanduser("~/../.java/.userPrefs/com/mendix/core") buildpackutil.mkdir_p(prefs_dir) prefs_template = """<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE map SYSTEM "http://java.sun.com/dtd/preferences.dtd"> <map MAP_XML_VERSION="1.0"> <entry key="id" value="{{LICENSE_ID}}"/> <entry key="license_key" value="{{LICENSE_KEY}}"/> </map>""" license_key = os.environ.get( "FORCED_LICENSE_KEY", os.environ.get("LICENSE_KEY", None) ) server_id = os.environ.get( "FORCED_SERVER_ID", os.environ.get("SERVER_ID", None) ) license_id = os.environ.get( "FORCED_LICENSE_ID", os.environ.get("LICENSE_ID", None) ) if server_id: logger.warning( "SERVER_ID is deprecated, please use LICENSE_ID instead" ) if not license_id: license_id = server_id if license_key is not None and license_id is not None: logger.debug("A license was supplied so going to activate it") prefs_body = prefs_template.replace( "{{LICENSE_ID}}", license_id ).replace("{{LICENSE_KEY}}", license_key) with open(os.path.join(prefs_dir, "prefs.xml"), "w") as prefs_file: prefs_file.write(prefs_body)
def set_runtime_config(metadata, mxruntime_config, vcap_data, m2ee): scheduled_event_execution, my_scheduled_events = get_scheduled_events( metadata) app_config = { "ApplicationRootUrl": "https://%s" % vcap_data["application_uris"][0], "MicroflowConstants": get_constants(metadata), "ScheduledEventExecution": scheduled_event_execution, } if my_scheduled_events is not None: app_config["MyScheduledEvents"] = my_scheduled_events if is_development_mode(): logger.warning("Runtime is being started in Development Mode. Set " 'DEVELOPMENT_MODE to "false" (currently "true") to ' "set it to production.") app_config["DTAPMode"] = "D" if m2ee.config.get_runtime_version() >= 7 and not i_am_primary_instance(): app_config["com.mendix.core.isClusterSlave"] = "true" elif (m2ee.config.get_runtime_version() >= 5.15 and os.getenv("ENABLE_STICKY_SESSIONS", "false").lower() == "true"): logger.info("Enabling sticky sessions") app_config["com.mendix.core.SessionIdCookieName"] = "JSESSIONID" buildpackutil.mkdir_p(os.path.join(os.getcwd(), "model", "resources")) mxruntime_config.update(app_config) mxruntime_config.update( buildpackutil.get_database_config( development_mode=is_development_mode())) mxruntime_config.update(get_filestore_config(m2ee)) mxruntime_config.update(get_certificate_authorities()) mxruntime_config.update(get_client_certificates()) mxruntime_config.update(get_custom_settings(metadata, mxruntime_config)) mxruntime_config.update(get_custom_runtime_settings())
def set_up_nginx_files(m2ee): lines = '' x_frame_options = os.environ.get('X_FRAME_OPTIONS', 'ALLOW') if x_frame_options == 'ALLOW': x_frame_options = '' else: x_frame_options = "add_header X-Frame-Options '%s';" % x_frame_options if use_instadeploy(m2ee.config.get_runtime_version()): mxbuild_upstream = 'proxy_pass http://mendix_mxbuild' else: mxbuild_upstream = 'return 501' with open('nginx/conf/nginx.conf') as fh: lines = ''.join(fh.readlines()) lines = lines.replace('CONFIG', get_path_config()).replace( 'NGINX_PORT', str(get_nginx_port())).replace('RUNTIME_PORT', str( get_runtime_port())).replace('ADMIN_PORT', str( get_admin_port())).replace('DEPLOY_PORT', str( get_deploy_port())).replace('ROOT', os.getcwd()).replace( 'XFRAMEOPTIONS', x_frame_options).replace('MXBUILD_UPSTREAM', mxbuild_upstream) for line in lines.split('\n'): logger.debug(line) with open('nginx/conf/nginx.conf', 'w') as fh: fh.write(lines) gen_htpasswd({'MxAdmin': get_m2ee_password()}) gen_htpasswd({'deploy': os.getenv('DEPLOY_PASSWORD')}, file_name_suffix='-mxbuild') buildpackutil.mkdir_p('nginx/logs') subprocess.check_call(['touch', 'nginx/logs/access.log']) subprocess.check_call(['touch', 'nginx/logs/error.log'])
def update_project_dir(): logger.debug('unzipping ' + MPK_FILE + ' to ' + INCOMING_MPK_DIR) subprocess.check_call(('rm', '-rf', INCOMING_MPK_DIR)) buildpackutil.mkdir_p(INCOMING_MPK_DIR) subprocess.check_call(('unzip', '-oqq', MPK_FILE, '-d', INCOMING_MPK_DIR)) new_mpr = os.path.basename(buildpackutil.get_mpr_file_from_dir( INCOMING_MPK_DIR)) existing_mpr_path = buildpackutil.get_mpr_file_from_dir(PROJECT_DIR) if existing_mpr_path: existing_mpr = os.path.basename(existing_mpr_path) else: existing_mpr = None logger.debug('rsync from incoming to intermediate') if buildpackutil.get_buildpack_loglevel() < logging.INFO: quiet_or_verbose = '--verbose' else: quiet_or_verbose = '--quiet' subprocess.call(( 'rsync', '--recursive', '--checksum', '--delete', INCOMING_MPK_DIR + '/', INTERMEDIATE_MPK_DIR + '/', )) logger.debug('rsync from intermediate to project') if new_mpr == existing_mpr: update_or_delete = '--update' else: update_or_delete = '--delete' subprocess.call(( 'rsync', '--recursive', update_or_delete, quiet_or_verbose, INTERMEDIATE_MPK_DIR + '/', PROJECT_DIR + '/', ))
def activate_license(): prefs_dir = os.path.expanduser('~/../.java/.userPrefs/com/mendix/core') buildpackutil.mkdir_p(prefs_dir) prefs_template = """<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE map SYSTEM "http://java.sun.com/dtd/preferences.dtd"> <map MAP_XML_VERSION="1.0"> <entry key="id" value="{{SERVER_ID}}"/> <entry key="license_key" value="{{LICENSE_KEY}}"/> </map>""" license = os.environ.get( 'FORCED_LICENSE_KEY', os.environ.get('LICENSE_KEY', None) ) server_id = os.environ.get( 'FORCED_SERVER_ID', os.environ.get('SERVER_ID', None) ) if license is not None and server_id is not None: logger.debug('A license was supplied so going to activate it') prefs_body = prefs_template.replace( '{{SERVER_ID}}', server_id ).replace( '{{LICENSE_KEY}}', license ) with open(os.path.join(prefs_dir, 'prefs.xml'), 'w') as prefs_file: prefs_file.write(prefs_body)
def complete_start_procedure_safe_to_use_for_restart(m2ee): buildpackutil.mkdir_p("model/lib/userlib") set_up_logging_file() start_app(m2ee) create_admin_user(m2ee) configure_logging(m2ee) display_running_version(m2ee) configure_debugger(m2ee)
def set_up_m2ee_client(vcap_data): m2ee = M2EE(yamlfiles=['.local/m2ee.yaml'], load_default_files=False, config={ 'm2ee': { # this is named admin_pass, but it's the verification http header # to communicate with the internal management port of the runtime 'admin_pass': get_m2ee_password(), } }) version = m2ee.config.get_runtime_version() mendix_runtimes_path = '/usr/local/share/mendix-runtimes.git' mendix_runtime_version_path = os.path.join(os.getcwd(), 'runtimes', str(version)) if os.path.isdir(mendix_runtimes_path) and not os.path.isdir(mendix_runtime_version_path): buildpackutil.mkdir_p(mendix_runtime_version_path) env = dict(os.environ) env['GIT_WORK_TREE'] = mendix_runtime_version_path # checkout the runtime version process = subprocess.Popen(['git', 'checkout', str(version), '-f'], cwd=mendix_runtimes_path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) process.communicate() if process.returncode != 0: logger.info('Mendix {} is not available in the rootfs'.format(version)) logger.info('Fallback (1): trying to fetch Mendix {} using git'.format(version)) process = subprocess.Popen(['git', 'fetch', 'origin', 'refs/tags/{0}:refs/tags/{0}'.format(str(version)), '&&', 'git', 'checkout', str(version), '-f'], cwd=mendix_runtimes_path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) process.communicate() if process.returncode != 0: logger.info('Unable to fetch Mendix {} using git'.format(version)) url = buildpackutil.get_blobstore_url('/runtime/mendix-%s.tar.gz' % str(version)) logger.info('Fallback (2): downloading Mendix {} from {}'.format(version, url)) buildpackutil.download_and_unpack(url, os.path.join(os.getcwd(), 'runtimes')) m2ee.reload_config() set_runtime_config( m2ee.config._model_metadata, m2ee.config._conf['mxruntime'], vcap_data, m2ee, ) java_version = buildpackutil.get_java_version( m2ee.config.get_runtime_version() ) set_jvm_memory( m2ee.config._conf['m2ee'], vcap_data, java_version, ) set_jetty_config(m2ee) activate_new_relic(m2ee, vcap_data['application_name']) activate_appdynamics(m2ee, vcap_data['application_name']) set_application_name(m2ee, vcap_data['application_name']) telegraf.update_config(m2ee, vcap_data['application_name']) datadog.update_config(m2ee, vcap_data['application_name']) return m2ee
def build(): logger.debug('unzipping ' + MPK_FILE + ' to ' + INCOMING_MPK_DIR) subprocess.check_call(('rm', '-rf', INCOMING_MPK_DIR)) buildpackutil.mkdir_p(INCOMING_MPK_DIR) subprocess.check_call(('unzip', '-oqq', MPK_FILE, '-d', INCOMING_MPK_DIR)) logger.debug('rsync from incoming to intermediate') if buildpackutil.get_buildpack_loglevel() < logging.INFO: quiet_or_verbose = '--verbose' else: quiet_or_verbose = '--quiet' subprocess.call(( 'rsync', '--recursive', '--checksum', '--delete', INCOMING_MPK_DIR + '/', INTERMEDIATE_MPK_DIR + '/', )) logger.debug('rsync from intermediate to project') subprocess.call(( 'rsync', '--recursive', '--update', quiet_or_verbose, INTERMEDIATE_MPK_DIR + '/', PROJECT_DIR + '/', )) mpr = os.path.abspath(buildpackutil.get_mpr_file_from_dir(PROJECT_DIR)) response = requests.post( 'http://localhost:6666/build', data=json.dumps({ 'target': 'Deploy', 'projectFilePath': mpr, 'forceFullDeployment': False }), headers={'Content-Type': 'application/json'}, timeout=120, ) response.raise_for_status() for name in ('web', 'model'): subprocess.call(( 'rsync', '-a', os.path.join(DEPLOYMENT_DIR, name) + '/', os.path.join(ROOT_DIR, name) + '/', )) return response.json()
def set_up_java(): logging.debug("begin download and install java") buildpackutil.mkdir_p(os.path.join(DOT_LOCAL_LOCATION, "bin")) jvm_location = buildpackutil.ensure_and_get_jvm( get_runtime_version(), CACHE_DIR, DOT_LOCAL_LOCATION, package="jre" ) # create a symlink in .local/bin/java os.symlink( # use .. when jdk is in .local because absolute path is different at staging time os.path.join( jvm_location.replace(DOT_LOCAL_LOCATION, ".."), "bin", "java" ), os.path.join(DOT_LOCAL_LOCATION, "bin", "java"), ) logging.debug("end download and install java")
def set_up_m2ee_client(vcap_data): m2ee = M2EE(yamlfiles=['.local/m2ee.yaml'], load_default_files=False) version = m2ee.config.get_runtime_version() mendix_runtimes_path = '/usr/local/share/mendix-runtimes.git' mendix_runtime_version_path = os.path.join(os.getcwd(), 'runtimes', str(version)) if os.path.isdir(mendix_runtimes_path) and not os.path.isdir(mendix_runtime_version_path): buildpackutil.mkdir_p(mendix_runtime_version_path) env = dict(os.environ) env['GIT_WORK_TREE'] = mendix_runtime_version_path # checkout the runtime version process = subprocess.Popen(['git', 'checkout', str(version), '-f'], cwd=mendix_runtimes_path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) process.communicate() if process.returncode != 0: # do a 'git fetch --tags' to refresh the bare repo, then retry to checkout the runtime version logger.info('mendix runtime version {mx_version} is missing in this rootfs'.format(mx_version=version)) process = subprocess.Popen(['git', 'fetch', '--tags', '&&', 'git', 'checkout', str(version), '-f'], cwd=mendix_runtimes_path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) process.communicate() if process.returncode != 0: # download the mendix runtime version from our blobstore logger.info('unable to use rootfs for mendix runtime version {mx_version}'.format(mx_version=version)) url = buildpackutil.get_blobstore_url('/runtime/mendix-%s.tar.gz' % str(version)) buildpackutil.download_and_unpack(url, os.path.join(os.getcwd(), 'runtimes')) m2ee.reload_config() set_runtime_config( m2ee.config._model_metadata, m2ee.config._conf['mxruntime'], vcap_data, m2ee, ) set_heap_size(m2ee.config._conf['m2ee']['javaopts']) activate_new_relic(m2ee, vcap_data['application_name']) activate_appdynamics(m2ee, vcap_data['application_name']) set_application_name(m2ee, vcap_data['application_name']) java_version = buildpackutil.get_java_version( m2ee.config.get_runtime_version() ) java_opts = m2ee.config._conf['m2ee']['javaopts'] if java_version.startswith('7'): java_opts.append('-XX:MaxPermSize=128M') elif java_version.startswith('8'): java_opts.append('-XX:MaxMetaspaceSize=128M') return m2ee
def update_project_dir(): logger.debug("unzipping " + MPK_FILE + " to " + INCOMING_MPK_DIR) subprocess.check_call(("rm", "-rf", INCOMING_MPK_DIR)) buildpackutil.mkdir_p(INCOMING_MPK_DIR) subprocess.check_call(("unzip", "-oqq", MPK_FILE, "-d", INCOMING_MPK_DIR)) new_mpr = os.path.basename( buildpackutil.get_mpr_file_from_dir(INCOMING_MPK_DIR) ) existing_mpr_path = buildpackutil.get_mpr_file_from_dir(PROJECT_DIR) if existing_mpr_path: existing_mpr = os.path.basename(existing_mpr_path) else: existing_mpr = None logger.debug("rsync from incoming to intermediate") if buildpackutil.get_buildpack_loglevel() < logging.INFO: quiet_or_verbose = "--verbose" else: quiet_or_verbose = "--quiet" subprocess.call( ( "rsync", "--recursive", "--checksum", "--delete", INCOMING_MPK_DIR + "/", INTERMEDIATE_MPK_DIR + "/", ) ) logger.debug("rsync from intermediate to project") if new_mpr == existing_mpr: update_or_delete = "--update" else: update_or_delete = "--delete" subprocess.call( ( "rsync", "--recursive", update_or_delete, quiet_or_verbose, INTERMEDIATE_MPK_DIR + "/", PROJECT_DIR + "/", ) )
def get_certificate_authorities(): config = {} cas = os.getenv('CERTIFICATE_AUTHORITIES', None) if cas: ca_list = cas.split('-----BEGIN CERTIFICATE-----') n = 0 files = [] for ca in ca_list: if '-----END CERTIFICATE-----' in ca: ca = '-----BEGIN CERTIFICATE-----' + ca location = os.path.abspath( '.local/certificate_authorities.%d.crt' % n) with open(location, 'w') as output_file: output_file.write(cas) files.append(location) n += 1 config['CACertificates'] = ','.join(files) buildpackutil.mkdir_p(os.path.join(os.getcwd(), 'model', 'resources')) return config
def set_up_m2ee_client(vcap_data): m2ee = M2EE(yamlfiles=['.local/m2ee.yaml'], load_default_files=False) version = m2ee.config.get_runtime_version() mendix_runtimes_path = '/usr/local/share/mendix-runtimes.git' mendix_runtime_version_path = os.path.join(os.getcwd(), 'runtimes', str(version)) if os.path.isdir(mendix_runtimes_path) and not os.path.isdir(mendix_runtime_version_path): buildpackutil.mkdir_p(mendix_runtime_version_path) env = dict(os.environ) env['GIT_WORK_TREE'] = mendix_runtime_version_path # checkout the runtime version process = subprocess.Popen(['git', 'checkout', str(version), '-f'], cwd=mendix_runtimes_path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) process.communicate() if process.returncode != 0: # do a 'git fetch --tags' to refresh the bare repo, then retry to checkout the runtime version logger.info('mendix runtime version {mx_version} is missing in this rootfs'.format(mx_version=version)) process = subprocess.Popen(['git', 'fetch', '--tags', '&&', 'git', 'checkout', str(version), '-f'], cwd=mendix_runtimes_path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) process.communicate() if process.returncode != 0: # download the mendix runtime version from our blobstore logger.info('unable to use rootfs for mendix runtime version {mx_version}'.format(mx_version=version)) url = buildpackutil.get_blobstore_url('/runtime/mendix-%s.tar.gz' % str(version)) buildpackutil.download_and_unpack(url, os.path.join(os.getcwd(), 'runtimes')) m2ee.reload_config() set_runtime_config( m2ee.config._model_metadata, m2ee.config._conf['mxruntime'], vcap_data, m2ee, ) set_heap_size(m2ee.config._conf['m2ee']['javaopts']) activate_new_relic(m2ee, vcap_data['application_name']) activate_appdynamics(m2ee, vcap_data['application_name']) set_application_name(m2ee, vcap_data['application_name']) return m2ee
def set_up_directory_structure(): logging.debug("making directory structure") buildpackutil.mkdir_p(DOT_LOCAL_LOCATION) for name in ["runtimes", "log", "database", "data", "bin"]: buildpackutil.mkdir_p(os.path.join(BUILD_DIR, name)) for name in ["files", "tmp"]: buildpackutil.mkdir_p(os.path.join(BUILD_DIR, "data", name))
def set_runtime_config(metadata, mxruntime_config, vcap_data, m2ee): scheduled_event_execution, my_scheduled_events = ( get_scheduled_events(metadata) ) app_config = { 'ApplicationRootUrl': 'https://%s' % vcap_data['application_uris'][0], 'MicroflowConstants': get_constants(metadata), 'ScheduledEventExecution': scheduled_event_execution, } if my_scheduled_events is not None: app_config['MyScheduledEvents'] = my_scheduled_events if is_development_mode(): logger.warning( 'Runtime is being started in Development Mode. Set ' 'DEVELOPMENT_MODE to "false" (currently "true") to ' 'set it to production.' ) app_config['DTAPMode'] = 'D' if (m2ee.config.get_runtime_version() >= 7 and not i_am_primary_instance()): app_config['com.mendix.core.isClusterSlave'] = 'true' elif (m2ee.config.get_runtime_version() >= 5.15 and os.getenv('ENABLE_STICKY_SESSIONS', 'false').lower() == 'true'): logger.info('Enabling sticky sessions') app_config['com.mendix.core.SessionIdCookieName'] = 'JSESSIONID' buildpackutil.mkdir_p(os.path.join(os.getcwd(), 'model', 'resources')) mxruntime_config.update(app_config) mxruntime_config.update(buildpackutil.get_database_config( development_mode=is_development_mode(), )) mxruntime_config.update(get_filestore_config(m2ee)) mxruntime_config.update(get_certificate_authorities()) mxruntime_config.update(get_client_certificates()) mxruntime_config.update(get_custom_settings(metadata, mxruntime_config)) mxruntime_config.update(get_custom_runtime_settings())
def set_up_m2ee_client(vcap_data): m2ee = M2EE( yamlfiles=[".local/m2ee.yaml"], load_default_files=False, config={ "m2ee": { # this is named admin_pass, but it's the verification http header # to communicate with the internal management port of the runtime "admin_pass": get_m2ee_password() } }, ) version = m2ee.config.get_runtime_version() mendix_runtimes_path = "/usr/local/share/mendix-runtimes.git" mendix_runtime_version_path = os.path.join( os.getcwd(), "runtimes", str(version) ) if os.path.isdir(mendix_runtimes_path) and not os.path.isdir( mendix_runtime_version_path ): buildpackutil.mkdir_p(mendix_runtime_version_path) env = dict(os.environ) env["GIT_WORK_TREE"] = mendix_runtime_version_path # checkout the runtime version process = subprocess.Popen( ["git", "checkout", str(version), "-f"], cwd=mendix_runtimes_path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) process.communicate() if process.returncode != 0: logger.info( "Mendix {} is not available in the rootfs".format(version) ) logger.info( "Fallback (1): trying to fetch Mendix {} using git".format( version ) ) process = subprocess.Popen( [ "git", "fetch", "origin", "refs/tags/{0}:refs/tags/{0}".format(str(version)), "&&", "git", "checkout", str(version), "-f", ], cwd=mendix_runtimes_path, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) process.communicate() if process.returncode != 0: logger.info( "Unable to fetch Mendix {} using git".format(version) ) url = buildpackutil.get_blobstore_url( "/runtime/mendix-%s.tar.gz" % str(version) ) logger.info( "Fallback (2): downloading Mendix {} from {}".format( version, url ) ) buildpackutil.download_and_unpack( url, os.path.join(os.getcwd(), "runtimes") ) m2ee.reload_config() set_runtime_config( m2ee.config._model_metadata, m2ee.config._conf["mxruntime"], vcap_data, m2ee, ) java_version = buildpackutil.get_java_version( m2ee.config.get_runtime_version() ) set_jvm_memory(m2ee.config._conf["m2ee"], vcap_data, java_version) set_jvm_locale(m2ee.config._conf["m2ee"], java_version) set_jetty_config(m2ee) activate_new_relic(m2ee, vcap_data["application_name"]) activate_appdynamics(m2ee, vcap_data["application_name"]) set_application_name(m2ee, vcap_data["application_name"]) telegraf.update_config(m2ee, vcap_data["application_name"]) datadog.update_config(m2ee, vcap_data["application_name"]) return m2ee
PROJECT_DIR = '.local/project' DEPLOYMENT_DIR = os.path.join(PROJECT_DIR, 'deployment') INCOMING_MPK_DIR = '.local/tmp_project' INTERMEDIATE_MPK_DIR = '.local/tmp_project_2' MPK_FILE = os.path.join(PROJECT_DIR, 'app.mpk') for directory in ( MXBUILD_FOLDER, PROJECT_DIR, DEPLOYMENT_DIR, INCOMING_MPK_DIR, INTERMEDIATE_MPK_DIR ): buildpackutil.mkdir_p(directory) class MxBuildFailure(Exception): ''' Represents any 4xx 5xx issues retrieved from MxBuild HTTP Server ''' def __init__(self, message, status_code, mxbuild_response): super(MxBuildFailure, self).__init__(message) self.status_code = status_code self.mxbuild_response = mxbuild_response class InstaDeployThread(threading.Thread): """ The reference for this implementation can be found at