类hudson.model.Label源码实例Demo

下面列出了怎么用hudson.model.Label的API类实例代码及写法,或者点击链接到github查看源代码。

@Override
public Collection<PlannedNode> provision(Label label, int excessWorkload) {
    Set<String> allInProvisioning = getNodesInProvisioning(label);
    LOGGER.info("In provisioning : " + allInProvisioning);
    int toBeProvisioned = Math.max(0, excessWorkload - allInProvisioning.size());
    LOGGER.info("Excess workload after pending Kubernetes agents: " + toBeProvisioned);

    List<PlannedNode> provisionNodes = new ArrayList<>();
    for (int i = 0; i < toBeProvisioned; i++) {
        PlannedNode node = new PlannedNode(name,
                Computer.threadPoolForRemoting.submit(() -> new KafkaCloudSlave(this)),
                AGENT_NUM_EXECUTORS);
        provisionNodes.add(node);
    }
    return provisionNodes;
}
 
源代码2 项目: jenkins-nomad   文件: NomadSlaveTemplate.java
@DataBoundConstructor
public NomadSlaveTemplate(
        String cpu,
        String memory,
        String disk,
        String labels,
        String remoteFs,
        String idleTerminationInMinutes,
        String region,
        String priority,
        String image
        ) {
    this.cpu = Integer.parseInt(cpu);
    this.memory = Integer.parseInt(memory);
    this.disk = Integer.parseInt(disk);
    this.priority = Integer.parseInt(priority);
    this.idleTerminationInMinutes = Integer.parseInt(idleTerminationInMinutes);
    this.remoteFs = remoteFs;
    this.labels = Util.fixNull(labels);
    this.labelSet = Label.parse(labels);
    this.region = region;
    this.image = image;

    readResolve();
}
 
protected void should_connect_agent(DockerTemplate template) throws IOException, ExecutionException, InterruptedException, TimeoutException {

        // FIXME on CI windows nodes don't have Docker4Windows
        Assume.assumeFalse(SystemUtils.IS_OS_WINDOWS);

        String dockerHost = SystemUtils.IS_OS_WINDOWS ? "tcp://localhost:2375" : "unix:///var/run/docker.sock";

        DockerCloud cloud = new DockerCloud(cloudName, new DockerAPI(new DockerServerEndpoint(dockerHost, null)),
                Collections.singletonList(template));

        j.jenkins.clouds.replaceBy(Collections.singleton(cloud));

        final FreeStyleProject project = j.createFreeStyleProject("test-docker-ssh");
        project.setAssignedLabel(Label.get(LABEL));
        project.getBuildersList().add(new Shell("whoami"));
        final QueueTaskFuture<FreeStyleBuild> scheduledBuild = project.scheduleBuild2(0);
        try {
            final FreeStyleBuild build = scheduledBuild.get(60L, TimeUnit.SECONDS);
            Assert.assertTrue(build.getResult() == Result.SUCCESS);
            Assert.assertTrue(build.getLog().contains("jenkins"));
        } finally {
            scheduledBuild.cancel(true);
        }
    }
 
@Test
public void givenEC2CloudsWhenOneCanCoverCapacity_shouldDoScalingForFirstOnly() {
    when(snapshot.getQueueLength()).thenReturn(2);
    when(state.getLabel()).thenReturn(label);

    final EC2FleetCloud ec2FleetCloud1 = mock(EC2FleetCloud.class);
    clouds.add(ec2FleetCloud1);
    final EC2FleetCloud ec2FleetCloud2 = mock(EC2FleetCloud.class);
    clouds.add(ec2FleetCloud2);
    when(ec2FleetCloud1.canProvision(any(Label.class))).thenReturn(true);
    when(ec2FleetCloud2.canProvision(any(Label.class))).thenReturn(true);
    when(ec2FleetCloud1.isNoDelayProvision()).thenReturn(true);
    when(ec2FleetCloud2.isNoDelayProvision()).thenReturn(true);
    when(ec2FleetCloud1.provision(any(Label.class), anyInt())).thenReturn(Arrays.asList(
            mock(NodeProvisioner.PlannedNode.class),
            mock(NodeProvisioner.PlannedNode.class)
    ));

    Assert.assertEquals(
            NodeProvisioner.StrategyDecision.PROVISIONING_COMPLETED,
            strategy.apply(state));
    verify(ec2FleetCloud1, times(1)).provision(label, 2);
    verify(ec2FleetCloud2, never()).provision(any(Label.class), anyInt());
}
 
