fix agent hot-reload issue and added list agents endpoint

This commit is contained in:
yusing 2025-02-11 12:45:34 +08:00
parent 429a77de8e
commit 71619042fd
6 changed files with 47 additions and 16 deletions

View file

@ -135,7 +135,7 @@ func (cfg *AgentConfig) Start(parent task.Parent) E.Error {
cfg.name = string(name) cfg.name = string(name)
cfg.l = logging.With().Str("agent", cfg.name).Logger() cfg.l = logging.With().Str("agent", cfg.name).Logger()
logging.Info().Msgf("agent %q started", cfg.name) logging.Info().Msgf("agent %q initialized", cfg.name)
return nil return nil
} }

View file

@ -28,6 +28,7 @@ const (
ListHomepageCategories = "homepage_categories" ListHomepageCategories = "homepage_categories"
ListIcons = "icons" ListIcons = "icons"
ListTasks = "tasks" ListTasks = "tasks"
ListAgents = "agents"
) )
func List(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) { func List(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
@ -77,6 +78,8 @@ func List(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
U.RespondJSON(w, r, icons) U.RespondJSON(w, r, icons)
case ListTasks: case ListTasks:
U.RespondJSON(w, r, task.DebugTaskList()) U.RespondJSON(w, r, task.DebugTaskList())
case ListAgents:
U.RespondJSON(w, r, cfg.ListAgents())
default: default:
U.HandleErr(w, r, U.ErrInvalidKey("what"), http.StatusBadRequest) U.HandleErr(w, r, U.ErrInvalidKey("what"), http.StatusBadRequest)
} }

View file

@ -0,0 +1,38 @@
package config
import (
"errors"
"github.com/yusing/go-proxy/agent/pkg/agent"
"github.com/yusing/go-proxy/internal/utils/functional"
)
var agentPool = functional.NewMapOf[string, *agent.AgentConfig]()
func addAgent(agent *agent.AgentConfig) {
agentPool.Store(agent.Addr, agent)
}
func removeAllAgents() {
agentPool.Clear()
}
func GetAgent(addr string) (agent *agent.AgentConfig, ok bool) {
agent, ok = agentPool.Load(addr)
return
}
func (cfg *Config) GetAgent(agentDockerHost string) (*agent.AgentConfig, bool) {
if !agent.IsDockerHostAgent(agentDockerHost) {
panic(errors.New("invalid use of GetAgent with docker host: " + agentDockerHost))
}
return GetAgent(agent.GetAgentAddrFromDockerHost(agentDockerHost))
}
func (cfg *Config) ListAgents() []*agent.AgentConfig {
agents := make([]*agent.AgentConfig, 0, agentPool.Size())
agentPool.RangeAll(func(key string, value *agent.AgentConfig) {
agents = append(agents, value)
})
return agents
}

View file

@ -9,7 +9,6 @@ import (
"sync" "sync"
"time" "time"
"github.com/yusing/go-proxy/agent/pkg/agent"
"github.com/yusing/go-proxy/internal/api" "github.com/yusing/go-proxy/internal/api"
"github.com/yusing/go-proxy/internal/autocert" "github.com/yusing/go-proxy/internal/autocert"
"github.com/yusing/go-proxy/internal/common" "github.com/yusing/go-proxy/internal/common"
@ -273,27 +272,18 @@ func (cfg *Config) storeProvider(p *proxy.Provider) {
cfg.providers.Store(p.String(), p) cfg.providers.Store(p.String(), p)
} }
func (cfg *Config) GetAgent(agentDockerHost string) (*agent.AgentConfig, bool) {
if !agent.IsDockerHostAgent(agentDockerHost) {
panic(errors.New("invalid use of GetAgent with docker host: " + agentDockerHost))
}
key := "agent@" + agent.GetAgentAddrFromDockerHost(agentDockerHost)
p, ok := cfg.providers.Load(key)
if !ok {
return nil, false
}
return p.ProviderImpl.(*proxy.AgentProvider).AgentConfig, true
}
func (cfg *Config) loadRouteProviders(providers *config.Providers) E.Error { func (cfg *Config) loadRouteProviders(providers *config.Providers) E.Error {
errs := E.NewBuilder("route provider errors") errs := E.NewBuilder("route provider errors")
results := E.NewBuilder("loaded route providers") results := E.NewBuilder("loaded route providers")
removeAllAgents()
for _, agent := range providers.Agents { for _, agent := range providers.Agents {
if err := agent.Start(cfg.task); err != nil { if err := agent.Start(cfg.task); err != nil {
errs.Add(err.Subject(agent.String())) errs.Add(err.Subject(agent.String()))
continue continue
} }
addAgent(agent)
p := proxy.NewAgentProvider(agent) p := proxy.NewAgentProvider(agent)
if err := cfg.errIfExists(p); err != nil { if err := cfg.errIfExists(p); err != nil {
errs.Add(err.Subject(p.String())) errs.Add(err.Subject(p.String()))

View file

@ -42,6 +42,7 @@ type (
RouteProviderList() []string RouteProviderList() []string
Context() context.Context Context() context.Context
GetAgent(agentDockerHost string) (*agent.AgentConfig, bool) GetAgent(agentDockerHost string) (*agent.AgentConfig, bool)
ListAgents() []*agent.AgentConfig
} }
) )

View file

@ -4,7 +4,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"runtime/debug"
"sync" "sync"
"github.com/docker/cli/cli/connhelper" "github.com/docker/cli/cli/connhelper"
@ -88,7 +87,7 @@ func ConnectClient(host string) (*SharedClient, error) {
if agent.IsDockerHostAgent(host) { if agent.IsDockerHostAgent(host) {
cfg, ok := config.GetInstance().GetAgent(host) cfg, ok := config.GetInstance().GetAgent(host)
if !ok { if !ok {
return nil, fmt.Errorf("agent %q not found\n%s", host, debug.Stack()) panic(fmt.Errorf("agent %q not found", host))
} }
opt = []client.Opt{ opt = []client.Opt{
client.WithHost(agent.DockerHost), client.WithHost(agent.DockerHost),