diff options
5 files changed, 98 insertions, 35 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepositoryNode.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepositoryNode.java index 717be040a9f..e12908f6aa8 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepositoryNode.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepositoryNode.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Arrays; import java.util.Set; @JsonIgnoreProperties(ignoreUnknown = true) @@ -45,6 +46,10 @@ public class NodeRepositoryNode { private String vespaVersion; @JsonProperty("wantedVespaVersion") private String wantedVespaVersion; + @JsonProperty("currentOsVersion") + private String currentOsVersion; + @JsonProperty("wantedOsVersion") + private String wantedOsVersion; @JsonProperty("failCount") private Integer failCount; @JsonProperty("hardwareFailure") @@ -356,42 +361,62 @@ public class NodeRepositoryNode { return allowedToBeDown; } + public String getCurrentOsVersion() { + return currentOsVersion; + } + + public void setCurrentOsVersion(String currentOsVersion) { + this.currentOsVersion = currentOsVersion; + } + + public String getWantedOsVersion() { + return wantedOsVersion; + } + + public void setWantedOsVersion(String wantedOsVersion) { + this.wantedOsVersion = wantedOsVersion; + } + @Override public String toString() { return "NodeRepositoryNode{" + - "url='" + url + '\'' + - ", id='" + id + '\'' + - ", state=" + state + - ", hostname='" + hostname + '\'' + - ", ipAddresses='" + ipAddresses + '\'' + - ", additionalIpAddresses='" + additionalIpAddresses + '\'' + - ", openStackId='" + openStackId + '\'' + - ", flavor='" + flavor + '\'' + - ", canonicalFlavor='" + canonicalFlavor + '\'' + - ", membership=" + membership + - ", owner=" + owner + - ", restartGeneration=" + restartGeneration + - ", rebootGeneration=" + rebootGeneration + - ", currentRestartGeneration=" + currentRestartGeneration + - ", currentRebootGeneration=" + currentRebootGeneration + - ", vespaVersion='" + vespaVersion + '\'' + - ", wantedVespaVersion='" + wantedVespaVersion + '\'' + - ", failCount=" + failCount + - ", hardwareFailure=" + hardwareFailure + - ", hardwareFailureDescription='" + hardwareFailureDescription + '\'' + - ", hardwareDivergence='" + hardwareDivergence + '\'' + - ", environment=" + environment + - ", type=" + type + - ", wantedDockerImage='" + wantedDockerImage + '\'' + - ", currentDockerImage='" + currentDockerImage + '\'' + - ", wantToRetire='" + wantToRetire + '\'' + - ", wantToDeprovision='" + wantToDeprovision + '\'' + - ", minDiskAvailableGb='" + minDiskAvailableGb + '\'' + - ", minMainMemoryAvailableGb='" + minMainMemoryAvailableGb + '\'' + - ", cost='" + cost + '\'' + - ", minCpuCores='" + minCpuCores + '\'' + - ", description='" + description + '\'' + - ", allowedToBeDown='" + allowedToBeDown + '\'' + - '}'; + "url='" + url + '\'' + + ", id='" + id + '\'' + + ", state=" + state + + ", hostname='" + hostname + '\'' + + ", ipAddresses=" + ipAddresses + + ", additionalIpAddresses=" + additionalIpAddresses + + ", openStackId='" + openStackId + '\'' + + ", flavor='" + flavor + '\'' + + ", canonicalFlavor='" + canonicalFlavor + '\'' + + ", membership=" + membership + + ", owner=" + owner + + ", restartGeneration=" + restartGeneration + + ", rebootGeneration=" + rebootGeneration + + ", currentRestartGeneration=" + currentRestartGeneration + + ", currentRebootGeneration=" + currentRebootGeneration + + ", vespaVersion='" + vespaVersion + '\'' + + ", wantedVespaVersion='" + wantedVespaVersion + '\'' + + ", currentOsVersion='" + currentOsVersion + '\'' + + ", wantedOsVersion='" + wantedOsVersion + '\'' + + ", failCount=" + failCount + + ", hardwareFailure=" + hardwareFailure + + ", hardwareFailureDescription='" + hardwareFailureDescription + '\'' + + ", hardwareDivergence='" + hardwareDivergence + '\'' + + ", environment=" + environment + + ", type=" + type + + ", wantedDockerImage='" + wantedDockerImage + '\'' + + ", currentDockerImage='" + currentDockerImage + '\'' + + ", parentHostname='" + parentHostname + '\'' + + ", wantToRetire=" + wantToRetire + + ", wantToDeprovision=" + wantToDeprovision + + ", minDiskAvailableGb=" + minDiskAvailableGb + + ", minMainMemoryAvailableGb=" + minMainMemoryAvailableGb + + ", cost=" + cost + + ", minCpuCores=" + minCpuCores + + ", description='" + description + '\'' + + ", history=" + Arrays.toString(history) + + ", allowedToBeDown=" + allowedToBeDown + + '}'; } } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeUpgrade.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeUpgrade.java index 6b6af02b88c..21c1d23ba3a 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeUpgrade.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeUpgrade.java @@ -3,23 +3,30 @@ package com.yahoo.vespa.hosted.controller.api.integration.noderepository; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; /** * @author mpolden */ @JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) public class NodeUpgrade { @JsonProperty("version") private final String version; + @JsonProperty("osVersion") + private final String osVersion; + @JsonProperty("force") private final boolean force; @JsonCreator - public NodeUpgrade(@JsonProperty("version") String version, @JsonProperty("force") boolean force) { + public NodeUpgrade(@JsonProperty("version") String version, @JsonProperty("osVersion") String osVersion, + @JsonProperty("force") boolean force) { this.version = version; + this.osVersion = osVersion; this.force = force; } @@ -27,6 +34,10 @@ public class NodeUpgrade { return version; } + public String getOsVersion() { + return osVersion; + } + public boolean isForce() { return force; } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InfrastructureVersions.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InfrastructureVersions.java index 52d7a63dc5e..61783bb4483 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InfrastructureVersions.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InfrastructureVersions.java @@ -31,6 +31,9 @@ public class InfrastructureVersions { if (nodeType != NodeType.config && nodeType != NodeType.confighost && nodeType != NodeType.proxyhost) { throw new IllegalArgumentException("Cannot set version for type " + nodeType); } + if (newTargetVersion.isEmpty()) { + throw new IllegalArgumentException("Invalid target version: " + newTargetVersion.toFullString()); + } try (Lock lock = db.lockInfrastructureVersions()) { Map<NodeType, Version> infrastructureVersions = db.readInfrastructureVersions(); diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/OsVersions.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/OsVersions.java index 7e941d58a62..78783f9c76a 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/OsVersions.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/OsVersions.java @@ -67,6 +67,9 @@ public class OsVersions { if (!nodeType.isDockerHost()) { throw new IllegalArgumentException("Setting target OS version for " + nodeType + " nodes is unsupported"); } + if (newTarget.isEmpty()) { + throw new IllegalArgumentException("Invalid target version: " + newTarget.toFullString()); + } try (Lock lock = db.lockOsVersions()) { Map<NodeType, Version> osVersions = db.readOsVersions(); Optional<Version> oldTarget = Optional.ofNullable(osVersions.get(nodeType)); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/RestApiTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/RestApiTest.java index 448b64d1e78..83d3acdd178 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/RestApiTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/RestApiTest.java @@ -522,6 +522,20 @@ public class RestApiTest { assertResponse(new Request("http://localhost:8080/nodes/v2/upgrade/"), "{\"versions\":{\"config\":\"6.123.456\",\"confighost\":\"6.123.456\"},\"osVersions\":{}}"); + // Setting empty version fails + assertResponse(new Request("http://localhost:8080/nodes/v2/upgrade/confighost", + Utf8.toBytes("{\"version\": null}"), + Request.Method.PATCH), + 400, + "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Invalid target version: 0.0.0\"}"); + + // Omitting version field fails + assertResponse(new Request("http://localhost:8080/nodes/v2/upgrade/confighost", + Utf8.toBytes("{}"), + Request.Method.PATCH), + 400, + "{\"error-code\":\"BAD_REQUEST\",\"message\":\"At least one of 'version' and 'osVersion' must be set\"}"); + // Downgrade without force fails assertResponse(new Request("http://localhost:8080/nodes/v2/upgrade/confighost", Utf8.toBytes("{\"version\": \"6.123.1\"}"), @@ -567,6 +581,13 @@ public class RestApiTest { 400, "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Setting target OS version for config nodes is unsupported\"}"); + // Setting empty osVersion fails + assertResponse(new Request("http://localhost:8080/nodes/v2/upgrade/confighost", + Utf8.toBytes("{\"osVersion\": null}"), + Request.Method.PATCH), + 400, + "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Invalid target version: 0.0.0\"}"); + // Attempt to downgrade OS assertResponse(new Request("http://localhost:8080/nodes/v2/upgrade/confighost", Utf8.toBytes("{\"osVersion\": \"7.4.2\"}"), |