You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by am...@apache.org on 2018/06/26 16:12:10 UTC

[ambari] branch trunk updated: [AMBARI-24168]. Express Upgrade Blocked on Missing OS in repo_version (… (#1602)

This is an automated email from the ASF dual-hosted git repository.

amagyar pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 5b08b29  [AMBARI-24168]. Express Upgrade Blocked on Missing OS in repo_version (… (#1602)
5b08b29 is described below

commit 5b08b29802d334cc921d81ffe7b60456de497271
Author: Attila Magyar <m....@gmail.com>
AuthorDate: Tue Jun 26 18:12:06 2018 +0200

    [AMBARI-24168]. Express Upgrade Blocked on Missing OS in repo_version (… (#1602)
    
    * AMBARI-24168. Express Upgrade Blocked on Missing OS in repo_version (amagyar)
    
    * AMBARI-24168. Express Upgrade Blocked on Missing OS in repo_version (amagyar)
    
    * AMBARI-24168. Express Upgrade Blocked on Missing OS in repo_version (amagyar)
---
 .../ambari/server/checks/CheckDescription.java     |  11 +-
 .../server/checks/MissingOsInRepoVersionCheck.java | 101 +++++++++++++++
 .../checks/MissingOsInRepoVersionCheckTest.java    | 140 +++++++++++++++++++++
 3 files changed, 251 insertions(+), 1 deletion(-)

diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
index f19b957..5163dab 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
@@ -28,7 +28,6 @@ import com.google.common.collect.ImmutableMap;
  * done for Stack Upgrades.
  */
 public class CheckDescription {
-
   public static CheckDescription CLIENT_RETRY = new CheckDescription("CLIENT_RETRY",
     PrereqCheckType.SERVICE,
     "Client Retry Properties",
@@ -400,6 +399,16 @@ public class CheckDescription {
                   "This is needed so the KDC administrator credential may be stored long enough to ensure it will be around if needed during the upgrade process.")
           .build());
 
+
+  public static final CheckDescription MISSING_OS_IN_REPO_VERSION = new CheckDescription("MISSING_OS_IN_REPO_VERSION",
+    PrereqCheckType.CLUSTER,
+    "Missing OS in repository version.",
+    new ImmutableMap.Builder<String, String>()
+      .put(MissingOsInRepoVersionCheck.SOURCE_OS, "The source version must have an entry for each OS type in the cluster")
+      .put(MissingOsInRepoVersionCheck.TARGET_OS, "The target version must have an entry for each OS type in the cluster")
+      .build());
+
+
   private String m_name;
   private PrereqCheckType m_type;
   private String m_description;
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/MissingOsInRepoVersionCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/MissingOsInRepoVersionCheck.java
new file mode 100644
index 0000000..14f27b9
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/MissingOsInRepoVersionCheck.java
@@ -0,0 +1,101 @@
+/*
+ *
+ *  * 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 static java.util.stream.Collectors.toSet;
+import static org.apache.ambari.server.state.MaintenanceState.OFF;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.PrereqCheckRequest;
+import org.apache.ambari.server.orm.entities.RepoOsEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.stack.PrereqCheckStatus;
+import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
+
+import com.google.inject.Singleton;
+
+/**
+ * This checks if the source and target version has an entry for each OS type in the cluster.
+ */
+@Singleton
+@UpgradeCheck(
+  group = UpgradeCheckGroup.REPOSITORY_VERSION,
+  required = { UpgradeType.NON_ROLLING, UpgradeType.ROLLING })
+public class MissingOsInRepoVersionCheck extends AbstractCheckDescriptor {
+  public static final String SOURCE_OS = "source_os";
+  public static final String TARGET_OS = "target_os";
+
+  public MissingOsInRepoVersionCheck() {
+    super(CheckDescription.MISSING_OS_IN_REPO_VERSION);
+  }
+
+  @Override
+  public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException {
+    Set<String> osFamiliesInCluster = osFamiliesInCluster(cluster(prerequisiteCheck));
+    if (!targetOsFamilies(request).containsAll(osFamiliesInCluster)) {
+      prerequisiteCheck.setFailReason(getFailReason(TARGET_OS, prerequisiteCheck, request));
+      prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
+      prerequisiteCheck.setFailedOn(new LinkedHashSet<>(osFamiliesInCluster));
+    } else if (!sourceOsFamilies(request).containsAll(osFamiliesInCluster)) {
+      prerequisiteCheck.setFailReason(getFailReason(SOURCE_OS, prerequisiteCheck, request));
+      prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
+      prerequisiteCheck.setFailedOn(new LinkedHashSet<>(osFamiliesInCluster));
+    }
+  }
+
+  private Cluster cluster(PrerequisiteCheck prerequisiteCheck) throws AmbariException {
+    return clustersProvider.get().getCluster(prerequisiteCheck.getClusterName());
+  }
+
+  /**
+   * @return set of each os family in the cluster, excluding hosts which are in maintenance state
+   */
+  private Set<String> osFamiliesInCluster(Cluster cluster) {
+    return cluster.getHosts().stream()
+      .filter(host -> host.getMaintenanceState(cluster.getClusterId()) == OFF)
+      .map(Host::getOsFamily)
+      .collect(toSet());
+  }
+
+  /**
+   * @return set of each os family in the source stack
+   */
+  private Set<String> sourceOsFamilies(PrereqCheckRequest request) throws AmbariException {
+    return ambariMetaInfo.get().getStack(request.getSourceStackId()).getRepositoriesByOs().keySet();
+  }
+
+  /**
+   * @return set of each os family in the target repository
+   */
+  private Set<String> targetOsFamilies(PrereqCheckRequest request) {
+    return request
+      .getTargetRepositoryVersion()
+      .getRepoOsEntities()
+      .stream()
+      .map(RepoOsEntity::getFamily)
+      .collect(toSet());
+  }
+}
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/MissingOsInRepoVersionCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/MissingOsInRepoVersionCheckTest.java
new file mode 100644
index 0000000..4498d74
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/MissingOsInRepoVersionCheckTest.java
@@ -0,0 +1,140 @@
+/*
+ *
+ *  * 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 static java.util.Collections.singleton;
+import static java.util.Collections.singletonList;
+import static org.apache.ambari.server.state.MaintenanceState.OFF;
+import static org.easymock.EasyMock.anyInt;
+import static org.easymock.EasyMock.expect;
+import static org.junit.Assert.assertEquals;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.controller.PrereqCheckRequest;
+import org.apache.ambari.server.orm.entities.RepoOsEntity;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.RepositoryInfo;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.stack.PrereqCheckStatus;
+import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import org.easymock.EasyMockRunner;
+import org.easymock.EasyMockSupport;
+import org.easymock.Mock;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(EasyMockRunner.class)
+public class MissingOsInRepoVersionCheckTest extends EasyMockSupport {
+  public static final String CLUSTER_NAME = "cluster";
+  public static final StackId SOURCE_STACK = new StackId("HDP-2.6");
+  public static final String OS_FAMILY_IN_CLUSTER = "centos7";
+  private MissingOsInRepoVersionCheck prerequisite;
+  @Mock
+  private Clusters clusters;
+  @Mock
+  private Cluster cluster;
+  @Mock
+  private Host host;
+  @Mock
+  private AmbariMetaInfo ambariMetaInfo;
+  private PrerequisiteCheck check;
+
+  @Before
+  public void setUp() throws Exception {
+    prerequisite = new MissingOsInRepoVersionCheck();
+    prerequisite.clustersProvider = () -> clusters;
+    prerequisite.ambariMetaInfo = () -> ambariMetaInfo;
+    check = new PrerequisiteCheck(null, CLUSTER_NAME);
+    expect(clusters.getCluster(CLUSTER_NAME)).andReturn(cluster).anyTimes();
+    expect(cluster.getHosts()).andReturn(singleton(host)).anyTimes();
+    expect(cluster.getClusterId()).andReturn(1l).anyTimes();
+    expect(host.getOsFamily()).andReturn(OS_FAMILY_IN_CLUSTER).anyTimes();
+    expect(host.getMaintenanceState(anyInt())).andReturn(OFF).anyTimes();
+  }
+
+  @Test
+  public void testSuccessWhenOsExistsBothInTargetAndSource() throws Exception {
+    sourceStackRepoIs(OS_FAMILY_IN_CLUSTER);
+    replayAll();
+    performPrerequisite(request(targetRepo(OS_FAMILY_IN_CLUSTER)));
+    verifyAll();
+    assertEquals(PrereqCheckStatus.PASS, check.getStatus());
+  }
+
+  @Test
+  public void testFailsWhenOsDoesntExistInSource() throws Exception {
+    sourceStackRepoIs("different-os");
+    replayAll();
+    performPrerequisite(request(targetRepo(OS_FAMILY_IN_CLUSTER)));
+    assertEquals(PrereqCheckStatus.FAIL, check.getStatus());
+    verifyAll();
+  }
+
+  @Test
+  public void testFailsWhenOsDoesntExistInTarget() throws Exception {
+    sourceStackRepoIs(OS_FAMILY_IN_CLUSTER);
+    replayAll();
+    performPrerequisite(request(targetRepo("different-os")));
+    assertEquals(PrereqCheckStatus.FAIL, check.getStatus());
+    verifyAll();
+  }
+
+  private void sourceStackRepoIs(String osFamily) throws AmbariException {
+    expect(ambariMetaInfo.getStack(SOURCE_STACK)).andReturn(stackInfo(repoInfo(osFamily))).anyTimes();
+  }
+
+  private StackInfo stackInfo(RepositoryInfo repositoryInfo) {
+    StackInfo stackInfo = new StackInfo();
+    stackInfo.getRepositories().add(repositoryInfo);
+    return stackInfo;
+  }
+
+  private RepositoryInfo repoInfo(String osType) {
+    RepositoryInfo repo = new RepositoryInfo();
+    repo.setOsType(osType);
+    return repo;
+  }
+
+  private PrereqCheckRequest request(RepositoryVersionEntity targetRepo) {
+    PrereqCheckRequest request = new PrereqCheckRequest(CLUSTER_NAME);
+    request.setSourceStackId(SOURCE_STACK);
+    request.setTargetRepositoryVersion(targetRepo);
+    return request;
+  }
+
+  private RepositoryVersionEntity targetRepo(String osFamilyInCluster) {
+    RepositoryVersionEntity targetRepo = new RepositoryVersionEntity();
+    RepoOsEntity osEntity = new RepoOsEntity();
+    osEntity.setFamily(osFamilyInCluster);
+    targetRepo.addRepoOsEntities(singletonList(osEntity));
+    return targetRepo;
+  }
+
+  private void performPrerequisite(PrereqCheckRequest request) throws AmbariException {
+    prerequisite.perform(check, request);
+  }
+}
\ No newline at end of file