|
@@ -0,0 +1,144 @@
|
|
|
+/*
|
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one
|
|
|
+ * or more contributor license agreements. See the NOTICE file
|
|
|
+ * distributed with this work for additional information
|
|
|
+ * regarding copyright ownership. The ASF licenses this file
|
|
|
+ * to you under the Apache License, Version 2.0 (the
|
|
|
+ * "License"); you may not use this file except in compliance
|
|
|
+ * with the License. You may obtain a copy of the License at
|
|
|
+ *
|
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
|
+ *
|
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
+ * See the License for the specific language governing permissions and
|
|
|
+ * limitations under the License.
|
|
|
+ */
|
|
|
+package org.apache.ambari.server.checks;
|
|
|
+
|
|
|
+import com.google.inject.Inject;
|
|
|
+import com.google.inject.Singleton;
|
|
|
+import org.apache.ambari.server.AmbariException;
|
|
|
+import org.apache.ambari.server.actionmanager.HostRoleStatus;
|
|
|
+import org.apache.ambari.server.controller.PrereqCheckRequest;
|
|
|
+import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
|
|
|
+import org.apache.ambari.server.orm.dao.RequestDAO;
|
|
|
+import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
|
|
|
+import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
|
|
|
+import org.apache.ambari.server.orm.entities.HostVersionEntity;
|
|
|
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
|
|
|
+import org.apache.ambari.server.orm.entities.RequestEntity;
|
|
|
+import org.apache.ambari.server.orm.entities.UpgradeEntity;
|
|
|
+import org.apache.ambari.server.state.Cluster;
|
|
|
+import org.apache.ambari.server.state.Host;
|
|
|
+import org.apache.ambari.server.state.MaintenanceState;
|
|
|
+import org.apache.ambari.server.state.RepositoryVersionState;
|
|
|
+import org.apache.ambari.server.state.StackId;
|
|
|
+import org.apache.ambari.server.state.stack.PrereqCheckStatus;
|
|
|
+import org.apache.ambari.server.state.stack.PrerequisiteCheck;
|
|
|
+import org.apache.ambari.server.state.stack.upgrade.Direction;
|
|
|
+import org.apache.commons.lang.StringUtils;
|
|
|
+
|
|
|
+import javax.inject.Provider;
|
|
|
+import java.text.MessageFormat;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.LinkedHashSet;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Set;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Checks if Install Packages needs to be re-run
|
|
|
+ */
|
|
|
+@Singleton
|
|
|
+@UpgradeCheck(group = UpgradeCheckGroup.DEFAULT, order = 4.0f, required = true)
|
|
|
+public class PreviousUpgradeCompleted extends AbstractCheckDescriptor {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * If this ever changes, we will need to keep the historic name.
|
|
|
+ */
|
|
|
+ public static final String FINALIZE_ACTION_CLASS_NAME = "org.apache.ambari.server.serveraction.upgrades.FinalizeUpgradeAction";
|
|
|
+ public static final String SET_CURRENT_COMMAND = "ambari-server set-current --cluster-name=$CLUSTERNAME --version-display-name=$VERSION_NAME";
|
|
|
+
|
|
|
+ @Inject
|
|
|
+ Provider<RequestDAO> requestDaoProvider;
|
|
|
+
|
|
|
+ @Inject
|
|
|
+ Provider<HostRoleCommandDAO> hostRoleCommandDaoProvider;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Constructor.
|
|
|
+ */
|
|
|
+ public PreviousUpgradeCompleted() {
|
|
|
+ super(CheckDescription.PREVIOUS_UPGRADE_COMPLETED);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException {
|
|
|
+ final String clusterName = request.getClusterName();
|
|
|
+ final Cluster cluster = clustersProvider.get().getCluster(clusterName);
|
|
|
+
|
|
|
+ String errorMessage = null;
|
|
|
+
|
|
|
+ List<UpgradeEntity> upgrades= upgradeDaoProvider.get().findAll();
|
|
|
+ if (upgrades != null) {
|
|
|
+ Long lastStartTime = 0L;
|
|
|
+ UpgradeEntity mostRecentUpgrade = null;
|
|
|
+ UpgradeEntity correspondingDowngrade = null;
|
|
|
+ for (UpgradeEntity upgrade : upgrades) {
|
|
|
+ // Find the most recent upgrade for this cluster
|
|
|
+ if (upgrade.getClusterId() == cluster.getClusterId() && upgrade.getDirection() == Direction.UPGRADE) {
|
|
|
+ Long requestId = upgrade.getRequestId();
|
|
|
+ RequestEntity upgradeRequest = requestDaoProvider.get().findByPK(requestId);
|
|
|
+ if (upgradeRequest != null && upgradeRequest.getStartTime() > lastStartTime) {
|
|
|
+ mostRecentUpgrade = upgrade;
|
|
|
+ lastStartTime = upgradeRequest.getStartTime();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check for the corresponding downgrade.
|
|
|
+ if (mostRecentUpgrade != null) {
|
|
|
+ for (UpgradeEntity downgrade : upgrades) {
|
|
|
+ // Surprisingly, a Downgrade's from and to version are identical.
|
|
|
+ if (downgrade.getClusterId() == cluster.getClusterId() && downgrade.getDirection() == Direction.DOWNGRADE &&
|
|
|
+ downgrade.getFromVersion().equals(mostRecentUpgrade.getToVersion())) {
|
|
|
+ correspondingDowngrade = downgrade;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // If it has no downgrade, then the "Save Cluster State" step should have COMPLETED.
|
|
|
+ if (correspondingDowngrade == null) {
|
|
|
+ // Should have only 1 element.
|
|
|
+ List<HostRoleCommandEntity> finalizeCommandList = hostRoleCommandDaoProvider.get().
|
|
|
+ findSortedCommandsByRequestIdAndCustomCommandName(mostRecentUpgrade.getRequestId(), FINALIZE_ACTION_CLASS_NAME);
|
|
|
+
|
|
|
+ // If the action is not COMPLETED, then something went wrong.
|
|
|
+ if (finalizeCommandList != null) {
|
|
|
+ for (HostRoleCommandEntity command : finalizeCommandList) {
|
|
|
+ if (command.getStatus() != HostRoleStatus.COMPLETED) {
|
|
|
+ errorMessage = MessageFormat.format("Upgrade attempt (id: {0}, request id: {1}, from version: {2}, " +
|
|
|
+ "to version: {3}) did not complete task with id {4} since its state is {5} instead of COMPLETED.",
|
|
|
+ mostRecentUpgrade.getId(), mostRecentUpgrade.getRequestId(), mostRecentUpgrade.getFromVersion(),
|
|
|
+ mostRecentUpgrade.getToVersion(), command.getTaskId(), command.getStatus());
|
|
|
+ errorMessage += " Please ensure that you called:\n" + SET_CURRENT_COMMAND;
|
|
|
+ errorMessage += MessageFormat.format("\nFurther, change the status of host_role_command with " +
|
|
|
+ "id {0} to COMPLETED", mostRecentUpgrade.getId());
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (null != errorMessage) {
|
|
|
+ LinkedHashSet<String> failedOn = new LinkedHashSet<String>();
|
|
|
+ failedOn.add(cluster.getClusterName());
|
|
|
+ prerequisiteCheck.setFailedOn(failedOn);
|
|
|
+ prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
|
|
|
+ prerequisiteCheck.setFailReason(errorMessage);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|