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

liuxun 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 0669b66  SUBMARINE-816. Implement Submarine delete event handler
0669b66 is described below

commit 0669b668c76dd19534fa29457265b1e34746c593
Author: Kai-Hsun Chen <[email protected]>
AuthorDate: Sat May 8 16:27:26 2021 +0800

    SUBMARINE-816. Implement Submarine delete event handler
    
    ### What is this PR for?
    This Jira aims to handle the delete events of custom resource "submarine". 
To elaborate, when the informer of the custom resource "submarine" receives a 
delete event, the submarine operator needs to delete the resources related to 
the "submarine" instance.
    
    Reference:
    (1) CRD: 
https://github.com/apache/submarine/blob/master/submarine-cloud-v2/artifacts/examples/crd.yaml
    (2) CR: 
https://github.com/apache/submarine/blob/master/submarine-cloud-v2/artifacts/examples/example-submarine.yaml
    ### What type of PR is it?
    [Feature]
    
    ### Todos
    * Create namespace via submarine operator
    
    ### What is the Jira issue?
    https://issues.apache.org/jira/browse/SUBMARINE-816
    
    ### How should this be tested?
    ```
    # Step1-1: In-cluster
    eval $(minikube docker-env)
    make image
    kubectl apply -f artifacts/examples/submarine-operator-service-account.yaml
    kubectl create ns submarine-operator-test
    kubectl apply -n submarine-operator-test -f 
artifacts/examples/example-submarine.yaml
    
    # Step1-2: Out-of-cluster
    go build -o submarine-operator
    ./submarine-operator
    kubectl create ns submarine-operator-test
    kubectl apply -n submarine-operator-test -f 
artifacts/examples/example-submarine.yaml
    
    # Step2: Delete Custom Resource
    kubectl delete submarine example-submarine -n submarine-operator-test
    
    # Step3: Check the result
    kubectl get ns
    kubectl get pv
    ```
    
    ### Screenshots (if appropriate)
    * Step1: Create example-submarine (custom resource) in namespace 
submarine-operator-test
    * Step2: Delete example-submarine
    
    
https://user-images.githubusercontent.com/20109646/117336563-eeedf400-aece-11eb-8d11-aff3b146de6e.mov
    
    ### Questions:
    * Do the license files need updating? No
    * Are there breaking changes for older versions? No
    * Does this need new documentation? Yes
    
    Author: Kai-Hsun Chen <[email protected]>
    
    Signed-off-by: Liu Xun <[email protected]>
    
    Closes #580 from kevin85421/SUBMARINE-816 and squashes the following 
commits:
    
    8e6d221 [Kai-Hsun Chen] Change hardcoded string to const
    17159ff [Kai-Hsun Chen] Update README.md
    9ff0571 [Kai-Hsun Chen] SUBMARINE-816. Implement Submarine delete event 
handler
---
 submarine-cloud-v2/README.md     |   3 +-
 submarine-cloud-v2/controller.go | 148 +++++++++++++++++++++++++--------------
 2 files changed, 98 insertions(+), 53 deletions(-)

diff --git a/submarine-cloud-v2/README.md b/submarine-cloud-v2/README.md
index 779fedc..2bc6b28 100644
--- a/submarine-cloud-v2/README.md
+++ b/submarine-cloud-v2/README.md
@@ -62,7 +62,8 @@ make image
 kubectl apply -f artifacts/examples/submarine-operator-service-account.yaml
 
 # Step3: Deploy a submarine-operator
-kubectl apply -f artifacts/examples/submarine-operator.yaml
+kubectl create ns submarine-operator-test
+kubectl apply -n submarine-operator-test -f 
artifacts/examples/example-submarine.yaml
 
 # Step4: Inspect submarine-operator POD logs 
 kubectl logs ${submarine-operator POD}
diff --git a/submarine-cloud-v2/controller.go b/submarine-cloud-v2/controller.go
index 18c5aad..bd64f10 100644
--- a/submarine-cloud-v2/controller.go
+++ b/submarine-cloud-v2/controller.go
@@ -95,6 +95,17 @@ type Controller struct {
        recorder record.EventRecorder
 }
 
+const (
+       ADD = iota
+       UPDATE
+       DELETE
+)
+
+type WorkQueueItem struct {
+       key    string
+       action int
+}
+
 // NewController returns a new sample controller
 func NewController(
        kubeclientset kubernetes.Interface,
@@ -144,9 +155,14 @@ func NewController(
        // Setting up event handler for Submarine
        klog.Info("Setting up event handlers")
        
submarineInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
-               AddFunc: controller.enqueueSubmarine,
+               AddFunc: func(toAdd interface{}) {
+                       controller.enqueueSubmarine(toAdd, ADD)
+               },
                UpdateFunc: func(old, new interface{}) {
-                       controller.enqueueSubmarine(new)
+                       controller.enqueueSubmarine(new, UPDATE)
+               },
+               DeleteFunc: func(toDelete interface{}) {
+                       controller.enqueueSubmarine(toDelete, DELETE)
                },
        })
 
