From d784b1eaba086f18af7b12f3bc928cdfb2193966 Mon Sep 17 00:00:00 2001
From: Malte Bauch <malte.bauch@stud.h-da.de>
Date: Tue, 12 Sep 2023 16:48:55 +0200
Subject: [PATCH] Add remove method to plugin

---
 controller/controller.go                       |  2 +-
 controller/interfaces/plugin/plugin.go         |  1 +
 controller/northbound/server/networkElement.go | 11 +++++++++++
 controller/nucleus/plugin.go                   | 11 +++++++++++
 controller/nucleus/pluginService.go            |  2 +-
 5 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/controller/controller.go b/controller/controller.go
index f830c20df..7bfd9f03e 100644
--- a/controller/controller.go
+++ b/controller/controller.go
@@ -391,7 +391,7 @@ func shutdown() error {
 		}
 		for _, plugin := range plugins {
 			log.Info("Defer: ", plugin.Manifest().Name)
-			plugin.GetClient().Kill()
+			plugin.Close()
 			log.Info("Defer - exited: ", plugin.GetClient().Exited())
 		}
 		coreLock.Unlock()
diff --git a/controller/interfaces/plugin/plugin.go b/controller/interfaces/plugin/plugin.go
index f61bda8a8..e51743309 100644
--- a/controller/interfaces/plugin/plugin.go
+++ b/controller/interfaces/plugin/plugin.go
@@ -46,6 +46,7 @@ type Plugin interface {
 	Ping() error
 	Restart() error
 	Close()
+	Remove() error
 	shared.DeviceModel
 }
 
diff --git a/controller/northbound/server/networkElement.go b/controller/northbound/server/networkElement.go
index 76a3439c3..3472a97e9 100644
--- a/controller/northbound/server/networkElement.go
+++ b/controller/northbound/server/networkElement.go
@@ -726,30 +726,41 @@ func (n *NetworkElementServer) addMne(ctx context.Context, name string, opt *tpb
 
 	mne, err := nucleus.NewNetworkElement(name, networkElementID, opt, pndID, plugin, conflict.Metadata{ResourceVersion: 0})
 	if err != nil {
+		plugin.Remove()
 		return uuid.Nil, err
 	}
 
 	if mne.IsTransportValid() {
 		resp, err := n.getPath(ctx, mne, "/")
 		if err != nil {
+			plugin.Remove()
 			return uuid.Nil, err
 		}
 
 		err = mne.ProcessResponse(resp)
 		if err != nil {
+			plugin.Remove()
 			return uuid.Nil, err
 		}
 
 		err = n.mneService.Add(mne)
 		if err != nil {
+			plugin.Remove()
 			return uuid.Nil, err
 		}
 
 		err = n.pluginService.Add(plugin)
 		if err != nil {
+			if err := plugin.Remove(); err != nil {
+				return uuid.Nil, status.Errorf(codes.Internal, "failed to clean up plugin: ", err)
+			}
+			if err := n.mneService.Delete(mne); err != nil {
+				return uuid.Nil, status.Errorf(codes.Internal, "failed to clean up device: ", err)
+			}
 			return uuid.Nil, err
 		}
 	} else {
+		plugin.Remove()
 		return uuid.Nil, status.Errorf(codes.InvalidArgument, "invalid transport data provided")
 	}
 
diff --git a/controller/nucleus/plugin.go b/controller/nucleus/plugin.go
index 032c30ed4..1709217e4 100644
--- a/controller/nucleus/plugin.go
+++ b/controller/nucleus/plugin.go
@@ -3,6 +3,7 @@ package nucleus
 import (
 	"encoding/json"
 	"fmt"
+	"os"
 	"os/exec"
 	"path/filepath"
 
@@ -129,6 +130,15 @@ func (p *Plugin) ReattachConfig() *hcplugin.ReattachConfig {
 	return p.client.ReattachConfig()
 }
 
+// Remove ensures that the Plugin is killed and the corresponding files are
+// removed.
+func (p *Plugin) Remove() error {
+	// stop the running plugins process
+	p.Close()
+	// remove the plugins folder
+	return os.RemoveAll(p.ExecPath())
+}
+
 // State returns the current state of the plugin.
 // Different states of the plugin can be:
 //   - created
@@ -165,6 +175,7 @@ func (p *Plugin) Restart() error {
 
 // Close ends the execution of the plugin.
 func (p *Plugin) Close() {
+	// end the plugin process
 	p.client.Kill()
 }
 
diff --git a/controller/nucleus/pluginService.go b/controller/nucleus/pluginService.go
index 4b0415181..3a1319efd 100644
--- a/controller/nucleus/pluginService.go
+++ b/controller/nucleus/pluginService.go
@@ -106,7 +106,7 @@ func (s *PluginService) Delete(pluginToDelete plugin.Plugin) error {
 	}
 
 	// stop the plugin
-	pluginToDelete.GetClient().Kill()
+	pluginToDelete.Close()
 
 	if err := s.eventService.PublishEvent(PluginEventTopic, event.NewDeleteEvent(pluginToDelete.ID())); err != nil {
 		log.Error(err)
-- 
GitLab