From db755855b43890daa7e50bac9d7b01abda614867 Mon Sep 17 00:00:00 2001 From: jonmv Date: Sat, 9 Apr 2022 23:39:37 +0200 Subject: ** Add RevisionId as key for ApplicationVersion, and gather them all in RevisionHistory --- .../integration/deployment/ApplicationVersion.java | 54 ++++++++++++++++---- .../api/integration/deployment/RevisionId.java | 59 ++++++++++++++++++++++ 2 files changed, 102 insertions(+), 11 deletions(-) create mode 100644 controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/RevisionId.java (limited to 'controller-api/src/main/java/com') 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 bb610ef80cd..4938b76bf48 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 @@ -17,14 +17,10 @@ import java.util.OptionalLong; */ public class ApplicationVersion implements Comparable { - /** - * Used in cases where application version cannot be determined, such as manual deployments (e.g. in dev - * environment) - */ - public static final ApplicationVersion unknown = new ApplicationVersion(Optional.empty(), OptionalLong.empty(), + /** Should not be used, but may still exist in serialized data :< */ + public static final ApplicationVersion unknown = new ApplicationVersion(Optional.empty(), OptionalLong.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), - Optional.empty(), Optional.empty(), true, - Optional.empty()); + Optional.empty(), true, Optional.empty(), false, true); // This never changes and is only used to create a valid semantic version number, as required by application bundles private static final String majorVersion = "1.0"; @@ -38,11 +34,14 @@ public class ApplicationVersion implements Comparable { private final Optional commit; private final boolean deployedDirectly; private final Optional bundleHash; + private final boolean hasPackage; + private final boolean shouldSkip; /** Public for serialisation only. */ public ApplicationVersion(Optional source, OptionalLong buildNumber, Optional authorEmail, Optional compileVersion, Optional buildTime, Optional sourceUrl, - Optional commit, boolean deployedDirectly, Optional bundleHash) { + Optional commit, boolean deployedDirectly, Optional bundleHash, + boolean hasPackage, boolean shouldSkip) { if (buildNumber.isEmpty() && ( source.isPresent() || authorEmail.isPresent() || compileVersion.isPresent() || buildTime.isPresent() || sourceUrl.isPresent() || commit.isPresent())) throw new IllegalArgumentException("Build number must be present if any other attribute is"); @@ -68,13 +67,20 @@ public class ApplicationVersion implements Comparable { this.commit = Objects.requireNonNull(commit, "commit cannot be null"); this.deployedDirectly = deployedDirectly; this.bundleHash = bundleHash; + this.hasPackage = hasPackage; + this.shouldSkip = shouldSkip; + } + + public RevisionId id() { + return isDeployedDirectly() ? RevisionId.forDevelopment(buildNumber().orElse(0)) + : RevisionId.forProduction(buildNumber().orElseThrow()); } /** Create an application package version from a completed build, without an author email */ public static ApplicationVersion from(SourceRevision source, long buildNumber) { return new ApplicationVersion(Optional.of(source), OptionalLong.of(buildNumber), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), false, - Optional.empty()); + Optional.empty(), true, false); } /** Creates a version from a completed build, an author email, and build meta data. */ @@ -82,7 +88,7 @@ public class ApplicationVersion implements Comparable { Version compileVersion, Instant buildTime) { return new ApplicationVersion(Optional.of(source), OptionalLong.of(buildNumber), Optional.of(authorEmail), Optional.of(compileVersion), Optional.of(buildTime), Optional.empty(), Optional.empty(), false, - Optional.empty()); + Optional.empty(), true, false); } /** Creates a version from a completed build, an author email, and build meta data. */ @@ -90,7 +96,8 @@ public class ApplicationVersion implements Comparable { Optional compileVersion, Optional buildTime, Optional sourceUrl, Optional commit, boolean deployedDirectly, Optional bundleHash) { - return new ApplicationVersion(source, OptionalLong.of(buildNumber), authorEmail, compileVersion, buildTime, sourceUrl, commit, deployedDirectly, bundleHash); + return new ApplicationVersion(source, OptionalLong.of(buildNumber), authorEmail, compileVersion, + buildTime, sourceUrl, commit, deployedDirectly, bundleHash, true, false); } /** Returns a unique identifier for this version or "unknown" if version is not known */ @@ -152,6 +159,31 @@ public class ApplicationVersion implements Comparable { return deployedDirectly; } + /** Returns a copy of this without a package stored. */ + public ApplicationVersion withoutPackage() { + return new ApplicationVersion(source, buildNumber, authorEmail, compileVersion, buildTime, sourceUrl, commit, deployedDirectly, bundleHash, false, shouldSkip); + } + + /** Whether we still have the package for this revision. */ + public boolean hasPackage() { + return hasPackage; + } + + /** Returns a copy of this which will not be rolled out to production. */ + public ApplicationVersion skipped() { + return new ApplicationVersion(source, buildNumber, authorEmail, compileVersion, buildTime, sourceUrl, commit, deployedDirectly, bundleHash, hasPackage, true); + } + + /** Whether we still have the package for this revision. */ + public boolean shouldSkip() { + return shouldSkip; + } + + /** Whether this revision should be deployed. */ + public boolean isDeployable() { + return hasPackage && ! shouldSkip; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/RevisionId.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/RevisionId.java new file mode 100644 index 00000000000..b8b24fd9c77 --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/RevisionId.java @@ -0,0 +1,59 @@ +package com.yahoo.vespa.hosted.controller.api.integration.deployment; + +import java.util.Objects; + +import static ai.vespa.validation.Validation.requireAtLeast; + +/** + * ID of a revision of an application package. This is the build number, and whether it was submitted for production deployment. + * + * @author jonmv + */ +public class RevisionId implements Comparable { + + private final long number; + private final boolean production; + + private RevisionId(long number, boolean production) { + this.number = number; + this.production = production; + } + + public static RevisionId forProduction(long number) { + return new RevisionId(requireAtLeast(number, "build number", 1L), true); + } + + public static RevisionId forDevelopment(long number) { + return new RevisionId(requireAtLeast(number, "build number", 0L), false); + } + + public long number() { return number; } + + private boolean isProduction() { return production; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + RevisionId that = (RevisionId) o; + return number == that.number && production == that.production; + } + + @Override + public int hashCode() { + return Objects.hash(number, production); + } + + /** Unknown, manual builds sort first, then known manual builds, then production builds, by increasing build number */ + @Override + public int compareTo(RevisionId o) { + return production != o.production ? Boolean.compare(production, o.production) + : Long.compare(number, o.number); + } + + @Override + public String toString() { + return (production ? "prod" : "dev") + " build " + number; + } + +} -- cgit v1.2.3