@Test
public void should_not_keep_planned_node_if_configured_so_jenkins_will_overprovision() throws Exception {
    ComputerLauncher computerLauncher = mock(ComputerLauncher.class);
    ComputerConnector computerConnector = mock(ComputerConnector.class);
    when(computerConnector.launch(anyString(), any(TaskListener.class))).thenReturn(computerLauncher);

    final EC2FleetCloud cloud = spy(new EC2FleetCloud(null, null, "credId", null, "region",
            null, "fId", "momo", null, computerConnector, false, false,
            0, 0, 10, 1, false, false,
            false, 0, 0, false,
            10, false));
    j.jenkins.clouds.add(cloud);

    mockEc2ApiToDescribeInstancesWhenModified(InstanceStateName.Running);

    getQueueTaskFutures(1);

    tryUntil(new Runnable() {
        @Override
        public void run() {
            j.jenkins.getLabelAtom("momo").nodeProvisioner.suggestReviewNow();
            verify(cloud, atLeast(2)).provision(any(Label.class), anyInt());
        }
    });
}
 
源代码6 项目: docker-plugin   文件: DockerTemplate.java
@DataBoundConstructor
public DockerTemplate(@Nonnull DockerTemplateBase dockerTemplateBase,
                      @Nonnull DockerComputerConnector connector,
                      String labelString,
                      String instanceCapStr
) {
    this.dockerTemplateBase = dockerTemplateBase;
    this.connector = connector;
    this.labelString = Util.fixEmpty(labelString);

    if (Strings.isNullOrEmpty(instanceCapStr)) {
        this.instanceCap = Integer.MAX_VALUE;
    } else {
        this.instanceCap = Integer.parseInt(instanceCapStr);
    }

    labelSet = Label.parse(labelString);
}
 
源代码7 项目: docker-plugin   文件: DockerCloud.java
/**
 * Multiple amis can have the same label.
 *
 * @return Templates matched to requested label assuming slave Mode
 */
public List<DockerTemplate> getTemplates(Label label) {
    final List<DockerTemplate> dockerTemplates = new ArrayList<>();

    for (DockerTemplate t : getTemplates()) {
        if ( t.getDisabled().isDisabled() ) {
            continue; // pretend it doesn't exist
        }
        if (label == null && t.getMode() == Node.Mode.NORMAL) {
            dockerTemplates.add(t);
        }

        if (label != null && label.matches(t.getLabelSet())) {
            dockerTemplates.add(t);
        }
    }

    // add temporary templates matched to requested label
    for (DockerTemplate template : getJobTemplates().values()) {
        if (label != null && label.matches(template.getLabelSet())) {
            dockerTemplates.add(template);
        }
    }

    return dockerTemplates;
}
 
@Nonnull
public List<DockerCloud> getDockerClouds(Label label) {
    List<DockerCloud> provisionClouds;

    //create a random list of docker clouds and prioritize idle clouds
    List<DockerCloud> availableClouds = getAvailableDockerClouds(label);
    if (availableClouds.size() > 0) {
        //select available clouds based on label which have potential capacity
        LOG.debug("Picking from available clouds.");
        provisionClouds = availableClouds;
    } else {
        //if there's no available clouds then fall back to original behavior
        LOG.debug("Falling back to getting all clouds regardless of availability.");
        provisionClouds = getAllDockerClouds();
    }

    //randomize the order of the DockerCloud list
    Collections.shuffle(provisionClouds);
    //sort by least loaded DockerCloud (i.e. fewest provisioned slaves)
    provisionClouds.sort(new DockerCloudLoadComparator());

    LOG.debug("Least loaded randomized DockerCloud: " +
            ((provisionClouds.size() > 0) ? provisionClouds.get(0).name : "none available"));

    return provisionClouds;
}
 
源代码9 项目: kubernetes-plugin   文件: PodTemplateFilter.java
/**
 * Pass the given pod templates list into all filters implementations.
 *
 * @param cloud The cloud instance the pod templates are getting considered for
 * @param podTemplates The initial list of pod templates
 * @param label The label that was requested for provisioning
 * @return The pod template list after filtering
 */
