You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ma...@apache.org on 2017/10/10 14:48:16 UTC
ambari git commit: AMBARI-21406. Refresh configurations without
restart command (magyari_sandor)
Repository: ambari
Updated Branches:
refs/heads/trunk 8908d3e05 -> 57682942b
AMBARI-21406. Refresh configurations without restart command (magyari_sandor)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/57682942
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/57682942
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/57682942
Branch: refs/heads/trunk
Commit: 57682942b7368a8de3f0a76f65e45b13c1626deb
Parents: 8908d3e
Author: Sandor Magyari <sm...@hortonworks.com>
Authored: Fri Aug 25 14:08:55 2017 +0200
Committer: Sandor Magyari <sm...@hortonworks.com>
Committed: Tue Oct 10 16:46:30 2017 +0200
----------------------------------------------------------------------
.../libraries/script/script.py | 23 ++-
.../AmbariCustomCommandExecutionHelper.java | 10 ++
.../AmbariManagementControllerImpl.java | 4 +-
.../ServiceComponentHostResponse.java | 15 ++
.../internal/HostComponentResourceProvider.java | 4 +
.../ambari/server/metadata/ActionMetadata.java | 1 +
.../apache/ambari/server/stack/StackModule.java | 29 +++-
.../ambari/server/state/ConfigHelper.java | 164 ++++++++++++++++++-
.../ambari/server/state/PropertyInfo.java | 29 ++++
.../ambari/server/state/RefreshCommand.java | 52 ++++++
.../state/RefreshCommandConfiguration.java | 71 ++++++++
.../apache/ambari/server/state/StackInfo.java | 10 ++
.../svccomphost/ServiceComponentHostImpl.java | 10 ++
.../HDFS/2.1.0.2.0/configuration/core-site.xml | 12 ++
.../HDFS/2.1.0.2.0/configuration/hdfs-site.xml | 3 +
.../HDFS/2.1.0.2.0/package/scripts/datanode.py | 13 +-
.../HDFS/2.1.0.2.0/package/scripts/hdfs.py | 52 +++++-
.../2.1.0.2.0/package/scripts/hdfs_client.py | 5 +
.../2.1.0.2.0/package/scripts/hdfs_namenode.py | 21 +++
.../HDFS/2.1.0.2.0/package/scripts/namenode.py | 21 ++-
.../HDFS/2.1.0.2.0/package/scripts/snamenode.py | 10 ++
.../HDFS/3.0.0.3.0/configuration/hdfs-site.xml | 6 +
.../HDFS/3.0.0.3.0/package/scripts/datanode.py | 13 +-
.../HDFS/3.0.0.3.0/package/scripts/hdfs.py | 52 +++++-
.../3.0.0.3.0/package/scripts/hdfs_client.py | 5 +
.../3.0.0.3.0/package/scripts/hdfs_namenode.py | 20 +++
.../HDFS/3.0.0.3.0/package/scripts/namenode.py | 21 ++-
.../HDFS/3.0.0.3.0/package/scripts/snamenode.py | 10 ++
.../src/main/resources/configuration-schema.xsd | 12 ++
.../src/main/resources/properties.json | 1 +
.../services/HDFS/configuration/hdfs-site.xml | 3 +
.../ambari/server/state/ConfigHelperTest.java | 76 ++++++++-
.../ambari/server/state/PropertyInfoTest.java | 20 +++
.../python/stacks/2.0.6/HDFS/test_datanode.py | 17 ++
.../python/stacks/2.0.6/HDFS/test_namenode.py | 33 ++++
.../services/HDFS/configuration/hdfs-site.xml | 8 +
36 files changed, 835 insertions(+), 21 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-common/src/main/python/resource_management/libraries/script/script.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/script/script.py b/ambari-common/src/main/python/resource_management/libraries/script/script.py
index bf8c0dc..12e6f98 100644
--- a/ambari-common/src/main/python/resource_management/libraries/script/script.py
+++ b/ambari-common/src/main/python/resource_management/libraries/script/script.py
@@ -1006,12 +1006,33 @@ class Script(object):
def configure(self, env, upgrade_type=None, config_dir=None):
"""
- To be overridden by subclasses
+ To be overridden by subclasses (may invoke save_configs)
:param upgrade_type: only valid during RU/EU, otherwise will be None
:param config_dir: for some clients during RU, the location to save configs to, otherwise None
"""
self.fail_with_error('configure method isn\'t implemented')
+ def save_configs(self, env):
+ """
+ To be overridden by subclasses
+ Creates / updates configuration files
+ """
+ self.fail_with_error('save_configs method isn\'t implemented')
+
+ def reconfigure(self, env):
+ """
+ Default implementation of RECONFIGURE action which may be overridden by subclasses
+ """
+ Logger.info("Refresh config files ...")
+ self.save_configs(env)
+
+ config = self.get_config()
+ if "reconfigureAction" in config["commandParams"] and config["commandParams"]["reconfigureAction"] is not None:
+ reconfigure_action = config["commandParams"]["reconfigureAction"]
+ Logger.info("Call %s" % reconfigure_action)
+ method = self.choose_method_to_execute(reconfigure_action)
+ method(env)
+
def generate_configs_get_template_file_content(self, filename, dicts):
config = self.get_config()
content = ''
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
index d0dd7e0..e12477e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
@@ -89,6 +89,7 @@ import org.apache.ambari.server.state.HostState;
import org.apache.ambari.server.state.MaintenanceState;
import org.apache.ambari.server.state.PropertyInfo;
import org.apache.ambari.server.state.PropertyInfo.PropertyType;
+import org.apache.ambari.server.state.RefreshCommandConfiguration;
import org.apache.ambari.server.state.RepositoryInfo;
import org.apache.ambari.server.state.Service;
import org.apache.ambari.server.state.ServiceComponent;
@@ -507,6 +508,15 @@ public class AmbariCustomCommandExecutionHelper {
StageUtils.useAmbariJdkInCommandParams(commandParams, configs);
roleParams.put(COMPONENT_CATEGORY, componentInfo.getCategory());
+ // set reconfigureAction in case of a RECONFIGURE command if there are any
+ if (commandName.equals("RECONFIGURE")) {
+ String refreshConfigsCommand = configHelper.getRefreshConfigsCommand(cluster, hostName, serviceName, componentName);
+ if (refreshConfigsCommand != null && !refreshConfigsCommand.equals(RefreshCommandConfiguration.REFRESH_CONFIGS)) {
+ LOG.info("Refreshing configs for {}/{} with command: ", componentName, hostName, refreshConfigsCommand);
+ commandParams.put("reconfigureAction", refreshConfigsCommand);
+ }
+ }
+
execCmd.setCommandParams(commandParams);
execCmd.setRoleParams(roleParams);
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index 5642575..8c4888c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -4795,7 +4795,9 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
properties = ambariMetaInfo.getServiceProperties(stackName, stackVersion, serviceName);
}
for (PropertyInfo property: properties) {
- response.add(property.convertToResponse());
+ if (property.shouldBeConfigured()) {
+ response.add(property.convertToResponse());
+ }
}
return response;
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostResponse.java
index 7b75e06..bc67117 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostResponse.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostResponse.java
@@ -40,6 +40,7 @@ public class ServiceComponentHostResponse {
private String desiredRepositoryVersion;
private String desiredState;
private boolean staleConfig = false;
+ private boolean reloadConfig = false;
private String adminState = null;
private String maintenanceState = null;
private UpgradeState upgradeState = UpgradeState.NONE;
@@ -283,6 +284,20 @@ public class ServiceComponentHostResponse {
}
/**
+ * @return true if configs are reloadable without RESTART command
+ */
+ public boolean isReloadConfig() {
+ return reloadConfig;
+ }
+
+ /**
+ * @param reloadConfig
+ */
+ public void setReloadConfig(boolean reloadConfig) {
+ this.reloadConfig = reloadConfig;
+ }
+
+ /**
* @return the maintenance state
*/
public String getMaintenanceState() {
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
index 48e15eb..6708560 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
@@ -106,6 +106,8 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
= PropertyHelper.getPropertyId("HostRoles", "actual_configs");
public static final String HOST_COMPONENT_STALE_CONFIGS_PROPERTY_ID
= PropertyHelper.getPropertyId("HostRoles", "stale_configs");
+ public static final String HOST_COMPONENT_RELOAD_CONFIGS_PROPERTY_ID
+ = PropertyHelper.getPropertyId("HostRoles", "reload_configs");
public static final String HOST_COMPONENT_DESIRED_ADMIN_STATE_PROPERTY_ID
= PropertyHelper.getPropertyId("HostRoles", "desired_admin_state");
public static final String HOST_COMPONENT_MAINTENANCE_STATE_PROPERTY_ID
@@ -244,6 +246,8 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
response.getActualConfigs(), requestedIds);
setResourceProperty(resource, HOST_COMPONENT_STALE_CONFIGS_PROPERTY_ID,
response.isStaleConfig(), requestedIds);
+ setResourceProperty(resource, HOST_COMPONENT_RELOAD_CONFIGS_PROPERTY_ID,
+ response.isReloadConfig(), requestedIds);
setResourceProperty(resource, HOST_COMPONENT_UPGRADE_STATE_PROPERTY_ID,
response.getUpgradeState(), requestedIds);
setResourceProperty(resource, HOST_COMPONENT_DESIRED_REPOSITORY_VERSION,
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/java/org/apache/ambari/server/metadata/ActionMetadata.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/metadata/ActionMetadata.java b/ambari-server/src/main/java/org/apache/ambari/server/metadata/ActionMetadata.java
index e0bfdcf..33dc0e8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/metadata/ActionMetadata.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/metadata/ActionMetadata.java
@@ -65,6 +65,7 @@ public class ActionMetadata {
defaultHostComponentCommands.add("CONFIGURE");
defaultHostComponentCommands.add("CONFIGURE_FUNCTION");
defaultHostComponentCommands.add("DISABLE_SECURITY");
+ defaultHostComponentCommands.add("RECONFIGURE");
}
private void fillServiceClients() {
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
index e88bbf2..520764d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
@@ -38,6 +38,7 @@ import org.apache.ambari.server.state.ConfigHelper;
import org.apache.ambari.server.state.ExtensionInfo;
import org.apache.ambari.server.state.PropertyDependencyInfo;
import org.apache.ambari.server.state.PropertyInfo;
+import org.apache.ambari.server.state.RefreshCommand;
import org.apache.ambari.server.state.RepositoryInfo;
import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.StackInfo;
@@ -579,6 +580,7 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
}
// Read the service and available configs for this stack
populateServices();
+
if (!stackInfo.isValid()) {
setValid(false);
addErrors(stackInfo.getErrors());
@@ -627,7 +629,7 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
for (ServiceInfo serviceInfo : serviceInfos) {
ServiceModule serviceModule = new ServiceModule(stackContext, serviceInfo, serviceDirectory);
serviceModules.add(serviceModule);
- if (!serviceModule.isValid()){
+ if (!serviceModule.isValid()) {
stackInfo.setValid(false);
setValid(false);
stackInfo.addErrors(serviceModule.getErrors());
@@ -769,7 +771,11 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
// relationship into map. Since we do not have the reverse {@link PropertyInfo},
// we have to loop through service-configs again later.
for (ServiceModule serviceModule : serviceModules.values()) {
+
+ Map<String, Map<String, String>> componentRefreshCommandsMap = new HashMap();
+
for (PropertyInfo pi : serviceModule.getModuleInfo().getProperties()) {
+
for (PropertyDependencyInfo pdi : pi.getDependsOnProperties()) {
String type = ConfigHelper.fileNameToConfigType(pi.getFilename());
String name = pi.getName();
@@ -784,7 +790,28 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
dependedByMap.put(pdi, newDependenciesSet);
}
}
+
+ // set refresh commands
+ if (pi.getSupportedRefreshCommands() != null && pi.getSupportedRefreshCommands().size() > 0) {
+ String type = ConfigHelper.fileNameToConfigType(pi.getFilename());
+ String propertyName = type + "/" + pi.getName();
+
+ Map<String, String> refreshCommandPropertyMap = componentRefreshCommandsMap.get(propertyName);
+
+ for (RefreshCommand refreshCommand : pi.getSupportedRefreshCommands()) {
+ String componentName = refreshCommand.getComponentName();
+ if (refreshCommandPropertyMap == null) {
+ refreshCommandPropertyMap = new HashMap<>();
+ componentRefreshCommandsMap.put(propertyName, refreshCommandPropertyMap);
+ }
+ refreshCommandPropertyMap.put(componentName, refreshCommand.getCommand());
+ }
+
+ }
+
}
+
+ stackInfo.getRefreshCommandConfiguration().addRefreshCommands(componentRefreshCommandsMap);
}
// Go through all service-configs again and set their 'depended-by' if necessary.
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
index bb7fcbe..eade914 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
@@ -17,12 +17,15 @@
*/
package org.apache.ambari.server.state;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -41,6 +44,7 @@ import org.apache.ambari.server.state.PropertyInfo.PropertyType;
import org.apache.ambari.server.state.configgroup.ConfigGroup;
import org.apache.ambari.server.utils.SecretReference;
import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -72,6 +76,8 @@ public class ConfigHelper {
*/
private final Cache<Integer, Boolean> staleConfigsCache;
+ private final Cache<Integer, String> refreshConfigCommandCache;
+
private static final Logger LOG =
LoggerFactory.getLogger(ConfigHelper.class);
@@ -113,6 +119,9 @@ public class ConfigHelper {
STALE_CONFIGS_CACHE_EXPIRATION_TIME = configuration.staleConfigCacheExpiration();
staleConfigsCache = CacheBuilder.newBuilder().
expireAfterWrite(STALE_CONFIGS_CACHE_EXPIRATION_TIME, TimeUnit.SECONDS).build();
+
+ refreshConfigCommandCache = CacheBuilder.newBuilder().
+ expireAfterWrite(STALE_CONFIGS_CACHE_EXPIRATION_TIME, TimeUnit.SECONDS).build();
}
/**
@@ -1302,6 +1311,8 @@ public class ConfigHelper {
StackId stackId = sch.getServiceComponent().getDesiredStackId();
+ StackInfo stackInfo = ambariMetaInfo.getStack(stackId);
+
ServiceInfo serviceInfo = ambariMetaInfo.getService(stackId.getStackName(),
stackId.getStackVersion(), sch.getServiceName());
@@ -1316,8 +1327,10 @@ public class ConfigHelper {
// ---- merge values, determine changed keys, check stack: stale
Iterator<Entry<String, Map<String, String>>> it = desired.entrySet().iterator();
+ List<String> changedProperties = new LinkedList<>();
- while (it.hasNext() && !stale) {
+ while (it.hasNext()) {
+ boolean staleEntry = false;
Entry<String, Map<String, String>> desiredEntry = it.next();
String type = desiredEntry.getKey();
@@ -1325,29 +1338,108 @@ public class ConfigHelper {
if (!actual.containsKey(type)) {
// desired is set, but actual is not
- if (!serviceInfo.hasConfigDependency(type)) {
- stale = componentInfo != null && componentInfo.hasConfigType(type);
- } else {
- stale = true;
- }
+ staleEntry = (serviceInfo.hasConfigDependency(type) || componentInfo.hasConfigType(type));
} else {
// desired and actual both define the type
HostConfig hc = actual.get(type);
Map<String, String> actualTags = buildTags(hc);
if (!isTagChanged(tags, actualTags, hasGroupSpecificConfigsForType(cluster, sch.getHostName(), type))) {
- stale = false;
+ staleEntry = false;
} else {
- stale = serviceInfo.hasConfigDependency(type) || componentInfo.hasConfigType(type);
+ staleEntry = (serviceInfo.hasConfigDependency(type) || componentInfo.hasConfigType(type));
+ if (staleEntry) {
+ Collection<String> changedKeys = findChangedKeys(cluster, type, tags.values(), actualTags.values());
+ changedProperties.addAll(changedKeys);
+ }
}
}
+ stale = stale | staleEntry;
}
+
+ String refreshCommand = calculateRefreshCommand(stackInfo.getRefreshCommandConfiguration(), sch, changedProperties);
+
if (STALE_CONFIGS_CACHE_ENABLED) {
staleConfigsCache.put(staleHash, stale);
+ if (refreshCommand != null) {
+ refreshConfigCommandCache.put(staleHash, refreshCommand);
+ }
}
+
+ // gather all changed properties and see if we can find a common refreshConfigs command for this component
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Changed properties {} ({}) {} : COMMAND: {}", stale, sch.getServiceComponentName(), sch.getHostName(), refreshCommand);
+ for (String p : changedProperties) {
+ LOG.debug(p);
+ }
+ }
+
return stale;
}
+ public String getRefreshConfigsCommand(Cluster cluster, String hostName, String serviceName, String componentName) throws AmbariException {
+ ServiceComponent serviceComponent = cluster.getService(serviceName).getServiceComponent(componentName);
+ ServiceComponentHost sch = serviceComponent.getServiceComponentHost(hostName);
+ return getRefreshConfigsCommand(cluster, sch);
+ }
+
+ public String getRefreshConfigsCommand(Cluster cluster, ServiceComponentHost sch) throws AmbariException {
+ String refreshCommand = null;
+
+ Map<String, HostConfig> actual = sch.getActualConfigs();
+ if (STALE_CONFIGS_CACHE_ENABLED) {
+ Map<String, Map<String, String>> desired = getEffectiveDesiredTags(cluster, sch.getHostName(),
+ cluster.getDesiredConfigs());
+ int staleHash = Objects.hashCode(actual.hashCode(),
+ desired.hashCode(),
+ sch.getHostName(),
+ sch.getServiceComponentName(),
+ sch.getServiceName());
+ refreshCommand = refreshConfigCommandCache.getIfPresent(staleHash);
+ }
+ return refreshCommand;
+ }
+
+
+ /**
+ * Calculates refresh command for a set of changed properties as follows:
+ * - if a property has no refresh command return null
+ * - in case of multiple refresh commands: as REFRESH_CONFIGS is executed by default in case of any other command as well,
+ * can be overriden by RELOAD_CONFIGS or any other custom command, however in case of any other different commands return null
+ * as it's not possible to refresh all properties with one command.
+ *
+ * examples:
+ * {REFRESH_CONFIGS, REFRESH_CONFIGS, RELOAD_CONFIGS} ==> RELOAD_CONFIGS
+ * {REFRESH_CONFIGS, RELOADPROXYUSERS, RELOAD_CONFIGS} ==> null
+ *
+ * @param refreshCommandConfiguration
+ * @param sch
+ * @param changedProperties
+ * @return
+ */
+ private String calculateRefreshCommand(RefreshCommandConfiguration refreshCommandConfiguration,
+ ServiceComponentHost sch, List<String> changedProperties) {
+
+ String finalRefreshCommand = null;
+ for (String propertyName : changedProperties) {
+ String refreshCommand = refreshCommandConfiguration.getRefreshCommandForComponent(sch, propertyName);
+ if (refreshCommand == null) {
+ return null;
+ }
+ if (finalRefreshCommand == null) {
+ finalRefreshCommand = refreshCommand;
+ }
+ if (!finalRefreshCommand.equals(refreshCommand)) {
+ if (finalRefreshCommand.equals(RefreshCommandConfiguration.REFRESH_CONFIGS)) {
+ finalRefreshCommand = refreshCommand;
+ } else if (!refreshCommand.equals(RefreshCommandConfiguration.REFRESH_CONFIGS)) {
+ return null;
+ }
+ }
+ }
+ return finalRefreshCommand;
+ }
+
/**
* Determines if the hostname has group specific configs for the type specified
*
@@ -1374,6 +1466,62 @@ public class ConfigHelper {
}
/**
+ * @return the keys that have changed values
+ */
+ private Collection<String> findChangedKeys(Cluster cluster, String type,
+ Collection<String> desiredTags, Collection<String> actualTags) {
+
+ Map<String, String> desiredValues = new HashMap<>();
+ Map<String, String> actualValues = new HashMap<>();
+
+ for (String tag : desiredTags) {
+ Config config = cluster.getConfig(type, tag);
+ if (null != config) {
+ desiredValues.putAll(config.getProperties());
+ }
+ }
+
+ for (String tag : actualTags) {
+ Config config = cluster.getConfig(type, tag);
+ if (null != config) {
+ actualValues.putAll(config.getProperties());
+ }
+ }
+
+ List<String> keys = new ArrayList<>();
+
+ for (Entry<String, String> entry : desiredValues.entrySet()) {
+ String key = entry.getKey();
+ String value = entry.getValue();
+
+ if (!actualValues.containsKey(key) || !valuesAreEqual(actualValues.get(key), value)) {
+ keys.add(type + "/" + key);
+ }
+ }
+
+ return keys;
+ }
+
+ /**
+ * Compares values as double in case they are numbers.
+ * @param actualValue
+ * @param newValue
+ * @return
+ */
+ private boolean valuesAreEqual(String actualValue, String newValue) {
+ boolean actualValueIsNumber = NumberUtils.isNumber(actualValue);
+ boolean newValueIsNumber = NumberUtils.isNumber(newValue);
+ if (actualValueIsNumber && newValueIsNumber) {
+ Double ab = Double.parseDouble(actualValue);
+ Double bb = Double.parseDouble(newValue);
+ return ab.equals(bb);
+ } else if (!actualValueIsNumber && !newValueIsNumber) {
+ return actualValue.equals(newValue);
+ }
+ return false;
+ }
+
+ /**
* @return the map of tags for a desired config
*/
private Map<String, String> buildTags(HostConfig hc) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/java/org/apache/ambari/server/state/PropertyInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/PropertyInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/PropertyInfo.java
index 63c850e..31fcb9d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/PropertyInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/PropertyInfo.java
@@ -90,6 +90,11 @@ public class PropertyInfo {
private Set<PropertyDependencyInfo> usedByProperties =
new HashSet<>();
+ @XmlElementWrapper(name="supported-refresh-commands")
+ @XmlElement(name="refresh-command")
+ private Set<RefreshCommand> supportedRefreshCommands = new HashSet<>();
+
+
//This method is called after all the properties (except IDREF) are unmarshalled for this object,
//but before this object is set to the parent object.
void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
@@ -209,6 +214,30 @@ public class PropertyInfo {
this.requireInput = requireInput;
}
+ public List<Element> getPropertyAttributes() {
+ return propertyAttributes;
+ }
+
+ public void setPropertyAttributes(List<Element> propertyAttributes) {
+ this.propertyAttributes = propertyAttributes;
+ }
+
+ public Set<RefreshCommand> getSupportedRefreshCommands() {
+ return supportedRefreshCommands;
+ }
+
+ public void setSupportedRefreshCommands(Set<RefreshCommand> supportedRefreshCommands) {
+ this.supportedRefreshCommands = supportedRefreshCommands;
+ }
+
+ /**
+ * Willcard properties should not be included to stack configurations.
+ * @return
+ */
+ public boolean shouldBeConfigured() {
+ return !getName().contains("*");
+ }
+
@Override
public int hashCode() {
final int prime = 31;
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/java/org/apache/ambari/server/state/RefreshCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/RefreshCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/state/RefreshCommand.java
new file mode 100644
index 0000000..e09a875
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/RefreshCommand.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.state;
+
+import javax.xml.bind.annotation.XmlAttribute;
+
+/**
+ * Represents a RefreshCommand defined for a component and a property.
+ */
+public class RefreshCommand {
+
+ @XmlAttribute(name="componentName", required = true)
+ private String componentName;
+
+ /**
+ * Default command is reload_configs.
+ */
+ @XmlAttribute(name="command", required = false)
+ private String command = RefreshCommandConfiguration.RELOAD_CONFIGS;
+
+ public RefreshCommand() {
+ }
+
+ public RefreshCommand(String componentName, String command) {
+ this.componentName = componentName;
+ this.command = command;
+ }
+
+ public String getComponentName() {
+ return componentName;
+ }
+
+ public String getCommand() {
+ return command;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/java/org/apache/ambari/server/state/RefreshCommandConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/RefreshCommandConfiguration.java b/ambari-server/src/main/java/org/apache/ambari/server/state/RefreshCommandConfiguration.java
new file mode 100644
index 0000000..5999c6c
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/RefreshCommandConfiguration.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.state;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class RefreshCommandConfiguration {
+
+ public static final String RELOAD_CONFIGS = "reload_configs";
+ public static final String REFRESH_CONFIGS = "refresh_configs";
+
+ private Map<String, Map<String, String>> propertyComponentCommandMap;
+
+ public RefreshCommandConfiguration() {
+ }
+
+ private String findKey(String propertyName) {
+ for (String keyName : propertyComponentCommandMap.keySet()) {
+ if (propertyName.startsWith(keyName)) {
+ return keyName;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * If no command is defined for a component then the default command will be REFRESH_CONFIGS in case of a client component or
+ * if there's only one command defined for an another component. This is because if RELOAD_CONFIGS is defined for NAMENODE then
+ * presumably other dependent components will need just a refresh.
+ */
+ public String getRefreshCommandForComponent(ServiceComponentHost sch, String propertyName) {
+ if (sch.isClientComponent()) {
+ return REFRESH_CONFIGS;
+ }
+ String keyName = findKey(propertyName);
+ Map<String, String> componentCommandMap = propertyComponentCommandMap.get(keyName);
+ if (componentCommandMap != null) {
+ String commandForComponent = componentCommandMap.get(sch.getServiceComponentName());
+ if (commandForComponent != null) {
+ return commandForComponent;
+ } else if(componentCommandMap.size() == 1) {
+ return REFRESH_CONFIGS;
+ }
+ }
+ return null;
+ }
+
+ public void addRefreshCommands(Map<String, Map<String, String>> refreshCommands) {
+ if (propertyComponentCommandMap == null) {
+ propertyComponentCommandMap = new HashMap();
+ }
+ propertyComponentCommandMap.putAll(refreshCommands);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
index c32e907..70d5926 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
@@ -90,6 +90,8 @@ public class StackInfo implements Comparable<StackInfo>, Validable {
* */
private List<String> servicesWithNoConfigs = new ArrayList<>();
+ private RefreshCommandConfiguration refreshCommandConfiguration = new RefreshCommandConfiguration();
+
public String getMinJdk() {
return minJdk;
}
@@ -604,4 +606,12 @@ public class StackInfo implements Comparable<StackInfo>, Validable {
public VersionDefinitionXml getLatestVersionDefinition() {
return latestVersion;
}
+
+ public RefreshCommandConfiguration getRefreshCommandConfiguration() {
+ return refreshCommandConfiguration;
+ }
+
+ public void setRefreshCommandConfiguration(RefreshCommandConfiguration refreshCommandConfiguration) {
+ this.refreshCommandConfiguration = refreshCommandConfiguration;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
index f490ff0..3b8f6da 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
@@ -1181,6 +1181,16 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
LOG.error("Could not determine stale config", e);
}
+ try {
+ Cluster cluster = clusters.getCluster(clusterName);
+ ServiceComponent serviceComponent = cluster.getService(serviceName).getServiceComponent(serviceComponentName);
+ ServiceComponentHost sch = serviceComponent.getServiceComponentHost(hostName);
+ String refreshConfigsCommand = helper.getRefreshConfigsCommand(cluster,sch);
+ r.setReloadConfig(refreshConfigsCommand != null);
+ } catch (Exception e) {
+ LOG.error("Could not determine reload config flag", e);
+ }
+
return r;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/core-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/core-site.xml b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/core-site.xml
index 5c6f043..d39ea78 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/core-site.xml
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/core-site.xml
@@ -185,4 +185,16 @@ DEFAULT
</description>
<on-ambari-upgrade add="true"/>
</property>
+ <property>
+ <name>hadoop.proxyuser.*</name>
+ <value/>
+ <description>
+ This * property is not configured it's used just to define refresh commands for all properties
+ prefixed with hadoop.proxyuser.
+ </description>
+ <supported-refresh-commands>
+ <refresh-command componentName="NAMENODE" command="reloadproxyusers" />
+ </supported-refresh-commands>
+ <on-ambari-upgrade add="false"/>
+ </property>
</configuration>
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/hdfs-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/hdfs-site.xml b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/hdfs-site.xml
index 7fdc227..d97a52e 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/hdfs-site.xml
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/hdfs-site.xml
@@ -184,6 +184,9 @@
<value>3</value>
<description>Determines datanode heartbeat interval in seconds.</description>
<on-ambari-upgrade add="true"/>
+ <supported-refresh-commands>
+ <refresh-command componentName="NAMENODE" command="reload_configs" />
+ </supported-refresh-commands>
</property>
<property>
<name>dfs.namenode.safemode.threshold-pct</name>
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/datanode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/datanode.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/datanode.py
index 0aa0bc0..c0abb15 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/datanode.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/datanode.py
@@ -31,7 +31,7 @@ from resource_management.libraries.functions.decorator import retry
from resource_management.libraries.functions.security_commons import build_expectations, \
cached_kinit_executor, get_params_from_filesystem, validate_security_config_properties, FILE_TYPE_XML
from resource_management.core.logger import Logger
-from hdfs import hdfs
+from hdfs import hdfs, reconfig
from ambari_commons.os_family_impl import OsFamilyImpl
from ambari_commons import OSConst
from utils import get_hdfs_binary
@@ -57,6 +57,17 @@ class DataNode(Script):
hdfs("datanode")
datanode(action="configure")
+ def save_configs(self, env):
+ import params
+ env.set_params(params)
+ hdfs("datanode")
+
+ def reload_configs(self, env):
+ import params
+ env.set_params(params)
+ Logger.info("RELOAD CONFIGS")
+ reconfig("datanode", params.dfs_dn_ipc_address)
+
def start(self, env, upgrade_type=None):
import params
env.set_params(params)
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py
index 07c7616..4022986 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py
@@ -20,12 +20,16 @@ Ambari Agent
"""
from resource_management.libraries.script.script import Script
-from resource_management.core.resources.system import Directory, File, Link
+from resource_management.core.resources.system import Execute, Directory, File, Link
from resource_management.core.resources import Package
from resource_management.core.source import Template
from resource_management.core.resources.service import ServiceConfig
from resource_management.libraries.resources.xml_config import XmlConfig
+
from resource_management.libraries.functions.get_lzo_packages import get_lzo_packages
+from resource_management.core.exceptions import Fail
+from resource_management.core.logger import Logger
+from resource_management.libraries.functions.format import format
import os
from ambari_commons.os_family_impl import OsFamilyFuncImpl, OsFamilyImpl
from ambari_commons import OSConst
@@ -157,6 +161,52 @@ def install_snappy():
to=params.so_src_x64,
)
+class ConfigStatusParser():
+ def __init__(self):
+ self.reconfig_successful = False
+
+ def handle_new_line(self, line, is_stderr):
+ if is_stderr:
+ return
+
+ if line.startswith('SUCCESS: Changed property'):
+ self.reconfig_successful = True
+
+ Logger.info('[reconfig] %s' % (line))
+
+@OsFamilyFuncImpl(os_family=OsFamilyImpl.DEFAULT)
+def reconfig(componentName, componentAddress):
+ import params
+
+ if params.security_enabled:
+ Execute(params.nn_kinit_cmd,
+ user=params.hdfs_user
+ )
+
+ nn_reconfig_cmd = format('hdfs --config {hadoop_conf_dir} dfsadmin -reconfig {componentName} {componentAddress} start')
+
+ Execute (nn_reconfig_cmd,
+ user=params.hdfs_user,
+ logoutput=True,
+ path=params.hadoop_bin_dir
+ )
+
+ nn_reconfig_cmd = format('hdfs --config {hadoop_conf_dir} dfsadmin -reconfig {componentName} {componentAddress} status')
+ config_status_parser = ConfigStatusParser()
+ Execute (nn_reconfig_cmd,
+ user=params.hdfs_user,
+ logoutput=False,
+ path=params.hadoop_bin_dir,
+ on_new_line=config_status_parser.handle_new_line
+ )
+
+
+ if not config_status_parser.reconfig_successful:
+ Logger.info('Reconfiguration failed')
+ raise Fail('Reconfiguration failed!')
+
+ Logger.info('Reconfiguration successfully completed.')
+
@OsFamilyFuncImpl(os_family=OSConst.WINSRV_FAMILY)
def hdfs(component=None):
import params
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py
index 0896f30..f2e96c3 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py
@@ -42,6 +42,11 @@ class HdfsClient(Script):
env.set_params(params)
hdfs()
+ def save_configs(self, env):
+ import params
+ env.set_params(params)
+ hdfs()
+
def start(self, env, upgrade_type=None):
import params
env.set_params(params)
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_namenode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_namenode.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_namenode.py
index cac6e9c..2224f72 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_namenode.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_namenode.py
@@ -430,6 +430,27 @@ def is_namenode_formatted(params):
return False
+
+@OsFamilyFuncImpl(os_family=OsFamilyImpl.DEFAULT)
+def refreshProxyUsers():
+ import params
+
+ if params.security_enabled:
+ Execute(params.nn_kinit_cmd,
+ user=params.hdfs_user
+ )
+
+ if params.dfs_ha_enabled:
+ # due to a bug in hdfs, refreshNodes will not run on both namenodes so we
+ # need to execute each command scoped to a particular namenode
+ nn_refresh_cmd = format('dfsadmin -fs hdfs://{namenode_rpc} -refreshSuperUserGroupsConfiguration')
+ else:
+ nn_refresh_cmd = format('dfsadmin -fs {namenode_address} -refreshSuperUserGroupsConfiguration')
+ ExecuteHadoop(nn_refresh_cmd,
+ user=params.hdfs_user,
+ conf_dir=params.hadoop_conf_dir,
+ bin_dir=params.hadoop_bin_dir)
+
@OsFamilyFuncImpl(os_family=OsFamilyImpl.DEFAULT)
def decommission():
import params
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
index 50bf1e0..291da05 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
@@ -46,8 +46,8 @@ from ambari_commons import OSConst
import namenode_upgrade
-from hdfs_namenode import namenode, wait_for_safemode_off
-from hdfs import hdfs
+from hdfs_namenode import namenode, wait_for_safemode_off, refreshProxyUsers
+from hdfs import hdfs, reconfig
import hdfs_rebalance
from utils import initiate_safe_zkfc_failover, get_hdfs_binary, get_dfsadmin_base_command
@@ -86,6 +86,23 @@ class NameNode(Script):
hdfs_binary = self.get_hdfs_binary()
namenode(action="configure", hdfs_binary=hdfs_binary, env=env)
+ def save_configs(self, env):
+ import params
+ env.set_params(params)
+ hdfs()
+
+ def reload_configs(self, env):
+ import params
+ env.set_params(params)
+ Logger.info("RELOAD CONFIGS")
+ reconfig("namenode", params.namenode_address)
+
+ def reloadproxyusers(self, env):
+ import params
+ env.set_params(params)
+ Logger.info("RELOAD HDFS PROXY USERS")
+ refreshProxyUsers()
+
def start(self, env, upgrade_type=None):
import params
env.set_params(params)
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/snamenode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/snamenode.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/snamenode.py
index 4977e1c..3d387b4 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/snamenode.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/snamenode.py
@@ -44,6 +44,16 @@ class SNameNode(Script):
hdfs("secondarynamenode")
snamenode(action="configure")
+ def save_configs(self, env):
+ import params
+ env.set_params(params)
+ hdfs("secondarynamenode")
+
+ def reload_configs(self, env):
+ import params
+ env.set_params(params)
+ Logger.info("RELOAD CONFIGS")
+
def start(self, env, upgrade_type=None):
import params
env.set_params(params)
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/configuration/hdfs-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/configuration/hdfs-site.xml b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/configuration/hdfs-site.xml
index 5c28527..940f87c 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/configuration/hdfs-site.xml
+++ b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/configuration/hdfs-site.xml
@@ -181,6 +181,9 @@
<value>3</value>
<description>Determines datanode heartbeat interval in seconds.</description>
<on-ambari-upgrade add="false"/>
+ <supported-refresh-commands>
+ <refresh-command componentName="NAMENODE" command="reload_configs" />
+ </supported-refresh-commands>
</property>
<property>
<name>dfs.namenode.safemode.threshold-pct</name>
@@ -637,5 +640,8 @@
<name>hadoop.caller.context.enabled</name>
<value>true</value>
<on-ambari-upgrade add="false"/>
+ <supported-refresh-commands>
+ <refresh-command componentName="NAMENODE" command="reload_configs" />
+ </supported-refresh-commands>
</property>
</configuration>
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/datanode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/datanode.py b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/datanode.py
index d8fb361..a843374 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/datanode.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/datanode.py
@@ -25,7 +25,7 @@ from resource_management.libraries.functions.stack_features import check_stack_f
from resource_management.libraries.functions.security_commons import build_expectations, \
cached_kinit_executor, get_params_from_filesystem, validate_security_config_properties, FILE_TYPE_XML
from resource_management.core.logger import Logger
-from hdfs import hdfs
+from hdfs import hdfs, reconfig
from ambari_commons.os_family_impl import OsFamilyImpl
from ambari_commons import OSConst
from utils import get_hdfs_binary
@@ -50,6 +50,17 @@ class DataNode(Script):
hdfs("datanode")
datanode(action="configure")
+ def save_configs(self, env):
+ import params
+ env.set_params(params)
+ hdfs("datanode")
+
+ def reload_configs(self, env):
+ import params
+ env.set_params(params)
+ Logger.info("RELOAD CONFIGS")
+ reconfig("datanode", params.dfs_dn_ipc_address)
+
def start(self, env, upgrade_type=None):
import params
env.set_params(params)
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs.py b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs.py
index 07c7616..4022986 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs.py
@@ -20,12 +20,16 @@ Ambari Agent
"""
from resource_management.libraries.script.script import Script
-from resource_management.core.resources.system import Directory, File, Link
+from resource_management.core.resources.system import Execute, Directory, File, Link
from resource_management.core.resources import Package
from resource_management.core.source import Template
from resource_management.core.resources.service import ServiceConfig
from resource_management.libraries.resources.xml_config import XmlConfig
+
from resource_management.libraries.functions.get_lzo_packages import get_lzo_packages
+from resource_management.core.exceptions import Fail
+from resource_management.core.logger import Logger
+from resource_management.libraries.functions.format import format
import os
from ambari_commons.os_family_impl import OsFamilyFuncImpl, OsFamilyImpl
from ambari_commons import OSConst
@@ -157,6 +161,52 @@ def install_snappy():
to=params.so_src_x64,
)
+class ConfigStatusParser():
+ def __init__(self):
+ self.reconfig_successful = False
+
+ def handle_new_line(self, line, is_stderr):
+ if is_stderr:
+ return
+
+ if line.startswith('SUCCESS: Changed property'):
+ self.reconfig_successful = True
+
+ Logger.info('[reconfig] %s' % (line))
+
+@OsFamilyFuncImpl(os_family=OsFamilyImpl.DEFAULT)
+def reconfig(componentName, componentAddress):
+ import params
+
+ if params.security_enabled:
+ Execute(params.nn_kinit_cmd,
+ user=params.hdfs_user
+ )
+
+ nn_reconfig_cmd = format('hdfs --config {hadoop_conf_dir} dfsadmin -reconfig {componentName} {componentAddress} start')
+
+ Execute (nn_reconfig_cmd,
+ user=params.hdfs_user,
+ logoutput=True,
+ path=params.hadoop_bin_dir
+ )
+
+ nn_reconfig_cmd = format('hdfs --config {hadoop_conf_dir} dfsadmin -reconfig {componentName} {componentAddress} status')
+ config_status_parser = ConfigStatusParser()
+ Execute (nn_reconfig_cmd,
+ user=params.hdfs_user,
+ logoutput=False,
+ path=params.hadoop_bin_dir,
+ on_new_line=config_status_parser.handle_new_line
+ )
+
+
+ if not config_status_parser.reconfig_successful:
+ Logger.info('Reconfiguration failed')
+ raise Fail('Reconfiguration failed!')
+
+ Logger.info('Reconfiguration successfully completed.')
+
@OsFamilyFuncImpl(os_family=OSConst.WINSRV_FAMILY)
def hdfs(component=None):
import params
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs_client.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs_client.py b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs_client.py
index 0896f30..f2e96c3 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs_client.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs_client.py
@@ -42,6 +42,11 @@ class HdfsClient(Script):
env.set_params(params)
hdfs()
+ def save_configs(self, env):
+ import params
+ env.set_params(params)
+ hdfs()
+
def start(self, env, upgrade_type=None):
import params
env.set_params(params)
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs_namenode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs_namenode.py b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs_namenode.py
index 5a1f368..94cd66c 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs_namenode.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs_namenode.py
@@ -460,6 +460,26 @@ def decommission():
conf_dir=conf_dir,
bin_dir=params.hadoop_bin_dir)
+@OsFamilyFuncImpl(os_family=OsFamilyImpl.DEFAULT)
+def refreshProxyUsers():
+ import params
+
+ if params.security_enabled:
+ Execute(params.nn_kinit_cmd,
+ user=params.hdfs_user
+ )
+
+ if params.dfs_ha_enabled:
+ # due to a bug in hdfs, refreshNodes will not run on both namenodes so we
+ # need to execute each command scoped to a particular namenode
+ nn_refresh_cmd = format('dfsadmin -fs hdfs://{namenode_rpc} -refreshSuperUserGroupsConfiguration')
+ else:
+ nn_refresh_cmd = format('dfsadmin -fs {namenode_address} -refreshSuperUserGroupsConfiguration')
+ ExecuteHadoop(nn_refresh_cmd,
+ user=params.hdfs_user,
+ conf_dir=params.hadoop_conf_dir,
+ bin_dir=params.hadoop_bin_dir)
+
@OsFamilyFuncImpl(os_family=OSConst.WINSRV_FAMILY)
def decommission():
import params
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/namenode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/namenode.py b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/namenode.py
index 7a0e784..ffdafb8 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/namenode.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/namenode.py
@@ -46,8 +46,8 @@ from ambari_commons import OSConst
import namenode_upgrade
-from hdfs_namenode import namenode, wait_for_safemode_off
-from hdfs import hdfs
+from hdfs_namenode import namenode, wait_for_safemode_off, refreshProxyUsers
+from hdfs import hdfs, reconfig
import hdfs_rebalance
from utils import initiate_safe_zkfc_failover, get_hdfs_binary, get_dfsadmin_base_command
@@ -86,6 +86,23 @@ class NameNode(Script):
hdfs_binary = self.get_hdfs_binary()
namenode(action="configure", hdfs_binary=hdfs_binary, env=env)
+ def save_configs(self, env):
+ import params
+ env.set_params(params)
+ hdfs()
+
+ def reload_configs(self, env):
+ import params
+ env.set_params(params)
+ Logger.info("RELOAD CONFIGS")
+ reconfig("namenode", params.namenode_address)
+
+ def reloadproxyusers(self, env):
+ import params
+ env.set_params(params)
+ Logger.info("RELOAD HDFS PROXY USERS")
+ refreshProxyUsers()
+
def start(self, env, upgrade_type=None):
import params
env.set_params(params)
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/snamenode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/snamenode.py b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/snamenode.py
index f5ff3e1..b0ed533 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/snamenode.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/snamenode.py
@@ -44,6 +44,16 @@ class SNameNode(Script):
hdfs("secondarynamenode")
snamenode(action="configure")
+ def save_configs(self, env):
+ import params
+ env.set_params(params)
+ hdfs("secondarynamenode")
+
+ def reload_configs(self, env):
+ import params
+ env.set_params(params)
+ Logger.info("RELOAD CONFIGS")
+
def start(self, env, upgrade_type=None):
import params
env.set_params(params)
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/configuration-schema.xsd
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/configuration-schema.xsd b/ambari-server/src/main/resources/configuration-schema.xsd
index 9350984..12b0217 100644
--- a/ambari-server/src/main/resources/configuration-schema.xsd
+++ b/ambari-server/src/main/resources/configuration-schema.xsd
@@ -41,6 +41,13 @@
<xs:element name="deleted" type="xs:boolean" minOccurs="0"/>
<xs:element name="final" type="xs:boolean" minOccurs="0"/>
<xs:element name="on-ambari-upgrade" type="propertyUpgradeBehavior" minOccurs="1"/>
+ <xs:element name="supported-refresh-commands" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="refresh-command" type="refreshCommands" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
<xs:element name="on-stack-upgrade" type="propertyStackUpgradeBehavior" minOccurs="0"/>
<xs:element name="property-type" minOccurs="0">
<xs:simpleType>
@@ -84,6 +91,11 @@
<xs:attribute name="merge" type="xs:boolean" use="optional" default="true"/>
</xs:complexType>
+ <xs:complexType name="refreshCommands">
+ <xs:attribute name="componentName" type="xs:string" use="required"/>
+ <xs:attribute name="command" type="xs:string" use="optional"/>
+ </xs:complexType>
+
<xs:complexType name="valueAttributesInfo">
<xs:all>
<xs:element name="type" type="xs:string" minOccurs="0"/>
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/properties.json b/ambari-server/src/main/resources/properties.json
index e42864f..1d12f83 100644
--- a/ambari-server/src/main/resources/properties.json
+++ b/ambari-server/src/main/resources/properties.json
@@ -53,6 +53,7 @@
"HostRoles/actual_configs",
"params/run_smoke_test",
"HostRoles/stale_configs",
+ "HostRoles/reload_configs",
"HostRoles/desired_admin_state",
"HostRoles/maintenance_state",
"HostRoles/service_name",
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/main/resources/stacks/HDP/2.3/services/HDFS/configuration/hdfs-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/HDFS/configuration/hdfs-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/services/HDFS/configuration/hdfs-site.xml
index 86aa3ec..14fcf6a 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/HDFS/configuration/hdfs-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/HDFS/configuration/hdfs-site.xml
@@ -76,5 +76,8 @@
<name>hadoop.caller.context.enabled</name>
<value>true</value>
<on-ambari-upgrade add="false"/>
+ <supported-refresh-commands>
+ <refresh-command componentName="NAMENODE" command="reload_configs" />
+ </supported-refresh-commands>
</property>
</configuration>
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/test/java/org/apache/ambari/server/state/ConfigHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/ConfigHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/ConfigHelperTest.java
index 38a38cc..8a0a782 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/ConfigHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/ConfigHelperTest.java
@@ -157,6 +157,7 @@ public class ConfigHelperTest {
cluster.addService("FLUME", repositoryVersion);
cluster.addService("OOZIE", repositoryVersion);
+ cluster.addService("HDFS", repositoryVersion);
final ClusterRequest clusterRequest2 =
new ClusterRequest(cluster.getClusterId(), clusterName,
@@ -229,6 +230,45 @@ public class ConfigHelperTest {
managementController.updateClusters(new HashSet<ClusterRequest>() {{
add(clusterRequest5);
}}, null);
+
+ // hdfs-site/hadoop.caller.context.enabled
+ ConfigurationRequest cr6 = new ConfigurationRequest();
+ cr6.setClusterName(clusterName);
+ cr6.setType("hdfs-site");
+ cr6.setVersionTag("version1");
+ cr6.setProperties(new HashMap<String, String>() {{
+ put("hadoop.caller.context.enabled", "true");
+ }});
+ cr6.setPropertiesAttributes(null);
+
+ final ClusterRequest clusterRequest6 =
+ new ClusterRequest(cluster.getClusterId(), clusterName,
+ cluster.getDesiredStackVersion().getStackVersion(), null);
+
+ clusterRequest6.setDesiredConfig(Collections.singletonList(cr6));
+ managementController.updateClusters(new HashSet<ClusterRequest>() {{
+ add(clusterRequest6);
+ }}, null);
+
+ // hdfs-site/hadoop.caller.context.enabled
+ ConfigurationRequest cr7 = new ConfigurationRequest();
+ cr7.setClusterName(clusterName);
+ cr7.setType("hdfs-site");
+ cr7.setVersionTag("version2");
+ cr7.setProperties(new HashMap<String, String>() {{
+ put("hadoop.caller.context.enabled", "false");
+ }});
+ cr7.setPropertiesAttributes(null);
+
+ final ClusterRequest clusterRequest7 =
+ new ClusterRequest(cluster.getClusterId(), clusterName,
+ cluster.getDesiredStackVersion().getStackVersion(), null);
+
+ clusterRequest7.setDesiredConfig(Collections.singletonList(cr7));
+ managementController.updateClusters(new HashSet<ClusterRequest>() {{
+ add(clusterRequest7);
+ }}, null);
+
}
@After
@@ -545,7 +585,7 @@ public class ConfigHelperTest {
configHelper.getEffectiveDesiredTags(cluster, "h3"));
Assert.assertNotNull(effectiveAttributes);
- Assert.assertEquals(7, effectiveAttributes.size());
+ Assert.assertEquals(8, effectiveAttributes.size());
Assert.assertTrue(effectiveAttributes.containsKey("global3"));
Map<String, Map<String, String>> globalAttrs = effectiveAttributes.get("global3");
@@ -991,7 +1031,39 @@ public class ConfigHelperTest {
Assert.assertTrue(configHelper.isStaleConfigs(sch, null));
verify(sch);
- }
+ }
+
+ @Test
+ public void testCalculateRefreshCommands() throws Exception {
+
+ Map<String, HostConfig> schReturn = new HashMap<>();
+ HostConfig hc = new HostConfig();
+ // Put a different version to check for change
+ hc.setDefaultVersionTag("version1");
+ schReturn.put("hdfs-site", hc);
+
+ ServiceComponent sc = createNiceMock(ServiceComponent.class);
+
+ // set up mocks
+ ServiceComponentHost sch = createNiceMock(ServiceComponentHost.class);
+ expect(sc.getDesiredStackId()).andReturn(cluster.getDesiredStackVersion()).anyTimes();
+
+ // set up expectations
+ expect(sch.getActualConfigs()).andReturn(schReturn).anyTimes();
+ expect(sch.getHostName()).andReturn("h1").anyTimes();
+ expect(sch.getClusterId()).andReturn(cluster.getClusterId()).anyTimes();
+ expect(sch.getServiceName()).andReturn("HDFS").anyTimes();
+ expect(sch.getServiceComponentName()).andReturn("NAMENODE").anyTimes();
+ expect(sch.getServiceComponent()).andReturn(sc).anyTimes();
+
+ replay(sc, sch);
+
+ Assert.assertTrue(configHelper.isStaleConfigs(sch, null));
+ String refreshConfigsCommand = configHelper.getRefreshConfigsCommand(cluster, sch);
+ Assert.assertEquals("reload_configs", refreshConfigsCommand);
+ verify(sch);
+ }
+
}
public static class RunWithCustomModule {
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/test/java/org/apache/ambari/server/state/PropertyInfoTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/PropertyInfoTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/PropertyInfoTest.java
index 7a94ebf..4a04d0b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/PropertyInfoTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/PropertyInfoTest.java
@@ -137,6 +137,26 @@ public class PropertyInfoTest {
}
@Test
+ public void testBehaviorWithSupportedRefreshCommandsTags() throws JAXBException {
+ // given
+ String xml =
+ "<property>\n" +
+ " <name>prop_name</name>\n" +
+ " <value>prop_val</value>\n" +
+ " <supported-refresh-commands>\n" +
+ " <refresh-command componentName=\"NAMENODE\" command=\"reload_configs\" />\n" +
+ " </supported-refresh-commands>\n" +
+ "</property>";
+
+ // when
+ PropertyInfo propertyInfo = propertyInfoFrom(xml);
+
+ // then
+ assertEquals(propertyInfo.getSupportedRefreshCommands().iterator().next().getCommand(), "reload_configs");
+ assertEquals(propertyInfo.getSupportedRefreshCommands().iterator().next().getComponentName(), "NAMENODE");
+ }
+
+ @Test
public void testUnknownPropertyType() throws Exception {
// Given
String xml =
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/test/python/stacks/2.0.6/HDFS/test_datanode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/HDFS/test_datanode.py b/ambari-server/src/test/python/stacks/2.0.6/HDFS/test_datanode.py
index b1a4154..ef59e84 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/HDFS/test_datanode.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/HDFS/test_datanode.py
@@ -666,3 +666,20 @@ class TestDatanode(RMFTestCase):
self.assertEquals(
('hdfs dfsadmin -fs hdfs://ns1 -D ipc.client.connect.max.retries=5 -D ipc.client.connect.retry.interval=1000 -getDatanodeInfo 0.0.0.0:8010'),
mocks_dict['checked_call'].call_args_list[0][0][0])
+
+ def test_reload_configs(self):
+ with self.assertRaises(Fail):
+ self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/datanode.py",
+ classname = "DataNode",
+ command = "reload_configs",
+ config_file = "default.json",
+ stack_version = self.STACK_VERSION,
+ target = RMFTestCase.TARGET_COMMON_SERVICES
+ )
+
+ # self.assertResourceCalled('Execute', "hdfs dfsadmin -fs hdfs://c6401.ambari.apache.org:8020 -reconfig namenode c6401.ambari.apache.org:8020 start",
+ # tries=115,
+ # try_sleep=10,
+ # user="hdfs",
+ # logoutput=True
+ # )
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/test/python/stacks/2.0.6/HDFS/test_namenode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/HDFS/test_namenode.py b/ambari-server/src/test/python/stacks/2.0.6/HDFS/test_namenode.py
index 06e12f6..4e1124a 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/HDFS/test_namenode.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/HDFS/test_namenode.py
@@ -1745,6 +1745,39 @@ class TestNamenode(RMFTestCase):
get_namenode_states_mock.return_value = active_namenodes, standby_namenodes, unknown_namenodes
self.assertFalse(is_this_namenode_active())
+ def test_reloadproxyusers(self):
+ self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/namenode.py",
+ classname = "NameNode",
+ command = "reloadproxyusers",
+ config_file = "default.json",
+ stack_version = self.STACK_VERSION,
+ target = RMFTestCase.TARGET_COMMON_SERVICES
+ )
+
+ self.assertResourceCalled('ExecuteHadoop', 'dfsadmin -fs hdfs://c6401.ambari.apache.org:8020 -refreshSuperUserGroupsConfiguration',
+ user = 'hdfs',
+ conf_dir = '/etc/hadoop/conf',
+ bin_dir = '/usr/bin')
+ self.assertNoMoreResources()
+
+ def test_reload_configs(self):
+ with self.assertRaises(Fail):
+ self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/namenode.py",
+ classname = "NameNode",
+ command = "reload_configs",
+ config_file = "default.json",
+ stack_version = self.STACK_VERSION,
+ target = RMFTestCase.TARGET_COMMON_SERVICES
+ )
+
+ # self.assertResourceCalled('Execute', "hdfs dfsadmin -fs hdfs://c6401.ambari.apache.org:8020 -reconfig namenode c6401.ambari.apache.org:8020 start",
+ # tries=115,
+ # try_sleep=10,
+ # user="hdfs",
+ # logoutput=True
+ # )
+
+
class Popen_Mock:
return_value = 1
http://git-wip-us.apache.org/repos/asf/ambari/blob/57682942/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/configuration/hdfs-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/configuration/hdfs-site.xml b/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/configuration/hdfs-site.xml
index 28657eb..9e52a33 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/configuration/hdfs-site.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/configuration/hdfs-site.xml
@@ -444,4 +444,12 @@ don't exist, they will be created with this permission.</description>
</description>
<on-ambari-upgrade add="true"/>
</property>
+ <property>
+ <name>hadoop.caller.context.enabled</name>
+ <value>true</value>
+ <on-ambari-upgrade add="false"/>
+ <supported-refresh-commands>
+ <refresh-command componentName="NAMENODE" command="reload_configs" />
+ </supported-refresh-commands>
+ </property>
</configuration>