From bdcc7ff935d3f4589614abe9bdd7050de1521812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20=C3=85hall?= Date: Wed, 20 Aug 2025 10:18:35 +0200 Subject: [PATCH] Initial commit of datagraph_launcher --- launcher/go.mod | 5 +++ launcher/go.sum | 2 + launcher/main.go | 113 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 launcher/go.mod create mode 100644 launcher/go.sum create mode 100644 launcher/main.go diff --git a/launcher/go.mod b/launcher/go.mod new file mode 100644 index 0000000..0836261 --- /dev/null +++ b/launcher/go.mod @@ -0,0 +1,5 @@ +module datagraph_launcher + +go 1.24.2 + +require github.com/goccy/go-yaml v1.18.0 diff --git a/launcher/go.sum b/launcher/go.sum new file mode 100644 index 0000000..eb0d822 --- /dev/null +++ b/launcher/go.sum @@ -0,0 +1,2 @@ +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= diff --git a/launcher/main.go b/launcher/main.go new file mode 100644 index 0000000..7469912 --- /dev/null +++ b/launcher/main.go @@ -0,0 +1,113 @@ +package main + +import ( + // External + "github.com/goccy/go-yaml" + + // Standard + "encoding/json" + "flag" + "fmt" + "io" + "os" + "path" +) + +const VERSION = "v1" + +type DatagraphNode struct { + ID int + Name string + Children []*DatagraphNode + TypeName string + Data struct { + Exec string + Dynamic string + Inplace bool + } +} + +type Entry struct { + Name string + Exec string `yaml:",omitempty"` + Inplace bool `yaml:",omitempty"` + Dynamic string `yaml:",omitempty"` + Commands []*Entry `yaml:",omitempty"` +} + +func (node DatagraphNode) toEntry() (e Entry) { + e.Name = node.Name + e.Exec = node.Data.Exec + e.Dynamic = node.Data.Dynamic + e.Inplace = node.Data.Inplace + + for _, childNode := range node.Children { + childEntry := childNode.toEntry() + e.Commands = append(e.Commands, &childEntry) + } + return +} + +func init() { + var flagVersion bool + + flag.BoolVar(&flagVersion, "version", false, "Print version and exit") + flag.Parse() + + if flagVersion { + fmt.Println(VERSION) + os.Exit(0) + } +} + +func main() { + // Script could be run for different users and have different places where config is supposed to go. + dir := os.Getenv("DATAGRAPH_DIR") + if dir == "" { + fmt.Fprintf(os.Stderr, "Set env variable DATAGRAPH_DIR\n") + os.Exit(1) + } + + // Make it easier for admins by creating directories automatically. + err := os.MkdirAll(dir, 0700) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) + } + + // JSON data from datagraph is read into a data structure + // for further processing into the launcher + datagraphData, _ := io.ReadAll(os.Stdin) + var node DatagraphNode + err = json.Unmarshal(datagraphData, &node) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) + } + + // Each top node is a separate file. + for _, topNode := range node.Children { + y, err := yaml.Marshal(topNode.toEntry()) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) + } + + f, err := os.OpenFile( + path.Join(dir, topNode.Name+".yaml"), + os.O_CREATE|os.O_WRONLY|os.O_TRUNC, + 0600, + ) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) + } + defer f.Close() + + _, err = f.Write(y) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) + } + } +}