فهرست منبع

AMBARI-11728. Upgrade Ambari from 1.7 to Ambari 2.0. I'm on HDP 2.2.0.0, but the version is not showing up in the Stacks and Versions page. (dlysnichenko)

Lisnichenko Dmitro 10 سال پیش
والد
کامیت
c4710db437

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

@@ -520,7 +520,7 @@ public class HeartBeatHandler {
         }
       }
 
-      //pass custom STAR, STOP and RESTART
+      //pass custom START, STOP and RESTART
       if (RoleCommand.ACTIONEXECUTE.toString().equals(report.getRoleCommand()) ||
          (RoleCommand.CUSTOM_COMMAND.toString().equals(report.getRoleCommand()) &&
          !("RESTART".equals(report.getCustomCommand()) ||

+ 18 - 1
ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java

@@ -96,6 +96,7 @@ import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.DesiredConfig;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.HostHealthStatus;
+import org.apache.ambari.server.state.HostState;
 import org.apache.ambari.server.state.MaintenanceState;
 import org.apache.ambari.server.state.RepositoryVersionState;
 import org.apache.ambari.server.state.SecurityType;
@@ -1249,6 +1250,7 @@ public class ClusterImpl implements Cluster {
       ClusterVersionEntity clusterVersion = clusterVersionDAO.findByClusterAndStackAndVersion(
           getClusterName(), stackId, repositoryVersion);
 
+      boolean performingInitialBootstrap = false;
       if (clusterVersion == null) {
         if (clusterVersionDAO.findByCluster(getClusterName()).isEmpty()) {
           // During an Ambari Upgrade from 1.7.0 -> 2.0.0, the Cluster Version
@@ -1256,6 +1258,7 @@ public class ClusterImpl implements Cluster {
           // This can still fail if the Repository Version has not yet been created,
           // which can happen if the first HostComponentState to trigger this method
           // cannot advertise a version.
+          performingInitialBootstrap = true;
           createClusterVersionInternal(
               stackId,
               repositoryVersion,
@@ -1321,6 +1324,14 @@ public class ClusterImpl implements Cluster {
       // Otherwise, operations are still in progress.
       for (String hostname : hostsWithoutHostVersion) {
         HostEntity hostEntity = hostDAO.findByName(hostname);
+
+        // During initial bootstrap, unhealthy hosts are ignored
+        // so we boostrap the CURRENT version anyway
+        if (performingInitialBootstrap &&
+                hostEntity.getHostStateEntity().getCurrentState() != HostState.HEALTHY) {
+          continue;
+        }
+
         final Collection<HostComponentStateEntity> allHostComponents = hostEntity.getHostComponentStateEntities();
 
         for (HostComponentStateEntity hostComponentStateEntity : allHostComponents) {
@@ -1379,7 +1390,12 @@ public class ClusterImpl implements Cluster {
     hostTransitionStateWriteLock.lock();
     try {
       // Create one if it doesn't already exist. It will be possible to make further transitions below.
+      boolean performingInitialBootstrap = false;
       if (hostVersionEntity == null) {
+        if (hostVersionDAO.findByClusterAndHost(getClusterName(), host.getHostName()).isEmpty()) {
+          // That is an initial bootstrap
+          performingInitialBootstrap = true;
+        }
         hostVersionEntity = new HostVersionEntity(host, repositoryVersion, RepositoryVersionState.UPGRADING);
         hostVersionDAO.create(hostVersionEntity);
       }
@@ -1390,7 +1406,8 @@ public class ClusterImpl implements Cluster {
 
       if (!isCurrentPresent) {
         // Transition from UPGRADING -> CURRENT. This is allowed because Host Version Entity is bootstrapped in an UPGRADING state.
-        if (hostSummary.isUpgradeFinished() && hostVersionEntity.getState().equals(RepositoryVersionState.UPGRADING)) {
+        // Alternatively, transition to CURRENT during initial bootstrap if at least one host component advertised a version
+        if (hostSummary.isUpgradeFinished() && hostVersionEntity.getState().equals(RepositoryVersionState.UPGRADING) || performingInitialBootstrap) {
           hostVersionEntity.setState(RepositoryVersionState.CURRENT);
           hostVersionDAO.merge(hostVersionEntity);
         }

+ 68 - 0
ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java

@@ -371,6 +371,11 @@ public class ClusterTest {
       clusters.mapHostToCluster(hostName, clusterName);
     }
 
+    // Transition all hosts to HEALTHY state
+    for (Host host : cluster.getHosts()) {
+      host.setState(HostState.HEALTHY);
+    }
+
     // Add Services
     Service s1 = serviceFactory.createNew(cluster, "HDFS");
     Service s2 = serviceFactory.createNew(cluster, "ZOOKEEPER");
@@ -1824,6 +1829,69 @@ public class ClusterTest {
     }
   }
 
+  @Test
+  public void testBootstrapHostVersion() throws Exception {
+    String clusterName = "c1";
+    String v1 = "2.2.0-123";
+    StackId stackId = new StackId("HDP-2.2.0");
+
+    Map<String, String> hostAttributes = new HashMap<String, String>();
+    hostAttributes.put("os_family", "redhat");
+    hostAttributes.put("os_release_version", "5.9");
+
+    Cluster cluster = createClusterForRU(clusterName, stackId, hostAttributes);
+
+    // Make one host unhealthy
+    Host deadHost = cluster.getHosts().iterator().next();
+    deadHost.setState(HostState.UNHEALTHY);
+
+    // Begin bootstrap by starting to advertise versions
+    // Set the version for the HostComponentState objects
+    int versionedComponentCount = 0;
+    List<HostComponentStateEntity> hostComponentStates = hostComponentStateDAO.findAll();
+    for(int i = 0; i < hostComponentStates.size(); i++) {
+      HostComponentStateEntity hce = hostComponentStates.get(i);
+      ComponentInfo compInfo = metaInfo.getComponent(
+              stackId.getStackName(), stackId.getStackVersion(),
+              hce.getServiceName(),
+              hce.getComponentName());
+
+      if (hce.getHostName().equals(deadHost.getHostName())) {
+        continue; // Skip setting version
+      }
+
+      if (compInfo.isVersionAdvertised()) {
+        hce.setVersion(v1);
+        hostComponentStateDAO.merge(hce);
+        versionedComponentCount++;
+      }
+
+      // Simulate the StackVersionListener during the installation of the first Stack Version
+      Service svc = cluster.getService(hce.getServiceName());
+      ServiceComponent svcComp = svc.getServiceComponent(hce.getComponentName());
+      ServiceComponentHost scHost = svcComp.getServiceComponentHost(hce.getHostName());
+
+      scHost.recalculateHostVersionState();
+      cluster.recalculateClusterVersionState(cluster.getDesiredStackVersion(),
+              v1);
+
+      Collection<ClusterVersionEntity> clusterVersions = cluster.getAllClusterVersions();
+
+      if (versionedComponentCount > 0) {
+        // On the first component with a version, a RepoVersion should have been created
+        RepositoryVersionEntity repositoryVersion = repositoryVersionDAO.findByStackAndVersion(stackId, v1);
+        Assert.assertNotNull(repositoryVersion);
+        Assert.assertTrue(clusterVersions != null && clusterVersions.size() == 1);
+
+        // Since host 2 is dead, and host 3 contains only components that dont report a version,
+        // cluster version transitions to CURRENT after first component on host 1 reports it's version
+        if (versionedComponentCount == 1 && i < (hostComponentStates.size() - 1)) {
+          Assert.assertEquals(clusterVersions.iterator().next().getState(), RepositoryVersionState.CURRENT);
+        }
+      }
+    }
+  }
+
   @Test
   public void testTransitionNonReportableHost() throws Exception {
     StackId stackId = new StackId("HDP-2.0.5");