blob: 3a4467ff90c06110fad7b23ffba152c5e2cf457a [file] [log] [blame]
/*
* 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.getFromVersion())) {
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);
}
}
}