You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ds...@apache.org on 2013/12/20 20:01:01 UTC
git commit: AMBARI-4145 Ability to restart a component (dsen)
Updated Branches:
refs/heads/trunk 26dee15ee -> d60ee2cb1
AMBARI-4145 Ability to restart a component (dsen)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d60ee2cb
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d60ee2cb
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d60ee2cb
Branch: refs/heads/trunk
Commit: d60ee2cb16f25d799ade3ceb629ad9edb3643049
Parents: 26dee15
Author: Dmitry Sen <ds...@hortonworks.com>
Authored: Fri Dec 20 20:42:38 2013 +0200
Committer: Dmitry Sen <ds...@hortonworks.com>
Committed: Fri Dec 20 21:00:50 2013 +0200
----------------------------------------------------------------------
.../ambari_agent/CustomServiceOrchestrator.py | 3 +
.../libraries/script/script.py | 26 +++++
.../org/apache/ambari/server/RoleCommand.java | 1 +
.../ambari/server/agent/ExecutionCommand.java | 1 +
.../ambari/server/agent/HeartBeatHandler.java | 3 +-
.../AmbariCustomCommandExecutionHelperImpl.java | 115 ++++++++++++++++++-
.../ambari/server/metadata/ActionMetadata.java | 16 +++
.../ambari/server/state/ComponentInfo.java | 11 ++
.../HDP/2.0._/services/HBASE/metainfo.xml | 2 +-
.../HBASE/package/scripts/hbase_regionserver.py | 2 +-
.../server/agent/TestHeartbeatHandler.java | 51 ++++++++
.../api/util/StackExtensionHelperTest.java | 1 +
12 files changed, 227 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/d60ee2cb/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py b/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
index 7acbefd..7ffc1c9 100644
--- a/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
+++ b/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
@@ -43,6 +43,7 @@ class CustomServiceOrchestrator():
SCRIPT_TYPE_PYTHON = "PYTHON"
COMMAND_NAME_STATUS = "STATUS"
CUSTOM_ACTION_COMMAND = 'ACTIONEXECUTE'
+ CUSTOM_COMMAND_COMMAND = 'CUSTOM_COMMAND'
PRE_HOOK_PREFIX="before"
POST_HOOK_PREFIX="after"
@@ -95,6 +96,8 @@ class CustomServiceOrchestrator():
script_tuple = (os.path.join(base_dir, script) , base_dir)
hook_dir = None
else:
+ if command_name == self.CUSTOM_COMMAND_COMMAND:
+ command_name = command['hostLevelParams']['custom_command']
stack_name = command['hostLevelParams']['stack_name']
stack_version = command['hostLevelParams']['stack_version']
hook_dir = self.file_cache.get_hook_base_dir(stack_name, stack_version)
http://git-wip-us.apache.org/repos/asf/ambari/blob/d60ee2cb/ambari-agent/src/main/python/resource_management/libraries/script/script.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/resource_management/libraries/script/script.py b/ambari-agent/src/main/python/resource_management/libraries/script/script.py
index 93d9aa2..b8c9d83 100644
--- a/ambari-agent/src/main/python/resource_management/libraries/script/script.py
+++ b/ambari-agent/src/main/python/resource_management/libraries/script/script.py
@@ -163,3 +163,29 @@ class Script(object):
print("Error: " + message)
sys.stderr.write("Error: " + message)
sys.exit(1)
+
+ def start(self, env):
+ """
+ To be overridden by subclasses
+ """
+ self.fail_with_error('start method isn\'t implemented')
+
+ def stop(self, env):
+ """
+ To be overridden by subclasses
+ """
+ self.fail_with_error('stop method isn\'t implemented')
+
+ def restart(self, env):
+ """
+ Default implementation of restart command is to call stop and start methods
+ Feel free to override restart() method with your implementation.
+ """
+ self.stop(env)
+ self.start(env)
+
+ def configure(self, env):
+ """
+ To be overridden by subclasses
+ """
+ self.fail_with_error('configure method isn\'t implemented')
http://git-wip-us.apache.org/repos/asf/ambari/blob/d60ee2cb/ambari-server/src/main/java/org/apache/ambari/server/RoleCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/RoleCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/RoleCommand.java
index be5f591..b98c50c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/RoleCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/RoleCommand.java
@@ -33,5 +33,6 @@ public enum RoleCommand {
ABORT,
UPGRADE,
SERVICE_CHECK,
+ CUSTOM_COMMAND,
ACTIONEXECUTE
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d60ee2cb/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
index 5df20cc..dc8d605 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
@@ -258,6 +258,7 @@ public class ExecutionCommand extends AgentCommand {
String SERVICE_CHECK = "SERVICE_CHECK"; // TODO: is it standart command? maybe add it to RoleCommand enum?
String COMMAND_TIMEOUT_DEFAULT = "600"; // TODO: Will be replaced by proper initialization in another jira
+ String CUSTOM_COMMAND = "custom_command";
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d60ee2cb/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
index 7501fb4..947b97f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
@@ -193,7 +193,8 @@ public class HeartBeatHandler {
List<CommandReport> reports = heartbeat.getReports();
for (CommandReport report : reports) {
LOG.debug("Received command report: " + report);
- if (RoleCommand.ACTIONEXECUTE.toString().equals(report.getRoleCommand())) {
+ if (RoleCommand.ACTIONEXECUTE.toString().equals(report.getRoleCommand()) ||
+ RoleCommand.CUSTOM_COMMAND.toString().equals(report.getRoleCommand())) {
continue;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d60ee2cb/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperImpl.java
index d0901e4..f1c7743 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperImpl.java
@@ -81,7 +81,8 @@ public class AmbariCustomCommandExecutionHelperImpl implements AmbariCustomComma
+ ", serviceName=" + actionRequest.getServiceName()
+ ", request=" + actionRequest.toString());
- if (!isValidCommand(actionRequest.getCommandName(), actionRequest.getServiceName())) {
+ if (!isValidCommand(actionRequest.getCommandName(),
+ actionRequest.getServiceName()) && !isValidCustomCommand(actionRequest)) {
throw new AmbariException(
"Unsupported action " + actionRequest.getCommandName() + " for " + actionRequest.getServiceName());
}
@@ -100,6 +101,28 @@ public class AmbariCustomCommandExecutionHelperImpl implements AmbariCustomComma
return true;
}
+ private Boolean isValidCustomCommand(ExecuteActionRequest actionRequest) throws AmbariException {
+ String clustername = actionRequest.getClusterName();
+ Cluster cluster = clusters.getCluster(clustername);
+ StackId stackId = cluster.getDesiredStackVersion();
+ String serviceName = actionRequest.getServiceName();
+ String componentName = actionRequest.getComponentName();
+ String commandName = actionRequest.getCommandName();
+
+ if (componentName == null) {
+ return false;
+ }
+ ComponentInfo componentInfo = ambariMetaInfo.getComponent(
+ stackId.getStackName(), stackId.getStackVersion(),
+ serviceName, componentName);
+
+ if (!componentInfo.isCustomCommand(commandName) &&
+ !actionMetadata.isDefaultHostComponentCommand(commandName)) {
+ return false;
+ }
+ return true;
+ }
+
@Override
public void addAction(ExecuteActionRequest actionRequest, Stage stage,
HostsMap hostsMap, Map<String, String> hostLevelParams)
@@ -108,11 +131,99 @@ public class AmbariCustomCommandExecutionHelperImpl implements AmbariCustomComma
addServiceCheckAction(actionRequest, stage, hostsMap, hostLevelParams);
} else if (actionRequest.getCommandName().equals("DECOMMISSION_DATANODE")) {
addDecommissionDatanodeAction(actionRequest, stage, hostLevelParams);
+ } else if (isValidCustomCommand(actionRequest)) {
+ addCustomcommandAction(actionRequest, stage, hostsMap, hostLevelParams);
} else {
throw new AmbariException("Unsupported action " + actionRequest.getCommandName());
}
}
+ private void addCustomcommandAction(ExecuteActionRequest actionRequest,
+ Stage stage, HostsMap hostsMap, Map<String, String> hostLevelParams)
+ throws AmbariException {
+
+ if (actionRequest.getHosts().isEmpty()) {
+ throw new AmbariException("Invalid request : No hosts specified.");
+ }
+
+ String serviceName = actionRequest.getServiceName();
+ String componentName = actionRequest.getComponentName();
+ String commandName = actionRequest.getCommandName();
+
+ String clusterName = stage.getClusterName();
+ Cluster cluster = clusters.getCluster(clusterName);
+ StackId stackId = cluster.getDesiredStackVersion();
+ AmbariMetaInfo ambariMetaInfo = amc.getAmbariMetaInfo();
+ ServiceInfo serviceInfo =
+ ambariMetaInfo.getServiceInfo(stackId.getStackName(),
+ stackId.getStackVersion(), serviceName);
+
+ long nowTimestamp = System.currentTimeMillis();
+
+ for (String hostName: actionRequest.getHosts()) {
+
+ stage.addHostRoleExecutionCommand(hostName, Role.valueOf(componentName),
+ RoleCommand.CUSTOM_COMMAND,
+ new ServiceComponentHostOpInProgressEvent(componentName,
+ hostName, nowTimestamp), cluster.getClusterName(), serviceName);
+
+ Map<String, Map<String, String>> configurations =
+ new TreeMap<String, Map<String, String>>();
+ Map<String, Map<String, String>> configTags =
+ amc.findConfigurationTagsWithOverrides(cluster, hostName);
+
+ ExecutionCommand execCmd = stage.getExecutionCommandWrapper(hostName,
+ componentName).getExecutionCommand();
+
+ execCmd.setConfigurations(configurations);
+ execCmd.setConfigurationTags(configTags);
+
+ execCmd.setClusterHostInfo(
+ StageUtils.getClusterHostInfo(clusters.getHostsForCluster(clusterName), cluster, hostsMap, configs));
+
+ if (hostLevelParams == null) {
+ hostLevelParams = new TreeMap<String, String>();
+ }
+ hostLevelParams.put(JDK_LOCATION, amc.getJdkResourceUrl());
+ hostLevelParams.put(STACK_NAME, stackId.getStackName());
+ hostLevelParams.put(STACK_VERSION,stackId.getStackVersion());
+ hostLevelParams.put(CUSTOM_COMMAND, commandName);
+ execCmd.setHostLevelParams(hostLevelParams);
+
+ Map<String,String> commandParams = new TreeMap<String, String>();
+ commandParams.put(SCHEMA_VERSION, serviceInfo.getSchemaVersion());
+
+ String commandTimeout = COMMAND_TIMEOUT_DEFAULT;
+
+ if (serviceInfo.getSchemaVersion().equals(AmbariMetaInfo.SCHEMA_VERSION_2)) {
+ // Service check command is not custom command
+ ComponentInfo componentInfo = ambariMetaInfo.getComponent(
+ stackId.getStackName(), stackId.getStackVersion(),
+ serviceName, componentName);
+ CommandScriptDefinition script = componentInfo.getCommandScript();
+
+ if (script != null) {
+ commandParams.put(SCRIPT, script.getScript());
+ commandParams.put(SCRIPT_TYPE, script.getScriptType().toString());
+ commandTimeout = String.valueOf(script.getTimeout());
+ } else {
+ String message = String.format("Component %s has not command script " +
+ "defined. It is not possible to run service check" +
+ " for this service", componentName);
+ throw new AmbariException(message);
+ }
+ // We don't need package/repo infomation to perform service check
+ }
+ commandParams.put(COMMAND_TIMEOUT, commandTimeout);
+
+ commandParams.put(SERVICE_METADATA_FOLDER,
+ serviceInfo.getServiceMetadataFolder());
+
+ execCmd.setCommandParams(commandParams);
+
+ }
+ }
+
private void addServiceCheckAction(ExecuteActionRequest actionRequest, Stage stage,
HostsMap hostsMap,
Map<String, String> hostLevelParams)
@@ -238,7 +349,7 @@ public class AmbariCustomCommandExecutionHelperImpl implements AmbariCustomComma
commandParams.put(SCRIPT_TYPE, script.getScriptType().toString());
commandTimeout = String.valueOf(script.getTimeout());
} else {
- String message = String.format("Service %s has not command script " +
+ String message = String.format("Service %s has no command script " +
"defined. It is not possible to run service check" +
" for this service", serviceName);
throw new AmbariException(message);
http://git-wip-us.apache.org/repos/asf/ambari/blob/d60ee2cb/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 dc6d229..d6bd198 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
@@ -32,11 +32,20 @@ public class ActionMetadata {
private final Map<String, String> serviceClients = new HashMap<String, String>();
private final Map<String, String> serviceCheckActions =
new HashMap<String, String>();
+ private final List<String> defaultHostComponentCommands = new ArrayList<String>();
public ActionMetadata() {
fillServiceActions();
fillServiceClients();
fillServiceCheckActions();
+ fillHostComponentCommands();
+ }
+
+ private void fillHostComponentCommands() {
+ //Standart commands for any host component
+ // TODO: Add START/STOP/INSTALL commands
+ defaultHostComponentCommands.add("RESTART");
+ defaultHostComponentCommands.add("CONFIGURE");
}
private void fillServiceClients() {
@@ -106,4 +115,11 @@ public class ActionMetadata {
public String getServiceCheckAction(String serviceName) {
return serviceCheckActions.get(serviceName.toLowerCase());
}
+
+ public boolean isDefaultHostComponentCommand(String command) {
+ if (command != null && defaultHostComponentCommands.contains(command)) {
+ return true;
+ }
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d60ee2cb/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
index 8e2a562..7be8fc3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
@@ -89,4 +89,15 @@ public class ComponentInfo {
}
return customCommands;
}
+
+ public boolean isCustomCommand(String commandName) {
+ if (customCommands != null && commandName != null) {
+ for (CustomCommandDefinition cc: customCommands) {
+ if (commandName.equals(cc.getName())){
+ return true;
+ }
+ }
+ }
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d60ee2cb/ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/metainfo.xml
index 363338b..f6db6be 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/metainfo.xml
@@ -44,7 +44,7 @@
</commandScript>
<customCommands>
<customCommand>
- <name>DECOMMISSION_REGIONSERVER</name>
+ <name>DECOMMISSION</name>
<commandScript>
<script>scripts/hbase_regionserver.py</script>
<scriptType>PYTHON</scriptType>
http://git-wip-us.apache.org/repos/asf/ambari/blob/d60ee2cb/ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/hbase_regionserver.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/hbase_regionserver.py b/ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/hbase_regionserver.py
index 014d0ab..2d91e75 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/hbase_regionserver.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/hbase_regionserver.py
@@ -59,7 +59,7 @@ class HbaseRegionServer(Script):
pid_file = format("{pid_dir}/hbase-hbase-regionserver.pid")
check_process_status(pid_file)
- def decommission(self):
+ def decommission(self, env):
print "Decommission not yet implemented!"
def main():
http://git-wip-us.apache.org/repos/asf/ambari/blob/d60ee2cb/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
index e8a3a1f..6417a72 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
@@ -1308,6 +1308,57 @@ public class TestHeartbeatHandler {
State.INSTALL_FAILED, serviceComponentHost2.getState());
}
+ @Test
+ public void testIgnoreCustomActionReport() throws AmbariException, InvalidStateTransitionException {
+ ActionManager am = getMockActionManager();
+
+ CommandReport cr1 = new CommandReport();
+ cr1.setActionId(StageUtils.getActionId(requestId, stageId));
+ cr1.setTaskId(1);
+ cr1.setClusterName(DummyCluster);
+ cr1.setServiceName(HDFS);
+ cr1.setRole(NAMENODE);
+ cr1.setStatus(HostRoleStatus.FAILED.toString());
+ cr1.setRoleCommand("CUSTOM_COMMAND");
+ cr1.setStdErr("none");
+ cr1.setStdOut("dummy output");
+ cr1.setExitCode(0);
+ CommandReport cr2 = new CommandReport();
+ cr2.setActionId(StageUtils.getActionId(requestId, stageId));
+ cr2.setTaskId(2);
+ cr2.setClusterName(DummyCluster);
+ cr2.setServiceName(HDFS);
+ cr2.setRole(NAMENODE);
+ cr2.setStatus(HostRoleStatus.FAILED.toString());
+ cr2.setRoleCommand("ACTIONEXECUTE");
+ cr2.setStdErr("none");
+ cr2.setStdOut("dummy output");
+ cr2.setExitCode(0);
+
+ ArrayList<CommandReport> reports = new ArrayList<CommandReport>();
+ reports.add(cr1);
+ reports.add(cr2);
+
+ HeartBeat hb = new HeartBeat();
+ hb.setTimestamp(System.currentTimeMillis());
+ hb.setResponseId(0);
+ hb.setHostname(DummyHostname1);
+ hb.setNodeStatus(new HostStatus(Status.HEALTHY, DummyHostStatus));
+ hb.setReports(reports);
+
+ ActionQueue aq = new ActionQueue();
+ HeartBeatHandler handler = getHeartBeatHandler(am, aq);
+
+ // CUSTOM_COMMAND and ACTIONEXECUTE reports are ignored
+ // they should not change the host component state
+ try {
+ handler.handleHeartBeat(hb);
+ } catch (Exception e) {
+ fail();
+ }
+
+ }
+
private ActionManager getMockActionManager() {
return new ActionManager(0, 0, null, null,
new ActionDBInMemoryImpl(), new HostsMap((String) null), null, unitOfWork, null);
http://git-wip-us.apache.org/repos/asf/ambari/blob/d60ee2cb/ambari-server/src/test/java/org/apache/ambari/server/api/util/StackExtensionHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/util/StackExtensionHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/util/StackExtensionHelperTest.java
index 152a6b5..a31ed6e 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/util/StackExtensionHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/util/StackExtensionHelperTest.java
@@ -89,6 +89,7 @@ public class StackExtensionHelperTest {
firstComponent.getCustomCommands();
assertEquals(1, customCommands.size());
assertEquals("RESTART", customCommands.get(0).getName());
+ assertTrue(firstComponent.isCustomCommand("RESTART"));
assertEquals("scripts/hbase_master_restart.py",
customCommands.get(0).getCommandScript().getScript());
assertEquals(CommandScriptDefinition.Type.PYTHON,