Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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.hadoop.ozone.upgrade;

import java.util.Map;
import org.apache.hadoop.hdds.ComponentVersion;

/**
* Supplies upgrade actions keyed by {@link ComponentVersion}. Implementations typically perform classpath scanning or
* return a fixed map for tests. The component version manager decides when each action is invoked.
*
* @param <A> concrete upgrade action type (for example OM-specific or HDDS-specific)
*/
@FunctionalInterface
public interface ComponentUpgradeActionProvider<A> {

/**
* Returns all upgrade actions from this provider, keyed by component version.
* <p>
* Implementations must return a newly allocated map on each call; the caller may retain and use it directly.
*/
Map<ComponentVersion, A> load();
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,8 @@ public String toString() {
public enum ResultCodes {
OK,
INVALID_REQUEST,
UPDATE_LAYOUT_VERSION_FAILED,
LAYOUT_FEATURE_FINALIZATION_FAILED,
PREFINALIZE_ACTION_VALIDATION_FAILED,
FIRST_UPGRADE_START_ACTION_FAILED,
PREFINALIZE_VALIDATION_FAILED;
APPARENT_VERSION_UPDATE_FAILED,
UPGRADE_FINALIZATION_FAILED,
FINALIZE_UPGRADE_ACTION_FAILED,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,19 @@ public final class UpgradeFinalization {
);

/**
* Default message to provide when the service is in ALREADY_FINALIZED state.
* Returned from finalize upgrade commands when finalization is not required.
*/
public static final StatusAndMessages FINALIZED_MSG = new StatusAndMessages(
Status.ALREADY_FINALIZED, Collections.emptyList()
);

/**
* Returned from progress/status queries when finalization is not required.
*/
public static final StatusAndMessages FINALIZATION_DONE_MSG = new StatusAndMessages(
Status.FINALIZATION_DONE, Collections.emptyList()
);

/**
* Represents the current state in which the service is with regards to
* finalization after an upgrade.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ private static DatanodeDetailsYaml getDatanodeDetailsYaml(
HDDSLayoutFeature layoutFeature
= f.getAnnotation(BelongsToHDDSLayoutVersion.class).value();
if (layoutFeature.layoutVersion() >
datanodeLayoutStorage.getLayoutVersion()) {
datanodeLayoutStorage.getApparentVersion()) {
continue;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public DatanodeStateMachine(HddsDatanodeService hddsDatanodeService,
datanodeDetails.getUuidString());

layoutVersionManager = new HDDSLayoutVersionManager(
layoutStorage.getLayoutVersion());
layoutStorage.getApparentVersion());
upgradeFinalizer = new DataNodeUpgradeFinalizer(layoutVersionManager);
VersionedDatanodeFeatures.initialize(layoutVersionManager);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public void finalizeLayoutFeature(LayoutFeature layoutFeature,
String msg = String.format("Failed to finalize datanode layout feature " +
"%s. It is not an HDDS Layout Feature.", layoutFeature);
throw new UpgradeException(msg,
UpgradeException.ResultCodes.LAYOUT_FEATURE_FINALIZATION_FAILED);
UpgradeException.ResultCodes.UPGRADE_FINALIZATION_FAILED);
}
}
}
10 changes: 4 additions & 6 deletions hadoop-hdds/docs/content/design/upgrade-dev-primer.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,11 @@ Downgrade to a lower version is allowed from the pre-finalized state. This invol
org.apache.hadoop.hdds.upgrade.HDDSLayoutFeature
Class to add a new layout feature being brought in. Layout version is typically 1 + last layout feature in that catalog.

## LayoutVersionManager
org.apache.hadoop.ozone.om.upgrade.OMLayoutVersionManager
org.apache.hadoop.hdds.upgrade.HDDSLayoutVersionManager
Every component carries an instance of this interface, which provides APIs to get runtime layout version, and if a feature is allowed based on that or not.
## Version management (OM vs HDDS)

The LayoutVersionManager interface carries an API that can be used to check if a feature is allowed in the current layout version.
org.apache.hadoop.ozone.upgrade.LayoutVersionManager#isAllowed(org.apache.hadoop.ozone.upgrade.LayoutFeature)
**Ozone Manager** uses [`org.apache.hadoop.ozone.om.upgrade.OMVersionManager`](https://github.com/apache/ozone/blob/master/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/upgrade/OMVersionManager.java) ([`org.apache.hadoop.ozone.upgrade.ComponentVersionManager`](https://github.com/apache/ozone/blob/master/hadoop-hdds/framework/src/main/java/org/apache/hadoop/ozone/upgrade/ComponentVersionManager.java)), with upgrade actions discovered via [`org.apache.hadoop.ozone.om.upgrade.OMUpgradeActionProvider`](https://github.com/apache/ozone/blob/master/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/upgrade/OMUpgradeActionProvider.java). It exposes apparent/software `ComponentVersion` and `isAllowed(ComponentVersion)` for gating.

**SCM / DataNode** continue to use [`org.apache.hadoop.hdds.upgrade.HDDSLayoutVersionManager`](https://github.com/apache/ozone/blob/master/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/upgrade/HDDSLayoutVersionManager.java) ([`org.apache.hadoop.ozone.upgrade.AbstractLayoutVersionManager`](https://github.com/apache/ozone/blob/master/hadoop-hdds/framework/src/main/java/org/apache/hadoop/ozone/upgrade/AbstractLayoutVersionManager.java)), which provides metadata/software layout integers and `isAllowed(LayoutFeature)`.

## @DisallowedUntilLayoutVersion Annotation
Method level annotation used to "disallow" an API if current layout version does not include the associated layout feature. Currently it is added only to the OM module, but can easily be moved down to a common module based on need on the HDDS layer.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,45 @@
import java.io.IOException;
import org.apache.hadoop.hdds.ComponentVersion;
import org.apache.hadoop.hdds.HDDSVersion;
import org.apache.hadoop.ozone.common.Storage;
import org.apache.hadoop.ozone.upgrade.ComponentVersionManager;
import org.apache.hadoop.ozone.upgrade.UpgradeException;

/**
* Component version manager for HDDS (Datanodes and SCM).
*/
public class HDDSVersionManager extends ComponentVersionManager {
public HDDSVersionManager(int serializedApparentVersion) throws IOException {
super(computeApparentVersion(serializedApparentVersion), HDDSVersion.SOFTWARE_VERSION);
public HDDSVersionManager(Storage storage) throws IOException {
super(storage, computeApparentVersion(storage.getApparentVersion()), HDDSVersion.SOFTWARE_VERSION);
}

/**
* If the apparent version stored on the disk is >= 100, it indicates the component has been finalized for the
* ZDU feature, and the apparent version corresponds to a version in {@link HDDSVersion}.
* If the apparent version stored on the disk is < 100, it indicates the component is not yet finalized for the
* ZDU feature, and the apparent version corresponds to a version in {@link HDDSLayoutFeature}.
* If the apparent version stored on the disk is &gt;= {@link HDDSVersion#ZDU} serialized, the apparent version is
* resolved via {@link HDDSVersion#deserialize(int)}. Values with no matching {@link HDDSVersion} fail startup with
* the persisted integer in the exception message.
* If the value is below that threshold, the apparent version is resolved as a {@link HDDSLayoutFeature}. Integers in
* the gap between the largest {@link HDDSLayoutFeature} and ZDU are not valid legacy layout values; startup fails
* with the persisted integer in the exception message.
*/
private static ComponentVersion computeApparentVersion(int serializedApparentVersion) {
if (serializedApparentVersion < HDDSVersion.ZDU.serialize()) {
return HDDSLayoutFeature.deserialize(serializedApparentVersion);
private static ComponentVersion computeApparentVersion(int serializedApparentVersion) throws IOException {
if (serializedApparentVersion >= HDDSVersion.ZDU.serialize()) {
HDDSVersion fromHdds = HDDSVersion.deserialize(serializedApparentVersion);
if (fromHdds != HDDSVersion.FUTURE_VERSION) {
return fromHdds;
}
} else {
return HDDSVersion.deserialize(serializedApparentVersion);
ComponentVersion fromLayout = HDDSLayoutFeature.deserialize(serializedApparentVersion);
if (fromLayout != null) {
return fromLayout;
}
}
throw new IOException("Initialization failed. Disk contains unknown apparent version " + serializedApparentVersion +
" for software version " + HDDSVersion.SOFTWARE_VERSION + ". Make sure this component was not downgraded" +
" after finalization");
}

// TODO HDDS-14826: Register upgrade actions based on annotations
@Override
protected void runUpgradeAction(ComponentVersion componentVersion) throws UpgradeException {
// TODO HDDS-14826: Register upgrade actions based on annotations

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: change to the ticket that'll do this

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, will update this in the next PR. I actually haven't made the Jiras for the HDDS updates yet.

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,20 +124,12 @@ public void setClusterId(String clusterId) throws IOException {
}
}

public int getLayoutVersion() {
return storageInfo.getLayoutVersion();
public int getApparentVersion() {
return storageInfo.getApparentVersion();
}

public void setLayoutVersion(int version) {
storageInfo.setLayoutVersion(version);
}

public void setFirstUpgradeActionLayoutVersion(int version) {
storageInfo.setFirstUpgradeActionLayoutVersion(version);
}

public int getFirstUpgradeActionLayoutVersion() {
return storageInfo.getFirstUpgradeActionLayoutVersion();
public void setApparentVersion(int version) {
storageInfo.setApparentVersion(version);
}

/**
Expand Down Expand Up @@ -288,8 +280,7 @@ public void persistCurrentState() throws IOException {
storageInfo.writeTo(getVersionFile());
}

protected static int getInitLayoutVersion(OzoneConfiguration conf,
String configKey,
protected static int getInitApparentVersion(OzoneConfiguration conf, String configKey,
IntSupplier defaultLvSupplier) {
int lV = conf.getInt(configKey, OZONE_INIT_DEFAULT_LAYOUT_VERSION_DEFAULT);
if (lV == OZONE_INIT_DEFAULT_LAYOUT_VERSION_DEFAULT) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,6 @@ public class StorageInfo {
*/
private static final String LAYOUT_VERSION = "layoutVersion";

private static final String FIRST_UPGRADE_ACTION_LAYOUT_VERSION =
"firstUpgradeActionLayoutVersion";

private static final int INVALID_LAYOUT_VERSION = -1;

/**
Expand Down Expand Up @@ -93,7 +90,7 @@ public StorageInfo(NodeType type, File propertiesFile)
verifyNodeType(type);
verifyClusterId();
verifyCreationTime();
verifyLayoutVersion();
verifyApparentVersion();
}

public NodeType getNodeType() {
Expand All @@ -112,15 +109,15 @@ public Long getCreationTime() {
return null;
}

public int getLayoutVersion() {
public int getApparentVersion() {
String layout = properties.getProperty(LAYOUT_VERSION);
if (layout != null) {
return Integer.parseInt(layout);
}
return 0;
}

private void verifyLayoutVersion() {
private void verifyApparentVersion() {
String layout = getProperty(LAYOUT_VERSION);
if (layout == null) {
LOG.warn("Found " + STORAGE_FILE_VERSION + " file without any layout " +
Expand All @@ -129,20 +126,6 @@ private void verifyLayoutVersion() {
}
}

public int getFirstUpgradeActionLayoutVersion() {
String upgradingTo =
properties.getProperty(FIRST_UPGRADE_ACTION_LAYOUT_VERSION);
if (upgradingTo != null) {
return Integer.parseInt(upgradingTo);
}
return INVALID_LAYOUT_VERSION;
}

public void setFirstUpgradeActionLayoutVersion(int layoutVersion) {
properties.setProperty(
FIRST_UPGRADE_ACTION_LAYOUT_VERSION, Integer.toString(layoutVersion));
}

public String getProperty(String key) {
return properties.getProperty(key);
}
Expand All @@ -159,7 +142,7 @@ public void setClusterId(String clusterId) {
properties.setProperty(CLUSTER_ID, clusterId);
}

public void setLayoutVersion(int version) {
public void setApparentVersion(int version) {
properties.setProperty(LAYOUT_VERSION, Integer.toString(version));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@

package org.apache.hadoop.ozone.upgrade;

import static org.apache.hadoop.ozone.upgrade.UpgradeException.ResultCodes.APPARENT_VERSION_UPDATE_FAILED;
import static org.apache.hadoop.ozone.upgrade.UpgradeException.ResultCodes.INVALID_REQUEST;
import static org.apache.hadoop.ozone.upgrade.UpgradeException.ResultCodes.LAYOUT_FEATURE_FINALIZATION_FAILED;
import static org.apache.hadoop.ozone.upgrade.UpgradeException.ResultCodes.UPDATE_LAYOUT_VERSION_FAILED;
import static org.apache.hadoop.ozone.upgrade.UpgradeException.ResultCodes.UPGRADE_FINALIZATION_FAILED;
import static org.apache.hadoop.ozone.upgrade.UpgradeFinalization.FINALIZATION_IN_PROGRESS_MSG;
import static org.apache.hadoop.ozone.upgrade.UpgradeFinalization.FINALIZATION_REQUIRED_MSG;
import static org.apache.hadoop.ozone.upgrade.UpgradeFinalization.FINALIZED_MSG;
Expand Down Expand Up @@ -291,11 +291,11 @@ protected void updateLayoutVersionInVersionFile(LayoutFeature feature,
}

private int currentStoredLayoutVersion(Storage config) {
return config.getLayoutVersion();
return config.getApparentVersion();
}

private void updateStorageLayoutVersion(int version, Storage config) {
config.setLayoutVersion(version);
config.setApparentVersion(version);
}

private void persistStorage(Storage config) throws IOException {
Expand Down Expand Up @@ -326,13 +326,13 @@ protected void logAndEmit(String msg) {
protected void logFinalizationFailureAndThrow(Exception e, String feature)
throws UpgradeException {
String msg = "Error during finalization of " + feature + ".";
logAndThrow(e, msg, LAYOUT_FEATURE_FINALIZATION_FAILED);
logAndThrow(e, msg, UPGRADE_FINALIZATION_FAILED);
}

private void logLayoutVersionUpdateFailureAndThrow(IOException e)
throws UpgradeException {
String msg = "Updating the LayoutVersion in the VERSION file failed.";
logAndThrow(e, msg, UPDATE_LAYOUT_VERSION_FAILED);
logAndThrow(e, msg, APPARENT_VERSION_UPDATE_FAILED);
}

private void logAndThrow(Exception e, String msg, ResultCodes resultCode)
Expand Down
Loading
Loading