diff options
author | Martin Polden <mpolden@mpolden.no> | 2023-03-10 11:43:23 +0100 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2023-03-10 11:52:38 +0100 |
commit | 0f1333ac8b35fd91dae612bdbcf89a943c62792c (patch) | |
tree | 3ab3bb24ef9f06b463d21246d8f2aacdadc8e6c0 /node-repository/src | |
parent | f6702b43e47bfdc925b3d9187766cdd7d4f82bf9 (diff) |
Take a separate lock for maintenance deployments
Diffstat (limited to 'node-repository/src')
14 files changed, 128 insertions, 103 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Applications.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Applications.java index 9cfed5d046c..8daac029c7b 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Applications.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Applications.java @@ -73,4 +73,9 @@ public class Applications { return db.lock(application, timeout); } + /** Create a lock which provides exclusive rights to perform a maintenance deployment */ + public Mutex lockMaintenance(ApplicationId application) { + return db.lockMaintenance(application); + } + } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ApplicationMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ApplicationMaintainer.java index 8ddf31289f9..50eee9e33b3 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ApplicationMaintainer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ApplicationMaintainer.java @@ -46,6 +46,8 @@ public abstract class ApplicationMaintainer extends NodeRepositoryMaintainer { return 1.0; } + protected final Deployer deployer() { return deployer; } + /** Returns the number of deployments that are pending execution */ public int pendingDeployments() { return pendingDeployments.size(); @@ -54,6 +56,9 @@ public abstract class ApplicationMaintainer extends NodeRepositoryMaintainer { /** Returns whether given application should be deployed at this moment in time */ protected abstract boolean canDeployNow(ApplicationId application); + /** Returns the applications that should be maintained by this now. */ + protected abstract Map<ApplicationId, String> applicationsNeedingMaintenance(); + /** * Redeploy this application. * @@ -62,19 +67,14 @@ public abstract class ApplicationMaintainer extends NodeRepositoryMaintainer { */ protected void deploy(ApplicationId application, String reason) { if (pendingDeployments.addIfAbsent(application)) { // Avoid queuing multiple deployments for same application - deploymentExecutor.execute(() -> deployWithLock(application, reason)); + deploymentExecutor.execute(() -> deployNow(application, reason)); } } - protected Deployer deployer() { return deployer; } - - /** Returns the applications that should be maintained by this now. */ - protected abstract Map<ApplicationId, String> applicationsNeedingMaintenance(); - /** * Redeploy this application. A lock will be taken for the duration of the deployment activation */ - protected final void deployWithLock(ApplicationId application, String reason) { + protected final void deployNow(ApplicationId application, String reason) { try (MaintenanceDeployment deployment = new MaintenanceDeployment(application, deployer, metric, nodeRepository())) { if ( ! deployment.isValid()) return; // this will be done at another config server if ( ! canDeployNow(application)) return; // redeployment is no longer needed @@ -95,7 +95,7 @@ public abstract class ApplicationMaintainer extends NodeRepositoryMaintainer { @Override public void shutdown() { super.shutdown(); - this.deploymentExecutor.shutdownNow(); + deploymentExecutor.shutdownNow(); } @Override @@ -103,7 +103,9 @@ public abstract class ApplicationMaintainer extends NodeRepositoryMaintainer { super.awaitShutdown(); try { // Give deployments in progress some time to complete - this.deploymentExecutor.awaitTermination(1, TimeUnit.MINUTES); + if (!deploymentExecutor.awaitTermination(1, TimeUnit.MINUTES)) { + log.log(Level.WARNING, "Failed to shut down deployment executor within deadline"); + } } catch (InterruptedException e) { throw new RuntimeException(e); } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java index 69c03dbf6dc..44944af15d7 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java @@ -6,7 +6,6 @@ import com.yahoo.config.provision.ApplicationLockException; import com.yahoo.config.provision.ClusterResources; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.Deployer; -import com.yahoo.config.provision.Environment; import com.yahoo.jdisc.Metric; import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeList; @@ -19,6 +18,7 @@ import com.yahoo.vespa.hosted.provision.autoscale.Autoscaler; import com.yahoo.vespa.hosted.provision.autoscale.Autoscaling; import com.yahoo.vespa.hosted.provision.autoscale.NodeMetricSnapshot; import com.yahoo.vespa.hosted.provision.node.History; + import java.time.Duration; import java.time.Instant; import java.util.Map; @@ -68,6 +68,7 @@ public class AutoscalingMaintainer extends NodeRepositoryMaintainer { * @return true if an autoscaling decision was made or nothing should be done, false if there was an error */ private boolean autoscale(ApplicationId applicationId, ClusterSpec.Id clusterId) { + boolean redeploy = false; try (var lock = nodeRepository().applications().lock(applicationId)) { Optional<Application> application = nodeRepository().applications().get(applicationId); if (application.isEmpty()) return true; @@ -92,13 +93,9 @@ public class AutoscalingMaintainer extends NodeRepositoryMaintainer { // Attempt to perform the autoscaling immediately, and log it regardless if (autoscaling != null && autoscaling.resources().isPresent() && !current.equals(autoscaling.resources().get())) { - try (MaintenanceDeployment deployment = new MaintenanceDeployment(applicationId, deployer, metric, nodeRepository())) { - if (deployment.isValid()) - deployment.activate(); - logAutoscaling(current, autoscaling.resources().get(), applicationId, clusterNodes.not().retired()); - } + redeploy = true; + logAutoscaling(current, autoscaling.resources().get(), applicationId, clusterNodes.not().retired()); } - return true; } catch (ApplicationLockException e) { return false; @@ -106,6 +103,13 @@ public class AutoscalingMaintainer extends NodeRepositoryMaintainer { catch (IllegalArgumentException e) { throw new IllegalArgumentException("Illegal arguments for " + applicationId + " cluster " + clusterId, e); } + if (redeploy) { + try (MaintenanceDeployment deployment = new MaintenanceDeployment(applicationId, deployer, metric, nodeRepository())) { + if (deployment.isValid()) + deployment.activate(); + } + } + return true; } private Applications applications() { diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ExpeditedChangeApplicationMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ExpeditedChangeApplicationMaintainer.java index 2f3cea8ca64..ffa125230a8 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ExpeditedChangeApplicationMaintainer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ExpeditedChangeApplicationMaintainer.java @@ -63,7 +63,7 @@ public class ExpeditedChangeApplicationMaintainer extends ApplicationMaintainer */ @Override protected void deploy(ApplicationId application, String reason) { - deployWithLock(application, reason); + deployNow(application, reason); } /** Returns the reason for doing an expedited deploy. */ @@ -73,11 +73,11 @@ public class ExpeditedChangeApplicationMaintainer extends ApplicationMaintainer List<String> reasons = nodes.stream() .flatMap(node -> node.history() - .events() - .stream() - .filter(event -> expediteChangeBy(event.agent())) - .filter(event -> lastDeployTime.get().isBefore(event.at())) - .map(event -> event.type() + (event.agent() == Agent.system ? "" : " by " + event.agent()))) + .events() + .stream() + .filter(event -> expediteChangeBy(event.agent())) + .filter(event -> lastDeployTime.get().isBefore(event.at())) + .map(event -> event.type() + (event.agent() == Agent.system ? "" : " by " + event.agent()))) .sorted() .distinct() .toList(); diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/MaintenanceDeployment.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/MaintenanceDeployment.java index bcc571355e3..189238a1c11 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/MaintenanceDeployment.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/MaintenanceDeployment.java @@ -1,8 +1,8 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.provision.maintenance; +import com.yahoo.concurrent.UncheckedTimeoutException; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.ApplicationLockException; import com.yahoo.config.provision.Deployer; import com.yahoo.config.provision.Deployment; import com.yahoo.config.provision.TransientException; @@ -16,7 +16,6 @@ import com.yahoo.vespa.hosted.provision.node.Agent; import com.yahoo.yolean.Exceptions; import java.io.Closeable; -import java.time.Duration; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -63,18 +62,12 @@ class MaintenanceDeployment implements Closeable { return deployment.isPresent(); } - /** - * Returns the application lock held by this, or empty if it is not held. - * - * @throws IllegalStateException id this is called when closed - */ - public Optional<Mutex> applicationLock() { - if (closed) throw new IllegalStateException(this + " is closed"); - return lock; - } - + /** Prepare this deployment. Returns whether prepare was successful */ public boolean prepare() { - return doStep(() -> { deployment.get().prepare(); return 0L; }).isPresent(); + return doStep(() -> { + deployment.get().prepare(); + return 0L; + }).isPresent(); } /** @@ -104,13 +97,10 @@ class MaintenanceDeployment implements Closeable { } private Optional<Mutex> tryLock(ApplicationId application, NodeRepository nodeRepository) { - Duration timeout = Duration.ofSeconds(3); try { - // Use a short lock to avoid interfering with change deployments - return Optional.of(nodeRepository.applications().lock(application, timeout)); - } - catch (ApplicationLockException e) { - log.log(Level.INFO, () -> "Could not lock " + application + " for maintenance deployment within " + timeout); + return Optional.of(nodeRepository.applications().lockMaintenance(application)); + } catch (UncheckedTimeoutException e) { + log.log(Level.INFO, () -> "Could not lock " + application + " for maintenance deployment within timeout"); return Optional.empty(); } } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainer.java index 036c46479d1..10a828c887a 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainer.java @@ -47,13 +47,12 @@ public class PeriodicApplicationMaintainer extends ApplicationMaintainer { .orElse(false); } - // Returns the applications that need to be redeployed by this config server at this point in time. @Override protected Map<ApplicationId, String> applicationsNeedingMaintenance() { if (deployer().bootstrapping()) return Map.of(); // Collect all deployment times before sorting as deployments may happen while we build the set, breaking - // the comparable contract. Stale times are fine as the time is rechecked in ApplicationMaintainer#deployWithLock + // the comparable contract. Stale times are fine as the time is rechecked in ApplicationMaintainer#deployNow Map<ApplicationId, Instant> deploymentTimes = nodesNeedingMaintenance().stream() .map(node -> node.allocation().get().owner()) .distinct() diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirer.java index 87af8c05b14..1ae9b00d794 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirer.java @@ -14,9 +14,10 @@ import com.yahoo.vespa.orchestrator.OrchestrationException; import com.yahoo.yolean.Exceptions; import java.time.Duration; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.OptionalLong; /** * Maintenance job which deactivates retired nodes, if given permission by orchestrator, or @@ -47,40 +48,55 @@ public class RetiredExpirer extends NodeRepositoryMaintainer { protected double maintain() { int attempts = 0; int successes = 0; + List<ApplicationId> applicationsWithRetiredNodes = nodeRepository().nodes().list(Node.State.active) + .retired() + .stream() + .map(node -> node.allocation().get().owner()) + .distinct() + .toList(); + for (var application : applicationsWithRetiredNodes) { + attempts++; + if (removeRetiredNodes(application)) { + successes++; + } + } + return attempts == 0 ? 1.0 : ((double)successes / attempts); + } - NodeList activeNodes = nodeRepository().nodes().list(Node.State.active); - Map<ApplicationId, NodeList> retiredNodesByApplication = activeNodes.retired().groupingBy(node -> node.allocation().get().owner()); - for (Map.Entry<ApplicationId, NodeList> entry : retiredNodesByApplication.entrySet()) { - ApplicationId application = entry.getKey(); - NodeList retiredNodes = entry.getValue(); - Map<Removal, NodeList> nodesByRemovalReason = retiredNodes.groupingBy(node -> removalOf(node, activeNodes)); - if (nodesByRemovalReason.isEmpty()) continue; - - for (var kv : nodesByRemovalReason.entrySet()) { - Removal removal = kv.getKey(); - if (removal.equals(Removal.none())) continue; - - NodeList nodes = kv.getValue(); - attempts++; - try (MaintenanceDeployment deployment = new MaintenanceDeployment(application, deployer, metric, nodeRepository())) { - if (!deployment.isValid()) { - log.info("Skipping invalid deployment for " + application); - continue; - } - - nodeRepository().nodes().setRemovable(application, nodes.asList(), removal.isReusable()); - Optional<Long> session = deployment.activate(); - String nodeList = String.join(", ", nodes.mapToList(Node::hostname)); - if (session.isEmpty()) { - log.info("Failed to redeploy " + application); - continue; - } - log.info("Redeployed " + application + " at session " + session.get() + " to deactivate retired nodes: " + nodeList); - successes++; + /** Mark retired nodes as removable and redeploy application */ + private boolean removeRetiredNodes(ApplicationId application) { + try (MaintenanceDeployment deployment = new MaintenanceDeployment(application, deployer, metric, nodeRepository())) { + if (!deployment.isValid()) { + log.info("Skipping invalid deployment for " + application); + return false; + } + boolean redeploy = false; + List<String> nodesToDeactivate = new ArrayList<>(); + try (var lock = nodeRepository().applications().lock(application)) { + NodeList activeNodes = nodeRepository().nodes().list(Node.State.active); + Map<Removal, NodeList> nodesByRemovalReason = activeNodes.owner(application) + .retired() + .groupingBy(node -> removalOf(node, activeNodes)); + for (var kv : nodesByRemovalReason.entrySet()) { + Removal reason = kv.getKey(); + if (reason.equals(Removal.none())) continue; + redeploy = true; + nodesToDeactivate.addAll(kv.getValue().hostnames()); + nodeRepository().nodes().setRemovable(kv.getValue(), reason.isReusable()); } } + if (!redeploy) { + return true; + } + Optional<Long> session = deployment.activate(); + String nodeList = String.join(", ", nodesToDeactivate); + if (session.isEmpty()) { + log.info("Failed to redeploy " + application); + return false; + } + log.info("Redeployed " + application + " at session " + session.get() + " to deactivate retired nodes: " + nodeList); + return true; } - return attempts == 0 ? 1.0 : ((double)successes / attempts); } /** diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/SpareCapacityMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/SpareCapacityMaintainer.java index 5ce88346178..dcdcbf09175 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/SpareCapacityMaintainer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/SpareCapacityMaintainer.java @@ -8,6 +8,7 @@ import com.yahoo.config.provision.NodeResources; import com.yahoo.jdisc.Metric; import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeList; +import com.yahoo.vespa.hosted.provision.NodeMutex; import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.maintenance.MaintenanceDeployment.Move; import com.yahoo.vespa.hosted.provision.node.Agent; @@ -49,9 +50,7 @@ public class SpareCapacityMaintainer extends NodeRepositoryMaintainer { NodeRepository nodeRepository, Metric metric, Duration interval) { - this(deployer, nodeRepository, metric, interval, - 10_000 // Should take less than a few minutes - ); + this(deployer, nodeRepository, metric, interval, 10_000 /* Should take less than a few minutes */); } public SpareCapacityMaintainer(Deployer deployer, @@ -160,22 +159,32 @@ public class SpareCapacityMaintainer extends NodeRepositoryMaintainer { .filter(node -> node.state() == Node.State.active) .min(this::retireOvercomittedComparator); if (nodeToRetire.isEmpty()) return; + retire(nodeToRetire.get()); + } - ApplicationId application = nodeToRetire.get().allocation().get().owner(); - try (MaintenanceDeployment deployment = new MaintenanceDeployment(application, deployer, metric, nodeRepository())) { - if ( ! deployment.isValid()) return; - - Optional<Node> nodeWithWantToRetire = nodeRepository().nodes().node(nodeToRetire.get().hostname()) - .map(node -> node.withWantToRetire(true, Agent.SpareCapacityMaintainer, nodeRepository().clock().instant())); - if (nodeWithWantToRetire.isEmpty()) return; - - nodeRepository().nodes().write(nodeWithWantToRetire.get(), deployment.applicationLock().get()); - log.log(Level.INFO, String.format("Redeploying %s to move %s from overcommitted host", - application, nodeToRetire.get().hostname())); + /** Mark node for retirement and redeploy its application */ + private void retire(Node node) { + ApplicationId owner = node.allocation().get().owner(); + try (MaintenanceDeployment deployment = new MaintenanceDeployment(owner, deployer, metric, nodeRepository())) { + if (!deployment.isValid()) return; + if (!markWantToRetire(node.hostname())) return; + log.log(Level.INFO, String.format("Redeploying %s to move %s from over-committed host", + owner, node.hostname())); deployment.activate(); } } + private boolean markWantToRetire(String hostname) { + Optional<NodeMutex> optionalNodeMutex = nodeRepository().nodes().lockAndGet(hostname); + if (optionalNodeMutex.isEmpty()) return false; + try (var nodeMutex = optionalNodeMutex.get()) { + Node retiredNode = nodeMutex.node().withWantToRetire(true, Agent.SpareCapacityMaintainer, + nodeRepository().clock().instant()); + nodeRepository().nodes().write(retiredNode, nodeMutex); + return true; + } + } + private static class CapacitySolver { private final HostCapacity hostCapacity; diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java index bb3d288e555..10f0c8aa554 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java @@ -203,17 +203,12 @@ public class Nodes { /** * Sets a list of nodes to have their allocation removable (active to inactive) in the node repository. * - * @param application the application the nodes belong to * @param nodes the nodes to make removable. These nodes MUST be in the active state * @param reusable move the node directly to {@link Node.State#dirty} after removal */ - public void setRemovable(ApplicationId application, List<Node> nodes, boolean reusable) { - try (Mutex lock = applications.lock(application)) { - List<Node> removableNodes = nodes.stream() - .map(node -> node.with(node.allocation().get().removable(true, reusable))) - .toList(); - write(removableNodes, lock); - } + public void setRemovable(NodeList nodes, boolean reusable) { + performOn(nodes, (node, mutex) -> write(node.with(node.allocation().get().removable(true, reusable)), + mutex)); } /** diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDb.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDb.java index c1ab8489f40..cec413cf4e3 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDb.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDb.java @@ -391,6 +391,11 @@ public class CuratorDb { return db.lock(lockPath.append("archiveUris"), defaultLockTimeout); } + public Lock lockMaintenance(ApplicationId application) { + return db.lock(lockPath.append("maintenanceDeployment").append(application.serializedForm()), + Duration.ofSeconds(3)); + } + // Load balancers ----------------------------------------------------------- public List<LoadBalancerId> readLoadBalancerIds() { diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainerTest.java index 880a69b61e5..e075995c89e 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainerTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainerTest.java @@ -402,8 +402,8 @@ public class HostCapacityMaintainerTest { // Config server becomes removable (done by RetiredExpirer in a real system) and redeployment moves it // to parked int removedIndex = nodeToRemove.get().allocation().get().membership().index(); - tester.nodeRepository().nodes().setRemovable(configSrvApp, List.of(nodeToRemove.get()), true); - tester.nodeRepository().nodes().setRemovable(hostApp, List.of(hostToRemove.get()), true); + tester.nodeRepository().nodes().setRemovable(NodeList.of(nodeToRemove.get()), true); + tester.nodeRepository().nodes().setRemovable(NodeList.of(hostToRemove.get()), true); tester.prepareAndActivateInfraApplication(configSrvApp, hostType.childNodeType()); tester.prepareAndActivateInfraApplication(hostApp, hostType); tester.nodeRepository().nodes().markNodeAvailableForNewAllocation(nodeToRemove.get().hostname(), Agent.operator, "Readied by host-admin"); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java index b5735cfae84..98c17eb4d5e 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java @@ -515,9 +515,9 @@ public class OsVersionsTest { private void replaceNodes(ApplicationId application) { // Deploy to retire nodes deployApplication(application); - List<Node> retired = tester.nodeRepository().nodes().list().owner(application).retired().asList(); + NodeList retired = tester.nodeRepository().nodes().list().owner(application).retired(); assertFalse("At least one node is retired", retired.isEmpty()); - tester.nodeRepository().nodes().setRemovable(application, retired, false); + tester.nodeRepository().nodes().setRemovable(retired, false); // Redeploy to deactivate removable nodes and allocate new ones deployApplication(application); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImplTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImplTest.java index 9a38cbbba44..9cd5adef5f4 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImplTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImplTest.java @@ -10,8 +10,8 @@ import com.yahoo.config.provision.HostSpec; import com.yahoo.config.provision.NodeType; import com.yahoo.config.provision.Provisioner; import com.yahoo.config.provision.Zone; -import com.yahoo.vespa.flags.InMemoryFlagSource; import com.yahoo.vespa.hosted.provision.Node; +import com.yahoo.vespa.hosted.provision.NodeList; import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.NodeRepositoryTester; import com.yahoo.vespa.hosted.provision.maintenance.InfrastructureVersions; @@ -122,7 +122,7 @@ public class InfraDeployerImplTest { addNode(5, Node.State.dirty, Optional.empty()); addNode(6, Node.State.ready, Optional.empty()); Node node7 = addNode(7, Node.State.active, Optional.of(target)); - nodeRepository.nodes().setRemovable(application.getApplicationId(), List.of(node7), false); + nodeRepository.nodes().setRemovable(NodeList.of(node7), false); infraDeployer.getDeployment(application.getApplicationId()).orElseThrow().activate(); 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 c1c4630f431..fb773f19b8a 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 @@ -636,7 +636,7 @@ public class VirtualNodeProvisioningTest { tester.activate(app1, cluster1, Capacity.from(new ClusterResources(2, 1, r))); // Deactivate any retired nodes - usually done by the RetiredExpirer - tester.nodeRepository().nodes().setRemovable(app1, tester.getNodes(app1).retired().asList(), false); + tester.nodeRepository().nodes().setRemovable(tester.getNodes(app1).retired(), false); tester.activate(app1, cluster1, Capacity.from(new ClusterResources(2, 1, r))); if (expectedReuse) { |