diff --git a/pkg/agent/session.go b/pkg/agent/session.go index 95ba7588df..20356bc856 100644 --- a/pkg/agent/session.go +++ b/pkg/agent/session.go @@ -201,18 +201,3 @@ func findAllSubprocesses(pid int) []int { return res } - -// TODO: add this check back - -// func isRoot() bool { -// u, err := user.Current() -// return err == nil && u.Username == "root" -// } - -// func printDarwinMessage() { -// if runtime.GOOS == "darwin" { -// if !isRoot() { -// log.Error("on macOS it is required to run the agent with sudo") -// } -// } -// } diff --git a/pkg/cli/cli_test.go b/pkg/cli/cli_test.go index da1c08da07..1e45af3869 100644 --- a/pkg/cli/cli_test.go +++ b/pkg/cli/cli_test.go @@ -18,6 +18,7 @@ type FlagsStruct struct { Foos []string Bar int Baz time.Duration + FooBar string } var _ = Describe("config package", func() { @@ -41,6 +42,7 @@ var _ = Describe("config package", func() { "-foos", "test-val-3", "-bar", "123", "-baz", "10h", + "-foo-bar", "test-val-4", }) Expect(err).ToNot(HaveOccurred()) @@ -48,6 +50,7 @@ var _ = Describe("config package", func() { Expect(cfg.Foos).To(Equal([]string{"test-val-2", "test-val-3"})) Expect(cfg.Bar).To(Equal(123)) Expect(cfg.Baz).To(Equal(10 * time.Hour)) + Expect(cfg.FooBar).To(Equal("test-val-4")) }) }) @@ -77,6 +80,7 @@ var _ = Describe("config package", func() { Expect(cfg.Foos).To(Equal([]string{"test-val-2", "test-val-3"})) Expect(cfg.Bar).To(Equal(123)) Expect(cfg.Baz).To(Equal(10 * time.Hour)) + Expect(cfg.FooBar).To(Equal("test-val-4")) }) It("arguments take precendence", func() { diff --git a/pkg/cli/example.yml b/pkg/cli/example.yml index 0757577f85..7354982df5 100644 --- a/pkg/cli/example.yml +++ b/pkg/cli/example.yml @@ -5,3 +5,4 @@ foos: - "test-val-3" bar: 123 baz: "10h" +foo-bar: "test-val-4" diff --git a/pkg/exec/cli.go b/pkg/exec/cli.go index 48289db2e2..3893cb39bf 100644 --- a/pkg/exec/cli.go +++ b/pkg/exec/cli.go @@ -6,7 +6,9 @@ import ( "os" "os/exec" "os/signal" + "os/user" "path" + "runtime" "strings" "syscall" "time" @@ -33,11 +35,12 @@ func Cli(cfg *config.Config, args []string) error { supportedSpies := supportedSpiesWithoutGospy() suggestedCommand := fmt.Sprintf("pyroscope exec -spy-name %s %s", supportedSpies[0], strings.Join(args, " ")) return fmt.Errorf( - "could not automatically find a spy for program \"%s\". Pass spy name via %s argument, for example: \n %s\n\nAvailable spies are: %s\n\nIf you believe this is a mistake, please submit an issue at %s", + "could not automatically find a spy for program \"%s\". Pass spy name via %s argument, for example: \n %s\n\nAvailable spies are: %s\n%s\nIf you believe this is a mistake, please submit an issue at %s", baseName, color.YellowString("-spy-name"), color.YellowString(suggestedCommand), strings.Join(supportedSpies, ","), + armMessage(), color.BlueString("https://github.com/pyroscope-io/pyroscope/issues"), ) } @@ -45,8 +48,8 @@ func Cli(cfg *config.Config, args []string) error { logrus.Info("to disable logging from pyroscope, pass " + color.YellowString("-no-logging") + " argument to pyroscope exec") - if spyName == "gospy" { - return fmt.Errorf("gospy can not profile other processes. See our documentation on using gospy: %s", color.BlueString("https://pyroscope.io/docs/")) + if err := performChecks(spyName); err != nil { + return err } signal.Ignore(syscall.SIGCHLD) @@ -97,3 +100,48 @@ func supportedSpiesWithoutGospy() []string { return supportedSpies } + +func performChecks(spyName string) error { + if spyName == "gospy" { + return fmt.Errorf("gospy can not profile other processes. See our documentation on using gospy: %s", color.BlueString("https://pyroscope.io/docs/")) + } + + if runtime.GOOS == "darwin" { + if !isRoot() { + logrus.Error("on macOS you're required to run the agent with sudo") + } + } + + if stringsContains(spy.SupportedSpies, spyName) { + supportedSpies := supportedSpiesWithoutGospy() + return fmt.Errorf( + "Spy \"%s\" is not supported. Available spies are: %s\n%s", + color.BlueString("spyName"), + strings.Join(supportedSpies, ","), + armMessage(), + ) + } + + return nil +} + +func stringsContains(arr []string, element string) bool { + for _, v := range arr { + if v == element { + return true + } + } + return false +} + +func isRoot() bool { + u, err := user.Current() + return err == nil && u.Username == "root" +} + +func armMessage() string { + if runtime.GOARCH == "arm64" { + return "Note that rbspy is not available on arm64 platform" + } + return "" +}