Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add spotVM and maxRunDuration feature to VM provisioning #492

Open
wants to merge 30 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
742724e
Add maxRunDuration feature to VM provisioning
gbhat618 Dec 10, 2024
0f38202
spot vm and max run duration settings put
gbhat618 Dec 11, 2024
d8e0bca
update comments
gbhat618 Dec 11, 2024
615e605
change from radio to dropdown descriptor selector
gbhat618 Dec 12, 2024
d57ea0c
update comments
gbhat618 Dec 12, 2024
579410e
add an integration test for spot vms with maximum run durations
gbhat618 Dec 13, 2024
17a0113
Fix trailing slash
gbhat618 Dec 16, 2024
411e510
Merge branch 'develop' of github.com:jenkinsci/google-compute-engine-…
gbhat618 Dec 16, 2024
3ddd4d3
update tests and new tests for scheduling code
gbhat618 Dec 16, 2024
363925a
remove the @deprecated annotation that would otherwise break casc com…
gbhat618 Dec 16, 2024
f4c7154
remove the todo added during code analysis
gbhat618 Dec 16, 2024
74fe8c3
fix the access specifier in descriptor
gbhat618 Dec 16, 2024
cfae906
comment add license
gbhat618 Dec 16, 2024
937abdf
remove unused field leftout during refactor
gbhat618 Dec 16, 2024
8fa2222
fix spelling mistake in default
gbhat618 Dec 17, 2024
1708135
re-order setters to reduce diff
gbhat618 Dec 17, 2024
e806d25
fix the default provisioning type considering preemptible could be al…
gbhat618 Dec 17, 2024
50a74b8
spotless
gbhat618 Dec 17, 2024
3e7e787
fix duplication, handle field deprecation and migration
gbhat618 Dec 18, 2024
244da59
fix the preemptive task rescheduling integration tests
gbhat618 Dec 18, 2024
c076896
Update src/main/java/com/google/jenkins/plugins/computeengine/Instanc…
gbhat618 Dec 19, 2024
f656ffc
Update src/main/java/com/google/jenkins/plugins/computeengine/Instanc…
gbhat618 Dec 19, 2024
361bdd0
removing the ProvisioningTypeValue enum
gbhat618 Dec 19, 2024
11c7068
fix the test instead of casc compatibility
gbhat618 Dec 19, 2024
8d7f256
add DataBoundConstructors to classes
gbhat618 Dec 19, 2024
e602674
keep casc compatibility for preemptible field
gbhat618 Dec 19, 2024
ba2d713
fix the test throwing error in RemainingActivityListener, by waitUnti…
gbhat618 Dec 20, 2024
a2dc12c
rename the package from ui.helps to better name configs
gbhat618 Dec 20, 2024
3a2cea4
config (not confi)
gbhat618 Dec 20, 2024
7442934
revert the integration test infra chagnes as these are handled by oth…
gbhat618 Dec 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@

import static com.google.cloud.graphite.platforms.plugin.client.util.ClientUtil.nameFromSelfLink;
import static com.google.jenkins.plugins.computeengine.ComputeEngineCloud.checkPermissions;
import static com.google.jenkins.plugins.computeengine.ui.helpers.ProvisioningTypeValue.PREEMPTIBLE;
import static com.google.jenkins.plugins.computeengine.ui.helpers.ProvisioningTypeValue.SPOT;

import com.google.api.client.json.GenericJson;
import com.google.api.services.compute.model.AcceleratorConfig;
import com.google.api.services.compute.model.AttachedDisk;
import com.google.api.services.compute.model.AttachedDiskInitializeParams;
Expand All @@ -42,6 +45,8 @@
import com.google.jenkins.plugins.computeengine.ssh.GoogleKeyCredential;
import com.google.jenkins.plugins.computeengine.ssh.GoogleKeyPair;
import com.google.jenkins.plugins.computeengine.ssh.GooglePrivateKey;
import com.google.jenkins.plugins.computeengine.ui.helpers.ProvisioningType;
import com.google.jenkins.plugins.computeengine.ui.helpers.ProvisioningTypeValue;
import edu.umd.cs.findbugs.annotations.Nullable;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.Extension;
Expand All @@ -63,6 +68,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Level;
Expand Down Expand Up @@ -120,7 +126,19 @@
private String machineType;
private String numExecutorsStr;
private String startupScript;

