Repository: ambari Updated Branches: refs/heads/trunk c405aacf5 -> 76c1fc247
AMBARI-20220 - Parameterize the Startup Web Server Timeout Default Value (jonathanhurley) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/76c1fc24 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/76c1fc24 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/76c1fc24 Branch: refs/heads/trunk Commit: 76c1fc2473b311ea25512cbde7019b28f0b47ad9 Parents: c405aac Author: Jonathan Hurley <jhur...@hortonworks.com> Authored: Mon Feb 27 20:16:05 2017 -0500 Committer: Jonathan Hurley <jhur...@hortonworks.com> Committed: Tue Feb 28 08:56:34 2017 -0500 ---------------------------------------------------------------------- ambari-server/docs/configuration/index.md | 7 +++++- .../server/configuration/Configuration.java | 18 ++++++++++---- .../python/ambari_server/serverConfiguration.py | 22 +++++++++++++++++ .../src/main/python/ambari_server_main.py | 24 +++++++++--------- .../src/test/python/TestAmbariServer.py | 26 ++++++++++++++++++-- 5 files changed, 77 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/76c1fc24/ambari-server/docs/configuration/index.md ---------------------------------------------------------------------- diff --git a/ambari-server/docs/configuration/index.md b/ambari-server/docs/configuration/index.md index ae2d549..968db56 100644 --- a/ambari-server/docs/configuration/index.md +++ b/ambari-server/docs/configuration/index.md @@ -44,6 +44,7 @@ The following are the properties which can be used to configure Ambari. | agent.check.remote.mounts | Determines whether the Ambari Agents will use the `df` or `df -l` command when checking disk mounts for capacity issues. Auto-mounted remote directories can cause long delays. |`false` | | agent.package.install.task.timeout | The time, in seconds, before package installation commands are killed. |`1800` | | agent.package.parallel.commands.limit | The maximum number of tasks which can run within a single operational request. If there are more tasks, then they will be broken up between multiple operations. |`100` | +| agent.service.check.task.timeout | The time, in seconds, before agent service check commands are killed. |`0` | | agent.ssl | Determines whether SSL is used to communicate between Ambari Server and Ambari Agents. |`true` | | agent.stack.retry.on_repo_unavailability | Determines whether agents should retrying installation commands when the repository is not available. This can prevent false installation errors with repositories that are sporadically inaccessible. |`false` | | agent.stack.retry.tries | The number of times an Ambari Agent should retry package installation when it fails due to a repository error. <br/><br/> This property is related to `agent.stack.retry.on_repo_unavailability`. |`5` | @@ -61,6 +62,7 @@ The following are the properties which can be used to configure Ambari. | ambari.post.user.creation.hook | The location of the post user creation hook on the ambari server hosting machine. |`/var/lib/ambari-server/resources/scripts/post-user-creation-hook.sh` | | ambari.post.user.creation.hook.enabled | Indicates whether the post user creation is enabled or not. By default is false. |`false` | | ambari.python.wrap | The name of the shell script used to wrap all invocations of Python by Ambari. |`ambari-python-wrap` | +| ambariserver.metrics.disable | Global disable flag for AmbariServer Metrics. |`false` | | anonymous.audit.name | The name of the user given to requests which are executed without any credentials. |`_anonymous` | | api.authenticated.user | The username of the default user assumed to be executing API calls. When set, authentication is not required in order to login to Ambari or use the REST APIs. | | | api.csrfPrevention.enabled | Determines whether Cross-Site Request Forgery attacks are prevented by looking for the `X-Requested-By` header. |`true` | @@ -148,6 +150,7 @@ The following are the properties which can be used to configure Ambari. | kerberos.operation.retry.timeout | The time to wait (in seconds) between failed kerberos operations retries. |`10` | | ldap.sync.username.collision.behavior | Determines how to handle username collision while updating from LDAP.<br/><br/>The following are examples of valid values:<ul><li>`skip`<li>`convert`</ul> |`convert` | | log4j.monitor.delay | Indicates the delay, in milliseconds, for the log4j monitor to check for changes |`300000` | +| logsearch.metadata.cache.expire.timeout | The time, in hours, that the Ambari Server will hold Log File metadata in its internal cache before making a request to the LogSearch Portal to get the latest metadata. |`24` | | logsearch.portal.connect.timeout | The time, in milliseconds, that the Ambari Server will wait while attempting to connect to the LogSearch Portal service. |`5000` | | logsearch.portal.read.timeout | The time, in milliseconds, that the Ambari Server will wait while attempting to read a response from the LogSearch Portal service. |`5000` | | metadata.path | The location on the Ambari Server where the stack resources exist.<br/><br/>The following are examples of valid values:<ul><li>`/var/lib/ambari-server/resources/stacks`</ul> | | @@ -172,7 +175,7 @@ The following are the properties which can be used to configure Ambari. | repo.validation.suffixes.ubuntu | The suffixes to use when validating Ubuntu repositories. |`/dists/%s/Release` | | resources.dir | The location on the Ambari Server where all resources exist, including common services, stacks, and scripts. |`/var/lib/ambari-server/resources/` | | rolling.upgrade.skip.packages.prefixes | A comma-separated list of packages which will be skipped during a stack upgrade. | | -| security.agent.hostname.validate | Determines whether the Ambari Agent host names should be validated against a regular expression to ensure that they are well-formed.<br><br>WARNING: By setting this value to false, host names will not be validated, allowing a possible security vulnerability as described in CVE-2014-3582. See https://cwiki.apache.org/confluence/display/AMBARI/Ambari+Vulnerabilities for more information.|`true` | +| security.agent.hostname.validate | Determines whether the Ambari Agent host names should be validated against a regular expression to ensure that they are well-formed.<br><br>WARNING: By setting this value to false, host names will not be validated, allowing a possible security vulnerability as described in CVE-2014-3582. See https://cwiki.apache.org/confluence/display/AMBARI/Ambari+Vulnerabilities for more information. |`true` | | security.master.key.location | The location on the Ambari Server of the master key file. This is the key to the master keystore. | | | security.master.keystore.location | The location on the Ambari Server of the master keystore file. | | | security.server.cert_name | The name of the file located in the `security.server.keys_dir` directory where certificates will be generated when Ambari uses the `openssl ca` command. |`ca.crt` | @@ -248,9 +251,11 @@ The following are the properties which can be used to configure Ambari. | server.requestlogs.namepattern | The pattern of request log file name |`ambari-access-yyyy_mm_dd.log` | | server.requestlogs.path | The location on the Ambari Server where request logs can be created. | | | server.requestlogs.retaindays | The number of days that request log would be retained. |`15` | +| server.script.threads | The number of threads that should be allocated to run external script. |`4` | | server.script.timeout | The time, in milliseconds, until an external script is killed. |`5000` | | server.stage.command.execution_type | How to execute commands in one stage |`STAGE` | | server.stages.parallel | Determines whether operations in different execution requests can be run concurrently. |`true` | +| server.startup.web.timeout | The time, in seconds, that the ambari-server Python script will wait for Jetty to startup before returning an error code. |`50` | | server.task.timeout | The time, in seconds, before a server-side operation is terminated. |`1200` | | server.timeline.metrics.cache.catchup.interval | The time, in milliseconds, that Ambari Metrics intervals should use when extending the boundaries of the original request.<br/><br/> This property is related to `server.timeline.metrics.cache.disabled`. |`300000` | | server.timeline.metrics.cache.connect.timeout.millis | The time, in milliseconds, to wait while attempting to connect to Ambari Metrics.<br/><br/> This property is related to `server.timeline.metrics.cache.disabled`. |`5000` | http://git-wip-us.apache.org/repos/asf/ambari/blob/76c1fc24/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java index e1df5bd..eaecf35 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java @@ -2639,6 +2639,14 @@ public class Configuration { public static final ConfigurationProperty<Integer> LOGSEARCH_METADATA_CACHE_EXPIRE_TIMEOUT = new ConfigurationProperty<>( "logsearch.metadata.cache.expire.timeout", 24); + /** + * The time, in seconds, that the ambari-server Python script will wait for + * Jetty to startup before returning an error code. + */ + @Markdown(description = "The time, in seconds, that the ambari-server Python script will wait for Jetty to startup before returning an error code.") + public static final ConfigurationProperty<Integer> SERVER_STARTUP_WEB_TIMEOUT = new ConfigurationProperty<>( + "server.startup.web.timeout", 50); + private static final Logger LOG = LoggerFactory.getLogger( Configuration.class); @@ -2696,7 +2704,7 @@ public class Configuration { H2("h2"); private static final Map<String, DatabaseType> m_mappedTypes = - new HashMap<String, Configuration.DatabaseType>(5); + new HashMap<>(5); static { for (DatabaseType databaseType : EnumSet.allOf(DatabaseType.class)) { @@ -2775,12 +2783,12 @@ public class Configuration { public Configuration(Properties properties) { this.properties = properties; - agentConfigsMap = new HashMap<String, String>(); + agentConfigsMap = new HashMap<>(); agentConfigsMap.put(CHECK_REMOTE_MOUNTS.getKey(), getProperty(CHECK_REMOTE_MOUNTS)); agentConfigsMap.put(CHECK_MOUNTS_TIMEOUT.getKey(), getProperty(CHECK_MOUNTS_TIMEOUT)); agentConfigsMap.put(ENABLE_AUTO_AGENT_CACHE_UPDATE.getKey(), getProperty(ENABLE_AUTO_AGENT_CACHE_UPDATE)); - configsMap = new HashMap<String, String>(); + configsMap = new HashMap<>(); configsMap.putAll(agentConfigsMap); configsMap.put(AMBARI_PYTHON_WRAP.getKey(), getProperty(AMBARI_PYTHON_WRAP)); configsMap.put(SRVR_AGENT_HOSTNAME_VALIDATE.getKey(), getProperty(SRVR_AGENT_HOSTNAME_VALIDATE)); @@ -4292,7 +4300,7 @@ public class Configuration { public Map<String, String> getAmbariProperties() { Properties properties = readConfigFile(); - Map<String, String> ambariPropertiesMap = new HashMap<String, String>(); + Map<String, String> ambariPropertiesMap = new HashMap<>(); for(String key : properties.stringPropertyNames()) { ambariPropertiesMap.put(key, properties.getProperty(key)); @@ -5852,7 +5860,7 @@ public class Configuration { // Get and process the configured user type values to convert the comma-delimited string of // user types into a ordered (as found in the comma-delimited value) list of UserType values. String userTypes = getProperty(KERBEROS_AUTH_USER_TYPES); - List<UserType> orderedUserTypes = new ArrayList<UserType>(); + List<UserType> orderedUserTypes = new ArrayList<>(); String[] types = userTypes.split(","); for (String type : types) { http://git-wip-us.apache.org/repos/asf/ambari/blob/76c1fc24/ambari-server/src/main/python/ambari_server/serverConfiguration.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/python/ambari_server/serverConfiguration.py b/ambari-server/src/main/python/ambari_server/serverConfiguration.py index c771b1e..0b4af4f 100644 --- a/ambari-server/src/main/python/ambari_server/serverConfiguration.py +++ b/ambari-server/src/main/python/ambari_server/serverConfiguration.py @@ -181,6 +181,9 @@ VIEWS_DIR_PROPERTY = "views.dir" ACTIVE_INSTANCE_PROPERTY = "active.instance" +# web server startup timeout +WEB_SERVER_STARTUP_TIMEOUT = "server.startup.web.timeout" + #Common setup or upgrade message SETUP_OR_UPGRADE_MSG = "- If this is a new setup, then run the \"ambari-server setup\" command to create the user\n" \ "- If this is an upgrade of an existing setup, run the \"ambari-server upgrade\" command.\n" \ @@ -972,6 +975,25 @@ def remove_password_file(filename): return 0 +def get_web_server_startup_timeout(properties): + """ + Gets the time, in seconds, that the startup script should wait for the web server to bind to + the configured port. If this value is too low, then the startup script will return an + error code even though Ambari is actually starting up. + :param properties: + :return: The timeout value, in seconds. The default is 50. + """ + # get the timeout property and strip it if it exists + timeout = properties[WEB_SERVER_STARTUP_TIMEOUT] + timeout = None if timeout is None else timeout.strip() + + if timeout is None or timeout == "": + timeout = 50 + else: + timeout = int(timeout) + return timeout + + def get_original_master_key(properties, options = None): input = True masterKey = None http://git-wip-us.apache.org/repos/asf/ambari/blob/76c1fc24/ambari-server/src/main/python/ambari_server_main.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/python/ambari_server_main.py b/ambari-server/src/main/python/ambari_server_main.py index 66678b0..0cd19cc 100644 --- a/ambari-server/src/main/python/ambari_server_main.py +++ b/ambari-server/src/main/python/ambari_server_main.py @@ -23,22 +23,21 @@ import sys import logging from ambari_commons.exceptions import FatalException -from ambari_commons.logging_utils import get_debug_mode, print_warning_msg, print_info_msg, \ - set_debug_mode_from_options +from ambari_commons.logging_utils import get_debug_mode, print_warning_msg, print_info_msg, set_debug_mode_from_options from ambari_commons.os_check import OSConst from ambari_commons.os_family_impl import OsFamilyFuncImpl, OsFamilyImpl -from ambari_commons.os_utils import is_root, run_os_command +from ambari_commons.os_utils import is_root from ambari_server.ambariPath import AmbariPath from ambari_server.dbConfiguration import ensure_dbms_is_running, ensure_jdbc_driver_is_installed from ambari_server.serverConfiguration import configDefaults, find_jdk, get_ambari_properties, \ - get_conf_dir, get_is_persisted, get_is_secure, get_java_exe_path, get_original_master_key, read_ambari_user, \ - get_is_active_instance, update_properties, get_ambari_server_ui_port, \ - PID_NAME, SECURITY_KEY_ENV_VAR_NAME, SECURITY_MASTER_KEY_LOCATION, \ - SETUP_OR_UPGRADE_MSG, check_database_name_property, parse_properties_file, get_missing_properties + get_java_exe_path, read_ambari_user, \ + get_is_active_instance, update_properties, get_ambari_server_ui_port, PID_NAME, \ + check_database_name_property, parse_properties_file, get_missing_properties + +from ambari_server.serverConfiguration import get_web_server_startup_timeout from ambari_server.serverUtils import refresh_stack_hash from ambari_server.setupHttps import get_fqdn -from ambari_server.setupSecurity import generate_env, \ - ensure_can_start_under_current_user +from ambari_server.setupSecurity import generate_env, ensure_can_start_under_current_user from ambari_server.utils import check_reverse_lookup, save_pid, locate_file, locate_all_file_paths, looking_for_pid, \ save_main_pid_ex, check_exitcode, get_live_pids_count, wait_for_ui_start from ambari_server.serverClassPath import ServerClassPath @@ -104,7 +103,6 @@ SERVER_START_CMD_DEBUG_WINDOWS = "{0} " \ SERVER_START_TIMEOUT = 5 #seconds SERVER_START_RETRIES = 4 -WEB_UI_INIT_TIME = 50 #seconds SERVER_PING_TIMEOUT_WINDOWS = 5 SERVER_PING_ATTEMPTS_WINDOWS = 4 @@ -229,9 +227,11 @@ def wait_for_server_start(pidFile, scmStatus): exception = None if server_started: ambari_server_ui_port = get_ambari_server_ui_port(properties) - if not wait_for_ui_start(int(ambari_server_ui_port), WEB_UI_INIT_TIME): + web_server_startup_timeout = get_web_server_startup_timeout(properties) + + if not wait_for_ui_start(int(ambari_server_ui_port), web_server_startup_timeout): exception = FatalException(1, "Server not yet listening on http port " + ambari_server_ui_port + \ - " after " + str(WEB_UI_INIT_TIME) + " seconds. Exiting.") + " after " + str(web_server_startup_timeout) + " seconds. Exiting.") elif get_live_pids_count(pids) <= 0: exitcode = check_exitcode(os.path.join(configDefaults.PID_DIR, EXITCODE_NAME)) exception = FatalException(-1, AMBARI_SERVER_DIE_MSG.format(exitcode, configDefaults.SERVER_OUT_FILE)) http://git-wip-us.apache.org/repos/asf/ambari/blob/76c1fc24/ambari-server/src/test/python/TestAmbariServer.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/python/TestAmbariServer.py b/ambari-server/src/test/python/TestAmbariServer.py index 0f704f9..9579c22 100644 --- a/ambari-server/src/test/python/TestAmbariServer.py +++ b/ambari-server/src/test/python/TestAmbariServer.py @@ -4401,8 +4401,8 @@ class TestAmbariServer(TestCase): @patch("os.chown") @patch("ambari_server.setupSecurity.get_master_key_location") @patch("ambari_server.setupSecurity.save_master_key") - @patch("ambari_server_main.get_is_persisted") - @patch("ambari_server_main.get_is_secure") + @patch("ambari_server.setupSecurity.get_is_persisted") + @patch("ambari_server.setupSecurity.get_is_secure") @patch('os.chmod', autospec=True) @patch("ambari_server.serverConfiguration.write_property") @patch("ambari_server.serverConfiguration.get_validated_string_input") @@ -8555,6 +8555,28 @@ class TestAmbariServer(TestCase): self.assertTrue(is_server_runing_method.called) pass + + def test_web_server_startup_timeout(self): + from ambari_server.serverConfiguration import get_web_server_startup_timeout + from ambari_server.serverConfiguration import WEB_SERVER_STARTUP_TIMEOUT + + properties = Properties() + timeout = get_web_server_startup_timeout(properties) + self.assertEquals(50, timeout) + + properties.process_pair(WEB_SERVER_STARTUP_TIMEOUT, "") + timeout = get_web_server_startup_timeout(properties) + self.assertEquals(50, timeout) + + properties.process_pair(WEB_SERVER_STARTUP_TIMEOUT, "120") + timeout = get_web_server_startup_timeout(properties) + self.assertEquals(120, timeout) + + properties.process_pair(WEB_SERVER_STARTUP_TIMEOUT, "120 ") + timeout = get_web_server_startup_timeout(properties) + self.assertEquals(120, timeout) + + def _create_empty_options_mock(self): options = MagicMock() options.ldap_url = None