-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Decouple trial license resets from product version #100169
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
Merged
elasticsearchmachine
merged 12 commits into
elastic:main
from
gwbrown:license/decouple-trial-from-version
Nov 2, 2023
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
87c330f
Decouple trial license resets from product version
gwbrown 880e7d6
Clean up some missed version -> era
gwbrown 3f54f9b
Correct tests & add clarifying comments
gwbrown 2191282
Merge remote-tracking branch 'origin/main' into license/decouple-tria…
gwbrown 6b9ad0e
Era -> Version
gwbrown 7704e3a
Merge remote-tracking branch 'origin/main' into license/decouple-tria…
gwbrown 41ebb01
Merge remote-tracking branch 'origin/main' into license/decouple-tria…
gwbrown 41989f6
Address review feedback, specifically:
gwbrown 08b4d25
Yet more era->version
gwbrown 2f248c2
Merge remote-tracking branch 'origin/main' into license/decouple-tria…
gwbrown f1fd28a
Remove another unnecessary test & another version->era
gwbrown 1487461
Merge branch 'main' into license/decouple-trial-from-version
elasticmachine File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
124 changes: 124 additions & 0 deletions
124
x-pack/plugin/core/src/main/java/org/elasticsearch/license/internal/TrialLicenseVersion.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License | ||
| * 2.0; you may not use this file except in compliance with the Elastic License | ||
| * 2.0. | ||
| */ | ||
|
|
||
| package org.elasticsearch.license.internal; | ||
|
|
||
| import org.elasticsearch.common.io.stream.StreamInput; | ||
| import org.elasticsearch.common.io.stream.StreamOutput; | ||
| import org.elasticsearch.common.io.stream.Writeable; | ||
| import org.elasticsearch.xcontent.ToXContentFragment; | ||
| import org.elasticsearch.xcontent.XContentBuilder; | ||
|
|
||
| import java.io.IOException; | ||
| import java.util.Objects; | ||
|
|
||
| /** | ||
| * Sometimes we release a version with a bunch of cool new features, and we want people to be able to start a new trial license in a cluster | ||
| * that's already used a trial and let it expire. This class controls when we do that. The serialization of this class is designed to | ||
| * maintain compatibility with old-school Elasticsearch versions (specifically the {@link org.elasticsearch.Version} class). | ||
| */ | ||
| public class TrialLicenseVersion implements ToXContentFragment, Writeable { | ||
|
|
||
| // This was the highest version at the time we cut over to having a specific version for the trial license, rather than reusing the | ||
| // generic Elasticsearch version. While it's derived from the Elasticsearch version formula for BWC, it is independent of it going | ||
| // forward. When we want users to be able to start a new trial, increment this number. | ||
| // Pkg-private for testing only. | ||
| static final int TRIAL_VERSION_CUTOVER = 8_12_00_99; | ||
| public static final TrialLicenseVersion CURRENT = new TrialLicenseVersion(TRIAL_VERSION_CUTOVER); | ||
|
|
||
| // The most recently released major version when we cut over. Here for maintaining BWC behavior. | ||
| static final int TRIAL_VERSION_CUTOVER_MAJOR = 8; | ||
|
|
||
| private final int trialVersion; | ||
|
|
||
| public TrialLicenseVersion(int trialVersion) { | ||
| this.trialVersion = trialVersion; | ||
| } | ||
|
|
||
| public TrialLicenseVersion(StreamInput in) throws IOException { | ||
| this.trialVersion = in.readVInt(); | ||
| } | ||
|
|
||
| public static TrialLicenseVersion fromXContent(String from) { | ||
| try { | ||
| return new TrialLicenseVersion(Integer.parseInt(from)); | ||
| } catch (NumberFormatException ex) { | ||
| return new TrialLicenseVersion(parseVersionString(from)); | ||
| } | ||
| } | ||
|
|
||
| // copied from Version and simplified, for backwards compatibility parsing old version strings in LicensesMetadata XContent | ||
| private static int parseVersionString(String version) { | ||
| final boolean snapshot = version.endsWith("-SNAPSHOT"); // this is some BWC for 2.x and before indices | ||
| if (snapshot) { | ||
| version = version.substring(0, version.length() - 9); | ||
| } | ||
| String[] parts = version.split("[.-]"); | ||
| if (parts.length != 3) { | ||
| throw new IllegalArgumentException("unable to parse trial license version: " + version); | ||
| } | ||
|
|
||
| try { | ||
| final int rawMajor = Integer.parseInt(parts[0]); | ||
| // we reverse the version id calculation based on some assumption as we can't reliably reverse the modulo | ||
| final int major = rawMajor * 1000000; | ||
| final int minor = Integer.parseInt(parts[1]) * 10000; | ||
| final int revision = Integer.parseInt(parts[2]) * 100; | ||
|
|
||
| // 99 is leftover from alpha/beta/rc, it should be removed | ||
| return major + minor + revision + 99; | ||
|
|
||
| } catch (NumberFormatException e) { | ||
| throw new IllegalArgumentException("unable to parse trial license version: " + version, e); | ||
| } | ||
| } | ||
|
|
||
| int asInt() { | ||
| return trialVersion; | ||
| } | ||
|
|
||
| public boolean ableToStartNewTrialSince(TrialLicenseVersion since) { | ||
| if (since.asInt() < TRIAL_VERSION_CUTOVER) { | ||
| int sinceMajorVersion = since.asInt() / 1_000_000; // integer division is intentional | ||
| return sinceMajorVersion < TRIAL_VERSION_CUTOVER_MAJOR; | ||
| } | ||
| return since.asInt() < trialVersion; | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return Integer.toString(trialVersion); | ||
| } | ||
|
|
||
| @Override | ||
| public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||
| return builder.value(trialVersion); // suffix added for BWC | ||
| } | ||
|
|
||
| // pkg-private for testing | ||
| String asVersionString() { | ||
| return this + ".0.0"; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean equals(Object o) { | ||
| if (this == o) return true; | ||
| if (o == null || getClass() != o.getClass()) return false; | ||
| TrialLicenseVersion that = (TrialLicenseVersion) o; | ||
| return trialVersion == that.trialVersion; | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return Objects.hash(trialVersion); | ||
| } | ||
|
|
||
| @Override | ||
| public void writeTo(StreamOutput out) throws IOException { | ||
| out.writeVInt(trialVersion); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Can we use this bwc format only in bwc cases? Does the license maintain the version bit as a string or version id?
Uh oh!
There was an error while loading. Please reload this page.
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.
A string, unfortunately:
elasticsearch/x-pack/plugin/core/src/main/java/org/elasticsearch/license/LicensesMetadata.java
Line 155 in 878127c
(⬆️ code is from
main, to be clear).Note this is
LicensesMetadata, rather than in the license itself, so we only store one of these for the whole cluster but it's still in the persistent cluster state. We can probably switch to emitting an integer, are there are any cases where we'd need an old version of ES to be able to parse XContent emitted by a newer version? The main case I'm aware of where we need to read aLicensesMetadataXContent is restoring a snapshot, and you can't restore a snapshot taken by a newer version than you're currently on AFAIK.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.
As long as we only upgrade the license metadata format after the min version of the cluster has stabilized in the upgrade, we should be ok.