public static List<PodTemplate> applyAll(@Nonnull KubernetesCloud cloud, @Nonnull List<PodTemplate> podTemplates, @CheckForNull Label label) {
    List<PodTemplate> result = new ArrayList<>();
    for (PodTemplate t : podTemplates) {
        PodTemplate output = t;
        for (PodTemplateFilter f : all()) {
            output = f.transform(cloud, output, label);
            if (output == null) {
                break;
            }
        }
        if (output != null) {
            result.add(output);
        }
    }
    return result;
}
 
源代码10 项目: kubernetes-plugin   文件: KubernetesPipelineTest.java
@Test
public void podTemplateWithMultipleLabels() throws Exception {
    PodTemplate pt = new PodTemplate();
    pt.setName("podTemplate");
    pt.setLabel("label1 label2");
    ContainerTemplate jnlp = new ContainerTemplate("jnlp", "jenkins/jnlp-slave:3.35-5-alpine");
    pt.setContainers(Collections.singletonList(jnlp));
    cloud.addTemplate(pt);
    SemaphoreStep.waitForStart("pod/1", b);
    Map<String, String> labels = getLabels(cloud, this, name);
    labels.put("jenkins/label","label1_label2");
    KubernetesSlave node = r.jenkins.getNodes().stream()
            .filter(KubernetesSlave.class::isInstance)
            .map(KubernetesSlave.class::cast)
            .findAny().get();
    assertTrue(node.getAssignedLabels().containsAll(Label.parse("label1 label2")));
    PodList pods = cloud.connect().pods().withLabels(labels).list();
    assertThat(
            "Expected one pod with labels " + labels + " but got: "
                    + pods.getItems().stream().map(pod -> pod.getMetadata()).collect(Collectors.toList()),
            pods.getItems(), hasSize(1));
    SemaphoreStep.success("pod/1", null);
    r.assertBuildStatusSuccess(r.waitForCompletion(b));
}
 
源代码11 项目: docker-swarm-plugin   文件: DockerSwarmAgent.java
@Override
public CauseOfBlockage canTake(final Queue.BuildableItem item) {
    final Label l = item.getAssignedLabel();
    if (l != null && this.name.equals(l.getName())) {
        return null;
    }
    return super.canTake(item);
}
 
public Set<String> getNodesInProvisioning(@CheckForNull Label label) {
    if (label == null) return Collections.emptySet();
    return label.getNodes().stream()
            .filter(KafkaCloudSlave.class::isInstance)
            .filter(node -> {
                Computer computer = node.toComputer();
                return computer != null && !computer.isOnline();
            })
            .map(Node::getNodeName)
            .collect(Collectors.toSet());
}
 
源代码13 项目: amazon-ecs-plugin   文件: ECSCloud.java
private ECSTaskTemplate getTemplate(Label label) {
    if (label == null) {
        return null;
    }
    for (ECSTaskTemplate t : getAllTemplates()) {
        if (label.matches(t.getLabelSet())) {
            return t;
        }
    }
    return null;
}
 
@NonNull
@Override
public Set<Attribute<LabelAtom, ?>> describe() {
    return new HashSet<>(Arrays.asList(
        new Attribute<LabelAtom, String>("name", String.class)
            .getter(Label::getName),
        new MultivaluedAttribute<LabelAtom, LabelAtomProperty>("properties", LabelAtomProperty.class)
        .getter(labelAtom -> labelAtom.getProperties())
        .setter((labelAtom, properties) -> labelAtom.getProperties().addAll(properties))
    ));
}
 
@Test
@ConfiguredWithReadme("docker/README.md")
public void update_docker_cloud() throws Exception {
    DockerCloud docker = DockerCloud.getCloudByName("docker");
    assertNotNull(docker);
    assertNotNull(docker.getDockerApi());
    assertNotNull(docker.getDockerApi().getDockerHost());
    assertEquals("unix:///var/run/docker.sock", docker.getDockerApi().getDockerHost().getUri());

    DockerTemplate template = docker.getTemplate(Label.get("docker-agent"));
    checkTemplate(template, "docker-agent", "jenkins", "/home/jenkins/agent", "10",
            new String[] { "hello:/hello", "world:/world"}, "hello=world\nfoo=bar");

    ConfigurationAsCode.get().configure(getClass().getResource("DockerCloudTest2.yml").toExternalForm());

    docker = DockerCloud.getCloudByName("docker");
    assertNotNull(docker);
    assertNotNull(docker.getDockerApi());
    assertNotNull(docker.getDockerApi().getDockerHost());
    assertEquals("unix:///var/run/docker.sock", docker.getDockerApi().getDockerHost().getUri());

    template = docker.getTemplate(Label.get("docker-agent"));
    checkTemplate(template, "docker-agent", "jenkins", "/home/jenkins/agent", "10",
            new String[] { "hello:/hello", "world:/world"}, "hello=world\nfoo=bar");

    template = docker.getTemplate(Label.get("generic"));
    checkTemplate(template, "generic", "jenkins", "/home/jenkins/agent2", "5",
            new String[] { "hello:/hello", "world:/world"}, "hello=world\nfoo=bar");
}
 
