diff options
author | HÃ¥kon Hallingstad <hakon@oath.com> | 2018-12-04 19:19:56 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-04 19:19:56 +0100 |
commit | 120ca2632951acf181441be3b34356ce02ccbda2 (patch) | |
tree | c305baf94d24196ff87d9318b68b89f85ce1b838 /node-repository/src/main/java/com/yahoo | |
parent | 65ab8c5339f5e062ec9159b13fbe65e5c69fdd81 (diff) | |
parent | e7f762adce2fcb434838a22665bbc6b2ff803c80 (diff) |
Merge pull request #7851 from vespa-engine/revert-7850-revert-7828-hakonhall/add-infrastructure-applications-to-dupermodel
Revert "Revert "Add infrastructure applications to DuperModel""
Diffstat (limited to 'node-repository/src/main/java/com/yahoo')
4 files changed, 98 insertions, 57 deletions
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 07e4d586a91..9248ab36f2a 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,8 +1,8 @@ // 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.google.common.collect.ImmutableList; import com.yahoo.component.Version; +import com.yahoo.config.provision.HostName; import com.yahoo.config.provision.HostSpec; import com.yahoo.config.provision.NodeType; import com.yahoo.config.provision.Provisioner; @@ -11,12 +11,8 @@ 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.monitor.application.ConfigServerApplication; -import com.yahoo.vespa.service.monitor.application.ConfigServerHostApplication; -import com.yahoo.vespa.service.monitor.application.ControllerApplication; -import com.yahoo.vespa.service.monitor.application.ControllerHostApplication; -import com.yahoo.vespa.service.monitor.application.HostedVespaApplication; -import com.yahoo.vespa.service.monitor.application.ProxyHostApplication; +import com.yahoo.vespa.service.monitor.application.DuperModelInfraApi; +import com.yahoo.vespa.service.monitor.application.InfraApplicationApi; import java.time.Duration; import java.util.List; @@ -34,33 +30,57 @@ import java.util.stream.Collectors; public class InfrastructureProvisioner extends Maintainer { private static final Logger logger = Logger.getLogger(InfrastructureProvisioner.class.getName()); - private static final List<HostedVespaApplication> HOSTED_VESPA_APPLICATIONS = ImmutableList.of( - ConfigServerApplication.CONFIG_SERVER_APPLICATION, - ConfigServerHostApplication.CONFIG_SERVER_HOST_APPLICATION, - ProxyHostApplication.PROXY_HOST_APPLICATION, - ControllerApplication.CONTROLLER_APPLICATION, - ControllerHostApplication.CONTROLLER_HOST_APPLICATION); private final Provisioner provisioner; private final InfrastructureVersions infrastructureVersions; + private final DuperModelInfraApi duperModel; public InfrastructureProvisioner(Provisioner provisioner, NodeRepository nodeRepository, - InfrastructureVersions infrastructureVersions, Duration interval, JobControl jobControl) { + InfrastructureVersions infrastructureVersions, Duration interval, JobControl jobControl, + DuperModelInfraApi duperModel) { super(nodeRepository, interval, jobControl); this.provisioner = provisioner; this.infrastructureVersions = infrastructureVersions; + this.duperModel = duperModel; } @Override protected void maintain() { - for (HostedVespaApplication application: HOSTED_VESPA_APPLICATIONS) { + for (InfraApplicationApi application: duperModel.getSupportedInfraApplications()) { try (Mutex lock = nodeRepository().lock(application.getApplicationId())) { - Optional<Version> version = getTargetVersion(application.getCapacity().type()); - if (! version.isPresent()) continue; + NodeType nodeType = application.getCapacity().type(); + + Optional<Version> targetVersion = infrastructureVersions.getTargetVersionFor(nodeType); + if (!targetVersion.isPresent()) { + logger.log(LogLevel.DEBUG, "Skipping provision of " + nodeType + ": No target version set"); + duperModel.infraApplicationRemoved(application.getApplicationId()); + continue; + } + + List<Version> wantedVersions = nodeRepository() + .getNodes(nodeType, Node.State.ready, Node.State.reserved, Node.State.active, Node.State.inactive) + .stream() + .map(node -> node.allocation() + .map(allocation -> allocation.membership().cluster().vespaVersion()) + .orElse(null)) + .collect(Collectors.toList()); + if (wantedVersions.isEmpty()) { + // TODO: Unprovision active nodes from application? + logger.log(LogLevel.DEBUG, "Skipping provision of " + nodeType + ": No nodes to provision"); + duperModel.infraApplicationRemoved(application.getApplicationId()); + continue; + } + + if (wantedVersions.stream().allMatch(targetVersion.get()::equals) && + duperModel.infraApplicationIsActive(application.getApplicationId())) { + logger.log(LogLevel.DEBUG, "Skipping provision of " + nodeType + + ": Already provisioned to target version " + targetVersion); + continue; + } List<HostSpec> hostSpecs = provisioner.prepare( application.getApplicationId(), - application.getClusterSpecWithVersion(version.get()), + application.getClusterSpecWithVersion(targetVersion.get()), application.getCapacity(), 1, // groups logger::log); @@ -68,42 +88,14 @@ public class InfrastructureProvisioner extends Maintainer { NestedTransaction nestedTransaction = new NestedTransaction(); provisioner.activate(nestedTransaction, application.getApplicationId(), hostSpecs); nestedTransaction.commit(); - } - } - } - /** - * Returns the version that the given node type should be provisioned to. This is - * the version returned by {@link InfrastructureVersions#getTargetVersionFor} unless a provisioning is: - * <ul> - * <li>not possible: no nodes of given type in legal state in node-repo</li> - * <li>redundant: all nodes that can be provisioned already have the right wanted Vespa version</li> - * </ul> - */ - Optional<Version> getTargetVersion(NodeType nodeType) { - Optional<Version> targetVersion = infrastructureVersions.getTargetVersionFor(nodeType); - if (!targetVersion.isPresent()) { - logger.log(LogLevel.DEBUG, "Skipping provision of " + nodeType + ": No target version set"); - return Optional.empty(); - } - - List<Version> wantedVersions = nodeRepository().getNodes(nodeType, - Node.State.ready, Node.State.reserved, Node.State.active, Node.State.inactive).stream() - .map(node -> node.allocation() - .map(allocation -> allocation.membership().cluster().vespaVersion()) - .orElse(null)) - .collect(Collectors.toList()); - if (wantedVersions.isEmpty()) { - logger.log(LogLevel.DEBUG, "Skipping provision of " + nodeType + ": No nodes to provision"); - return Optional.empty(); - } - - if (wantedVersions.stream().allMatch(targetVersion.get()::equals)) { - logger.log(LogLevel.DEBUG, "Skipping provision of " + nodeType + - ": Already provisioned to target version " + targetVersion); - return Optional.empty(); + duperModel.infraApplicationActivated( + application.getApplicationId(), + hostSpecs.stream().map(HostSpec::hostname).map(HostName::from).collect(Collectors.toList())); + } catch (RuntimeException e) { + logger.log(LogLevel.INFO, "Failed to activate " + application.getApplicationId(), e); + // loop around to activate the next application + } } - return targetVersion; } - } 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 ded19a84f0d..677288009da 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 @@ -18,6 +18,7 @@ import com.yahoo.vespa.hosted.provision.maintenance.retire.RetirementPolicyList; import com.yahoo.vespa.hosted.provision.provisioning.FlavorSpareChecker; import com.yahoo.vespa.hosted.provision.provisioning.FlavorSpareCount; import com.yahoo.vespa.orchestrator.Orchestrator; +import com.yahoo.vespa.service.monitor.application.DuperModelInfraApi; import com.yahoo.vespa.service.monitor.ServiceMonitor; import java.time.Clock; @@ -57,15 +58,16 @@ public class NodeRepositoryMaintenance extends AbstractComponent { public NodeRepositoryMaintenance(NodeRepository nodeRepository, Deployer deployer, Provisioner provisioner, HostLivenessTracker hostLivenessTracker, ServiceMonitor serviceMonitor, Zone zone, Orchestrator orchestrator, Metric metric, - ConfigserverConfig configserverConfig) { + ConfigserverConfig configserverConfig, + DuperModelInfraApi duperModelInfraApi) { this(nodeRepository, deployer, provisioner, hostLivenessTracker, serviceMonitor, zone, Clock.systemUTC(), - orchestrator, metric, configserverConfig); + orchestrator, metric, configserverConfig, duperModelInfraApi); } public NodeRepositoryMaintenance(NodeRepository nodeRepository, Deployer deployer, Provisioner provisioner, HostLivenessTracker hostLivenessTracker, ServiceMonitor serviceMonitor, Zone zone, Clock clock, Orchestrator orchestrator, Metric metric, - ConfigserverConfig configserverConfig) { + ConfigserverConfig configserverConfig, DuperModelInfraApi duperModelInfraApi) { DefaultTimes defaults = new DefaultTimes(zone); jobControl = new JobControl(nodeRepository.database()); infrastructureVersions = new InfrastructureVersions(nodeRepository.database()); @@ -81,7 +83,7 @@ public class NodeRepositoryMaintenance extends AbstractComponent { provisionedExpirer = new ProvisionedExpirer(nodeRepository, clock, durationFromEnv("provisioned_expiry").orElse(defaults.provisionedExpiry), jobControl); nodeRebooter = new NodeRebooter(nodeRepository, clock, durationFromEnv("reboot_interval").orElse(defaults.rebootInterval), jobControl); metricsReporter = new MetricsReporter(nodeRepository, metric, orchestrator, serviceMonitor, periodicApplicationMaintainer::pendingDeployments, durationFromEnv("metrics_interval").orElse(defaults.metricsInterval), jobControl); - infrastructureProvisioner = new InfrastructureProvisioner(provisioner, nodeRepository, infrastructureVersions, durationFromEnv("infrastructure_provision_interval").orElse(defaults.infrastructureProvisionInterval), jobControl); + infrastructureProvisioner = new InfrastructureProvisioner(provisioner, nodeRepository, infrastructureVersions, durationFromEnv("infrastructure_provision_interval").orElse(defaults.infrastructureProvisionInterval), jobControl, duperModelInfraApi); RetirementPolicy policy = new RetirementPolicyList(new RetireIPv4OnlyNodes(zone)); 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 27215529cf4..035cb8f0aaf 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 @@ -21,6 +21,7 @@ public class ContainerConfig { " <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" + + " <component id='com.yahoo.vespa.hosted.provision.testutils.MockDuperModel'/>\n" + " <component id='com.yahoo.vespa.hosted.provision.testutils.MockNodeFlavors'/>\n" + " <component id='com.yahoo.vespa.hosted.provision.testutils.MockNodeRepository'/>\n" + " <component id='com.yahoo.vespa.hosted.provision.lb.LoadBalancerServiceProvider'/>\n" + diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockDuperModel.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockDuperModel.java new file mode 100644 index 00000000000..b366538949a --- /dev/null +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockDuperModel.java @@ -0,0 +1,46 @@ +// 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.testutils; + +import com.google.inject.Inject; +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.HostName; +import com.yahoo.vespa.service.monitor.application.DuperModelInfraApi; +import com.yahoo.vespa.service.monitor.application.InfraApplicationApi; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author hakonhall + */ +public class MockDuperModel implements DuperModelInfraApi { + private final Map<ApplicationId, InfraApplicationApi> supportedInfraApps = new HashMap<>(); + private final ConcurrentHashMap<ApplicationId, List<HostName>> activeApps = new ConcurrentHashMap<>(); + + @Inject + public MockDuperModel() { + } + + @Override + public List<InfraApplicationApi> getSupportedInfraApplications() { + return new ArrayList<>(supportedInfraApps.values()); + } + + @Override + public boolean infraApplicationIsActive(ApplicationId applicationId) { + return activeApps.containsKey(applicationId); + } + + @Override + public void infraApplicationActivated(ApplicationId applicationId, List<HostName> hostnames) { + activeApps.put(applicationId, hostnames); + } + + @Override + public void infraApplicationRemoved(ApplicationId applicationId) { + activeApps.remove(applicationId); + } +} |