You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@heron.apache.org by sa...@apache.org on 2022/05/01 16:52:26 UTC

[incubator-heron] 01/02: [K8s] Added support for Empty Directory.

This is an automated email from the ASF dual-hosted git repository.

saadurrahman pushed a commit to branch saadurrahman/3821-Remove-Deprecated-Volumes-K8s-dev
in repository https://gitbox.apache.org/repos/asf/incubator-heron.git

commit 1528fbf8bd691eaea778a6238c43bf83f4581c4f
Author: Saad Ur Rahman <sa...@apache.org>
AuthorDate: Sun May 1 12:51:01 2022 -0400

    [K8s] Added support for Empty Directory.
---
 .../apache/heron/scheduler/kubernetes/Volumes.java | 66 ++++++++++++++++++----
 .../heron/scheduler/kubernetes/VolumesTests.java   | 36 ++++++++++--
 2 files changed, 86 insertions(+), 16 deletions(-)

diff --git a/heron/schedulers/src/java/org/apache/heron/scheduler/kubernetes/Volumes.java b/heron/schedulers/src/java/org/apache/heron/scheduler/kubernetes/Volumes.java
index a4d92cfc938..3b597338031 100644
--- a/heron/schedulers/src/java/org/apache/heron/scheduler/kubernetes/Volumes.java
+++ b/heron/schedulers/src/java/org/apache/heron/scheduler/kubernetes/Volumes.java
@@ -22,35 +22,81 @@ package org.apache.heron.scheduler.kubernetes;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.heron.spi.common.Config;
-
+import io.kubernetes.client.custom.Quantity;
 import io.kubernetes.client.openapi.models.V1Volume;
+import io.kubernetes.client.openapi.models.V1VolumeBuilder;
 
 final class Volumes {
 
-  private final Map<String, VolumeFactory> volumes = new HashMap<>();
+  public enum VolumeType {
+    EmptyDir,
+    Generic,
+    HostPath,
+    NetworkFileSystem,
+    PersistentVolumeClaim,
+    VolumeMount
+  }
+  private final Map<VolumeType, VolumeFactory> volumes = new HashMap<>();
 
   private Volumes() {
+    volumes.put(VolumeType.EmptyDir, new EmptyDirVolumeFactory());
   }
 
   static Volumes get() {
     return new Volumes();
   }
 
-  V1Volume create(Config config) {
-    final String volumeType = KubernetesContext.getVolumeType(config);
+  /**
+   * Creates <code>Generic</code>, <code>Empty Directory</code>, <code>Host Path</code>, and
+   * <code>Network File System</code> volumes.
+   * @param volumeType One of the supported volume types.
+   * @param volumeName The name of the volume to generate.
+   * @param configs A map of configurations.
+   * @return Fully configured <code>V1Volume</code>.
+   */
+  V1Volume create(VolumeType volumeType, String volumeName,
+                  Map<KubernetesConstants.VolumeConfigKeys, String> configs) {
     if (volumes.containsKey(volumeType)) {
-      return volumes.get(volumeType).create(config);
+      return volumes.get(volumeType).create(volumeName, configs);
     }
     return null;
   }
 
   interface VolumeFactory {
-    V1Volume create(Config config);
+    V1Volume create(String volumeName, Map<KubernetesConstants.VolumeConfigKeys, String> configs);
   }
 
-  private static V1Volume newVolume(Config config) {
-    final String volumeName = KubernetesContext.getVolumeName(config);
-    return new V1Volume().name(volumeName);
+  static class EmptyDirVolumeFactory implements VolumeFactory {
+
+    /**
+     * Generates an <code>Empty Directory</code> <code>V1 Volume</code>.
+     * @param volumeName The name of the volume to generate.
+     * @param configs A map of configurations.
+     * @return A fully configured <code>Empty Directory</code> volume.
+     */
+    @Override
+    public V1Volume create(String volumeName,
+                           Map<KubernetesConstants.VolumeConfigKeys, String> configs) {
+      final V1Volume volume = new V1VolumeBuilder()
+          .withName(volumeName)
+          .withNewEmptyDir()
+          .endEmptyDir()
+          .build();
+
+      for (Map.Entry<KubernetesConstants.VolumeConfigKeys, String> config : configs.entrySet()) {
+        switch(config.getKey()) {
+          case medium:
+            volume.getEmptyDir().medium(config.getValue());
+            break;
+          case sizeLimit:
+            volume.getEmptyDir().sizeLimit(new Quantity(config.getValue()));
+            break;
+          default:
+            break;
+        }
+      }
+
+      return volume;
+    }
   }
 }
diff --git a/heron/schedulers/tests/java/org/apache/heron/scheduler/kubernetes/VolumesTests.java b/heron/schedulers/tests/java/org/apache/heron/scheduler/kubernetes/VolumesTests.java
index 2609e70f177..c855ecd556b 100644
--- a/heron/schedulers/tests/java/org/apache/heron/scheduler/kubernetes/VolumesTests.java
+++ b/heron/schedulers/tests/java/org/apache/heron/scheduler/kubernetes/VolumesTests.java
@@ -19,19 +19,43 @@
 
 package org.apache.heron.scheduler.kubernetes;
 
+import java.util.Map;
+
+import com.google.common.collect.ImmutableMap;
+
 import org.junit.Assert;
 import org.junit.Test;
 
-import org.apache.heron.spi.common.Config;
-
 import io.kubernetes.client.openapi.models.V1Volume;
+import io.kubernetes.client.openapi.models.V1VolumeBuilder;
 
 public class VolumesTests {
 
   @Test
-  public void testNoVolume() {
-    final Config config = Config.newBuilder().build();
-    final V1Volume volume = Volumes.get().create(config);
-    Assert.assertNull(volume);
+  public void testEmptyDir() {
+    final String volumeName = "volume-name-empty-dir";
+    final String medium = "Memory";
+    final String sizeLimit = "1Gi";
+    final String path = "/path/to/mount";
+    final String subPath = "/sub/path/to/mount";
+    final Map<KubernetesConstants.VolumeConfigKeys, String> configEmptyDir =
+        ImmutableMap.<KubernetesConstants.VolumeConfigKeys, String>builder()
+            .put(KubernetesConstants.VolumeConfigKeys.sizeLimit, sizeLimit)
+            .put(KubernetesConstants.VolumeConfigKeys.medium, medium)
+            .put(KubernetesConstants.VolumeConfigKeys.path, path)
+            .put(KubernetesConstants.VolumeConfigKeys.subPath, subPath)
+            .build();
+      final V1Volume expectedVolume = new V1VolumeBuilder()
+          .withName(volumeName)
+          .withNewEmptyDir()
+          .withMedium(medium)
+          .withNewSizeLimit(sizeLimit)
+          .endEmptyDir()
+          .build();
+
+    final V1Volume actualVolume = Volumes.get()
+        .create(Volumes.VolumeType.EmptyDir, volumeName, configEmptyDir);
+
+    Assert.assertEquals("Volume Factory Empty Directory", expectedVolume, actualVolume);
   }
 }