You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@submarine.apache.org by ka...@apache.org on 2021/07/04 14:59:34 UTC

[submarine] branch master updated: SUBMARINE-891. Remove namespace function arguments when creating resources

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

kaihsun 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 5739c09  SUBMARINE-891. Remove namespace function arguments when creating resources
5739c09 is described below

commit 5739c09bf1b0a6ad5169d76203a84cc778e3a56d
Author: MortalHappiness <b0...@ntu.edu.tw>
AuthorDate: Sun Jul 4 17:47:08 2021 +0800

    SUBMARINE-891. Remove namespace function arguments when creating resources
    
    ### What is this PR for?
    Currently when creating resources we pass namespace as function argument. However it is unnecessary since it can be read from submarine custom resource.
    
    ### What type of PR is it?
    [Refactoring]
    
    ### Todos
    
    ### What is the Jira issue?
    https://issues.apache.org/jira/browse/SUBMARINE-891
    
    ### How should this be tested?
    
    ### Screenshots (if appropriate)
    
    ### Questions:
    * Do the license files need updating? No
    * Are there breaking changes for older versions? No
    * Does this need new documentation? No
    
    Author: MortalHappiness <b0...@ntu.edu.tw>
    
    Signed-off-by: Kai-Hsun Chen <ka...@apache.org>
    
    Closes #643 from MortalHappiness/SUBMARINE-891 and squashes the following commits:
    
    aa36829f [MortalHappiness] SUBMARINE-891. Remove namespace function arguments when creating resources
---
 submarine-cloud-v2/main.go                         |   5 +-
 submarine-cloud-v2/pkg/controller/controller.go    |  34 ++++-
 .../pkg/controller/submarine_database.go           | 124 +++++++++---------
 .../pkg/controller/submarine_ingress.go            |  21 ++-
 .../pkg/controller/submarine_server.go             |  38 +++---
 .../pkg/controller/submarine_server_rbac.go        |  20 +--
 .../pkg/controller/submarine_tensorboard.go        | 145 ++++++++++-----------
 7 files changed, 197 insertions(+), 190 deletions(-)