/**
* Use the {@link #provisioningType} field instead.
*/
@Deprecated
private boolean preemptible;

/**
* Succeeds {@link #preemptible}.
*/
private ProvisioningType provisioningType;
gbhat618 marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for reviewers: this class is using Lombok (not a good idea!):


private long maxRunDurationSeconds;

Check warning on line 141 in src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 139-141 are not covered by tests
private String minCpuPlatform;
private String labels;
private String runAsUser;
Expand Down Expand Up @@ -494,295 +512,339 @@

private Scheduling scheduling() {
Scheduling scheduling = new Scheduling();
scheduling.setPreemptible(preemptible);

if (provisioningType != null) {

Check warning on line 516 in src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 516 is only partially covered, one branch is missing
if (provisioningType.getValue() == PREEMPTIBLE) {
scheduling.setPreemptible(true);
} else if (provisioningType.getValue() == SPOT) {
scheduling.setProvisioningModel("SPOT");
// only the instance is deleted, the disk deletion is based on bootDiskAutoDelete config value
scheduling.setInstanceTerminationAction("DELETE");

Check warning on line 522 in src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 517-522 are not covered by tests
}
} else if (preemptible) { // keeping the check for `preemptible` for backward compatibility

Check warning on line 524 in src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 524 is only partially covered, one branch is missing
scheduling.setPreemptible(true);
} // else: standard provisioning

if (maxRunDurationSeconds > 0 && provisioningType.getValue() != PREEMPTIBLE) {

Check warning on line 528 in src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 528 is only partially covered, 3 branches are missing
GenericJson j = new GenericJson();
j.set("seconds", maxRunDurationSeconds);
scheduling.set("maxRunDuration", j);
// only the instance is deleted, the disk deletion is based on bootDiskAutoDelete config value
scheduling.setInstanceTerminationAction("DELETE");
}
return scheduling;
}

private List<AttachedDisk> disks() {
AttachedDisk boot = new AttachedDisk();
boot.setBoot(true);
boot.setAutoDelete(bootDiskAutoDelete);
boot.setInitializeParams(new AttachedDiskInitializeParams()
.setDiskSizeGb(bootDiskSizeGb)
.setDiskType(bootDiskType)
.setSourceImage(bootDiskSourceImageName));

List<AttachedDisk> disks = new ArrayList<>();
disks.add(boot);
return disks;
}

private List<AcceleratorConfig> accelerators() {
if (acceleratorConfiguration != null
&& notNullOrEmpty(acceleratorConfiguration.getGpuCount())
&& notNullOrEmpty(acceleratorConfiguration.getGpuType())) {
List<AcceleratorConfig> accelerators = new ArrayList<>();
accelerators.add(new AcceleratorConfig()
.setAcceleratorType(acceleratorConfiguration.getGpuType())
.setAcceleratorCount(acceleratorConfiguration.gpuCount()));
return accelerators;
}
return null;
}

private List<NetworkInterface> networkInterfaces() {
List<NetworkInterface> networkInterfaces = new ArrayList<>();

NetworkInterface networkInterface = networkInterfaceIpStackMode.getNetworkInterface();

// Don't include subnetwork name if using default
if (!networkConfiguration.getSubnetwork().equals("default")) {
networkInterface.setSubnetwork(stripSelfLinkPrefix(networkConfiguration.getSubnetwork()));
}

networkInterfaces.add(networkInterface);
return networkInterfaces;
}

