summaryrefslogtreecommitdiffstats
path: root/controller-server
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2023-07-26 10:06:57 +0200
committerMartin Polden <mpolden@mpolden.no>2023-07-26 10:06:57 +0200
commit1b7662a84c36e57e38caa7daac0556d1efaafcd3 (patch)
treee398912d557301237d1d1e9257a8833723e04bf5 /controller-server
parent97de0d7eb3761c8d8ca9d6d67c96c5c6f9895a36 (diff)
Add API for listing certified OS versions
Diffstat (limited to 'controller-server')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/OsController.java21
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiHandler.java13
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/CertifiedOsVersion.java11
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsVersionStatusUpdaterTest.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiTest.java5
5 files changed, 42 insertions, 10 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/OsController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/OsController.java
index 6ad7a005036..c426c27418d 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/OsController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/OsController.java
@@ -127,7 +127,7 @@ public record OsController(Controller controller) {
requireCloud(cloud);
try (Mutex lock = curator().lockCertifiedOsVersions()) {
OsVersion osVersion = new OsVersion(version, cloud);
- Set<CertifiedOsVersion> certifiedVersions = curator().readCertifiedOsVersions();
+ Set<CertifiedOsVersion> certifiedVersions = readCertified();
Optional<CertifiedOsVersion> matching = certifiedVersions.stream()
.filter(cv -> cv.osVersion().equals(osVersion))
.findFirst();
@@ -145,7 +145,7 @@ public record OsController(Controller controller) {
public void uncertify(Version version, CloudName cloud) {
try (Mutex lock = curator().lockCertifiedOsVersions()) {
OsVersion osVersion = new OsVersion(version, cloud);
- Set<CertifiedOsVersion> certifiedVersions = curator().readCertifiedOsVersions();
+ Set<CertifiedOsVersion> certifiedVersions = readCertified();
Optional<CertifiedOsVersion> existing = certifiedVersions.stream()
.filter(cv -> cv.osVersion().equals(osVersion))
.findFirst();
@@ -162,7 +162,7 @@ public record OsController(Controller controller) {
public void removeStaleCertifications(OsVersionStatus currentStatus) {
try (Mutex lock = curator().lockCertifiedOsVersions()) {
Set<OsVersion> knownVersions = currentStatus.versions().keySet();
- Set<CertifiedOsVersion> certifiedVersions = new HashSet<>(curator().readCertifiedOsVersions());
+ Set<CertifiedOsVersion> certifiedVersions = new HashSet<>(readCertified());
if (certifiedVersions.removeIf(cv -> !knownVersions.contains(cv.osVersion()))) {
curator().writeCertifiedOsVersions(certifiedVersions);
}
@@ -174,11 +174,16 @@ public record OsController(Controller controller) {
if (controller.system().isCd()) return true; // Always certified (this is the system doing the certifying)
Version systemVersion = controller.readSystemVersion();
- return controller.curator().readCertifiedOsVersions().stream()
- .anyMatch(certifiedOsVersion -> certifiedOsVersion.osVersion().equals(osVersion) &&
- // A later system version is fine, as we don't guarantee that
- // an OS upgrade will always coincide with a Vespa release
- !certifiedOsVersion.vespaVersion().isAfter(systemVersion));
+ return readCertified().stream()
+ .anyMatch(certifiedOsVersion -> certifiedOsVersion.osVersion().equals(osVersion) &&
+ // A later system version is fine, as we don't guarantee that
+ // an OS upgrade will always coincide with a Vespa release
+ !certifiedOsVersion.vespaVersion().isAfter(systemVersion));
+ }
+
+ /** Returns all certified versions */
+ public Set<CertifiedOsVersion> readCertified() {
+ return controller.curator().readCertifiedOsVersions();
}
private void requireCloud(CloudName cloud) {
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiHandler.java
index b3bb2797a89..167c30cb630 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiHandler.java
@@ -86,6 +86,7 @@ public class OsApiHandler extends AuditLoggingRequestHandler {
private HttpResponse get(HttpRequest request) {
Path path = new Path(request.getUri());
if (path.matches("/os/v1/")) return new SlimeJsonResponse(osVersions());
+ if (path.matches("/os/v1/certify")) return new SlimeJsonResponse(certifiedOsVersions());
return ErrorResponse.notFoundError("Nothing at " + path);
}
@@ -181,6 +182,18 @@ public class OsApiHandler extends AuditLoggingRequestHandler {
target.toFullString() + (pin ? " (pinned)" : ""));
}
+ private Slime certifiedOsVersions() {
+ Slime slime = new Slime();
+ Cursor array = slime.setArray();
+ controller.os().readCertified().stream().sorted().forEach(cv -> {
+ Cursor object = array.addObject();
+ object.setString("version", cv.osVersion().version().toFullString());
+ object.setString("cloud", cv.osVersion().cloud().value());
+ object.setString("vespaVersion", cv.vespaVersion().toFullString());
+ });
+ return slime;
+ }
+
private Slime osVersions() {
Slime slime = new Slime();
Cursor root = slime.setObject();
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/CertifiedOsVersion.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/CertifiedOsVersion.java
index be99e170f03..9402165f112 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/CertifiedOsVersion.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/versions/CertifiedOsVersion.java
@@ -2,6 +2,7 @@ package com.yahoo.vespa.hosted.controller.versions;
import com.yahoo.component.Version;
+import java.util.Comparator;
import java.util.Objects;
/**
@@ -9,11 +10,19 @@ import java.util.Objects;
*
* @author mpolden
*/
-public record CertifiedOsVersion(OsVersion osVersion, Version vespaVersion) {
+public record CertifiedOsVersion(OsVersion osVersion, Version vespaVersion) implements Comparable<CertifiedOsVersion> {
+
+ private static final Comparator<CertifiedOsVersion> comparator = Comparator.comparing(CertifiedOsVersion::osVersion)
+ .thenComparing(CertifiedOsVersion::vespaVersion);
public CertifiedOsVersion {
Objects.requireNonNull(osVersion);
Objects.requireNonNull(vespaVersion);
}
+ @Override
+ public int compareTo(CertifiedOsVersion that) {
+ return comparator.compare(this, that);
+ }
+
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsVersionStatusUpdaterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsVersionStatusUpdaterTest.java
index ce121029aaa..af535abce26 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsVersionStatusUpdaterTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsVersionStatusUpdaterTest.java
@@ -79,7 +79,7 @@ public class OsVersionStatusUpdaterTest {
}
private static Set<OsVersion> certifiedOsVersions(ControllerTester tester) {
- return tester.controller().curator().readCertifiedOsVersions().stream()
+ return tester.controller().os().readCertified().stream()
.map(CertifiedOsVersion::osVersion)
.collect(Collectors.toSet());
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiTest.java
index 7e9cbdec2df..f1a40307804 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiTest.java
@@ -115,8 +115,13 @@ public class OsApiTest extends ControllerContainerTest {
// Certify an OS and Vespa version pair
assertResponse(new Request("http://localhost:8080/os/v1/certify/cloud1/7.5.2", "8.200.37", Request.Method.POST),
"{\"message\":\"Certified 7.5.2 in cloud cloud1 as compatible with Vespa version 8.200.37\"}", 200);
+ assertResponse(new Request("http://localhost:8080/os/v1/certify/cloud2/7.5.2", "8.200.33", Request.Method.POST),
+ "{\"message\":\"Certified 7.5.2 in cloud cloud2 as compatible with Vespa version 8.200.33\"}", 200);
assertResponse(new Request("http://localhost:8080/os/v1/certify/cloud1/7.5.2", "8.200.42", Request.Method.POST),
"{\"message\":\"7.5.2 is already certified in cloud cloud1 as compatible with Vespa version 8.200.37. Leaving certification unchanged\"}", 200);
+ assertResponse(new Request("http://localhost:8080/os/v1/certify", "", Request.Method.GET),
+ """
+[{"version":"7.5.2","cloud":"cloud1","vespaVersion":"8.200.37"},{"version":"7.5.2","cloud":"cloud2","vespaVersion":"8.200.33"}]""", 200);
assertResponse(new Request("http://localhost:8080/os/v1/certify/cloud1/7.5.2", "", Request.Method.DELETE),
"{\"message\":\"Removed certification of 7.5.2 in cloud cloud1\"}", 200);