mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-10-15 12:15:16 +00:00
feat: waiter connection manager - save/switch/delete connections, auto-apply default
This commit is contained in:
@ -17,6 +17,10 @@ func handleBuiltin(cmd string, cfg *Config, state *State, reconnect func()) bool
|
|||||||
/connect <path> switch to a different unix socket
|
/connect <path> switch to a different unix socket
|
||||||
/remote <url> switch to remote HTTP mode
|
/remote <url> switch to remote HTTP mode
|
||||||
/local switch back to local socket mode
|
/local switch back to local socket mode
|
||||||
|
/conn list list saved connections
|
||||||
|
/conn save <name> save current connection as <name>
|
||||||
|
/conn use <name> switch to saved connection
|
||||||
|
/conn del <name> delete saved connection
|
||||||
|
|
||||||
Server commands (sent to agent):
|
Server commands (sent to agent):
|
||||||
/status system status
|
/status system status
|
||||||
@ -66,6 +70,48 @@ Any other text is sent to the agent directly.`)
|
|||||||
reconnect()
|
reconnect()
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
case cmd == "/conn list":
|
||||||
|
if len(cfg.Connections) == 0 {
|
||||||
|
fmt.Println("no saved connections")
|
||||||
|
}
|
||||||
|
for _, c := range cfg.Connections {
|
||||||
|
mark := " "
|
||||||
|
if c.Name == cfg.Default {
|
||||||
|
mark = "*"
|
||||||
|
}
|
||||||
|
addr := c.Remote
|
||||||
|
if addr == "" {
|
||||||
|
addr = c.Socket
|
||||||
|
}
|
||||||
|
fmt.Printf(" %s %-15s %s\n", mark, c.Name, addr)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
|
||||||
|
case strings.HasPrefix(cmd, "/conn save "):
|
||||||
|
name := strings.TrimSpace(cmd[11:])
|
||||||
|
cfg.SaveConnection(name)
|
||||||
|
fmt.Printf("connection saved as '%s' (default)\n", name)
|
||||||
|
return true
|
||||||
|
|
||||||
|
case strings.HasPrefix(cmd, "/conn use "):
|
||||||
|
name := strings.TrimSpace(cmd[10:])
|
||||||
|
if cfg.SwitchConnection(name) {
|
||||||
|
fmt.Printf("switched to '%s'\n", name)
|
||||||
|
reconnect()
|
||||||
|
} else {
|
||||||
|
fmt.Printf("connection '%s' not found\n", name)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
|
||||||
|
case strings.HasPrefix(cmd, "/conn del "):
|
||||||
|
name := strings.TrimSpace(cmd[10:])
|
||||||
|
if cfg.DeleteConnection(name) {
|
||||||
|
fmt.Printf("connection '%s' deleted\n", name)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("connection '%s' not found\n", name)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
|
||||||
case cmd == "/status":
|
case cmd == "/status":
|
||||||
if rc := state.RemoteConn(); rc != nil {
|
if rc := state.RemoteConn(); rc != nil {
|
||||||
d, _ := rc.DoAPI("GET", "/api/v1/status", "")
|
d, _ := rc.DoAPI("GET", "/api/v1/status", "")
|
||||||
|
|||||||
@ -8,10 +8,40 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Connection struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
Socket string `yaml:"socket,omitempty"`
|
||||||
|
Remote string `yaml:"remote,omitempty"`
|
||||||
|
APIKey string `yaml:"api_key,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Socket string `yaml:"socket"`
|
Socket string `yaml:"socket"`
|
||||||
Remote string `yaml:"remote"`
|
Remote string `yaml:"remote"`
|
||||||
APIKey string `yaml:"api_key"`
|
APIKey string `yaml:"api_key"`
|
||||||
|
Default string `yaml:"default"`
|
||||||
|
Connections []Connection `yaml:"connections,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) Active() *Connection {
|
||||||
|
for i := range c.Connections {
|
||||||
|
if c.Connections[i].Name == c.Default {
|
||||||
|
return &c.Connections[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) ApplyDefault() {
|
||||||
|
conn := c.Active()
|
||||||
|
if conn == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if c.Socket == "" && c.Remote == "" {
|
||||||
|
c.Socket = conn.Socket
|
||||||
|
c.Remote = conn.Remote
|
||||||
|
c.APIKey = conn.APIKey
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func discoverConfig(configPath string) *Config {
|
func discoverConfig(configPath string) *Config {
|
||||||
@ -48,6 +78,14 @@ func configCandidates() []string {
|
|||||||
return cands
|
return cands
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func configPath() string {
|
||||||
|
home, _ := os.UserHomeDir()
|
||||||
|
if home == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return filepath.Join(home, ".config", "homeagent", "waiter.yaml")
|
||||||
|
}
|
||||||
|
|
||||||
func readFile(path string) *Config {
|
func readFile(path string) *Config {
|
||||||
data, err := os.ReadFile(path)
|
data, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -61,6 +99,19 @@ func readFile(path string) *Config {
|
|||||||
return &cfg
|
return &cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Config) Save() {
|
||||||
|
p := configPath()
|
||||||
|
if p == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
os.MkdirAll(filepath.Dir(p), 0755)
|
||||||
|
data, err := yaml.Marshal(c)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
os.WriteFile(p, data, 0644)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Config) MergeCLI(socket, remote, apiKey string) {
|
func (c *Config) MergeCLI(socket, remote, apiKey string) {
|
||||||
if socket != "" {
|
if socket != "" {
|
||||||
c.Socket = socket
|
c.Socket = socket
|
||||||
@ -72,3 +123,51 @@ func (c *Config) MergeCLI(socket, remote, apiKey string) {
|
|||||||
c.APIKey = apiKey
|
c.APIKey = apiKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Config) SaveConnection(name string) {
|
||||||
|
conn := Connection{
|
||||||
|
Name: name,
|
||||||
|
Socket: c.Socket,
|
||||||
|
Remote: c.Remote,
|
||||||
|
APIKey: c.APIKey,
|
||||||
|
}
|
||||||
|
for i, existing := range c.Connections {
|
||||||
|
if existing.Name == name {
|
||||||
|
c.Connections[i] = conn
|
||||||
|
c.Default = name
|
||||||
|
c.Save()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.Connections = append(c.Connections, conn)
|
||||||
|
c.Default = name
|
||||||
|
c.Save()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) SwitchConnection(name string) bool {
|
||||||
|
for _, conn := range c.Connections {
|
||||||
|
if conn.Name == name {
|
||||||
|
c.Socket = conn.Socket
|
||||||
|
c.Remote = conn.Remote
|
||||||
|
c.APIKey = conn.APIKey
|
||||||
|
c.Default = name
|
||||||
|
c.Save()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) DeleteConnection(name string) bool {
|
||||||
|
for i, conn := range c.Connections {
|
||||||
|
if conn.Name == name {
|
||||||
|
c.Connections = append(c.Connections[:i], c.Connections[i+1:]...)
|
||||||
|
if c.Default == name {
|
||||||
|
c.Default = ""
|
||||||
|
}
|
||||||
|
c.Save()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
@ -86,6 +86,7 @@ func main() {
|
|||||||
|
|
||||||
cfg := discoverConfig(*configPath)
|
cfg := discoverConfig(*configPath)
|
||||||
cfg.MergeCLI(*socket, *remote, *apiKey)
|
cfg.MergeCLI(*socket, *remote, *apiKey)
|
||||||
|
cfg.ApplyDefault()
|
||||||
|
|
||||||
if cfg.Socket == "" && cfg.Remote == "" {
|
if cfg.Socket == "" && cfg.Remote == "" {
|
||||||
cfg.Socket = discoverSocket("")
|
cfg.Socket = discoverSocket("")
|
||||||
|
|||||||
Reference in New Issue
Block a user