From 25afa4b9d01fff32d30efd79cebc80f8ce0fe6e7 Mon Sep 17 00:00:00 2001 From: Prithak Sharma Date: Mon, 4 Mar 2024 09:59:46 +0000 Subject: [PATCH] feat: separate logs to STDOUT & STDERR Allows, runner to log output and errors to different io.Writers --- cmd/container/main.go | 9 ++++++--- core/tools/ansible.go | 8 +++++--- core/tools/packer.go | 7 ++++--- core/tools/runner.go | 7 ++++--- core/tools/terraform.go | 15 ++++++++++----- 5 files changed, 29 insertions(+), 17 deletions(-) diff --git a/cmd/container/main.go b/cmd/container/main.go index 8a546836..78f276b6 100644 --- a/cmd/container/main.go +++ b/cmd/container/main.go @@ -29,12 +29,14 @@ func main() { amiBuilder := tools.Packer{ WorkingDir: packerDir, - Output: os.Stdout, + StdOut: os.Stdout, + StdErr: os.Stderr, } infraManager := tools.Terraform{ WorkingDir: terraformWorkspaceDir, - Output: os.Stdout, + StdOut: os.Stdout, + StdErr: os.Stderr, } scenarioManager := tools.AnsiblePlaybook{ @@ -43,7 +45,8 @@ func main() { // Ansible complains on Windows+WSL that the directory ansible configuration is world writable // and hence ignore the configuration unless explicitly set using the ANSIBLE_CONFIG environment variable. Env: []string{"ANSIBLE_CONFIG=" + ansibleConfigPath}, - Output: os.Stdout, + StdOut: os.Stdout, + StdErr: os.Stderr, } withStateBucketFlag := cli.WithFlag("stateBucket", "", "the name of the S3 bucket to store Terraform state") diff --git a/core/tools/ansible.go b/core/tools/ansible.go index 96f0d047..3a581b8e 100644 --- a/core/tools/ansible.go +++ b/core/tools/ansible.go @@ -22,13 +22,15 @@ type AnsiblePlaybook struct { WorkingDir string PlaybookDir string Env []string - Output io.Writer + StdOut io.Writer + StdErr io.Writer } func (p AnsiblePlaybook) Install(ctx context.Context, id string) error { playbook := fmt.Sprintf("%s.yaml", id) - if err := ansiblePlaybookCommand(p.WorkingDir, p.PlaybookDir, p.Env, playbook).Run(ctx, p.Output); err != nil { + err := ansiblePlaybookCommand(p.WorkingDir, p.PlaybookDir, p.Env, playbook).Run(ctx, p.StdOut, p.StdErr) + if err != nil { return fmt.Errorf("failed to execute Ansible Playbook: %w", err) } @@ -39,7 +41,7 @@ func (p AnsiblePlaybook) Uninstall(ctx context.Context, id string) error { playbook := fmt.Sprintf("%s.yaml", id) if err := ansiblePlaybookCommand(p.WorkingDir, p.PlaybookDir, p.Env, playbook, "state=absent"). - Run(ctx, p.Output); err != nil { + Run(ctx, p.StdOut, p.StdErr); err != nil { return fmt.Errorf("failed to run Ansible Playbook with state=absent: %w", err) } diff --git a/core/tools/packer.go b/core/tools/packer.go index 631c5cc0..193c8067 100644 --- a/core/tools/packer.go +++ b/core/tools/packer.go @@ -18,17 +18,18 @@ type AMIBuilder interface { type Packer struct { WorkingDir string - Output io.Writer + StdOut io.Writer + StdErr io.Writer } func (p Packer) Build(ctx context.Context, id string) error { template := fmt.Sprintf("%s.pkr.hcl", id) - if err := packerInitCommand(p.WorkingDir, template).Run(ctx, p.Output); err != nil { + if err := packerInitCommand(p.WorkingDir, template).Run(ctx, p.StdOut, p.StdErr); err != nil { return fmt.Errorf("failed to initialise packer: %w", err) } - if err := packerBuildCommand(p.WorkingDir, template).Run(ctx, p.Output); err != nil { + if err := packerBuildCommand(p.WorkingDir, template).Run(ctx, p.StdOut, p.StdErr); err != nil { return fmt.Errorf("failed to build ami with packer: %w", err) } diff --git a/core/tools/runner.go b/core/tools/runner.go index edc308d3..c89aac80 100644 --- a/core/tools/runner.go +++ b/core/tools/runner.go @@ -18,18 +18,19 @@ type runner struct { Arguments []string } -func (c runner) Run(ctx context.Context, output io.Writer) error { +func (c runner) Run(ctx context.Context, stdOut, stdErr io.Writer) error { slog.Info("running", "runner", c) //nolint:gosec cmd := exec.CommandContext(ctx, string(c.Executable), c.Arguments...) cmd.Dir = c.WorkingDir - cmd.Stdout = output - cmd.Stderr = output + cmd.Stdout = stdOut + cmd.Stderr = stdErr cmd.Env = c.Env err := cmd.Run() if err != nil { + slog.Error("failed to run runner", "runner", c, "error", err) return fmt.Errorf("failed to run runner: %w", err) } diff --git a/core/tools/terraform.go b/core/tools/terraform.go index e04710e1..8658456c 100644 --- a/core/tools/terraform.go +++ b/core/tools/terraform.go @@ -23,19 +23,22 @@ type InfraManager interface { type Terraform struct { WorkingDir string - Output io.Writer + StdOut io.Writer + StdErr io.Writer } func (t Terraform) Create(ctx context.Context, stateBucket string, stateKey string, name string) error { backend := backendConfig(stateBucket, stateKey) - if err := terraformInitCommand(t.WorkingDir, backend).Run(ctx, t.Output); err != nil { + err := terraformInitCommand(t.WorkingDir, backend).Run(ctx, t.StdOut, t.StdErr) + if err != nil { return fmt.Errorf("failed to initialise terraform: %w", err) } vars := terraformVars(name) - if err := terraformCommand(t.WorkingDir, TerraformApply, vars).Run(ctx, t.Output); err != nil { + err = terraformCommand(t.WorkingDir, TerraformApply, vars).Run(ctx, t.StdOut, t.StdErr) + if err != nil { return fmt.Errorf("failed to apply terraform: %w", err) } @@ -45,13 +48,15 @@ func (t Terraform) Create(ctx context.Context, stateBucket string, stateKey stri func (t Terraform) Destroy(ctx context.Context, stateBucket string, stateKey string, name string) error { backend := backendConfig(stateBucket, stateKey) - if err := terraformInitCommand(t.WorkingDir, backend).Run(ctx, t.Output); err != nil { + err := terraformInitCommand(t.WorkingDir, backend).Run(ctx, t.StdOut, t.StdErr) + if err != nil { return fmt.Errorf("failed to initialise terraform: %w", err) } vars := terraformVars(name) - if err := terraformCommand(t.WorkingDir, TerraformDestroy, vars).Run(ctx, t.Output); err != nil { + err = terraformCommand(t.WorkingDir, TerraformDestroy, vars).Run(ctx, t.StdOut, t.StdErr) + if err != nil { return fmt.Errorf("failed to destroy terraform: %w", err) }