From 35f218e40846bd675563eccf0f1d34f265db1100 Mon Sep 17 00:00:00 2001 From: Brandon Johnson Date: Tue, 6 Aug 2024 15:17:15 -0400 Subject: [PATCH] [cmd/opampsupervisor]: Write agent config and logs to storage directory (#34348) **Description:* * Writes the agent's `effective.yaml` and `agent.log` to the storage directory. **Link to tracking Issue:** Closes #34341 **Testing:** * Added an e2e test testing that the supervisor writes the files to the correct location --- ...fix_supervisor-write-files-to-storage.yaml | 13 +++++++++ cmd/opampsupervisor/e2e_test.go | 28 +++++++++++++++++++ .../supervisor/commander/commander.go | 7 +++-- cmd/opampsupervisor/supervisor/supervisor.go | 28 +++++++++++-------- 4 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 .chloggen/fix_supervisor-write-files-to-storage.yaml diff --git a/.chloggen/fix_supervisor-write-files-to-storage.yaml b/.chloggen/fix_supervisor-write-files-to-storage.yaml new file mode 100644 index 000000000000..a7cc8f5e5d3f --- /dev/null +++ b/.chloggen/fix_supervisor-write-files-to-storage.yaml @@ -0,0 +1,13 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: bug_fix + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: cmd/opampsupervisor + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Write the generated effective config and agent log files to the user-defined storage directory. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [34341] diff --git a/cmd/opampsupervisor/e2e_test.go b/cmd/opampsupervisor/e2e_test.go index 39635add3e82..690298d19e8c 100644 --- a/cmd/opampsupervisor/e2e_test.go +++ b/cmd/opampsupervisor/e2e_test.go @@ -1191,6 +1191,34 @@ func TestSupervisorPersistsNewInstanceID(t *testing.T) { require.Equal(t, newID, uuid.UUID(newRecievedAgentID)) } +func TestSupervisorWritesAgentFilesToStorageDir(t *testing.T) { + // Tests that the agent logs and effective.yaml are written under the storage directory. + storageDir := t.TempDir() + + server := newOpAMPServer( + t, + defaultConnectingHandler, + server.ConnectionCallbacksStruct{}, + ) + + s := newSupervisor(t, "basic", map[string]string{ + "url": server.addr, + "storage_dir": storageDir, + }) + + waitForSupervisorConnection(server.supervisorConnected, true) + + t.Logf("Supervisor connected") + + s.Shutdown() + + t.Logf("Supervisor shutdown") + + // Check config and log files are written in storage dir + require.FileExists(t, filepath.Join(storageDir, "agent.log")) + require.FileExists(t, filepath.Join(storageDir, "effective.yaml")) +} + func findRandomPort() (int, error) { l, err := net.Listen("tcp", "localhost:0") diff --git a/cmd/opampsupervisor/supervisor/commander/commander.go b/cmd/opampsupervisor/supervisor/commander/commander.go index 8d71f7c46ce8..b4e4c74c03b2 100644 --- a/cmd/opampsupervisor/supervisor/commander/commander.go +++ b/cmd/opampsupervisor/supervisor/commander/commander.go @@ -9,6 +9,7 @@ import ( "fmt" "os" "os/exec" + "path/filepath" "sync/atomic" "syscall" "time" @@ -23,6 +24,7 @@ import ( type Commander struct { logger *zap.Logger cfg config.Agent + logsDir string args []string cmd *exec.Cmd doneCh chan struct{} @@ -30,9 +32,10 @@ type Commander struct { running *atomic.Int64 } -func NewCommander(logger *zap.Logger, cfg config.Agent, args ...string) (*Commander, error) { +func NewCommander(logger *zap.Logger, logsDir string, cfg config.Agent, args ...string) (*Commander, error) { return &Commander{ logger: logger, + logsDir: logsDir, cfg: cfg, args: args, running: &atomic.Int64{}, @@ -69,7 +72,7 @@ func (c *Commander) Start(ctx context.Context) error { c.logger.Debug("Starting agent", zap.String("agent", c.cfg.Executable)) - logFilePath := "agent.log" + logFilePath := filepath.Join(c.logsDir, "agent.log") logFile, err := os.Create(logFilePath) if err != nil { return fmt.Errorf("cannot create %s: %w", logFilePath, err) diff --git a/cmd/opampsupervisor/supervisor/supervisor.go b/cmd/opampsupervisor/supervisor/supervisor.go index 0f6cbcf6b740..b5a8eb70da10 100644 --- a/cmd/opampsupervisor/supervisor/supervisor.go +++ b/cmd/opampsupervisor/supervisor/supervisor.go @@ -60,8 +60,8 @@ var ( ) const ( - persistentStateFilePath = "persistent_state.yaml" - agentConfigFilePath = "effective.yaml" + persistentStateFileName = "persistent_state.yaml" + agentConfigFileName = "effective.yaml" ) const maxBufferedCustomMessages = 10 @@ -166,7 +166,7 @@ func NewSupervisor(logger *zap.Logger, configFile string) (*Supervisor, error) { } var err error - s.persistentState, err = loadOrCreatePersistentState(s.persistentStateFile()) + s.persistentState, err = loadOrCreatePersistentState(s.persistentStateFilePath()) if err != nil { return nil, err } @@ -197,8 +197,9 @@ func NewSupervisor(logger *zap.Logger, configFile string) (*Supervisor, error) { s.commander, err = commander.NewCommander( s.logger, + s.config.Storage.Directory, s.config.Agent, - "--config", agentConfigFilePath, + "--config", s.agentConfigFilePath(), ) if err != nil { return nil, err @@ -278,7 +279,7 @@ func (s *Supervisor) getBootstrapInfo() (err error) { return err } - err = os.WriteFile(agentConfigFilePath, bootstrapConfig, 0600) + err = os.WriteFile(s.agentConfigFilePath(), bootstrapConfig, 0600) if err != nil { return fmt.Errorf("failed to write agent config: %w", err) } @@ -338,8 +339,9 @@ func (s *Supervisor) getBootstrapInfo() (err error) { cmd, err := commander.NewCommander( s.logger, + s.config.Storage.Directory, s.config.Agent, - "--config", agentConfigFilePath, + "--config", s.agentConfigFilePath(), ) if err != nil { return err @@ -801,7 +803,7 @@ func (s *Supervisor) loadAndWriteInitialMergedConfig() error { // write the initial merged config to disk cfg := s.mergedConfig.Load().(string) - if err := os.WriteFile(agentConfigFilePath, []byte(cfg), 0600); err != nil { + if err := os.WriteFile(s.agentConfigFilePath(), []byte(cfg), 0600); err != nil { s.logger.Error("Failed to write agent config.", zap.Error(err)) } @@ -1046,7 +1048,7 @@ func (s *Supervisor) healthCheck() { } func (s *Supervisor) runAgentProcess() { - if _, err := os.Stat(agentConfigFilePath); err == nil { + if _, err := os.Stat(s.agentConfigFilePath()); err == nil { // We have an effective config file saved previously. Use it to start the agent. s.logger.Debug("Effective config found, starting agent initial time") s.startAgent() @@ -1118,7 +1120,7 @@ func (s *Supervisor) stopAgentApplyConfig() { s.logger.Error("Could not stop agent process", zap.Error(err)) } - if err := os.WriteFile(agentConfigFilePath, []byte(cfg), 0600); err != nil { + if err := os.WriteFile(s.agentConfigFilePath(), []byte(cfg), 0600); err != nil { s.logger.Error("Failed to write agent config.", zap.Error(err)) } } @@ -1309,8 +1311,12 @@ func (s *Supervisor) processAgentIdentificationMessage(msg *protobufs.AgentIdent return true } -func (s *Supervisor) persistentStateFile() string { - return filepath.Join(s.config.Storage.Directory, persistentStateFilePath) +func (s *Supervisor) persistentStateFilePath() string { + return filepath.Join(s.config.Storage.Directory, persistentStateFileName) +} + +func (s *Supervisor) agentConfigFilePath() string { + return filepath.Join(s.config.Storage.Directory, agentConfigFileName) } func (s *Supervisor) findRandomPort() (int, error) {