Skip to content

Commit ccfd496

Browse files
committed
* Refactor ephemeral volume logic, apply same defaults as DynamicPVC
* Move up help files * Remove erroneous subPath from DynamicPVCVolume * Fix fields on creation
1 parent de4c1b5 commit ccfd496

File tree

17 files changed

+135
-109
lines changed

17 files changed

+135
-109
lines changed

src/main/java/org/csanchez/jenkins/plugins/kubernetes/volumes/DynamicPVC.java

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,16 @@
77
import io.fabric8.kubernetes.api.model.OwnerReferenceBuilder;
88
import io.fabric8.kubernetes.api.model.PersistentVolumeClaim;
99
import io.fabric8.kubernetes.api.model.PersistentVolumeClaimBuilder;
10-
import io.fabric8.kubernetes.api.model.Quantity;
1110
import io.fabric8.kubernetes.api.model.Volume;
1211
import io.fabric8.kubernetes.api.model.VolumeBuilder;
1312
import io.fabric8.kubernetes.client.KubernetesClient;
14-
import java.util.Collections;
15-
import java.util.Map;
1613
import java.util.logging.Level;
1714
import java.util.logging.Logger;
18-
import org.apache.commons.lang.StringUtils;
1915

2016
/**
2117
* Interface containing common code between {@link DynamicPVCVolume} and {@link org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.DynamicPVCWorkspaceVolume}.
2218
*/
23-
public interface DynamicPVC {
19+
public interface DynamicPVC extends ProvisionedVolume {
2420
Logger LOGGER = Logger.getLogger(DynamicPVC.class.getName());
2521

2622
default Volume buildPVC(String volumeName, String podName) {
@@ -62,32 +58,11 @@ default PersistentVolumeClaim createPVC(KubernetesClient client, ObjectMeta podM
6258
.build();
6359
pvc = client.persistentVolumeClaims()
6460
.inNamespace(podMetaData.getNamespace())
65-
.create(pvc);
61+
.resource(pvc)
62+
.create();
6663
LOGGER.log(INFO, "Created PVC: {0}/{1}", new Object[] {namespace, pvcName});
6764
return pvc;
6865
}
6966

70-
default String getStorageClassNameOrDefault() {
71-
return getStorageClassName();
72-
}
73-
74-
String getStorageClassName();
75-
76-
default Map<String, Quantity> getResourceMap() {
77-
return Collections.singletonMap("storage", new Quantity(getRequestsSizeOrDefault()));
78-
}
79-
80-
default String getRequestsSizeOrDefault() {
81-
return StringUtils.defaultString(getRequestsSize(), "10Gi");
82-
}
83-
84-
String getRequestsSize();
85-
86-
default String getAccessModesOrDefault() {
87-
return StringUtils.defaultString(getAccessModes(), "ReadWriteOnce");
88-
}
89-
90-
String getAccessModes();
91-
9267
String getPvcName(String podName);
9368
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.csanchez.jenkins.plugins.kubernetes.volumes;
2+
3+
import io.fabric8.kubernetes.api.model.Volume;
4+
import io.fabric8.kubernetes.api.model.VolumeBuilder;
5+
6+
/**
7+
* Interface containing common code between {@link GenericEphemeralVolume} and {@link org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.GenericEphemeralWorkspaceVolume}.
8+
*/
9+
public interface EphemeralVolume extends ProvisionedVolume {
10+
default Volume buildEphemeralVolume(String volumeName) {
11+
return new VolumeBuilder()
12+
.withName(volumeName)
13+
.withNewEphemeral()
14+
.withNewVolumeClaimTemplate()
15+
.withNewSpec()
16+
.withAccessModes(getAccessModesOrDefault())
17+
.withStorageClassName(getStorageClassNameOrDefault())
18+
.withNewResources()
19+
.withRequests(getResourceMap())
20+
.endResources()
21+
.endSpec()
22+
.endVolumeClaimTemplate()
23+
.endEphemeral()
24+
.build();
25+
}
26+
}

src/main/java/org/csanchez/jenkins/plugins/kubernetes/volumes/GenericEphemeralVolume.java

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,30 @@
77
import hudson.Util;
88
import hudson.model.Descriptor;
99
import hudson.util.ListBoxModel;
10-
import io.fabric8.kubernetes.api.model.Quantity;
1110
import io.fabric8.kubernetes.api.model.Volume;
12-
import io.fabric8.kubernetes.api.model.VolumeBuilder;
11+
import java.util.Objects;
1312
import org.jenkinsci.Symbol;
1413
import org.kohsuke.accmod.Restricted;
1514
import org.kohsuke.accmod.restrictions.DoNotUse;
1615
import org.kohsuke.stapler.DataBoundConstructor;
1716
import org.kohsuke.stapler.DataBoundSetter;
1817
import org.kohsuke.stapler.interceptor.RequirePOST;
1918

20-
import java.util.Map;
21-
import java.util.Objects;
22-
import java.util.UUID;
23-
2419
/**
2520
* Uses a generic ephemeral volume, that is created before the agent pod is created, and terminated afterwards.
2621
* See <a href="https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes">Kubernetes documentation</a>
2722
*/
2823
@SuppressFBWarnings(
2924
value = "SE_NO_SERIALVERSIONID",
3025
justification = "Serialization happens exclusively through XStream and not Java Serialization.")
31-
public class GenericEphemeralVolume extends PodVolume {
32-
private String id;
26+
public class GenericEphemeralVolume extends PodVolume implements EphemeralVolume {
3327
private String storageClassName;
3428
private String requestsSize;
3529
private String accessModes;
3630
private String mountPath;
3731

3832
@DataBoundConstructor
39-
public GenericEphemeralVolume() {
40-
this.id = UUID.randomUUID().toString().substring(0, 8);
41-
}
33+
public GenericEphemeralVolume() {}
4234

4335
@CheckForNull
4436
public String getAccessModes() {
@@ -47,7 +39,7 @@ public String getAccessModes() {
4739

4840
@DataBoundSetter
4941
public void setAccessModes(@CheckForNull String accessModes) {
50-
this.accessModes = Util.fixEmpty(accessModes);
42+
this.accessModes = accessModes;
5143
}
5244

5345
@CheckForNull
@@ -57,7 +49,7 @@ public String getRequestsSize() {
5749

5850
@DataBoundSetter
5951
public void setRequestsSize(@CheckForNull String requestsSize) {
60-
this.requestsSize = Util.fixEmpty(requestsSize);
52+
this.requestsSize = Util.fixEmptyAndTrim(requestsSize);
6153
}
6254

6355
@CheckForNull
@@ -67,7 +59,7 @@ public String getStorageClassName() {
6759

6860
@DataBoundSetter
6961
public void setStorageClassName(@CheckForNull String storageClassName) {
70-
this.storageClassName = Util.fixEmpty(storageClassName);
62+
this.storageClassName = Util.fixEmptyAndTrim(storageClassName);
7163
}
7264

7365
@Override
@@ -77,20 +69,7 @@ public String getMountPath() {
7769

7870
@Override
7971
public Volume buildVolume(String volumeName, String podName) {
80-
return new VolumeBuilder().
81-
withName(volumeName).
82-
withNewEphemeral().
83-
withNewVolumeClaimTemplate().
84-
withNewSpec().
85-
withAccessModes(getAccessModes()).
86-
withStorageClassName(getStorageClassName()).
87-
withNewResources().
88-
withRequests(Map.of("storage", new Quantity(getRequestsSize()))).
89-
endResources().
90-
endSpec().
91-
endVolumeClaimTemplate().
92-
endEphemeral().
93-
build();
72+
return buildEphemeralVolume(volumeName);
9473
}
9574

9675
@DataBoundSetter
@@ -103,21 +82,22 @@ public boolean equals(Object o) {
10382
if (this == o) return true;
10483
if (o == null || getClass() != o.getClass()) return false;
10584
GenericEphemeralVolume that = (GenericEphemeralVolume) o;
106-
return Objects.equals(id, that.id)
107-
&& Objects.equals(storageClassName, that.storageClassName)
85+
return Objects.equals(storageClassName, that.storageClassName)
10886
&& Objects.equals(requestsSize, that.requestsSize)
109-
&& Objects.equals(accessModes, that.accessModes);
87+
&& Objects.equals(accessModes, that.accessModes)
88+
&& Objects.equals(mountPath, that.mountPath);
11089
}
11190

11291
@Override
11392
public int hashCode() {
114-
return Objects.hash(id, storageClassName, requestsSize, accessModes);
93+
return Objects.hash(storageClassName, requestsSize, accessModes, mountPath);
11594
}
11695

11796
@Extension
11897
@Symbol("genericEphemeralVolume")
11998
public static class DescriptorImpl extends Descriptor<PodVolume> {
12099
@Override
100+
@NonNull
121101
public String getDisplayName() {
122102
return "Generic ephemeral volume";
123103
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.csanchez.jenkins.plugins.kubernetes.volumes;
2+
3+
import io.fabric8.kubernetes.api.model.Quantity;
4+
import java.util.Collections;
5+
import java.util.Map;
6+
import org.apache.commons.lang.StringUtils;
7+
8+
public interface ProvisionedVolume {
9+
default String getStorageClassNameOrDefault() {
10+
return getStorageClassName();
11+
}
12+
13+
String getStorageClassName();
14+
15+
default Map<String, Quantity> getResourceMap() {
16+
return Collections.singletonMap("storage", new Quantity(getRequestsSizeOrDefault()));
17+
}
18+
19+
default String getRequestsSizeOrDefault() {
20+
return StringUtils.defaultString(getRequestsSize(), "10Gi");
21+
}
22+
23+
String getRequestsSize();
24+
25+
default String getAccessModesOrDefault() {
26+
return StringUtils.defaultString(getAccessModes(), "ReadWriteOnce");
27+
}
28+
29+
String getAccessModes();
30+
}

src/main/java/org/csanchez/jenkins/plugins/kubernetes/volumes/workspace/GenericEphemeralWorkspaceVolume.java

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,79 @@
11
package org.csanchez.jenkins.plugins.kubernetes.volumes.workspace;
22

33
import edu.umd.cs.findbugs.annotations.CheckForNull;
4+
import edu.umd.cs.findbugs.annotations.NonNull;
45
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
56
import hudson.Extension;
67
import hudson.Util;
78
import hudson.model.Descriptor;
89
import hudson.util.ListBoxModel;
9-
import io.fabric8.kubernetes.api.model.Quantity;
1010
import io.fabric8.kubernetes.api.model.Volume;
11-
import io.fabric8.kubernetes.api.model.VolumeBuilder;
11+
import org.csanchez.jenkins.plugins.kubernetes.volumes.EphemeralVolume;
1212
import org.csanchez.jenkins.plugins.kubernetes.volumes.PVCVolumeUtils;
1313
import org.jenkinsci.Symbol;
1414
import org.kohsuke.accmod.Restricted;
1515
import org.kohsuke.accmod.restrictions.DoNotUse;
1616
import org.kohsuke.stapler.DataBoundConstructor;
17+
import org.kohsuke.stapler.DataBoundSetter;
1718
import org.kohsuke.stapler.interceptor.RequirePOST;
1819

19-
import java.util.Map;
20-
2120
/**
2221
* Uses a generic ephemeral volume, that is created before the agent pod is created, and terminated afterwards.
2322
*/
2423
@SuppressFBWarnings(
2524
value = "SE_NO_SERIALVERSIONID",
2625
justification = "Serialization happens exclusively through XStream and not Java Serialization.")
27-
public class GenericEphemeralWorkspaceVolume extends WorkspaceVolume {
26+
public class GenericEphemeralWorkspaceVolume extends WorkspaceVolume implements EphemeralVolume {
2827

2928
private String storageClassName;
3029
private String requestsSize;
3130
private String accessModes;
3231

3332
@DataBoundConstructor
34-
public GenericEphemeralWorkspaceVolume(String storageClassName, String requestsSize, String accessModes) {
35-
this.storageClassName = storageClassName;
36-
this.requestsSize = requestsSize;
37-
this.accessModes = accessModes;
38-
}
33+
public GenericEphemeralWorkspaceVolume() {}
3934

35+
@Override
4036
public String getStorageClassName() {
4137
return storageClassName;
4238
}
4339

40+
@DataBoundSetter
4441
public void setStorageClassName(String storageClassName) {
45-
this.storageClassName = storageClassName;
42+
this.storageClassName = Util.fixEmptyAndTrim(storageClassName);
4643
}
4744

45+
@Override
4846
public String getRequestsSize() {
4947
return requestsSize;
5048
}
5149

50+
@DataBoundSetter
5251
public void setRequestsSize(@CheckForNull String requestsSize) {
53-
this.requestsSize = Util.fixEmpty(requestsSize);
52+
this.requestsSize = Util.fixEmptyAndTrim(requestsSize);
5453
}
5554

55+
@Override
5656
public String getAccessModes() {
5757
return accessModes;
5858
}
5959

60+
@DataBoundSetter
6061
public void setAccessModes(String accessModes) {
6162
this.accessModes = accessModes;
6263
}
6364

6465
@Override
6566
public Volume buildVolume(String volumeName, String podName) {
66-
return new VolumeBuilder()
67-
.withName(volumeName)
68-
.withNewEphemeral()
69-
.withNewVolumeClaimTemplate()
70-
.withNewSpec()
71-
.withAccessModes(getAccessModes())
72-
.withStorageClassName(getStorageClassName())
73-
.withNewResources()
74-
.withRequests(Map.of("storage", new Quantity(getRequestsSize())))
75-
.endResources()
76-
.endSpec()
77-
.endVolumeClaimTemplate()
78-
.endEphemeral()
79-
.build();
67+
return buildEphemeralVolume(volumeName);
8068
}
8169

8270
@Extension
8371
@Symbol("genericEphemeralVolume")
8472
public static class DescriptorImpl extends Descriptor<WorkspaceVolume> {
8573
@Override
74+
@NonNull
8675
public String getDisplayName() {
87-
return "Generic Ephemerel Volume";
76+
return "Generic Ephemeral Volume";
8877
}
8978

9079
@SuppressWarnings("unused") // by stapler

src/main/resources/org/csanchez/jenkins/plugins/kubernetes/volumes/DynamicPVCVolume/config.jelly

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@
1010
<f:textbox />
1111
</f:entry>
1212

13-
<f:entry title="${%Mount subPath}" field="subPath">
14-
<f:textbox />
15-
</f:entry>
16-
1713
<f:entry title="${%Storage Class Name}" field="storageClassName">
1814
<f:textbox />
1915
</f:entry>

src/main/resources/org/csanchez/jenkins/plugins/kubernetes/volumes/GenericEphemeralVolume/config.jelly

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout"
33
xmlns:t="/lib/hudson" xmlns:f="/lib/form">
44
<f:description>
5-
Creates a generic ephemeral volume mount for a pod.
5+
Creates a <a href="https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes" target="_new">generic ephemeral volume</a> using the specified parameters.
66
</f:description>
77

88
<f:entry title="${%Mount path}" field="mountPath">

0 commit comments

Comments
 (0)