源代码16 项目: jenkins-nomad   文件: NomadCloud.java
public NomadSlaveTemplate getTemplate(Label label) {
    for (NomadSlaveTemplate t : templates) {
        if (label == null && !t.getLabelSet().isEmpty()) {
            continue;
        }
        if ((label == null && t.getLabelSet().isEmpty()) || (label != null && label.matches(t.getLabelSet()))) {
            return t;
        }
    }
    return null;
}
 
源代码17 项目: blueocean-plugin   文件: RunImplTest.java
@Test @Ignore
public void replayRunTest() throws Exception {
    WorkflowJob job1 = j.jenkins.createProject(WorkflowJob.class, "pipeline1");
    j.createOnlineSlave(Label.get("remote"));
    job1.setDefinition(new CpsFlowDefinition(
        "node('remote') {\n" +
            "    ws {\n" +
            "        git($/" + sampleRepo + "/$)\n" +
            "    }\n" +
            "}"));


    WorkflowRun b1 = job1.scheduleBuild2(0).get();
    j.assertBuildStatusSuccess(b1);

    sampleRepo.write("file1", "");
    sampleRepo.git("add", "file1");
    sampleRepo.git("commit", "--message=init");

    WorkflowRun b2 = job1.scheduleBuild2(0).get();
    j.assertBuildStatusSuccess(b2);

    Assert.assertNotEquals(new PipelineRunImpl(b1, null, null).getCommitId(), new PipelineRunImpl(b2, null, null).getCommitId());

    request().post("/organizations/jenkins/pipelines/pipeline1/runs/1/replay").build(String.class);

    j.waitForCompletion(job1.getLastBuild());

    Map r = request().get("/organizations/jenkins/pipelines/pipeline1/runs/3/").build(Map.class);
    assertEquals(r.get("commitId"), new PipelineRunImpl(b2,null, null).getCommitId());
}
 
源代码18 项目: blueocean-plugin   文件: RunImplTest.java
@Issue("JENKINS-44981")
@Test
public void queuedSingleNode() throws Exception {
    WorkflowJob p = createWorkflowJobWithJenkinsfile(getClass(),"queuedSingleNode.jenkinsfile");

    // Ensure null before first run
    Map pipeline = request().get(String.format("/organizations/jenkins/pipelines/%s/", p.getName())).build(Map.class);
    Assert.assertNull(pipeline.get("latestRun"));

    // Run until completed
    WorkflowRun r = p.scheduleBuild2(0).waitForStart();
    j.waitForMessage("Still waiting to schedule task", r);

    // Get latest run for this pipeline
    pipeline = request().get(String.format("/organizations/jenkins/pipelines/%s/", p.getName())).build(Map.class);
    Map latestRun = (Map) pipeline.get("latestRun");

    Assert.assertEquals("QUEUED", latestRun.get("state"));
    Assert.assertEquals("1", latestRun.get("id"));

    // Jenkins 2.125 introduced quotes around these labels - see commit 91ddc6. This came
    // just after the current Jenkins LTS, which is version 2.121.1. So this assert now
    // tests for the new quoted version, and the old non-quoted version.
    Assert.assertThat((String)latestRun.get("causeOfBlockage"), anyOf(
        equalTo("\u2018Jenkins\u2019 doesn’t have label \u2018test\u2019"),
        equalTo("Jenkins doesn’t have label test")
    ));

    j.createOnlineSlave(Label.get("test"));

    j.assertBuildStatusSuccess(j.waitForCompletion(r));
}
 
