/** Creates this from a desired node count: The request may be satisfied with a smaller number of nodes. */ public static Capacity fromNodeCount(int capacity) { return fromNodeCount(capacity, Optional.empty(), false, true); }
public int decideSize(Capacity requestedCapacity, ClusterSpec.Type clusterType) { int requestedNodes = ensureRedundancy(requestedCapacity.nodeCount(), clusterType, requestedCapacity.canFail()); if (requestedCapacity.isRequired()) return requestedNodes; switch(zone.environment()) { case dev : case test : return 1; case perf : return Math.min(requestedCapacity.nodeCount(), 3); case staging: return requestedNodes <= 1 ? requestedNodes : Math.max(2, requestedNodes / 10); case prod : return requestedNodes; default : throw new IllegalArgumentException("Unsupported environment " + zone.environment()); } }
public static Capacity fromNodeCount(int nodeCount, Optional<String> flavor, boolean required, boolean canFail) { return new Capacity(nodeCount, flavor, required, canFail, NodeType.tenant); }
if (cluster.group().isPresent() && groups > 1) throw new IllegalArgumentException("Cannot both be specifying a group and ask for groups to be created"); if (requestedCapacity.nodeCount() % groups != 0) throw new IllegalArgumentException("Requested " + requestedCapacity.nodeCount() + " nodes in " + groups + " groups, but the node count is not divisible into this number of groups"); int capacity = failOnOutOfCapacity || requestedCapacity.isRequired() ? requestedCapacity.nodeCount() : Math.min(requestedCapacity.nodeCount(), freeNodes.get("default").size() + totalAllocatedTo(cluster)); if (groups > capacity) groups = capacity; String flavor = requestedCapacity.flavor().orElse("default"); capacity, startIndexForClusters, requestedCapacity.canFail())); capacity / groups, allocation.size(), requestedCapacity.canFail()));
int wantedGroups, ProvisionLogger logger) { if (cluster.group().isPresent()) throw new IllegalArgumentException("Node requests cannot specify a group"); if (requestedCapacity.nodeCount() > 0 && requestedCapacity.nodeCount() % wantedGroups != 0) throw new IllegalArgumentException("Requested " + requestedCapacity.nodeCount() + " nodes in " + wantedGroups + " groups, " + "which doesn't allow the nodes to be divided evenly into groups"); if ( requestedCapacity.type() == NodeType.tenant) { int nodeCount = application.instance().isTester() ? 1 : capacityPolicies.decideSize(requestedCapacity, cluster.type()); if (zone.environment().isManuallyDeployed() && nodeCount < requestedCapacity.nodeCount()) logger.log(Level.INFO, "Requested " + requestedCapacity.nodeCount() + " nodes for " + cluster + ", downscaling to " + nodeCount + " nodes in " + zone.environment()); Flavor flavor = capacityPolicies.decideFlavor(requestedCapacity, cluster); boolean exclusive = capacityPolicies.decideExclusivity(cluster.isExclusive()); requestedNodes = NodeSpec.from(nodeCount, flavor, exclusive, requestedCapacity.canFail()); requestedNodes = NodeSpec.from(requestedCapacity.type()); effectiveGroups = 1; // type request with multiple groups is not supported
false, Set.of(RotationName.from("us-cluster"))); activate(provisioner.prepare(zoneApp, zoneCluster, Capacity.fromRequiredNodeType(NodeType.host), 1, null), zoneApp, provisioner); Version.fromString("6.42"), false, Collections.emptySet()); provisioner.prepare(app1, cluster1, Capacity.fromNodeCount(2), 1, null); Version.fromString("6.42"), false, Collections.emptySet()); activate(provisioner.prepare(app2, cluster2, Capacity.fromNodeCount(2), 1, null), app2, provisioner); Version.fromString("6.42"), false, Collections.emptySet()); activate(provisioner.prepare(app3, cluster3, Capacity.fromNodeCount(2, Optional.of("docker"), false, true), 1, null), app3, provisioner);
public Flavor decideFlavor(Capacity requestedCapacity, ClusterSpec cluster) { // for now, always use the requested flavor if a docker flavor is requested Optional<String> requestedFlavor = requestedCapacity.flavor(); if (requestedFlavor.isPresent() && flavors.getFlavorOrThrow(requestedFlavor.get()).getType() == Flavor.Type.DOCKER_CONTAINER) return flavors.getFlavorOrThrow(requestedFlavor.get()); String defaultFlavorName = zone.defaultFlavor(cluster.type()); if (zone.system() == SystemName.cd) return flavors.getFlavorOrThrow(requestedFlavor.orElse(defaultFlavorName)); switch(zone.environment()) { case dev : case test : case staging : return flavors.getFlavorOrThrow(defaultFlavorName); default : return flavors.getFlavorOrThrow(requestedFlavor.orElse(defaultFlavorName)); } }
private List<Container> createNodesFromNodeType(ContainerCluster cluster, Element nodesElement, ConfigModelContext context) { NodeType type = NodeType.valueOf(nodesElement.getAttribute("type")); ClusterSpec clusterSpec = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from(cluster.getName()), context.getDeployState().getWantedNodeVespaVersion(), false, Collections.emptySet()); Map<HostResource, ClusterMembership> hosts = cluster.getRoot().getHostSystem().allocateHosts(clusterSpec, Capacity.fromRequiredNodeType(type), 1, log); return createNodesFromHosts(context.getDeployLogger(), hosts, cluster); }
for (InfraApplicationApi application: duperModel.getSupportedInfraApplications()) { try (Mutex lock = nodeRepository().lock(application.getApplicationId())) { NodeType nodeType = application.getCapacity().type();
public Map<HostResource, ClusterMembership> provision(HostSystem hostSystem, ClusterSpec.Type clusterType, ClusterSpec.Id clusterId, DeployLogger logger, Set<RotationName> rotations) { ClusterSpec cluster = ClusterSpec.request(clusterType, clusterId, version, exclusive, rotations); return hostSystem.allocateHosts(cluster, Capacity.fromNodeCount(count, flavor, required, canFail), groups, logger); }
/** Creates this from a node type */ public static Capacity fromRequiredNodeType(NodeType type) { return new Capacity(0, Optional.empty(), true, false, type); }
/** Creates a single host when there is no nodes tag */ private HostResource allocateSingleNodeHost(ContainerCluster cluster, DeployLogger logger, Element containerElement, ConfigModelContext context) { DeployState deployState = context.getDeployState(); HostSystem hostSystem = cluster.getHostSystem(); if (deployState.isHosted()) { Optional<HostResource> singleContentHost = getHostResourceFromContentClusters(cluster, containerElement, context); if (singleContentHost.isPresent()) { // there is a content cluster; put the container on its first node return singleContentHost.get(); } else { // request 1 node ClusterSpec clusterSpec = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from(cluster.getName()), deployState.getWantedNodeVespaVersion(), false, Collections.emptySet()); Capacity capacity = Capacity.fromNodeCount(1, Optional.empty(), false, ! deployState.getProperties().isBootstrap()); return hostSystem.allocateHosts(clusterSpec, capacity, 1, logger).keySet().iterator().next(); } } else { return hostSystem.getHost(Container.SINGLENODE_CONTAINER_SERVICESPEC); } }