summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/ClusterMembership.java28
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/ClusterSpec.java43
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/DockerImage.java39
-rw-r--r--config-provisioning/src/test/java/com/yahoo/config/provision/ClusterMembershipTest.java14
-rw-r--r--config-provisioning/src/test/java/com/yahoo/config/provision/ProvisionInfoTest.java8
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/provision/StaticProvisioner.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java26
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java1
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java6
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirerTest.java2
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveAndFailedExpirerTest.java8
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java13
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainerTest.java7
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainerTest.java4
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/ReservationExpirerTest.java2
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirerTest.java4
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java57
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AclProvisioningTest.java4
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java11
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/MultigroupProvisioningTest.java2
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/NodeTypeProvisioningTest.java8
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java12
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java2
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningTest.java4
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node10.json3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4-after-changes.json3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4.json3
28 files changed, 214 insertions, 104 deletions
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterMembership.java b/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterMembership.java
index d8ad7295b1c..ff7ff0b4971 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterMembership.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterMembership.java
@@ -1,6 +1,8 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.provision;
+import com.yahoo.component.Version;
+
import java.util.Optional;
/**
@@ -18,7 +20,7 @@ public class ClusterMembership {
protected ClusterMembership() {}
- private ClusterMembership(String stringValue, Optional<String> dockerImage) {
+ private ClusterMembership(String stringValue, Optional<Version> vespaVersion) {
String restValue;
if (stringValue.endsWith("/retired")) {
retired = true;
@@ -32,9 +34,9 @@ public class ClusterMembership {
String[] components = restValue.split("/");
if ( components.length == 3) // Aug 2016: This should never happen any more
- initWithoutGroup(components, dockerImage);
+ initWithoutGroup(components, vespaVersion);
else if (components.length == 4)
- initWithGroup(components, dockerImage);
+ initWithGroup(components, vespaVersion);
else
throw new RuntimeException("Could not parse '" + stringValue + "' to a cluster membership. " +
"Expected 'id/type.index[/group]'");
@@ -49,16 +51,16 @@ public class ClusterMembership {
this.stringValue = toStringValue();
}
- private void initWithoutGroup(String[] components, Optional<String> dockerImage) {
- this.cluster = ClusterSpec.request(ClusterSpec.Type.valueOf(components[0]),
- ClusterSpec.Id.from(components[1]),
- dockerImage);
+ private void initWithoutGroup(String[] components, Optional<Version> vespaVersion) {
+ this.cluster = ClusterSpec.requestVersion(ClusterSpec.Type.valueOf(components[0]),
+ ClusterSpec.Id.from(components[1]),
+ vespaVersion);
this.index = Integer.parseInt(components[2]);
}
- private void initWithGroup(String[] components, Optional<String> dockerImage) {
+ private void initWithGroup(String[] components, Optional<Version> vespaVersion) {
this.cluster = ClusterSpec.from(ClusterSpec.Type.valueOf(components[0]), ClusterSpec.Id.from(components[1]),
- ClusterSpec.Group.from(Integer.valueOf(components[2])), dockerImage);
+ ClusterSpec.Group.from(Integer.valueOf(components[2])), vespaVersion);
this.index = Integer.parseInt(components[3]);
}
@@ -110,8 +112,14 @@ public class ClusterMembership {
@Override
public String toString() { return stringValue(); }
+ @Deprecated
+ // TODO: April 2017 - Remove this when no version older than 6.92 is in production
public static ClusterMembership from(String stringValue, Optional<String> dockerImage) {
- return new ClusterMembership(stringValue, dockerImage);
+ return fromVersion(stringValue, dockerImage.map(DockerImage::new).map(DockerImage::tagAsVersion));
+ }
+
+ public static ClusterMembership fromVersion(String stringValue, Optional<Version> vespaVersion) {
+ return new ClusterMembership(stringValue, vespaVersion);
}
public static ClusterMembership from(ClusterSpec cluster, int index) {
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterSpec.java b/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterSpec.java
index 79d4a5afc74..25c83d288eb 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterSpec.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterSpec.java
@@ -1,6 +1,7 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.provision;
+import com.yahoo.component.Version;
import java.util.Objects;
import java.util.Optional;
@@ -18,13 +19,13 @@ public final class ClusterSpec {
/** The group id of these hosts, or empty if this is represents a request for hosts */
private final Optional<Group> groupId;
- private final Optional<String> dockerImage;
+ private final Optional<Version> vespaVersion;
- private ClusterSpec(Type type, Id id, Optional<Group> groupId, Optional<String> dockerImage) {
+ private ClusterSpec(Type type, Id id, Optional<Group> groupId, Optional<Version> vespaVersion) {
this.type = type;
this.id = id;
this.groupId = groupId;
- this.dockerImage = dockerImage;
+ this.vespaVersion = vespaVersion;
}
/** Returns the cluster type */
@@ -33,27 +34,39 @@ public final class ClusterSpec {
/** Returns the cluster id */
public Id id() { return id; }
- public Optional<String> dockerImage() { return dockerImage; }
+ public Optional<Version> vespaVersion() { return vespaVersion; }
+
+ public Optional<String> dockerImage() {
+ return vespaVersion.map(DockerImage.defaultImage::withTag).map(DockerImage::toString);
+ }
/** Returns the group within the cluster this specifies, or empty to specify the whole cluster */
public Optional<Group> group() { return groupId; }
- public ClusterSpec changeGroup(Optional<Group> newGroup) { return new ClusterSpec(type, id, newGroup, dockerImage); }
+ public ClusterSpec changeGroup(Optional<Group> newGroup) { return new ClusterSpec(type, id, newGroup, vespaVersion); }
- /** Create a specification <b>specifying</b> an existing cluster group having these attributes */
- public static ClusterSpec from(Type type, Id id, Group groupId, Optional<String> dockerImage) {
- return new ClusterSpec(type, id, Optional.of(groupId), dockerImage);
+ /** Create a specification <b>requesting</b> a cluster with these attributes */
+ @Deprecated
+ // TODO: April 2017 - Remove this we no longer have old config-models using it
+ public static ClusterSpec request(Type type, Id id, Optional<String> dockerImage) {
+ return requestVersion(type, id, dockerImage.map(DockerImage::new).map(DockerImage::tagAsVersion));
}
/** Create a specification <b>requesting</b> a cluster with these attributes */
- public static ClusterSpec request(Type type, Id id, Optional<String> dockerImage) {
- return new ClusterSpec(type, id, Optional.empty(), dockerImage);
+ public static ClusterSpec requestVersion(Type type, Id id, Optional<Version> vespaVersion) {
+ return new ClusterSpec(type, id, Optional.empty(), vespaVersion);
+ }
+
+ /** Create a specification <b>specifying</b> an existing cluster group having these attributes */
+ public static ClusterSpec from(Type type, Id id, Group groupId, Optional<Version> vespaVersion) {
+ return new ClusterSpec(type, id, Optional.of(groupId), vespaVersion);
}
@Override
public String toString() {
- return String.join(" ", type.toString(), id.toString(),
- groupId.map(Group::toString).orElse(""), dockerImage.orElse(""));
+ return String.join(" ", type.toString(), id.toString(),
+ groupId.map(Group::toString).orElse(""),
+ vespaVersion.orElse(Version.emptyVersion).toString());
}
@Override
@@ -67,12 +80,12 @@ public final class ClusterSpec {
if ( ! other.type.equals(this.type)) return false;
if ( ! other.id.equals(this.id)) return false;
if ( ! other.groupId.equals(this.groupId)) return false;
- if ( ! other.dockerImage.equals(this.dockerImage)) return false;
+ if ( ! other.vespaVersion.equals(this.vespaVersion)) return false;
return true;
}
- /** Returns whether this is equal, disregarding the group value and wanted docker image */
- public boolean equalsIgnoringGroupAndDockerImage(Object o) {
+ /** Returns whether this is equal, disregarding the group value and wanted Vespa version */
+ public boolean equalsIgnoringGroupAndVespaVersion(Object o) {
if (o == this) return true;
if ( ! (o instanceof ClusterSpec)) return false;
ClusterSpec other = (ClusterSpec)o;
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/DockerImage.java b/config-provisioning/src/main/java/com/yahoo/config/provision/DockerImage.java
new file mode 100644
index 00000000000..2c6c9d82419
--- /dev/null
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/DockerImage.java
@@ -0,0 +1,39 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.config.provision;
+
+import com.yahoo.component.Version;
+
+/**
+ * A Docker image.
+ *
+ * @author mpolden
+ */
+public class DockerImage {
+
+ public static final DockerImage defaultImage = new DockerImage("docker-registry.ops.yahoo.com:4443/vespa/ci");
+
+ private final String name;
+
+ public DockerImage(String name) {
+ this.name = name;
+ }
+
+ /** Get Docker image tag as version */
+ public Version tagAsVersion() {
+ String[] parts = toString().split(":");
+ if (parts.length < 2) {
+ throw new IllegalArgumentException("Could not parse tag from Docker image '" + toString() + "'");
+ }
+ return Version.fromString(parts[parts.length - 1]);
+ }
+
+ /** Returns the Docker image tagged with the given version */
+ public DockerImage withTag(Version version) {
+ return new DockerImage(name + ":" + version.toFullString());
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/config-provisioning/src/test/java/com/yahoo/config/provision/ClusterMembershipTest.java b/config-provisioning/src/test/java/com/yahoo/config/provision/ClusterMembershipTest.java
index 7cf0abecc2d..56da6dbcaa7 100644
--- a/config-provisioning/src/test/java/com/yahoo/config/provision/ClusterMembershipTest.java
+++ b/config-provisioning/src/test/java/com/yahoo/config/provision/ClusterMembershipTest.java
@@ -2,12 +2,12 @@
package com.yahoo.config.provision;
import org.junit.Test;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
import java.util.Optional;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
/**
* @author bratseth
@@ -16,24 +16,24 @@ public class ClusterMembershipTest {
@Test
public void testContainerServiceInstance() {
- ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("id1"), Optional.empty());
+ ClusterSpec cluster = ClusterSpec.requestVersion(ClusterSpec.Type.container, ClusterSpec.Id.from("id1"), Optional.empty());
assertContainerService(ClusterMembership.from(cluster, 3));
}
@Test
public void testContainerServiceInstanceFromString() {
- assertContainerService(ClusterMembership.from("container/id1/3", Optional.empty()));
+ assertContainerService(ClusterMembership.fromVersion("container/id1/3", Optional.empty()));
}
@Test
public void testServiceInstance() {
- ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("id1"), Optional.empty());
+ ClusterSpec cluster = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("id1"), Optional.empty());
assertContentService(ClusterMembership.from(cluster, 37));
}
@Test
public void testServiceInstanceFromString() {
- assertContentService(ClusterMembership.from("content/id1/37", Optional.empty()));
+ assertContentService(ClusterMembership.fromVersion("content/id1/37", Optional.empty()));
}
@Test
@@ -50,7 +50,7 @@ public class ClusterMembershipTest {
@Test
public void testServiceInstanceWithRetire() {
- ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("id1"), Optional.empty());
+ ClusterSpec cluster = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("id1"), Optional.empty());
assertContentServiceWithRetire(ClusterMembership.retiredFrom(cluster, 37));
}
diff --git a/config-provisioning/src/test/java/com/yahoo/config/provision/ProvisionInfoTest.java b/config-provisioning/src/test/java/com/yahoo/config/provision/ProvisionInfoTest.java
index b4239f2b3bd..52b4f6853b8 100644
--- a/config-provisioning/src/test/java/com/yahoo/config/provision/ProvisionInfoTest.java
+++ b/config-provisioning/src/test/java/com/yahoo/config/provision/ProvisionInfoTest.java
@@ -10,10 +10,6 @@ import java.util.Optional;
import java.util.Set;
import static org.junit.Assert.assertEquals;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
@@ -25,7 +21,7 @@ public class ProvisionInfoTest {
private final HostSpec h1 = new HostSpec("host1", Optional.empty());
private final HostSpec h2 = new HostSpec("host2", Optional.empty());
private final HostSpec h3 = new HostSpec("host3", Optional.of(ClusterMembership.from("container/test/0", Optional.empty())));
- private final HostSpec h4 = new HostSpec("host4", Optional.of(ClusterMembership.from("container/test/1", Optional.of("dockerImg"))));
+ private final HostSpec h4 = new HostSpec("host4", Optional.of(ClusterMembership.from("container/test/1", Optional.of("docker-registry.ops.yahoo.com:4443/vespa/ci:6.42.1"))));
@Test
public void testProvisionInfoSerialization() throws IOException {
@@ -61,7 +57,7 @@ public class ProvisionInfoTest {
assertTrue(serializedInfo.getHosts().contains(h4));
assertTrue(!getHost(h1.hostname(), serializedInfo.getHosts()).membership().isPresent());
assertEquals("container/test/0", getHost(h3.hostname(), serializedInfo.getHosts()).membership().get().stringValue());
- assertEquals("dockerImg", getHost(h4.hostname(), serializedInfo.getHosts()).membership().get().cluster().dockerImage().get());
+ assertEquals("docker-registry.ops.yahoo.com:4443/vespa/ci:6.42.1", getHost(h4.hostname(), serializedInfo.getHosts()).membership().get().cluster().dockerImage().get());
}
private HostSpec getHost(String hostname, Set<HostSpec> hosts) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/provision/StaticProvisioner.java b/configserver/src/main/java/com/yahoo/vespa/config/server/provision/StaticProvisioner.java
index 2850241f493..f6b82a03088 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/provision/StaticProvisioner.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/provision/StaticProvisioner.java
@@ -36,7 +36,7 @@ public class StaticProvisioner implements HostProvisioner {
if (requestedCluster.group().isPresent()) // we are requesting a specific group
return nodeCluster.equals(requestedCluster);
else // we are requesting nodes of all groups in this cluster
- return nodeCluster.equalsIgnoringGroupAndDockerImage(requestedCluster);
+ return nodeCluster.equalsIgnoringGroupAndVespaVersion(requestedCluster);
}
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java
index 9b7e0f1b25a..090c4e6bfef 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java
@@ -6,7 +6,10 @@ import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.ClusterMembership;
+import com.yahoo.config.provision.DockerImage;
+import com.yahoo.config.provision.Flavor;
import com.yahoo.config.provision.InstanceName;
+import com.yahoo.config.provision.NodeFlavors;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.TenantName;
import com.yahoo.slime.ArrayTraverser;
@@ -17,10 +20,8 @@ import com.yahoo.vespa.config.SlimeUtils;
import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.node.Agent;
import com.yahoo.vespa.hosted.provision.node.Allocation;
-import com.yahoo.config.provision.Flavor;
import com.yahoo.vespa.hosted.provision.node.Generation;
import com.yahoo.vespa.hosted.provision.node.History;
-import com.yahoo.config.provision.NodeFlavors;
import com.yahoo.vespa.hosted.provision.node.Status;
import java.io.IOException;
@@ -73,6 +74,7 @@ public class NodeSerializer {
private static final String removableKey = "removable";
// Saved as part of allocation instead of serviceId, since serviceId serialized form is not easily extendable.
private static final String dockerImageKey = "dockerImage";
+ private static final String wantedVespaVersionKey = "wantedVespaVersion";
// History event fields
private static final String historyEventTypeKey = "type";
@@ -124,8 +126,8 @@ public class NodeSerializer {
object.setLong(restartGenerationKey, allocation.restartGeneration().wanted());
object.setLong(currentRestartGenerationKey, allocation.restartGeneration().current());
object.setBool(removableKey, allocation.isRemovable());
- allocation.membership().cluster().dockerImage()
- .ifPresent( dockerImage -> object.setString(dockerImageKey, dockerImage));
+ allocation.membership().cluster().vespaVersion()
+ .ifPresent(version -> object.setString(wantedVespaVersionKey, version.toString()));
}
private void toSlime(History history, Cursor array) {
@@ -180,8 +182,7 @@ public class NodeSerializer {
private Optional<Allocation> allocationFromSlime(Inspector object) {
if ( ! object.valid()) return Optional.empty();
return Optional.of(new Allocation(applicationIdFromSlime(object),
- ClusterMembership.from(object.field(serviceIdKey).asString(),
- optionalString(object.field(dockerImageKey))),
+ clusterMembershipFromSlime(object),
generationFromSlime(object, restartGenerationKey, currentRestartGenerationKey),
object.field(removableKey).asBool()));
}
@@ -215,6 +216,19 @@ public class NodeSerializer {
return new Generation(object.field(wantedField).asLong(), current.asLong());
}
+ // TODO: Simplify and inline after April 2017
+ private ClusterMembership clusterMembershipFromSlime(Inspector object) {
+ Optional<Version> vespaVersion;
+ if (object.field(dockerImageKey).valid()) {
+ vespaVersion = optionalString(object.field(dockerImageKey))
+ .map(DockerImage::new)
+ .map(DockerImage::tagAsVersion);
+ } else {
+ vespaVersion = softwareVersionFromSlime(object.field(wantedVespaVersionKey));
+ }
+ return ClusterMembership.fromVersion(object.field(serviceIdKey).asString(), vespaVersion);
+ }
+
private Optional<Version> softwareVersionFromSlime(Inspector object) {
if ( ! object.valid()) return Optional.empty();
return Optional.of(Version.fromString(object.asString()));
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java
index 07dbe7eeb50..c611438fcbe 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java
@@ -221,7 +221,7 @@ class GroupPreparer {
boolean wantToRetireNode = false;
ClusterMembership membership = offered.allocation().get().membership();
if ( ! offered.allocation().get().owner().equals(application)) continue; // wrong application
- if ( ! membership.cluster().equalsIgnoringGroupAndDockerImage(cluster)) continue; // wrong cluster id/type
+ if ( ! membership.cluster().equalsIgnoringGroupAndVespaVersion(cluster)) continue; // wrong cluster id/type
if ((! canChangeGroup || saturated()) && ! membership.cluster().group().equals(cluster.group())) continue; // wrong group and we can't or have no reason to change it
if ( offered.allocation().get().isRemovable()) continue; // don't accept; causes removal
if ( indexes.contains(membership.index())) continue; // duplicate index (just to be sure)
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java
index 6c096f9a743..a7b7f362df3 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java
@@ -156,6 +156,7 @@ class NodesResponse extends HttpResponse {
object.setLong("restartGeneration", node.allocation().get().restartGeneration().wanted());
object.setLong("currentRestartGeneration", node.allocation().get().restartGeneration().current());
node.allocation().get().membership().cluster().dockerImage().ifPresent(image -> object.setString("wantedDockerImage", image));
+ node.allocation().get().membership().cluster().vespaVersion().ifPresent(version -> object.setString("wantedVespaVersion", version.toFullString()));
}
object.setLong("rebootGeneration", node.status().reboot().wanted());
object.setLong("currentRebootGeneration", node.status().reboot().current());
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
index 46d8e553fd6..ef9639ed460 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
@@ -101,15 +101,15 @@ public class MockNodeRepository extends NodeRepository {
setDirty("host55.yahoo.com");
ApplicationId app1 = ApplicationId.from(TenantName.from("tenant1"), ApplicationName.from("application1"), InstanceName.from("instance1"));
- ClusterSpec cluster1 = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("id1"), Optional.of("image-123"));
+ ClusterSpec cluster1 = ClusterSpec.requestVersion(ClusterSpec.Type.container, ClusterSpec.Id.from("id1"), Optional.of(Version.fromString("6.42")));
provisioner.prepare(app1, cluster1, Capacity.fromNodeCount(2), 1, null);
ApplicationId app2 = ApplicationId.from(TenantName.from("tenant2"), ApplicationName.from("application2"), InstanceName.from("instance2"));
- ClusterSpec cluster2 = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("id2"), Optional.empty());
+ ClusterSpec cluster2 = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("id2"), Optional.empty());
activate(provisioner.prepare(app2, cluster2, Capacity.fromNodeCount(2), 1, null), app2, provisioner);
ApplicationId app3 = ApplicationId.from(TenantName.from("tenant3"), ApplicationName.from("application3"), InstanceName.from("instance3"));
- ClusterSpec cluster3 = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("id3"), Optional.empty());
+ ClusterSpec cluster3 = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("id3"), Optional.empty());
activate(provisioner.prepare(app3, cluster3, Capacity.fromNodeCount(2), 1, null), app3, provisioner);
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirerTest.java
index 399ef349ca0..35232e703c1 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirerTest.java
@@ -105,7 +105,7 @@ public class FailedExpirerTest {
List<Node> provisioned = nodeRepository.getNodes(NodeType.tenant, Node.State.provisioned);
nodeRepository.setReady(nodeRepository.setDirty(provisioned));
ApplicationId applicationId = ApplicationId.from(TenantName.from("foo"), ApplicationName.from("bar"), InstanceName.from("fuz"));
- ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
+ ClusterSpec cluster = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
provisioner.prepare(applicationId, cluster, Capacity.fromNodeCount(3), 1, null);
NestedTransaction transaction = new NestedTransaction().add(new CuratorTransaction(curator));
provisioner.activate(transaction, applicationId, ProvisioningTester.toHostSpecs(nodes));
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveAndFailedExpirerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveAndFailedExpirerTest.java
index c670c28a1ab..d0b7d78b217 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveAndFailedExpirerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveAndFailedExpirerTest.java
@@ -41,7 +41,7 @@ public class InactiveAndFailedExpirerTest {
List<Node> nodes = tester.makeReadyNodes(2, "default");
// Allocate then deallocate 2 nodes
- ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
+ ClusterSpec cluster = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
tester.prepare(applicationId, cluster, Capacity.fromNodeCount(2), 1);
tester.activate(applicationId, ProvisioningTester.toHostSpecs(nodes));
assertEquals(2, tester.getNodes(applicationId, Node.State.active).size());
@@ -78,7 +78,7 @@ public class InactiveAndFailedExpirerTest {
List<Node> nodes = tester.makeReadyNodes(1, "default");
// Allocate and deallocate a single node
- ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
+ ClusterSpec cluster = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
tester.prepare(applicationId, cluster, Capacity.fromNodeCount(1), 1);
tester.activate(applicationId, ProvisioningTester.toHostSpecs(nodes));
assertEquals(1, tester.getNodes(applicationId, Node.State.active).size());
@@ -104,8 +104,8 @@ public class InactiveAndFailedExpirerTest {
@Test
public void node_that_wants_to_retire_is_moved_to_parked() {
ProvisioningTester tester = new ProvisioningTester(new Zone(Environment.prod, RegionName.from("us-east")));
- ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test"),
- Optional.empty());
+ ClusterSpec cluster = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("test"),
+ Optional.empty());
tester.makeReadyNodes(5, "default");
// Allocate two nodes
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java
index 07722460c66..86aef3617f0 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java
@@ -1,5 +1,6 @@
package com.yahoo.vespa.hosted.provision.maintenance;
+import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.Capacity;
@@ -102,8 +103,8 @@ public class NodeFailTester {
tester.createHostNodes(3);
// Create applications
- ClusterSpec clusterApp1 = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("test"), Optional.empty());
- ClusterSpec clusterApp2 = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
+ ClusterSpec clusterApp1 = ClusterSpec.requestVersion(ClusterSpec.Type.container, ClusterSpec.Id.from("test"), Optional.empty());
+ ClusterSpec clusterApp2 = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
int wantedNodesApp1 = 5;
int wantedNodesApp2 = 7;
tester.activate(app1, clusterApp1, wantedNodesApp1);
@@ -131,9 +132,9 @@ public class NodeFailTester {
}
// Create applications
- ClusterSpec clusterNodeAdminApp = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("node-admin"), Optional.empty());
- ClusterSpec clusterApp1 = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("test"), Optional.of("vespa:6.75.0"));
- ClusterSpec clusterApp2 = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.of("vespa:6.75.0"));
+ ClusterSpec clusterNodeAdminApp = ClusterSpec.requestVersion(ClusterSpec.Type.container, ClusterSpec.Id.from("node-admin"), Optional.empty());
+ ClusterSpec clusterApp1 = ClusterSpec.requestVersion(ClusterSpec.Type.container, ClusterSpec.Id.from("test"), Optional.of(Version.fromString("6.75.0")));
+ ClusterSpec clusterApp2 = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.of(Version.fromString("6.75.0")));
Capacity allHosts = Capacity.fromRequiredNodeType(NodeType.host);
Capacity capacity1 = Capacity.fromNodeCount(3, Optional.of("docker"));
Capacity capacity2 = Capacity.fromNodeCount(5, Optional.of("docker"));
@@ -162,7 +163,7 @@ public class NodeFailTester {
// Create application
Capacity allProxies = Capacity.fromRequiredNodeType(NodeType.proxy);
- ClusterSpec clusterApp1 = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("test"), Optional.empty());
+ ClusterSpec clusterApp1 = ClusterSpec.requestVersion(ClusterSpec.Type.container, ClusterSpec.Id.from("test"), Optional.empty());
tester.activate(app1, clusterApp1, allProxies);
assertEquals(16, tester.nodeRepository.getNodes(NodeType.proxy, Node.State.active).size());
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainerTest.java
index c4135b19a63..63b22ba4726 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainerTest.java
@@ -5,8 +5,6 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
-import com.yahoo.config.provision.Deployer;
-import com.yahoo.config.provision.Deployment;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.InstanceName;
@@ -27,7 +25,6 @@ import com.yahoo.vespa.hosted.provision.node.Agent;
import com.yahoo.vespa.hosted.provision.provisioning.NodeRepositoryProvisioner;
import com.yahoo.vespa.hosted.provision.testutils.FlavorConfigBuilder;
import com.yahoo.vespa.hosted.provision.testutils.MockNameResolver;
-import org.junit.Before;
import org.junit.Test;
import java.time.Duration;
@@ -111,8 +108,8 @@ public class OperatorChangeApplicationMaintainerTest {
final ApplicationId app1 = ApplicationId.from(TenantName.from("foo1"), ApplicationName.from("bar"), InstanceName.from("fuz"));
final ApplicationId app2 = ApplicationId.from(TenantName.from("foo2"), ApplicationName.from("bar"), InstanceName.from("fuz"));
- final ClusterSpec clusterApp1 = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("test"), Optional.empty());
- final ClusterSpec clusterApp2 = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
+ final ClusterSpec clusterApp1 = ClusterSpec.requestVersion(ClusterSpec.Type.container, ClusterSpec.Id.from("test"), Optional.empty());
+ final ClusterSpec clusterApp2 = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
final int wantedNodesApp1 = 5;
final int wantedNodesApp2 = 7;
MockDeployer deployer; // created on activation
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainerTest.java
index c8ca4777ff9..9094e3fc599 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainerTest.java
@@ -151,8 +151,8 @@ public class PeriodicApplicationMaintainerTest {
final ApplicationId app1 = ApplicationId.from(TenantName.from("foo1"), ApplicationName.from("bar"), InstanceName.from("fuz"));
final ApplicationId app2 = ApplicationId.from(TenantName.from("foo2"), ApplicationName.from("bar"), InstanceName.from("fuz"));
- final ClusterSpec clusterApp1 = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("test"), Optional.empty());
- final ClusterSpec clusterApp2 = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
+ final ClusterSpec clusterApp1 = ClusterSpec.requestVersion(ClusterSpec.Type.container, ClusterSpec.Id.from("test"), Optional.empty());
+ final ClusterSpec clusterApp2 = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
final int wantedNodesApp1 = 5;
final int wantedNodesApp2 = 7;
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/ReservationExpirerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/ReservationExpirerTest.java
index 8bf15bed0b7..8d41adec2cd 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/ReservationExpirerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/ReservationExpirerTest.java
@@ -52,7 +52,7 @@ public class ReservationExpirerTest {
assertEquals(2, nodeRepository.getNodes(NodeType.tenant, Node.State.dirty).size());
nodeRepository.setReady(nodes);
ApplicationId applicationId = new ApplicationId.Builder().tenant("foo").applicationName("bar").instanceName("fuz").build();
- ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
+ ClusterSpec cluster = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
provisioner.prepare(applicationId, cluster, Capacity.fromNodeCount(2), 1, null);
assertEquals(2, nodeRepository.getNodes(NodeType.tenant, Node.State.reserved).size());
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirerTest.java
index a71097cae06..3e6281d59a7 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirerTest.java
@@ -57,7 +57,7 @@ public class RetiredExpirerTest {
// Allocate content cluster of sizes 7 -> 2 -> 3:
// Should end up with 3 nodes in the cluster (one previously retired), and 3 retired
- ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
+ ClusterSpec cluster = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
int wantedNodes;
activate(applicationId, cluster, wantedNodes=7, 1, provisioner);
activate(applicationId, cluster, wantedNodes=2, 1, provisioner);
@@ -94,7 +94,7 @@ public class RetiredExpirerTest {
ApplicationId applicationId = ApplicationId.from(TenantName.from("foo"), ApplicationName.from("bar"), InstanceName.from("fuz"));
- ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
+ ClusterSpec cluster = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty());
activate(applicationId, cluster, 8, 8, provisioner);
activate(applicationId, cluster, 1, 1, provisioner);
assertEquals(8, nodeRepository.getNodes(applicationId, Node.State.active).size());
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java
index f83cd8f9694..940715db8b4 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java
@@ -6,6 +6,7 @@ import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.ClusterMembership;
+import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.NodeFlavors;
import com.yahoo.config.provision.NodeType;
@@ -64,7 +65,7 @@ public class SerializationTest {
node = node.allocate(ApplicationId.from(TenantName.from("myTenant"),
ApplicationName.from("myApplication"),
InstanceName.from("myInstance")),
- ClusterMembership.from("content/myId/0/0", Optional.empty()),
+ ClusterMembership.fromVersion("content/myId/0/0", Optional.empty()),
clock.instant());
assertEquals(1, node.history().events().size());
node = node.withRestart(new Generation(1, 2));
@@ -100,7 +101,7 @@ public class SerializationTest {
Node node = createNode().allocate(ApplicationId.from(TenantName.from("myTenant"),
ApplicationName.from("myApplication"),
InstanceName.from("myInstance")),
- ClusterMembership.from("content/myId/0/0", Optional.empty()),
+ ClusterMembership.fromVersion("content/myId/0/0", Optional.empty()),
clock.instant());
Node copy = nodeSerializer.fromJson(Node.State.provisioned, nodeSerializer.toJson(node));
assertEquals(NodeType.host, copy.type());
@@ -154,7 +155,7 @@ public class SerializationTest {
node = node.allocate(ApplicationId.from(TenantName.from("myTenant"),
ApplicationName.from("myApplication"),
InstanceName.from("myInstance")),
- ClusterMembership.from("content/myId/0", Optional.empty()),
+ ClusterMembership.fromVersion("content/myId/0", Optional.empty()),
clock.instant());
assertEquals(1, node.history().events().size());
clock.advance(Duration.ofMinutes(2));
@@ -202,7 +203,7 @@ public class SerializationTest {
node = node.allocate(ApplicationId.from(TenantName.from("myTenant"),
ApplicationName.from("myApplication"),
InstanceName.from("myInstance")),
- ClusterMembership.from("content/myId/0/0", Optional.empty()),
+ ClusterMembership.fromVersion("content/myId/0/0", Optional.empty()),
clock.instant());
node = node.with(node.status().setFailCount(0));
@@ -215,8 +216,10 @@ public class SerializationTest {
public void serialize_docker_image() {
Node node = createNode();
- Optional<String> dockerImage = Optional.of("my-docker-image");
- ClusterMembership clusterMembership = ClusterMembership.from("content/myId/0", dockerImage);
+ Optional<Version> version = Optional.of("docker-registry.ops.yahoo.com:4443/vespa/ci:6.42.0")
+ .map(DockerImage::new)
+ .map(DockerImage::tagAsVersion);
+ ClusterMembership clusterMembership = ClusterMembership.fromVersion("content/myId/0", version);
Node nodeWithAllocation = node.with(
new Allocation(ApplicationId.from(TenantName.from("myTenant"),
@@ -227,7 +230,7 @@ public class SerializationTest {
false));
Node deserializedNode = nodeSerializer.fromJson(State.provisioned, nodeSerializer.toJson(nodeWithAllocation));
- assertEquals(dockerImage, deserializedNode.allocation().get().membership().cluster().dockerImage());
+ assertEquals("docker-registry.ops.yahoo.com:4443/vespa/ci:6.42.0", deserializedNode.allocation().get().membership().cluster().dockerImage().get());
}
@Test
@@ -240,14 +243,14 @@ public class SerializationTest {
}
@Test
- public void serializes_multiple_ip_addresses() throws Exception {
+ public void serializes_multiple_ip_addresses() {
byte[] nodeWithMultipleIps = createNodeJson("node4.yahoo.tld", "127.0.0.4", "::4");
Node deserializedNode = nodeSerializer.fromJson(State.provisioned, nodeWithMultipleIps);
assertEquals(ImmutableSet.of("127.0.0.4", "::4"), deserializedNode.ipAddresses());
}
@Test
- public void want_to_retire_defaults_to_false() throws Exception {
+ public void want_to_retire_defaults_to_false() {
String nodeData =
"{\n" +
" \"type\" : \"tenant\",\n" +
@@ -260,6 +263,42 @@ public class SerializationTest {
assertFalse(node.status().wantToRetire());
}
+ @Test
+ // TODO: Remove after April 2017
+ public void vespa_version_serialization() throws Exception {
+ String nodeWithDockerImage =
+ "{\n" +
+ " \"type\" : \"tenant\",\n" +
+ " \"flavor\" : \"large\",\n" +
+ " \"openStackId\" : \"myId\",\n" +
+ " \"hostname\" : \"myHostname\",\n" +
+ " \"ipAddresses\" : [\"127.0.0.1\"],\n" +
+ " \"instance\": {\n" +
+ " \"serviceId\": \"content/myId/0\",\n" +
+ " \"dockerImage\": \"docker-registry.some.domain:4443/vespa/ci:6.42.1\"\n" +
+ " }\n" +
+ "}";
+ Node node = nodeSerializer.fromJson(State.active, Utf8.toBytes(nodeWithDockerImage));
+ assertEquals("6.42.1", node.allocation().get().membership().cluster().vespaVersion().get().toString());
+ assertEquals("docker-registry.ops.yahoo.com:4443/vespa/ci:6.42.1", node.allocation().get().membership().cluster().dockerImage().get());
+
+ String nodeWithWantedVespaVersion =
+ "{\n" +
+ " \"type\" : \"tenant\",\n" +
+ " \"flavor\" : \"large\",\n" +
+ " \"openStackId\" : \"myId\",\n" +
+ " \"hostname\" : \"myHostname\",\n" +
+ " \"ipAddresses\" : [\"127.0.0.1\"],\n" +
+ " \"instance\": {\n" +
+ " \"serviceId\": \"content/myId/0\",\n" +
+ " \"wantedVespaVersion\": \"6.42.2\"\n" +
+ " }\n" +
+ "}";
+ node = nodeSerializer.fromJson(State.active, Utf8.toBytes(nodeWithWantedVespaVersion));
+ assertEquals("6.42.2", node.allocation().get().membership().cluster().vespaVersion().get().toString());
+ assertEquals("docker-registry.ops.yahoo.com:4443/vespa/ci:6.42.2", node.allocation().get().membership().cluster().dockerImage().get());
+ }
+
private byte[] createNodeJson(String hostname, String... ipAddress) {
String ipAddressJsonPart = "";
if (ipAddress.length > 0) {
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AclProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AclProvisioningTest.java
index 2067061cd5f..4d83a5b5874 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AclProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AclProvisioningTest.java
@@ -223,8 +223,8 @@ public class AclProvisioningTest {
}
private List<Node> allocateNodes(Capacity capacity, ApplicationId applicationId) {
- ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test"),
- Optional.empty());
+ ClusterSpec cluster = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("test"),
+ Optional.empty());
List<HostSpec> prepared = tester.prepare(applicationId, cluster, capacity, 1);
tester.activate(applicationId, new HashSet<>(prepared));
return tester.getNodes(applicationId, Node.State.active).asList();
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java
index ee04e07fd10..3f3284115bc 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java
@@ -1,6 +1,7 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.provision.provisioning;
+import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
@@ -34,10 +35,10 @@ public class DockerProvisioningTest {
tester.makeReadyDockerNodes(1, dockerFlavor, "dockerHost" + i);
}
- Optional<String> wantedDockerImage = Optional.of("docker-registry.ops.yahoo.com:4443/vespa/ci:6.39");
+ Optional<Version> wantedVespaVersion = Optional.of(Version.fromString("6.39"));
final int nodeCount = 7;
List<HostSpec> hosts = tester.prepare(application1,
- ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), wantedDockerImage),
+ ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), wantedVespaVersion),
nodeCount, 1, dockerFlavor);
tester.activate(application1, new HashSet<>(hosts));
@@ -46,9 +47,9 @@ public class DockerProvisioningTest {
assertEquals(dockerFlavor, nodes.asList().get(0).flavor().canonicalName());
// Upgrade Vespa version on nodes
- Optional<String> upgradedWantedDockerImage = Optional.of("docker-registry.ops.yahoo.com:4443/vespa/ci:6.40");
+ Optional<Version> upgradedWantedVespaVersion = Optional.of(Version.fromString("6.40"));
List<HostSpec> upgradedHosts = tester.prepare(application1,
- ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), upgradedWantedDockerImage),
+ ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), upgradedWantedVespaVersion),
nodeCount, 1, dockerFlavor);
tester.activate(application1, new HashSet<>(upgradedHosts));
final NodeList upgradedNodes = tester.getNodes(application1, Node.State.active);
@@ -64,7 +65,7 @@ public class DockerProvisioningTest {
ApplicationId application1 = tester.makeApplicationId();
tester.makeReadyDockerNodes(1, dockerFlavor, "dockerHost");
- List<HostSpec> hosts = tester.prepare(application1, ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Optional.empty()), 1, 1, dockerFlavor);
+ List<HostSpec> hosts = tester.prepare(application1, ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Optional.empty()), 1, 1, dockerFlavor);
tester.activate(application1, new HashSet<>(hosts));
final NodeList nodes = tester.getNodes(application1, Node.State.active);
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/MultigroupProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/MultigroupProvisioningTest.java
index fa00b7d60b8..372819b3f98 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/MultigroupProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/MultigroupProvisioningTest.java
@@ -196,7 +196,7 @@ public class MultigroupProvisioningTest {
assertEquals("No additional groups are retained containing retired nodes", wantedGroups, allGroups.size());
}
- private ClusterSpec cluster() { return ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty()); }
+ private ClusterSpec cluster() { return ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Optional.empty()); }
private Set<HostSpec> prepare(ApplicationId application, Capacity capacity, int groupCount, ProvisioningTester tester) {
return new HashSet<>(tester.prepare(application, cluster(), capacity, groupCount));
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/NodeTypeProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/NodeTypeProvisioningTest.java
index f7b6d672d5f..a3ff24d0e73 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/NodeTypeProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/NodeTypeProvisioningTest.java
@@ -4,12 +4,10 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
-import com.yahoo.config.provision.HostFilter;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.Zone;
-import com.yahoo.transaction.NestedTransaction;
import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.node.Agent;
import org.junit.Test;
@@ -85,9 +83,9 @@ public class NodeTypeProvisioningTest {
private List<HostSpec> deployProxies(ApplicationId application, ProvisioningTester tester) {
return tester.prepare(application,
- ClusterSpec.request(ClusterSpec.Type.container,
- ClusterSpec.Id.from("test"),
- Optional.empty()),
+ ClusterSpec.requestVersion(ClusterSpec.Type.container,
+ ClusterSpec.Id.from("test"),
+ Optional.empty()),
Capacity.fromRequiredNodeType(NodeType.proxy),
1);
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java
index f4006480f2a..a12d77ecbd5 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java
@@ -657,8 +657,8 @@ public class ProvisioningTest {
tester.makeReadyNodes(6, "large-variant-variant"); //cost = 11
ApplicationId applicationId = tester.makeApplicationId();
- ClusterSpec contentClusterSpec = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Optional.empty());
- ClusterSpec containerClusterSpec = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("myContainer"), Optional.empty());
+ ClusterSpec contentClusterSpec = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Optional.empty());
+ ClusterSpec containerClusterSpec = ClusterSpec.requestVersion(ClusterSpec.Type.container, ClusterSpec.Id.from("myContainer"), Optional.empty());
List<HostSpec> containerNodes = tester.prepare(applicationId, containerClusterSpec, 5, 1, "large");
List<HostSpec> contentNodes = tester.prepare(applicationId, contentClusterSpec, 10, 1, "large");
@@ -679,10 +679,10 @@ public class ProvisioningTest {
private SystemState prepare(ApplicationId application, int container0Size, int container1Size, int content0Size, int content1Size, String flavor, ProvisioningTester tester) {
// "deploy prepare" with a two container clusters and a storage cluster having of two groups
- ClusterSpec containerCluster0 = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("container0"), Optional.empty());
- ClusterSpec containerCluster1 = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("container1"), Optional.empty());
- ClusterSpec contentCluster0 = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("content0"), Optional.empty());
- ClusterSpec contentCluster1 = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("content1"), Optional.empty());
+ ClusterSpec containerCluster0 = ClusterSpec.requestVersion(ClusterSpec.Type.container, ClusterSpec.Id.from("container0"), Optional.empty());
+ ClusterSpec containerCluster1 = ClusterSpec.requestVersion(ClusterSpec.Type.container, ClusterSpec.Id.from("container1"), Optional.empty());
+ ClusterSpec contentCluster0 = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("content0"), Optional.empty());
+ ClusterSpec contentCluster1 = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("content1"), Optional.empty());
Set<HostSpec> container0 = prepare(application, containerCluster0, container0Size, 1, flavor, tester);
Set<HostSpec> container1 = prepare(application, containerCluster1, container1Size, 1, flavor, tester);
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java
index 617211f7da5..bbf8967c254 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java
@@ -183,7 +183,7 @@ public class ProvisioningTester implements AutoCloseable {
Set<Integer> indices = new HashSet<>();
for (HostSpec host : hosts) {
ClusterSpec nodeCluster = host.membership().get().cluster();
- assertTrue(requestedCluster.equalsIgnoringGroupAndDockerImage(nodeCluster));
+ assertTrue(requestedCluster.equalsIgnoringGroupAndVespaVersion(nodeCluster));
if (requestedCluster.group().isPresent())
assertEquals(requestedCluster.group(), nodeCluster.group());
else
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningTest.java
index 7b166e957ef..ac7fdc3d44f 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningTest.java
@@ -31,8 +31,8 @@ import static org.junit.Assert.assertNotNull;
public class VirtualNodeProvisioningTest {
private static final String flavor = "v-4-8-100";
- private static final ClusterSpec contentClusterSpec = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Optional.empty());
- private static final ClusterSpec containerClusterSpec = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("myContainer"), Optional.empty());
+ private static final ClusterSpec contentClusterSpec = ClusterSpec.requestVersion(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Optional.empty());
+ private static final ClusterSpec containerClusterSpec = ClusterSpec.requestVersion(ClusterSpec.Type.container, ClusterSpec.Id.from("myContainer"), Optional.empty());
private ProvisioningTester tester;
private ApplicationId applicationId;
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node10.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node10.json
index 3a72cb2fbaa..bfa88681879 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node10.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node10.json
@@ -27,7 +27,8 @@
},
"restartGeneration": 0,
"currentRestartGeneration": 0,
- "wantedDockerImage":"image-123",
+ "wantedDockerImage":"docker-registry.ops.yahoo.com:4443/vespa/ci:6.42.0",
+ "wantedVespaVersion": "6.42.0",
"rebootGeneration": 1,
"currentRebootGeneration": 0,
"vespaVersion": "5.104.142",
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4-after-changes.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4-after-changes.json
index 696806eefa8..281a87ea372 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4-after-changes.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4-after-changes.json
@@ -27,7 +27,8 @@
},
"restartGeneration": 0,
"currentRestartGeneration": 1,
- "wantedDockerImage": "image-123",
+ "wantedDockerImage": "docker-registry.ops.yahoo.com:4443/vespa/ci:6.42.0",
+ "wantedVespaVersion": "6.42.0",
"rebootGeneration": 2,
"currentRebootGeneration": 1,
"vespaVersion": "5.104.142",
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4.json
index a42db8aa266..04db01226da 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4.json
@@ -27,7 +27,8 @@
},
"restartGeneration": 0,
"currentRestartGeneration": 0,
- "wantedDockerImage":"image-123",
+ "wantedDockerImage":"docker-registry.ops.yahoo.com:4443/vespa/ci:6.42.0",
+ "wantedVespaVersion": "6.42.0",
"rebootGeneration": 1,
"currentRebootGeneration": 0,
"currentDockerImage":"image-12",