75 lines
2.2 KiB
Go
75 lines
2.2 KiB
Go
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
// enodia-sentinel-go is the experimental Phase 1 sidecar. Python remains the
|
|
// production implementation and behavioral oracle until parity is complete.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
"time"
|
|
|
|
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/agent"
|
|
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/config"
|
|
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/model"
|
|
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/system"
|
|
)
|
|
|
|
func main() {
|
|
if err := run(); err != nil {
|
|
fmt.Fprintln(os.Stderr, "enodia-sentinel-go:", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func run() error {
|
|
once := flag.Bool("once", false, "emit one sweep and exit")
|
|
configPath := flag.String("config", "", "Sentinel TOML path (default: ENODIA_CONFIG or /etc/enodia-sentinel.toml)")
|
|
procRoot := flag.String("proc-root", "/proc", "procfs root")
|
|
fixture := flag.String("fixture", "", "JSON SystemState fixture (parity/testing only)")
|
|
host := flag.String("host", "", "override hostname (parity/testing only)")
|
|
timestamp := flag.String("timestamp", "", "override RFC3339 timestamp (parity/testing only)")
|
|
flag.Parse()
|
|
|
|
cfg, err := config.Load(*configPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
capture := func() (model.State, error) { return system.Capture(*procRoot) }
|
|
if *fixture != "" {
|
|
capture = func() (model.State, error) {
|
|
var state model.State
|
|
raw, err := os.ReadFile(*fixture)
|
|
if err != nil {
|
|
return state, err
|
|
}
|
|
err = json.Unmarshal(raw, &state)
|
|
return state, err
|
|
}
|
|
}
|
|
|
|
runner := agent.New(cfg, capture)
|
|
if *host != "" {
|
|
runner.Host = func() (string, error) { return *host, nil }
|
|
}
|
|
if *timestamp != "" {
|
|
fixed, err := time.Parse(time.RFC3339Nano, *timestamp)
|
|
if err != nil {
|
|
return fmt.Errorf("timestamp: %w", err)
|
|
}
|
|
runner.Now = func() time.Time { return fixed }
|
|
}
|
|
|
|
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
|
defer stop()
|
|
encoder := json.NewEncoder(os.Stdout)
|
|
encoder.SetEscapeHTML(false)
|
|
return runner.Run(ctx, *once, func(event map[string]any) error {
|
|
return encoder.Encode(event)
|
|
})
|
|
}
|