You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by tb...@apache.org on 2014/12/23 13:55:07 UTC

[1/2] ambari git commit: AMBARI-8852 - RU: Cannot Retry on failure (tbeerbower)

Repository: ambari
Updated Branches:
  refs/heads/trunk 2ec55887c -> 85ff51496


http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/test/java/org/apache/ambari/server/stageplanner/TestStagePlanner.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stageplanner/TestStagePlanner.java b/ambari-server/src/test/java/org/apache/ambari/server/stageplanner/TestStagePlanner.java
index dd2a519..0a381f9 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/stageplanner/TestStagePlanner.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/stageplanner/TestStagePlanner.java
@@ -89,10 +89,10 @@ public class TestStagePlanner {
     Stage stage = StageUtils.getATestStage(1, 1, "host1", "", "");
     stage.addHostRoleExecutionCommand("host2", Role.HBASE_MASTER,
         RoleCommand.START, new ServiceComponentHostStartEvent("HBASE_MASTER",
-            "host2", now), "cluster1", "HBASE");
+            "host2", now), "cluster1", "HBASE", false);
     stage.addHostRoleExecutionCommand("host3", Role.ZOOKEEPER_SERVER,
         RoleCommand.START, new ServiceComponentHostStartEvent("ZOOKEEPER_SERVER",
-            "host3", now), "cluster1", "ZOOKEEPER");
+            "host3", now), "cluster1", "ZOOKEEPER", false);
     System.out.println(stage.toString());
 
     rg.build(stage);
