Browse Source

AMBARI-4570. Various issues related to decommission support

Sumit Mohanty 11 năm trước cách đây
mục cha
commit
2b4e395639
33 tập tin đã thay đổi với 337 bổ sung71 xóa
  1. 30 12
      ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java
  2. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
  3. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
  4. 86 22
      ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
  5. 13 1
      ambari-server/src/main/java/org/apache/ambari/server/controller/ShortTaskStatus.java
  6. 14 2
      ambari-server/src/main/java/org/apache/ambari/server/controller/TaskStatusResponse.java
  7. 11 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/TaskResourceProvider.java
  8. 35 0
      ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
  9. 1 1
      ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
  10. 1 1
      ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
  11. 1 1
      ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
  12. 2 0
      ambari-server/src/main/resources/properties.json
  13. 2 2
      ambari-server/src/main/resources/stacks/HDP/1.3.2/services/HBASE/package/scripts/params.py
  14. 6 4
      ambari-server/src/main/resources/stacks/HDP/1.3.2/services/HDFS/package/scripts/hdfs_namenode.py
  15. 1 0
      ambari-server/src/main/resources/stacks/HDP/1.3.2/services/HDFS/package/scripts/params.py
  16. 6 4
      ambari-server/src/main/resources/stacks/HDP/1.3.2/services/MAPREDUCE/package/scripts/jobtracker.py
  17. 1 0
      ambari-server/src/main/resources/stacks/HDP/1.3.2/services/MAPREDUCE/package/scripts/params.py
  18. 2 2
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HBASE/package/scripts/params.py
  19. 9 4
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/package/scripts/hdfs_namenode.py
  20. 1 0
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/package/scripts/params.py
  21. 2 1
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/params.py
  22. 4 3
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/resourcemanager.py
  23. 2 0
      ambari-server/src/main/resources/upgrade/ddl/Ambari-DDL-MySQL-UPGRADE.sql
  24. 2 0
      ambari-server/src/main/resources/upgrade/ddl/Ambari-DDL-Oracle-UPGRADE.sql
  25. 2 0
      ambari-server/src/main/resources/upgrade/ddl/Ambari-DDL-Postgres-UPGRADE-1.3.0.sql
  26. 64 1
      ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
  27. 7 1
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/TaskResourceProviderTest.java
  28. 15 0
      ambari-server/src/test/python/stacks/1.3.2/MAPREDUCE/test_mapreduce_jobtracker.py
  29. 3 1
      ambari-server/src/test/python/stacks/1.3.2/configs/default.hbasedecom.json
  30. 3 1
      ambari-server/src/test/python/stacks/1.3.2/configs/default.json
  31. 4 2
      ambari-server/src/test/python/stacks/1.3.2/configs/secured.json
  32. 2 1
      ambari-server/src/test/python/stacks/2.0.6/configs/default.json
  33. 3 2
      ambari-server/src/test/python/stacks/2.0.6/configs/secured.json

+ 30 - 12
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java

@@ -17,6 +17,7 @@
  */
 package org.apache.ambari.server.actionmanager;
 
+import com.google.inject.Injector;
 import com.google.inject.assistedinject.Assisted;
 import com.google.inject.assistedinject.AssistedInject;
 import org.apache.ambari.server.Role;
