From 84c78cd8cc12b20381b0f9ca18eb16a269e299d2 Mon Sep 17 00:00:00 2001
From: Malte Bauch <malte.bauch@stud.h-da.de>
Date: Mon, 11 Dec 2023 14:47:58 +0100
Subject: [PATCH] Plugin store allows to persist plugin data through json file

Plugins will keep their UUIDs after a restart.
---
 .../plugin-registry/plugin-store.json         |  1 +
 plugin-registry/main.go                       | 43 +++++++++-------
 plugin-registry/plugin-registry.Dockerfile    |  1 +
 plugin-registry/store.go                      | 51 +++++++++++++++++++
 4 files changed, 79 insertions(+), 17 deletions(-)
 create mode 100644 dev_env_data/plugin-registry/plugin-store.json
 create mode 100644 plugin-registry/store.go

diff --git a/dev_env_data/plugin-registry/plugin-store.json b/dev_env_data/plugin-registry/plugin-store.json
new file mode 100644
index 000000000..48da2b394
--- /dev/null
+++ b/dev_env_data/plugin-registry/plugin-store.json
@@ -0,0 +1 @@
+[{"id":"e2c358b3-6482-4010-b0d8-679dff73153b","path":"plugins/arista/bundled_plugin.zip","hash":"h1:+ORKoJds8/v25xH4uvd3pPqa1eIs6JXHw/Ef4HMtG6A=","manifest":{"name":"Arista","firmware":"standard","author":"goSDN-Team","version":"1.0.0"}},{"id":"d1c269a2-6482-4010-b0d8-679dff73153b","path":"plugins/openconfig/bundled_plugin.zip","hash":"h1:FpK0b9SSrly8IJMfhbgt/Q8k3f4V5tRlIEX7K9btMrI=","manifest":{"name":"Openconfig","firmware":"standard","author":"goSDN-Team","version":"1.0.0"}}]
diff --git a/plugin-registry/main.go b/plugin-registry/main.go
index 5b0539f6a..aff913d70 100644
--- a/plugin-registry/main.go
+++ b/plugin-registry/main.go
@@ -51,6 +51,11 @@ func registerPlugins() *PluginRegistry {
 	pr := &PluginRegistry{}
 	pluginStore := NewStore(pluginStorePath)
 
+	plugins, err := pluginStore.GetAll()
+	if err != nil {
+		fmt.Println(err)
+	}
+
 	for _, dir := range dirs {
 		fmt.Printf("File %+v\n", dir)
 
@@ -66,29 +71,33 @@ func registerPlugins() *PluginRegistry {
 				panic(err)
 			}
 
-			//var id uuid.UUID
-			//switch i {
-			//case 0:
-			//	id = uuid.MustParse("e2c358b3-6482-4010-b0d8-679dff73153b")
-			//case 1:
-			//	id = uuid.MustParse("d1c269a2-6482-4010-b0d8-679dff73153b")
-			//case 2:
-			//	id = uuid.MustParse("f3b474c2-6482-4010-b0d8-679dff73153b")
-			//default:
-			//	break
-			//}
-
-			plugin := &Plugin{
-				ID:       uuid.New(),
-				Path:     filepath.Join(dirPath, util.BundledPluginName),
-				Hash:     dirHashed,
-				Manifest: manifest,
+			var plugin *Plugin
+			for i, p := range plugins {
+				if p.Hash == dirHashed {
+					plugin = p
+					plugins[i] = plugins[len(plugins)-1]
+					plugins = plugins[:len(plugins)-1]
+					break
+				}
+			}
+
+			if plugin == nil {
+				plugin = &Plugin{
+					ID:       uuid.New(),
+					Path:     filepath.Join(dirPath, util.BundledPluginName),
+					Hash:     dirHashed,
+					Manifest: manifest,
+				}
 			}
 
 			pr.Plugins = append(pr.Plugins, plugin)
 		}
 	}
 
+	for _, p := range pr.Plugins {
+		fmt.Printf("registeredPlugin: %v\n", p)
+	}
+
 	if err := pluginStore.Update(pr.Plugins); err != nil {
 		fmt.Println(err)
 	}
diff --git a/plugin-registry/plugin-registry.Dockerfile b/plugin-registry/plugin-registry.Dockerfile
index a82ea5647..9b568ff16 100644
--- a/plugin-registry/plugin-registry.Dockerfile
+++ b/plugin-registry/plugin-registry.Dockerfile
@@ -20,4 +20,5 @@ EXPOSE 55057
 WORKDIR /app/
 COPY --from=builder /plugin-registry/artifacts/plugin-registry .
 COPY --from=builder /plugin-registry/plugin-registry/plugins ./plugins
+COPY --from=builder /plugin-registry/dev_env_data/plugin-registry/plugin-store.json ./plugin-store.json
 ENTRYPOINT ["./plugin-registry", "-socket", "55057"]
diff --git a/plugin-registry/store.go b/plugin-registry/store.go
new file mode 100644
index 000000000..72772d309
--- /dev/null
+++ b/plugin-registry/store.go
@@ -0,0 +1,51 @@
+package main
+
+import (
+	"encoding/json"
+	"os"
+	"sync"
+)
+
+type Store struct {
+	fm   sync.Mutex
+	path string
+}
+
+func NewStore(path string) *Store {
+	return &Store{
+		path: path,
+	}
+}
+
+func (s *Store) Update(plugins []*Plugin) error {
+	s.fm.Lock()
+	defer s.fm.Unlock()
+
+	serializedPlugins, err := json.Marshal(plugins)
+	if err != nil {
+		return err
+	}
+
+	if err := os.WriteFile(s.path, serializedPlugins, 0600); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (s *Store) GetAll() ([]*Plugin, error) {
+	s.fm.Lock()
+	defer s.fm.Unlock()
+
+	var plugins []*Plugin
+
+	j, err := os.ReadFile(s.path)
+	if err != nil {
+		return nil, err
+	}
+
+	if err := json.Unmarshal(j, &plugins); err != nil {
+		return nil, err
+	}
+
+	return plugins, nil
+}
-- 
GitLab