Skip to content

Commit

Permalink
Merge branch 'HDDS-3698-nonrolling-upgrade' into HDDS-5109
Browse files Browse the repository at this point in the history
* HDDS-3698-nonrolling-upgrade:
  HDDS-5244. Allow multiple OM request versions to be supported at same layout version. (apache#2265)
  HDDS-5138. Upgrade related RPC calls should be allowed only for admins. (apache#2217)
  HDDS-5226. Do not fail SCM HA pre-finalize validation if SCM HA was already being used. (apache#2257)

Conflicts:
    hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerStateMachine.java
  • Loading branch information
errose28 committed May 27, 2021
2 parents e6f0fa7 + 92b5106 commit a814475
Show file tree
Hide file tree
Showing 26 changed files with 529 additions and 200 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/post-commit.yml
Expand Up @@ -118,7 +118,7 @@ jobs:
acceptance:
needs: compile
runs-on: ubuntu-18.04
timeout-minutes: 120
timeout-minutes: 120 # Todo HDDS-5270
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
strategy:
matrix:
Expand Down Expand Up @@ -163,7 +163,7 @@ jobs:
continue-on-error: true
integration:
runs-on: ubuntu-18.04
timeout-minutes: 100
timeout-minutes: 120
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
strategy:
matrix:
Expand Down
Expand Up @@ -667,13 +667,33 @@ public boolean getReplicationManagerStatus() {
@Override
public StatusAndMessages finalizeScmUpgrade(String upgradeClientID) throws
IOException {
// check admin authorization
String remoteUser = getRpcRemoteUsername();
try {
getScm().checkAdminAccess(remoteUser);
} catch (IOException e) {
LOG.error("Authorization failed for finalize scm upgrade", e);
throw e;
}
return scm.finalizeUpgrade(upgradeClientID);
}

@Override
public StatusAndMessages queryUpgradeFinalizationProgress(
String upgradeClientID, boolean force, boolean readonly)
throws IOException {
throws IOException {
if (!readonly) {
// check admin authorization
String remoteUser = getRpcRemoteUsername();
try {
getScm().checkAdminAccess(remoteUser);
} catch (IOException e) {
LOG.error("Authorization failed for query scm upgrade finalization " +
"progress", e);
throw e;
}
}

return scm.queryUpgradeFinalizationProgress(upgradeClientID, force,
readonly);
}
Expand All @@ -697,7 +717,7 @@ public List<HddsProtos.DatanodeUsageInfoProto> getDatanodeUsageInfo(
try {
getScm().checkAdminAccess(remoteUser);
} catch (IOException e) {
LOG.error("Authorisation failed", e);
LOG.error("Authorization failed", e);
throw e;
}

Expand Down Expand Up @@ -765,7 +785,7 @@ public List<HddsProtos.DatanodeUsageInfoProto> getDatanodeUsageInfo(
try {
getScm().checkAdminAccess(remoteUser);
} catch (IOException e) {
LOG.error("Authorisation failed", e);
LOG.error("Authorization failed", e);
throw e;
}

Expand Down
Expand Up @@ -51,6 +51,7 @@
import org.apache.hadoop.hdds.scm.ha.SCMHAUtils;
import org.apache.hadoop.hdds.scm.ha.SequenceIdGenerator;
import org.apache.hadoop.hdds.scm.ScmInfo;
import org.apache.hadoop.hdds.scm.server.upgrade.ScmHAUnfinalizedStateValidationAction;
import org.apache.hadoop.hdds.security.x509.certificate.authority.CertificateStore;
import org.apache.hadoop.hdds.security.x509.certificate.authority.PKIProfiles.DefaultCAProfile;
import org.apache.hadoop.hdds.security.x509.certificate.authority.PKIProfiles.DefaultProfile;
Expand Down Expand Up @@ -962,6 +963,11 @@ public static boolean scmInit(OzoneConfiguration conf,
return false;
}
} else {
// If SCM HA was not being used before pre-finalize, and is being used
// when the cluster is pre-finalized for the SCM HA feature, init
// should fail.
ScmHAUnfinalizedStateValidationAction.checkScmHA(conf, scmStorageConfig);

clusterId = scmStorageConfig.getClusterID();
final boolean isSCMHAEnabled = scmStorageConfig.isSCMHAEnabled();
if (SCMHAUtils.isSCMHAEnabled(conf) && !isSCMHAEnabled) {
Expand Down Expand Up @@ -1158,6 +1164,8 @@ public String getDatanodeRpcPort() {
*/
@Override
public void start() throws IOException {
upgradeFinalizer.runPrefinalizeStateActions(scmStorageConfig, this);

if (LOG.isInfoEnabled()) {
LOG.info(buildRpcServerStartMessage(
"StorageContainerLocationProtocol RPC server",
Expand All @@ -1169,8 +1177,6 @@ public void start() throws IOException {
ms = HddsServerUtil
.initializeMetrics(configuration, "StorageContainerManager");

upgradeFinalizer.runPrefinalizeStateActions(scmStorageConfig, this);

commandWatcherLeaseManager.start();
getClientProtocolServer().start();

Expand Down
Expand Up @@ -22,26 +22,49 @@
import static org.apache.hadoop.ozone.upgrade.LayoutFeature.UpgradeActionType.VALIDATE_IN_PREFINALIZE;
import static org.apache.hadoop.ozone.upgrade.UpgradeActionHdds.Component.SCM;

import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.hdds.scm.ScmConfigKeys;
import org.apache.hadoop.hdds.scm.ha.SCMHAUtils;
import org.apache.hadoop.hdds.scm.server.SCMStorageConfig;
import org.apache.hadoop.hdds.scm.server.StorageContainerManager;
import org.apache.hadoop.hdds.upgrade.HDDSLayoutVersionManager;
import org.apache.hadoop.hdds.upgrade.HDDSUpgradeAction;
import org.apache.hadoop.ozone.upgrade.UpgradeActionHdds;
import org.apache.hadoop.ozone.upgrade.UpgradeException;

import java.io.IOException;

/**
* Checks that SCM HA cannot be used in a pre-finalized cluster, unless it
* was already being used before this action was run.
*/
@UpgradeActionHdds(feature = SCM_HA, component = SCM,
type = VALIDATE_IN_PREFINALIZE)
public class ScmHAUnfinalizedStateValidationAction
implements HDDSUpgradeAction<StorageContainerManager> {

@Override
public void execute(StorageContainerManager scm) throws Exception {
boolean isHAEnabled =
scm.getConfiguration().getBoolean(ScmConfigKeys.OZONE_SCM_HA_ENABLE_KEY,
ScmConfigKeys.OZONE_SCM_HA_ENABLE_DEFAULT);
public void execute(StorageContainerManager scm) throws IOException {
checkScmHA(scm.getConfiguration(), scm.getScmStorageConfig());
}

/**
* Allows checking that SCM HA is not enabled while pre-finalized in both
* scm init and the upgrade action run on start.
*/
public static void checkScmHA(OzoneConfiguration conf,
SCMStorageConfig storageConf) throws IOException {

// Since this action may need to be called outside the upgrade framework
// during init, it needs to check for pre-finalized state.
HDDSLayoutVersionManager versionManager =
new HDDSLayoutVersionManager(storageConf.getLayoutVersion());

if (isHAEnabled) {
if (versionManager.needsFinalization() &&
SCMHAUtils.isSCMHAEnabled(conf) &&
!storageConf.isSCMHAEnabled()) {
throw new UpgradeException(String.format("Configuration %s cannot be " +
"used until SCM upgrade has been finalized",
"used until SCM upgrade has been finalized",
ScmConfigKeys.OZONE_SCM_HA_ENABLE_KEY),
UpgradeException.ResultCodes.PREFINALIZE_ACTION_VALIDATION_FAILED);
}
Expand Down

This file was deleted.

@@ -0,0 +1,128 @@
/*
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.hadoop.hdds.scm.upgrade;

import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.hdds.scm.ScmConfig;
import org.apache.hadoop.hdds.scm.ScmConfigKeys;
import org.apache.hadoop.hdds.scm.TestUtils;
import org.apache.hadoop.hdds.scm.server.StorageContainerManager;
import org.apache.hadoop.hdds.upgrade.HDDSLayoutFeature;
import org.apache.hadoop.ozone.OzoneConfigKeys;
import org.apache.hadoop.ozone.upgrade.UpgradeException;
import org.apache.hadoop.ozone.upgrade.UpgradeFinalizer;
import org.apache.hadoop.test.LambdaTestUtils;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.UUID;

/**
* Tests that the SCM HA pre-finalize validation action is only triggered in
* pre-finalize startup if SCM HA was not already being used in the cluster,
* but has been turned on after.
*
* Starting a new SCM HA cluster finalized should not trigger the action. This
* is tested by all other tests that use SCM HA from the latest version of the
* code.
*
* Starting a new cluster finalized without SCM HA enabled should not trigger
* the action. This is tested by all other tests that run non-HA clusters.
*/
@RunWith(Parameterized.class)
public class TestSCMHAUnfinalizedStateValidationAction {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();

private final boolean haEnabledBefore;
private final boolean haEnabledPreFinalized;
private final boolean shouldFail;
private final String dataPath;
private static final String CLUSTER_ID = UUID.randomUUID().toString();

@Parameterized.Parameters(name = "haEnabledBefore={0} " +
"haEnabledPreFinalized={1}")
public static Collection<Object[]> cases() {
List<Object[]> params = new ArrayList<>();

for (boolean haBefore: Arrays.asList(true, false)) {
for (boolean haAfter: Arrays.asList(true, false)) {
params.add(new Object[]{haBefore, haAfter});
}
}

return params;
}

public TestSCMHAUnfinalizedStateValidationAction(
boolean haEnabledBefore, boolean haEnabledPreFinalized)
throws Exception {
this.haEnabledBefore = haEnabledBefore;
this.haEnabledPreFinalized = haEnabledPreFinalized;

shouldFail = !this.haEnabledBefore && this.haEnabledPreFinalized;

temporaryFolder.create();
dataPath = temporaryFolder.newFolder().getAbsolutePath();
}

@Test
public void testUpgrade() throws Exception {
// Write version file for original version.
OzoneConfiguration conf = new OzoneConfiguration();
conf.setInt(ScmConfig.ConfigStrings.HDDS_SCM_INIT_DEFAULT_LAYOUT_VERSION,
HDDSLayoutFeature.INITIAL_VERSION.layoutVersion());
conf.setBoolean(ScmConfigKeys.OZONE_SCM_HA_ENABLE_KEY, haEnabledBefore);
conf.set(ScmConfigKeys.OZONE_SCM_DB_DIRS, dataPath);
conf.set(OzoneConfigKeys.OZONE_METADATA_DIRS, dataPath);
// This init should always succeed, since SCM is not pre-finalized yet.
boolean initResult1 = StorageContainerManager.scmInit(conf, CLUSTER_ID);
Assert.assertTrue(initResult1);

// Set up new pre-finalized SCM.
conf.setBoolean(ScmConfigKeys.OZONE_SCM_HA_ENABLE_KEY,
haEnabledPreFinalized);
StorageContainerManager scm = TestUtils.getScm(conf);
Assert.assertEquals(UpgradeFinalizer.Status.FINALIZATION_REQUIRED,
scm.getUpgradeFinalizer().getStatus());

if (shouldFail) {
// Start on its own should fail.
LambdaTestUtils.intercept(UpgradeException.class, scm::start);

// Init followed by start should both fail.
// Init is not necessary here, but is allowed to be run.
LambdaTestUtils.intercept(UpgradeException.class,
() -> StorageContainerManager.scmInit(conf, CLUSTER_ID));
LambdaTestUtils.intercept(UpgradeException.class, scm::start);
} else {
boolean initResult2 = StorageContainerManager.scmInit(conf, CLUSTER_ID);
Assert.assertTrue(initResult2);
scm.start();
scm.stop();
}
}
}
4 changes: 0 additions & 4 deletions hadoop-ozone/dist/src/main/compose/ozone-ha/test.sh
Expand Up @@ -33,10 +33,6 @@ execute_robot_test ${SCM} basic/links.robot
execute_robot_test ${SCM} s3
execute_robot_test ${SCM} freon

# prepare test should be the last test to run, until a cancel prepare test is
# added. (TODO)
execute_robot_test ${SCM} omha/om-prepare.robot

stop_docker_env

generate_report
Expand Up @@ -161,5 +161,4 @@ public boolean checkAccess(IOzoneObj ozoneObject, RequestContext context) {
return TestOmAcls.aclAllow;
}
}

}

0 comments on commit a814475

Please sign in to comment.