<NME> PodTemplateStep.java
<BEF> package org.csanchez.jenkins.plugins.kubernetes.pipeline;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import edu.umd.cs.findbugs.annotations.CheckForNull;
import hudson.slaves.Cloud;
import hudson.util.ListBoxModel;
import jenkins.model.Jenkins;
import org.apache.commons.lang.StringUtils;
import org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate;
import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud;
import org.csanchez.jenkins.plugins.kubernetes.PodAnnotation;
import org.csanchez.jenkins.plugins.kubernetes.PodTemplate;
import org.csanchez.jenkins.plugins.kubernetes.model.TemplateEnvVar;
import org.csanchez.jenkins.plugins.kubernetes.pod.retention.PodRetention;
import org.csanchez.jenkins.plugins.kubernetes.pod.yaml.YamlMergeStrategy;
import org.csanchez.jenkins.plugins.kubernetes.volumes.PodVolume;
import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.WorkspaceVolume;
import org.jenkinsci.plugins.workflow.steps.Step;
import org.jenkinsci.plugins.workflow.steps.StepContext;
import org.jenkinsci.plugins.workflow.steps.StepDescriptor;
import org.jenkinsci.plugins.workflow.steps.StepExecution;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

import hudson.Extension;
import hudson.Util;
import hudson.model.Node;
import hudson.model.Run;
import hudson.model.TaskListener;
import org.kohsuke.stapler.QueryParameter;

public class PodTemplateStep extends Step implements Serializable {

    private static final long serialVersionUID = 5588861066775717487L;

    @CheckForNull
    private String cloud;

    @CheckForNull
    private String inheritFrom;

    @CheckForNull
    private String label;

    @CheckForNull
    private String name;

    @CheckForNull
    private String namespace;

    private List<ContainerTemplate> containers = new ArrayList<>();
    private List<TemplateEnvVar> envVars = new ArrayList<>();
    private List<PodVolume> volumes = new ArrayList<PodVolume>();

    @CheckForNull
    private WorkspaceVolume workspaceVolume;

    private List<PodAnnotation> annotations = new ArrayList<>();
    private List<String> imagePullSecrets = new ArrayList<>();

    private Integer instanceCap = Integer.MAX_VALUE;
    private int idleMinutes;
    private int slaveConnectTimeout = PodTemplate.DEFAULT_SLAVE_JENKINS_CONNECTION_TIMEOUT;
    private int activeDeadlineSeconds;

    private Boolean hostNetwork;

    @CheckForNull
    private String serviceAccount;

    @CheckForNull
    private String schedulerName;

    @CheckForNull
    private String nodeSelector;

    private Node.Mode nodeUsageMode = Node.Mode.EXCLUSIVE;
    private String workingDir = ContainerTemplate.DEFAULT_WORKING_DIR;

    @CheckForNull
    private String yaml;

    private YamlMergeStrategy yamlMergeStrategy = YamlMergeStrategy.defaultStrategy();

    @CheckForNull
    private PodRetention podRetention;

    private Boolean showRawYaml;


    @CheckForNull
    private String runAsUser;

    @CheckForNull
    private String runAsGroup;

    @CheckForNull
    private String supplementalGroups;

    @DataBoundConstructor
    public PodTemplateStep() {}

    public String getLabel() {
        return label;
    }

    @DataBoundSetter
    public void setLabel(@CheckForNull String label) {
        this.label = Util.fixEmpty(label);
    }

    @CheckForNull
    public String getName() {
        return name;
    }

    @DataBoundSetter
    public void setName(@CheckForNull String name) {
        this.name = Util.fixEmpty(name);
    }

    @CheckForNull
    public String getNamespace() {
        return namespace;
    }

    @DataBoundSetter
    public void setNamespace(@CheckForNull String namespace) {
        this.namespace = Util.fixEmpty(namespace);
    }

    @CheckForNull
    public String getCloud() {
        return cloud;
    }

