From 0c9889f3859964ed1d9b11999886d0b520ccbfc5 Mon Sep 17 00:00:00 2001 From: Mustafa Baser Date: Wed, 29 Dec 2021 18:34:30 +0300 Subject: [PATCH] feat: jans admin ui setup --- install.py | 3 + setup.py | 6 - setup_app/installers/admin_ui.py | 120 ------------------ setup_app/installers/base.py | 25 +++- setup_app/installers/config_api.py | 25 +++- setup_app/installers/jans.py | 2 +- setup_app/installers/jans_cli.py | 3 - setup_app/installers/jetty.py | 9 +- setup_app/utils/properties_utils.py | 13 +- templates/jans-cli/admin_ui_addons.ldif | 6 + templates/jans-cli/client.ldif | 4 + .../auiConfiguration.properties | 30 +++++ templates/jetty/jans-config-api | 9 +- 13 files changed, 104 insertions(+), 151 deletions(-) delete mode 100644 setup_app/installers/admin_ui.py create mode 100644 templates/jans-cli/admin_ui_addons.ldif create mode 100644 templates/jans-config-api/auiConfiguration.properties diff --git a/install.py b/install.py index 8ec879d267d..0a78cb6e6ea 100644 --- a/install.py +++ b/install.py @@ -151,6 +151,9 @@ def download_gcs(): download(urljoin(maven_base_url, 'scim-plugin/{0}{1}/scim-plugin-{0}{1}-distribution.jar'.format(app_versions['JANS_APP_VERSION'], app_versions['JANS_BUILD'])), os.path.join(jans_app_dir, 'scim-plugin.jar')) download('https://ox.gluu.org/icrby8xcvbcv/cli-swagger/jca.tgz', os.path.join(jans_app_dir, 'jca-swagger-client.tgz')) download('https://ox.gluu.org/icrby8xcvbcv/cli-swagger/scim.tgz', os.path.join(jans_app_dir, 'scim-swagger-client.tgz')) + download(urljoin(maven_base_url, 'admin-ui-plugin/{0}{1}/admin-ui-plugin-{0}{1}-distribution.jar'.format(app_versions['JANS_APP_VERSION'], app_versions['JANS_BUILD'])), os.path.join(jans_app_dir, 'admin-ui-plugin-distribution.jar')) + download('https://raw.githubusercontent.com/JanssenProject/jans-config-api/master/server/src/main/resources/log4j2.xml', os.path.join(jans_app_dir, 'log4j2.xml')) + download('https://raw.githubusercontent.com/JanssenProject/jans-config-api/master/plugins/admin-ui-plugin/config/log4j2-adminui.xml', os.path.join(jans_app_dir, 'log4j2-adminui.xml')) if argsp.profile == 'jans': download('https://maven.gluu.org/maven/org/gluufederation/opendj/opendj-server-legacy/{0}/opendj-server-legacy-{0}.zip'.format(app_versions['OPENDJ_VERSION']), os.path.join(app_dir, 'opendj-server-legacy-{0}.zip'.format(app_versions['OPENDJ_VERSION']))) diff --git a/setup.py b/setup.py index e30f57bb716..e9837d1e376 100755 --- a/setup.py +++ b/setup.py @@ -67,7 +67,6 @@ from setup_app.installers.config_api import ConfigApiInstaller from setup_app.installers.jans_cli import JansCliInstaller from setup_app.installers.rdbm import RDBMInstaller -#from setup_app.installers.admin_ui import AdminUIInstaller # from setup_app.installers.oxd import OxdInstaller @@ -170,7 +169,6 @@ scimInstaller = ScimInstaller() elevenInstaller = ElevenInstaller() jansCliInstaller = JansCliInstaller() -#adminUIInstaller = AdminUIInstaller() # oxdInstaller = OxdInstaller() @@ -327,10 +325,6 @@ def do_installation(): not Config.installed_instance and Config.get(elevenInstaller.install_var)): elevenInstaller.start_installation() - #if (Config.installed_instance and adminUIInstaller.install_var in Config.addPostSetupService) or ( - # not Config.installed_instance and Config.get(adminUIInstaller.install_var)): - # adminUIInstaller.start_installation() - if Config.installJansCli: jansCliInstaller.start_installation() jansCliInstaller.configure() diff --git a/setup_app/installers/admin_ui.py b/setup_app/installers/admin_ui.py deleted file mode 100644 index 1c00a64f1fc..00000000000 --- a/setup_app/installers/admin_ui.py +++ /dev/null @@ -1,120 +0,0 @@ -import os -import time -import glob -import json -import ruamel.yaml -import ldap3 - -from string import Template - -from setup_app import paths -from setup_app.static import AppType, InstallOption, BackendTypes -from setup_app.utils import base -from setup_app.config import Config -from setup_app.utils.setup_utils import SetupUtils -from setup_app.installers.base import BaseInstaller -from setup_app.pylib.ldif4.ldif import LDIFWriter - -class AdminUIInstaller(SetupUtils, BaseInstaller): - - def __init__(self): - setattr(base.current_app, self.__class__.__name__, self) - self.service_name = 'gluu-admin-ui' - self.needdb = True - self.app_type = AppType.SERVICE - self.install_type = InstallOption.OPTONAL - self.install_var = 'installAdminUI' - self.register_progess() - self.output_folder = os.path.join(Config.outputFolder,'gluu-admin-ui') - self.clients_ldif_fn = os.path.join(self.output_folder, 'clients.ldif') - self.root_dir = os.path.join(Config.jansOptFolder, 'gluu-admin-ui') - self.gluuOxVersion = '5.0.0-SNAPSHOT' - self.source_files = [ - (os.path.join(Config.distJansFolder, 'gluu-admin-ui-app.jar'), 'https://ox.gluu.org/maven/org/gluu/gluu-admin-ui-app/{0}/gluu-admin-ui-app-{0}.jar'.format(self.gluuOxVersion)) - ] - self.load_ldif_files = [] - - - def install(self): - self.download_files(downloads=[self.source_files[0][0]]) - self.copyFile(self.source_files[0][0], self.root_dir) - - self.generate_configuration() - self.render_import_templates() - - def installed(self): - return os.path.exists(self.root_dir) - - - def create_folders(self): - for d in (self.root_dir,self.output_folder): - if not os.path.exists(d): - self.createDirs(d) - - self.run([paths.cmd_chown, '-R', 'jetty:jetty', self.root_dir]) - - - def generate_configuration(self): - - self.check_clients([('admin_ui_client_id', '1901.')]) - - if not Config.get('admin_ui_client_pw'): - Config.admin_ui_client_pw = self.getPW(32) - Config.admin_ui_client_encoded_pw = self.obscure(Config.admin_ui_client_pw) - - createClient = True - config_api_dn = 'inum={},ou=clients,o=jans'.format(Config.admin_ui_client_id) - if Config.installed_instance and self.dbUtils.search('ou=clients,o=jans', search_filter='(&(inum={})(objectClass=jansClnt))'.format(Config.admin_ui_client_id)): - createClient = False - - if createClient: - clients_ldif_fd = open(self.clients_ldif_fn, 'wb') - ldif_clients_writer = LDIFWriter(clients_ldif_fd, cols=1000) - ldif_clients_writer.unparse( - config_api_dn, { - 'objectClass': ['top', 'jansClnt'], - 'del': ['false'], - 'displayName': ['Jans Admin UI Client'], - 'inum': [Config.admin_ui_client_id], - 'jansAccessTknAsJwt': ['false'], - 'jansAccessTknSigAlg': ['RS256'], - 'jansAppTyp': ['web'], - 'jansAttrs': ['{"tlsClientAuthSubjectDn":"","runIntrospectionScriptBeforeAccessTokenAsJwtCreationAndIncludeClaims":false,"keepClientAuthorizationAfterExpiration":false,"allowSpontaneousScopes":false,"spontaneousScopes":[],"spontaneousScopeScriptDns":[],"backchannelLogoutUri":[],"backchannelLogoutSessionRequired":false,"additionalAudience":[],"postAuthnScripts":[],"consentGatheringScripts":[],"introspectionScripts":[],"rptClaimsScripts":[]}'], - 'jansClntSecret': [Config.admin_ui_client_encoded_pw], - 'jansDefAcrValues': ['simple_password_auth'], - 'jansDisabled': ['false'], - 'jansGrantTyp': ['authorization_code', 'refresh_token', 'client_credentials'], - 'jansIdTknSignedRespAlg': ['RS256'], - 'jansInclClaimsInIdTkn': ['false'], - 'jansLogoutSessRequired': ['false'], - 'jansPersistClntAuthzs': ['true'], - 'jansRequireAuthTime': ['false'], - 'jansRespTyp': ['code'], - 'jansRptAsJwt': ['false'], - 'jansPostLogoutRedirectURI': ['http://localhost:4100'], - 'jansRedirectURI': ['http://localhost:4100'], - 'jansLogoutURI': ['http://localhost:4100/logout'], - 'jansScope': ['inum=43F1,ou=scopes,o=jans','inum=6D90,ou=scopes,o=jans','inum=FOC4,ou=scopes,o=jans'], - 'jansSubjectTyp': ['pairwise'], - 'jansTknEndpointAuthMethod': ['client_secret_basic'], - 'jansTrustedClnt': ['false'], - }) - - clients_ldif_fd.close() - self.load_ldif_files.append(self.clients_ldif_fn) - - admin_dn = 'inum={},ou=people,o=jans'.format(Config.admin_inum) - backend_location = self.dbUtils.get_backend_location_for_dn(admin_dn) - - result = self.dbUtils.dn_exists(admin_dn) - if result and not 'jansAdminUIRole' in result: - if backend_location == BackendTypes.LDAP: - ldap_operation_result = self.dbUtils.ldap_conn.modify( - admin_dn, - {'jansAdminUIRole': [ldap3.MODIFY_ADD, 'api-admin']}) - self.dbUtils.log_ldap_result(ldap_operation_result) - - def render_import_templates(self): - self.dbUtils.import_ldif(self.load_ldif_files) - - diff --git a/setup_app/installers/base.py b/setup_app/installers/base.py index 4434b58af8f..118c90f2c37 100644 --- a/setup_app/installers/base.py +++ b/setup_app/installers/base.py @@ -50,6 +50,7 @@ def start_installation(self): self.render_import_templates() self.update_backend() + self.service_post_setup() def update_rendering_dict(self): mydict = {} @@ -72,8 +73,9 @@ def check_clients(self, client_var_id_list, resource=False): client_pw = cids[2]['pw'] client_encoded_pw = cids[2]['encoded'] else: - client_pw = None - client_encoded_pw = None + tmp_ = client_var_name.split('_') + client_pw = '_'.join(tmp_[:-1]) + '_pw' + client_encoded_pw = '_'.join(tmp_[:-1]) + '_encoded_pw' self.logIt("Checking ID for client {}".format(client_var_name)) if not Config.get(client_var_name): @@ -81,15 +83,21 @@ def check_clients(self, client_var_id_list, resource=False): if result: setattr(Config, client_var_name, result[field_name]) self.logIt("{} was found in backend as {}".format(client_var_name, result[field_name])) - if client_encoded_pw: - if 'jansClntSecret' in result: - setattr(Config, client_encoded_pw, result['jansClntSecret']) - setattr(Config, client_pw, self.unobscure(result['jansClntSecret'])) - + if 'jansClntSecret' in result: + setattr(Config, client_encoded_pw, result['jansClntSecret']) + setattr(Config, client_pw, self.unobscure(result['jansClntSecret'])) if not Config.get(client_var_name): setattr(Config, client_var_name, client_id_prefix + str(uuid.uuid4())) self.logIt("Client ID for {} was created as {}".format(client_var_name, Config.get(client_var_name))) + else: + self.logIt("Client {} exists in current configuration as {}".format(client_var_name, getattr(Config, client_var_name))) + if not Config.get(client_pw): + self.logIt("Generating password for {}".format(client_pw)) + client_pw_s = self.getPW() + client_encoder_pw_s = self.obscure(client_pw_s) + setattr(Config, client_pw, client_pw_s) + setattr(Config, client_encoded_pw, client_encoder_pw_s) def check_scope(self, scope_id): search_filter = '(&(objectClass=jansScope)(jansId={}))'.format(scope_id) @@ -203,3 +211,6 @@ def installed(self): def check_need_for_download(self): pass + + def service_post_setup(self): + pass diff --git a/setup_app/installers/config_api.py b/setup_app/installers/config_api.py index 2591e8aae2c..7b917d903df 100644 --- a/setup_app/installers/config_api.py +++ b/setup_app/installers/config_api.py @@ -37,12 +37,20 @@ def __init__(self): self.config_ldif_fn = os.path.join(self.output_folder, 'config.ldif') self.load_ldif_files = [self.config_ldif_fn, self.scope_ldif_fn] self.libDir = os.path.join(self.jetty_base, self.service_name, 'custom/libs/') + self.custom_config_dir = os.path.join(self.jetty_base, self.service_name, 'custom/config') + self.admin_ui_config_properties = os.path.join(self.output_folder, 'auiConfiguration.properties') self.source_files = [ (os.path.join(Config.distJansFolder, 'jans-config-api.war'), 'https://maven.jans.io/maven/io/jans/jans-config-api-server/{0}/jans-config-api-server-{0}.war'.format(Config.oxVersion)), - (os.path.join(Config.distJansFolder, 'scim-plugin.jar'), 'https://maven.jans.io/maven/io/jans/scim-plugin/{0}/scim-plugin-{0}-distribution.jar'.format(Config.oxVersion)) + (os.path.join(Config.distJansFolder, 'scim-plugin.jar'), 'https://maven.jans.io/maven/io/jans/scim-plugin/{0}/scim-plugin-{0}-distribution.jar'.format(Config.oxVersion)), + (os.path.join(Config.distJansFolder, 'admin-ui-plugin-distribution.jar'), 'https://maven.jans.io/maven/io/jans/admin-ui-plugin/{0}/admin-ui-plugin-{0}-distribution.jar'.format(Config.oxVersion)), + (os.path.join(Config.distJansFolder, 'log4j2.xml'), 'https://raw.githubusercontent.com/JanssenProject/jans-config-api/master/server/src/main/resources/log4j2.xml'), + (os.path.join(Config.distJansFolder, 'log4j2-adminui.xml'), 'https://raw.githubusercontent.com/JanssenProject/jans-config-api/master/plugins/admin-ui-plugin/config/log4j2-adminui.xml'), ] + + + def install(self): self.installJettyService(self.jetty_app_configuration[self.service_name], True) self.logIt("Copying fido.war into jetty webapps folder...") @@ -59,7 +67,7 @@ def installed(self): def create_folders(self): - for d in (self.output_folder,): + for d in (self.output_folder, self.custom_config_dir): if not os.path.exists(d): self.createDirs(d) @@ -236,4 +244,15 @@ def load_test_data(self): self.writeFile(out_fn, rendered_text) self.dbUtils.import_ldif([out_fn]) - + def service_post_setup(self): + if Config.installAdminUI: + self.logIt("Installing Jans Admin UI", pbar=self.service_name) + self.check_clients([('role_based_client_id', '2000.')]) + self.renderTemplateInOut(self.admin_ui_config_properties, self.templates_folder, self.output_folder) + self.copyFile(self.source_files[2][0], self.libDir) + admin_ui_plugin_path = os.path.join(self.libDir, os.path.basename(self.source_files[2][0])) + self.add_extra_class(admin_ui_plugin_path) + self.copyFile(self.admin_ui_config_properties, self.custom_config_dir) + + for logfn in (self.source_files[3][0], self.source_files[4][0]): + self.copyFile(logfn, self.custom_config_dir) diff --git a/setup_app/installers/jans.py b/setup_app/installers/jans.py index 035b4da47db..de6fac61de9 100644 --- a/setup_app/installers/jans.py +++ b/setup_app/installers/jans.py @@ -70,7 +70,7 @@ def __repr__(self): txt += 'Install Apache 2 web server'.ljust(30) + repr(Config.installHttpd).rjust(35) + (' *' if 'installHttpd' in Config.addPostSetupService else '') + "\n" txt += 'Install Auth Server'.ljust(30) + repr(Config.installOxAuth).rjust(35) + "\n" txt += 'Install Jans Auth Config Api'.ljust(30) + repr(Config.installConfigApi).rjust(35) + "\n" - #txt += 'Install Gluu Admin UI'.ljust(30) + repr(Config.installAdminUI).rjust(35) + "\n" + txt += 'Install Jans Admin UI'.ljust(30) + repr(Config.installAdminUI).rjust(35) + "\n" if Config.profile == 'jans': txt += 'Install Fido2 Server'.ljust(30) + repr(Config.installFido2).rjust(35) + (' *' if 'installFido2' in Config.addPostSetupService else '') + "\n" txt += 'Install Scim Server'.ljust(30) + repr(Config.installScimServer).rjust(35) + (' *' if 'installScimServer' in Config.addPostSetupService else '') + "\n" diff --git a/setup_app/installers/jans_cli.py b/setup_app/installers/jans_cli.py index a63667089fb..680d0a58b15 100644 --- a/setup_app/installers/jans_cli.py +++ b/setup_app/installers/jans_cli.py @@ -67,9 +67,6 @@ def install(self): def generate_configuration(self): self.check_clients([('role_based_client_id', '2000.')]) - if not Config.get('role_based_client_pw'): - Config.role_based_client_pw = self.getPW() - Config.role_based_client_encoded_pw = self.obscure(Config.role_based_client_pw) def configure(self, options={}): config = configparser.ConfigParser() diff --git a/setup_app/installers/jetty.py b/setup_app/installers/jetty.py index 8e4584ad34d..d71e8a7428d 100644 --- a/setup_app/installers/jetty.py +++ b/setup_app/installers/jetty.py @@ -363,9 +363,10 @@ def war_for_jetty10(self, war_file): shutil.move(tmp_war_fn+'.zip', war_file) - def add_extra_class(self, class_path): - - tree = ET.parse(self.web_app_xml_fn) + def add_extra_class(self, class_path, xml_fn=None): + if not xml_fn: + xml_fn = self.web_app_xml_fn + tree = ET.parse(xml_fn) root = tree.getroot() for app_set in root.findall("Set"): @@ -377,7 +378,7 @@ def add_extra_class(self, class_path): child.text = class_path root.append(child) - with open(self.web_app_xml_fn, 'wb') as f: + with open(xml_fn, 'wb') as f: f.write(b'\n') f.write(b'\n') f.write(ET.tostring(root, method='xml')) diff --git a/setup_app/utils/properties_utils.py b/setup_app/utils/properties_utils.py index 926641aa73b..507d8380048 100644 --- a/setup_app/utils/properties_utils.py +++ b/setup_app/utils/properties_utils.py @@ -595,7 +595,7 @@ def promptAdminUI(self): if Config.installed_instance and Config.installAdminUI: return - promptForAdminUI = self.getPrompt("Install Gluu Admin UI?", + promptForAdminUI = self.getPrompt("Install Jans Admin UI?", self.getDefaultOption(Config.installAdminUI) )[0].lower() @@ -844,10 +844,13 @@ def promptForProperties(self): if Config.installHttpd: Config.ip = self.get_ip() - detectedHostname = self.detect_hostname() + if base.argsp.host_name: + detectedHostname = base.argsp.host_name + else: + detectedHostname = self.detect_hostname() - if detectedHostname == 'localhost': - detectedHostname = None + if detectedHostname == 'localhost': + detectedHostname = None while True: if detectedHostname: @@ -905,7 +908,7 @@ def promptForProperties(self): Config.admin_password = adminPass self.promptForConfigApi() - #self.promptAdminUI() + self.promptAdminUI() self.promptForScimServer() self.promptForFido2Server() self.promptForEleven() diff --git a/templates/jans-cli/admin_ui_addons.ldif b/templates/jans-cli/admin_ui_addons.ldif new file mode 100644 index 00000000000..118c861797a --- /dev/null +++ b/templates/jans-cli/admin_ui_addons.ldif @@ -0,0 +1,6 @@ +jansRedirectURI: https://%(hostname)s/admin-ui +jansRedirectURI: http://localhost:4100 +jansLogoutURI: http://localhost:4100/logout +jansLogoutURI: https://%(hostname)s/admin-ui/logout +jansPostLogoutRedirectURI: http://localhost:4100 +jansPostLogoutRedirectURI: https://%(hostname)s/admin-ui \ No newline at end of file diff --git a/templates/jans-cli/client.ldif b/templates/jans-cli/client.ldif index db3c634a24f..0d768586377 100644 --- a/templates/jans-cli/client.ldif +++ b/templates/jans-cli/client.ldif @@ -21,6 +21,10 @@ jansLogoutSessRequired: false jansPersistClntAuthzs: true jansRedirectURI: https://%(hostname)s/admin-ui jansRedirectURI: http://localhost:4100 +jansLogoutURI: http://localhost:4100/logout +jansLogoutURI: https://%(hostname)s/admin-ui/logout +jansPostLogoutRedirectURI: http://localhost:4100 +jansPostLogoutRedirectURI: https://%(hostname)s/admin-ui jansRequireAuthTime: false jansRespTyp: code jansRptAsJwt: false diff --git a/templates/jans-config-api/auiConfiguration.properties b/templates/jans-config-api/auiConfiguration.properties new file mode 100644 index 00000000000..de30b130344 --- /dev/null +++ b/templates/jans-config-api/auiConfiguration.properties @@ -0,0 +1,30 @@ +authserver.clientId=%(role_based_client_id)s +authserver.clientSecret=%(role_based_client_encoded_pw)s +authserver.authzBaseUrl=https://%(hostname)s/jans-auth/authorize.htm +authserver.scope=openid+profile+email+user_name +authserver.redirectUrl=https://%(hostname)s/admin +authserver.frontChannelLogoutUrl=https://%(hostname)s/admin/logout +authserver.postLogoutRedirectUri=https://%(hostname)s/admin +authserver.tokenEndpoint=https://%(hostname)s/jans-auth/restv1/token +authserver.introspectionEndpoint=https://%(hostname)s/jans-auth/restv1/introspection +authserver.userInfoEndpoint=https://%(hostname)s/jans-auth/restv1/userinfo +authserver.endSessionEndpoint=https://%(hostname)s/jans-auth/restv1/end_session + +tokenServer.clientId=%(role_based_client_id)s +tokenServer.clientSecret=%(role_based_client_encoded_pw)s +tokenServer.authzBaseUrl=https://%(hostname)s/jans-auth/authorize.htm +tokenServer.scope=openid+profile+email+user_name +tokenServer.redirectUrl=https://%(hostname)s/admin +tokenServer.logoutUrl=https://%(hostname)s/admin +tokenServer.tokenEndpoint=https://%(hostname)s/jans-auth/restv1/token +tokenServer.introspectionEndpoint=https://%(hostname)s/jans-auth/restv1/introspection +tokenServer.userInfoEndpoint=https://%(hostname)s/jans-auth/restv1/userinfo + + +## licenseSpring details + +licenseSpring.apiKey=9816ef29-a5fa-4df7-bba7-b7ae83711d28 +licenseSpring.productCode=adminui001 +licenseSpring.sharedKey=FW4xYR1nFnY6ISWulhMOYSBqx1Li_10D74RznCZxVtQ +licenseSpring.managementKey=raGfAOAy.y9oyJYZaBb8rlM4yfTbNUB7l8InWdE2l +licenseSpring.enabled=false diff --git a/templates/jetty/jans-config-api b/templates/jetty/jans-config-api index 580d05e33c9..e712a78cc60 100644 --- a/templates/jetty/jans-config-api +++ b/templates/jetty/jans-config-api @@ -1,11 +1,16 @@ JAVA_HOME=%(jre_home)s JAVA=$JAVA_HOME/bin/java -JAVA_OPTIONS="-server -Xms%(jans-config-api_min_heap_mem)sm -Xmx%(jans-config-api_max_heap_mem)sm -XX:+DisableExplicitGC -Djans.base=%(jansBaseFolder)s -Dserver.base=%(jetty_base)s/jans-config-api -Dlog.base=%(jetty_base)s/jans-config-api -Dpython.home=%(jython_home)s" - JETTY_HOME=%(jetty_home)s JETTY_BASE=%(jetty_base)s/jans-config-api JETTY_USER=%(jetty_user)s JETTY_ARGS="jetty.http.host=localhost jetty.http.port=8074" TMPDIR=%(jetty_dist)s/temp +LOG4J_CONFIG_FILES = ""; +for filename in $JETTY_BASE/custom/config/log4j2*.xml; do + LOG4J_CONFIG_FILES="${LOG4J_CONFIG_FILES}${LOG4J_CONFIG_FILES:+,}$filename" +done + +JAVA_OPTIONS="-server -Xms%(jans-config-api_min_heap_mem)sm -Xmx%(jans-config-api_max_heap_mem)sm -XX:+DisableExplicitGC -Djans.base=%(jansBaseFolder)s -Dserver.base=%(jetty_base)s/jans-config-api -Dlog.base=%(jetty_base)s/jans-config-api -Dpython.home=%(jython_home)s -Dlog4j.configurationFile=$LOG4J_CONFIG_FILES -Dlog4j2.debug=true" + export PYTHON_HOME=%(jython_home)s