diff --git a/agents/supervisor/supervisor.go b/agents/supervisor/supervisor.go index e9665cda7..b1903ca91 100644 --- a/agents/supervisor/supervisor.go +++ b/agents/supervisor/supervisor.go @@ -48,13 +48,14 @@ import ( // Supervisor manages all Agents, both processes and built-in. type Supervisor struct { - ctx context.Context - paths *config.Paths - serverCfg *config.Server - portsRegistry *portsRegistry - changes chan *agentpb.StateChangedRequest - qanRequests chan *agentpb.QANCollectRequest - l *logrus.Entry + ctx context.Context + paths *config.Paths + serverCfg *config.Server + exporterAddress *config.ExporterAddress + portsRegistry *portsRegistry + changes chan *agentpb.StateChangedRequest + qanRequests chan *agentpb.QANCollectRequest + l *logrus.Entry rw sync.RWMutex agentProcesses map[string]*agentProcessInfo @@ -86,15 +87,16 @@ type builtinAgentInfo struct { // Supervisor is gracefully stopped when context passed to NewSupervisor is canceled. // Changes of Agent statuses are reported via Changes() channel which must be read until it is closed. // QAN data is sent to QANRequests() channel which must be read until it is closed. -func NewSupervisor(ctx context.Context, paths *config.Paths, ports *config.Ports, server *config.Server) *Supervisor { +func NewSupervisor(ctx context.Context, paths *config.Paths, ports *config.Ports, server *config.Server, exporterAddress *config.ExporterAddress) *Supervisor { supervisor := &Supervisor{ - ctx: ctx, - paths: paths, - serverCfg: server, - portsRegistry: newPortsRegistry(ports.Min, ports.Max, nil), - changes: make(chan *agentpb.StateChangedRequest, 10), - qanRequests: make(chan *agentpb.QANCollectRequest, 10), - l: logrus.WithField("component", "supervisor"), + ctx: ctx, + paths: paths, + serverCfg: server, + exporterAddress: exporterAddress, + portsRegistry: newPortsRegistry(ports.Min, ports.Max, nil), + changes: make(chan *agentpb.StateChangedRequest, 10), + qanRequests: make(chan *agentpb.QANCollectRequest, 10), + l: logrus.WithField("component", "supervisor"), agentProcesses: make(map[string]*agentProcessInfo), builtinAgents: make(map[string]*builtinAgentInfo), @@ -498,6 +500,11 @@ func (s *Supervisor) processParams(agentID string, agentProcess *agentpb.SetStat var processParams process.Params processParams.Type = agentProcess.Type + l := logrus.WithFields(logrus.Fields{ + "component": "agent-process", + "agentID": agentID, + }) + templateParams := map[string]interface{}{ "listen_port": port, } @@ -562,6 +569,11 @@ func (s *Supervisor) processParams(agentID string, agentProcess *agentpb.SetStat return nil, err } processParams.Args[i] = string(b) + + if strings.Contains(e, "-web.listen-address=:") { + processParams.Args[i] = strings.Replace(processParams.Args[i], "=:", fmt.Sprintf("=%s:", s.exporterAddress.ListenAddress()), 1) + l.Debugf("Set --web.listen-address to %s", processParams.Args[i]) + } } processParams.Env = make([]string, len(agentProcess.Env)) diff --git a/agents/supervisor/supervisor_test.go b/agents/supervisor/supervisor_test.go index db8647b0b..66c012f59 100644 --- a/agents/supervisor/supervisor_test.go +++ b/agents/supervisor/supervisor_test.go @@ -17,6 +17,7 @@ package supervisor import ( "context" + "fmt" "os" "path/filepath" "sort" @@ -50,7 +51,8 @@ func TestSupervisor(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) tempDir, err := os.MkdirTemp("", "pmm-agent-") require.NoError(t, err) - s := NewSupervisor(ctx, &config.Paths{TempDir: tempDir}, &config.Ports{Min: 65000, Max: 65099}, &config.Server{Address: "localhost:443"}) + s := NewSupervisor(ctx, &config.Paths{TempDir: tempDir}, &config.Ports{Min: 65000, Max: 65099}, + &config.Server{Address: "localhost:443"}, &config.ExporterAddress{Default: ""}) t.Run("Start13", func(t *testing.T) { expectedList := []*agentlocalpb.AgentInfo{} @@ -284,7 +286,7 @@ func TestSupervisorProcessParams(t *testing.T) { TempDir: temp, } - s := NewSupervisor(ctx, paths, &config.Ports{}, &config.Server{}) //nolint:varnamelen + s := NewSupervisor(ctx, paths, &config.Ports{}, &config.Server{}, &config.ExporterAddress{Default: "127.0.0.1"}) //nolint:varnamelen teardown := func() { cancel() @@ -326,7 +328,7 @@ func TestSupervisorProcessParams(t *testing.T) { expected := process.Params{ Path: "/path/to/mysql_exporter", Args: []string{ - "-web.listen-address=:12345", + fmt.Sprintf("-web.listen-address=%s:12345", s.exporterAddress.ListenAddress()), "-web.ssl-cert-file=" + filepath.Join(s.paths.TempDir, "mysqld_exporter", "ID", "Cert"), }, Env: []string{ diff --git a/commands/run.go b/commands/run.go index 005abd799..de1937adb 100644 --- a/commands/run.go +++ b/commands/run.go @@ -73,7 +73,7 @@ func run(ctx context.Context, cfg *config.Config, configFilepath string) { // It should be created separately. // TODO https://jira.percona.com/browse/PMM-7206 - supervisor := supervisor.NewSupervisor(ctx, &cfg.Paths, &cfg.Ports, &cfg.Server) + supervisor := supervisor.NewSupervisor(ctx, &cfg.Paths, &cfg.Ports, &cfg.Server, &cfg.ExporterListenAddress) connectionChecker := connectionchecker.New(&cfg.Paths) v := versioner.New(&versioner.RealExecFunctions{}) client := client.New(cfg, supervisor, connectionChecker, v) diff --git a/config/config.go b/config/config.go index 3271d0e7d..ddb3d8609 100644 --- a/config/config.go +++ b/config/config.go @@ -35,6 +35,16 @@ import ( const pathBaseDefault = "/usr/local/percona/pmm2" +// ExporterAddress stores listen address values for exporters. +type ExporterAddress struct { + Default string `yaml:"default"` +} + +// ListenAddress returns the exporter listen-address. +func (e *ExporterAddress) ListenAddress() string { + return e.Default +} + // Server represents PMM Server configuration. type Server struct { Address string `yaml:"address"` @@ -143,6 +153,8 @@ type Config struct { ListenAddress string `yaml:"listen-address"` ListenPort uint16 `yaml:"listen-port"` + ExporterListenAddress ExporterAddress `yaml:"exporter-listen-address"` + Server Server `yaml:"server"` Paths Paths `yaml:"paths"` Ports Ports `yaml:"ports"` @@ -324,6 +336,8 @@ func Application(cfg *Config) (*kingpin.Application, *string) { Envar("PMM_AGENT_LISTEN_ADDRESS").StringVar(&cfg.ListenAddress) app.Flag("listen-port", "Agent local API port [PMM_AGENT_LISTEN_PORT]"). Envar("PMM_AGENT_LISTEN_PORT").Uint16Var(&cfg.ListenPort) + app.Flag("exporter-listen-address", "Exporter web interface address [PMM_AGENT_EXPORTER_LISTEN_ADDRESS]"). + Envar("PMM_AGENT_EXPORTER_LISTEN_ADDRESS").StringVar(&cfg.ExporterListenAddress.Default) app.Flag("server-address", "PMM Server address [PMM_AGENT_SERVER_ADDRESS]"). Envar("PMM_AGENT_SERVER_ADDRESS").PlaceHolder("").StringVar(&cfg.Server.Address)