@Test
public void givenNoRequiredCapacity_shouldDoNotScale() {
    final EC2FleetCloud ec2FleetCloud = mock(EC2FleetCloud.class);
    clouds.add(ec2FleetCloud);

    strategy.apply(state);

    verify(ec2FleetCloud, never()).canProvision(any(Label.class));
}
 
@Test
public void givenAvailableSameAsRequiredCapacity_shouldDoNotScale() {
    final EC2FleetCloud ec2FleetCloud = mock(EC2FleetCloud.class);
    clouds.add(ec2FleetCloud);
    when(snapshot.getQueueLength()).thenReturn(10);
    when(snapshot.getAvailableExecutors()).thenReturn(10);

    Assert.assertEquals(
            NodeProvisioner.StrategyDecision.PROVISIONING_COMPLETED,
            strategy.apply(state));

    verify(ec2FleetCloud, never()).canProvision(any(Label.class));
}
 
@Test
public void givenEC2CloudWithDisabledNoDelay_shouldDoNotScale() {
    when(snapshot.getQueueLength()).thenReturn(10);
    when(state.getLabel()).thenReturn(label);

    final EC2FleetCloud ec2FleetCloud = mock(EC2FleetCloud.class);
    clouds.add(ec2FleetCloud);
    when(ec2FleetCloud.canProvision(any(Label.class))).thenReturn(true);
    when(ec2FleetCloud.isNoDelayProvision()).thenReturn(false);

    Assert.assertEquals(
            NodeProvisioner.StrategyDecision.CONSULT_REMAINING_STRATEGIES,
            strategy.apply(state));
    verify(ec2FleetCloud, never()).provision(any(Label.class), anyInt());
}
 
@Test
public void givenEC2CloudWhichCannotProvision_shouldDoNotScale() {
    when(snapshot.getQueueLength()).thenReturn(10);
    when(state.getLabel()).thenReturn(label);

    final EC2FleetCloud ec2FleetCloud = mock(EC2FleetCloud.class);
    clouds.add(ec2FleetCloud);
    when(ec2FleetCloud.canProvision(any(Label.class))).thenReturn(false);

    Assert.assertEquals(
            NodeProvisioner.StrategyDecision.CONSULT_REMAINING_STRATEGIES,
            strategy.apply(state));
    verify(ec2FleetCloud, never()).provision(any(Label.class), anyInt());
}
 
@Override
public Collection<NodeProvisioner.PlannedNode> provision(
        final Label label, final int excessWorkload) {
    final Collection<NodeProvisioner.PlannedNode> r = super.provision(label, excessWorkload);
    for (NodeProvisioner.PlannedNode ignore : r) provisionTimes.add(System.currentTimeMillis());
    return r;
}
 
@Test
public void should_keep_planned_node_until_node_will_not_be_online_so_jenkins_will_not_request_overprovision() throws Exception {
    ComputerLauncher computerLauncher = mock(ComputerLauncher.class);
    ComputerConnector computerConnector = mock(ComputerConnector.class);
    when(computerConnector.launch(anyString(), any(TaskListener.class))).thenReturn(computerLauncher);

    EC2FleetCloud cloud = spy(new EC2FleetCloud(null, null, "credId", null, "region",
            null, "fId", "momo", null, computerConnector, false, false,
            0, 0, 10, 1, false, false,
            false, 300, 15, false,
            2, false));

    // provide init state
    cloud.setStats(new FleetStateStats("", 0, "active",
            Collections.<String>emptySet(), Collections.<String, Double>emptyMap()));

    j.jenkins.clouds.add(cloud);

    mockEc2ApiToDescribeInstancesWhenModified(InstanceStateName.Running);

    List<QueueTaskFuture> rs = getQueueTaskFutures(1);

    final String labelString = "momo";
    triggerSuggestReviewNow(labelString);

    Thread.sleep(TimeUnit.MINUTES.toMillis(2));

    verify(cloud, times(1)).provision(any(Label.class), anyInt());

    cancelTasks(rs);
}
 
@Override
public Collection<NodeProvisioner.PlannedNode> provision(
        final Label label, final int excessWorkload) {
    try (Meter.Shot s = provisionMeter.start()) {
        return super.provision(label, excessWorkload);
    }
}
 