@@ -201,10 +217,12 @@ func (c *Controller) processNextWorkItem() bool {
        err := func(obj interface{}) error {
                // TODO: Maintain workqueue
                defer c.workqueue.Done(obj)
-               key, _ := obj.(string)
-               c.syncHandler(key)
+               var item WorkQueueItem
+
+               item, _ = obj.(WorkQueueItem)
+               c.syncHandler(item)
                c.workqueue.Forget(obj)
-               klog.Infof("Successfully synced '%s'", key)
+               klog.Infof("Successfully synced '%s'", item.key)
                return nil
        }(obj)
 
@@ -1036,8 +1054,10 @@ func (c *Controller) newSubmarineTensorboard(namespace 
string, spec *v1alpha1.Su
 // syncHandler compares the actual state with the desired, and attempts to
 // converge the two. It then updates the Status block of the Foo resource
 // with the current status of the resource.
-func (c *Controller) syncHandler(key string) error {
+func (c *Controller) syncHandler(workqueueItem WorkQueueItem) error {
        // TODO: business logic
+       key := workqueueItem.key
+       action := workqueueItem.action
 
        // Convert the namespace/name string into a distinct namespace and name
        namespace, name, err := cache.SplitMetaNamespaceKey(key)
@@ -1046,59 +1066,80 @@ func (c *Controller) syncHandler(key string) error {
                return nil
        }
 
-       // Get the Submarine resource with this namespace/name
-       submarine, err := c.submarinesLister.Submarines(namespace).Get(name)
-       if err != nil {
-               // The Submarine resource may no longer exist, in which case we 
stop
-               // processing
-               if errors.IsNotFound(err) {
-                       utilruntime.HandleError(fmt.Errorf("submarine '%s' in 
work queue no longer exists", key))
-                       return nil
+       klog.Info("syncHandler: ", key, " / ", action)
+
+       if action != DELETE { // Case: ADD & UPDATE
+               klog.Info("Add / Update: ", key)
+               // Get the Submarine resource with this namespace/name
+               submarine, err := 
c.submarinesLister.Submarines(namespace).Get(name)
+               if err != nil {
+                       // The Submarine resource may no longer exist, in which 
case we stop
+                       // processing
+                       if errors.IsNotFound(err) {
+                               utilruntime.HandleError(fmt.Errorf("submarine 
'%s' in work queue no longer exists", key))
+                               return nil
+                       }
                }
-       }
 
-       klog.Info("syncHandler: ", key)
+               // Print out the spec of the Submarine resource
+               b, err := json.MarshalIndent(submarine.Spec, "", "  ")
+               fmt.Println(string(b))
 
-       // Print out the spec of the Submarine resource
-       b, err := json.MarshalIndent(submarine.Spec, "", "  ")
-       fmt.Println(string(b))
+               // Install subcharts
+               c.newSubCharts(namespace)
 
-       // Install subcharts
-       c.newSubCharts(namespace)
+               // Create submarine-server
+               serverImage := submarine.Spec.Server.Image
+               serverReplicas := *submarine.Spec.Server.Replicas
+               if serverImage == "" {
+                       serverImage = "apache/submarine:server-" + 
submarine.Spec.Version
+               }
+               err = c.newSubmarineServer(namespace, serverImage, 
serverReplicas)
+               if err != nil {
+                       return err
+               }
 
-       // Create submarine-server
-       serverImage := submarine.Spec.Server.Image
-       serverReplicas := *submarine.Spec.Server.Replicas
-       if serverImage == "" {
-               serverImage = "apache/submarine:server-" + 
submarine.Spec.Version
-       }
-       err = c.newSubmarineServer(namespace, serverImage, serverReplicas)
-       if err != nil {
-               return err
-       }
+               // Create Submarine Database
+               err = c.newSubmarineDatabase(namespace, &submarine.Spec)
+               if err != nil {
+                       return err
+               }
 
-       // Create Submarine Database
-       err = c.newSubmarineDatabase(namespace, &submarine.Spec)
-       if err != nil {
-               return err
-       }
+               // Create ingress
+               err = c.newIngress(namespace)
+               if err != nil {
+                       return err
+               }
 
-       // Create ingress
-       err = c.newIngress(namespace)
-       if err != nil {
-               return err
-       }
+               // Create RBAC
+               err = c.newSubmarineServerRBAC(namespace)
+               if err != nil {
+                       return err
+               }
 
-       // Create RBAC
-       err = c.newSubmarineServerRBAC(namespace)
-       if err != nil {
-               return err
-       }
+               // Create Submarine Tensorboard
+               err = c.newSubmarineTensorboard(namespace, &submarine.Spec)
+               if err != nil {
+                       return err
+               }
+       } else {
+               // DELETE
+               err = 
c.kubeclientset.CoreV1().Namespaces().Delete(context.TODO(), namespace, 
metav1.DeleteOptions{})
+               if err != nil {
+                       return err
+               }
 
-       // Create Submarine Tensorboard
-       err = c.newSubmarineTensorboard(namespace, &submarine.Spec)
-       if err != nil {
-               return err
+               err = 
c.kubeclientset.CoreV1().PersistentVolumes().Delete(context.TODO(), 
"submarine-database-pv--"+namespace, metav1.DeleteOptions{})
+               if err != nil {
+                       return err
+               }
+
+               err = 
c.kubeclientset.CoreV1().PersistentVolumes().Delete(context.TODO(), 
"submarine-tensorboard-pv--"+namespace, metav1.DeleteOptions{})
+               if err != nil {
+                       return err
+               }
+
+               klog.Info("Delete Namespace: ", namespace)
        }
 
        return nil
@@ -1107,7 +1148,7 @@ func (c *Controller) syncHandler(key string) error {
 // enqueueFoo takes a Submarine resource and converts it into a namespace/name
 // string which is then put onto the work queue. This method should *not* be
 // passed resources of any type other than Submarine.
-func (c *Controller) enqueueSubmarine(obj interface{}) {
+func (c *Controller) enqueueSubmarine(obj interface{}, action int) {
        var key string
        var err error
        if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil {
@@ -1117,5 +1158,8 @@ func (c *Controller) enqueueSubmarine(obj interface{}) {
 
        // key: [namespace]/[CR name]
        // Example: default/example-submarine
-       c.workqueue.Add(key)
+       c.workqueue.Add(WorkQueueItem{
+               key:    key,
+               action: action,
+       })
 }

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to