@@ -115,37 +115,37 @@ public class TestStagePlanner {
     Stage stage = StageUtils.getATestStage(1, 1, "host1", "", "");
     stage.addHostRoleExecutionCommand("host11", Role.SECONDARY_NAMENODE,
         RoleCommand.START, new ServiceComponentHostStartEvent("SECONDARY_NAMENODE",
-            "host11", now), "cluster1", "HDFS");
+            "host11", now), "cluster1", "HDFS", false);
     stage.addHostRoleExecutionCommand("host2", Role.HBASE_MASTER,
         RoleCommand.START, new ServiceComponentHostStartEvent("HBASE_MASTER",
-            "host2", now), "cluster1", "HBASE");
+            "host2", now), "cluster1", "HBASE", false);
     stage.addHostRoleExecutionCommand("host3", Role.ZOOKEEPER_SERVER,
         RoleCommand.START, new ServiceComponentHostStartEvent("ZOOKEEPER_SERVER",
-            "host3", now), "cluster1", "ZOOKEEPER");
+            "host3", now), "cluster1", "ZOOKEEPER", false);
     stage.addHostRoleExecutionCommand("host4", Role.DATANODE,
         RoleCommand.START, new ServiceComponentHostStartEvent("DATANODE",
-            "host4", now), "cluster1", "HDFS");
+            "host4", now), "cluster1", "HDFS", false);
     stage.addHostRoleExecutionCommand("host4", Role.HBASE_REGIONSERVER,
         RoleCommand.START, new ServiceComponentHostStartEvent("HBASE_REGIONSERVER",
-            "host4", now), "cluster1", "HBASE");
+            "host4", now), "cluster1", "HBASE", false);
     stage.addHostRoleExecutionCommand("host4", Role.TASKTRACKER,
         RoleCommand.START, new ServiceComponentHostStartEvent("TASKTRACKER",
-            "host4", now), "cluster1", "MAPREDUCE");
+            "host4", now), "cluster1", "MAPREDUCE", false);
     stage.addHostRoleExecutionCommand("host5", Role.JOBTRACKER,
         RoleCommand.START, new ServiceComponentHostStartEvent("JOBTRACKER",
-            "host5", now), "cluster1", "MAPREDUCE");
+            "host5", now), "cluster1", "MAPREDUCE", false);
     stage.addHostRoleExecutionCommand("host6", Role.OOZIE_SERVER,
         RoleCommand.START, new ServiceComponentHostStartEvent("OOZIE_SERVER",
-            "host6", now), "cluster1", "OOZIE");
+            "host6", now), "cluster1", "OOZIE", false);
     stage.addHostRoleExecutionCommand("host7", Role.WEBHCAT_SERVER,
         RoleCommand.START, new ServiceComponentHostStartEvent("WEBHCAT_SERVER",
-            "host7", now), "cluster1", "WEBHCAT");
+            "host7", now), "cluster1", "WEBHCAT", false);
     stage.addHostRoleExecutionCommand("host4", Role.GANGLIA_MONITOR,
         RoleCommand.START, new ServiceComponentHostStartEvent("GANGLIA_MONITOR",
-            "host4", now), "cluster1", "GANGLIA");
+            "host4", now), "cluster1", "GANGLIA", false);
     stage.addHostRoleExecutionCommand("host9", Role.GANGLIA_SERVER,
         RoleCommand.START, new ServiceComponentHostStartEvent("GANGLIA_SERVER",
-            "host9", now), "cluster1", "GANGLIA");
+            "host9", now), "cluster1", "GANGLIA", false);
     System.out.println(stage.toString());
     rg.build(stage);
     System.out.println(rg.stringifyGraph());

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog200Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog200Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog200Test.java
index f8d061a..cd68dc1 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog200Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog200Test.java
@@ -118,6 +118,7 @@ public class UpgradeCatalog200Test {
     Capture<DBAccessor.DBColumnInfo> hostComponentStateSecurityStateColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
     Capture<DBAccessor.DBColumnInfo> hostComponentDesiredStateSecurityStateColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
     Capture<DBAccessor.DBColumnInfo> hostRoleCommandRetryColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
+    Capture<DBAccessor.DBColumnInfo> stageSkippableColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
 
     Capture<DBAccessor.DBColumnInfo> viewparameterLabelColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
     Capture<DBAccessor.DBColumnInfo> viewparameterPlaceholderColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
@@ -156,6 +157,10 @@ public class UpgradeCatalog200Test {
     dbAccessor.addColumn(eq("host_role_command"),
         capture(hostRoleCommandRetryColumnCapture));
 
+    // Stage skippable
+    dbAccessor.addColumn(eq("stage"),
+        capture(stageSkippableColumnCapture));
+
     // Host Component State: security State
     dbAccessor.addColumn(eq("hostcomponentstate"),
         capture(hostComponentStateSecurityStateColumnCapture));
@@ -230,6 +235,14 @@ public class UpgradeCatalog200Test {
     assertEquals(0, upgradeRetryColumn.getDefaultValue());
     assertFalse(upgradeRetryColumn.isNullable());
 
+    // Verify added column in host_role_command table
+    DBAccessor.DBColumnInfo upgradeSkippableColumn = stageSkippableColumnCapture.getValue();
+    assertEquals("skippable", upgradeSkippableColumn.getName());
+    assertEquals(1, (int) upgradeSkippableColumn.getLength());
+    assertEquals(Integer.class, upgradeSkippableColumn.getType());
+    assertEquals(0, upgradeSkippableColumn.getDefaultValue());
+    assertFalse(upgradeSkippableColumn.isNullable());
+
     // verify security_state columns
     verifyComponentSecurityStateColumn(hostComponentStateSecurityStateColumnCapture);
     verifyComponentSecurityStateColumn(hostComponentDesiredStateSecurityStateColumnCapture);


[2/2] ambari git commit: AMBARI-8852 - RU: Cannot Retry on failure (tbeerbower)

Posted by tb...@apache.org.
AMBARI-8852 - RU: Cannot Retry on failure (tbeerbower)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/85ff5149
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/85ff5149
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/85ff5149

Branch: refs/heads/trunk
Commit: 85ff51496d555bdac09198523a9860b20be31c35
Parents: 2ec5588
Author: tbeerbower <tb...@hortonworks.com>
Authored: Tue Dec 23 07:54:39 2014 -0500
Committer: tbeerbower <tb...@hortonworks.com>
Committed: Tue Dec 23 07:54:49 2014 -0500

----------------------------------------------------------------------
 .../server/actionmanager/ActionScheduler.java   | 82 +++++++++--------
 .../server/actionmanager/HostRoleCommand.java   | 19 +++-
 .../ambari/server/actionmanager/Stage.java      | 73 ++++++++++++---
 .../controller/AmbariActionExecutionHelper.java | 13 ++-
 .../AmbariCustomCommandExecutionHelper.java     | 97 +++++++++++---------
 .../AmbariManagementControllerImpl.java         |  8 +-
 .../server/controller/KerberosHelper.java       |  4 +-
 .../ClusterStackVersionResourceProvider.java    |  2 +-
 .../HostStackVersionResourceProvider.java       |  2 +-
 .../internal/RequestResourceProvider.java       |  5 +-
 .../internal/StageResourceProvider.java         | 16 +++-
 .../internal/UpgradeGroupResourceProvider.java  |  2 +-
 .../internal/UpgradeResourceProvider.java       | 28 ++++--
 .../ambari/server/orm/entities/StageEntity.java | 23 +++++
 .../server/upgrade/UpgradeCatalog200.java       |  3 +
 .../apache/ambari/server/utils/StageUtils.java  |  2 +-
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |  1 +
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql |  1 +
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |  1 +
 .../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql     |  1 +
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   |  2 +-
 .../ExecutionCommandWrapperTest.java            |  2 +-
 .../actionmanager/TestActionDBAccessorImpl.java | 18 ++--
 .../server/actionmanager/TestActionManager.java |  2 +-
 .../actionmanager/TestActionScheduler.java      | 16 ++--
 .../ambari/server/actionmanager/TestStage.java  |  4 +-
 .../server/agent/TestHeartbeatHandler.java      |  8 +-
 .../AmbariManagementControllerTest.java         | 10 +-
 .../internal/StageResourceProviderTest.java     | 44 +++++++++
 .../serveraction/ServerActionExecutorTest.java  |  4 +-
 .../server/stageplanner/TestStagePlanner.java   | 26 +++---
 .../server/upgrade/UpgradeCatalog200Test.java   | 13 +++
 32 files changed, 356 insertions(+), 176 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java
index ccecad9..6511369 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java
@@ -232,11 +232,11 @@ class ActionScheduler implements Runnable {
       boolean exclusiveRequestIsGoing = false;
       // This loop greatly depends on the fact that order of stages in
       // a list does not change between invocations
-      for (Stage s : stages) {
+      for (Stage stage : stages) {
         // Check if we can process this stage in parallel with another stages
         i_stage ++;
-        long requestId = s.getRequestId();
-        LOG.debug("==> STAGE_i = " + i_stage + "(requestId=" + requestId + ",StageId=" + s.getStageId() + ")");
+        long requestId = stage.getRequestId();
+        LOG.debug("==> STAGE_i = " + i_stage + "(requestId=" + requestId + ",StageId=" + stage.getStageId() + ")");
         Request request = db.getRequest(requestId);
 
         if (request.isExclusive()) {
@@ -262,7 +262,7 @@ class ActionScheduler implements Runnable {
 
         // Commands that will be scheduled in current scheduler wakeup
         List<ExecutionCommand> commandsToSchedule = new ArrayList<ExecutionCommand>();
-        Map<String, RoleStats> roleStats = processInProgressStage(s, commandsToSchedule);
+        Map<String, RoleStats> roleStats = processInProgressStage(stage, commandsToSchedule);
         // Check if stage is failed
         boolean failed = false;
         for (Map.Entry<String, RoleStats>entry : roleStats.entrySet()) {
@@ -281,14 +281,14 @@ class ActionScheduler implements Runnable {
 
         if(!failed) {
           // Prior stage may have failed and it may need to fail the whole request
-          failed = hasPreviousStageFailed(s);
+          failed = hasPreviousStageFailed(stage);
         }
 
         if (failed) {
           LOG.warn("Operation completely failed, aborting request id:"
-              + s.getRequestId());
-          cancelHostRoleCommands(s.getOrderedHostRoleCommands(), FAILED_TASK_ABORT_REASONING);
-          abortOperationsForStage(s);
+              + stage.getRequestId());
+          cancelHostRoleCommands(stage.getOrderedHostRoleCommands(), FAILED_TASK_ABORT_REASONING);
+          abortOperationsForStage(stage);
           return;
         }
 
@@ -298,18 +298,18 @@ class ActionScheduler implements Runnable {
         //Schedule what we have so far
 
         for (ExecutionCommand cmd : commandsToSchedule) {
-            processHostRole(s, cmd, commandsToStart, commandsToUpdate);
+            processHostRole(stage, cmd, commandsToStart, commandsToUpdate);
         }
 
         LOG.debug("==> Commands to start: {}", commandsToStart.size());
         LOG.debug("==> Commands to update: {}", commandsToUpdate.size());
 
         //Multimap is analog of Map<Object, List<Object>> but allows to avoid nested loop
-        ListMultimap<String, ServiceComponentHostEvent> eventMap = formEventMap(s, commandsToStart);
+        ListMultimap<String, ServiceComponentHostEvent> eventMap = formEventMap(stage, commandsToStart);
         List<ExecutionCommand> commandsToAbort = new ArrayList<ExecutionCommand>();
         if (!eventMap.isEmpty()) {
           LOG.debug("==> processing {} serviceComponentHostEvents...", eventMap.size());
-          Cluster cluster = fsmObject.getCluster(s.getClusterName());
+          Cluster cluster = fsmObject.getCluster(stage.getClusterName());
           if (cluster != null) {
             List<ServiceComponentHostEvent> failedEvents =
               cluster.processServiceComponentHostEvents(eventMap);
@@ -327,12 +327,12 @@ class ActionScheduler implements Runnable {
               }
             }
           } else {
-            LOG.warn("There was events to process but cluster {} not found", s.getClusterName());
+            LOG.warn("There was events to process but cluster {} not found", stage.getClusterName());
           }
         }
 
         LOG.debug("==> Scheduling {} tasks...", commandsToUpdate.size());
-        db.bulkHostRoleScheduled(s, commandsToUpdate);
+        db.bulkHostRoleScheduled(stage, commandsToUpdate);
 
         if (commandsToAbort.size() > 0) { // Code branch may be a bit slow, but is extremely rarely used
           LOG.debug("==> Aborting {} tasks...", commandsToAbort.size());
@@ -344,7 +344,7 @@ class ActionScheduler implements Runnable {
           Collection<HostRoleCommand> hostRoleCommands = db.getTasks(taskIds);
 
           cancelHostRoleCommands(hostRoleCommands, FAILED_TASK_ABORT_REASONING);
-          db.bulkAbortHostRole(s, commandsToAbort);
+          db.bulkAbortHostRole(stage, commandsToAbort);
         }
 
         LOG.debug("==> Adding {} tasks to queue...", commandsToUpdate.size());
@@ -412,7 +412,9 @@ class ActionScheduler implements Runnable {
 
   private boolean hasPreviousStageFailed(Stage stage) {
     boolean failed = false;
+
     long prevStageId = stage.getStageId() - 1;
+
     if (prevStageId > 0) {
       // Find previous stage instance
       List<Stage> allStages = db.getAllStages(stage.getRequestId());
@@ -424,34 +426,36 @@ class ActionScheduler implements Runnable {
         }
       }
 
-      //It may be null for test scenarios
-      if(prevStage != null) {
-        Map<Role, Integer> hostCountsForRoles = new HashMap<Role, Integer>();
-        Map<Role, Integer> failedHostCountsForRoles = new HashMap<Role, Integer>();
-
-        for (String host : prevStage.getHostRoleCommands().keySet()) {
-          Map<String, HostRoleCommand> roleCommandMap = prevStage.getHostRoleCommands().get(host);
-          for (String role : roleCommandMap.keySet()) {
-            HostRoleCommand c = roleCommandMap.get(role);
-            if (hostCountsForRoles.get(c.getRole()) == null) {
-              hostCountsForRoles.put(c.getRole(), 0);
-              failedHostCountsForRoles.put(c.getRole(), 0);
-            }
-            int hostCount = hostCountsForRoles.get(c.getRole());
-            hostCountsForRoles.put(c.getRole(), hostCount + 1);
-            if (c.getStatus().isFailedState()) {
-              int failedHostCount = failedHostCountsForRoles.get(c.getRole());
-              failedHostCountsForRoles.put(c.getRole(), failedHostCount + 1);
-            }
+      // If the previous stage is skippable then we shouldn't automatically fail the given stage
+      if (prevStage == null || prevStage.isSkippable()) {
+        return false;
+      }
+
+      Map<Role, Integer> hostCountsForRoles       = new HashMap<Role, Integer>();
+      Map<Role, Integer> failedHostCountsForRoles = new HashMap<Role, Integer>();
+
+      for (String host : prevStage.getHostRoleCommands().keySet()) {
+        Map<String, HostRoleCommand> roleCommandMap = prevStage.getHostRoleCommands().get(host);
+        for (String role : roleCommandMap.keySet()) {
+          HostRoleCommand c = roleCommandMap.get(role);
+          if (hostCountsForRoles.get(c.getRole()) == null) {
+            hostCountsForRoles.put(c.getRole(), 0);
+            failedHostCountsForRoles.put(c.getRole(), 0);
+          }
+          int hostCount = hostCountsForRoles.get(c.getRole());
+          hostCountsForRoles.put(c.getRole(), hostCount + 1);
+          if (c.getStatus().isFailedState()) {
+            int failedHostCount = failedHostCountsForRoles.get(c.getRole());
+            failedHostCountsForRoles.put(c.getRole(), failedHostCount + 1);
           }
         }
+      }
 
-        for (Role role : hostCountsForRoles.keySet()) {
-          float failedHosts = failedHostCountsForRoles.get(role);
-          float totalHosts = hostCountsForRoles.get(role);
-          if (((totalHosts - failedHosts) / totalHosts) < prevStage.getSuccessFactor(role)) {
-            failed = true;
-          }
+      for (Role role : hostCountsForRoles.keySet()) {
+        float failedHosts = failedHostCountsForRoles.get(role);
+        float totalHosts = hostCountsForRoles.get(role);
+        if (((totalHosts - failedHosts) / totalHosts) < prevStage.getSuccessFactor(role)) {
+          failed = true;
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java
index f71e2d5..59fce90 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java
@@ -26,8 +26,6 @@ import org.apache.ambari.server.orm.dao.ExecutionCommandDAO;
 import org.apache.ambari.server.orm.entities.ExecutionCommandEntity;
 import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
 import org.apache.ambari.server.state.ServiceComponentHostEvent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * This class encapsulates the information for an task on a host for a
@@ -36,7 +34,6 @@ import org.slf4j.LoggerFactory;
  * track the request.
  */
 public class HostRoleCommand {
-  private static final Logger log = LoggerFactory.getLogger(HostRoleCommand.class);
   private final Role role;
   private final ServiceComponentHostEventWrapper event;
   private long taskId = -1;
@@ -54,6 +51,7 @@ public class HostRoleCommand {
   private long endTime = -1;
   private long lastAttemptTime = -1;
   private short attemptCount = 0;
+  private final boolean retryAllowed;
   private RoleCommand roleCommand;
   private String commandDetail;
   private String customCommandName;
@@ -62,10 +60,16 @@ public class HostRoleCommand {
 
   public HostRoleCommand(String host, Role role,
                          ServiceComponentHostEvent event, RoleCommand command) {
+    this(host, role, event, command, false);
+  }
+
+  public HostRoleCommand(String host, Role role,
+                         ServiceComponentHostEvent event, RoleCommand command, boolean retryAllowed) {
     this.hostName = host;
     this.role = role;
     this.event = new ServiceComponentHostEventWrapper(event);
     this.roleCommand = command;
+    this.retryAllowed = retryAllowed;
   }
 
   @AssistedInject
@@ -86,6 +90,7 @@ public class HostRoleCommand {
     endTime = hostRoleCommandEntity.getEndTime() != null ? hostRoleCommandEntity.getEndTime() : -1L;
     lastAttemptTime = hostRoleCommandEntity.getLastAttemptTime();
     attemptCount = hostRoleCommandEntity.getAttemptCount();
+    retryAllowed = hostRoleCommandEntity.isRetryAllowed();
     roleCommand = hostRoleCommandEntity.getRoleCommand();
     event = new ServiceComponentHostEventWrapper(hostRoleCommandEntity.getEvent());
     commandDetail = hostRoleCommandEntity.getCommandDetail();
@@ -108,6 +113,7 @@ public class HostRoleCommand {
     hostRoleCommandEntity.setEndTime(endTime);
     hostRoleCommandEntity.setLastAttemptTime(lastAttemptTime);
     hostRoleCommandEntity.setAttemptCount(attemptCount);
+    hostRoleCommandEntity.setRetryAllowed(retryAllowed);
     hostRoleCommandEntity.setRoleCommand(roleCommand);
     hostRoleCommandEntity.setCommandDetail(commandDetail);
     hostRoleCommandEntity.setCustomCommandName(customCommandName);
@@ -233,6 +239,10 @@ public class HostRoleCommand {
     this.attemptCount++;
   }
 
+  public boolean isRetryAllowed() {
+    return retryAllowed;
+  }
+
   public String getStructuredOut() {
     return structuredOut;
   }
@@ -285,8 +295,7 @@ public class HostRoleCommand {
 
   @Override
   public int hashCode() {
-    return (hostName.toString() + role.toString() + roleCommand.toString())
-        .hashCode();
+    return (hostName + role.toString() + roleCommand.toString()).hashCode();
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
index 57fadf7..f0e4e9c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
@@ -65,6 +65,8 @@ public class Stage {
   private String commandParamsStage;
   private String hostParamsStage;
 
+  private boolean skippable;
+
   private int stageTimeout = -1;
 
   private volatile boolean wrappersLoaded = false;
@@ -96,6 +98,7 @@ public class Stage {
     this.clusterHostInfo = clusterHostInfo;
     this.commandParamsStage = commandParamsStage;
     this.hostParamsStage = hostParamsStage;
+    this.skippable = false;
   }
 
   @AssistedInject
@@ -104,6 +107,7 @@ public class Stage {
 
     requestId = stageEntity.getRequestId();
     stageId = stageEntity.getStageId();
+    skippable = stageEntity.isSkippable();
     logDir = stageEntity.getLogInfo();
 
     long clusterId = stageEntity.getClusterId().longValue();
@@ -150,6 +154,7 @@ public class Stage {
     stageEntity.setRequestId(requestId);
     stageEntity.setStageId(getStageId());
     stageEntity.setLogInfo(logDir);
+    stageEntity.setSkippable(skippable);
     stageEntity.setRequestContext(requestContext);
     stageEntity.setHostRoleCommands(new ArrayList<HostRoleCommandEntity>());
     stageEntity.setRoleSuccessCriterias(new ArrayList<RoleSuccessCriteriaEntity>());
@@ -247,9 +252,12 @@ public class Stage {
     return StageUtils.getActionId(requestId, getStageId());
   }
 
-  private synchronized ExecutionCommandWrapper addGenericExecutionCommand(String clusterName, String hostName, Role role, RoleCommand command, ServiceComponentHostEvent event){
+  private synchronized ExecutionCommandWrapper addGenericExecutionCommand(
+      String clusterName, String hostName, Role role,
+      RoleCommand command, ServiceComponentHostEvent event, boolean retryAllowed){
+
     //used on stage creation only, no need to check if wrappers loaded
-    HostRoleCommand hrc = new HostRoleCommand(hostName, role, event, command);
+    HostRoleCommand hrc = new HostRoleCommand(hostName, role, event, command, retryAllowed);
     ExecutionCommand cmd = new ExecutionCommand();
     ExecutionCommandWrapper wrapper = new ExecutionCommandWrapper(cmd);
     hrc.setExecutionCommandWrapper(wrapper);
@@ -287,20 +295,23 @@ public class Stage {
     execCmdList.add(wrapper);
     return wrapper;
   }
+
   /**
    * A new host role command is created for execution.
    * Creates both ExecutionCommand and HostRoleCommand objects and
    * adds them to the Stage. This should be called only once for a host-role
    * for a given stage.
    */
-  public synchronized void addHostRoleExecutionCommand(String host, Role role,  RoleCommand command,
-      ServiceComponentHostEvent event, String clusterName, String serviceName) {
-    ExecutionCommandWrapper commandWrapper = addGenericExecutionCommand(clusterName, host, role, command, event);
+  public synchronized void addHostRoleExecutionCommand(String host, Role role, RoleCommand command,
+                                                       ServiceComponentHostEvent event, String clusterName,
+                                                       String serviceName, boolean retryAllowed) {
+
+    ExecutionCommandWrapper commandWrapper =
+        addGenericExecutionCommand(clusterName, host, role, command, event, retryAllowed);
 
     commandWrapper.getExecutionCommand().setServiceName(serviceName);
   }
 
-
   /**
    * Creates server-side execution command.
    * <p/>
@@ -318,15 +329,17 @@ public class Stage {
    * @param commandDetail a String declaring a descriptive name to pass to the action - null or an
    *                      empty string indicates no value is to be set
    * @param timeout       an Integer declaring the timeout for this action - if null, a default
+   * @param retryAllowed   indicates whether retry after failure is allowed
    */
   public synchronized void addServerActionCommand(String actionName, Role role, RoleCommand command,
                                                   String clusterName, ServiceComponentHostServerActionEvent event,
                                                   @Nullable Map<String, String> commandParams,
                                                   @Nullable String commandDetail,
-                                                  @Nullable Integer timeout) {
+                                                  @Nullable Integer timeout,
+                                                  boolean retryAllowed) {
 
     addServerActionCommand(actionName, role, command,
-        clusterName, StageUtils.getHostName(), event, commandParams, commandDetail, timeout);
+        clusterName, StageUtils.getHostName(), event, commandParams, commandDetail, timeout, retryAllowed);
   }
 
   /**
@@ -351,14 +364,17 @@ public class Stage {
    * @param commandDetail a String declaring a descriptive name to pass to the action - null or an
    *                      empty string indicates no value is to be set
    * @param timeout       an Integer declaring the timeout for this action - if null, a default
+   * @param retryAllowed   indicates whether retry after failure is allowed
    */
   public synchronized void addServerActionCommand(String actionName, Role role, RoleCommand command,
                                                   String clusterName, String hostName,
                                                   ServiceComponentHostServerActionEvent event,
                                                   @Nullable Map<String, String> commandParams,
                                                   @Nullable String commandDetail,
-                                                  @Nullable Integer timeout) {
-    ExecutionCommandWrapper commandWrapper = addGenericExecutionCommand(clusterName, hostName, role, command, event);
+                                                  @Nullable Integer timeout, boolean retryAllowed) {
+    ExecutionCommandWrapper commandWrapper =
+        addGenericExecutionCommand(clusterName, hostName, role, command, event, retryAllowed);
+
     ExecutionCommand cmd = commandWrapper.getExecutionCommand();
 
     Map<String, String> cmdParams = new HashMap<String, String>();
@@ -384,10 +400,12 @@ public class Stage {
   }
 
   /**
-   *  Adds cancel command to stage for given cancelTargets collection of task id's that has to be canceled in Agent layer.
+   *  Adds cancel command to stage for given cancelTargets collection of
+   *  task id's that has to be canceled in Agent layer.
    */
   public synchronized void addCancelRequestCommand(List<Long> cancelTargets, String clusterName, String hostName) {
-    ExecutionCommandWrapper commandWrapper = addGenericExecutionCommand(clusterName, hostName, Role.AMBARI_SERVER_ACTION, RoleCommand.ABORT, null);
+    ExecutionCommandWrapper commandWrapper = addGenericExecutionCommand(clusterName, hostName,
+        Role.AMBARI_SERVER_ACTION, RoleCommand.ABORT, null, false);
     ExecutionCommand cmd = commandWrapper.getExecutionCommand();
     cmd.setCommandType(AgentCommandType.CANCEL_COMMAND);
 
@@ -569,8 +587,7 @@ public class Stage {
   /**
    * This method should be used only in stage planner. To add
    * a new execution command use
-   * {@link #addHostRoleExecutionCommand(String, Role, RoleCommand,
-   * ServiceComponentHostEvent, String, String)}
+   * {@link #addHostRoleExecutionCommand(String, org.apache.ambari.server.Role, org.apache.ambari.server.RoleCommand, org.apache.ambari.server.state.ServiceComponentHostEvent, String, String, boolean)}
    */
   public synchronized void addExecutionCommandWrapper(Stage origStage,
       String hostname, Role r) {
@@ -623,6 +640,34 @@ public class Stage {
     return stageTimeout;
   }
 
+  /**
+   * Determine whether or not this stage is skippable.
+   *
+   * A skippable stage can be skipped on failure so that the
+   * remaining stages of the request can execute.
+   * If a stage is not skippable, a failure will cause the
+   * remaining stages of the request to be aborted.
+   *
+   * @return true if this stage is skippable
+   */
+  public boolean isSkippable() {
+    return skippable;
+  }
+
+  /**
+   * Set skippable for this stage.
+   *
+   * A skippable stage can be skipped on failure so that the
+   * remaining stages of the request can execute.
+   * If a stage is not skippable, a failure will cause the
+   * remaining stages of the request to be aborted.
+   *
+   * @param skippable  true if this stage should be skippable
+   */
+  public void setSkippable(boolean skippable) {
+    this.skippable = skippable;
+  }
+
   @Override //Object
   public synchronized String toString() {
     StringBuilder builder = new StringBuilder();

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
index 17d5782..ad86bb1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
@@ -202,12 +202,15 @@ public class AmbariActionExecutionHelper {
 
   /**
    * Add tasks to the stage based on the requested action execution
-   * @param actionContext the context associated with the action
-   * @param stage stage into which tasks must be inserted
-   * @throws AmbariException
+   *
+   * @param actionContext  the context associated with the action
+   * @param stage          stage into which tasks must be inserted
+   * @param retryAllowed   indicates whether retry is allowed on failure
+   *
+   * @throws AmbariException if the task can not be added
    */
   public void addExecutionCommandsToStage(
-          final ActionExecutionContext actionContext, Stage stage)
+      final ActionExecutionContext actionContext, Stage stage, boolean retryAllowed)
       throws AmbariException {
 
     String actionName = actionContext.getActionName();
@@ -331,7 +334,7 @@ public class AmbariActionExecutionHelper {
         Role.valueOf(actionContext.getActionName()), RoleCommand.ACTIONEXECUTE,
           new ServiceComponentHostOpInProgressEvent(actionContext.getActionName(),
             hostName, System.currentTimeMillis()), clusterName,
-              serviceName);
+              serviceName, retryAllowed);
 
       Map<String, Map<String, String>> configurations = new TreeMap<String, Map<String, String>>();
       Map<String, Map<String, Map<String, String>>> configurationAttributes = new TreeMap<String, Map<String, Map<String, String>>>();

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/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 c8ae61d..b8f3cd7 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
@@ -112,12 +112,14 @@ public class AmbariCustomCommandExecutionHelper {
     masterToSlaveMappingForDecom.put("JOBTRACKER", "TASKTRACKER");
   }
 
-  public static String DECOM_INCLUDED_HOSTS = "included_hosts";
-  public static String DECOM_EXCLUDED_HOSTS = "excluded_hosts";
-  public static String DECOM_SLAVE_COMPONENT = "slave_type";
-  public static String HBASE_MARK_DRAINING_ONLY = "mark_draining_only";
-  public static String UPDATE_EXCLUDE_FILE_ONLY = "update_exclude_file_only";
-  private static String ALIGN_MAINTENANCE_STATE = "align_maintenance_state";
+  public final static String DECOM_INCLUDED_HOSTS = "included_hosts";
+  public final static String DECOM_EXCLUDED_HOSTS = "excluded_hosts";
+  public final static String DECOM_SLAVE_COMPONENT = "slave_type";
+  public final static String HBASE_MARK_DRAINING_ONLY = "mark_draining_only";
+  public final static String UPDATE_EXCLUDE_FILE_ONLY = "update_exclude_file_only";
+
+  private final static String ALIGN_MAINTENANCE_STATE = "align_maintenance_state";
+
   @Inject
   private ActionMetadata actionMetadata;
   @Inject
@@ -143,15 +145,8 @@ public class AmbariCustomCommandExecutionHelper {
 
   private Boolean isServiceCheckCommand(String command, String service) {
     List<String> actions = actionMetadata.getActions(service);
-    if (actions == null || actions.size() == 0) {
-      return false;
-    }
 
-    if (!actions.contains(command)) {
-      return false;
-    }
-
-    return true;
+    return !(actions == null || actions.size() == 0) && actions.contains(command);
   }
 
   private Boolean isValidCustomCommand(String clusterName,
@@ -224,7 +219,8 @@ public class AmbariCustomCommandExecutionHelper {
                                       final RequestResourceFilter resourceFilter,
                                       Stage stage,
                                       Map<String, String> additionalCommandParams,
-                                      String commandDetail)
+                                      String commandDetail,
+                                      boolean retryAllowed)
                                       throws AmbariException {
     final String serviceName = resourceFilter.getServiceName();
     final String componentName = resourceFilter.getComponentName();
@@ -287,7 +283,7 @@ public class AmbariCustomCommandExecutionHelper {
       stage.addHostRoleExecutionCommand(hostName, Role.valueOf(componentName),
           RoleCommand.CUSTOM_COMMAND,
           new ServiceComponentHostOpInProgressEvent(componentName,
-              hostName, nowTimestamp), cluster.getClusterName(), serviceName);
+              hostName, nowTimestamp), cluster.getClusterName(), serviceName, retryAllowed);
 
       Map<String, Map<String, String>> configurations =
           new TreeMap<String, Map<String, String>>();
@@ -387,10 +383,11 @@ public class AmbariCustomCommandExecutionHelper {
   }
 
   /**
-   * splits the passed commaseparated value and returns it as set
-   * @param commaSeparatedTags separated list
+   * Splits the passed comma separated value and returns it as set.
+   *
+   * @param commaSeparatedTags  separated list
+   *
    * @return set of items or null
-   * @throws AmbariException
    */
   private Set<String> parseAndValidateComponentsMapping(String commaSeparatedTags) {
     Set<String> retVal = null;
@@ -401,9 +398,10 @@ public class AmbariCustomCommandExecutionHelper {
   }
 
   private void findHostAndAddServiceCheckAction(
-          final ActionExecutionContext actionExecutionContext,
-          final RequestResourceFilter resourceFilter,
-          Stage stage)
+      final ActionExecutionContext actionExecutionContext,
+      final RequestResourceFilter resourceFilter,
+      Stage stage,
+      boolean retryAllowed)
           throws AmbariException {
 
     String clusterName = actionExecutionContext.getClusterName();
@@ -472,7 +470,7 @@ public class AmbariCustomCommandExecutionHelper {
     }
 
     addServiceCheckAction(stage, hostName, smokeTestRole, nowTimestamp,
-        serviceName, componentName, actionParameters);
+        serviceName, componentName, actionParameters, retryAllowed);
   }
 
   /**
@@ -485,7 +483,8 @@ public class AmbariCustomCommandExecutionHelper {
                                     long nowTimestamp,
                                     String serviceName,
                                     String componentName,
-                                    Map<String, String> actionParameters)
+                                    Map<String, String> actionParameters,
+                                    boolean retryAllowed)
                                     throws AmbariException {
 
     String clusterName = stage.getClusterName();
@@ -503,7 +502,7 @@ public class AmbariCustomCommandExecutionHelper {
         Role.valueOf(smokeTestRole),
         RoleCommand.SERVICE_CHECK,
         new ServiceComponentHostOpInProgressEvent(componentName, hostname,
-            nowTimestamp), cluster.getClusterName(), serviceName);
+            nowTimestamp), cluster.getClusterName(), serviceName, retryAllowed);
 
     HostRoleCommand hrc = stage.getHostRoleCommand(hostname, smokeTestRole);
     if (hrc != null) {
@@ -583,7 +582,8 @@ public class AmbariCustomCommandExecutionHelper {
    */
   private void addDecommissionAction(final ActionExecutionContext actionExecutionContext,
                                      final RequestResourceFilter resourceFilter,
-                                     Stage stage)
+                                     Stage stage,
+                                     boolean retryAllowed)
                                      throws AmbariException {
 
     String clusterName = actionExecutionContext.getClusterName();
@@ -794,7 +794,7 @@ public class AmbariCustomCommandExecutionHelper {
       if (!serviceName.equals(Service.Type.HBASE.name()) || hostName.equals(primaryCandidate)) {
         commandParams.put(UPDATE_EXCLUDE_FILE_ONLY, "false");
         addCustomCommandAction(commandContext, commandFilter, stage,
-          commandParams, commandDetail.toString());
+          commandParams, commandDetail.toString(), retryAllowed);
       }
     }
   }
@@ -816,8 +816,10 @@ public class AmbariCustomCommandExecutionHelper {
 
   /**
    * Validate custom command and throw exception is invalid request.
-   * @param actionRequest
-   * @throws AmbariException
+   *
+   * @param actionRequest  the action request
+   *
+   * @throws AmbariException if the action can not be validated
    */
   public void validateAction(ExecuteActionRequest actionRequest) throws AmbariException {
 
@@ -851,13 +853,17 @@ public class AmbariCustomCommandExecutionHelper {
 
   /**
    * Other than Service_Check and Decommission all other commands are pass-through
-   * @param actionExecutionContext received request to execute a command
-   * @param stage the initial stage for task creation
-   * @throws AmbariException
+   *
+   * @param actionExecutionContext  received request to execute a command
+   * @param stage                   the initial stage for task creation
+   * @param retryAllowed            indicates whether the the command allows retry
+   *
+   * @throws AmbariException if the commands can not be added
    */
   public void addExecutionCommandsToStage(ActionExecutionContext actionExecutionContext,
                                           Stage stage,
-                                          Map<String, String> requestParams)
+                                          Map<String, String> requestParams,
+                                          boolean retryAllowed)
                                           throws AmbariException {
 
     List<RequestResourceFilter> resourceFilters = actionExecutionContext.getResourceFilters();
@@ -870,9 +876,9 @@ public class AmbariCustomCommandExecutionHelper {
 
       if (actionExecutionContext.getActionName().contains(SERVICE_CHECK_COMMAND_NAME)) {
         findHostAndAddServiceCheckAction(actionExecutionContext,
-          resourceFilter, stage);
+          resourceFilter, stage, retryAllowed);
       } else if (actionExecutionContext.getActionName().equals(DECOMMISSION_COMMAND_NAME)) {
-        addDecommissionAction(actionExecutionContext, resourceFilter, stage);
+        addDecommissionAction(actionExecutionContext, resourceFilter, stage, retryAllowed);
       } else if (isValidCustomCommand(actionExecutionContext, resourceFilter)) {
         String commandDetail = getReadableCustomCommandDetail(actionExecutionContext, resourceFilter);
 
@@ -889,7 +895,7 @@ public class AmbariCustomCommandExecutionHelper {
           actionExecutionContext.getParameters().put(KeyNames.REFRESH_ADITIONAL_COMPONENT_TAGS, requestParams.get(KeyNames.REFRESH_ADITIONAL_COMPONENT_TAGS));
         }
         addCustomCommandAction(actionExecutionContext, resourceFilter, stage,
-          extraParams, commandDetail);
+          extraParams, commandDetail, retryAllowed);
       } else {
         throw new AmbariException("Unsupported action " +
           actionExecutionContext.getActionName());
@@ -899,10 +905,13 @@ public class AmbariCustomCommandExecutionHelper {
 
   /**
    * Get repository info given a cluster and host.
-   * @param cluster
-   * @param host
+   *
+   * @param cluster  the cluster
+   * @param host     the host
+   *
    * @return the repo info
-   * @throws AmbariException
+   *
+   * @throws AmbariException if the repository information can not be obtained
    */
   public String getRepoInfo(Cluster cluster, Host host) throws AmbariException {
     StackId stackId = cluster.getDesiredStackVersion();
@@ -933,10 +942,12 @@ public class AmbariCustomCommandExecutionHelper {
 
 
   /**
-   * Helper method to fill execution command information
-   * @param actionExecutionContext the context
-   * @param cluster the cluster for the command
-   * @return a wrapper of the imporant JSON structures to add to a stage.
+   * Helper method to fill execution command information.
+   *
+   * @param actionExecContext  the context
+   * @param cluster            the cluster for the command
+   *
+   * @return a wrapper of the imporant JSON structures to add to a stage
    */
   public ExecuteCommandJson getCommandJson(ActionExecutionContext actionExecContext,
       Cluster cluster) throws AmbariException {

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/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 19ee6d9..7ac9d95 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
@@ -1593,7 +1593,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     stage.addHostRoleExecutionCommand(scHost.getHostName(), Role.valueOf(scHost
       .getServiceComponentName()), roleCommand,
       event, scHost.getClusterName(),
-      scHost.getServiceName());
+      scHost.getServiceName(), false);
     String serviceName = scHost.getServiceName();
     String componentName = event.getServiceComponentName();
     String hostname = scHost.getHostName();
@@ -2073,7 +2073,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
 
         customCommandExecutionHelper.addServiceCheckAction(stage, clientHost,
           smokeTestRole, nowTimestamp, serviceName,
-          componentName, null);
+          componentName, null, false);
       }
 
       RoleCommandOrder rco = getRoleCommandOrder(cluster);
@@ -2846,9 +2846,9 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
         jsons.getHostParamsForStage());
 
     if (actionRequest.isCommand()) {
-      customCommandExecutionHelper.addExecutionCommandsToStage(actionExecContext, stage, requestProperties);
+      customCommandExecutionHelper.addExecutionCommandsToStage(actionExecContext, stage, requestProperties, false);
     } else {
-      actionExecutionHelper.addExecutionCommandsToStage(actionExecContext, stage);
+      actionExecutionHelper.addExecutionCommandsToStage(actionExecContext, stage, false);
     }
 
     RoleGraph rg;

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
index 562ce9e..c7d08cc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
@@ -763,7 +763,7 @@ public class KerberosHelper {
         event,
         commandParameters,
         commandDetail,
-        timeout);
+        timeout, false);
 
     return stage;
   }
@@ -1049,7 +1049,7 @@ public class KerberosHelper {
             "SET_KEYTAB",
             requestResourceFilters,
             requestParams);
-        customCommandExecutionHelper.addExecutionCommandsToStage(actionExecContext, stage, requestParams);
+        customCommandExecutionHelper.addExecutionCommandsToStage(actionExecContext, stage, requestParams, false);
       }
 
       roleGraph = new RoleGraph(roleCommandOrder);

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
index 9329ea9..4f5e03d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
@@ -363,7 +363,7 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
       actionContext.setTimeout(Short.valueOf(configuration.getDefaultAgentTaskTimeout()));
 
       try {
-        actionExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage);
+        actionExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage, false);
       } catch (AmbariException e) {
         throw new SystemException("Can not modify stage", e);
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
index 3b1b462..cf71fac 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
@@ -412,7 +412,7 @@ public class HostStackVersionResourceProvider extends AbstractControllerResource
     req.addStages(Collections.singletonList(stage));
 
     try {
-      actionExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage);
+      actionExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage, false);
     } catch (AmbariException e) {
       throw new SystemException("Can not modify stage", e);
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
index 3c4524a..c0fdd1d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
@@ -222,7 +222,7 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider
       List<HostRoleCommand> commands = internalRequest.getCommands();
       HostRoleStatus internalRequestStatus =
           StageResourceProvider.calculateSummaryStatus(
-              StageResourceProvider.calculateTaskStatusCounts(getHostRoleStatuses(commands)), commands.size());
+              StageResourceProvider.calculateTaskStatusCounts(getHostRoleStatuses(commands)), commands.size(), true);
 
       if (updateRequest.getStatus() != HostRoleStatus.ABORTED) {
         throw new IllegalArgumentException(
@@ -471,7 +471,8 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider
     Map<HostRoleStatus, Integer> hostRoleStatusCounters =
         StageResourceProvider.calculateTaskStatusCounts(getHostRoleStatuses(commands));
 
-    HostRoleStatus requestStatus   = StageResourceProvider.calculateSummaryStatus(hostRoleStatusCounters, taskCount);
+    HostRoleStatus requestStatus =
+        StageResourceProvider.calculateSummaryStatus(hostRoleStatusCounters, taskCount, true);
 
     double progressPercent = StageResourceProvider.calculateProgressPercent(hostRoleStatusCounters, taskCount);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StageResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StageResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StageResourceProvider.java
index c174a9c..8247153 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StageResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StageResourceProvider.java
@@ -89,6 +89,7 @@ public class StageResourceProvider extends AbstractResourceProvider implements E
   public static final String STAGE_CLUSTER_HOST_INFO = "Stage/cluster_host_info";
   public static final String STAGE_COMMAND_PARAMS = "Stage/command_params";
   public static final String STAGE_HOST_PARAMS = "Stage/host_params";
+  public static final String STAGE_SKIPPABLE = "Stage/skippable";
   public static final String STAGE_PROGRESS_PERCENT = "Stage/progress_percent";
   public static final String STAGE_STATUS = "Stage/status";
   public static final String STAGE_START_TIME = "Stage/start_time";
@@ -115,6 +116,7 @@ public class StageResourceProvider extends AbstractResourceProvider implements E
     PROPERTY_IDS.add(STAGE_CLUSTER_HOST_INFO);
     PROPERTY_IDS.add(STAGE_COMMAND_PARAMS);
     PROPERTY_IDS.add(STAGE_HOST_PARAMS);
+    PROPERTY_IDS.add(STAGE_SKIPPABLE);
     PROPERTY_IDS.add(STAGE_PROGRESS_PERCENT);
     PROPERTY_IDS.add(STAGE_STATUS);
     PROPERTY_IDS.add(STAGE_START_TIME);
@@ -265,7 +267,7 @@ public class StageResourceProvider extends AbstractResourceProvider implements E
 
     Map<HostRoleStatus, Integer> taskStatusCounts = calculateTaskStatusCounts(getHostRoleStatuses(tasks));
 
-    HostRoleStatus currentStatus = calculateSummaryStatus(taskStatusCounts, tasks.size());
+    HostRoleStatus currentStatus = calculateSummaryStatus(taskStatusCounts, tasks.size(), !entity.isSkippable());
 
     if (!isValidManualTransition(currentStatus, desiredStatus)) {
       throw new IllegalArgumentException("Can not transition a stage from " +
@@ -316,6 +318,7 @@ public class StageResourceProvider extends AbstractResourceProvider implements E
     setResourceProperty(resource, STAGE_CLUSTER_HOST_INFO, entity.getClusterHostInfo(), requestedIds);
     setResourceProperty(resource, STAGE_COMMAND_PARAMS, entity.getCommandParamsStage(), requestedIds);
     setResourceProperty(resource, STAGE_HOST_PARAMS, entity.getHostParamsStage(), requestedIds);
+    setResourceProperty(resource, STAGE_SKIPPABLE, entity.isSkippable(), requestedIds);
 
     Collection<HostRoleCommandEntity> tasks = entity.getHostRoleCommands();
 
@@ -336,7 +339,8 @@ public class StageResourceProvider extends AbstractResourceProvider implements E
 
     setResourceProperty(resource, STAGE_PROGRESS_PERCENT, calculateProgressPercent(taskStatusCounts, taskCount),
         requestedIds);
-    setResourceProperty(resource, STAGE_STATUS, calculateSummaryStatus(taskStatusCounts, taskCount).toString(),
+    setResourceProperty(resource, STAGE_STATUS,
+        calculateSummaryStatus(taskStatusCounts, taskCount, !entity.isSkippable()).toString(),
         requestedIds);
 
     return resource;
@@ -364,16 +368,18 @@ public class StageResourceProvider extends AbstractResourceProvider implements E
    *
    * @param counters  counts of resources that are in various states
    * @param total     total number of resources in request
+   * @param failAll   true if a single failed status should result in an overall failed status return
    *
    * @return summary request status based on statuses of tasks in different states.
    */
-  protected static HostRoleStatus calculateSummaryStatus(Map<HostRoleStatus, Integer> counters, int total) {
+  protected static HostRoleStatus calculateSummaryStatus(Map<HostRoleStatus, Integer> counters, int total,
+                                                         boolean failAll) {
     return counters.get(HostRoleStatus.HOLDING) > 0 ? HostRoleStatus.HOLDING :
         counters.get(HostRoleStatus.HOLDING_FAILED) > 0 ? HostRoleStatus.HOLDING_FAILED :
         counters.get(HostRoleStatus.HOLDING_TIMEDOUT) > 0 ? HostRoleStatus.HOLDING_TIMEDOUT :
-        counters.get(HostRoleStatus.FAILED) > 0 ? HostRoleStatus.FAILED :
+        counters.get(HostRoleStatus.FAILED) > 0 && failAll ? HostRoleStatus.FAILED :
         counters.get(HostRoleStatus.ABORTED) > 0 ? HostRoleStatus.ABORTED :
-        counters.get(HostRoleStatus.TIMEDOUT) > 0 ? HostRoleStatus.TIMEDOUT :
+        counters.get(HostRoleStatus.TIMEDOUT) > 0 && failAll ? HostRoleStatus.TIMEDOUT :
         counters.get(HostRoleStatus.IN_PROGRESS) > 0 ? HostRoleStatus.IN_PROGRESS :
         counters.get(HostRoleStatus.COMPLETED) == total ? HostRoleStatus.COMPLETED : HostRoleStatus.PENDING;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeGroupResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeGroupResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeGroupResourceProvider.java
index 47f6237..4df0f9c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeGroupResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeGroupResourceProvider.java
@@ -190,7 +190,7 @@ public class UpgradeGroupResourceProvider extends AbstractControllerResourceProv
         StageResourceProvider.calculateTaskStatusCounts(getHostRoleStatuses(stages));
 
     setResourceProperty(upgradeGroup, UPGRADE_GROUP_STATUS,
-        StageResourceProvider.calculateSummaryStatus(counters, stages.size()), requestedIds);
+        StageResourceProvider.calculateSummaryStatus(counters, stages.size(), false), requestedIds);
 
     setResourceProperty(upgradeGroup, UPGRADE_GROUP_PROGRESS_PERCENT,
         StageResourceProvider.calculateProgressPercent(counters, stages.size()), requestedIds);

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
index efc3713..0afc2c00 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
@@ -88,6 +88,12 @@ import com.google.inject.Provider;
 @StaticallyInject
 public class UpgradeResourceProvider extends AbstractControllerResourceProvider {
 
+  /**
+   * Default failure retry/skip options for upgrades.
+   */
+  private static final boolean UPGRADE_DEFAULT_ALLOW_RETRY = true;
+  private static final boolean UPGRADE_DEFAULT_SKIPPABLE = true;
+
   protected static final String UPGRADE_CLUSTER_NAME = "Upgrade/cluster_name";
   protected static final String UPGRADE_VERSION = "Upgrade/repository_version";
   protected static final String UPGRADE_REQUEST_ID = "Upgrade/request_id";
@@ -138,7 +144,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
   /**
    * Constructor.
    *
-   * @param controller
+   * @param controller  the controller
    */
   UpgradeResourceProvider(AmbariManagementController controller) {
     super(PROPERTY_IDS, KEY_PROPERTY_IDS, controller);
@@ -165,7 +171,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
           UpgradePack up = validateRequest(requestMap);
 
           return createUpgrade(up, requestMap);
-        };
+        }
       });
 
     notifyCreate(Resource.Type.Upgrade, request);
@@ -190,7 +196,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
         throw new IllegalArgumentException("The cluster name is required when querying for upgrades");
       }
 
-      Cluster cluster = null;
+      Cluster cluster;
       try {
         cluster = getManagementController().getClusters().getCluster(clusterName);
       } catch (AmbariException e) {
@@ -499,6 +505,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
         "{}", "{}",
         StageUtils.getGson().toJson(hostLevelParams));
 
+    stage.setSkippable(UPGRADE_DEFAULT_SKIPPABLE);
+
     long stageId = request.getLastStageId() + 1;
     if (0L == stageId) {
       stageId = 1L;
@@ -508,7 +516,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
 
     // !!! TODO verify the action is valid
 
-    actionExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage);
+    actionExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage, UPGRADE_DEFAULT_ALLOW_RETRY);
 
     // need to set meaningful text on the command
     for (Map<String, HostRoleCommand> map : stage.getHostRoleCommands().values()) {
@@ -553,6 +561,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
         jsons.getCommandParamsForStage(),
         jsons.getHostParamsForStage());
 
+    stage.setSkippable(UPGRADE_DEFAULT_SKIPPABLE);
+
     long stageId = request.getLastStageId() + 1;
     if (0L == stageId) {
       stageId = 1L;
@@ -565,7 +575,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     Map<String, String> requestParams = new HashMap<String, String>();
     requestParams.put("command", "RESTART");
 
-    commandExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage, requestParams);
+    commandExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage, requestParams, UPGRADE_DEFAULT_ALLOW_RETRY);
 
     request.addStages(Collections.singletonList(stage));
   }
@@ -600,6 +610,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
         jsons.getCommandParamsForStage(),
         jsons.getHostParamsForStage());
 
+    stage.setSkippable(UPGRADE_DEFAULT_SKIPPABLE);
+
     long stageId = request.getLastStageId() + 1;
     if (0L == stageId) {
       stageId = 1L;
@@ -609,7 +621,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
 
     Map<String, String> requestParams = new HashMap<String, String>();
 
-    commandExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage, requestParams);
+    commandExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage, requestParams, UPGRADE_DEFAULT_ALLOW_RETRY);
 
     request.addStages(Collections.singletonList(stage));
   }
@@ -659,6 +671,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
         jsons.getCommandParamsForStage(),
         jsons.getHostParamsForStage());
 
+    stage.setSkippable(UPGRADE_DEFAULT_SKIPPABLE);
+
     long stageId = request.getLastStageId() + 1;
     if (0L == stageId) {
       stageId = 1L;
@@ -674,7 +688,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
         RoleCommand.EXECUTE,
         cluster.getClusterName(), host,
         new ServiceComponentHostServerActionEvent(StageUtils.getHostName(), System.currentTimeMillis()),
-        commandParams, null, 1200);
+        commandParams, null, 1200, UPGRADE_DEFAULT_ALLOW_RETRY);
 
     request.addStages(Collections.singletonList(stage));
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StageEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StageEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StageEntity.java
index a7bc948..058fe9b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StageEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StageEntity.java
@@ -40,6 +40,9 @@ public class StageEntity {
   @Id
   private Long stageId = 0L;
 
+  @Column(name = "skippable", nullable = false)
+  private Integer skippable = Integer.valueOf(0);
+
   @Column(name = "log_info")
   @Basic
   private String logInfo = "";
@@ -191,4 +194,24 @@ public class StageEntity {
   public void setRequest(RequestEntity request) {
     this.request = request;
   }
+
+  /**
+   * Determine whether this stage is skippable.  If the stage is skippable then in can be skipped on
+   * error without failing the entire request.
+   *
+   * @return true if this stage is skippable
+   */
+  public boolean isSkippable() {
+    return skippable != 0;
+  }
+
+  /**
+   * Set skippable for this stage.  If the stage is skippable then in can be skipped on
+   * error without failing the entire request.
+   *
+   * @param skippable true indicates that the stage is skippable
+   */
+  public void setSkippable(boolean skippable) {
+    this.skippable = skippable ? 1 : 0;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java
index d59d8a1..06fe380 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java
@@ -176,6 +176,9 @@ public class UpgradeCatalog200 extends AbstractUpgradeCatalog {
     dbAccessor.addColumn("host_role_command", new DBAccessor.DBColumnInfo("retry_allowed",
         Integer.class, 1, 0, false));
 
+    dbAccessor.addColumn("stage", new DBAccessor.DBColumnInfo("skippable",
+        Integer.class, 1, 0, false));
+
     // New tables
     columns = new ArrayList<DBColumnInfo>();
     columns.add(new DBAccessor.DBColumnInfo("id", Long.class, null, null, false));

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java
index e6e51a1..f6d44d8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java
@@ -166,7 +166,7 @@ public class StageUtils {
     long now = System.currentTimeMillis();
     s.addHostRoleExecutionCommand(hostname, Role.NAMENODE, RoleCommand.INSTALL,
         new ServiceComponentHostInstallEvent("NAMENODE", hostname, now, "HDP-1.2.0"),
-        "cluster1", "HDFS");
+        "cluster1", "HDFS", false);
     ExecutionCommand execCmd = s.getExecutionCommandWrapper(hostname, "NAMENODE").getExecutionCommand();
     execCmd.setCommandId(s.getActionId());
     List<String> slaveHostList = new ArrayList<String>();

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
index d6229b3..d266b06 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -230,6 +230,7 @@ CREATE TABLE stage (
   stage_id BIGINT NOT NULL,
   request_id BIGINT NOT NULL,
   cluster_id BIGINT,
+  skippable SMALLINT DEFAULT 0 NOT NULL,
   log_info VARCHAR(255) NOT NULL,
   request_context VARCHAR(255),
   cluster_host_info LONGBLOB,

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
index cb8f776..e98a165 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -221,6 +221,7 @@ CREATE TABLE stage (
   stage_id NUMBER(19) NOT NULL,
   request_id NUMBER(19) NOT NULL,
   cluster_id NUMBER(19) NULL,
+  skippable NUMBER(1) DEFAULT 0 NOT NULL,
   log_info VARCHAR2(255) NULL,
   request_context VARCHAR2(255) NULL,
   cluster_host_info BLOB NOT NULL,

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index 4599390..248d86c 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -231,6 +231,7 @@ CREATE TABLE stage (
   stage_id BIGINT NOT NULL,
   request_id BIGINT NOT NULL,
   cluster_id BIGINT NOT NULL,
+  skippable SMALLINT DEFAULT 0 NOT NULL,
   log_info VARCHAR(255) NOT NULL,
   request_context VARCHAR(255),
   cluster_host_info BYTEA NOT NULL,

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
index 1e6631e..57a960c 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
@@ -266,6 +266,7 @@ CREATE TABLE ambari.stage (
   stage_id BIGINT NOT NULL,
   request_id BIGINT NOT NULL,
   cluster_id BIGINT NOT NULL,
+  skippable SMALLINT DEFAULT 0 NOT NULL,
   log_info VARCHAR(255) NOT NULL,
   request_context VARCHAR(255),
   cluster_host_info BYTEA NOT NULL,

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
index 8836f04..3cf548d 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -52,7 +52,7 @@ CREATE TABLE members (member_id INTEGER, group_id INTEGER NOT NULL, user_id INTE
 CREATE TABLE execution_command (command VARBINARY(8000), task_id BIGINT NOT NULL, PRIMARY KEY CLUSTERED (task_id));
 CREATE TABLE host_role_command (task_id BIGINT NOT NULL, attempt_count SMALLINT NOT NULL, retry_allowed SMALLINT DEFAULT 0 NOT NULL, event VARCHAR(MAX) 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 VARBINARY(max), std_out VARBINARY(max), output_log VARCHAR(255) NULL, error_log VARCHAR(255) NULL, structured_out VARBINARY(max), role_command VARCHAR(255), command_detail VARCHAR(255), custom_command_name VARCHAR(255), PRIMARY KEY CLUSTERED (task_id));
 CREATE TABLE 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 CLUSTERED (role, request_id, stage_id));
-CREATE TABLE stage (stage_id BIGINT NOT NULL, request_id BIGINT NOT NULL, cluster_id BIGINT NOT NULL, log_info VARCHAR(255) NOT NULL, request_context VARCHAR(255), cluster_host_info VARBINARY(8000) NOT NULL, command_params VARBINARY(8000), host_params VARBINARY(8000), PRIMARY KEY CLUSTERED (stage_id, request_id));
+CREATE TABLE stage (stage_id BIGINT NOT NULL, request_id BIGINT NOT NULL, cluster_id BIGINT NOT NULL, skippable SMALLINT DEFAULT 0 NOT NULL, log_info VARCHAR(255) NOT NULL, request_context VARCHAR(255), cluster_host_info VARBINARY(8000) NOT NULL, command_params VARBINARY(8000), host_params VARBINARY(8000), PRIMARY KEY CLUSTERED (stage_id, request_id));
 CREATE TABLE request (request_id BIGINT NOT NULL, cluster_id BIGINT, command_name VARCHAR(255), create_time BIGINT NOT NULL, end_time BIGINT NOT NULL, exclusive_execution BIT NOT NULL DEFAULT 0, inputs VARBINARY(8000), request_context VARCHAR(255), request_type VARCHAR(255), request_schedule_id BIGINT, start_time BIGINT NOT NULL, status VARCHAR(255), PRIMARY KEY CLUSTERED (request_id));
 CREATE TABLE requestresourcefilter (filter_id BIGINT NOT NULL, request_id BIGINT NOT NULL, service_name VARCHAR(255), component_name VARCHAR(255), hosts VARBINARY(8000), PRIMARY KEY CLUSTERED (filter_id));
 CREATE TABLE requestoperationlevel (operation_level_id BIGINT NOT NULL, request_id BIGINT NOT NULL, level_name VARCHAR(255), cluster_name VARCHAR(255), service_name VARCHAR(255), host_component_name VARCHAR(255), host_name VARCHAR(255), PRIMARY KEY CLUSTERED (operation_level_id));

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapperTest.java
index 948f137..d498c97 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapperTest.java
@@ -160,7 +160,7 @@ public class ExecutionCommandWrapperTest {
     s.addHostRoleExecutionCommand(hostName, Role.NAMENODE,
         RoleCommand.START,
         new ServiceComponentHostStartEvent(Role.NAMENODE.toString(),
-            hostName, System.currentTimeMillis()), clusterName, "HDFS");
+            hostName, System.currentTimeMillis()), clusterName, "HDFS", false);
     List<Stage> stages = new ArrayList<Stage>();
     stages.add(s);
     Request request = new Request(stages, clusters);

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionDBAccessorImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionDBAccessorImpl.java b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionDBAccessorImpl.java
index 7e4f850..2e79741 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionDBAccessorImpl.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionDBAccessorImpl.java
@@ -419,23 +419,23 @@ public class TestActionDBAccessorImpl {
     s.addHostRoleExecutionCommand("host1", Role.HBASE_MASTER,
         RoleCommand.START,
         new ServiceComponentHostStartEvent(Role.HBASE_MASTER.toString(),
-            "host1", System.currentTimeMillis()), "cluster1", "HBASE");
+            "host1", System.currentTimeMillis()), "cluster1", "HBASE", false);
     s.addHostRoleExecutionCommand("host2", Role.HBASE_MASTER,
         RoleCommand.START,
         new ServiceComponentHostStartEvent(Role.HBASE_MASTER.toString(),
-            "host2", System.currentTimeMillis()), "cluster1", "HBASE");
+            "host2", System.currentTimeMillis()), "cluster1", "HBASE", false);
     s.addHostRoleExecutionCommand(
         "host3",
         Role.HBASE_REGIONSERVER,
         RoleCommand.START,
         new ServiceComponentHostStartEvent(Role.HBASE_REGIONSERVER
-            .toString(), "host3", System.currentTimeMillis()), "cluster1", "HBASE");
+            .toString(), "host3", System.currentTimeMillis()), "cluster1", "HBASE", false);
     s.addHostRoleExecutionCommand(
         "host4",
         Role.HBASE_REGIONSERVER,
         RoleCommand.START,
         new ServiceComponentHostStartEvent(Role.HBASE_REGIONSERVER
-            .toString(), "host4", System.currentTimeMillis()), "cluster1", "HBASE");
+            .toString(), "host4", System.currentTimeMillis()), "cluster1", "HBASE", false);
     List<Stage> stages = new ArrayList<Stage>();
     stages.add(s);
     s.getOrderedHostRoleCommands().get(0).setStatus(HostRoleStatus.PENDING);
@@ -502,7 +502,7 @@ public class TestActionDBAccessorImpl {
       clusters.getHost(host).persist();
 
       s.addHostRoleExecutionCommand("host" + i, Role.HBASE_MASTER,
-        RoleCommand.START, null, "cluster1", "HBASE");
+        RoleCommand.START, null, "cluster1", "HBASE", false);
     }
 
     List<Stage> stages = new ArrayList<Stage>();
@@ -546,13 +546,13 @@ public class TestActionDBAccessorImpl {
     s.addHostRoleExecutionCommand(hostname, Role.HBASE_MASTER,
         RoleCommand.START,
         new ServiceComponentHostStartEvent(Role.HBASE_MASTER.toString(),
-            hostname, System.currentTimeMillis()), "cluster1", "HBASE");
+            hostname, System.currentTimeMillis()), "cluster1", "HBASE", false);
     s.addHostRoleExecutionCommand(
         hostname,
         Role.HBASE_REGIONSERVER,
         RoleCommand.START,
         new ServiceComponentHostStartEvent(Role.HBASE_REGIONSERVER
-            .toString(), hostname, System.currentTimeMillis()), "cluster1", "HBASE");
+            .toString(), hostname, System.currentTimeMillis()), "cluster1", "HBASE", false);
     return s;
   }
 
@@ -564,7 +564,7 @@ public class TestActionDBAccessorImpl {
     s.addHostRoleExecutionCommand(hostname, Role.valueOf(actionName),
         RoleCommand.ACTIONEXECUTE,
         new ServiceComponentHostStartEvent(Role.HBASE_MASTER.toString(),
-            hostname, System.currentTimeMillis()), "cluster1", "HBASE");
+            hostname, System.currentTimeMillis()), "cluster1", "HBASE", false);
     List<Stage> stages = new ArrayList<Stage>();
     stages.add(s);
     final RequestResourceFilter resourceFilter = new RequestResourceFilter("HBASE", "HBASE_MASTER", null);
@@ -581,7 +581,7 @@ public class TestActionDBAccessorImpl {
     Stage s = new Stage(requestId, "/a/b", "cluster1", 1L, "action db accessor test",
         "", "commandParamsStage", "hostParamsStage");
     s.setStageId(stageId);
-    s.addServerActionCommand(serverActionName, Role.AMBARI_SERVER_ACTION, RoleCommand.ACTIONEXECUTE, clusterName, null, null, "command details", 300);
+    s.addServerActionCommand(serverActionName, Role.AMBARI_SERVER_ACTION, RoleCommand.ACTIONEXECUTE, clusterName, null, null, "command details", 300, false);
     List<Stage> stages = new ArrayList<Stage>();
     stages.add(s);
     final RequestResourceFilter resourceFilter = new RequestResourceFilter("AMBARI", "SERVER", Arrays.asList(hostname));

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionManager.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionManager.java b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionManager.java
index 01a40f4..6c5a8a0 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionManager.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionManager.java
@@ -172,7 +172,7 @@ public class TestActionManager {
     s.addHostRoleExecutionCommand(hostname, Role.HBASE_MASTER,
         RoleCommand.START,
         new ServiceComponentHostStartEvent(Role.HBASE_MASTER.toString(),
-            hostname, System.currentTimeMillis()), "cluster1", "HBASE");
+            hostname, System.currentTimeMillis()), "cluster1", "HBASE", false);
     List<Stage> stages = new ArrayList<Stage>();
     stages.add(s);
     Request request = new Request(stages, clusters);

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionScheduler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionScheduler.java b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionScheduler.java
index edbb71d..c3418dc 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionScheduler.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionScheduler.java
@@ -222,7 +222,7 @@ public class TestActionScheduler {
       "{\"host_param\":\"param_value\"}", "{\"stage_param\":\"param_value\"}");
     s.addHostRoleExecutionCommand(hostname, Role.SECONDARY_NAMENODE, RoleCommand.INSTALL,
             new ServiceComponentHostInstallEvent("SECONDARY_NAMENODE", hostname, System.currentTimeMillis(), "HDP-1.2.0"),
-            "cluster1", "HDFS");
+            "cluster1", "HDFS", false);
     s.setHostRoleStatus(hostname, "SECONDARY_NAMENODE", HostRoleStatus.IN_PROGRESS);
     stages.add(s);
 
@@ -769,7 +769,7 @@ public class TestActionScheduler {
         RoleCommand.EXECUTE, "cluster1",
         new ServiceComponentHostServerActionEvent(serverHostname, System.currentTimeMillis()),
         payload,
-        null, timeout);
+        null, timeout, false);
 
     return stage;
   }
@@ -1355,7 +1355,7 @@ public class TestActionScheduler {
                                            RoleCommand command, String host, String cluster) {
     stage.addHostRoleExecutionCommand(host, role, command,
         new ServiceComponentHostInstallEvent(role.toString(), host, now, "HDP-0.2"),
-        cluster, service.toString());
+        cluster, service.toString(), false);
     stage.getExecutionCommandWrapper(host,
         role.toString()).getExecutionCommand();
   }
@@ -1384,19 +1384,19 @@ public class TestActionScheduler {
     stage.setStageId(1);
     stage.addHostRoleExecutionCommand("host1", Role.DATANODE, RoleCommand.UPGRADE,
         new ServiceComponentHostUpgradeEvent(Role.DATANODE.toString(), "host1", now, "HDP-0.2"),
-        "cluster1", Service.Type.HDFS.toString());
+        "cluster1", Service.Type.HDFS.toString(), false);
     stage.getExecutionCommandWrapper("host1",
         Role.DATANODE.toString()).getExecutionCommand();
 
     stage.addHostRoleExecutionCommand("host2", Role.DATANODE, RoleCommand.UPGRADE,
         new ServiceComponentHostUpgradeEvent(Role.DATANODE.toString(), "host2", now, "HDP-0.2"),
-        "cluster1", Service.Type.HDFS.toString());
+        "cluster1", Service.Type.HDFS.toString(), false);
     stage.getExecutionCommandWrapper("host2",
         Role.DATANODE.toString()).getExecutionCommand();
 
     stage.addHostRoleExecutionCommand("host3", Role.DATANODE, RoleCommand.UPGRADE,
         new ServiceComponentHostUpgradeEvent(Role.DATANODE.toString(), "host3", now, "HDP-0.2"),
-        "cluster1", Service.Type.HDFS.toString());
+        "cluster1", Service.Type.HDFS.toString(), false);
     stage.getExecutionCommandWrapper("host3",
         Role.DATANODE.toString()).getExecutionCommand();
     stages.add(stage);
@@ -1525,7 +1525,7 @@ public class TestActionScheduler {
     stage.setStageId(stageId);
     stage.addHostRoleExecutionCommand(hostname, role, roleCommand,
         new ServiceComponentHostUpgradeEvent(role.toString(), hostname, System.currentTimeMillis(), "HDP-0.2"),
-        clusterName, service.toString());
+        clusterName, service.toString(), false);
     stage.getExecutionCommandWrapper(hostname,
         role.toString()).getExecutionCommand();
     stage.getOrderedHostRoleCommands().get(0).setTaskId(taskId);
@@ -1552,7 +1552,7 @@ public class TestActionScheduler {
 
     stage.addHostRoleExecutionCommand(hostname, role, roleCommand,
       new ServiceComponentHostInstallEvent(role.toString(), hostname,
-        System.currentTimeMillis(), "HDP-0.2"), clusterName, service.toString());
+        System.currentTimeMillis(), "HDP-0.2"), clusterName, service.toString(), false);
     ExecutionCommand command = stage.getExecutionCommandWrapper
       (hostname, role.toString()).getExecutionCommand();
     command.setTaskId(taskId);

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestStage.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestStage.java b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestStage.java
index bde19a1..7ee6045 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestStage.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestStage.java
@@ -36,9 +36,9 @@ public class TestStage {
   public void testTaskTimeout() {
     Stage s = StageUtils.getATestStage(1, 1, "h1", CLUSTER_HOST_INFO, "{\"host_param\":\"param_value\"}", "{\"stage_param\":\"param_value\"}");
     s.addHostRoleExecutionCommand("h1", Role.DATANODE, RoleCommand.INSTALL,
-        null, "c1", "HDFS");
+        null, "c1", "HDFS", false);
     s.addHostRoleExecutionCommand("h1", Role.HBASE_MASTER, RoleCommand.INSTALL,
-        null, "c1", "HBASE");
+        null, "c1", "HBASE", false);
     for (ExecutionCommandWrapper wrapper : s.getExecutionCommands("h1")) {
       Map<String, String> commandParams = new TreeMap<String, String>();
       commandParams.put(ExecutionCommand.KeyNames.COMMAND_TIMEOUT, "600");

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/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 a6df0db..3cf3b67 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
@@ -769,7 +769,7 @@ public class TestHeartbeatHandler {
     s.addHostRoleExecutionCommand(DummyHostname1, Role.HBASE_MASTER,
         RoleCommand.START,
         new ServiceComponentHostStartEvent(Role.HBASE_MASTER.toString(),
-            DummyHostname1, System.currentTimeMillis()), DummyCluster, HBASE);
+            DummyHostname1, System.currentTimeMillis()), DummyCluster, HBASE, false);
     List<Stage> stages = new ArrayList<Stage>();
     stages.add(s);
     Request request = new Request(stages, clusters);
@@ -1154,7 +1154,7 @@ public class TestHeartbeatHandler {
     s.addHostRoleExecutionCommand(DummyHostname1, Role.DATANODE, RoleCommand.INSTALL,
       new ServiceComponentHostInstallEvent(Role.DATANODE.toString(),
         DummyHostname1, System.currentTimeMillis(), "HDP-1.3.0"),
-          DummyCluster, "HDFS");
+          DummyCluster, "HDFS", false);
     List<Stage> stages = new ArrayList<Stage>();
     stages.add(s);
     Request request = new Request(stages, clusters);
@@ -1731,11 +1731,11 @@ public class TestHeartbeatHandler {
     s.addHostRoleExecutionCommand(DummyHostname1, Role.DATANODE, RoleCommand.UPGRADE,
       new ServiceComponentHostUpgradeEvent(Role.DATANODE.toString(),
         DummyHostname1, System.currentTimeMillis(), "HDP-1.3.0"),
-      DummyCluster, "HDFS");
+      DummyCluster, "HDFS", false);
     s.addHostRoleExecutionCommand(DummyHostname1, Role.NAMENODE, RoleCommand.INSTALL,
       new ServiceComponentHostInstallEvent(Role.NAMENODE.toString(),
         DummyHostname1, System.currentTimeMillis(), "HDP-1.3.0"),
-          DummyCluster, "HDFS");
+          DummyCluster, "HDFS", false);
     List<Stage> stages = new ArrayList<Stage>();
     stages.add(s);
     Request request = new Request(stages, clusters);

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
index 72a22e6..bb74ca1 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
@@ -7800,7 +7800,7 @@ public class AmbariManagementControllerTest {
             RoleCommand.START,
             new ServiceComponentHostStartEvent(Role.HBASE_MASTER.toString(),
                     hostName1, System.currentTimeMillis()),
-            clusterName, "HBASE");
+            clusterName, "HBASE", false);
 
     stages.add(new Stage(requestId1, "/a2", clusterName, 1L, context,
       CLUSTER_HOST_INFO, "", ""));
@@ -7808,7 +7808,7 @@ public class AmbariManagementControllerTest {
     stages.get(1).addHostRoleExecutionCommand(hostName1, Role.HBASE_CLIENT,
             RoleCommand.START,
             new ServiceComponentHostStartEvent(Role.HBASE_CLIENT.toString(),
-                    hostName1, System.currentTimeMillis()), clusterName, "HBASE");
+                    hostName1, System.currentTimeMillis()), clusterName, "HBASE", false);
 
     stages.add(new Stage(requestId1, "/a3", clusterName, 1L, context,
       CLUSTER_HOST_INFO, "", ""));
@@ -7816,7 +7816,7 @@ public class AmbariManagementControllerTest {
     stages.get(2).addHostRoleExecutionCommand(hostName1, Role.HBASE_CLIENT,
             RoleCommand.START,
             new ServiceComponentHostStartEvent(Role.HBASE_CLIENT.toString(),
-                    hostName1, System.currentTimeMillis()), clusterName, "HBASE");
+                    hostName1, System.currentTimeMillis()), clusterName, "HBASE", false);
 
     Request request = new Request(stages, clusters);
     actionDB.persistActions(request);
@@ -7828,7 +7828,7 @@ public class AmbariManagementControllerTest {
     stages.get(0).addHostRoleExecutionCommand(hostName1, Role.HBASE_CLIENT,
             RoleCommand.START,
             new ServiceComponentHostStartEvent(Role.HBASE_CLIENT.toString(),
-                    hostName1, System.currentTimeMillis()), clusterName, "HBASE");
+                    hostName1, System.currentTimeMillis()), clusterName, "HBASE", false);
 
     stages.add(new Stage(requestId2, "/a5", clusterName, 1L, context,
       CLUSTER_HOST_INFO, "", ""));
@@ -7836,7 +7836,7 @@ public class AmbariManagementControllerTest {
     stages.get(1).addHostRoleExecutionCommand(hostName1, Role.HBASE_CLIENT,
             RoleCommand.START,
             new ServiceComponentHostStartEvent(Role.HBASE_CLIENT.toString(),
-                    hostName1, System.currentTimeMillis()), clusterName, "HBASE");
+                    hostName1, System.currentTimeMillis()), clusterName, "HBASE", false);
 
     request = new Request(stages, clusters);
     actionDB.persistActions(request);

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StageResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StageResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StageResourceProviderTest.java
index 4c47e94..0238881 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StageResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StageResourceProviderTest.java
@@ -235,6 +235,50 @@ public class StageResourceProviderTest {
     assertEquals(Double.valueOf(64.9), percent);
   }
 
+  @Test
+  public void testCalculateSummaryStatus() {
+
+    Collection<HostRoleStatus> hostRoleStatuses = new LinkedList<HostRoleStatus>();
+
+    hostRoleStatuses.add(HostRoleStatus.PENDING);
+    hostRoleStatuses.add(HostRoleStatus.PENDING);
+    hostRoleStatuses.add(HostRoleStatus.PENDING);
+    hostRoleStatuses.add(HostRoleStatus.PENDING);
+    hostRoleStatuses.add(HostRoleStatus.PENDING);
+    hostRoleStatuses.add(HostRoleStatus.PENDING);
+
+    Map<HostRoleStatus, Integer> counts = StageResourceProvider.calculateTaskStatusCounts(hostRoleStatuses);
+
+    assertEquals(HostRoleStatus.PENDING, StageResourceProvider.calculateSummaryStatus(counts, hostRoleStatuses.size(), true));
+
+    hostRoleStatuses = new LinkedList<HostRoleStatus>();
+
+    hostRoleStatuses.add(HostRoleStatus.COMPLETED);
+    hostRoleStatuses.add(HostRoleStatus.FAILED);
+    hostRoleStatuses.add(HostRoleStatus.ABORTED);
+    hostRoleStatuses.add(HostRoleStatus.ABORTED);
+    hostRoleStatuses.add(HostRoleStatus.ABORTED);
+    hostRoleStatuses.add(HostRoleStatus.ABORTED);
+
+    counts = StageResourceProvider.calculateTaskStatusCounts(hostRoleStatuses);
+
+    assertEquals(HostRoleStatus.FAILED, StageResourceProvider.calculateSummaryStatus(counts, hostRoleStatuses.size(), true));
+
+    hostRoleStatuses = new LinkedList<HostRoleStatus>();
+
+    hostRoleStatuses.add(HostRoleStatus.COMPLETED);
+    hostRoleStatuses.add(HostRoleStatus.FAILED);
+    hostRoleStatuses.add(HostRoleStatus.COMPLETED);
+    hostRoleStatuses.add(HostRoleStatus.COMPLETED);
+    hostRoleStatuses.add(HostRoleStatus.COMPLETED);
+    hostRoleStatuses.add(HostRoleStatus.COMPLETED);
+
+    counts = StageResourceProvider.calculateTaskStatusCounts(hostRoleStatuses);
+
+    assertEquals(HostRoleStatus.COMPLETED, StageResourceProvider.calculateSummaryStatus(counts, hostRoleStatuses.size(), false));
+  }
+
+
   private List<StageEntity> getStageEntities() {
     StageEntity stage = new StageEntity();
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/85ff5149/ambari-server/src/test/java/org/apache/ambari/server/serveraction/ServerActionExecutorTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/ServerActionExecutorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/ServerActionExecutorTest.java
index 96c0539..73f7be7 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/ServerActionExecutorTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/ServerActionExecutorTest.java
@@ -99,7 +99,7 @@ public class ServerActionExecutorTest {
         RoleCommand.EXECUTE,
         "cluster1", SERVER_HOST_NAME,
         new ServiceComponentHostServerActionEvent(StageUtils.getHostName(), System.currentTimeMillis()),
-        Collections.<String, String>emptyMap(), null, 1200);
+        Collections.<String, String>emptyMap(), null, 1200, false);
 
     final List<Stage> stages = new ArrayList<Stage>() {
       {
@@ -289,7 +289,7 @@ public class ServerActionExecutorTest {
     stage.addServerActionCommand(MockServerAction.class.getName(), Role.AMBARI_SERVER_ACTION,
         RoleCommand.EXECUTE, "cluster1",
         new ServiceComponentHostServerActionEvent(SERVER_HOST_NAME, System.currentTimeMillis()),
-        payload, "command detail", timeout);
+        payload, "command detail", timeout, false);
 
     return stage;
   }