diff options
Diffstat (limited to 'node-repository/src/main')
5 files changed, 39 insertions, 92 deletions
diff --git a/node-repository/src/main/config/node-repository.xml b/node-repository/src/main/config/node-repository.xml index 2bc3ae5cfeb..274be6d572a 100644 --- a/node-repository/src/main/config/node-repository.xml +++ b/node-repository/src/main/config/node-repository.xml @@ -1,5 +1,6 @@ <!-- services.xml snippet for the node repository. Included in config server services.xml if the package is installed--> <!-- Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<component id="com.yahoo.vespa.hosted.provision.provisioning.InfraDeployerImpl" bundle="node-repository"/> <component id="com.yahoo.vespa.hosted.provision.provisioning.NodeRepositoryProvisioner" bundle="node-repository" /> <component id="NodeRepository" class="com.yahoo.vespa.hosted.provision.NodeRepository" bundle="node-repository"/> <component id="com.yahoo.vespa.hosted.provision.maintenance.NodeRepositoryMaintenance" bundle="node-repository"/> diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InfrastructureProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InfrastructureProvisioner.java index 32a971b0d46..9ab816b8acc 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InfrastructureProvisioner.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InfrastructureProvisioner.java @@ -1,31 +1,17 @@ // Copyright 2018 Yahoo Holdings. 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.component.Version; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.HostName; -import com.yahoo.config.provision.HostSpec; -import com.yahoo.config.provision.NodeType; -import com.yahoo.config.provision.Provisioner; +import com.yahoo.config.provision.InfraDeployer; import com.yahoo.log.LogLevel; -import com.yahoo.transaction.Mutex; -import com.yahoo.transaction.NestedTransaction; -import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeRepository; -import com.yahoo.vespa.service.duper.DuperModel; -import com.yahoo.vespa.service.monitor.DuperModelInfraApi; -import com.yahoo.vespa.service.monitor.InfraApplicationApi; import java.time.Duration; -import java.util.List; -import java.util.Optional; import java.util.logging.Logger; -import java.util.stream.Collectors; /** - * This maintainer makes sure that 1. infrastructure nodes are allocated with correct wanted - * version and 2. keeping {@link DuperModel} up to date. Source for the wanted version comes - * from the target version set using /nodes/v2/upgrade/ endpoint. + * Periodically deploys infrastructure applications. + * TODO: Merge this with {@link PeriodicApplicationMaintainer} * * @author freva */ @@ -33,81 +19,22 @@ public class InfrastructureProvisioner extends Maintainer { private static final Logger logger = Logger.getLogger(InfrastructureProvisioner.class.getName()); - private final Provisioner provisioner; - private final DuperModelInfraApi duperModel; + private final InfraDeployer infraDeployer; - InfrastructureProvisioner(Provisioner provisioner, NodeRepository nodeRepository, - Duration interval, DuperModelInfraApi duperModel) { + InfrastructureProvisioner(NodeRepository nodeRepository, InfraDeployer infraDeployer, Duration interval) { super(nodeRepository, interval); - this.provisioner = provisioner; - this.duperModel = duperModel; + this.infraDeployer = infraDeployer; } @Override protected void maintain() { - for (InfraApplicationApi application: duperModel.getSupportedInfraApplications()) { - try (Mutex lock = nodeRepository().lock(application.getApplicationId())) { - NodeType nodeType = application.getCapacity().type(); - - Optional<Version> targetVersion = nodeRepository().infrastructureVersions().getTargetVersionFor(nodeType); - if (!targetVersion.isPresent()) { - logger.log(LogLevel.DEBUG, "No target version set for " + nodeType + ", removing application"); - removeApplication(application.getApplicationId()); - continue; - } - - List<Node> candidateNodes = nodeRepository() - .getNodes(nodeType, Node.State.ready, Node.State.reserved, Node.State.active, Node.State.inactive); - if (candidateNodes.isEmpty()) { - logger.log(LogLevel.DEBUG, "No nodes to provision for " + nodeType + ", removing application"); - removeApplication(application.getApplicationId()); - continue; - } - - if (!candidateNodes.stream().allMatch(node -> - node.state() == Node.State.active && - node.allocation() - .map(allocation -> allocation.membership().cluster().vespaVersion().equals(targetVersion.get())) - .orElse(false))) { - List<HostSpec> hostSpecs = provisioner.prepare( - application.getApplicationId(), - application.getClusterSpecWithVersion(targetVersion.get()), - application.getCapacity(), - 1, // groups - logger::log); - - // Sanity-check hostSpecs is the same list as candidateNodes? - - NestedTransaction nestedTransaction = new NestedTransaction(); - provisioner.activate(nestedTransaction, application.getApplicationId(), hostSpecs); - nestedTransaction.commit(); - } - - duperModel.infraApplicationActivated( - application.getApplicationId(), - candidateNodes.stream().map(Node::hostname).map(HostName::from).collect(Collectors.toList())); - - String detail; - if (candidateNodes.size() < 10) { - detail = ": " + candidateNodes.stream().map(Node::hostname).collect(Collectors.joining(",")); - } else { - detail = " with " + candidateNodes.size() + " hosts"; - } - logger.log(LogLevel.DEBUG, "Infrastructure application " + application.getApplicationId() + " activated" + detail); + for (ApplicationId application : infraDeployer.getSupportedInfraApplications()) { + try { + infraDeployer.getDeployment(application).orElseThrow().activate(); } catch (RuntimeException e) { - logger.log(LogLevel.INFO, "Failed to activate " + application.getApplicationId(), e); + logger.log(LogLevel.INFO, "Failed to activate " + application, e); // loop around to activate the next application } } } - - private void removeApplication(ApplicationId applicationId) { - // Use the DuperModel as source-of-truth on whether it has also been activated (to avoid periodic removals) - if (duperModel.infraApplicationIsActive(applicationId)) { - NestedTransaction nestedTransaction = new NestedTransaction(); - provisioner.remove(nestedTransaction, applicationId); - nestedTransaction.commit(); - duperModel.infraApplicationRemoved(applicationId); - } - } } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java index 4cfecb6c6aa..50a371458ce 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java @@ -7,7 +7,7 @@ import com.yahoo.component.AbstractComponent; import com.yahoo.config.provision.Deployer; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.HostLivenessTracker; -import com.yahoo.config.provision.Provisioner; +import com.yahoo.config.provision.InfraDeployer; import com.yahoo.config.provision.SystemName; import com.yahoo.config.provision.Zone; import com.yahoo.jdisc.Metric; @@ -20,7 +20,6 @@ import com.yahoo.vespa.hosted.provision.provisioning.FlavorSpareChecker; import com.yahoo.vespa.hosted.provision.provisioning.FlavorSpareCount; import com.yahoo.vespa.hosted.provision.provisioning.ProvisionServiceProvider; import com.yahoo.vespa.orchestrator.Orchestrator; -import com.yahoo.vespa.service.monitor.DuperModelInfraApi; import com.yahoo.vespa.service.monitor.ServiceMonitor; import java.time.Clock; @@ -57,21 +56,20 @@ public class NodeRepositoryMaintenance extends AbstractComponent { private final Optional<HostDeprovisionMaintainer> hostDeprovisionMaintainer; @Inject - public NodeRepositoryMaintenance(NodeRepository nodeRepository, Deployer deployer, Provisioner provisioner, + public NodeRepositoryMaintenance(NodeRepository nodeRepository, Deployer deployer, InfraDeployer infraDeployer, HostLivenessTracker hostLivenessTracker, ServiceMonitor serviceMonitor, Zone zone, Orchestrator orchestrator, Metric metric, ConfigserverConfig configserverConfig, - DuperModelInfraApi duperModelInfraApi, ProvisionServiceProvider provisionServiceProvider, FlagSource flagSource) { - this(nodeRepository, deployer, provisioner, hostLivenessTracker, serviceMonitor, zone, Clock.systemUTC(), - orchestrator, metric, configserverConfig, duperModelInfraApi, provisionServiceProvider, flagSource); + this(nodeRepository, deployer, infraDeployer, hostLivenessTracker, serviceMonitor, zone, Clock.systemUTC(), + orchestrator, metric, configserverConfig, provisionServiceProvider, flagSource); } - public NodeRepositoryMaintenance(NodeRepository nodeRepository, Deployer deployer, Provisioner provisioner, + public NodeRepositoryMaintenance(NodeRepository nodeRepository, Deployer deployer, InfraDeployer infraDeployer, HostLivenessTracker hostLivenessTracker, ServiceMonitor serviceMonitor, Zone zone, Clock clock, Orchestrator orchestrator, Metric metric, - ConfigserverConfig configserverConfig, DuperModelInfraApi duperModelInfraApi, + ConfigserverConfig configserverConfig, ProvisionServiceProvider provisionServiceProvider, FlagSource flagSource) { DefaultTimes defaults = new DefaultTimes(zone); @@ -86,7 +84,7 @@ public class NodeRepositoryMaintenance extends AbstractComponent { provisionedExpirer = new ProvisionedExpirer(nodeRepository, clock, durationFromEnv("provisioned_expiry").orElse(defaults.provisionedExpiry)); nodeRebooter = new NodeRebooter(nodeRepository, clock, durationFromEnv("reboot_interval").orElse(defaults.rebootInterval)); metricsReporter = new MetricsReporter(nodeRepository, metric, orchestrator, serviceMonitor, periodicApplicationMaintainer::pendingDeployments, durationFromEnv("metrics_interval").orElse(defaults.metricsInterval)); - infrastructureProvisioner = new InfrastructureProvisioner(provisioner, nodeRepository, durationFromEnv("infrastructure_provision_interval").orElse(defaults.infrastructureProvisionInterval), duperModelInfraApi); + infrastructureProvisioner = new InfrastructureProvisioner(nodeRepository, infraDeployer, durationFromEnv("infrastructure_provision_interval").orElse(defaults.infrastructureProvisionInterval)); loadBalancerExpirer = provisionServiceProvider.getLoadBalancerService().map(lbService -> new LoadBalancerExpirer(nodeRepository, durationFromEnv("load_balancer_expiry").orElse(defaults.loadBalancerExpiry), lbService)); hostProvisionMaintainer = provisionServiceProvider.getHostProvisioner().map(hostProvisioner -> diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ContainerConfig.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ContainerConfig.java index 2a07cadc6ad..71a9cfa4985 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ContainerConfig.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ContainerConfig.java @@ -18,6 +18,7 @@ public class ContainerConfig { " <component id='com.yahoo.vespa.curator.mock.MockCurator'/>\n" + " <component id='com.yahoo.vespa.hosted.provision.testutils.OrchestratorMock'/>\n" + " <component id='com.yahoo.vespa.hosted.provision.testutils.MockDeployer'/>\n" + + " <component id='com.yahoo.vespa.hosted.provision.testutils.MockInfraDeployer'/>\n" + " <component id='com.yahoo.vespa.hosted.provision.testutils.MockProvisioner'/>\n" + " <component id='com.yahoo.vespa.hosted.provision.testutils.TestHostLivenessTracker'/>\n" + " <component id='com.yahoo.vespa.hosted.provision.testutils.ServiceMonitorStub'/>\n" + diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockInfraDeployer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockInfraDeployer.java new file mode 100644 index 00000000000..5a5f8431653 --- /dev/null +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockInfraDeployer.java @@ -0,0 +1,20 @@ +package com.yahoo.vespa.hosted.provision.testutils; + +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.Deployment; +import com.yahoo.config.provision.InfraDeployer; + +import java.util.List; +import java.util.Optional; + +public class MockInfraDeployer implements InfraDeployer { + @Override + public Optional<Deployment> getDeployment(ApplicationId application) { + return Optional.empty(); + } + + @Override + public List<ApplicationId> getSupportedInfraApplications() { + return List.of(); + } +} |