diff --git a/submarine-cloud-v2/main.go b/submarine-cloud-v2/main.go
index 20c3772..8bdf512 100644
--- a/submarine-cloud-v2/main.go
+++ b/submarine-cloud-v2/main.go
@@ -19,12 +19,13 @@ package main
 
 import (
 	"flag"
+	"os"
+	"time"
+
 	clientset "github.com/apache/submarine/submarine-cloud-v2/pkg/client/clientset/versioned"
 	informers "github.com/apache/submarine/submarine-cloud-v2/pkg/client/informers/externalversions"
 	"github.com/apache/submarine/submarine-cloud-v2/pkg/controller"
 	"github.com/apache/submarine/submarine-cloud-v2/pkg/signals"
-	"os"
-	"time"
 
 	kubeinformers "k8s.io/client-go/informers"
 	"k8s.io/client-go/kubernetes"
diff --git a/submarine-cloud-v2/pkg/controller/controller.go b/submarine-cloud-v2/pkg/controller/controller.go
index fc8502e..8d46bef 100644
--- a/submarine-cloud-v2/pkg/controller/controller.go
+++ b/submarine-cloud-v2/pkg/controller/controller.go
@@ -63,10 +63,24 @@ import (
 const controllerAgentName = "submarine-controller"
 
 const (
-	serverName   = "submarine-server"
-	databaseName = "submarine-database"
+	serverName                  = "submarine-server"
+	databaseName                = "submarine-database"
+	tensorboardName             = "submarine-tensorboard"
+	ingressName                 = serverName + "-ingress"
+	databasePvNamePrefix        = databaseName + "-pv"
+	databasePvcName             = databaseName + "-pvc"
+	tensorboardPvNamePrefix     = tensorboardName + "-pv"
+	tensorboardPvcName          = tensorboardName + "-pvc"
+	tensorboardServiceName      = tensorboardName + "-service"
+	tensorboardIngressRouteName = tensorboardName + "-ingressroute"
 )
 
+// PersistentVolumes are not namespaced resources, so we add the namespace as a
+// suffix to distinguish them
+func pvName(pvPrefix string, namespace string) string {
+	return pvPrefix + "--" + namespace
+}
+
 const (
 	// SuccessSynced is used as part of the Event 'reason' when a Submarine is synced
 	SuccessSynced = "Synced"
@@ -427,6 +441,12 @@ func (c *Controller) syncHandler(workqueueItem WorkQueueItem) error {
 		b, err := json.MarshalIndent(submarine.Spec, "", "  ")
 		fmt.Println(string(b))
 
+		storageType := submarine.Spec.Storage.StorageType
+		if storageType != "nfs" && storageType != "host" {
+			utilruntime.HandleError(fmt.Errorf("Invalid storageType '%s' found in submarine spec, nothing will be created. Valid storage types are 'nfs' and 'host'", storageType))
+			return nil
+		}
+
 		var serverDeployment *appsv1.Deployment
 		var databaseDeployment *appsv1.Deployment
 
@@ -435,27 +455,27 @@ func (c *Controller) syncHandler(workqueueItem WorkQueueItem) error {
 			return err
 		}
 
-		serverDeployment, err = c.createSubmarineServer(submarine, namespace)
+		serverDeployment, err = c.createSubmarineServer(submarine)
 		if err != nil {
 			return err
 		}
 
-		databaseDeployment, err = c.createSubmarineDatabase(submarine, namespace)
+		databaseDeployment, err = c.createSubmarineDatabase(submarine)
 		if err != nil {
 			return err
 		}
 
-		err = c.createIngress(submarine, namespace)
+		err = c.createIngress(submarine)
 		if err != nil {
 			return err
 		}
 
-		err = c.createSubmarineServerRBAC(submarine, namespace)
+		err = c.createSubmarineServerRBAC(submarine)
 		if err != nil {
 			return err
 		}
 
-		err = c.createSubmarineTensorboard(submarine, namespace, &submarine.Spec)
+		err = c.createSubmarineTensorboard(submarine)
 		if err != nil {
 			return err
 		}
diff --git a/submarine-cloud-v2/pkg/controller/submarine_database.go b/submarine-cloud-v2/pkg/controller/submarine_database.go
index aa55325..3ff5199 100644
--- a/submarine-cloud-v2/pkg/controller/submarine_database.go
+++ b/submarine-cloud-v2/pkg/controller/submarine_database.go
@@ -32,10 +32,29 @@ import (
 	"k8s.io/klog/v2"
 )
 
-func newSubmarineDatabasePersistentVolume(submarine *v1alpha1.Submarine, persistentVolumeSource *corev1.PersistentVolumeSource, pvName string) *corev1.PersistentVolume {
+func newSubmarineDatabasePersistentVolume(submarine *v1alpha1.Submarine) *corev1.PersistentVolume {
+	var persistentVolumeSource corev1.PersistentVolumeSource
+	switch submarine.Spec.Storage.StorageType {
+	case "nfs":
+		persistentVolumeSource = corev1.PersistentVolumeSource{
+			NFS: &corev1.NFSVolumeSource{
+				Server: submarine.Spec.Storage.NfsIP,
+				Path:   submarine.Spec.Storage.NfsPath,
+			},
+		}
+	case "host":
+		hostPathType := corev1.HostPathDirectoryOrCreate
+		persistentVolumeSource = corev1.PersistentVolumeSource{
+			HostPath: &corev1.HostPathVolumeSource{
+				Path: submarine.Spec.Storage.HostPath,
+				Type: &hostPathType,
+			},
+		}
+	}
+
 	return &corev1.PersistentVolume{
 		ObjectMeta: metav1.ObjectMeta{
-			Name: pvName,
+			Name: pvName(databasePvNamePrefix, submarine.Namespace),
 			OwnerReferences: []metav1.OwnerReference{
 				*metav1.NewControllerRef(submarine, v1alpha1.SchemeGroupVersion.WithKind("Submarine")),
 			},
@@ -47,16 +66,16 @@ func newSubmarineDatabasePersistentVolume(submarine *v1alpha1.Submarine, persist
 			Capacity: corev1.ResourceList{
 				corev1.ResourceStorage: resource.MustParse(submarine.Spec.Database.StorageSize),
 			},
-			PersistentVolumeSource: *persistentVolumeSource,
+			PersistentVolumeSource: persistentVolumeSource,
 		},
 	}
 }
 
-func newSubmarineDatabasePersistentVolumeClaim(submarine *v1alpha1.Submarine, pvcName string, pvName string) *corev1.PersistentVolumeClaim {
+func newSubmarineDatabasePersistentVolumeClaim(submarine *v1alpha1.Submarine) *corev1.PersistentVolumeClaim {
 	storageClassName := ""
 	return &corev1.PersistentVolumeClaim{
 		ObjectMeta: metav1.ObjectMeta{
-			Name: pvcName,
+			Name: databasePvcName,
 			OwnerReferences: []metav1.OwnerReference{
 				*metav1.NewControllerRef(submarine, v1alpha1.SchemeGroupVersion.WithKind("Submarine")),
 			},
@@ -70,13 +89,13 @@ func newSubmarineDatabasePersistentVolumeClaim(submarine *v1alpha1.Submarine, pv
 					corev1.ResourceStorage: resource.MustParse(submarine.Spec.Database.StorageSize),
 				},
 			},
-			VolumeName:       pvName,
+			VolumeName:       pvName(databasePvNamePrefix, submarine.Namespace),
 			StorageClassName: &storageClassName,
 		},
 	}
 }
 
-func newSubmarineDatabaseDeployment(submarine *v1alpha1.Submarine, pvcName string) *appsv1.Deployment {
+func newSubmarineDatabaseDeployment(submarine *v1alpha1.Submarine) *appsv1.Deployment {
 	databaseImage := submarine.Spec.Database.Image
 	if databaseImage == "" {
 		databaseImage = "apache/submarine:database-" + submarine.Spec.Version
@@ -133,7 +152,7 @@ func newSubmarineDatabaseDeployment(submarine *v1alpha1.Submarine, pvcName strin
 							Name: "volume",
 							VolumeSource: corev1.VolumeSource{
 								PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
-									ClaimName: pvcName,
+									ClaimName: databasePvcName,
 								},
 							},
 						},
@@ -169,48 +188,24 @@ func newSubmarineDatabaseService(submarine *v1alpha1.Submarine) *corev1.Service
 
 // createSubmarineDatabase is a function to create submarine-database.
 // Reference: https://github.com/apache/submarine/blob/master/helm-charts/submarine/templates/submarine-database.yaml
-func (c *Controller) createSubmarineDatabase(submarine *v1alpha1.Submarine, namespace string) (*appsv1.Deployment, error) {
+func (c *Controller) createSubmarineDatabase(submarine *v1alpha1.Submarine) (*appsv1.Deployment, error) {
 	klog.Info("[createSubmarineDatabase]")
 
 	// Step1: Create PersistentVolume
-	// PersistentVolumes are not namespaced resources, so we add the namespace
-	// as a suffix to distinguish them
-	pvName := databaseName + "-pv--" + namespace
-	pv, pv_err := c.persistentvolumeLister.Get(pvName)
+	pv, err := c.persistentvolumeLister.Get(pvName(databasePvNamePrefix, submarine.Namespace))
 	// If the resource doesn't exist, we'll create it
-	if errors.IsNotFound(pv_err) {
-		var persistentVolumeSource corev1.PersistentVolumeSource
-		switch submarine.Spec.Storage.StorageType {
-		case "nfs":
-			persistentVolumeSource = corev1.PersistentVolumeSource{
-				NFS: &corev1.NFSVolumeSource{
-					Server: submarine.Spec.Storage.NfsIP,
-					Path:   submarine.Spec.Storage.NfsPath,
-				},
-			}
-		case "host":
-			hostPathType := corev1.HostPathDirectoryOrCreate
-			persistentVolumeSource = corev1.PersistentVolumeSource{
-				HostPath: &corev1.HostPathVolumeSource{
-					Path: submarine.Spec.Storage.HostPath,
-					Type: &hostPathType,
-				},
-			}
-		default:
-			klog.Warningln("	Invalid storageType found in submarine spec, nothing will be created!")
-			return nil, nil
-		}
-		pv, pv_err = c.kubeclientset.CoreV1().PersistentVolumes().Create(context.TODO(), newSubmarineDatabasePersistentVolume(submarine, &persistentVolumeSource, pvName), metav1.CreateOptions{})
-		if pv_err != nil {
-			klog.Info(pv_err)
+	if errors.IsNotFound(err) {
+		pv, err = c.kubeclientset.CoreV1().PersistentVolumes().Create(context.TODO(), newSubmarineDatabasePersistentVolume(submarine), metav1.CreateOptions{})
+		if err != nil {
+			klog.Info(err)
 		}
 		klog.Info("	Create PersistentVolume: ", pv.Name)
 	}
 	// If an error occurs during Get/Create, we'll requeue the item so we can
 	// attempt processing again later. This could have been caused by a
 	// temporary network failure, or any other transient reason.
-	if pv_err != nil {
-		return nil, pv_err
+	if err != nil {
+		return nil, err
 	}
 
 	if !metav1.IsControlledBy(pv, submarine) {
@@ -220,21 +215,20 @@ func (c *Controller) createSubmarineDatabase(submarine *v1alpha1.Submarine, name
 	}
 
 	// Step2: Create PersistentVolumeClaim
-	pvcName := databaseName + "-pvc"
-	pvc, pvc_err := c.persistentvolumeclaimLister.PersistentVolumeClaims(namespace).Get(pvcName)
+	pvc, err := c.persistentvolumeclaimLister.PersistentVolumeClaims(submarine.Namespace).Get(databasePvcName)
 	// If the resource doesn't exist, we'll create it
-	if errors.IsNotFound(pvc_err) {
-		pvc, pvc_err = c.kubeclientset.CoreV1().PersistentVolumeClaims(namespace).Create(context.TODO(), newSubmarineDatabasePersistentVolumeClaim(submarine, pvcName, pvName), metav1.CreateOptions{})
-		if pvc_err != nil {
-			klog.Info(pvc_err)
+	if errors.IsNotFound(err) {
+		pvc, err = c.kubeclientset.CoreV1().PersistentVolumeClaims(submarine.Namespace).Create(context.TODO(), newSubmarineDatabasePersistentVolumeClaim(submarine), metav1.CreateOptions{})
+		if err != nil {
+			klog.Info(err)
 		}
 		klog.Info("	Create PersistentVolumeClaim: ", pvc.Name)
 	}
 	// If an error occurs during Get/Create, we'll requeue the item so we can
 	// attempt processing again later. This could have been caused by a
 	// temporary network failure, or any other transient reason.
-	if pvc_err != nil {
-		return nil, pvc_err
+	if err != nil {
+		return nil, err
 	}
 
 	if !metav1.IsControlledBy(pvc, submarine) {
@@ -244,20 +238,20 @@ func (c *Controller) createSubmarineDatabase(submarine *v1alpha1.Submarine, name
 	}
 
 	// Step3: Create Deployment
-	deployment, deployment_err := c.deploymentLister.Deployments(namespace).Get(databaseName)
+	deployment, err := c.deploymentLister.Deployments(submarine.Namespace).Get(databaseName)
 	// If the resource doesn't exist, we'll create it
-	if errors.IsNotFound(deployment_err) {
-		deployment, deployment_err = c.kubeclientset.AppsV1().Deployments(namespace).Create(context.TODO(), newSubmarineDatabaseDeployment(submarine, pvcName), metav1.CreateOptions{})
-		if deployment_err != nil {
-			klog.Info(deployment_err)
+	if errors.IsNotFound(err) {
+		deployment, err = c.kubeclientset.AppsV1().Deployments(submarine.Namespace).Create(context.TODO(), newSubmarineDatabaseDeployment(submarine), metav1.CreateOptions{})
+		if err != nil {
+			klog.Info(err)
 		}
 		klog.Info("	Create Deployment: ", deployment.Name)
 	}
 	// If an error occurs during Get/Create, we'll requeue the item so we can
 	// attempt processing again later. This could have been caused by a
 	// temporary network failure, or any other transient reason.
-	if deployment_err != nil {
-		return nil, deployment_err
+	if err != nil {
+		return nil, err
 	}
 
 	if !metav1.IsControlledBy(deployment, submarine) {
@@ -269,28 +263,28 @@ func (c *Controller) createSubmarineDatabase(submarine *v1alpha1.Submarine, name
 	// Update the replicas of the database deployment if it is not equal to spec
 	if submarine.Spec.Database.Replicas != nil && *submarine.Spec.Database.Replicas != *deployment.Spec.Replicas {
 		klog.V(4).Infof("Submarine %s database spec replicas: %d, actual replicas: %d", submarine.Name, *submarine.Spec.Database.Replicas, *deployment.Spec.Replicas)
-		deployment, deployment_err = c.kubeclientset.AppsV1().Deployments(submarine.Namespace).Update(context.TODO(), newSubmarineDatabaseDeployment(submarine, pvcName), metav1.UpdateOptions{})
+		deployment, err = c.kubeclientset.AppsV1().Deployments(submarine.Namespace).Update(context.TODO(), newSubmarineDatabaseDeployment(submarine), metav1.UpdateOptions{})
 	}
 
-	if deployment_err != nil {
-		return nil, deployment_err
+	if err != nil {
+		return nil, err
 	}
 
 	// Step4: Create Service
-	service, service_err := c.serviceLister.Services(namespace).Get(databaseName)
+	service, err := c.serviceLister.Services(submarine.Namespace).Get(databaseName)
 	// If the resource doesn't exist, we'll create it
-	if errors.IsNotFound(service_err) {
-		service, service_err = c.kubeclientset.CoreV1().Services(namespace).Create(context.TODO(), newSubmarineDatabaseService(submarine), metav1.CreateOptions{})
-		if service_err != nil {
-			klog.Info(service_err)
+	if errors.IsNotFound(err) {
+		service, err = c.kubeclientset.CoreV1().Services(submarine.Namespace).Create(context.TODO(), newSubmarineDatabaseService(submarine), metav1.CreateOptions{})
+		if err != nil {
+			klog.Info(err)
 		}
 		klog.Info("	Create Service: ", service.Name)
 	}
 	// If an error occurs during Get/Create, we'll requeue the item so we can
 	// attempt processing again later. This could have been caused by a
 	// temporary network failure, or any other transient reason.
-	if service_err != nil {
-		return nil, service_err
+	if err != nil {
+		return nil, err
 	}
 
 	if !metav1.IsControlledBy(service, submarine) {
diff --git a/submarine-cloud-v2/pkg/controller/submarine_ingress.go b/submarine-cloud-v2/pkg/controller/submarine_ingress.go
index f927d34..8de307e 100644
--- a/submarine-cloud-v2/pkg/controller/submarine_ingress.go
+++ b/submarine-cloud-v2/pkg/controller/submarine_ingress.go
@@ -31,11 +31,11 @@ import (
 	"k8s.io/klog/v2"
 )
 
-func newSubmarineServerIngress(submarine *v1alpha1.Submarine, namespace string) *extensionsv1beta1.Ingress {
+func newSubmarineServerIngress(submarine *v1alpha1.Submarine) *extensionsv1beta1.Ingress {
 	return &extensionsv1beta1.Ingress{
 		ObjectMeta: metav1.ObjectMeta{
-			Name:      serverName + "-ingress",
-			Namespace: namespace,
+			Name:      ingressName,
+			Namespace: submarine.Namespace,
 			OwnerReferences: []metav1.OwnerReference{
 				*metav1.NewControllerRef(submarine, v1alpha1.SchemeGroupVersion.WithKind("Submarine")),
 			},
@@ -64,16 +64,15 @@ func newSubmarineServerIngress(submarine *v1alpha1.Submarine, namespace string)
 
 // createIngress is a function to create Ingress.
 // Reference: https://github.com/apache/submarine/blob/master/helm-charts/submarine/templates/submarine-ingress.yaml
-func (c *Controller) createIngress(submarine *v1alpha1.Submarine, namespace string) error {
+func (c *Controller) createIngress(submarine *v1alpha1.Submarine) error {
 	klog.Info("[createIngress]")
-	serverName := "submarine-server"
 
 	// Step1: Create ServiceAccount
-	ingress, ingress_err := c.ingressLister.Ingresses(namespace).Get(serverName + "-ingress")
+	ingress, err := c.ingressLister.Ingresses(submarine.Namespace).Get(ingressName)
 	// If the resource doesn't exist, we'll create it
-	if errors.IsNotFound(ingress_err) {
-		ingress, ingress_err = c.kubeclientset.ExtensionsV1beta1().Ingresses(namespace).Create(context.TODO(),
-			newSubmarineServerIngress(submarine, namespace),
+	if errors.IsNotFound(err) {
+		ingress, err = c.kubeclientset.ExtensionsV1beta1().Ingresses(submarine.Namespace).Create(context.TODO(),
+			newSubmarineServerIngress(submarine),
 			metav1.CreateOptions{})
 		klog.Info("	Create Ingress: ", ingress.Name)
 	}
@@ -81,8 +80,8 @@ func (c *Controller) createIngress(submarine *v1alpha1.Submarine, namespace stri
 	// If an error occurs during Get/Create, we'll requeue the item so we can
 	// attempt processing again later. This could have been caused by a
 	// temporary network failure, or any other transient reason.
-	if ingress_err != nil {
-		return ingress_err
+	if err != nil {
+		return err
 	}
 
 	if !metav1.IsControlledBy(ingress, submarine) {
diff --git a/submarine-cloud-v2/pkg/controller/submarine_server.go b/submarine-cloud-v2/pkg/controller/submarine_server.go
index adfde0e..a1c7a0b 100644
--- a/submarine-cloud-v2/pkg/controller/submarine_server.go
+++ b/submarine-cloud-v2/pkg/controller/submarine_server.go
@@ -139,22 +139,22 @@ func newSubmarineServerDeployment(submarine *v1alpha1.Submarine) *appsv1.Deploym
 
 // createSubmarineServer is a function to create submarine-server.
 // Reference: https://github.com/apache/submarine/blob/master/helm-charts/submarine/templates/submarine-server.yaml
-func (c *Controller) createSubmarineServer(submarine *v1alpha1.Submarine, namespace string) (*appsv1.Deployment, error) {
+func (c *Controller) createSubmarineServer(submarine *v1alpha1.Submarine) (*appsv1.Deployment, error) {
 	klog.Info("[createSubmarineServer]")
 
 	// Step1: Create ServiceAccount
-	serviceaccount, serviceaccount_err := c.serviceaccountLister.ServiceAccounts(namespace).Get(serverName)
+	serviceaccount, err := c.serviceaccountLister.ServiceAccounts(submarine.Namespace).Get(serverName)
 	// If the resource doesn't exist, we'll create it
-	if errors.IsNotFound(serviceaccount_err) {
-		serviceaccount, serviceaccount_err = c.kubeclientset.CoreV1().ServiceAccounts(namespace).Create(context.TODO(), newSubmarineServerServiceAccount(submarine), metav1.CreateOptions{})
+	if errors.IsNotFound(err) {
+		serviceaccount, err = c.kubeclientset.CoreV1().ServiceAccounts(submarine.Namespace).Create(context.TODO(), newSubmarineServerServiceAccount(submarine), metav1.CreateOptions{})
 		klog.Info("	Create ServiceAccount: ", serviceaccount.Name)
 	}
 
 	// If an error occurs during Get/Create, we'll requeue the item so we can
 	// attempt processing again later. This could have been caused by a
 	// temporary network failure, or any other transient reason.
-	if serviceaccount_err != nil {
-		return nil, serviceaccount_err
+	if err != nil {
+		return nil, err
 	}
 
 	if !metav1.IsControlledBy(serviceaccount, submarine) {
@@ -164,18 +164,18 @@ func (c *Controller) createSubmarineServer(submarine *v1alpha1.Submarine, namesp
 	}
 
 	// Step2: Create Service
-	service, service_err := c.serviceLister.Services(namespace).Get(serverName)
+	service, err := c.serviceLister.Services(submarine.Namespace).Get(serverName)
 	// If the resource doesn't exist, we'll create it
-	if errors.IsNotFound(service_err) {
-		service, service_err = c.kubeclientset.CoreV1().Services(namespace).Create(context.TODO(), newSubmarineServerService(submarine), metav1.CreateOptions{})
+	if errors.IsNotFound(err) {
+		service, err = c.kubeclientset.CoreV1().Services(submarine.Namespace).Create(context.TODO(), newSubmarineServerService(submarine), metav1.CreateOptions{})
 		klog.Info("	Create Service: ", service.Name)
 	}
 
 	// If an error occurs during Get/Create, we'll requeue the item so we can
 	// attempt processing again later. This could have been caused by a
 	// temporary network failure, or any other transient reason.
-	if service_err != nil {
-		return nil, service_err
+	if err != nil {
+		return nil, err
 	}
 
 	if !metav1.IsControlledBy(service, submarine) {
@@ -185,18 +185,18 @@ func (c *Controller) createSubmarineServer(submarine *v1alpha1.Submarine, namesp
 	}
 
 	// Step3: Create Deployment
-	deployment, deployment_err := c.deploymentLister.Deployments(namespace).Get(serverName)
+	deployment, err := c.deploymentLister.Deployments(submarine.Namespace).Get(serverName)
 	// If the resource doesn't exist, we'll create it
-	if errors.IsNotFound(deployment_err) {
-		deployment, deployment_err = c.kubeclientset.AppsV1().Deployments(namespace).Create(context.TODO(), newSubmarineServerDeployment(submarine), metav1.CreateOptions{})
+	if errors.IsNotFound(err) {
+		deployment, err = c.kubeclientset.AppsV1().Deployments(submarine.Namespace).Create(context.TODO(), newSubmarineServerDeployment(submarine), metav1.CreateOptions{})
 		klog.Info("	Create Deployment: ", deployment.Name)
 	}
 
 	// If an error occurs during Get/Create, we'll requeue the item so we can
 	// attempt processing again later. This could have been caused by a
 	// temporary network failure, or any other transient reason.
-	if deployment_err != nil {
-		return nil, deployment_err
+	if err != nil {
+		return nil, err
 	}
 
 	if !metav1.IsControlledBy(deployment, submarine) {
@@ -208,11 +208,11 @@ func (c *Controller) createSubmarineServer(submarine *v1alpha1.Submarine, namesp
 	// Update the replicas of the server deployment if it is not equal to spec
 	if submarine.Spec.Server.Replicas != nil && *submarine.Spec.Server.Replicas != *deployment.Spec.Replicas {
 		klog.V(4).Infof("Submarine %s server spec replicas: %d, actual replicas: %d", submarine.Name, *submarine.Spec.Server.Replicas, *deployment.Spec.Replicas)
-		deployment, deployment_err = c.kubeclientset.AppsV1().Deployments(submarine.Namespace).Update(context.TODO(), newSubmarineServerDeployment(submarine), metav1.UpdateOptions{})
+		deployment, err = c.kubeclientset.AppsV1().Deployments(submarine.Namespace).Update(context.TODO(), newSubmarineServerDeployment(submarine), metav1.UpdateOptions{})
 	}
 
-	if deployment_err != nil {
-		return nil, deployment_err
+	if err != nil {
+		return nil, err
 	}
 
 	return deployment, nil
diff --git a/submarine-cloud-v2/pkg/controller/submarine_server_rbac.go b/submarine-cloud-v2/pkg/controller/submarine_server_rbac.go
index 0f21b70..431b30c 100644
--- a/submarine-cloud-v2/pkg/controller/submarine_server_rbac.go
+++ b/submarine-cloud-v2/pkg/controller/submarine_server_rbac.go
@@ -63,7 +63,7 @@ func newSubmarineServerClusterRole(submarine *v1alpha1.Submarine) *rbacv1.Cluste
 	}
 }
 
-func newSubmarineServerClusterRoleBinding(submarine *v1alpha1.Submarine, serviceaccount_namespace string) *rbacv1.ClusterRoleBinding {
+func newSubmarineServerClusterRoleBinding(submarine *v1alpha1.Submarine) *rbacv1.ClusterRoleBinding {
 	return &rbacv1.ClusterRoleBinding{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: serverName,
@@ -74,7 +74,7 @@ func newSubmarineServerClusterRoleBinding(submarine *v1alpha1.Submarine, service
 		Subjects: []rbacv1.Subject{
 			{
 				Kind:      "ServiceAccount",
-				Namespace: serviceaccount_namespace,
+				Namespace: submarine.Namespace,
 				Name:      serverName,
 			},
 		},
@@ -88,22 +88,22 @@ func newSubmarineServerClusterRoleBinding(submarine *v1alpha1.Submarine, service
 
 // createSubmarineServerRBAC is a function to create RBAC for submarine-server.
 // Reference: https://github.com/apache/submarine/blob/master/helm-charts/submarine/templates/rbac.yaml
-func (c *Controller) createSubmarineServerRBAC(submarine *v1alpha1.Submarine, serviceaccount_namespace string) error {
+func (c *Controller) createSubmarineServerRBAC(submarine *v1alpha1.Submarine) error {
 	klog.Info("[createSubmarineServerRBAC]")
-	serverName := "submarine-server"
+
 	// Step1: Create ClusterRole
-	clusterrole, clusterrole_err := c.clusterroleLister.Get(serverName)
+	clusterrole, err := c.clusterroleLister.Get(serverName)
 	// If the resource doesn't exist, we'll create it
-	if errors.IsNotFound(clusterrole_err) {
-		clusterrole, clusterrole_err = c.kubeclientset.RbacV1().ClusterRoles().Create(context.TODO(), newSubmarineServerClusterRole(submarine), metav1.CreateOptions{})
+	if errors.IsNotFound(err) {
+		clusterrole, err = c.kubeclientset.RbacV1().ClusterRoles().Create(context.TODO(), newSubmarineServerClusterRole(submarine), metav1.CreateOptions{})
 		klog.Info("	Create ClusterRole: ", clusterrole.Name)
 	}
 
 	// If an error occurs during Get/Create, we'll requeue the item so we can
 	// attempt processing again later. This could have been caused by a
 	// temporary network failure, or any other transient reason.
-	if clusterrole_err != nil {
-		return clusterrole_err
+	if err != nil {
+		return err
 	}
 
 	if !metav1.IsControlledBy(clusterrole, submarine) {
@@ -115,7 +115,7 @@ func (c *Controller) createSubmarineServerRBAC(submarine *v1alpha1.Submarine, se
 	clusterrolebinding, clusterrolebinding_err := c.clusterrolebindingLister.Get(serverName)
 	// If the resource doesn't exist, we'll create it
 	if errors.IsNotFound(clusterrolebinding_err) {
-		clusterrolebinding, clusterrolebinding_err = c.kubeclientset.RbacV1().ClusterRoleBindings().Create(context.TODO(), newSubmarineServerClusterRoleBinding(submarine, serviceaccount_namespace), metav1.CreateOptions{})
+		clusterrolebinding, clusterrolebinding_err = c.kubeclientset.RbacV1().ClusterRoleBindings().Create(context.TODO(), newSubmarineServerClusterRoleBinding(submarine), metav1.CreateOptions{})
 		klog.Info("	Create ClusterRoleBinding: ", clusterrolebinding.Name)
 	}
 
diff --git a/submarine-cloud-v2/pkg/controller/submarine_tensorboard.go b/submarine-cloud-v2/pkg/controller/submarine_tensorboard.go
index 9a71b04..4cadc36 100644
--- a/submarine-cloud-v2/pkg/controller/submarine_tensorboard.go
+++ b/submarine-cloud-v2/pkg/controller/submarine_tensorboard.go
@@ -34,10 +34,28 @@ import (
 	traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
 )
 
-func newSubmarineTensorboardPersistentVolume(submarine *v1alpha1.Submarine, pvName string, storageSize string, persistentVolumeSource *corev1.PersistentVolumeSource) *corev1.PersistentVolume {
+func newSubmarineTensorboardPersistentVolume(submarine *v1alpha1.Submarine) *corev1.PersistentVolume {
+	var persistentVolumeSource corev1.PersistentVolumeSource
+	switch submarine.Spec.Storage.StorageType {
+	case "nfs":
+		persistentVolumeSource = corev1.PersistentVolumeSource{
+			NFS: &corev1.NFSVolumeSource{
+				Server: submarine.Spec.Storage.NfsIP,
+				Path:   submarine.Spec.Storage.NfsPath,
+			},
+		}
+	case "host":
+		hostPathType := corev1.HostPathDirectoryOrCreate
+		persistentVolumeSource = corev1.PersistentVolumeSource{
+			HostPath: &corev1.HostPathVolumeSource{
+				Path: submarine.Spec.Storage.HostPath,
+				Type: &hostPathType,
+			},
+		}
+	}
 	return &corev1.PersistentVolume{
 		ObjectMeta: metav1.ObjectMeta{
-			Name: pvName,
+			Name: pvName(tensorboardPvNamePrefix, submarine.Namespace),
 			OwnerReferences: []metav1.OwnerReference{
 				*metav1.NewControllerRef(submarine, v1alpha1.SchemeGroupVersion.WithKind("Submarine")),
 			},
@@ -47,18 +65,18 @@ func newSubmarineTensorboardPersistentVolume(submarine *v1alpha1.Submarine, pvNa
 				corev1.ReadWriteMany,
 			},
 			Capacity: corev1.ResourceList{
-				corev1.ResourceStorage: resource.MustParse(storageSize),
+				corev1.ResourceStorage: resource.MustParse(submarine.Spec.Tensorboard.StorageSize),
 			},
-			PersistentVolumeSource: *persistentVolumeSource,
+			PersistentVolumeSource: persistentVolumeSource,
 		},
 	}
 }
 
-func newSubmarineTensorboardPersistentVolumeClaim(submarine *v1alpha1.Submarine, pvcName string, pvName string, storageSize string) *corev1.PersistentVolumeClaim {
+func newSubmarineTensorboardPersistentVolumeClaim(submarine *v1alpha1.Submarine) *corev1.PersistentVolumeClaim {
 	storageClassName := ""
 	return &corev1.PersistentVolumeClaim{
 		ObjectMeta: metav1.ObjectMeta{
-			Name: pvcName,
+			Name: tensorboardPvcName,
 			OwnerReferences: []metav1.OwnerReference{
 				*metav1.NewControllerRef(submarine, v1alpha1.SchemeGroupVersion.WithKind("Submarine")),
 			},
@@ -69,16 +87,16 @@ func newSubmarineTensorboardPersistentVolumeClaim(submarine *v1alpha1.Submarine,
 			},
 			Resources: corev1.ResourceRequirements{
 				Requests: corev1.ResourceList{
-					corev1.ResourceStorage: resource.MustParse(storageSize),
+					corev1.ResourceStorage: resource.MustParse(submarine.Spec.Tensorboard.StorageSize),
 				},
 			},
-			VolumeName:       pvName,
+			VolumeName:       pvName(tensorboardPvNamePrefix, submarine.Namespace),
 			StorageClassName: &storageClassName,
 		},
 	}
 }
 
-func newSubmarineTensorboardDeployment(submarine *v1alpha1.Submarine, tensorboardName string, pvcName string) *appsv1.Deployment {
+func newSubmarineTensorboardDeployment(submarine *v1alpha1.Submarine) *appsv1.Deployment {
 	return &appsv1.Deployment{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: tensorboardName,
@@ -128,7 +146,7 @@ func newSubmarineTensorboardDeployment(submarine *v1alpha1.Submarine, tensorboar
 							Name: "volume",
 							VolumeSource: corev1.VolumeSource{
 								PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
-									ClaimName: pvcName,
+									ClaimName: tensorboardPvcName,
 								},
 							},
 						},
@@ -139,10 +157,10 @@ func newSubmarineTensorboardDeployment(submarine *v1alpha1.Submarine, tensorboar
 	}
 }
 
-func newSubmarineTensorboardService(submarine *v1alpha1.Submarine, serviceName string, tensorboardName string) *corev1.Service {
+func newSubmarineTensorboardService(submarine *v1alpha1.Submarine) *corev1.Service {
 	return &corev1.Service{
 		ObjectMeta: metav1.ObjectMeta{
-			Name: serviceName,
+			Name: tensorboardServiceName,
 			OwnerReferences: []metav1.OwnerReference{
 				*metav1.NewControllerRef(submarine, v1alpha1.SchemeGroupVersion.WithKind("Submarine")),
 			},
@@ -162,7 +180,7 @@ func newSubmarineTensorboardService(submarine *v1alpha1.Submarine, serviceName s
 	}
 }
 
-func newSubmarineTensorboardIngressRoute(submarine *v1alpha1.Submarine, tensorboardName string, serviceName string) *traefikv1alpha1.IngressRoute {
+func newSubmarineTensorboardIngressRoute(submarine *v1alpha1.Submarine) *traefikv1alpha1.IngressRoute {
 	return &traefikv1alpha1.IngressRoute{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: tensorboardName + "-ingressroute",
@@ -182,7 +200,7 @@ func newSubmarineTensorboardIngressRoute(submarine *v1alpha1.Submarine, tensorbo
 						{
 							LoadBalancerSpec: traefikv1alpha1.LoadBalancerSpec{
 								Kind: "Service",
-								Name: serviceName,
+								Name: tensorboardServiceName,
 								Port: 8080,
 							},
 						},
@@ -195,42 +213,19 @@ func newSubmarineTensorboardIngressRoute(submarine *v1alpha1.Submarine, tensorbo
 
 // createSubmarineTensorboard is a function to create submarine-tensorboard.
 // Reference: https://github.com/apache/submarine/blob/master/helm-charts/submarine/templates/submarine-tensorboard.yaml
-func (c *Controller) createSubmarineTensorboard(submarine *v1alpha1.Submarine, namespace string, spec *v1alpha1.SubmarineSpec) error {
+func (c *Controller) createSubmarineTensorboard(submarine *v1alpha1.Submarine) error {
 	klog.Info("[createSubmarineTensorboard]")
-	tensorboardName := "submarine-tensorboard"
 
 	// Step 1: Create PersistentVolume
 	// PersistentVolumes are not namespaced resources, so we add the namespace
 	// as a suffix to distinguish them
-	pvName := tensorboardName + "-pv--" + namespace
-	pv, pv_err := c.persistentvolumeLister.Get(pvName)
+	pv, err := c.persistentvolumeLister.Get(pvName(tensorboardPvNamePrefix, submarine.Namespace))
 
 	// If the resource doesn't exist, we'll create it
-	if errors.IsNotFound(pv_err) {
-		var persistentVolumeSource corev1.PersistentVolumeSource
-		switch spec.Storage.StorageType {
-		case "nfs":
-			persistentVolumeSource = corev1.PersistentVolumeSource{
-				NFS: &corev1.NFSVolumeSource{
-					Server: spec.Storage.NfsIP,
-					Path:   spec.Storage.NfsPath,
-				},
-			}
-		case "host":
-			hostPathType := corev1.HostPathDirectoryOrCreate
-			persistentVolumeSource = corev1.PersistentVolumeSource{
-				HostPath: &corev1.HostPathVolumeSource{
-					Path: spec.Storage.HostPath,
-					Type: &hostPathType,
-				},
-			}
-		default:
-			klog.Warningln("	Invalid storageType found in submarine spec, nothing will be created!")
-			return nil
-		}
-		pv, pv_err = c.kubeclientset.CoreV1().PersistentVolumes().Create(context.TODO(), newSubmarineTensorboardPersistentVolume(submarine, pvName, spec.Tensorboard.StorageSize, &persistentVolumeSource), metav1.CreateOptions{})
-		if pv_err != nil {
-			klog.Info(pv_err)
+	if errors.IsNotFound(err) {
+		pv, err = c.kubeclientset.CoreV1().PersistentVolumes().Create(context.TODO(), newSubmarineTensorboardPersistentVolume(submarine), metav1.CreateOptions{})
+		if err != nil {
+			klog.Info(err)
 		}
 		klog.Info("	Create PersistentVolume: ", pv.Name)
 	}
@@ -238,8 +233,8 @@ func (c *Controller) createSubmarineTensorboard(submarine *v1alpha1.Submarine, n
 	// If an error occurs during Get/Create, we'll requeue the item so we can
 	// attempt processing again later. This could have been caused by a
 	// temporary network failure, or any other transient reason.
-	if pv_err != nil {
-		return pv_err
+	if err != nil {
+		return err
 	}
 
 	if !metav1.IsControlledBy(pv, submarine) {
@@ -249,23 +244,22 @@ func (c *Controller) createSubmarineTensorboard(submarine *v1alpha1.Submarine, n
 	}
 
 	// Step 2: Create PersistentVolumeClaim
-	pvcName := tensorboardName + "-pvc"
-	pvc, pvc_err := c.persistentvolumeclaimLister.PersistentVolumeClaims(namespace).Get(pvcName)
+	pvc, err := c.persistentvolumeclaimLister.PersistentVolumeClaims(submarine.Namespace).Get(tensorboardPvcName)
 	// If the resource doesn't exist, we'll create it
-	if errors.IsNotFound(pvc_err) {
-		pvc, pvc_err = c.kubeclientset.CoreV1().PersistentVolumeClaims(namespace).Create(context.TODO(),
-			newSubmarineTensorboardPersistentVolumeClaim(submarine, pvcName, pvName, spec.Tensorboard.StorageSize),
+	if errors.IsNotFound(err) {
+		pvc, err = c.kubeclientset.CoreV1().PersistentVolumeClaims(submarine.Namespace).Create(context.TODO(),
+			newSubmarineTensorboardPersistentVolumeClaim(submarine),
 			metav1.CreateOptions{})
-		if pvc_err != nil {
-			klog.Info(pvc_err)
+		if err != nil {
+			klog.Info(err)
 		}
 		klog.Info("	Create PersistentVolumeClaim: ", pvc.Name)
 	}
 	// If an error occurs during Get/Create, we'll requeue the item so we can
 	// attempt processing again later. This could have been caused by a
 	// temporary network failure, or any other transient reason.
-	if pvc_err != nil {
-		return pvc_err
+	if err != nil {
+		return err
 	}
 
 	if !metav1.IsControlledBy(pvc, submarine) {
@@ -275,19 +269,19 @@ func (c *Controller) createSubmarineTensorboard(submarine *v1alpha1.Submarine, n
 	}
 
 	// Step 3: Create Deployment
-	deployment, deployment_err := c.deploymentLister.Deployments(namespace).Get(tensorboardName)
-	if errors.IsNotFound(deployment_err) {
-		deployment, deployment_err = c.kubeclientset.AppsV1().Deployments(namespace).Create(context.TODO(), newSubmarineTensorboardDeployment(submarine, tensorboardName, pvcName), metav1.CreateOptions{})
-		if deployment_err != nil {
-			klog.Info(deployment_err)
+	deployment, err := c.deploymentLister.Deployments(submarine.Namespace).Get(tensorboardName)
+	if errors.IsNotFound(err) {
+		deployment, err = c.kubeclientset.AppsV1().Deployments(submarine.Namespace).Create(context.TODO(), newSubmarineTensorboardDeployment(submarine), metav1.CreateOptions{})
+		if err != nil {
+			klog.Info(err)
 		}
 		klog.Info("	Create Deployment: ", deployment.Name)
 	}
 	// If an error occurs during Get/Create, we'll requeue the item so we can
 	// attempt processing again later. This could have been caused by a
 	// temporary network failure, or any other transient reason.
-	if deployment_err != nil {
-		return deployment_err
+	if err != nil {
+		return err
 	}
 
 	if !metav1.IsControlledBy(deployment, submarine) {
@@ -297,21 +291,20 @@ func (c *Controller) createSubmarineTensorboard(submarine *v1alpha1.Submarine, n
 	}
 
 	// Step 4: Create Service
-	serviceName := tensorboardName + "-service"
-	service, service_err := c.serviceLister.Services(namespace).Get(serviceName)
+	service, err := c.serviceLister.Services(submarine.Namespace).Get(tensorboardServiceName)
 	// If the resource doesn't exist, we'll create it
-	if errors.IsNotFound(service_err) {
-		service, service_err = c.kubeclientset.CoreV1().Services(namespace).Create(context.TODO(), newSubmarineTensorboardService(submarine, serviceName, tensorboardName), metav1.CreateOptions{})
-		if service_err != nil {
-			klog.Info(service_err)
+	if errors.IsNotFound(err) {
+		service, err = c.kubeclientset.CoreV1().Services(submarine.Namespace).Create(context.TODO(), newSubmarineTensorboardService(submarine), metav1.CreateOptions{})
+		if err != nil {
+			klog.Info(err)
 		}
 		klog.Info(" Create Service: ", service.Name)
 	}
 	// If an error occurs during Get/Create, we'll requeue the item so we can
 	// attempt processing again later. This could have been caused by a
 	// temporary network failure, or any other transient reason.
-	if service_err != nil {
-		return service_err
+	if err != nil {
+		return err
 	}
 
 	if !metav1.IsControlledBy(service, submarine) {
@@ -321,20 +314,20 @@ func (c *Controller) createSubmarineTensorboard(submarine *v1alpha1.Submarine, n
 	}
 
 	// Step 5: Create IngressRoute
-	ingressroute, ingressroute_err := c.ingressrouteLister.IngressRoutes(namespace).Get(tensorboardName + "-ingressroute")
+	ingressroute, err := c.ingressrouteLister.IngressRoutes(submarine.Namespace).Get(tensorboardIngressRouteName)
 	// If the resource doesn't exist, we'll create it
-	if errors.IsNotFound(ingressroute_err) {
-		ingressroute, ingressroute_err = c.traefikclientset.TraefikV1alpha1().IngressRoutes(namespace).Create(context.TODO(), newSubmarineTensorboardIngressRoute(submarine, tensorboardName, serviceName), metav1.CreateOptions{})
-		if ingressroute_err != nil {
-			klog.Info(ingressroute_err)
+	if errors.IsNotFound(err) {
+		ingressroute, err = c.traefikclientset.TraefikV1alpha1().IngressRoutes(submarine.Namespace).Create(context.TODO(), newSubmarineTensorboardIngressRoute(submarine), metav1.CreateOptions{})
+		if err != nil {
+			klog.Info(err)
 		}
 		klog.Info(" Create IngressRoute: ", ingressroute.Name)
 	}
 	// If an error occurs during Get/Create, we'll requeue the item so we can
 	// attempt processing again later. This could have been caused by a
 	// temporary network failure, or any other transient reason.
-	if ingressroute_err != nil {
-		return ingressroute_err
+	if err != nil {
+		return err
 	}
 
 	if !metav1.IsControlledBy(ingressroute, submarine) {

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@submarine.apache.org
For additional commands, e-mail: dev-help@submarine.apache.org