summaryrefslogtreecommitdiff
path: root/internal/control/state.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/control/state.go')
-rw-r--r--internal/control/state.go71
1 files changed, 71 insertions, 0 deletions
diff --git a/internal/control/state.go b/internal/control/state.go
new file mode 100644
index 0000000..7fc7827
--- /dev/null
+++ b/internal/control/state.go
@@ -0,0 +1,71 @@
+package control
+
+import (
+ "encoding/json"
+ "errors"
+ "os"
+ "path/filepath"
+ "sort"
+ "time"
+)
+
+type NodeState struct {
+ NodeID string `json:"node_id"`
+ BootstrapStatus string `json:"bootstrap_status"`
+ LastBootstrapAt *time.Time `json:"last_bootstrap_at,omitempty"`
+ LastHealthCheckAt *time.Time `json:"last_health_check_at,omitempty"`
+ LastDNSSyncAt *time.Time `json:"last_dns_sync_at,omitempty"`
+ PublicHost string `json:"public_host,omitempty"`
+ Services []ServiceStatus `json:"services,omitempty"`
+ Metadata map[string]any `json:"metadata,omitempty"`
+}
+
+type ServiceStatus struct {
+ Type string `json:"type"`
+ Status string `json:"status"`
+ Port int `json:"port"`
+}
+
+func LoadNodeState(dir, nodeID string) (*NodeState, error) {
+ data, err := os.ReadFile(filepath.Join(dir, nodeID+".json"))
+ if err != nil {
+ return nil, err
+ }
+
+ var state NodeState
+ if err := json.Unmarshal(data, &state); err != nil {
+ return nil, err
+ }
+ return &state, nil
+}
+
+func SaveNodeState(dir string, state NodeState) error {
+ if err := os.MkdirAll(dir, 0o755); err != nil {
+ return err
+ }
+
+ sort.Slice(state.Services, func(i, j int) bool {
+ return state.Services[i].Type < state.Services[j].Type
+ })
+
+ data, err := json.MarshalIndent(state, "", " ")
+ if err != nil {
+ return err
+ }
+ data = append(data, '\n')
+
+ tmpPath := filepath.Join(dir, state.NodeID+".json.tmp")
+ finalPath := filepath.Join(dir, state.NodeID+".json")
+ if err := os.WriteFile(tmpPath, data, 0o600); err != nil {
+ return err
+ }
+ return os.Rename(tmpPath, finalPath)
+}
+
+func DeleteNodeState(dir, nodeID string) error {
+ err := os.Remove(filepath.Join(dir, nodeID+".json"))
+ if errors.Is(err, os.ErrNotExist) {
+ return nil
+ }
+ return err
+}