diff --git a/agent/pkg/agent/config.go b/agent/pkg/agent/config.go index 23aba0c..7d149b0 100644 --- a/agent/pkg/agent/config.go +++ b/agent/pkg/agent/config.go @@ -135,7 +135,7 @@ func (cfg *AgentConfig) Start(parent task.Parent) E.Error { cfg.name = string(name) 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 } diff --git a/internal/api/v1/list.go b/internal/api/v1/list.go index 2e861c1..751f1e8 100644 --- a/internal/api/v1/list.go +++ b/internal/api/v1/list.go @@ -28,6 +28,7 @@ const ( ListHomepageCategories = "homepage_categories" ListIcons = "icons" ListTasks = "tasks" + ListAgents = "agents" ) 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) case ListTasks: U.RespondJSON(w, r, task.DebugTaskList()) + case ListAgents: + U.RespondJSON(w, r, cfg.ListAgents()) default: U.HandleErr(w, r, U.ErrInvalidKey("what"), http.StatusBadRequest) } diff --git a/internal/config/agent_pool.go b/internal/config/agent_pool.go new file mode 100644 index 0000000..7fcd407 --- /dev/null +++ b/internal/config/agent_pool.go @@ -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 +} diff --git a/internal/config/config.go b/internal/config/config.go index 8e64614..4127188 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -9,7 +9,6 @@ import ( "sync" "time" - "github.com/yusing/go-proxy/agent/pkg/agent" "github.com/yusing/go-proxy/internal/api" "github.com/yusing/go-proxy/internal/autocert" "github.com/yusing/go-proxy/internal/common" @@ -273,27 +272,18 @@ func (cfg *Config) storeProvider(p *proxy.Provider) { 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 { errs := E.NewBuilder("route provider errors") results := E.NewBuilder("loaded route providers") + removeAllAgents() + for _, agent := range providers.Agents { if err := agent.Start(cfg.task); err != nil { errs.Add(err.Subject(agent.String())) continue } + addAgent(agent) p := proxy.NewAgentProvider(agent) if err := cfg.errIfExists(p); err != nil { errs.Add(err.Subject(p.String())) diff --git a/internal/config/types/config.go b/internal/config/types/config.go index b836b5f..2e5e4fb 100644 --- a/internal/config/types/config.go +++ b/internal/config/types/config.go @@ -42,6 +42,7 @@ type ( RouteProviderList() []string Context() context.Context GetAgent(agentDockerHost string) (*agent.AgentConfig, bool) + ListAgents() []*agent.AgentConfig } ) diff --git a/internal/docker/client.go b/internal/docker/client.go index 6ff7254..3a77b58 100644 --- a/internal/docker/client.go +++ b/internal/docker/client.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "net/http" - "runtime/debug" "sync" "github.com/docker/cli/cli/connhelper" @@ -88,7 +87,7 @@ func ConnectClient(host string) (*SharedClient, error) { if agent.IsDockerHostAgent(host) { cfg, ok := config.GetInstance().GetAgent(host) 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{ client.WithHost(agent.DockerHost),