private List<ServiceAccount> serviceAccounts() {
if (notNullOrEmpty(serviceAccountEmail)) {
List<ServiceAccount> serviceAccounts = new ArrayList<>();
serviceAccounts.add(new ServiceAccount()
.setEmail(serviceAccountEmail)
.setScopes(Arrays.asList(new String[] {"https://www.googleapis.com/auth/cloud-platform"})));
return serviceAccounts;
} else {
return null;
}
}

@Extension
public static final class DescriptorImpl extends Descriptor<InstanceConfiguration> {
private static ComputeClient computeClient;
private static List<ProvisioningType.ProvisioningTypeDescriptor> provisioningTypeDescriptors;

public static void setComputeClient(ComputeClient client) {
computeClient = client;
}

public static String defaultRetentionTimeMinutes() {
return DEFAULT_RETENTION_TIME_MINUTES.toString();
}

public static String defaultLaunchTimeoutSeconds() {
return DEFAULT_LAUNCH_TIMEOUT_SECONDS.toString();
}

public static String defaultBootDiskSizeGb() {
return DEFAULT_BOOT_DISK_SIZE_GB.toString();
}

public static String defaultBootDiskAutoDelete() {
return "true";
}

public static String defaultRunAsUser() {
return DEFAULT_RUN_AS_USER;
}

public static WindowsConfiguration defaultWindowsConfiguration() {
return WindowsConfiguration.builder()
.passwordCredentialsId("")
.privateKeyCredentialsId("")
.build();
}

public static SshConfiguration defaultSshConfiguration() {
return SshConfiguration.builder().customPrivateKeyCredentialsId("").build();
}

public static NetworkConfiguration defaultNetworkConfiguration() {
return new AutofilledNetworkConfiguration();
}

private static ComputeClient computeClient(Jenkins context, String credentialsId) throws IOException {
if (computeClient != null) {
return computeClient;
}
ClientFactory clientFactory = ClientUtil.getClientFactory(context, credentialsId);
return clientFactory.computeClient();
}

@Override
public String getHelpFile(String fieldName) {
String p = super.getHelpFile(fieldName);
if (p == null) {
Descriptor d = Jenkins.get().getDescriptor(ComputeEngineInstance.class);
if (d != null) p = d.getHelpFile(fieldName);
}
return p;
}

public List<NetworkConfiguration.NetworkConfigurationDescriptor> getNetworkConfigurationDescriptors() {
List<NetworkConfiguration.NetworkConfigurationDescriptor> d =
Jenkins.get().getDescriptorList(NetworkConfiguration.class);
// No deprecated regions
Iterator it = d.iterator();
while (it.hasNext()) {
NetworkConfiguration.NetworkConfigurationDescriptor o =
(NetworkConfiguration.NetworkConfigurationDescriptor) it.next();
if (o.clazz.getName().equals("NetworkConfiguration")) {
it.remove();
}
}
return d;
}

public FormValidation doCheckNetworkTags(@QueryParameter String value) {
if (value == null || value.isEmpty()) {
return FormValidation.ok();
}

String re = "[a-z]([-a-z0-9]*[a-z0-9])?";
for (String tag : value.split(" ")) {
if (!tag.matches(re)) {
return FormValidation.error("Tags must be space-delimited and each tag must match regex" + re);
}
}

return FormValidation.ok();
}

public FormValidation doCheckNamePrefix(@QueryParameter String value) {
if (value == null || value.isEmpty()) {
return FormValidation.error("A prefix is required");
}

String re = "[a-z]([-a-z0-9]*[a-z0-9])?";
if (!value.matches(re)) {
return FormValidation.error("Prefix must match regex " + re);
}

Integer maxLen = 50;
if (value.length() > maxLen) {
return FormValidation.error("Maximum length is " + maxLen);
}
return FormValidation.ok();
}

public FormValidation doCheckDescription(@QueryParameter String value) {
if (value == null || value.isEmpty()) {
return FormValidation.error("A description is required");
}
return FormValidation.ok();
}

public ListBoxModel doFillRegionItems(
@AncestorInPath Jenkins context,
@QueryParameter("projectId") @RelativePath("..") final String projectId,
@QueryParameter("credentialsId") @RelativePath("..") final String credentialsId) {
checkPermissions(Jenkins.get(), Jenkins.ADMINISTER);
ListBoxModel items = new ListBoxModel();
items.add("");
try {
ComputeClient compute = computeClient(context, credentialsId);
List<Region> regions = compute.listRegions(projectId);

for (Region r : regions) {
items.add(r.getName(), r.getSelfLink());
}
return items;
} catch (IOException ioe) {
items.clear();
items.add("Error retrieving regions");
return items;
}
}

public ListBoxModel doFillTemplateItems(
@AncestorInPath Jenkins context,
@QueryParameter("projectId") @RelativePath("..") final String projectId,
@QueryParameter("credentialsId") @RelativePath("..") final String credentialsId) {
checkPermissions(Jenkins.get(), Jenkins.ADMINISTER);
ListBoxModel items = new ListBoxModel();
items.add("");
try {
ComputeClient compute = computeClient(context, credentialsId);
List<InstanceTemplate> instanceTemplates = compute.listTemplates(projectId);

for (InstanceTemplate instanceTemplate : instanceTemplates) {
items.add(instanceTemplate.getName(), instanceTemplate.getSelfLink());
}
return items;
} catch (IOException ioe) {
items.clear();
items.add("Error retrieving instanceTemplates");
return items;
}
}

public FormValidation doCheckRegion(@QueryParameter String value) {
if (StringUtils.isEmpty(value)) {
return FormValidation.error("Please select a region...");
}
return FormValidation.ok();
}

public ListBoxModel doFillZoneItems(
@AncestorInPath Jenkins context,
@QueryParameter("projectId") @RelativePath("..") final String projectId,
@QueryParameter("region") final String region,
@QueryParameter("credentialsId") @RelativePath("..") final String credentialsId) {
checkPermissions(Jenkins.get(), Jenkins.ADMINISTER);
ListBoxModel items = new ListBoxModel();
items.add("");
try {
ComputeClient compute = computeClient(context, credentialsId);
List<Zone> zones = compute.listZones(projectId, region);

for (Zone z : zones) {
items.add(z.getName(), z.getSelfLink());
}
return items;
} catch (IOException ioe) {
items.clear();
items.add("Error retrieving zones");
return items;
} catch (IllegalArgumentException iae) {
// TODO log
return null;
}
}

public FormValidation doCheckZone(@QueryParameter String value) {
if (StringUtils.isEmpty(value)) {
return FormValidation.error("Please select a zone...");
}
return FormValidation.ok();
}

public ListBoxModel doFillMachineTypeItems(
@AncestorInPath Jenkins context,
@QueryParameter("projectId") @RelativePath("..") final String projectId,
@QueryParameter("zone") final String zone,
@QueryParameter("credentialsId") @RelativePath("..") final String credentialsId) {
checkPermissions(Jenkins.get(), Jenkins.ADMINISTER);
ListBoxModel items = new ListBoxModel();
items.add("");
try {
ComputeClient compute = computeClient(context, credentialsId);
List<MachineType> machineTypes = compute.listMachineTypes(projectId, zone);

for (MachineType m : machineTypes) {
items.add(m.getName(), m.getSelfLink());
}
return items;
} catch (IOException ioe) {
items.clear();
items.add("Error retrieving machine types");
return items;
} catch (IllegalArgumentException iae) {
// TODO log
return null;
}
}

public FormValidation doCheckMachineType(@QueryParameter String value) {
if (StringUtils.isEmpty(value)) {
return FormValidation.error("Please select a machine type...");
}
return FormValidation.ok();
}

public FormValidation doCheckMaxRunDurationSeconds(
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
@QueryParameter String value, @QueryParameter(value = "provisioningType") String provisioningTypeIdx) {
gbhat618 marked this conversation as resolved.
Show resolved Hide resolved
try {
long maxRunDurationSeconds = Long.parseLong(value);
if (maxRunDurationSeconds < 0) {
return FormValidation.error("Max run duration must be greater than or equal to 0");
}

if (StringUtils.isNotBlank(provisioningTypeIdx)) {
ProvisioningTypeValue provisioningTypeValue = provisioningTypeDescriptors
.get(Integer.parseInt(provisioningTypeIdx))
.getProvisioningTypeValue();
if (provisioningTypeValue == PREEMPTIBLE) {
return FormValidation.warning(
"Max run duration is not supported for preemptible VMs and will be ignored.");
}
}

return FormValidation.ok();
} catch (NumberFormatException e) {
return FormValidation.error("Max run duration must be non-negative number");
}
}

public ListBoxModel doFillMinCpuPlatformItems(
@AncestorInPath Jenkins context,
@QueryParameter("projectId") @RelativePath("..") final String projectId,
Expand Down Expand Up @@ -943,6 +1005,15 @@
return FormValidation.ok();
}

@SuppressWarnings("unused")
gbhat618 marked this conversation as resolved.
Show resolved Hide resolved
public List<ProvisioningType.ProvisioningTypeDescriptor> getProvisioningTypes() {
if (provisioningTypeDescriptors == null) {
provisioningTypeDescriptors =
Objects.requireNonNull(Jenkins.getInstanceOrNull()).getDescriptorList(ProvisioningType.class);
}
return provisioningTypeDescriptors;

Check warning on line 1014 in src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 529-1014 are not covered by tests
}

public List<NetworkInterfaceIpStackMode.Descriptor> getNetworkInterfaceIpStackModeDescriptors() {
return ExtensionList.lookup(NetworkInterfaceIpStackMode.Descriptor.class);
}
Expand All @@ -959,6 +1030,8 @@
instanceConfiguration.setNumExecutorsStr(this.numExecutorsStr);
instanceConfiguration.setStartupScript(this.startupScript);
instanceConfiguration.setPreemptible(this.preemptible);
instanceConfiguration.setProvisioningType(this.provisioningType);
instanceConfiguration.setMaxRunDurationSeconds(this.maxRunDurationSeconds);
instanceConfiguration.setMinCpuPlatform(this.minCpuPlatform);
instanceConfiguration.setLabelString(this.labels);
instanceConfiguration.setRunAsUser(this.runAsUser);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2024 CloudBees, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.jenkins.plugins.computeengine.ui.helpers;
gbhat618 marked this conversation as resolved.
Show resolved Hide resolved

import hudson.Extension;
import org.kohsuke.stapler.DataBoundConstructor;

@SuppressWarnings("unused")
public class PreemptibleVm extends ProvisioningType {

@DataBoundConstructor
public PreemptibleVm() {
super(ProvisioningTypeValue.PREEMPTIBLE);
}

Check warning on line 28 in src/main/java/com/google/jenkins/plugins/computeengine/ui/helpers/PreemptibleVm.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 27-28 are not covered by tests

@Extension
public static class DescriptorImpl extends ProvisioningTypeDescriptor {
@Override
public String getDisplayName() {
return "Preemptible VM";
}

@Override
public ProvisioningTypeValue getProvisioningTypeValue() {
return ProvisioningTypeValue.PREEMPTIBLE;

Check warning on line 39 in src/main/java/com/google/jenkins/plugins/computeengine/ui/helpers/PreemptibleVm.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 39 is not covered by tests
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2024 CloudBees, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.jenkins.plugins.computeengine.ui.helpers;

import hudson.model.AbstractDescribableImpl;
import hudson.model.Descriptor;
import org.kohsuke.stapler.DataBoundSetter;

/**
* ProvisioningType represents the type of VM to be provisioned.
*/
public abstract class ProvisioningType extends AbstractDescribableImpl<ProvisioningType> {
public ProvisioningTypeValue value;

public ProvisioningType(ProvisioningTypeValue value) {
this.value = value;
}

public ProvisioningTypeValue getValue() {
return value;
}

@DataBoundSetter
public void setProvisioningTypeValue(ProvisioningTypeValue value) {
this.value = value;
}

Check warning on line 40 in src/main/java/com/google/jenkins/plugins/computeengine/ui/helpers/ProvisioningType.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 29-40 are not covered by tests

public abstract static class ProvisioningTypeDescriptor extends Descriptor<ProvisioningType> {
public abstract ProvisioningTypeValue getProvisioningTypeValue();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2024 CloudBees, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.jenkins.plugins.computeengine.ui.helpers;

public enum ProvisioningTypeValue {
gbhat618 marked this conversation as resolved.
Show resolved Hide resolved
STANDARD,
SPOT,
PREEMPTIBLE;

Check warning on line 22 in src/main/java/com/google/jenkins/plugins/computeengine/ui/helpers/ProvisioningTypeValue.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 19-22 are not covered by tests
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2024 CloudBees, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.jenkins.plugins.computeengine.ui.helpers;

import hudson.Extension;
import org.kohsuke.stapler.DataBoundConstructor;

@SuppressWarnings("unused")
public class SpotVm extends ProvisioningType {
gbhat618 marked this conversation as resolved.
Show resolved Hide resolved

@DataBoundConstructor
public SpotVm() {
super(ProvisioningTypeValue.SPOT);
}

Check warning on line 28 in src/main/java/com/google/jenkins/plugins/computeengine/ui/helpers/SpotVm.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 27-28 are not covered by tests

@Extension
public static class DescriptorImpl extends ProvisioningTypeDescriptor {
@Override
public String getDisplayName() {
return "Spot VM";
}

@Override
public ProvisioningTypeValue getProvisioningTypeValue() {
return ProvisioningTypeValue.SPOT;

Check warning on line 39 in src/main/java/com/google/jenkins/plugins/computeengine/ui/helpers/SpotVm.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 39 is not covered by tests
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2024 CloudBees, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.jenkins.plugins.computeengine.ui.helpers;

import hudson.Extension;
import org.kohsuke.stapler.DataBoundConstructor;

@SuppressWarnings("unused")
public class Standard extends ProvisioningType {

@DataBoundConstructor
public Standard() {
super(ProvisioningTypeValue.STANDARD);
}

Check warning on line 28 in src/main/java/com/google/jenkins/plugins/computeengine/ui/helpers/Standard.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 27-28 are not covered by tests

@Extension
public static class DescriptorImpl extends ProvisioningTypeDescriptor {
@Override
public String getDisplayName() {
return "Standard";
}

@Override
public ProvisioningTypeValue getProvisioningTypeValue() {
return ProvisioningTypeValue.STANDARD;

Check warning on line 39 in src/main/java/com/google/jenkins/plugins/computeengine/ui/helpers/Standard.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 39 is not covered by tests
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,12 @@
<f:entry field="machineType" title="${%Machine Type}">
<f:select/>
</f:entry>
<f:entry field="preemptible" title="${%Preemptible?}">
<f:checkbox/>
<f:descriptorRadioList descriptors="${descriptor.provisioningTypes}"
gbhat618 marked this conversation as resolved.
Show resolved Hide resolved
title="Provisioning Type"
instance="${instance}"
varName="provisioningType"/>
<f:entry field="maxRunDurationSeconds" title="${%Max Run Duration Seconds}">
<f:textbox/>
</f:entry>
<f:entry field="minCpuPlatform" title="${%Minimum Cpu Platform}">
<f:select/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!--
Copyright 2024 CloudBees, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<div>
The maximum duration (in seconds) after which the VM will be automatically deleted by GCP.
See <a href="https://cloud.google.com/compute/docs/instances/limit-vm-runtime">Limit the run time of a VM</a> for more details.
</div>

This file was deleted.

Loading
Loading