helmd hub: central server på Pi5 + agent-uplink + helmd ctl + web-login
Hub-läge i samma binär (doc/hub-plan.md): agenter ansluter utåt med delad agent-nyckel (hub-sektion i config.json), web-/CLI-klienter loggar in (lokala konton, pbkdf2; Authenticator-interface för LDAP senare) och styr alla agenters sessioner via proxy + merged SSE. Webbklienten autodetekterar hub/local via /api/mode. Nya kommandon: helmd hub [setpass|users|agentkey], helmd ctl (login/agents/sessions/ prompt/screen/answer/events …). Enhetstester + scripts/run-hub-smoke.sh (15-stegs e2e: hub + agent + ctl). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011KikHkfCiC3yELbsMN8fT9
This commit is contained in:
@@ -18,6 +18,17 @@ type NtfyConfig struct {
|
||||
NotifyOnQuestion bool `json:"notify_on_question"`
|
||||
}
|
||||
|
||||
// HubUplink pekar ut vilken hub agenten ska ansluta till. Anslutningen
|
||||
// sker utåt (agenten ringer hubben) utan konto — hubben litar på den
|
||||
// delade agent-nyckeln (hämtas med `helmd hub agentkey` på hubben
|
||||
// eller efter inloggning i webben/CLI:n).
|
||||
type HubUplink struct {
|
||||
URL string `json:"url"` // t.ex. http://192.168.0.19:8790
|
||||
Name string `json:"name"` // agentens namn i hubben (tomt = hostname)
|
||||
Key string `json:"key"` // hubbens agent_key
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Listen string `json:"listen"`
|
||||
Token string `json:"token"`
|
||||
@@ -30,6 +41,7 @@ type Config struct {
|
||||
Cols int `json:"cols"`
|
||||
Rows int `json:"rows"`
|
||||
Ntfy NtfyConfig `json:"ntfy"`
|
||||
Hub HubUplink `json:"hub"`
|
||||
|
||||
path string
|
||||
}
|
||||
@@ -53,6 +65,11 @@ func defaultConfig() *Config {
|
||||
Enabled: true,
|
||||
NotifyOnQuestion: true,
|
||||
},
|
||||
Hub: HubUplink{
|
||||
URL: "",
|
||||
Name: hostname(),
|
||||
Enabled: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +124,14 @@ func (c *Config) Save() error {
|
||||
return os.WriteFile(c.path, append(data, '\n'), 0o600)
|
||||
}
|
||||
|
||||
func hostname() string {
|
||||
h, err := os.Hostname()
|
||||
if err != nil || h == "" {
|
||||
return "agent"
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func newToken() string {
|
||||
b := make([]byte, 24)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user