You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@submarine.apache.org by pi...@apache.org on 2021/12/20 05:45:04 UTC
[submarine] branch master updated: SUBMARINE-1126. Let Jupyter Notebook save user setting after pod restarted.
This is an automated email from the ASF dual-hosted git repository.
pingsutw pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/submarine.git
The following commit(s) were added to refs/heads/master by this push:
new a0f5a49 SUBMARINE-1126. Let Jupyter Notebook save user setting after pod restarted.
a0f5a49 is described below
commit a0f5a49d74f01f00929c9d4e5048161c6bee23d8
Author: cdmikechen <cd...@hotmail.com>
AuthorDate: Thu Dec 16 17:17:55 2021 +0800
SUBMARINE-1126. Let Jupyter Notebook save user setting after pod restarted.
### What is this PR for?
Jupyter Notebook have created a workspace volume `/home/jovyan/workspace` , but the user settings are saved in `/home/jovyan/.jupyter/lab/user-settings/jupyterlab/`.
So that after pod restart, submarine will lost user settings. I think we should add a new volume to save user settings in `/home/jovyan/.jupyter/`.
### What type of PR is it?
Improvement
### Todos
* [x] - Add a new PVC named `notebook-pvc-user-*` when creating notebook pod CRD
### What is the Jira issue?
https://issues.apache.org/jira/browse/SUBMARINE-1126
### How should this be tested?
There are no new test cases right now.
### Screenshots (if appropriate)
![image](https://user-images.githubusercontent.com/12069428/146344069-5c92950b-cbd0-41d9-bc01-69625e9945a0.png)
### Questions:
* Do the license files need updating? No
* Are there breaking changes for older versions? No
* Does this need new documentation? Maybe No
Author: cdmikechen <cd...@hotmail.com>
Signed-off-by: Kevin <pi...@apache.org>
Closes #834 from cdmikechen/SUBMARINE-1126 and squashes the following commits:
5696a8cb [cdmikechen] SUBMARINE-1126. Let Jupyter Notebook save user setting after pod restarted.
---
.../server/submitter/k8s/K8sSubmitter.java | 29 +++++++-----
.../submitter/k8s/parser/NotebookSpecParser.java | 52 +++++++++++++++-------
.../server/submitter/k8s/util/NotebookUtils.java | 7 +--
3 files changed, 58 insertions(+), 30 deletions(-)
diff --git a/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/K8sSubmitter.java b/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/K8sSubmitter.java
index 1befeca..8ee8439 100644
--- a/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/K8sSubmitter.java
+++ b/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/K8sSubmitter.java
@@ -383,8 +383,8 @@ public class K8sSubmitter implements Submitter {
final String name = spec.getMeta().getName();
final String scName = NotebookUtils.SC_NAME;
final String host = NotebookUtils.HOST_PATH;
- final String storage = NotebookUtils.STORAGE;
- final String pvcName = NotebookUtils.PVC_PREFIX + name;
+ final String workspacePvc = String.format("%s-%s", NotebookUtils.PVC_PREFIX, name);
+ final String userPvc = String.format("%s-user-%s", NotebookUtils.PVC_PREFIX, name);
String namespace = getServerNamespace();
// parse notebook custom resource
@@ -401,7 +401,10 @@ public class K8sSubmitter implements Submitter {
// create persistent volume claim
try {
- createPersistentVolumeClaim(pvcName, namespace, scName, storage);
+ // workspace
+ createPersistentVolumeClaim(workspacePvc, namespace, scName, NotebookUtils.STORAGE);
+ // user setting
+ createPersistentVolumeClaim(userPvc, namespace, scName, NotebookUtils.DEFAULT_USER_STORAGE);
} catch (ApiException e) {
LOG.error("K8s submitter: Create persistent volume claim for Notebook object failed by " +
e.getMessage(), e);
@@ -416,11 +419,11 @@ public class K8sSubmitter implements Submitter {
notebook = NotebookUtils.parseObject(object, NotebookUtils.ParseOpt.PARSE_OPT_CREATE);
} catch (JsonSyntaxException e) {
LOG.error("K8s submitter: parse response object failed by " + e.getMessage(), e);
- rollbackCreationPVC(pvcName, namespace);
+ rollbackCreationPVC(namespace, workspacePvc, userPvc);
throw new SubmarineRuntimeException(500, "K8s Submitter parse upstream response failed.");
} catch (ApiException e) {
LOG.error("K8s submitter: parse Notebook object failed by " + e.getMessage(), e);
- rollbackCreationPVC(pvcName, namespace);
+ rollbackCreationPVC(namespace, workspacePvc, userPvc);
throw new SubmarineRuntimeException(e.getCode(), "K8s submitter: parse Notebook object failed by " +
e.getMessage());
}
@@ -432,7 +435,7 @@ public class K8sSubmitter implements Submitter {
LOG.error("K8s submitter: Create ingressroute for Notebook object failed by " +
e.getMessage(), e);
rollbackCreationNotebook(notebookCR, namespace);
- rollbackCreationPVC(pvcName, namespace);
+ rollbackCreationPVC(namespace, workspacePvc, userPvc);
throw new SubmarineRuntimeException(e.getCode(), "K8s submitter: ingressroute for Notebook " +
"object failed by " + e.getMessage());
}
@@ -481,7 +484,6 @@ public class K8sSubmitter implements Submitter {
public Notebook deleteNotebook(NotebookSpec spec) throws SubmarineRuntimeException {
Notebook notebook;
final String name = spec.getMeta().getName();
- final String pvcName = NotebookUtils.PVC_PREFIX + name;
String namespace = getServerNamespace();
try {
@@ -492,7 +494,12 @@ public class K8sSubmitter implements Submitter {
null, new V1DeleteOptionsBuilder().withApiVersion(notebookCR.getApiVersion()).build());
notebook = NotebookUtils.parseObject(object, NotebookUtils.ParseOpt.PARSE_OPT_DELETE);
deleteIngressRoute(namespace, notebookCR.getMetadata().getName());
- deletePersistentVolumeClaim(pvcName, namespace);
+
+ // delete pvc
+ // workspace pvc
+ deletePersistentVolumeClaim(String.format("%s-%s", NotebookUtils.PVC_PREFIX, name), namespace);
+ // user set pvc
+ deletePersistentVolumeClaim(String.format("%s-user-%s", NotebookUtils.PVC_PREFIX, name), namespace);
} catch (ApiException e) {
throw new SubmarineRuntimeException(e.getCode(), e.getMessage());
}
@@ -799,9 +806,11 @@ public class K8sSubmitter implements Submitter {
return seldonDeployment;
}
- private void rollbackCreationPVC(String pvcName, String namespace) {
+ private void rollbackCreationPVC(String namespace, String ... pvcNames) {
try {
- deletePersistentVolumeClaim(pvcName, namespace);
+ for (String pvcName : pvcNames) {
+ deletePersistentVolumeClaim(pvcName, namespace);
+ }
} catch (ApiException e) {
LOG.error("K8s submitter: delete persistent volume claim failed by {}, may cause some dirty data",
e.getMessage());
diff --git a/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/parser/NotebookSpecParser.java b/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/parser/NotebookSpecParser.java
index 0ed30b1..2067364 100644
--- a/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/parser/NotebookSpecParser.java
+++ b/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/parser/NotebookSpecParser.java
@@ -49,7 +49,12 @@ import java.util.Map;
public class NotebookSpecParser {
- private static SubmarineConfiguration conf =
+ // jupyter workspace path
+ private static final String DEFAULT_WORKSPACE_MOUNT_PATH = "/home/jovyan/workspace";
+ // jupyter user setting path, avoid losing user setting after pod restarted
+ private static final String DEFAULT_USER_SET_MOUNT_PATH = "/home/jovyan/.jupyter";
+
+ private static final SubmarineConfiguration conf =
SubmarineConfiguration.getInstance();
@@ -75,13 +80,15 @@ public class NotebookSpecParser {
}
private static V1PodTemplateSpec parseTemplateSpec(NotebookSpec notebookSpec) {
+ String name = notebookSpec.getMeta().getName();
+
NotebookPodSpec notebookPodSpec = notebookSpec.getSpec();
V1PodTemplateSpec podTemplateSpec = new V1PodTemplateSpec();
V1PodSpec podSpec = new V1PodSpec();
// Set container
List<V1Container> containers = new ArrayList<>();
V1Container container = new V1Container();
- container.setName(notebookSpec.getMeta().getName());
+ container.setName(name);
// Environment variables
if (notebookPodSpec.getEnvVars() != null) {
@@ -147,13 +154,17 @@ public class NotebookSpecParser {
}
// Volume spec
- final String DEFAULT_MOUNT_PATH = "/home/jovyan/workspace";
-
List<V1VolumeMount> volumeMountList = new ArrayList<>();
- V1VolumeMount volumeMount = new V1VolumeMount();
- volumeMount.setMountPath(DEFAULT_MOUNT_PATH);
- volumeMount.setName(NotebookUtils.STORAGE_PREFIX + notebookSpec.getMeta().getName());
- volumeMountList.add(volumeMount);
+ // workspace path
+ V1VolumeMount workspace = new V1VolumeMount();
+ workspace.setMountPath(DEFAULT_WORKSPACE_MOUNT_PATH);
+ workspace.setName(String.format("%s-%s", NotebookUtils.STORAGE_PREFIX, name));
+ volumeMountList.add(workspace);
+ // user setting path
+ V1VolumeMount userSetting = new V1VolumeMount();
+ userSetting.setMountPath(DEFAULT_USER_SET_MOUNT_PATH);
+ userSetting.setName(String.format("%s-user-%s", NotebookUtils.STORAGE_PREFIX, name));
+ volumeMountList.add(userSetting);
container.setVolumeMounts(volumeMountList);
containers.add(container);
@@ -161,17 +172,24 @@ public class NotebookSpecParser {
// create volume object for persistent volume
List<V1Volume> volumeList = new ArrayList<>();
- V1Volume volume = new V1Volume();
- String volumeName = NotebookUtils.STORAGE_PREFIX + notebookSpec.getMeta().getName();
- V1PersistentVolumeClaimVolumeSource persistentVolumeClaim = new V1PersistentVolumeClaimVolumeSource();
- String claimName = NotebookUtils.PVC_PREFIX + notebookSpec.getMeta().getName();
- persistentVolumeClaim.setClaimName(claimName);
- volume.setName(volumeName);
- volume.setPersistentVolumeClaim(persistentVolumeClaim);
- volumeList.add(volume);
- podSpec.setVolumes(volumeList);
+ // workspace
+ V1Volume workspaceVolume = new V1Volume();
+ workspaceVolume.setName(String.format("%s-%s", NotebookUtils.STORAGE_PREFIX, name));
+ V1PersistentVolumeClaimVolumeSource workspacePvc = new V1PersistentVolumeClaimVolumeSource();
+ workspacePvc.setClaimName(String.format("%s-%s", NotebookUtils.PVC_PREFIX, name));
+ workspaceVolume.setPersistentVolumeClaim(workspacePvc);
+ volumeList.add(workspaceVolume);
+ // user setting
+ V1Volume userVolume = new V1Volume();
+ userVolume.setName(String.format("%s-user-%s", NotebookUtils.STORAGE_PREFIX, name));
+ V1PersistentVolumeClaimVolumeSource userPvc = new V1PersistentVolumeClaimVolumeSource();
+ userPvc.setClaimName(String.format("%s-user-%s", NotebookUtils.PVC_PREFIX, name));
+ userVolume.setPersistentVolumeClaim(userPvc);
+ volumeList.add(userVolume);
+ podSpec.setVolumes(volumeList);
podTemplateSpec.setSpec(podSpec);
+
return podTemplateSpec;
}
diff --git a/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/util/NotebookUtils.java b/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/util/NotebookUtils.java
index c567520..8805997 100644
--- a/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/util/NotebookUtils.java
+++ b/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/util/NotebookUtils.java
@@ -44,10 +44,11 @@ public class NotebookUtils {
private static final Logger LOG = LoggerFactory.getLogger(NotebookUtils.class);
public static final String STORAGE = "10Gi";
+ public static final String DEFAULT_USER_STORAGE = "100Mi";
public static final String SC_NAME = "submarine-storageclass";
- public static final String STORAGE_PREFIX = "notebook-storage-";
- public static final String PV_PREFIX = "notebook-pv-";
- public static final String PVC_PREFIX = "notebook-pvc-";
+ public static final String STORAGE_PREFIX = "notebook-storage";
+ public static final String PV_PREFIX = "notebook-pv";
+ public static final String PVC_PREFIX = "notebook-pvc";
public static final String HOST_PATH = "/mnt";
public enum ParseOpt {
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@submarine.apache.org
For additional commands, e-mail: dev-help@submarine.apache.org