diff options
author | jonmv <venstad@gmail.com> | 2022-09-12 23:58:10 +0200 |
---|---|---|
committer | jonmv <venstad@gmail.com> | 2022-09-12 23:58:10 +0200 |
commit | d220817377fefd1f839d30920f24cffc64eabd75 (patch) | |
tree | 16451c87c662f13afbb190bf9f8d35a01f128a3c | |
parent | 61ce6727165ab6d0d1362771ac464e9cf4a12494 (diff) |
Store allowedMajor in ApplicationVersion, and respect in DeploymentUpgrader
7 files changed, 36 insertions, 20 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationVersion.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationVersion.java index 445ca0435d4..04604ae7007 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationVersion.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationVersion.java @@ -10,6 +10,7 @@ import java.util.Optional; import java.util.OptionalLong; import static ai.vespa.validation.Validation.requireAtLeast; +import static java.util.Objects.requireNonNull; /** * An application package version, identified by a source revision and a build number. @@ -27,6 +28,7 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { private final Optional<SourceRevision> source; private final Optional<String> authorEmail; private final Optional<Version> compileVersion; + private final Optional<Integer> allowedMajor; private final Optional<Instant> buildTime; private final Optional<String> sourceUrl; private final Optional<String> commit; @@ -37,8 +39,8 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { private final int risk; public ApplicationVersion(RevisionId id, Optional<SourceRevision> source, Optional<String> authorEmail, - Optional<Version> compileVersion, Optional<Instant> buildTime, Optional<String> sourceUrl, - Optional<String> commit, Optional<String> bundleHash, + Optional<Version> compileVersion, Optional<Integer> allowedMajor, Optional<Instant> buildTime, + Optional<String> sourceUrl, Optional<String> commit, Optional<String> bundleHash, boolean hasPackage, boolean shouldSkip, Optional<String> description, int risk) { if (commit.isPresent() && commit.get().length() > 128) @@ -54,9 +56,10 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { this.source = source; this.authorEmail = authorEmail; this.compileVersion = compileVersion; + this.allowedMajor = requireNonNull(allowedMajor); this.buildTime = buildTime; - this.sourceUrl = Objects.requireNonNull(sourceUrl, "sourceUrl cannot be null"); - this.commit = Objects.requireNonNull(commit, "commit cannot be null"); + this.sourceUrl = requireNonNull(sourceUrl, "sourceUrl cannot be null"); + this.commit = requireNonNull(commit, "commit cannot be null"); this.bundleHash = bundleHash; this.hasPackage = hasPackage; this.shouldSkip = shouldSkip; @@ -70,24 +73,24 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { /** Create an application package version from a completed build, without an author email */ public static ApplicationVersion from(RevisionId id, SourceRevision source) { - return new ApplicationVersion(id, Optional.of(source), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), true, false, Optional.empty(), 0); + return new ApplicationVersion(id, Optional.of(source), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), true, false, Optional.empty(), 0); } /** Creates a version from a completed build, an author email, and build metadata. */ public static ApplicationVersion from(RevisionId id, SourceRevision source, String authorEmail, Version compileVersion, Instant buildTime) { - return new ApplicationVersion(id, Optional.of(source), Optional.of(authorEmail), Optional.of(compileVersion), Optional.of(buildTime), Optional.empty(), Optional.empty(), Optional.empty(), true, false, Optional.empty(), 0); + return new ApplicationVersion(id, Optional.of(source), Optional.of(authorEmail), Optional.of(compileVersion), Optional.empty(), Optional.of(buildTime), Optional.empty(), Optional.empty(), Optional.empty(), true, false, Optional.empty(), 0); } /** Creates a minimal version for a development build. */ - public static ApplicationVersion forDevelopment(RevisionId id, Optional<Version> compileVersion) { - return new ApplicationVersion(id, Optional.empty(), Optional.empty(), compileVersion, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), true, false, Optional.empty(), 0); + public static ApplicationVersion forDevelopment(RevisionId id, Optional<Version> compileVersion, Optional<Integer> allowedMajor) { + return new ApplicationVersion(id, Optional.empty(), Optional.empty(), compileVersion, allowedMajor, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), true, false, Optional.empty(), 0); } /** Creates a version from a completed build, an author email, and build metadata. */ public static ApplicationVersion forProduction(RevisionId id, Optional<SourceRevision> source, Optional<String> authorEmail, - Optional<Version> compileVersion, Optional<Instant> buildTime, Optional<String> sourceUrl, + Optional<Version> compileVersion, Optional<Integer> allowedMajor, Optional<Instant> buildTime, Optional<String> sourceUrl, Optional<String> commit, Optional<String> bundleHash, Optional<String> description, int risk) { - return new ApplicationVersion(id, source, authorEmail, compileVersion, buildTime, + return new ApplicationVersion(id, source, authorEmail, compileVersion, allowedMajor, buildTime, sourceUrl, commit, bundleHash, true, false, description, risk); } @@ -115,6 +118,8 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { /** Returns the Vespa version this package was compiled against, if known. */ public Optional<Version> compileVersion() { return compileVersion; } + public Optional<Integer> allowedMajor() { return allowedMajor; } + /** Returns the time this package was built, if known. */ public Optional<Instant> buildTime() { return buildTime; } @@ -145,7 +150,7 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { /** Returns a copy of this without a package stored. */ public ApplicationVersion withoutPackage() { - return new ApplicationVersion(id, source, authorEmail, compileVersion, buildTime, sourceUrl, commit, bundleHash, false, shouldSkip, description, risk); + return new ApplicationVersion(id, source, authorEmail, compileVersion, allowedMajor, buildTime, sourceUrl, commit, bundleHash, false, shouldSkip, description, risk); } /** Whether we still have the package for this revision. */ @@ -155,7 +160,7 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { /** Returns a copy of this which will not be rolled out to production. */ public ApplicationVersion skipped() { - return new ApplicationVersion(id, source, authorEmail, compileVersion, buildTime, sourceUrl, commit, bundleHash, hasPackage, true, description, risk); + return new ApplicationVersion(id, source, authorEmail, compileVersion, allowedMajor, buildTime, sourceUrl, commit, bundleHash, hasPackage, true, description, risk); } /** Whether we still have the package for this revision. */ diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java index 79d3217564d..e91c0903280 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java @@ -709,7 +709,7 @@ public class JobController { long build = 1 + lastRun.map(run -> run.versions().targetRevision().number()).orElse(0L); RevisionId revisionId = RevisionId.forDevelopment(build, new JobId(id, type)); - ApplicationVersion version = ApplicationVersion.forDevelopment(revisionId, applicationPackage.compileVersion()); + ApplicationVersion version = ApplicationVersion.forDevelopment(revisionId, applicationPackage.compileVersion(), applicationPackage.deploymentSpec().majorVersion()); byte[] diff = getDiff(applicationPackage, deploymentId, lastRun); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/RevisionHistory.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/RevisionHistory.java index 0200fbae71f..ab8f7fe22d3 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/RevisionHistory.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/RevisionHistory.java @@ -94,7 +94,7 @@ public class RevisionHistory { // Fallback for when an application version isn't known for the given key. private static ApplicationVersion revisionOf(RevisionId id) { - return new ApplicationVersion(id, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), false, false, Optional.empty(), 0); + return new ApplicationVersion(id, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), false, false, Optional.empty(), 0); } /** Returns the production {@link ApplicationVersion} with this revision ID. */ diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/Submission.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/Submission.java index e366920690b..6c9de2fd584 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/Submission.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/Submission.java @@ -6,6 +6,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.deployment.SourceRevisi import com.yahoo.vespa.hosted.controller.application.pkg.ApplicationPackage; import java.util.Optional; +import java.util.OptionalInt; import static com.yahoo.vespa.hosted.controller.application.pkg.ApplicationPackage.calculateHash; @@ -42,6 +43,7 @@ public class Submission { source, authorEmail, applicationPackage.compileVersion(), + applicationPackage.deploymentSpec().majorVersion(), applicationPackage.buildTime(), sourceUrl, source.map(SourceRevision::commit), diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentUpgrader.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentUpgrader.java index 789b7137830..fd177c469d2 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentUpgrader.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentUpgrader.java @@ -5,6 +5,7 @@ import com.yahoo.component.Version; import com.yahoo.vespa.hosted.controller.Application; import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.Instance; +import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion; import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobId; import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType; import com.yahoo.vespa.hosted.controller.application.Deployment; @@ -53,10 +54,12 @@ public class DeploymentUpgrader extends ControllerMaintainer { Run last = controller().jobController().last(job).get(); Versions target = new Versions(targetPlatform, last.versions().targetRevision(), Optional.of(last.versions().targetPlatform()), Optional.of(last.versions().targetRevision())); if ( ! last.hasEnded()) continue; - if (application.revisions().get(last.versions().targetRevision()).compileVersion() - .map(version -> controller().applications().versionCompatibility(instance.id()).refuse(version, target.targetPlatform())) - .orElse(false)) continue; - // TODO jonmv: respect major-version from deployment spec o_O Probably add it to ApplicationVersion. + ApplicationVersion devVersion = application.revisions().get(last.versions().targetRevision()); + if (devVersion.compileVersion() + .map(version -> controller().applications().versionCompatibility(instance.id()).refuse(version, target.targetPlatform())) + .orElse(false)) continue; + if ( devVersion.allowedMajor().isPresent() + && devVersion.allowedMajor().get() < targetPlatform.getMajor()) continue; if ( ! deployment.version().isBefore(target.targetPlatform())) continue; if ( ! isLikelyNightFor(job)) continue; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java index 48d8627f407..5aa847f648a 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java @@ -120,6 +120,7 @@ public class ApplicationSerializer { private static final String hasPackageField = "hasPackage"; private static final String shouldSkipField = "shouldSkip"; private static final String compileVersionField = "compileVersion"; + private static final String allowedMajorField = "allowedMajor"; private static final String buildTimeField = "buildTime"; private static final String sourceUrlField = "sourceUrl"; private static final String bundleHashField = "bundleHash"; @@ -257,6 +258,7 @@ public class ApplicationSerializer { applicationVersion.source().ifPresent(source -> toSlime(source, object.setObject(sourceRevisionField))); applicationVersion.authorEmail().ifPresent(email -> object.setString(authorEmailField, email)); applicationVersion.compileVersion().ifPresent(version -> object.setString(compileVersionField, version.toString())); + applicationVersion.allowedMajor().ifPresent(major -> object.setLong(allowedMajorField, major)); applicationVersion.buildTime().ifPresent(time -> object.setLong(buildTimeField, time.toEpochMilli())); applicationVersion.sourceUrl().ifPresent(url -> object.setString(sourceUrlField, url)); applicationVersion.commit().ifPresent(commit -> object.setString(commitField, commit)); @@ -478,6 +480,7 @@ public class ApplicationSerializer { Optional<SourceRevision> sourceRevision = sourceRevisionFromSlime(object.field(sourceRevisionField)); Optional<String> authorEmail = SlimeUtils.optionalString(object.field(authorEmailField)); Optional<Version> compileVersion = SlimeUtils.optionalString(object.field(compileVersionField)).map(Version::fromString); + Optional<Integer> allowedMajor = SlimeUtils.optionalInteger(object.field(allowedMajorField)).stream().boxed().findFirst(); Optional<Instant> buildTime = SlimeUtils.optionalInstant(object.field(buildTimeField)); Optional<String> sourceUrl = SlimeUtils.optionalString(object.field(sourceUrlField)); Optional<String> commit = SlimeUtils.optionalString(object.field(commitField)); @@ -487,8 +490,8 @@ public class ApplicationSerializer { int risk = (int) object.field(riskField).asLong(); Optional<String> bundleHash = SlimeUtils.optionalString(object.field(bundleHashField)); - return new ApplicationVersion(id, sourceRevision, authorEmail, compileVersion, buildTime, sourceUrl, - commit, bundleHash, hasPackage, shouldSkip, description, risk); + return new ApplicationVersion(id, sourceRevision, authorEmail, compileVersion, allowedMajor, buildTime, + sourceUrl, commit, bundleHash, hasPackage, shouldSkip, description, risk); } private Optional<SourceRevision> sourceRevisionFromSlime(Inspector object) { diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java index 88da698b3f2..849261d5ae4 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java @@ -92,6 +92,7 @@ public class ApplicationSerializerTest { Optional.of(new SourceRevision("git@github:org/repo.git", "branch1", "commit1")), Optional.of("william@shakespeare"), Optional.of(Version.fromString("1.2.3")), + Optional.of(123), Optional.of(Instant.ofEpochMilli(666)), Optional.empty(), Optional.of("best commit"), @@ -161,6 +162,8 @@ public class ApplicationSerializerTest { assertEquals(applicationVersion1, serialized.revisions().last().get()); assertEquals(applicationVersion1, serialized.revisions().get(serialized.instances().get(id1.instance()).deployments().get(zone1).revision())); assertEquals(original.revisions().last(), serialized.revisions().last()); + assertEquals(original.revisions().last().get().compileVersion(), serialized.revisions().last().get().compileVersion()); + assertEquals(original.revisions().last().get().allowedMajor(), serialized.revisions().last().get().allowedMajor()); assertEquals(original.revisions().last().get().authorEmail(), serialized.revisions().last().get().authorEmail()); assertEquals(original.revisions().last().get().buildTime(), serialized.revisions().last().get().buildTime()); assertEquals(original.revisions().last().get().sourceUrl(), serialized.revisions().last().get().sourceUrl()); |