You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@submarine.apache.org by li...@apache.org on 2021/05/09 15:17:26 UTC
[submarine] branch master updated: SUBMARINE-816. Implement
Submarine delete event handler
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 <b0...@ntu.edu.tw>
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 <b0...@ntu.edu.tw>
Signed-off-by: Liu Xun <li...@apache.org>
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: dev-unsubscribe@submarine.apache.org
For additional commands, e-mail: dev-help@submarine.apache.org