    @DataBoundSetter
    public void setCloud(@CheckForNull String cloud) {

    @DataBoundSetter
    public void setInheritFrom(@CheckForNull String inheritFrom) {
        if (DescriptorImpl.defaultInheritFrom.equals(inheritFrom)) { // Added to make KubernetesPipelineTest.runInPodNestedExplicitInherit() pass
            this.inheritFrom = null;
        } else {
            this.inheritFrom = inheritFrom;

    @DataBoundSetter
    public void setInheritFrom(@CheckForNull String inheritFrom) {
        if (DescriptorImpl.defaultInheritFrom.equals(inheritFrom)) {
            this.inheritFrom = null;
        } else {
            this.inheritFrom = inheritFrom;
        }
    }

    public List<ContainerTemplate> getContainers() {
        return containers;
    }

    @DataBoundSetter
    public void setContainers(List<ContainerTemplate> containers) {
        this.containers = containers;
    }

    public List<TemplateEnvVar> getEnvVars() {
        return envVars == null ? Collections.emptyList() : envVars;
    }

    @DataBoundSetter
    public void setEnvVars(List<TemplateEnvVar> envVars) {
        if (envVars != null) {
            this.envVars.clear();
            this.envVars.addAll(envVars);
        }
    }

    @CheckForNull
    public YamlMergeStrategy getYamlMergeStrategy() {
        return yamlMergeStrategy;
    }

    @DataBoundSetter
    public void setYamlMergeStrategy(YamlMergeStrategy yamlMergeStrategy) {
        this.yamlMergeStrategy = yamlMergeStrategy;
    }

    public List<PodVolume> getVolumes() {
        return volumes;
    }

    @DataBoundSetter
    public void setVolumes(List<PodVolume> volumes) {
        this.volumes = volumes;
    }

    @CheckForNull
    public WorkspaceVolume getWorkspaceVolume() {
        return workspaceVolume == null ? DescriptorImpl.defaultWorkspaceVolume : this.workspaceVolume;
    }

    @DataBoundSetter
    public void setWorkspaceVolume(@CheckForNull WorkspaceVolume workspaceVolume) {
        this.workspaceVolume = (workspaceVolume == null || workspaceVolume.equals(DescriptorImpl.defaultWorkspaceVolume)) ? null : workspaceVolume;
    }

    public Integer getInstanceCap() {
        return instanceCap;
    }

    @DataBoundSetter
    public void setInstanceCap(@CheckForNull Integer instanceCap) {
        if (instanceCap == null || instanceCap.intValue() <= 0) {
            this.instanceCap = Integer.MAX_VALUE;
        } else {
            this.instanceCap = instanceCap;
        }
    }

    public int getIdleMinutes() {
        return idleMinutes;
    }

    @DataBoundSetter
    public void setIdleMinutes(@CheckForNull int idleMinutes) {
        this.idleMinutes = idleMinutes;
    }

    @CheckForNull
    public int getSlaveConnectTimeout() {
        return slaveConnectTimeout;
    }

    @DataBoundSetter
    public void setSlaveConnectTimeout(@CheckForNull int slaveConnectTimeout) {
        this.slaveConnectTimeout = slaveConnectTimeout;
    }

    @CheckForNull
    public int getActiveDeadlineSeconds() {
        return activeDeadlineSeconds;
    }

    @DataBoundSetter
    public void setActiveDeadlineSeconds(@CheckForNull int activeDeadlineSeconds) {
        this.activeDeadlineSeconds = activeDeadlineSeconds;
    }

    public Boolean getHostNetwork() {
        return hostNetwork;
    }

    @DataBoundSetter
    public void setHostNetwork(boolean hostNetwork) {
        this.hostNetwork = hostNetwork;
    }

    @CheckForNull
    public String getServiceAccount() { return serviceAccount; }

    @DataBoundSetter
    public void setServiceAccount(@CheckForNull String serviceAccount) {
        this.serviceAccount = Util.fixEmpty(serviceAccount);
    }

    @CheckForNull
    public String getSchedulerName() { return schedulerName; }

    @DataBoundSetter
    public void setSchedulerName(@CheckForNull String schedulerName) {
        this.schedulerName = Util.fixEmpty(schedulerName);
    }

    @CheckForNull
    public String getNodeSelector() {
        return nodeSelector;
    }

    @DataBoundSetter
    public void setNodeSelector(@CheckForNull String nodeSelector) {
        this.nodeSelector = Util.fixEmpty(nodeSelector);
    }

    public Node.Mode getNodeUsageMode() {
        return nodeUsageMode;
    }

    public void setNodeUsageMode(Node.Mode nodeUsageMode) {
        this.nodeUsageMode = nodeUsageMode;
    }

    @DataBoundSetter
    public void setNodeUsageMode(String nodeUsageMode) {
        this.nodeUsageMode = Node.Mode.valueOf(nodeUsageMode);
    }

    public String getWorkingDir() {
        return workingDir;
    }

    @DataBoundSetter
    public void setWorkingDir(String workingDir) {
        this.workingDir = workingDir;
    }

    @Override
    public StepExecution start(StepContext context) throws Exception {
        return new PodTemplateStepExecution(this, context);
    }

    public List<PodAnnotation> getAnnotations() {
        return annotations;
    }

    @DataBoundSetter
    public void setAnnotations(List<PodAnnotation> annotations) {
        this.annotations = annotations;
    }

    public List<String> getImagePullSecrets() {
        return imagePullSecrets == null ? Collections.emptyList() : imagePullSecrets;
    }

    @DataBoundSetter
    public void setImagePullSecrets(List<String> imagePullSecrets) {
        if (imagePullSecrets != null) {
            this.imagePullSecrets.clear();
            this.imagePullSecrets.addAll(imagePullSecrets);
        }
    }

    @CheckForNull
    public String getYaml() {
        return yaml;
    }

    @DataBoundSetter
    public void setYaml(@CheckForNull String yaml) {
        this.yaml = Util.fixEmpty(yaml);
    }

    @CheckForNull
    public PodRetention getPodRetention() {
        return this.podRetention == null ? DescriptorImpl.defaultPodRetention : this.podRetention;
    }

    @DataBoundSetter
    public void setPodRetention(@CheckForNull PodRetention podRetention) {
        this.podRetention = (podRetention == null || podRetention.equals(DescriptorImpl.defaultPodRetention)) ? null : podRetention;
    }

    boolean isShowRawYamlSet() {
        return showRawYaml != null;
    }

    public boolean isShowRawYaml() {
        return isShowRawYamlSet() ? showRawYaml.booleanValue() : true;
    }

    @DataBoundSetter
    public void setShowRawYaml(boolean showRawYaml) {
        this.showRawYaml = Boolean.valueOf(showRawYaml);
    }

    public String getRunAsUser(){
        return this.runAsUser;
    }

    @DataBoundSetter
    public void setRunAsUser(String runAsUser) {
        this.runAsUser = runAsUser;
    }

    public String getRunAsGroup(){
        return this.runAsGroup;
    }

    @DataBoundSetter
    public void setRunAsGroup(String runAsGroup) {
        this.runAsGroup = runAsGroup;
    }

    @CheckForNull
    public String getSupplementalGroups() {
        return supplementalGroups;
    }

    @DataBoundSetter
    public void setSupplementalGroups(@CheckForNull String supplementalGroups) {
        this.supplementalGroups = Util.fixEmpty(supplementalGroups);
    }

    @Extension
    public static class DescriptorImpl extends StepDescriptor {

        static final String[] POD_TEMPLATE_FIELDS = {"name", "namespace", "inheritFrom", "containers", "envVars", "volumes", "annotations", "yaml", "showRawYaml", "instanceCap", "podRetention", "supplementalGroups", "idleMinutes", "activeDeadlineSeconds", "serviceAccount", "nodeSelector", "workingDir", "workspaceVolume"};

        public DescriptorImpl() {
            for (String field : POD_TEMPLATE_FIELDS) {
                addHelpFileRedirect(field, PodTemplate.class, field);
            }
        }

        @SuppressWarnings("unused") // by stapler/jelly
        public ListBoxModel doFillCloudItems() {
            ListBoxModel result = new ListBoxModel();
            result.add("—any—", "");
            if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) { // TODO track use of SYSTEM_READ and/or MANAGE in GlobalCloudConfiguration
                return result;
            }
            Jenkins.get().clouds
                    .getAll(KubernetesCloud.class)
                    .forEach(cloud -> result.add(cloud.name));
            return result;
        }

        @SuppressWarnings("unused") // by stapler/jelly
        public ListBoxModel doFillInheritFromItems(@QueryParameter("cloud") String cloudName) {
            cloudName = Util.fixEmpty(cloudName);
            ListBoxModel result = new ListBoxModel();
            result.add("—Default inheritance—", "<default>");
            result.add("—Disable inheritance—", " ");
            if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) { // TODO track use of SYSTEM_READ and/or MANAGE in GlobalCloudConfiguration
                return result;
            }
            Cloud cloud;
            if (cloudName == null) {
                cloud = Jenkins.get().clouds.get(KubernetesCloud.class);
            } else {
                cloud = Jenkins.get().getCloud(cloudName);
            }
            if (cloud instanceof KubernetesCloud) {
                List<PodTemplate> templates = ((KubernetesCloud) cloud).getTemplates();
                result.addAll(templates.stream()
                        .filter(template -> StringUtils.isNotEmpty(template.getName()))
                        .map(PodTemplate::getName)
                        .map(ListBoxModel.Option::new)
                        .collect(Collectors.toList()));
            }
            return result;
        }

        @Override
        public String getFunctionName() {
            return "podTemplate";
        }

        @Override
        public String getDisplayName() {
            return "Define a podTemplate to use in the kubernetes plugin";
        }

        @Override
        public boolean takesImplicitBlockArgument() {
            return true;
        }

        @Override
        public Set<? extends Class<?>> getRequiredContext() {
            return Collections.unmodifiableSet(new HashSet<>(Arrays.asList(Run.class, TaskListener.class)));
        }

        @SuppressWarnings("unused") // jelly
        public String getWorkingDir() {
            return ContainerTemplate.DEFAULT_WORKING_DIR;
        }

        public static final Integer defaultInstanceCap = Integer.MAX_VALUE;
        public static final PodRetention defaultPodRetention = PodRetention.getPodTemplateDefault();
        public static final WorkspaceVolume defaultWorkspaceVolume = WorkspaceVolume.getDefault();
        /** Only used for snippet generation. */
        public static final String defaultInheritFrom = "<default>";
    }
}

<MSG> Update src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStep.java

Co-Authored-By: Jesse Glick <f03f7b035106bba3da9b565be6f0115dc0d88f87@cloudbees.com>
<DFF> @@ -147,7 +147,7 @@ public class PodTemplateStep extends Step implements Serializable {
 
     @DataBoundSetter
     public void setInheritFrom(@CheckForNull String inheritFrom) {
-        if (DescriptorImpl.defaultInheritFrom.equals(inheritFrom)) { // Added to make KubernetesPipelineTest.runInPodNestedExplicitInherit() pass
+        if (DescriptorImpl.defaultInheritFrom.equals(inheritFrom)) {
             this.inheritFrom = null;
         } else {
             this.inheritFrom = inheritFrom;

{'commit': 'diff --git a/src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStep.java b/src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStep.java\nindex 1ffcc26a..c301167d 100755\n--- a/src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStep.java\n+++ b/src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStep.java\n@@ -147,7 +147,7 @@ public class PodTemplateStep extends Step implements Serializable {\n \n     @DataBoundSetter\n     public void setInheritFrom(@CheckForNull String inheritFrom) {\n-        if (DescriptorImpl.defaultInheritFrom.equals(inheritFrom)) { // Added to make KubernetesPipelineTest.runInPodNestedExplicitInherit() pass\n+        if (DescriptorImpl.defaultInheritFrom.equals(inheritFrom)) {\n             this.inheritFrom = null;\n         } else {\n             this.inheritFrom = inheritFrom;\n', 'commit_subject': 'Update src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStep.java', 'repo_name': 'jenkinsci/kubernetes-plugin', 'committer': {'name': 'GitHub', 'email': '1505422b2465e9a84f6fdfaa161078890c593f06@github.com', 'time_sec': '1583954535', 'tz_offset': '-240', 'date': {'seconds': '1583954535'}}, 'commit_tree': 'f745b028d1c39e6dc22c584e680c1e83222b73c4', 'commit_message': 'Update src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStep.java\n\nCo-Authored-By: Jesse Glick <f03f7b035106bba3da9b565be6f0115dc0d88f87@cloudbees.com>', 'language_name': 'Java', 'license': 'apache-2.0', 'hunks': '@@ -147,7 +147,7 @@ public class PodTemplateStep extends Step implements Serializable {\n \n     @DataBoundSetter\n     public void setInheritFrom(@CheckForNull String inheritFrom) {\n-        if (DescriptorImpl.defaultInheritFrom.equals(inheritFrom)) { // Added to make KubernetesPipelineTest.runInPodNestedExplicitInherit() pass\n+        if (DescriptorImpl.defaultInheritFrom.equals(inheritFrom)) {\n             this.inheritFrom = null;\n         } else {\n             this.inheritFrom = inheritFrom;\n', 'addition_count': 1, 'deletion_count': 1, 'src_file': 'a/src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStep.java', 'tgt_file': 'b/src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStep.java', 'file_extension': '.java', 'before_file': 'package org.csanchez.jenkins.plugins.kubernetes.pipeline;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.stream.Collectors;\n\nimport edu.umd.cs.findbugs.annotations.CheckForNull;\nimport hudson.slaves.Cloud;\nimport hudson.util.ListBoxModel;\nimport jenkins.model.Jenkins;\nimport org.apache.commons.lang.StringUtils;\nimport org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate;\nimport org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud;\nimport org.csanchez.jenkins.plugins.kubernetes.PodAnnotation;\nimport org.csanchez.jenkins.plugins.kubernetes.PodTemplate;\nimport org.csanchez.jenkins.plugins.kubernetes.model.TemplateEnvVar;\nimport org.csanchez.jenkins.plugins.kubernetes.pod.retention.PodRetention;\nimport org.csanchez.jenkins.plugins.kubernetes.pod.yaml.YamlMergeStrategy;\nimport org.csanchez.jenkins.plugins.kubernetes.volumes.PodVolume;\nimport org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.WorkspaceVolume;\nimport org.jenkinsci.plugins.workflow.steps.Step;\nimport org.jenkinsci.plugins.workflow.steps.StepContext;\nimport org.jenkinsci.plugins.workflow.steps.StepDescriptor;\nimport org.jenkinsci.plugins.workflow.steps.StepExecution;\nimport org.kohsuke.stapler.DataBoundConstructor;\nimport org.kohsuke.stapler.DataBoundSetter;\n\nimport hudson.Extension;\nimport hudson.Util;\nimport hudson.model.Node;\nimport hudson.model.Run;\nimport hudson.model.TaskListener;\nimport org.kohsuke.stapler.QueryParameter;\n\npublic class PodTemplateStep extends Step implements Serializable {\n\n    private static final long serialVersionUID = 5588861066775717487L;\n\n    @CheckForNull\n    private String cloud;\n\n    @CheckForNull\n    private String inheritFrom;\n\n    @CheckForNull\n    private String label;\n\n    @CheckForNull\n    private String name;\n\n    @CheckForNull\n    private String namespace;\n\n    private List<ContainerTemplate> containers = new ArrayList<>();\n    private List<TemplateEnvVar> envVars = new ArrayList<>();\n    private List<PodVolume> volumes = new ArrayList<PodVolume>();\n\n    @CheckForNull\n    private WorkspaceVolume workspaceVolume;\n\n    private List<PodAnnotation> annotations = new ArrayList<>();\n    private List<String> imagePullSecrets = new ArrayList<>();\n\n    private Integer instanceCap = Integer.MAX_VALUE;\n    private int idleMinutes;\n    private int slaveConnectTimeout = PodTemplate.DEFAULT_SLAVE_JENKINS_CONNECTION_TIMEOUT;\n    private int activeDeadlineSeconds;\n\n    private Boolean hostNetwork;\n\n    @CheckForNull\n    private String serviceAccount;\n\n    @CheckForNull\n    private String schedulerName;\n\n    @CheckForNull\n    private String nodeSelector;\n\n    private Node.Mode nodeUsageMode = Node.Mode.EXCLUSIVE;\n    private String workingDir = ContainerTemplate.DEFAULT_WORKING_DIR;\n\n    @CheckForNull\n    private String yaml;\n\n    private YamlMergeStrategy yamlMergeStrategy = YamlMergeStrategy.defaultStrategy();\n\n    @CheckForNull\n    private PodRetention podRetention;\n\n    private Boolean showRawYaml;\n\n\n    @CheckForNull\n    private String runAsUser;\n\n    @CheckForNull\n    private String runAsGroup;\n\n    @CheckForNull\n    private String supplementalGroups;\n\n    @DataBoundConstructor\n    public PodTemplateStep() {}\n\n    public String getLabel() {\n        return label;\n    }\n\n    @DataBoundSetter\n    public void setLabel(@CheckForNull String label) {\n        this.label = Util.fixEmpty(label);\n    }\n\n    @CheckForNull\n    public String getName() {\n        return name;\n    }\n\n    @DataBoundSetter\n    public void setName(@CheckForNull String name) {\n        this.name = Util.fixEmpty(name);\n    }\n\n    @CheckForNull\n    public String getNamespace() {\n        return namespace;\n    }\n\n    @DataBoundSetter\n    public void setNamespace(@CheckForNull String namespace) {\n        this.namespace = Util.fixEmpty(namespace);\n    }\n\n    @CheckForNull\n    public String getCloud() {\n        return cloud;\n    }\n\n    @DataBoundSetter\n    public void setCloud(@CheckForNull String cloud) {\n\n    @DataBoundSetter\n    public void setInheritFrom(@CheckForNull String inheritFrom) {\n        if (DescriptorImpl.defaultInheritFrom.equals(inheritFrom)) { // Added to make KubernetesPipelineTest.runInPodNestedExplicitInherit() pass\n            this.inheritFrom = null;\n        } else {\n            this.inheritFrom = inheritFrom;\n\n    @DataBoundSetter\n    public void setInheritFrom(@CheckForNull String inheritFrom) {\n        if (DescriptorImpl.defaultInheritFrom.equals(inheritFrom)) {\n            this.inheritFrom = null;\n        } else {\n            this.inheritFrom = inheritFrom;\n        }\n    }\n\n    public List<ContainerTemplate> getContainers() {\n        return containers;\n    }\n\n    @DataBoundSetter\n    public void setContainers(List<ContainerTemplate> containers) {\n        this.containers = containers;\n    }\n\n    public List<TemplateEnvVar> getEnvVars() {\n        return envVars == null ? Collections.emptyList() : envVars;\n    }\n\n    @DataBoundSetter\n    public void setEnvVars(List<TemplateEnvVar> envVars) {\n        if (envVars != null) {\n            this.envVars.clear();\n            this.envVars.addAll(envVars);\n        }\n    }\n\n    @CheckForNull\n    public YamlMergeStrategy getYamlMergeStrategy() {\n        return yamlMergeStrategy;\n    }\n\n    @DataBoundSetter\n    public void setYamlMergeStrategy(YamlMergeStrategy yamlMergeStrategy) {\n        this.yamlMergeStrategy = yamlMergeStrategy;\n    }\n\n    public List<PodVolume> getVolumes() {\n        return volumes;\n    }\n\n    @DataBoundSetter\n    public void setVolumes(List<PodVolume> volumes) {\n        this.volumes = volumes;\n    }\n\n    @CheckForNull\n    public WorkspaceVolume getWorkspaceVolume() {\n        return workspaceVolume == null ? DescriptorImpl.defaultWorkspaceVolume : this.workspaceVolume;\n    }\n\n    @DataBoundSetter\n    public void setWorkspaceVolume(@CheckForNull WorkspaceVolume workspaceVolume) {\n        this.workspaceVolume = (workspaceVolume == null || workspaceVolume.equals(DescriptorImpl.defaultWorkspaceVolume)) ? null : workspaceVolume;\n    }\n\n    public Integer getInstanceCap() {\n        return instanceCap;\n    }\n\n    @DataBoundSetter\n    public void setInstanceCap(@CheckForNull Integer instanceCap) {\n        if (instanceCap == null || instanceCap.intValue() <= 0) {\n            this.instanceCap = Integer.MAX_VALUE;\n        } else {\n            this.instanceCap = instanceCap;\n        }\n    }\n\n    public int getIdleMinutes() {\n        return idleMinutes;\n    }\n\n    @DataBoundSetter\n    public void setIdleMinutes(@CheckForNull int idleMinutes) {\n        this.idleMinutes = idleMinutes;\n    }\n\n    @CheckForNull\n    public int getSlaveConnectTimeout() {\n        return slaveConnectTimeout;\n    }\n\n    @DataBoundSetter\n    public void setSlaveConnectTimeout(@CheckForNull int slaveConnectTimeout) {\n        this.slaveConnectTimeout = slaveConnectTimeout;\n    }\n\n    @CheckForNull\n    public int getActiveDeadlineSeconds() {\n        return activeDeadlineSeconds;\n    }\n\n    @DataBoundSetter\n    public void setActiveDeadlineSeconds(@CheckForNull int activeDeadlineSeconds) {\n        this.activeDeadlineSeconds = activeDeadlineSeconds;\n    }\n\n    public Boolean getHostNetwork() {\n        return hostNetwork;\n    }\n\n    @DataBoundSetter\n    public void setHostNetwork(boolean hostNetwork) {\n        this.hostNetwork = hostNetwork;\n    }\n\n    @CheckForNull\n    public String getServiceAccount() { return serviceAccount; }\n\n    @DataBoundSetter\n    public void setServiceAccount(@CheckForNull String serviceAccount) {\n        this.serviceAccount = Util.fixEmpty(serviceAccount);\n    }\n\n    @CheckForNull\n    public String getSchedulerName() { return schedulerName; }\n\n    @DataBoundSetter\n    public void setSchedulerName(@CheckForNull String schedulerName) {\n        this.schedulerName = Util.fixEmpty(schedulerName);\n    }\n\n    @CheckForNull\n    public String getNodeSelector() {\n        return nodeSelector;\n    }\n\n    @DataBoundSetter\n    public void setNodeSelector(@CheckForNull String nodeSelector) {\n        this.nodeSelector = Util.fixEmpty(nodeSelector);\n    }\n\n    public Node.Mode getNodeUsageMode() {\n        return nodeUsageMode;\n    }\n\n    public void setNodeUsageMode(Node.Mode nodeUsageMode) {\n        this.nodeUsageMode = nodeUsageMode;\n    }\n\n    @DataBoundSetter\n    public void setNodeUsageMode(String nodeUsageMode) {\n        this.nodeUsageMode = Node.Mode.valueOf(nodeUsageMode);\n    }\n\n    public String getWorkingDir() {\n        return workingDir;\n    }\n\n    @DataBoundSetter\n    public void setWorkingDir(String workingDir) {\n        this.workingDir = workingDir;\n    }\n\n    @Override\n    public StepExecution start(StepContext context) throws Exception {\n        return new PodTemplateStepExecution(this, context);\n    }\n\n    public List<PodAnnotation> getAnnotations() {\n        return annotations;\n    }\n\n    @DataBoundSetter\n    public void setAnnotations(List<PodAnnotation> annotations) {\n        this.annotations = annotations;\n    }\n\n    public List<String> getImagePullSecrets() {\n        return imagePullSecrets == null ? Collections.emptyList() : imagePullSecrets;\n    }\n\n    @DataBoundSetter\n    public void setImagePullSecrets(List<String> imagePullSecrets) {\n        if (imagePullSecrets != null) {\n            this.imagePullSecrets.clear();\n            this.imagePullSecrets.addAll(imagePullSecrets);\n        }\n    }\n\n    @CheckForNull\n    public String getYaml() {\n        return yaml;\n    }\n\n    @DataBoundSetter\n    public void setYaml(@CheckForNull String yaml) {\n        this.yaml = Util.fixEmpty(yaml);\n    }\n\n    @CheckForNull\n    public PodRetention getPodRetention() {\n        return this.podRetention == null ? DescriptorImpl.defaultPodRetention : this.podRetention;\n    }\n\n    @DataBoundSetter\n    public void setPodRetention(@CheckForNull PodRetention podRetention) {\n        this.podRetention = (podRetention == null || podRetention.equals(DescriptorImpl.defaultPodRetention)) ? null : podRetention;\n    }\n\n    boolean isShowRawYamlSet() {\n        return showRawYaml != null;\n    }\n\n    public boolean isShowRawYaml() {\n        return isShowRawYamlSet() ? showRawYaml.booleanValue() : true;\n    }\n\n    @DataBoundSetter\n    public void setShowRawYaml(boolean showRawYaml) {\n        this.showRawYaml = Boolean.valueOf(showRawYaml);\n    }\n\n    public String getRunAsUser(){\n        return this.runAsUser;\n    }\n\n    @DataBoundSetter\n    public void setRunAsUser(String runAsUser) {\n        this.runAsUser = runAsUser;\n    }\n\n    public String getRunAsGroup(){\n        return this.runAsGroup;\n    }\n\n    @DataBoundSetter\n    public void setRunAsGroup(String runAsGroup) {\n        this.runAsGroup = runAsGroup;\n    }\n\n    @CheckForNull\n    public String getSupplementalGroups() {\n        return supplementalGroups;\n    }\n\n    @DataBoundSetter\n    public void setSupplementalGroups(@CheckForNull String supplementalGroups) {\n        this.supplementalGroups = Util.fixEmpty(supplementalGroups);\n    }\n\n    @Extension\n    public static class DescriptorImpl extends StepDescriptor {\n\n        static final String[] POD_TEMPLATE_FIELDS = {"name", "namespace", "inheritFrom", "containers", "envVars", "volumes", "annotations", "yaml", "showRawYaml", "instanceCap", "podRetention", "supplementalGroups", "idleMinutes", "activeDeadlineSeconds", "serviceAccount", "nodeSelector", "workingDir", "workspaceVolume"};\n\n        public DescriptorImpl() {\n            for (String field : POD_TEMPLATE_FIELDS) {\n                addHelpFileRedirect(field, PodTemplate.class, field);\n            }\n        }\n\n        @SuppressWarnings("unused") // by stapler/jelly\n        public ListBoxModel doFillCloudItems() {\n            ListBoxModel result = new ListBoxModel();\n            result.add("—any—", "");\n            if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) { // TODO track use of SYSTEM_READ and/or MANAGE in GlobalCloudConfiguration\n                return result;\n            }\n            Jenkins.get().clouds\n                    .getAll(KubernetesCloud.class)\n                    .forEach(cloud -> result.add(cloud.name));\n            return result;\n        }\n\n        @SuppressWarnings("unused") // by stapler/jelly\n        public ListBoxModel doFillInheritFromItems(@QueryParameter("cloud") String cloudName) {\n            cloudName = Util.fixEmpty(cloudName);\n            ListBoxModel result = new ListBoxModel();\n            result.add("—Default inheritance—", "<default>");\n            result.add("—Disable inheritance—", " ");\n            if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) { // TODO track use of SYSTEM_READ and/or MANAGE in GlobalCloudConfiguration\n                return result;\n            }\n            Cloud cloud;\n            if (cloudName == null) {\n                cloud = Jenkins.get().clouds.get(KubernetesCloud.class);\n            } else {\n                cloud = Jenkins.get().getCloud(cloudName);\n            }\n            if (cloud instanceof KubernetesCloud) {\n                List<PodTemplate> templates = ((KubernetesCloud) cloud).getTemplates();\n                result.addAll(templates.stream()\n                        .filter(template -> StringUtils.isNotEmpty(template.getName()))\n                        .map(PodTemplate::getName)\n                        .map(ListBoxModel.Option::new)\n                        .collect(Collectors.toList()));\n            }\n            return result;\n        }\n\n        @Override\n        public String getFunctionName() {\n            return "podTemplate";\n        }\n\n        @Override\n        public String getDisplayName() {\n            return "Define a podTemplate to use in the kubernetes plugin";\n        }\n\n        @Override\n        public boolean takesImplicitBlockArgument() {\n            return true;\n        }\n\n        @Override\n        public Set<? extends Class<?>> getRequiredContext() {\n            return Collections.unmodifiableSet(new HashSet<>(Arrays.asList(Run.class, TaskListener.class)));\n        }\n\n        @SuppressWarnings("unused") // jelly\n        public String getWorkingDir() {\n            return ContainerTemplate.DEFAULT_WORKING_DIR;\n        }\n\n        public static final Integer defaultInstanceCap = Integer.MAX_VALUE;\n        public static final PodRetention defaultPodRetention = PodRetention.getPodTemplateDefault();\n        public static final WorkspaceVolume defaultWorkspaceVolume = WorkspaceVolume.getDefault();\n        /** Only used for snippet generation. */\n        public static final String defaultInheritFrom = "<default>";\n    }\n}\n', 'message': 'Update src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStep.java\n\nCo-Authored-By: Jesse Glick <f03f7b035106bba3da9b565be6f0115dc0d88f87@cloudbees.com>', 'author_name': 'GitHub', 'lang': 'java'}