@@ -28,8 +29,6 @@ import org.apache.ambari.server.state.ServiceComponentHostEvent;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Injector;
-
 /**
  * This class encapsulates the information for an task on a host for a
  * particular role which action manager needs. It doesn't capture actual
@@ -38,30 +37,29 @@ import com.google.inject.Injector;
  */
 public class HostRoleCommand {
   private static final Logger log = LoggerFactory.getLogger(HostRoleCommand.class);
-
+  private final Role role;
+  private final ServiceComponentHostEventWrapper event;
   private long taskId = -1;
   private long stageId = -1;
   private long requestId = -1;
   private String hostName;
-  private final Role role;
   private HostRoleStatus status = HostRoleStatus.PENDING;
   private String stdout = "";
   private String stderr = "";
   private String structuredOut = "";
   private int exitCode = 999; //Default is unknown
-  private final ServiceComponentHostEventWrapper event;
   private long startTime = -1;
   private long endTime = -1;
   private long lastAttemptTime = -1;
   private short attemptCount = 0;
   private RoleCommand roleCommand;
-
+  private String commandDetail;
+  private String customCommandName;
   private ExecutionCommandWrapper executionCommandWrapper;
-
   private ExecutionCommandDAO executionCommandDAO;
 
   public HostRoleCommand(String host, Role role,
-      ServiceComponentHostEvent event, RoleCommand command) {
+                         ServiceComponentHostEvent event, RoleCommand command) {
     this.hostName = host;
     this.role = role;
     this.event = new ServiceComponentHostEventWrapper(event);
@@ -86,6 +84,8 @@ public class HostRoleCommand {
     attemptCount = hostRoleCommandEntity.getAttemptCount();
     roleCommand = hostRoleCommandEntity.getRoleCommand();
     event = new ServiceComponentHostEventWrapper(hostRoleCommandEntity.getEvent());
+    commandDetail = hostRoleCommandEntity.getCommandDetail();
+    customCommandName = hostRoleCommandEntity.getCustomCommandName();
     //make use of lazy loading
 
     executionCommandDAO = injector.getInstance(ExecutionCommandDAO.class);
@@ -105,6 +105,8 @@ public class HostRoleCommand {
     hostRoleCommandEntity.setLastAttemptTime(lastAttemptTime);
     hostRoleCommandEntity.setAttemptCount(attemptCount);
     hostRoleCommandEntity.setRoleCommand(roleCommand);
+    hostRoleCommandEntity.setCommandDetail(commandDetail);
+    hostRoleCommandEntity.setCustomCommandName(customCommandName);
 
     hostRoleCommandEntity.setEvent(event.getEventJson());
 
@@ -139,18 +141,34 @@ public class HostRoleCommand {
     return role;
   }
 
-  public HostRoleStatus getStatus() {
-    return status;
+  public String getCommandDetail() {
+    return commandDetail;
   }
 
-  public ServiceComponentHostEventWrapper getEvent() {
-    return event;
+  public void setCommandDetail(String commandDetail) {
+    this.commandDetail = commandDetail;
+  }
+
+  public String getCustomCommandName() {
+    return customCommandName;
+  }
+
+  public void setCustomCommandName(String customCommandName) {
+    this.customCommandName = customCommandName;
+  }
+
+  public HostRoleStatus getStatus() {
+    return status;
   }
 
   public void setStatus(HostRoleStatus status) {
     this.status = status;
   }
 
+  public ServiceComponentHostEventWrapper getEvent() {
+    return event;
+  }
+
   public String getStdout() {
     return stdout;
   }

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java

@@ -443,7 +443,7 @@ public class Stage {
         origStage.getHostRoleCommand(hostname, role));
   }
 
-  HostRoleCommand getHostRoleCommand(String hostname, String role) {
+  public HostRoleCommand getHostRoleCommand(String hostname, String role) {
     return hostRoleCommands.get(hostname).get(role);
   }
 

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java

@@ -344,7 +344,7 @@ public class HeartBeatHandler {
             }
           } else if (report.getStatus().equals("FAILED")) {
             LOG.warn("Operation failed - may be retried. Service component host: "
-                + schName + ", host: " + hostname);
+                + schName + ", host: " + hostname + " Action id" + report.getActionId());
             scHost.handleEvent(new ServiceComponentHostOpFailedEvent(schName,
                 hostname, now));
           } else if (report.getStatus().equals("IN_PROGRESS")) {

+ 86 - 22
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java

@@ -24,6 +24,7 @@ import com.google.inject.Singleton;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.RoleCommand;
+import org.apache.ambari.server.actionmanager.HostRoleCommand;
 import org.apache.ambari.server.actionmanager.Stage;
 import org.apache.ambari.server.agent.ExecutionCommand;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
@@ -54,6 +55,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -106,6 +108,7 @@ public class AmbariCustomCommandExecutionHelper {
   private static String DECOM_EXCLUDED_HOSTS = "excluded_hosts";
   private static String DECOM_SLAVE_COMPONENT = "slave_type";
   private static String HBASE_MARK_DRAINING_ONLY = "mark_draining_only";
+  private static String UPDATE_EXCLUDE_FILE_ONLY = "update_exclude_file_only";
   @Inject
   private ActionMetadata actionMetadata;
   @Inject
@@ -197,15 +200,29 @@ public class AmbariCustomCommandExecutionHelper {
     } else if (actionRequest.getCommandName().equals("DECOMMISSION")) {
       addDecommissionAction(actionRequest, stage, hostLevelParams);
     } else if (isValidCustomCommand(actionRequest)) {
-      addCustomCommandAction(actionRequest, stage, hostLevelParams, null);
+      String commandDetail = getReadableCustomCommandDetail(actionRequest);
+      addCustomCommandAction(actionRequest, stage, hostLevelParams, null, commandDetail);
     } else {
       throw new AmbariException("Unsupported action " + actionRequest.getCommandName());
     }
   }
 
+  private String getReadableCustomCommandDetail(ExecuteActionRequest actionRequest) {
+    StringBuffer sb = new StringBuffer();
+    sb.append(actionRequest.getCommandName());
+    if (actionRequest.getServiceName() != null && !actionRequest.getServiceName().equals("")) {
+      sb.append(" for " + actionRequest.getServiceName());
+    }
+    if (actionRequest.getComponentName() != null && !actionRequest.getComponentName().equals("")) {
+      sb.append("/" + actionRequest.getComponentName());
+    }
+    return sb.toString();
+  }
+
   private void addCustomCommandAction(ExecuteActionRequest actionRequest,
                                       Stage stage, Map<String, String> hostLevelParams,
-                                      Map<String, String> additionalCommandParams)
+                                      Map<String, String> additionalCommandParams,
+                                      String commandDetail)
       throws AmbariException {
 
     if (actionRequest.getHosts().isEmpty()) {
@@ -224,7 +241,7 @@ public class AmbariCustomCommandExecutionHelper {
         ambariMetaInfo.getServiceInfo(stackId.getStackName(),
             stackId.getStackVersion(), serviceName);
     StackInfo stackInfo = ambariMetaInfo.getStackInfo(stackId.getStackName(),
-            stackId.getStackVersion());
+        stackId.getStackVersion());
 
     long nowTimestamp = System.currentTimeMillis();
 
@@ -240,6 +257,12 @@ public class AmbariCustomCommandExecutionHelper {
       Map<String, Map<String, String>> configTags =
           amc.findConfigurationTagsWithOverrides(cluster, hostName);
 
+      HostRoleCommand cmd = stage.getHostRoleCommand(hostName, componentName);
+      if (cmd != null) {
+        cmd.setCommandDetail(commandDetail);
+        cmd.setCustomCommandName(actionRequest.getCommandName());
+      }
+
       ExecutionCommand execCmd = stage.getExecutionCommandWrapper(hostName,
           componentName).getExecutionCommand();
 
@@ -278,7 +301,7 @@ public class AmbariCustomCommandExecutionHelper {
         } else {
           String message = String.format("Component %s has not command script " +
               "defined. It is not possible to send command for " +
-                  "this service", componentName);
+              "this service", componentName);
           throw new AmbariException(message);
         }
         // We don't need package/repo information to perform service check
@@ -366,7 +389,7 @@ public class AmbariCustomCommandExecutionHelper {
         ambariMetaInfo.getServiceInfo(stackId.getStackName(),
             stackId.getStackVersion(), serviceName);
     StackInfo stackInfo = ambariMetaInfo.getStackInfo(stackId.getStackName(),
-            stackId.getStackVersion());
+        stackId.getStackVersion());
 
 
     stage.addHostRoleExecutionCommand(hostname,
@@ -375,6 +398,10 @@ public class AmbariCustomCommandExecutionHelper {
         new ServiceComponentHostOpInProgressEvent(componentName, hostname,
             nowTimestamp), cluster.getClusterName(), serviceName);
 
+    HostRoleCommand hrc = stage.getHostRoleCommand(hostname, smokeTestRole);
+    if (hrc != null) {
+      hrc.setCommandDetail(String.format("%s %s", RoleCommand.SERVICE_CHECK.toString(), serviceName));
+    }
     // [ type -> [ key, value ] ]
     Map<String, Map<String, String>> configurations =
         new TreeMap<String, Map<String, String>>();
@@ -533,29 +560,66 @@ public class AmbariCustomCommandExecutionHelper {
       }
     }
 
-    Set<String> masterHosts = masterComponent.getServiceComponentHosts().keySet();
-    ExecuteActionRequest commandRequest = new ExecuteActionRequest(
-        request.getClusterName(), request.getCommandName(), request.getActionName(), request.getServiceName(),
-        masterComponent.getName(), new ArrayList<String>(masterHosts), null);
+    // In the event there are more than one master host the following logic is applied
+    // -- HDFS/DN, MR1/TT, YARN/NM call refresh node on both
+    // -- HBASE/RS call only on one host
 
-    String clusterHostInfoJson = StageUtils.getGson().toJson(
-        StageUtils.getClusterHostInfo(clusters.getHostsForCluster(cluster.getClusterName()), cluster));
+    // Ensure host is active
+    Map<String, ServiceComponentHost> masterSchs = masterComponent.getServiceComponentHosts();
+    String primaryCandidate = null;
+    for (String hostName : masterSchs.keySet()) {
+      if (primaryCandidate == null) {
+        primaryCandidate = hostName;
+      } else {
+        ServiceComponentHost sch = masterSchs.get(hostName);
+        if (sch.getState() == State.STARTED) {
+          primaryCandidate = hostName;
+        }
+      }
+    }
 
-    // Reset cluster host info as it has changed
-    stage.setClusterHostInfo(clusterHostInfoJson);
+    StringBuilder commandDetail = getReadableDecommissionCommandDetail(request, includedHosts, listOfExcludedHosts);
 
-    Map<String, String> commandParams = null;
-    if (serviceName.equals(Service.Type.HBASE.name()) && listOfExcludedHosts.size() > 0) {
-      commandParams = new HashMap<String, String>();
-      commandParams.put(DECOM_EXCLUDED_HOSTS, StringUtils.join(listOfExcludedHosts, ','));
-      if (isDrainOnlyRequest != null) {
-        if (isDrainOnlyRequest.equals("true") || isDrainOnlyRequest.equals("false")) {
+    for (String hostName : masterSchs.keySet()) {
+      ExecuteActionRequest commandRequest = new ExecuteActionRequest(
+          request.getClusterName(), request.getCommandName(), request.getActionName(), request.getServiceName(),
+          masterComponent.getName(), Collections.singletonList(hostName), null);
+
+      String clusterHostInfoJson = StageUtils.getGson().toJson(
+          StageUtils.getClusterHostInfo(clusters.getHostsForCluster(cluster.getClusterName()), cluster));
+
+      // Reset cluster host info as it has changed
+      stage.setClusterHostInfo(clusterHostInfoJson);
+
+      Map<String, String> commandParams = new HashMap<String, String>();
+      if (serviceName.equals(Service.Type.HBASE.name())) {
+        commandParams.put(DECOM_EXCLUDED_HOSTS, StringUtils.join(listOfExcludedHosts, ','));
+        if ((isDrainOnlyRequest != null) && isDrainOnlyRequest.equals("true")) {
           commandParams.put(HBASE_MARK_DRAINING_ONLY, isDrainOnlyRequest);
+        } else {
+          commandParams.put(HBASE_MARK_DRAINING_ONLY, "false");
         }
       }
+
+      if (!serviceName.equals(Service.Type.HBASE.name()) || hostName.equals(primaryCandidate)) {
+        commandParams.put(UPDATE_EXCLUDE_FILE_ONLY, "false");
+        addCustomCommandAction(commandRequest, stage, hostLevelParams, commandParams, commandDetail.toString());
+      }
     }
+  }
 
-    addCustomCommandAction(commandRequest, stage, hostLevelParams, commandParams);
+  private StringBuilder getReadableDecommissionCommandDetail(ExecuteActionRequest request,
+                                                             Set<String> includedHosts,
+                                                             List<String> listOfExcludedHosts) {
+    StringBuilder commandDetail = new StringBuilder();
+    commandDetail.append(request.getCommandName());
+    if (listOfExcludedHosts.size() > 0) {
+      commandDetail.append(", Excluded: ").append(StringUtils.join(listOfExcludedHosts, ','));
+    }
+    if (includedHosts.size() > 0) {
+      commandDetail.append(", Included: ").append(StringUtils.join(includedHosts, ','));
+    }
+    return commandDetail;
   }
 
   /**
@@ -585,7 +649,7 @@ public class AmbariCustomCommandExecutionHelper {
         stackId.getStackName(), stackId.getStackVersion(),
         serviceName, componentName);
     StackInfo stackInfo = ambariMetaInfo.getStackInfo(stackId.getStackName(),
-            stackId.getStackVersion());
+        stackId.getStackVersion());
 
     ExecutionCommand execCmd = stage.getExecutionCommandWrapper(scHost.getHostName(),
         scHost.getServiceComponentName()).getExecutionCommand();
@@ -612,7 +676,7 @@ public class AmbariCustomCommandExecutionHelper {
      * component main commandScript to agent. This script is only used for
      * default commads like INSTALL/STOP/START/CONFIGURE
      */
-    String commandTimeout =configs.getDefaultAgentTaskTimeout();
+    String commandTimeout = configs.getDefaultAgentTaskTimeout();
     CommandScriptDefinition script = componentInfo.getCommandScript();
     if (serviceInfo.getSchemaVersion().equals(AmbariMetaInfo.SCHEMA_VERSION_2)) {
       if (script != null) {

+ 13 - 1
ambari-server/src/main/java/org/apache/ambari/server/controller/ShortTaskStatus.java

@@ -27,17 +27,20 @@ public class ShortTaskStatus {
   protected String role;
   protected String command;
   protected String status;
+  protected String customCommandName;
 
   public ShortTaskStatus() {
   }
 
-  public ShortTaskStatus(int taskId, long stageId, String hostName, String role, String command, String status) {
+  public ShortTaskStatus(int taskId, long stageId, String hostName, String role, String command, String status,
+                         String customCommandName) {
     this.taskId = taskId;
     this.stageId = stageId;
     this.hostName = hostName;
     this.role = role;
     this.command = command;
     this.status = status;
+    this.customCommandName = customCommandName;
   }
 
   public ShortTaskStatus(HostRoleCommand hostRoleCommand) {
@@ -47,6 +50,15 @@ public class ShortTaskStatus {
     this.hostName = hostRoleCommand.getHostName();
     this.role = hostRoleCommand.getRole().toString();
     this.status = hostRoleCommand.getStatus().toString();
+    this.customCommandName = hostRoleCommand.getCustomCommandName();
+  }
+
+  public String getCustomCommandName() {
+    return customCommandName;
+  }
+
+  public void setCustomCommandName(String customCommandName) {
+    this.customCommandName = customCommandName;
   }
 
   public long getTaskId() {

+ 14 - 2
ambari-server/src/main/java/org/apache/ambari/server/controller/TaskStatusResponse.java

@@ -26,6 +26,7 @@ public class TaskStatusResponse extends ShortTaskStatus {
   private String stderr;
   private String stdout;
   private String structuredOut;
+  private String commandDetail;
   private long startTime;
   private Long endTime;
   private short attemptCount;
@@ -35,14 +36,16 @@ public class TaskStatusResponse extends ShortTaskStatus {
 
   public TaskStatusResponse(long requestId,
                             int taskId, long stageId, String hostName, String role, String command, String status,
-                            int exitCode, String stderr, String stdout, long startTime, short attemptCount) {
-    super(taskId, stageId, hostName, role, command, status);
+                            int exitCode, String stderr, String stdout, long startTime, short attemptCount,
+                            String commandDetail, String customCommandName) {
+    super(taskId, stageId, hostName, role, command, status, customCommandName);
     this.requestId = requestId;
     this.exitCode = exitCode;
     this.stderr = stderr;
     this.stdout = stdout;
     this.startTime = startTime;
     this.attemptCount = attemptCount;
+    this.commandDetail = commandDetail;
   }
 
   public TaskStatusResponse(HostRoleCommand hostRoleCommand) {
@@ -55,6 +58,7 @@ public class TaskStatusResponse extends ShortTaskStatus {
     this.attemptCount = hostRoleCommand.getAttemptCount();
     this.structuredOut = hostRoleCommand.getStructuredOut();
     this.endTime = hostRoleCommand.getEndTime();
+    this.commandDetail = hostRoleCommand.getCommandDetail();
   }
 
   public long getRequestId() {
@@ -121,6 +125,14 @@ public class TaskStatusResponse extends ShortTaskStatus {
     this.endTime = endTime;
   }
 
+  public String getCommandDetail() {
+    return commandDetail;
+  }
+
+  public void setCommandDetail(String commandDetail) {
+    this.commandDetail = commandDetail;
+  }
+
   @Override
   public String toString() {
       return super.toString();

+ 11 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/TaskResourceProvider.java

@@ -60,6 +60,8 @@ class TaskResourceProvider extends AbstractControllerResourceProvider {
   protected static final String TASK_START_TIME_PROPERTY_ID   = PropertyHelper.getPropertyId("Tasks", "start_time");
   protected static final String TASK_END_TIME_PROPERTY_ID     = PropertyHelper.getPropertyId("Tasks", "end_time");
   protected static final String TASK_ATTEMPT_CNT_PROPERTY_ID  = PropertyHelper.getPropertyId("Tasks", "attempt_cnt");
+  protected static final String TASK_COMMAND_DET_PROPERTY_ID  = PropertyHelper.getPropertyId("Tasks", "command_detail");
+  protected static final String TASK_CUST_CMD_NAME_PROPERTY_ID  = PropertyHelper.getPropertyId("Tasks", "custom_command_name");
 
 
   private static Set<String> pkPropertyIds =
@@ -147,6 +149,15 @@ class TaskResourceProvider extends AbstractControllerResourceProvider {
         setResourceProperty(resource, TASK_START_TIME_PROPERTY_ID, response.getStartTime(), requestedIds);
         setResourceProperty(resource, TASK_END_TIME_PROPERTY_ID, response.getEndTime(), requestedIds);
         setResourceProperty(resource, TASK_ATTEMPT_CNT_PROPERTY_ID, response.getAttemptCount(), requestedIds);
+        if (response.getCustomCommandName() != null) {
+          setResourceProperty(resource, TASK_CUST_CMD_NAME_PROPERTY_ID, response.getCustomCommandName(), requestedIds);
+        }
+        if (response.getCommandDetail() == null) {
+          setResourceProperty(resource, TASK_COMMAND_DET_PROPERTY_ID,
+              String.format("%s %s", response.getRole(), response.getCommand()), requestedIds);
+        } else {
+          setResourceProperty(resource, TASK_COMMAND_DET_PROPERTY_ID, response.getCommandDetail(), requestedIds);
+        }
         resources.add(resource);
       }
     }

+ 35 - 0
ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java

@@ -56,6 +56,8 @@ import org.apache.commons.lang.ArrayUtils;
 
 public class HostRoleCommandEntity {
 
+  private static int MAX_COMMAND_DETAIL_LENGTH = 250;
+
   @Column(name = "task_id")
   @Id
   @GeneratedValue(strategy = GenerationType.TABLE, generator = "host_role_command_id_generator")
@@ -120,10 +122,21 @@ public class HostRoleCommandEntity {
   @Column(name = "attempt_count", nullable = false)
   private Short attemptCount = 0;
 
+  // This is really command type as well as name
   @Column(name = "role_command")
   @Enumerated(EnumType.STRING)
   private RoleCommand roleCommand;
 
+  // A readable description of the command
+  @Column(name = "command_detail")
+  @Basic
+  private String commandDetail;
+
+  // When command type id CUSTOM_COMMAND and CUSTOM_ACTION this is the name
+  @Column(name = "custom_command_name")
+  @Basic
+  private String customCommandName;
+
   @OneToOne(mappedBy = "hostRoleCommand", cascade = CascadeType.REMOVE, fetch = FetchType.LAZY)
   private ExecutionCommandEntity executionCommand;
 
@@ -263,6 +276,28 @@ public class HostRoleCommandEntity {
     this.endTime = endTime;
   }
 
+  public String getCommandDetail() {
+    return commandDetail;
+  }
+
+  public void setCommandDetail(String commandDetail) {
+    String truncatedCommandDetail = commandDetail;
+    if (commandDetail != null) {
+      if (commandDetail.length() > MAX_COMMAND_DETAIL_LENGTH) {
+        truncatedCommandDetail = commandDetail.substring(0, MAX_COMMAND_DETAIL_LENGTH) + "...";
+      }
+    }
+    this.commandDetail = truncatedCommandDetail;
+  }
+
+  public String getCustomCommandName() {
+    return customCommandName;
+  }
+
+  public void setCustomCommandName(String customCommandName) {
+    this.customCommandName = customCommandName;
+  }
+
   @Override
   public boolean equals(Object o) {
     if (this == o) return true;

+ 1 - 1
ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql

@@ -39,7 +39,7 @@ CREATE TABLE servicedesiredstate (cluster_id BIGINT NOT NULL, desired_host_role_
 CREATE TABLE roles (role_name VARCHAR(255) NOT NULL, PRIMARY KEY (role_name));
 CREATE TABLE users (user_id INTEGER, create_time TIMESTAMP DEFAULT NOW(), ldap_user INTEGER NOT NULL DEFAULT 0, user_name VARCHAR(255) NOT NULL, user_password VARCHAR(255), PRIMARY KEY (user_id));
 CREATE TABLE execution_command (task_id BIGINT NOT NULL, command LONGBLOB, PRIMARY KEY (task_id));
-CREATE TABLE host_role_command (task_id BIGINT NOT NULL, attempt_count SMALLINT NOT NULL, event LONGTEXT NOT NULL, exitcode INTEGER NOT NULL, host_name VARCHAR(255) NOT NULL, last_attempt_time BIGINT NOT NULL, request_id BIGINT NOT NULL, role VARCHAR(255), role_command VARCHAR(255), stage_id BIGINT NOT NULL, start_time BIGINT NOT NULL, end_time BIGINT, status VARCHAR(255), std_error LONGBLOB, std_out LONGBLOB, structured_out LONGBLOB, PRIMARY KEY (task_id));
+CREATE TABLE host_role_command (task_id BIGINT NOT NULL, attempt_count SMALLINT NOT NULL, event LONGTEXT NOT NULL, exitcode INTEGER NOT NULL, host_name VARCHAR(255) NOT NULL, last_attempt_time BIGINT NOT NULL, request_id BIGINT NOT NULL, role VARCHAR(255), role_command VARCHAR(255), stage_id BIGINT NOT NULL, start_time BIGINT NOT NULL, end_time BIGINT, status VARCHAR(255), std_error LONGBLOB, std_out LONGBLOB, structured_out LONGBLOB, command_detail VARCHAR(255), custom_command_name VARCHAR(255), PRIMARY KEY (task_id));
 CREATE TABLE role_success_criteria (role VARCHAR(255) NOT NULL, request_id BIGINT NOT NULL, stage_id BIGINT NOT NULL, success_factor DOUBLE NOT NULL, PRIMARY KEY (role, request_id, stage_id));
 CREATE TABLE stage (stage_id BIGINT NOT NULL, request_id BIGINT NOT NULL, cluster_id BIGINT, log_info VARCHAR(255) NOT NULL, request_context VARCHAR(255), cluster_host_info LONGBLOB, PRIMARY KEY (stage_id, request_id));
 CREATE TABLE request (request_id BIGINT NOT NULL, cluster_id BIGINT, request_schedule_id BIGINT, command_name VARCHAR(255), create_time BIGINT NOT NULL, end_time BIGINT NOT NULL, inputs LONGTEXT, request_context VARCHAR(255), request_type VARCHAR(255), start_time BIGINT NOT NULL, status VARCHAR(255), target_component VARCHAR(255), target_hosts LONGTEXT, target_service VARCHAR(255), PRIMARY KEY (request_id));

+ 1 - 1
ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql

@@ -29,7 +29,7 @@ CREATE TABLE servicedesiredstate (cluster_id NUMBER(19) NOT NULL, desired_host_r
 CREATE TABLE roles (role_name VARCHAR2(255) NOT NULL, PRIMARY KEY (role_name));
 CREATE TABLE users (user_id NUMBER(10) NOT NULL, create_time TIMESTAMP NULL, ldap_user NUMBER(10) DEFAULT 0, user_name VARCHAR2(255) NULL, user_password VARCHAR2(255) NULL, PRIMARY KEY (user_id));
 CREATE TABLE execution_command (task_id NUMBER(19) NOT NULL, command BLOB NULL, PRIMARY KEY (task_id));
-CREATE TABLE host_role_command (task_id NUMBER(19) NOT NULL, attempt_count NUMBER(5) NOT NULL, event CLOB NULL, exitcode NUMBER(10) NOT NULL, host_name VARCHAR2(255) NOT NULL, last_attempt_time NUMBER(19) NOT NULL, request_id NUMBER(19) NOT NULL, role VARCHAR2(255) NULL, role_command VARCHAR2(255) NULL, stage_id NUMBER(19) NOT NULL, start_time NUMBER(19) NOT NULL, end_time NUMBER(19), status VARCHAR2(255) NULL, std_error BLOB NULL, std_out BLOB NULL, structured_out BLOB NULL, PRIMARY KEY (task_id));
+CREATE TABLE host_role_command (task_id NUMBER(19) NOT NULL, attempt_count NUMBER(5) NOT NULL, event CLOB NULL, exitcode NUMBER(10) NOT NULL, host_name VARCHAR2(255) NOT NULL, last_attempt_time NUMBER(19) NOT NULL, request_id NUMBER(19) NOT NULL, role VARCHAR2(255) NULL, role_command VARCHAR2(255) NULL, stage_id NUMBER(19) NOT NULL, start_time NUMBER(19) NOT NULL, end_time NUMBER(19), status VARCHAR2(255) NULL, std_error BLOB NULL, std_out BLOB NULL, structured_out BLOB NULL,  command_detail VARCHAR2(255) NULL, custom_command_name VARCHAR2(255) NULL, PRIMARY KEY (task_id));
 CREATE TABLE role_success_criteria (role VARCHAR2(255) NOT NULL, request_id NUMBER(19) NOT NULL, stage_id NUMBER(19) NOT NULL, success_factor NUMBER(19,4) NOT NULL, PRIMARY KEY (role, request_id, stage_id));
 CREATE TABLE stage (stage_id NUMBER(19) NOT NULL, request_id NUMBER(19) NOT NULL, cluster_id NUMBER(19) NULL, log_info VARCHAR2(255) NULL, request_context VARCHAR2(255) NULL, cluster_host_info BLOB NOT NULL, PRIMARY KEY (stage_id, request_id));
 CREATE TABLE request (request_id NUMBER(19) NOT NULL, cluster_id NUMBER(19), request_schedule_id NUMBER(19), command_name VARCHAR(255), create_time NUMBER(19) NOT NULL, end_time NUMBER(19) NOT NULL, inputs CLOB, request_context VARCHAR(255), request_type VARCHAR(255), start_time NUMBER(19) NOT NULL, status VARCHAR(255), target_component VARCHAR(255), target_hosts CLOB, target_service VARCHAR(255), PRIMARY KEY (request_id));

+ 1 - 1
ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql

@@ -70,7 +70,7 @@ GRANT ALL PRIVILEGES ON TABLE ambari.users TO :username;
 CREATE TABLE ambari.execution_command (command BYTEA, task_id BIGINT NOT NULL, PRIMARY KEY (task_id));
 GRANT ALL PRIVILEGES ON TABLE ambari.execution_command TO :username;
 
-CREATE TABLE ambari.host_role_command (task_id BIGINT NOT NULL, attempt_count SMALLINT NOT NULL, event VARCHAR(32000) NOT NULL, exitcode INTEGER NOT NULL, host_name VARCHAR(255) NOT NULL, last_attempt_time BIGINT NOT NULL, request_id BIGINT NOT NULL, role VARCHAR(255), stage_id BIGINT NOT NULL, start_time BIGINT NOT NULL, end_time BIGINT, status VARCHAR(255), std_error BYTEA, std_out BYTEA, structured_out BYTEA, role_command VARCHAR(255), PRIMARY KEY (task_id));
+CREATE TABLE ambari.host_role_command (task_id BIGINT NOT NULL, attempt_count SMALLINT NOT NULL, event VARCHAR(32000) NOT NULL, exitcode INTEGER NOT NULL, host_name VARCHAR(255) NOT NULL, last_attempt_time BIGINT NOT NULL, request_id BIGINT NOT NULL, role VARCHAR(255), stage_id BIGINT NOT NULL, start_time BIGINT NOT NULL, end_time BIGINT, status VARCHAR(255), std_error BYTEA, std_out BYTEA, structured_out BYTEA, role_command VARCHAR(255), command_detail VARCHAR(255), custom_command_name VARCHAR(255), PRIMARY KEY (task_id));
 GRANT ALL PRIVILEGES ON TABLE ambari.host_role_command TO :username;
 
 CREATE TABLE ambari.role_success_criteria (role VARCHAR(255) NOT NULL, request_id BIGINT NOT NULL, stage_id BIGINT NOT NULL, success_factor FLOAT NOT NULL, PRIMARY KEY (role, request_id, stage_id));

+ 2 - 0
ambari-server/src/main/resources/properties.json

@@ -144,6 +144,8 @@
         "Tasks/end_time",
         "Tasks/structured_out",
         "Tasks/attempt_cnt",
+        "Tasks/custom_command_name",
+        "Tasks/command_detail",
         "_"
     ],
     "User":[

+ 2 - 2
ambari-server/src/main/resources/stacks/HDP/1.3.2/services/HBASE/package/scripts/params.py

@@ -30,8 +30,8 @@ daemon_script = "/usr/lib/hbase/bin/hbase-daemon.sh"
 region_mover = "/usr/lib/hbase/bin/region_mover.rb"
 region_drainer = "/usr/lib/hbase/bin/draining_servers.rb"
 hbase_cmd = "/usr/lib/hbase/bin/hbase"
-hbase_excluded_hosts = default("/commandParams/excluded_hosts", "")
-hbase_drain_only = default("/commandParams/mark_draining_only", False)
+hbase_excluded_hosts = config['commandParams']['excluded_hosts']
+hbase_drain_only = config['commandParams']['mark_draining_only']
 
 hbase_user = config['configurations']['global']['hbase_user']
 smokeuser = config['configurations']['global']['smokeuser']

+ 6 - 4
ambari-server/src/main/resources/stacks/HDP/1.3.2/services/HDFS/package/scripts/hdfs_namenode.py

@@ -186,7 +186,9 @@ def decommission():
        group=params.user_group
   )
 
-  ExecuteHadoop('dfsadmin -refreshNodes',
-                user=hdfs_user,
-                conf_dir=conf_dir,
-                kinit_override=True)
+  if params.update_exclude_file_only == False:
+    ExecuteHadoop('dfsadmin -refreshNodes',
+                  user=hdfs_user,
+                  conf_dir=conf_dir,
+                  kinit_override=True)
+    pass

+ 1 - 0
ambari-server/src/main/resources/stacks/HDP/1.3.2/services/HDFS/package/scripts/params.py

@@ -49,6 +49,7 @@ dfs_journalnode_kerberos_internal_spnego_principal = config['configurations']['h
 #exclude file
 hdfs_exclude_file = default("/clusterHostInfo/decom_dn_hosts", [])
 exclude_file_path = config['configurations']['hdfs-site']['dfs.hosts.exclude']
+update_exclude_file_only = config['commandParams']['update_exclude_file_only']
 
 kinit_path_local = functions.get_kinit_path([default("kinit_path_local",None), "/usr/bin", "/usr/kerberos/bin", "/usr/sbin"])
 #hosts

+ 6 - 4
ambari-server/src/main/resources/stacks/HDP/1.3.2/services/MAPREDUCE/package/scripts/jobtracker.py

@@ -73,10 +73,12 @@ class Jobtracker(Script):
          group=user_group
     )
 
-    ExecuteHadoop('mradmin -refreshNodes',
-                user=mapred_user,
-                conf_dir=conf_dir,
-                kinit_override=True)
+    if params.update_exclude_file_only == False:
+      ExecuteHadoop('mradmin -refreshNodes',
+                  user=mapred_user,
+                  conf_dir=conf_dir,
+                  kinit_override=True)
+      pass
     pass
 
 if __name__ == "__main__":

+ 1 - 0
ambari-server/src/main/resources/stacks/HDP/1.3.2/services/MAPREDUCE/package/scripts/params.py

@@ -41,6 +41,7 @@ user_group = config['configurations']['global']['user_group']
 hdfs_log_dir_prefix = config['configurations']['global']['hdfs_log_dir_prefix']
 mapred_log_dir = format("{hdfs_log_dir_prefix}/{mapred_user}")
 mapred_local_dir = config['configurations']['mapred-site']['mapred.local.dir']
+update_exclude_file_only = config['commandParams']['update_exclude_file_only']
 
 hadoop_jar_location = "/usr/lib/hadoop/"
 smokeuser = config['configurations']['global']['smokeuser']

+ 2 - 2
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HBASE/package/scripts/params.py

@@ -30,8 +30,8 @@ daemon_script = "/usr/lib/hbase/bin/hbase-daemon.sh"
 region_mover = "/usr/lib/hbase/bin/region_mover.rb"
 region_drainer = "/usr/lib/hbase/bin/draining_servers.rb"
 hbase_cmd = "/usr/lib/hbase/bin/hbase"
-hbase_excluded_hosts = default("/commandParams/excluded_hosts", "")
-hbase_drain_only = default("/commandParams/mark_draining_only", False)
+hbase_excluded_hosts = config['commandParams']['excluded_hosts']
+hbase_drain_only = config['commandParams']['mark_draining_only']
 
 hbase_user = config['configurations']['global']['hbase_user']
 smokeuser = config['configurations']['global']['smokeuser']

+ 9 - 4
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/package/scripts/hdfs_namenode.py

@@ -63,6 +63,7 @@ def namenode(action=None, format=True):
   if action == "decommission":
     decommission()
 
+
 def create_name_dirs(directories):
   import params
 
@@ -137,6 +138,7 @@ def create_app_directories():
                      mode="755"
       )
 
+
 def create_user_directories():
   import params
 
@@ -206,7 +208,10 @@ def decommission():
        group=user_group
   )
 
-  ExecuteHadoop('dfsadmin -refreshNodes',
-                user=hdfs_user,
-                conf_dir=conf_dir,
-                kinit_override=True)
+  if params.update_exclude_file_only == False:
+    ExecuteHadoop('dfsadmin -refreshNodes',
+                  user=hdfs_user,
+                  conf_dir=conf_dir,
+                  kinit_override=True)
+    pass
+  pass

+ 1 - 0
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/package/scripts/params.py

@@ -50,6 +50,7 @@ dfs_journalnode_kerberos_internal_spnego_principal = config['configurations']['h
 #exclude file
 hdfs_exclude_file = default("/clusterHostInfo/decom_dn_hosts", [])
 exclude_file_path = config['configurations']['hdfs-site']['dfs.hosts.exclude']
+update_exclude_file_only = config['commandParams']['update_exclude_file_only']
 
 kinit_path_local = functions.get_kinit_path([default("kinit_path_local",None), "/usr/bin", "/usr/kerberos/bin", "/usr/sbin"])
 #hosts

+ 2 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/params.py

@@ -87,4 +87,5 @@ yarn_container_bin = "/usr/lib/hadoop-yarn/bin"
 
 #exclude file
 exclude_hosts = default("/clusterHostInfo/decom_nm_hosts", [])
-exclude_file_path = config['configurations']['yarn-site']['yarn.resourcemanager.nodes.exclude-path']
+exclude_file_path = config['configurations']['yarn-site']['yarn.resourcemanager.nodes.exclude-path']
+update_exclude_file_only = config['commandParams']['update_exclude_file_only']

+ 4 - 3
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/resourcemanager.py

@@ -102,9 +102,10 @@ class Resourcemanager(Script):
          group=user_group
     )
 
-    Execute(yarn_refresh_cmd,
-            user=yarn_user
-    )
+    if params.update_exclude_file_only == False:
+      Execute(yarn_refresh_cmd,
+            user=yarn_user)
+      pass
     pass
 
 

+ 2 - 0
ambari-server/src/main/resources/upgrade/ddl/Ambari-DDL-MySQL-UPGRADE.sql

@@ -83,6 +83,8 @@ create index idx_qrtz_ft_tg on QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
 ALTER TABLE hostcomponentdesiredstate ADD passive_state VARCHAR(32) NOT NULL DEFAULT 'ACTIVE';
 ALTER TABLE servicedesiredstate ADD passive_state VARCHAR(32) NOT NULL DEFAULT 'ACTIVE';
 ALTER TABLE hoststate ADD passive_state VARCHAR(512);
+ALTER TABLE host_role_command ADD command_detail VARCHAR(255);
+ALTER TABLE host_role_command ADD custom_command_name VARCHAR(255);
 
 -- blueprint related tables
 CREATE TABLE blueprint (blueprint_name VARCHAR(255) NOT NULL, stack_name VARCHAR(255) NOT NULL, stack_version VARCHAR(255) NOT NULL, PRIMARY KEY(blueprint_name));

+ 2 - 0
ambari-server/src/main/resources/upgrade/ddl/Ambari-DDL-Oracle-UPGRADE.sql

@@ -70,6 +70,8 @@ ALTER TABLE hosts DROP COLUMN disks_info;
 --Added end_time and structured output support to command execution result
 ALTER TABLE host_role_command ADD (end_time NUMBER(19) DEFAULT NULL);
 ALTER TABLE host_role_command ADD (structured_out BLOB DEFAULT NULL);
+ALTER TABLE host_role_command ADD (command_detail VARCHAR(255) DEFAULT NULL);
+ALTER TABLE host_role_command ADD (custom_command_name VARCHAR(255) DEFAULT NULL);
 
 --1.5.0 upgrade
 CREATE TABLE request (request_id NUMBER(19) NOT NULL, cluster_id NUMBER(19), request_schedule_id NUMBER(19), command_name VARCHAR(255), create_time NUMBER(19) NOT NULL, end_time NUMBER(19) NOT NULL, inputs CLOB, request_context VARCHAR(255), request_type VARCHAR(255), start_time NUMBER(19) NOT NULL, status VARCHAR(255), target_component VARCHAR(255), target_hosts CLOB, target_service VARCHAR(255), PRIMARY KEY (request_id))

+ 2 - 0
ambari-server/src/main/resources/upgrade/ddl/Ambari-DDL-Postgres-UPGRADE-1.3.0.sql

@@ -158,6 +158,8 @@ ALTER TABLE ambari.hosts DROP COLUMN disks_info;
 --Added end_time and structured output support to command execution result
 ALTER TABLE ambari.host_role_command ADD COLUMN end_time BIGINT;
 ALTER TABLE ambari.host_role_command ADD COLUMN structured_out BYTEA;
+ALTER TABLE ambari.host_role_command ADD COLUMN command_detail VARCHAR(255);
+ALTER TABLE ambari.host_role_command ADD COLUMN custom_command_name VARCHAR(255);
 
 --1.5.0 upgrade
 

+ 64 - 1
ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java

@@ -27,6 +27,7 @@ import static org.easymock.EasyMock.verify;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -2323,6 +2324,8 @@ public class AmbariManagementControllerTest {
 
     createServiceComponentHost(clusterName, serviceName, componentName1,
         host1, null);
+    createServiceComponentHost(clusterName, serviceName, componentName1,
+        host2, null);
     createServiceComponentHost(clusterName, serviceName, componentName2,
         host1, null);
     createServiceComponentHost(clusterName, serviceName, componentName2,
@@ -2361,6 +2364,11 @@ public class AmbariManagementControllerTest {
     Assert.assertEquals(HostComponentAdminState.DECOMMISSIONED, scHost.getComponentAdminState());
     Assert.assertEquals(PassiveState.PASSIVE, scHost.getPassiveState());
     HostRoleCommand command = storedTasks.get(0);
+    Assert.assertTrue("DECOMMISSION, Excluded: h2".equals(command.getCommandDetail()));
+    Assert.assertTrue("DECOMMISSION".equals(command.getCustomCommandName()));
+    Map<String, String> cmdParams = command.getExecutionCommandWrapper().getExecutionCommand().getCommandParams();
+    Assert.assertTrue(cmdParams.containsKey("mark_draining_only"));
+    Assert.assertEquals("false", cmdParams.get("mark_draining_only"));
     Assert.assertEquals(Role.HBASE_MASTER, command.getRole());
     Assert.assertEquals(RoleCommand.CUSTOM_COMMAND, command.getRoleCommand());
     Map<String, Set<String>> cInfo = execCmd.getClusterHostInfo();
@@ -2394,6 +2402,44 @@ public class AmbariManagementControllerTest {
     Assert.assertEquals(PassiveState.PASSIVE, scHost.getPassiveState());
     cInfo = execCmd.getClusterHostInfo();
     Assert.assertTrue(cInfo.containsKey("decom_hbase_rs_hosts"));
+    command = storedTasks.get(0);
+    Assert.assertEquals("DECOMMISSION", execCmd.getHostLevelParams().get("custom_command"));
+    Assert.assertTrue("DECOMMISSION, Excluded: h2".equals(command.getCommandDetail()));
+    Assert.assertTrue("DECOMMISSION".equals(command.getCustomCommandName()));
+    cmdParams = command.getExecutionCommandWrapper().getExecutionCommand().getCommandParams();
+    Assert.assertTrue(cmdParams.containsKey("mark_draining_only"));
+    Assert.assertEquals("true", cmdParams.get("mark_draining_only"));
+
+    //Recommission
+    params = new HashMap<String, String>() {{
+      put("included_hosts", "h2");
+    }};
+    request = new ExecuteActionRequest(clusterName, "DECOMMISSION", null, "HBASE", "HBASE_MASTER",
+        null, params);
+
+    response = controller.createAction(request,
+        requestProperties);
+
+    storedTasks = actionDB.getRequestTasks(response.getRequestId());
+    execCmd = storedTasks.get(0).getExecutionCommandWrapper
+        ().getExecutionCommand();
+    Assert.assertNotNull(storedTasks);
+    Assert.assertEquals(1, storedTasks.size());
+    Assert.assertEquals(HostComponentAdminState.INSERVICE, scHost.getComponentAdminState());
+    Assert.assertEquals(PassiveState.ACTIVE, scHost.getPassiveState());
+    command = storedTasks.get(0);
+    Assert.assertTrue("DECOMMISSION, Included: h2".equals(command.getCommandDetail()));
+    Assert.assertTrue("DECOMMISSION".equals(command.getCustomCommandName()));
+    cmdParams = command.getExecutionCommandWrapper().getExecutionCommand().getCommandParams();
+    Assert.assertTrue(cmdParams.containsKey("mark_draining_only"));
+    Assert.assertEquals("false", cmdParams.get("mark_draining_only"));
+
+    Assert.assertTrue(cmdParams.containsKey("excluded_hosts"));
+    Assert.assertEquals("", cmdParams.get("excluded_hosts"));
+    Assert.assertEquals(Role.HBASE_MASTER, command.getRole());
+    Assert.assertEquals(RoleCommand.CUSTOM_COMMAND, command.getRoleCommand());
+    cInfo = execCmd.getClusterHostInfo();
+    Assert.assertFalse(cInfo.containsKey("decom_hbase_rs_hosts"));
     Assert.assertEquals("DECOMMISSION", execCmd.getHostLevelParams().get("custom_command"));
   }
 
@@ -4104,6 +4150,9 @@ public class AmbariManagementControllerTest {
     assertEquals(1, storedTasks.size());
     HostRoleCommand hostRoleCommand = storedTasks.get(0);
 
+    assertEquals("SERVICE_CHECK HDFS", hostRoleCommand.getCommandDetail());
+    assertNull(hostRoleCommand.getCustomCommandName());
+
     assertEquals(task.getTaskId(), hostRoleCommand.getTaskId());
     assertEquals(actionRequest.getServiceName(), hostRoleCommand.getExecutionCommandWrapper().getExecutionCommand().getServiceName());
     assertEquals(actionRequest.getClusterName(), hostRoleCommand.getExecutionCommandWrapper().getExecutionCommand().getClusterName());
@@ -5853,6 +5902,9 @@ public class AmbariManagementControllerTest {
     storedTasks = actionDB.getRequestTasks(response.getRequestId());
     execCmd = storedTasks.get(0).getExecutionCommandWrapper
         ().getExecutionCommand();
+    Map<String, String> cmdParams = execCmd.getCommandParams();
+    Assert.assertTrue(cmdParams.containsKey("update_exclude_file_only"));
+    Assert.assertTrue(cmdParams.get("update_exclude_file_only").equals("false"));
     Assert.assertNotNull(storedTasks);
     Assert.assertEquals(1, storedTasks.size());
     Assert.assertEquals(HostComponentAdminState.DECOMMISSIONED, scHost.getComponentAdminState());
@@ -5862,7 +5914,7 @@ public class AmbariManagementControllerTest {
     Assert.assertEquals("0,1", cInfo.get("decom_dn_hosts").iterator().next());
     Assert.assertEquals("DECOMMISSION", execCmd.getHostLevelParams().get("custom_command"));
 
-    // Recommission the other datanode  (while adding NN HA)
+    // Recommission the other datanode  (while adding NameNode HA)
     createServiceComponentHost(clusterName, serviceName, componentName1,
         host2, null);
     ServiceComponentHostRequest r = new ServiceComponentHostRequest(clusterName, serviceName,
@@ -5898,6 +5950,17 @@ public class AmbariManagementControllerTest {
     Assert.assertEquals(2, storedTasks.size());
     cInfo = execCmd.getClusterHostInfo();
     Assert.assertFalse(cInfo.containsKey("decom_dn_hosts"));
+    int countRefresh = 0;
+    for(HostRoleCommand hrc : storedTasks) {
+      Assert.assertTrue("DECOMMISSION, Included: h1,h2".equals(hrc.getCommandDetail()));
+      Assert.assertTrue("DECOMMISSION".equals(hrc.getCustomCommandName()));
+      cmdParams = hrc.getExecutionCommandWrapper().getExecutionCommand().getCommandParams();
+      if(!cmdParams.containsKey("update_exclude_file_only")
+          || !cmdParams.get("update_exclude_file_only").equals("true")) {
+        countRefresh++;
+      }
+    }
+    Assert.assertEquals(2, countRefresh);
 
     // Slave components will have admin state as INSERVICE even if the state in DB is null
     scHost.setComponentAdminState(null);

+ 7 - 1
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/TaskResourceProviderTest.java

@@ -94,7 +94,8 @@ public class TaskResourceProviderTest {
     AmbariManagementController managementController = createMock(AmbariManagementController.class);
 
     Set<TaskStatusResponse> allResponse = new HashSet<TaskStatusResponse>();
-    allResponse.add(new TaskStatusResponse(100L, 100, 100L, "HostName100", "", "", "", 0, "", "", 0L, (short) 0));
+    allResponse.add(new TaskStatusResponse(100L, 100, 100L, "HostName100", "", "", "", 0, "", "", 0L, (short) 0,
+        "commandDetail", "customCommandName"));
 
     // set expectations
     expect(managementController.getTaskStatus(AbstractResourceProviderTest.Matcher.getTaskRequestSet(100L, 100L))).
@@ -113,6 +114,7 @@ public class TaskResourceProviderTest {
 
     propertyIds.add(TaskResourceProvider.TASK_ID_PROPERTY_ID);
     propertyIds.add(TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID);
+    propertyIds.add(TaskResourceProvider.TASK_COMMAND_DET_PROPERTY_ID);
 
     Predicate predicate = new PredicateBuilder().property(TaskResourceProvider.TASK_ID_PROPERTY_ID).equals("100").
                           and().property(TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID).equals("100").toPredicate();
@@ -123,6 +125,10 @@ public class TaskResourceProviderTest {
     for (Resource resource : resources) {
       long taskId = (Long) resource.getPropertyValue(TaskResourceProvider.TASK_ID_PROPERTY_ID);
       Assert.assertEquals(100L, taskId);
+      Assert.assertEquals(null, resource.getPropertyValue(TaskResourceProvider
+          .TASK_CUST_CMD_NAME_PROPERTY_ID));
+      Assert.assertEquals("commandDetail", resource.getPropertyValue(TaskResourceProvider
+          .TASK_COMMAND_DET_PROPERTY_ID));
     }
 
     // verify

+ 15 - 0
ambari-server/src/test/python/stacks/1.3.2/MAPREDUCE/test_mapreduce_jobtracker.py

@@ -83,6 +83,21 @@ class TestJobtracker(RMFTestCase):
     )
     self.assertNoMoreResources()
 
+  def test_decommission_default_no_refersh(self):
+
+    self.executeScript("1.3.2/services/MAPREDUCE/package/scripts/jobtracker.py",
+                       classname = "Jobtracker",
+                       command = "decommission",
+                       config_file="default.hbasedecom.json"
+    )
+
+    self.assertResourceCalled('File', '/etc/hadoop/conf/mapred.exclude',
+                              owner = 'mapred',
+                              content = Template('exclude_hosts_list.j2'),
+                              group = 'hadoop',
+                              )
+    self.assertNoMoreResources()
+
   def test_configure_secured(self):
 
     self.executeScript("1.3.2/services/MAPREDUCE/package/scripts/jobtracker.py",

+ 3 - 1
ambari-server/src/test/python/stacks/1.3.2/configs/default.hbasedecom.json

@@ -29,7 +29,9 @@
         "script_type": "PYTHON", 
         "schema_version": "2.0", 
         "script": "scripts/datanode.py",
-        "excluded_hosts": "host1,host2"
+        "excluded_hosts": "host1,host2",
+        "mark_draining_only" : "true",
+        "update_exclude_file_only" : "true"
     }, 
     "taskId": 18, 
     "public_hostname": "c6402.ambari.apache.org", 

+ 3 - 1
ambari-server/src/test/python/stacks/1.3.2/configs/default.json

@@ -29,7 +29,9 @@
         "script_type": "PYTHON", 
         "schema_version": "2.0", 
         "script": "scripts/datanode.py",
-        "excluded_hosts": "host1,host2"
+        "excluded_hosts": "host1,host2",
+        "mark_draining_only" : "false",
+        "update_exclude_file_only" : "false"
     }, 
     "taskId": 18, 
     "public_hostname": "c6402.ambari.apache.org", 

+ 4 - 2
ambari-server/src/test/python/stacks/1.3.2/configs/secured.json

@@ -29,8 +29,10 @@
         "script_type": "PYTHON", 
         "schema_version": "2.0", 
         "script": "scripts/mysql_server.py",
-        "excluded_hosts": "host1"
-    }, 
+        "excluded_hosts": "host1",
+        "mark_draining_only" : "false",
+        "update_exclude_file_only" : "false"
+    },
     "taskId": 117, 
     "public_hostname": "c6402.ambari.apache.org", 
     "configurations": {

+ 2 - 1
ambari-server/src/test/python/stacks/2.0.6/configs/default.json

@@ -25,7 +25,8 @@
         "script_type": "PYTHON", 
         "schema_version": "2.0", 
         "script": "scripts/service_check.py",
-        "excluded_hosts": "host1,host2"
+        "excluded_hosts": "host1,host2",
+        "mark_draining_only" : "false"
     },
     "taskId": 152, 
     "public_hostname": "c6401.ambari.apache.org", 

+ 3 - 2
ambari-server/src/test/python/stacks/2.0.6/configs/secured.json

@@ -30,8 +30,9 @@
         "script_type": "PYTHON", 
         "schema_version": "2.0", 
         "script": "scripts/yarn_client.py",
-        "excluded_hosts": "host1"
-    }, 
+        "excluded_hosts": "host1",
+        "mark_draining_only" : "false"
+    },
     "taskId": 186, 
     "public_hostname": "c6401.ambari.apache.org", 
     "configurations": {