summaryrefslogtreecommitdiffstats
path: root/node-repository
diff options
context:
space:
mode:
authorHÃ¥kon Hallingstad <hakon@verizonmedia.com>2020-10-29 15:23:00 +0100
committerGitHub <noreply@github.com>2020-10-29 15:23:00 +0100
commit75ada372a00146982e109260cd4c78439519eded (patch)
treea450d85194d12c34ad0bb9fee485b980cf8fa153 /node-repository
parent55b28181a0e757db3a185a1f65c5349fdc2fdd00 (diff)
parent53e8c967707120c107436e6c3c3fd2cba21ce57a (diff)
Merge pull request #15086 from vespa-engine/hakonhall/allow-provisioning-shared-and-set-exclusiveto-on-provisioned-node
Allow provisioning shared, and set exclusiveTo on provisioned node
Diffstat (limited to 'node-repository')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainer.java5
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java3
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.java17
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisionedHost.java15
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainerTest.java7
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java16
7 files changed, 46 insertions, 20 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainer.java
index f4ad2edfa9d..e5f23a30968 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainer.java
@@ -19,6 +19,7 @@ import com.yahoo.vespa.hosted.provision.node.Agent;
import com.yahoo.vespa.hosted.provision.node.IP;
import com.yahoo.vespa.hosted.provision.provisioning.FatalProvisioningException;
import com.yahoo.vespa.hosted.provision.provisioning.HostProvisioner;
+import com.yahoo.vespa.hosted.provision.provisioning.HostProvisioner.HostSharing;
import com.yahoo.vespa.hosted.provision.provisioning.NodeResourceComparator;
import com.yahoo.vespa.hosted.provision.provisioning.ProvisionedHost;
import com.yahoo.yolean.Exceptions;
@@ -44,7 +45,6 @@ import java.util.stream.IntStream;
public class DynamicProvisioningMaintainer extends NodeRepositoryMaintainer {
private static final Logger log = Logger.getLogger(DynamicProvisioningMaintainer.class.getName());
- private static final ApplicationId preprovisionAppId = ApplicationId.from("hosted-vespa", "tenant-host", "preprovision");
private final HostProvisioner hostProvisioner;
private final ListFlag<HostCapacity> targetCapacityFlag;
@@ -155,7 +155,8 @@ public class DynamicProvisioningMaintainer extends NodeRepositoryMaintainer {
try {
Version osVersion = nodeRepository().osVersions().targetFor(NodeType.host).orElse(Version.emptyVersion);
List<Node> hosts = hostProvisioner.provisionHosts(nodeRepository().database().getProvisionIndexes(1),
- resources, preprovisionAppId, osVersion, false)
+ resources, ApplicationId.defaultId(), osVersion,
+ HostSharing.shared)
.stream()
.map(ProvisionedHost::generateHost)
.collect(Collectors.toList());
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 5c71799cab6..b0baae650e4 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
@@ -13,6 +13,7 @@ import com.yahoo.vespa.hosted.provision.LockedNodeList;
import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.vespa.hosted.provision.node.Agent;
+import com.yahoo.vespa.hosted.provision.provisioning.HostProvisioner.HostSharing;
import java.util.List;
import java.util.Optional;
@@ -82,7 +83,7 @@ public class GroupPreparer {
deficit.getFlavor(),
application,
osVersion,
- requestedNodes.isExclusive()))
+ requestedNodes.isExclusive() ? HostSharing.exclusive : HostSharing.any))
.orElseGet(List::of);
// At this point we have started provisioning of the hosts, the first priority is to make sure that
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.java
index 5a7456ab997..ae8c6757b5a 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.java
@@ -16,6 +16,19 @@ import java.util.Set;
*/
public interface HostProvisioner {
+ enum HostSharing {
+ /** The host must be provisioned exclusively for the applicationId */
+ exclusive,
+
+ /** The host must be provisioned to be shared with other applications. \
+ */
+ shared,
+
+ /** The client has no requirements on whether the host must be provisio\
+ ned exclusively or shared. */
+ any
+ }
+
/**
* Schedule provisioning of a given number of hosts.
*
@@ -25,12 +38,12 @@ public interface HostProvisioner {
* @param applicationId id of the application that will own the provisioned host
* @param osVersion the OS version to use. If this version does not exist, implementations may choose a suitable
* fallback version.
- * @param forceExclusive whether to force the provisioning of an exclusive host.
+ * @param sharing puts requirements on sharing or exclusivity of the host to be provisioned.
* @return list of {@link ProvisionedHost} describing the provisioned nodes
*/
List<ProvisionedHost> provisionHosts(List<Integer> provisionIndexes, NodeResources resources,
ApplicationId applicationId, Version osVersion,
- boolean forceExclusive);
+ HostSharing sharing);
/**
* Continue provisioning of given list of Nodes.
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisionedHost.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisionedHost.java
index d34f5246c26..61cedbb9373 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisionedHost.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisionedHost.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.hosted.provision.provisioning;
import com.yahoo.component.Version;
+import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Flavor;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
@@ -24,14 +25,17 @@ public class ProvisionedHost {
private final String id;
private final String hostHostname;
private final Flavor hostFlavor;
+ private final Optional<ApplicationId> exclusiveTo;
private final String nodeHostname;
private final NodeResources nodeResources;
private final Version osVersion;
- public ProvisionedHost(String id, String hostHostname, Flavor hostFlavor, String nodeHostname, NodeResources nodeResources, Version osVersion) {
+ public ProvisionedHost(String id, String hostHostname, Flavor hostFlavor, Optional<ApplicationId> exclusiveTo,
+ String nodeHostname, NodeResources nodeResources, Version osVersion) {
this.id = Objects.requireNonNull(id, "Host id must be set");
this.hostHostname = Objects.requireNonNull(hostHostname, "Host hostname must be set");
this.hostFlavor = Objects.requireNonNull(hostFlavor, "Host flavor must be set");
+ this.exclusiveTo = Objects.requireNonNull(exclusiveTo, "exclusiveTo must be set");
this.nodeHostname = Objects.requireNonNull(nodeHostname, "Node hostname must be set");
this.nodeResources = Objects.requireNonNull(nodeResources, "Node resources must be set");
this.osVersion = Objects.requireNonNull(osVersion, "OS version must be set");
@@ -39,10 +43,11 @@ public class ProvisionedHost {
/** Generate {@link Node} instance representing the provisioned physical host */
public Node generateHost() {
- // TODO: Set exclusive to
- return Node.create(id, IP.Config.EMPTY, hostHostname, hostFlavor, NodeType.host)
- .status(Status.initial().withOsVersion(OsVersion.EMPTY.withCurrent(Optional.of(osVersion))))
- .build();
+ Node.Builder builder = Node
+ .create(id, IP.Config.EMPTY, hostHostname, hostFlavor, NodeType.host)
+ .status(Status.initial().withOsVersion(OsVersion.EMPTY.withCurrent(Optional.of(osVersion))));
+ exclusiveTo.ifPresent(builder::exclusiveTo);
+ return builder.build();
}
/** Generate {@link Node} instance representing the node running on this physical host */
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java
index 03c42bf20ff..5a098158844 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java
@@ -278,7 +278,7 @@ class AutoscalingTester {
@Override
public List<ProvisionedHost> provisionHosts(List<Integer> provisionIndexes, NodeResources resources,
ApplicationId applicationId, Version osVersion,
- boolean forceExclusive) {
+ HostSharing sharing) {
Flavor hostFlavor = hostFlavors.stream().filter(f -> matches(f, resources)).findAny()
.orElseThrow(() -> new RuntimeException("No flavor matching " + resources + ". Flavors: " + hostFlavors));
@@ -287,6 +287,7 @@ class AutoscalingTester {
hosts.add(new ProvisionedHost("host" + index,
"hostname" + index,
hostFlavor,
+ Optional.empty(),
"nodename" + index,
resources,
osVersion));
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainerTest.java
index c6052829faf..444844a758f 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainerTest.java
@@ -144,10 +144,10 @@ public class DynamicProvisioningMaintainerTest {
assertTrue(tester.nodeRepository.getNode(host2.hostname()).isPresent());
}
- @Ignore // TODO (hakon): Fix or replace with spare-hosts flag
+ @Ignore // TODO (hakon): Enable as test of min-capacity specified in flag
@Test
public void provision_exact_capacity() {
- var tester = new DynamicProvisioningTester(Cloud.builder().dynamicProvisioning(false).build());
+ var tester = new DynamicProvisioningTester(Cloud.builder().dynamicProvisioning(true).build());
NodeResources resources1 = new NodeResources(24, 64, 100, 1);
NodeResources resources2 = new NodeResources(16, 24, 100, 1);
tester.flagSource.withListFlag(Flags.TARGET_CAPACITY.id(), List.of(new HostCapacity(resources1.vcpu(), resources1.memoryGb(), resources1.diskGb(), 1),
@@ -326,7 +326,7 @@ public class DynamicProvisioningMaintainerTest {
@Override
public List<ProvisionedHost> provisionHosts(List<Integer> provisionIndexes, NodeResources resources,
- ApplicationId applicationId, Version osVersion, boolean forceExclusive) {
+ ApplicationId applicationId, Version osVersion, HostSharing sharing) {
Flavor hostFlavor = flavors.getFlavors().stream()
.filter(f -> !f.isDocker())
.filter(f -> f.resources().compatibleWith(resources))
@@ -337,6 +337,7 @@ public class DynamicProvisioningMaintainerTest {
hosts.add(new ProvisionedHost("host" + index,
"hostname" + index,
hostFlavor,
+ Optional.empty(),
"nodename" + index,
resources,
osVersion));
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java
index c5e05713a7f..b871404aa9d 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java
@@ -22,6 +22,7 @@ import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeList;
import com.yahoo.vespa.hosted.provision.node.Agent;
import com.yahoo.vespa.hosted.provision.node.IP;
+import com.yahoo.vespa.hosted.provision.provisioning.HostProvisioner.HostSharing;
import com.yahoo.vespa.hosted.provision.testutils.MockNameResolver;
import org.junit.Test;
@@ -40,7 +41,6 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -72,7 +72,8 @@ public class DynamicDockerProvisionTest {
mockHostProvisioner(hostProvisioner, "large", 3, null); // Provision shared hosts
prepareAndActivate(application1, clusterSpec("mycluster"), 4, 1, resources);
- verify(hostProvisioner).provisionHosts(List.of(100, 101, 102, 103), resources, application1, Version.emptyVersion, false);
+ verify(hostProvisioner).provisionHosts(List.of(100, 101, 102, 103), resources, application1,
+ Version.emptyVersion, HostSharing.any);
// Total of 8 nodes should now be in node-repo, 4 active hosts and 4 active nodes
assertEquals(8, tester.nodeRepository().list().size());
@@ -96,7 +97,8 @@ public class DynamicDockerProvisionTest {
// Deploy new exclusive application
ApplicationId application3 = ProvisioningTester.makeApplicationId();
prepareAndActivate(application3, clusterSpec("mycluster", true), 4, 1, resources);
- verify(hostProvisioner).provisionHosts(List.of(104, 105, 106, 107), resources, application3, Version.emptyVersion, true);
+ verify(hostProvisioner).provisionHosts(List.of(104, 105, 106, 107), resources, application3,
+ Version.emptyVersion, HostSharing.exclusive);
// Total of 20 nodes should now be in node-repo, 8 active hosts and 12 active nodes
assertEquals(20, tester.nodeRepository().list().size());
@@ -425,7 +427,7 @@ public class DynamicDockerProvisionTest {
return provisionedHost;
})
.collect(Collectors.toList());
- }).when(hostProvisioner).provisionHosts(any(), any(), any(), any(), anyBoolean());
+ }).when(hostProvisioner).provisionHosts(any(), any(), any(), any(), any());
}
private static class MockHostProvisioner implements HostProvisioner {
@@ -439,12 +441,14 @@ public class DynamicDockerProvisionTest {
}
@Override
- public List<ProvisionedHost> provisionHosts(List<Integer> provisionIndexes, NodeResources resources, ApplicationId applicationId, Version osVersion, boolean forceExclusive) {
+ public List<ProvisionedHost> provisionHosts(List<Integer> provisionIndexes, NodeResources resources,
+ ApplicationId applicationId, Version osVersion, HostSharing sharing) {
Optional<Flavor> hostFlavor = hostFlavors.stream().filter(f -> compatible(f, resources)).findFirst();
if (hostFlavor.isEmpty())
throw new OutOfCapacityException("No host flavor matches " + resources);
return provisionIndexes.stream()
- .map(i -> new ProvisionedHost("id-" + i, "host-" + i, hostFlavor.get(), "host-" + i + "-1", resources, osVersion))
+ .map(i -> new ProvisionedHost("id-" + i, "host-" + i, hostFlavor.get(), Optional.empty(),
+ "host-" + i + "-1", resources, osVersion))
.collect(Collectors.toList());
}