aboutsummaryrefslogtreecommitdiffstats
path: root/node-repository
diff options
context:
space:
mode:
authorHarald Musum <musum@verizonmedia.com>2020-03-19 13:49:16 +0100
committerHarald Musum <musum@verizonmedia.com>2020-03-19 13:49:16 +0100
commit1760ca738f4d0d463535299ba64a06f50811c3b1 (patch)
treeee1573744f4e63743829200a1394d67d16aa3c4f /node-repository
parent141c98cbcf97153858d6ae5a535e331d7cf174ca (diff)
Serialize and deserialize docker image repo
Diffstat (limited to 'node-repository')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java3
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java4
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java7
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java86
4 files changed, 72 insertions, 28 deletions
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 be43c0139e0..bd5ba514a1f 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
@@ -187,8 +187,7 @@ public class NodeSerializer {
object.setLong(currentRestartGenerationKey, allocation.restartGeneration().current());
object.setBool(removableKey, allocation.isRemovable());
object.setString(wantedVespaVersionKey, allocation.membership().cluster().vespaVersion().toString());
- // TODO serialize dockerImageRepo
- //object.setString(wantedDockerImageRepoKey, allocation.membership().cluster().dockerImageRepo().orElse(""));
+ object.setString(wantedDockerImageRepoKey, allocation.membership().cluster().dockerImageRepo().orElse(""));
allocation.networkPorts().ifPresent(ports -> NetworkPortsSerializer.toSlime(ports, object.setArray(networkPortsKey)));
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java
index 7a49ad9c44d..73061acd9c1 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java
@@ -5,6 +5,7 @@ import com.google.inject.Inject;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.HostFilter;
import com.yahoo.config.provision.HostSpec;
@@ -148,7 +149,8 @@ public class NodeRepositoryProvisioner implements Provisioner {
Optional.of(nodeAllocation.membership()),
node.status().vespaVersion(),
nodeAllocation.networkPorts(),
- requestedResources));
+ requestedResources,
+ node.status().dockerImage().map(DockerImage::repository)));
if (nodeAllocation.networkPorts().isPresent()) {
log.log(LogLevel.DEBUG, () -> "Prepared node " + node.hostname() + " has port allocations");
}
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 7f283452538..c96458a0433 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
@@ -157,8 +157,11 @@ class NodesResponse extends HttpResponse {
toSlime(allocation.membership(), object.setObject("membership"));
object.setLong("restartGeneration", allocation.restartGeneration().wanted());
object.setLong("currentRestartGeneration", allocation.restartGeneration().current());
- object.setString("wantedDockerImage", nodeRepository.dockerImage(node).withTag(allocation.membership().cluster().vespaVersion()).asString());
- object.setString("wantedVespaVersion", allocation.membership().cluster().vespaVersion().toFullString());
+ String wantedVespaVersion = allocation.membership().cluster().vespaVersion().toFullString();
+ Optional<String> dockerImageRepo = allocation.membership().cluster().dockerImageRepo();
+ object.setString("wantedDockerImage", dockerImageRepo.map(s -> s + ":" + wantedVespaVersion)
+ .orElseGet(() -> nodeRepository.dockerImage(node).withTag(allocation.membership().cluster().vespaVersion()).asString()));
+ object.setString("wantedVespaVersion", wantedVespaVersion);
toSlime(allocation.requestedResources(), object.setObject("requestedResources"));
allocation.networkPorts().ifPresent(ports -> NetworkPortsSerializer.toSlime(ports, object.setArray("networkPorts")));
orchestrator.apply(new HostName(node.hostname()))
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 1f9d7ce5126..0919e537420 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
@@ -6,6 +6,7 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.HostFilter;
import com.yahoo.config.provision.HostSpec;
@@ -157,6 +158,33 @@ public class ProvisioningTest {
}
@Test
+ public void dockerImageRepoIsReturnedIfSet() {
+ ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.dev, RegionName.from("us-east"))).build();
+
+ tester.makeReadyNodes(4, defaultResources, NodeType.host, 1);
+ tester.prepareAndActivateInfraApplication(tester.makeApplicationId(), NodeType.host);
+
+ // deploy
+ ApplicationId application1 = tester.makeApplicationId();
+ SystemState state1 = prepare(application1, tester, 1, 1, 1, 1, defaultResources, "1.2.3");
+ String dockerImageRepo = "docker.domain.tld/my/image";
+ prepare(application1, tester, 1, 1, 1 , 1 , false, defaultResources, "1.2.3", Optional.of(dockerImageRepo));
+ tester.activate(application1, state1.allHosts);
+
+ HostSpec host1 = state1.container0.iterator().next();
+ assertFalse(host1.version().isPresent());
+ Node node1 = tester.nodeRepository().getNode(host1.hostname()).get();
+ tester.nodeRepository().write(node1.with(node1.status().withDockerImage(DockerImage.fromString(dockerImageRepo))), () -> {});
+
+ // redeploy
+ SystemState state2 = prepare(application1, tester, 1, 1, 1 ,1 , false, defaultResources, "1.2.3", Optional.of(dockerImageRepo));
+ tester.activate(application1, state2.allHosts);
+
+ host1 = state2.container0.iterator().next();
+ assertEquals(dockerImageRepo, host1.dockerImageRepo().get());
+ }
+
+ @Test
public void application_deployment_variable_application_size() {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
@@ -334,7 +362,21 @@ public class ProvisioningTest {
tester.prepareAndActivateInfraApplication(tester.makeApplicationId(), NodeType.host);
ApplicationId application = tester.makeApplicationId();
- SystemState state = prepare(application, 2, 2, 3, 3, defaultResources, Version.fromString("6.91"), tester);
+ SystemState state = prepare(application, tester, 2, 2, 3, 3, defaultResources, "6.91");
+ assertEquals(4, state.allHosts.size());
+ tester.activate(application, state.allHosts);
+ }
+
+ @Test
+ public void deploy_specific_vespa_version_and_docker_image() {
+ ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.dev, RegionName.from("us-east"))).build();
+
+ tester.makeReadyNodes(4, defaultResources, NodeType.host, 1);
+ tester.prepareAndActivateInfraApplication(tester.makeApplicationId(), NodeType.host);
+
+ ApplicationId application = tester.makeApplicationId();
+ String dockerImageRepo = "docker.domain.tld/my/image";
+ SystemState state = prepare(application, tester, 2, 2, 3, 3, false, defaultResources, "6.91", Optional.of(dockerImageRepo));
assertEquals(4, state.allHosts.size());
tester.activate(application, state.allHosts);
}
@@ -630,7 +672,7 @@ public class ProvisioningTest {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
ApplicationId application = tester.makeApplicationId();
try {
- prepare(application, 1, 0, 1, 0, true, defaultResources, Version.fromString("6.42"), tester);
+ prepare(application, tester, 1, 0, 1, 0, true, defaultResources, "6.42", Optional.empty());
fail("Expected exception");
} catch (IllegalArgumentException ignored) {}
}
@@ -652,17 +694,17 @@ public class ProvisioningTest {
public void cluster_spec_update_for_already_reserved_nodes() {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.dev, RegionName.from("us-east"))).build();
ApplicationId application = tester.makeApplicationId();
- Version version1 = Version.fromString("6.42");
- Version version2 = Version.fromString("6.43");
+ String version1 = "6.42";
+ String version2 = "6.43";
tester.makeReadyNodes(2, defaultResources);
- prepare(application, 1, 0, 1, 0, true, defaultResources, version1, tester);
+ prepare(application, tester, 1, 0, 1, 0, true, defaultResources, version1, Optional.empty());
tester.getNodes(application, Node.State.reserved).forEach(node ->
- assertEquals(version1, node.allocation().get().membership().cluster().vespaVersion()));
+ assertEquals(Version.fromString(version1), node.allocation().get().membership().cluster().vespaVersion()));
- prepare(application, 1, 0, 1, 0, true, defaultResources, version2, tester);
+ prepare(application, tester, 1, 0, 1, 0, true, defaultResources, version2, Optional.empty());
tester.getNodes(application, Node.State.reserved).forEach(node ->
- assertEquals(version2, node.allocation().get().membership().cluster().vespaVersion()));
+ assertEquals(Version.fromString(version2), node.allocation().get().membership().cluster().vespaVersion()));
}
@Test
@@ -702,29 +744,27 @@ public class ProvisioningTest {
private SystemState prepare(ApplicationId application, int container0Size, int container1Size, int content0Size,
int content1Size, NodeResources flavor, ProvisioningTester tester) {
- return prepare(application, container0Size, container1Size, content0Size, content1Size, flavor,
- Version.fromString("6.42"), tester);
+ return prepare(application, tester, container0Size, container1Size, content0Size, content1Size, flavor, "6.42");
}
- private SystemState prepare(ApplicationId application, int container0Size, int container1Size, int content0Size,
- int content1Size, NodeResources nodeResources, Version wantedVersion, ProvisioningTester tester) {
- return prepare(application, container0Size, container1Size, content0Size, content1Size, false, nodeResources,
- wantedVersion, tester);
+ private SystemState prepare(ApplicationId application, ProvisioningTester tester, int container0Size, int container1Size, int content0Size,
+ int content1Size, NodeResources nodeResources, String wantedVersion) {
+ return prepare(application, tester, container0Size, container1Size, content0Size, content1Size, false, nodeResources,
+ wantedVersion, Optional.empty());
}
- private SystemState prepare(ApplicationId application, int container0Size, int container1Size, int content0Size,
- int content1Size, boolean required, NodeResources nodeResources, Version wantedVersion,
- ProvisioningTester tester) {
+ private SystemState prepare(ApplicationId application, ProvisioningTester tester, int container0Size, int container1Size, int content0Size,
+ int content1Size, boolean required, NodeResources nodeResources, String wantedVersion, Optional<String> dockerImageRepo) {
// "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")).vespaVersion(wantedVersion).build();
ClusterSpec containerCluster1 = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("container1")).vespaVersion(wantedVersion).build();
ClusterSpec contentCluster0 = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("content0")).vespaVersion(wantedVersion).build();
ClusterSpec contentCluster1 = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("content1")).vespaVersion(wantedVersion).build();
- Set<HostSpec> container0 = prepare(application, containerCluster0, container0Size, 1, required, nodeResources, tester);
- Set<HostSpec> container1 = prepare(application, containerCluster1, container1Size, 1, required, nodeResources, tester);
- Set<HostSpec> content0 = prepare(application, contentCluster0, content0Size, 1, required, nodeResources, tester);
- Set<HostSpec> content1 = prepare(application, contentCluster1, content1Size, 1, required, nodeResources, tester);
+ Set<HostSpec> container0 = prepare(application, tester, containerCluster0, container0Size, 1, required, nodeResources);
+ Set<HostSpec> container1 = prepare(application, tester, containerCluster1, container1Size, 1, required, nodeResources);
+ Set<HostSpec> content0 = prepare(application, tester, contentCluster0, content0Size, 1, required, nodeResources);
+ Set<HostSpec> content1 = prepare(application, tester, contentCluster1, content1Size, 1, required, nodeResources);
Set<HostSpec> allHosts = new HashSet<>();
allHosts.addAll(container0);
@@ -755,8 +795,8 @@ public class ProvisioningTest {
return new SystemState(allHosts, container0, container1, content0, content1);
}
- private Set<HostSpec> prepare(ApplicationId application, ClusterSpec cluster, int nodeCount, int groups,
- boolean required, NodeResources nodeResources, ProvisioningTester tester) {
+ private Set<HostSpec> prepare(ApplicationId application, ProvisioningTester tester, ClusterSpec cluster, int nodeCount, int groups,
+ boolean required, NodeResources nodeResources) {
if (nodeCount == 0) return Collections.emptySet(); // this is a shady practice
return new HashSet<>(tester.prepare(application, cluster, nodeCount, groups, required, nodeResources));
}