|
@@ -48,6 +48,8 @@ import org.apache.ambari.server.ParentObjectNotFoundException;
|
|
|
import org.apache.ambari.server.ServiceComponentHostNotFoundException;
|
|
|
import org.apache.ambari.server.ServiceComponentNotFoundException;
|
|
|
import org.apache.ambari.server.ServiceNotFoundException;
|
|
|
+import org.apache.ambari.server.actionmanager.HostRoleCommand;
|
|
|
+import org.apache.ambari.server.actionmanager.HostRoleStatus;
|
|
|
import org.apache.ambari.server.api.services.AmbariMetaInfo;
|
|
|
import org.apache.ambari.server.configuration.Configuration;
|
|
|
import org.apache.ambari.server.controller.AmbariSessionManager;
|
|
@@ -56,6 +58,7 @@ import org.apache.ambari.server.controller.ConfigurationResponse;
|
|
|
import org.apache.ambari.server.controller.MaintenanceStateHelper;
|
|
|
import org.apache.ambari.server.controller.RootServiceResponseFactory.Services;
|
|
|
import org.apache.ambari.server.controller.ServiceConfigVersionResponse;
|
|
|
+import org.apache.ambari.server.controller.internal.UpgradeResourceProvider;
|
|
|
import org.apache.ambari.server.events.AmbariEvent.AmbariEventType;
|
|
|
import org.apache.ambari.server.events.ClusterEvent;
|
|
|
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
|
|
@@ -68,8 +71,10 @@ import org.apache.ambari.server.orm.dao.ClusterStateDAO;
|
|
|
import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
|
|
|
import org.apache.ambari.server.orm.dao.HostConfigMappingDAO;
|
|
|
import org.apache.ambari.server.orm.dao.HostDAO;
|
|
|
+import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
|
|
|
import org.apache.ambari.server.orm.dao.HostVersionDAO;
|
|
|
import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
|
|
|
+import org.apache.ambari.server.orm.dao.RequestDAO;
|
|
|
import org.apache.ambari.server.orm.dao.ServiceConfigDAO;
|
|
|
import org.apache.ambari.server.orm.dao.StackDAO;
|
|
|
import org.apache.ambari.server.orm.dao.TopologyRequestDAO;
|
|
@@ -83,16 +88,20 @@ import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
|
|
|
import org.apache.ambari.server.orm.entities.ConfigGroupEntity;
|
|
|
import org.apache.ambari.server.orm.entities.HostComponentStateEntity;
|
|
|
import org.apache.ambari.server.orm.entities.HostEntity;
|
|
|
+import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
|
|
|
import org.apache.ambari.server.orm.entities.HostVersionEntity;
|
|
|
import org.apache.ambari.server.orm.entities.PermissionEntity;
|
|
|
import org.apache.ambari.server.orm.entities.PrivilegeEntity;
|
|
|
import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
|
|
|
+import org.apache.ambari.server.orm.entities.RequestEntity;
|
|
|
import org.apache.ambari.server.orm.entities.RequestScheduleEntity;
|
|
|
import org.apache.ambari.server.orm.entities.ResourceEntity;
|
|
|
import org.apache.ambari.server.orm.entities.ServiceConfigEntity;
|
|
|
import org.apache.ambari.server.orm.entities.StackEntity;
|
|
|
import org.apache.ambari.server.orm.entities.TopologyRequestEntity;
|
|
|
import org.apache.ambari.server.orm.entities.UpgradeEntity;
|
|
|
+import org.apache.ambari.server.orm.entities.UpgradeGroupEntity;
|
|
|
+import org.apache.ambari.server.orm.entities.UpgradeItemEntity;
|
|
|
import org.apache.ambari.server.security.authorization.AuthorizationException;
|
|
|
import org.apache.ambari.server.security.authorization.AuthorizationHelper;
|
|
|
import org.apache.ambari.server.state.Cluster;
|
|
@@ -125,6 +134,7 @@ import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
|
|
|
import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
|
|
|
import org.apache.ambari.server.state.scheduler.RequestExecution;
|
|
|
import org.apache.ambari.server.state.scheduler.RequestExecutionFactory;
|
|
|
+import org.apache.ambari.server.state.stack.upgrade.Direction;
|
|
|
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostSummary;
|
|
|
import org.apache.ambari.server.topology.TopologyRequest;
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
@@ -211,6 +221,12 @@ public class ClusterImpl implements Cluster {
|
|
|
@Inject
|
|
|
private ClusterVersionDAO clusterVersionDAO;
|
|
|
|
|
|
+ @Inject
|
|
|
+ private HostRoleCommandDAO hostRoleCommandDAO;
|
|
|
+
|
|
|
+ @Inject
|
|
|
+ private RequestDAO requestDAO;
|
|
|
+
|
|
|
@Inject
|
|
|
private HostDAO hostDAO;
|
|
|
|
|
@@ -302,6 +318,9 @@ public class ClusterImpl implements Cluster {
|
|
|
StringUtils.isEmpty(desiredStackVersion.getStackVersion())) {
|
|
|
loadServiceConfigTypes();
|
|
|
}
|
|
|
+
|
|
|
+ // Load any active stack upgrades.
|
|
|
+ loadStackUpgrade();
|
|
|
}
|
|
|
|
|
|
|
|
@@ -320,6 +339,24 @@ public class ClusterImpl implements Cluster {
|
|
|
LOG.info("Service config types loaded: {}", serviceConfigTypes);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * When a cluster is first loaded, determine if it has a stack upgrade in progress.
|
|
|
+ */
|
|
|
+ private void loadStackUpgrade() {
|
|
|
+ clusterGlobalLock.writeLock().lock();
|
|
|
+
|
|
|
+ try {
|
|
|
+ UpgradeEntity activeUpgrade = this.getUpgradeInProgress();
|
|
|
+ if (activeUpgrade != null) {
|
|
|
+ this.setUpgradeEntity(activeUpgrade);
|
|
|
+ }
|
|
|
+ } catch (AmbariException e) {
|
|
|
+ LOG.error("Unable to load active stack upgrade. Error: " + e.getMessage());
|
|
|
+ } finally {
|
|
|
+ clusterGlobalLock.writeLock().unlock();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Construct config type to service name mapping
|
|
|
* @throws AmbariException when stack or its part not found
|
|
@@ -1140,12 +1177,106 @@ public class ClusterImpl implements Cluster {
|
|
|
Collection<ClusterVersionEntity> clusterVersionEntities = getClusterEntity().getClusterVersionEntities();
|
|
|
for (ClusterVersionEntity clusterVersionEntity : clusterVersionEntities) {
|
|
|
if (clusterVersionEntity.getState() == RepositoryVersionState.CURRENT) {
|
|
|
-// TODO assuming there's only 1 current version, return 1st found, exception was expected in previous implementation
|
|
|
+ // TODO assuming there's only 1 current version, return 1st found, exception was expected in previous implementation
|
|
|
return clusterVersionEntity;
|
|
|
}
|
|
|
}
|
|
|
return null;
|
|
|
-// return clusterVersionDAO.findByClusterAndStateCurrent(getClusterName());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Get any stack upgrade currently in progress.
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private UpgradeEntity getUpgradeInProgress() {
|
|
|
+ UpgradeEntity mostRecentUpgrade = upgradeDAO.findLastUpgradeOrDowngradeForCluster(this.getClusterId());
|
|
|
+ if (mostRecentUpgrade != null) {
|
|
|
+ List<HostRoleStatus> UNFINISHED_STATUSES = new ArrayList();
|
|
|
+ UNFINISHED_STATUSES.add(HostRoleStatus.PENDING);
|
|
|
+ UNFINISHED_STATUSES.add(HostRoleStatus.ABORTED);
|
|
|
+
|
|
|
+ List<HostRoleCommandEntity> commands = hostRoleCommandDAO.findByRequestIdAndStatuses(mostRecentUpgrade.getRequestId(), UNFINISHED_STATUSES);
|
|
|
+ if (!commands.isEmpty()) {
|
|
|
+ return mostRecentUpgrade;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * If no RU/EU is in progress, get the ClusterVersionEntity object whose state is CURRENT.
|
|
|
+ * If RU/EU is in progress, based on the direction and desired stack, determine which version to use.
|
|
|
+ * Assuming upgrading from HDP 2.2.0.0-1 to 2.3.0.0-2, then
|
|
|
+ * RU Upgrade: 2.3.0.0-2 (desired stack id)
|
|
|
+ * RU Downgrade: 2.2.0.0-1 (desired stack id)
|
|
|
+ * EU Upgrade: while stopping services and before changing desired stack, use 2.2.0.0-1, after, use 2.3.0.0-2
|
|
|
+ * EU Downgrade: while stopping services and before changing desired stack, use 2.3.0.0-2, after, use 2.2.0.0-1
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public ClusterVersionEntity getEffectiveClusterVersion() throws AmbariException {
|
|
|
+ // This is not reliable. Need to find the last upgrade request.
|
|
|
+ UpgradeEntity upgradeInProgress = this.getUpgradeEntity();
|
|
|
+ if (upgradeInProgress == null) {
|
|
|
+ return this.getCurrentClusterVersion();
|
|
|
+ }
|
|
|
+
|
|
|
+ String effectiveVersion = null;
|
|
|
+ switch (upgradeInProgress.getUpgradeType()) {
|
|
|
+ case NON_ROLLING:
|
|
|
+ if (upgradeInProgress.getDirection() == Direction.UPGRADE) {
|
|
|
+ boolean pastChangingStack = this.isNonRollingUpgradePastUpgradingStack(upgradeInProgress);
|
|
|
+ effectiveVersion = pastChangingStack ? upgradeInProgress.getToVersion() : upgradeInProgress.getFromVersion();
|
|
|
+ } else {
|
|
|
+ // Should be the lower value during a Downgrade.
|
|
|
+ effectiveVersion = upgradeInProgress.getToVersion();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ROLLING:
|
|
|
+ default:
|
|
|
+ // Version will be higher on upgrade and lower on downgrade directions.
|
|
|
+ effectiveVersion = upgradeInProgress.getToVersion();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (effectiveVersion == null) {
|
|
|
+ throw new AmbariException("Unable to determine which version to use during Stack Upgrade, effectiveVersion is null.");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Find the first cluster version whose repo matches the expected version.
|
|
|
+ Collection<ClusterVersionEntity> clusterVersionEntities = getClusterEntity().getClusterVersionEntities();
|
|
|
+ for (ClusterVersionEntity clusterVersionEntity : clusterVersionEntities) {
|
|
|
+ if (clusterVersionEntity.getRepositoryVersion().getVersion().equals(effectiveVersion)) {
|
|
|
+ return clusterVersionEntity;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Given a NonRolling stack upgrade, determine if it has already crossed the point of using the newer version.
|
|
|
+ * @param upgrade Stack Upgrade
|
|
|
+ * @return Return true if should be using to_version, otherwise, false to mean the from_version.
|
|
|
+ */
|
|
|
+ private boolean isNonRollingUpgradePastUpgradingStack(UpgradeEntity upgrade) {
|
|
|
+ for (UpgradeGroupEntity group : upgrade.getUpgradeGroups()) {
|
|
|
+ if (group.getName().equalsIgnoreCase(UpgradeResourceProvider.CONST_UPGRADE_GROUP_NAME)) {
|
|
|
+ for (UpgradeItemEntity item : group.getItems()) {
|
|
|
+ List<Long> taskIds = hostRoleCommandDAO.findTaskIdsByStage(upgrade.getRequestId(), item.getStageId());
|
|
|
+ List<HostRoleCommandEntity> commands = hostRoleCommandDAO.findByPKs(taskIds);
|
|
|
+ for (HostRoleCommandEntity command : commands) {
|
|
|
+ if (command.getCustomCommandName() != null &&
|
|
|
+ command.getCustomCommandName().equalsIgnoreCase(UpgradeResourceProvider.CONST_CUSTOM_COMMAND_NAME) &&
|
|
|
+ command.getStatus() == HostRoleStatus.COMPLETED) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
/**
|