@SuppressWarnings("unused") // used by stapler
public ComboBoxModel doFillLabelItems() {
    ComboBoxModel cbm = new ComboBoxModel();
    Set<Label> labels = Jenkins.get().getLabels();
    for (Label label : labels) {
        cbm.add(label.getDisplayName());
    }
    return cbm;
}
 
源代码27 项目: kubernetes-plugin   文件: KubernetesCloudTest.java
@Test
public void testInstanceCap() {
    KubernetesCloud cloud = new KubernetesCloud("name") {
        @Override
        public KubernetesClient connect() {
            KubernetesClient mockClient =  Mockito.mock(KubernetesClient.class);
            Mockito.when(mockClient.getNamespace()).thenReturn("default");
            MixedOperation<Pod, PodList, DoneablePod, PodResource<Pod, DoneablePod>> operation = Mockito.mock(MixedOperation.class);
            Mockito.when(operation.inNamespace(Mockito.anyString())).thenReturn(operation);
            Mockito.when(operation.withLabels(Mockito.anyMap())).thenReturn(operation);
            PodList podList = Mockito.mock(PodList.class);
            Mockito.when(podList.getItems()).thenReturn(new ArrayList<>());
            Mockito.when(operation.list()).thenReturn(podList);
            Mockito.when(mockClient.pods()).thenReturn(operation);
            return mockClient;
        }
    };

    PodTemplate podTemplate = new PodTemplate();
    podTemplate.setName("test");
    podTemplate.setLabel("test");

    cloud.addTemplate(podTemplate);

    Label test = Label.get("test");
    assertTrue(cloud.canProvision(test));

    Collection<NodeProvisioner.PlannedNode> plannedNodes = cloud.provision(test, 200);
    assertEquals(200, plannedNodes.size());

    podTemplate.setInstanceCap(5);
    plannedNodes = cloud.provision(test, 200);
    assertEquals(5, plannedNodes.size());
}
 
源代码28 项目: amazon-ecs-plugin   文件: ECSCloud.java
@Override
public synchronized Collection<NodeProvisioner.PlannedNode> provision(Label label, int excessWorkload) {

    LOGGER.log(Level.INFO, "Asked to provision {0} agent(s) for: {1}", new Object[]{excessWorkload, label});

    List<NodeProvisioner.PlannedNode> result = new ArrayList<>();
    final ECSTaskTemplate template = getTemplate(label);
    if (template != null) {
        String parentLabel = template.getInheritFrom();
        final ECSTaskTemplate merged = template.merge(getTemplate(parentLabel));

        for (int i = 1; i <= excessWorkload; i++) {
            String agentName = name + "-" + label.getName() + "-" + RandomStringUtils.random(5, "bcdfghjklmnpqrstvwxz0123456789");
            LOGGER.log(Level.INFO, "Will provision {0}, for label: {1}", new Object[]{agentName, label} );
            result.add(
                    new NodeProvisioner.PlannedNode(
                            agentName,
                            Computer.threadPoolForRemoting.submit(
                                    new ProvisioningCallback(merged, agentName)
                            ),
                            1
                    )
            );
        }
    }
    return result.isEmpty() ? Collections.emptyList() : result;

}
 
/**
 * Get a list of available DockerCloud clouds which are not at max
 * capacity.
 *
 * @param label A label expression of a Job Run requiring an executor.
 * @return A list of available DockerCloud clouds.
 */
protected List<DockerCloud> getAvailableDockerClouds(Label label) {
    return getAllDockerClouds().stream()
            .filter(cloud ->
                    cloud.canProvision(label) &&
                            (countCurrentDockerSlaves(cloud) >= 0) &&
                            (countCurrentDockerSlaves(cloud) < cloud.getContainerCap()))
            .collect(Collectors.toList());
}
 
源代码30 项目: jenkins-test-harness   文件: DummyCloudImpl.java
public Collection<PlannedNode> provision(Label label, int excessWorkload) {
    List<PlannedNode> r = new ArrayList<PlannedNode>();
    if(label!=this.label)   return r;   // provisioning impossible

    while(excessWorkload>0) {
        System.out.println("Provisioning");
        numProvisioned++;
        Future<Node> f = Computer.threadPoolForRemoting.submit(new Launcher(delay));
        r.add(new PlannedNode(name+" #"+numProvisioned,f,1));
        excessWorkload-=1;
    }
    return r;
}
 
 类所在包
 同包方法