// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: MIT //go:build windows package common import ( "fmt" "log" "os/exec" "path/filepath" "strings" ) const ( ConfigOutputPath = "C:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\amazon-cloudwatch-agent.json" AgentLogFile = "C:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\Logs\\amazon-cloudwatch-agent.log" ) func CopyFile(pathIn string, pathOut string) error { ps, err := exec.LookPath("powershell.exe") if err != nil { return err } log.Printf("Copy File %s to %s", pathIn, pathOut) pathInAbs, err := filepath.Abs(pathIn) if err != nil { return err } log.Printf("File %s abs path %s", pathIn, pathInAbs) params := append([]string{"-NoProfile", "-NonInteractive", "cp " + pathInAbs + " " + pathOut}) out, err := exec.Command(ps, params...).Output() if err != nil { log.Printf("Copy file failed: %v; the output is: %s", err, string(out)) return err } log.Printf("File : %s copied to : %s", pathIn, pathOut) return nil } func StartAgentWithMultiConfig(configOutputPath string, fatalOnFailure bool, ssm bool) error { ps, err := exec.LookPath("powershell.exe") if err != nil { return err } params := append([]string{"-NoProfile", "-NonInteractive", "-NoExit", "& \"C:\\Program Files\\Amazon\\AmazonCloudWatchAgent\\amazon-cloudwatch-agent-ctl.ps1\" -a append-config -m ec2 -s -c file:" + configOutputPath}) out, err := exec.Command(ps, params...).Output() if err != nil && fatalOnFailure { log.Printf("Start agent failed: %v; the output is: %s", err, string(out)) return err } else if err != nil { log.Printf(fmt.Sprint(err) + string(out)) } else { log.Printf("Agent has started") } return err } func StartAgent(configOutputPath string, fatalOnFailure bool, ssm bool) error { // @TODO add ssm functionality ps, err := exec.LookPath("powershell.exe") if err != nil { return err } params := append([]string{"-NoProfile", "-NonInteractive", "& \"C:\\Program Files\\Amazon\\AmazonCloudWatchAgent\\amazon-cloudwatch-agent-ctl.ps1\" -a fetch-config -m ec2 -s -c file:" + configOutputPath}) out, err := exec.Command(ps, params...).Output() if err != nil && fatalOnFailure { log.Printf("Start agent failed: %v; the output is: %s", err, string(out)) return err } else if err != nil { log.Printf(fmt.Sprint(err) + string(out)) } else { log.Printf("Agent has started") } return err } func StopAgent() error { ps, err := exec.LookPath("powershell.exe") if err != nil { return err } params := append([]string{"-NoProfile", "-NonInteractive", "& \"C:\\Program Files\\Amazon\\AmazonCloudWatchAgent\\amazon-cloudwatch-agent-ctl.ps1\" -a stop"}) out, err := exec.Command(ps, params...).Output() if err != nil { log.Printf("Stop agent failed: %v; the output is: %s", err, string(out)) return err } log.Printf("Agent is stopped") return nil } func RunShellScript(path string, args ...string) (string, error) { ps, err := exec.LookPath("powershell.exe") if err != nil { return "", err } shellArgs := []string{"-NoProfile", "-NonInteractive", "-NoExit"} if !strings.HasSuffix(path, ".ps1") { shellArgs = append(shellArgs, "-Command") } shellArgs = append(shellArgs, path) shellArgs = append(shellArgs, args...) log.Printf("running %v", shellArgs) out, err := exec.Command(ps, shellArgs...).Output() if err != nil { log.Printf("Error occurred when executing %s: %s | %s", path, err.Error(), string(out)) return "", err } return string(out), nil } // printOutputAndError does nothing if there was no error. // Else it prints stdout and stderr. func printOutputAndError(stdout []byte, err error) { if err == nil { return } stderr := "" ee, ok := err.(*exec.ExitError) if ok { stderr = string(ee.Stderr) } log.Printf("failed\n\tstdout:\n%s\n\tstderr:\n%s\n", string(stdout), stderr) } func RunCommand(cmd string) (string, error) { out, err := exec.Command("powershell.exe", "-NoProfile", "-NonInteractive", cmd).Output() printOutputAndError(out, err) return string(out), err } func RunCommands(commands []string) error { for _, cmd := range commands { _, err := RunCommand(cmd) if err != nil { return err } } return nil } func RunAsyncCommand(cmd string) error { log.Printf("running async cmd, %s", cmd) return exec.Command("powershell.exe", "-NoProfile", "-NonInteractive", "-NoExit", cmd).Start() }