-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Introduce minimumCompatibilityVersion to BuildVersion (ES-9378) #119101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
2039e5b
1ae13c2
8a983dd
0a7fa25
c562a84
93dbed6
38930fc
798e857
612ca86
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ | |
import org.apache.lucene.store.NativeFSLockFactory; | ||
import org.elasticsearch.Build; | ||
import org.elasticsearch.ElasticsearchException; | ||
import org.elasticsearch.Version; | ||
import org.elasticsearch.cluster.metadata.IndexMetadata; | ||
import org.elasticsearch.cluster.node.DiscoveryNode; | ||
import org.elasticsearch.cluster.node.DiscoveryNodeRole; | ||
|
@@ -86,8 +87,6 @@ | |
import java.util.function.Consumer; | ||
import java.util.function.Function; | ||
import java.util.function.Predicate; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
|
@@ -525,7 +524,7 @@ static void checkForIndexCompatibility(Logger logger, DataPath... dataPaths) thr | |
logger.info("oldest index version recorded in NodeMetadata {}", metadata.oldestIndexVersion()); | ||
|
||
if (metadata.oldestIndexVersion().before(IndexVersions.MINIMUM_COMPATIBLE)) { | ||
String bestDowngradeVersion = getBestDowngradeVersion(metadata.previousNodeVersion().toString()); | ||
BuildVersion bestDowngradeVersion = getBestDowngradeVersion(metadata.previousNodeVersion()); | ||
throw new IllegalStateException( | ||
"Cannot start this node because it holds metadata for indices with version [" | ||
+ metadata.oldestIndexVersion().toReleaseVersion() | ||
|
@@ -1504,28 +1503,17 @@ private static void tryWriteTempFile(Path path) throws IOException { | |
/** | ||
* Get a useful version string to direct a user's downgrade operation | ||
* | ||
* <p>If a user is trying to install 8.0 but has incompatible indices, the user should | ||
* downgrade to 7.17.x. We return 7.17.0, unless the user is trying to upgrade from | ||
* a 7.17.x release, in which case we return the last installed version. | ||
* <p>If a user is trying to install 9.0 (current major) but has incompatible indices, the user should | ||
* downgrade to 8.18.x (last minor of the previous major). We return 8.18.0, unless the user is trying to upgrade from | ||
* a 8.18.x release, in which case we return the last installed version. | ||
* @return Version to downgrade to | ||
*/ | ||
// visible for testing | ||
static String getBestDowngradeVersion(String previousNodeVersion) { | ||
// this method should only be called in the context of an upgrade to 8.x | ||
assert Build.current().version().startsWith("9.") == false; | ||
Pattern pattern = Pattern.compile("^7\\.(\\d+)\\.\\d+$"); | ||
Matcher matcher = pattern.matcher(previousNodeVersion); | ||
if (matcher.matches()) { | ||
try { | ||
int minorVersion = Integer.parseInt(matcher.group(1)); | ||
if (minorVersion >= 17) { | ||
return previousNodeVersion; | ||
} | ||
} catch (NumberFormatException e) { | ||
// continue and return default | ||
} | ||
static BuildVersion getBestDowngradeVersion(BuildVersion previousNodeVersion) { | ||
if (previousNodeVersion.onOrAfterMinimumCompatible()) { | ||
return previousNodeVersion; | ||
} | ||
return "7.17.0"; | ||
return BuildVersion.fromVersionId(Version.CURRENT.minimumCompatibilityVersion().id); | ||
|
||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,12 +9,11 @@ | |
package org.elasticsearch.env; | ||
|
||
import org.elasticsearch.Build; | ||
import org.elasticsearch.ElasticsearchException; | ||
import org.elasticsearch.Version; | ||
import org.elasticsearch.core.Tuple; | ||
import org.elasticsearch.core.UpdateForV9; | ||
import org.elasticsearch.gateway.MetadataStateFormat; | ||
import org.elasticsearch.index.IndexVersion; | ||
import org.elasticsearch.index.IndexVersions; | ||
import org.elasticsearch.test.ESTestCase; | ||
import org.elasticsearch.test.EqualsHashCodeTestUtils; | ||
import org.elasticsearch.test.VersionUtils; | ||
|
@@ -28,6 +27,7 @@ | |
import static org.hamcrest.Matchers.allOf; | ||
import static org.hamcrest.Matchers.endsWith; | ||
import static org.hamcrest.Matchers.equalTo; | ||
import static org.hamcrest.Matchers.instanceOf; | ||
import static org.hamcrest.Matchers.notNullValue; | ||
import static org.hamcrest.Matchers.startsWith; | ||
|
||
|
@@ -80,22 +80,20 @@ public void testEqualsHashcodeSerialization() { | |
); | ||
} | ||
|
||
@UpdateForV9(owner = UpdateForV9.Owner.CORE_INFRA) | ||
@AwaitsFix(bugUrl = "as mentioned in the comment below, the behavior here is changing for 9.0 so this test needs updating") | ||
public void testReadsFormatWithoutVersion() throws IOException { | ||
// the behaviour tested here is only appropriate if the current version is compatible with versions 7 and earlier | ||
assertTrue(IndexVersions.MINIMUM_COMPATIBLE.onOrBefore(IndexVersions.V_7_0_0)); | ||
// when the current version is incompatible with version 7, the behaviour should change to reject files like the given resource | ||
// which do not have the version field | ||
|
||
public void testFailsToReadFormatWithoutVersion() throws IOException { | ||
final Path tempDir = createTempDir(); | ||
final Path stateDir = Files.createDirectory(tempDir.resolve(MetadataStateFormat.STATE_DIR_NAME)); | ||
final InputStream resource = this.getClass().getResourceAsStream("testReadsFormatWithoutVersion.binary"); | ||
assertThat(resource, notNullValue()); | ||
Files.copy(resource, stateDir.resolve(NodeMetadata.FORMAT.getStateFileName(between(0, Integer.MAX_VALUE)))); | ||
final NodeMetadata nodeMetadata = NodeMetadata.FORMAT.loadLatestState(logger, xContentRegistry(), tempDir); | ||
assertThat(nodeMetadata.nodeId(), equalTo("y6VUVMSaStO4Tz-B5BxcOw")); | ||
assertThat(nodeMetadata.nodeVersion(), equalTo(BuildVersion.fromVersionId(0))); | ||
|
||
ElasticsearchException ex = assertThrows( | ||
|
||
ElasticsearchException.class, | ||
() -> NodeMetadata.FORMAT.loadLatestState(logger, xContentRegistry(), tempDir) | ||
); | ||
Throwable rootCause = ex.getRootCause(); | ||
assertThat(rootCause, instanceOf(IllegalStateException.class)); | ||
assertThat("Node version is required in node metadata", equalTo(rootCause.getMessage())); | ||
} | ||
|
||
public void testUpgradesLegitimateVersions() { | ||
|
@@ -155,11 +153,9 @@ public void testDoesNotUpgradeAncientVersion() { | |
); | ||
} | ||
|
||
@UpdateForV9(owner = UpdateForV9.Owner.CORE_INFRA) | ||
@AwaitsFix(bugUrl = "Needs to be updated for 9.0 version bump") | ||
public void testUpgradeMarksPreviousVersion() { | ||
final String nodeId = randomAlphaOfLength(10); | ||
final Version version = VersionUtils.randomVersionBetween(random(), Version.CURRENT.minimumCompatibilityVersion(), Version.V_8_0_0); | ||
final Version version = VersionUtils.randomVersionBetween(random(), Version.CURRENT.minimumCompatibilityVersion(), Version.V_9_0_0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this test be rewritten to be built on BuildVersion and IndexVersion? We seem to be still using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see how to do it without big refactoring - BuildVersion currently is essentially a wrapper around Version, so it doesn't seem possible to create it without having a version id within a valid range |
||
final BuildVersion buildVersion = BuildVersion.fromVersionId(version.id()); | ||
|
||
final NodeMetadata nodeMetadata = new NodeMetadata(nodeId, buildVersion, IndexVersion.current()).upgradeToCurrentVersion(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you rewrite this in abstract terms so we don't need to update it with each major release? You could use
N.0
and(N-1).last
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done