diff --git a/cmd/troubleshoot/cli/run.go b/cmd/troubleshoot/cli/run.go index eeabb6cc..dd0171c1 100644 --- a/cmd/troubleshoot/cli/run.go +++ b/cmd/troubleshoot/cli/run.go @@ -106,6 +106,23 @@ func runTroubleshoot(v *viper.Viper, args []string) error { }) } + if interactive { + c := color.New() + c.Println(fmt.Sprintf("\r%s\r", cursor.ClearEntireLine())) + } + + if interactive { + if len(mainBundle.Spec.HostCollectors) > 0 && !util.IsRunningAsRoot() { + msg := "Some host collectors may require elevated privileges to run.\nDo you want to exit and rerun the command as a privileged user?" + fmt.Print(cursor.Show()) + if util.PromptYesNo(msg) { + fmt.Println("Exiting...") + return nil + } + fmt.Print(cursor.Hide()) + } + } + var wg sync.WaitGroup collectorCB := func(c chan interface{}, msg string) { c <- msg } progressChan := make(chan interface{}) @@ -174,11 +191,6 @@ func runTroubleshoot(v *viper.Viper, args []string) error { nonInteractiveOutput := analysisOutput{} - if interactive { - c := color.New() - c.Println(fmt.Sprintf("\r%s\r", cursor.ClearEntireLine())) - } - response, err := supportbundle.CollectSupportBundleFromSpec(&mainBundle.Spec, additionalRedactors, createOpts) if err != nil { return errors.Wrap(err, "failed to run collect and analyze process") diff --git a/internal/util/util.go b/internal/util/util.go index f1cde73f..f7b416f1 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -1,9 +1,12 @@ package util import ( + "bufio" "bytes" + "fmt" "net/url" "os" + "os/user" "strings" "text/template" @@ -105,3 +108,38 @@ func RenderTemplate(tpl string, data interface{}) (string, error) { // Return the string representation of the buffer return buf.String(), nil } + +func IsRunningAsRoot() bool { + currentUser, err := user.Current() + if err != nil { + return false + } + + // Check if the user ID is 0 (root's UID) + return currentUser.Uid == "0" +} + +func PromptYesNo(question string) bool { + reader := bufio.NewReader(os.Stdin) + + for { + fmt.Printf("%s (yes/no): ", question) + + response, err := reader.ReadString('\n') + if err != nil { + fmt.Println("Error reading response:", err) + continue + } + + response = strings.TrimSpace(response) + response = strings.ToLower(response) + + if response == "yes" || response == "y" { + return true + } else if response == "no" || response == "n" { + return false + } else { + fmt.Println("Please type 'yes' or 'no'.") + } + } +} diff --git a/pkg/preflight/run.go b/pkg/preflight/run.go index 9ed3d2b9..45a75f05 100644 --- a/pkg/preflight/run.go +++ b/pkg/preflight/run.go @@ -10,6 +10,7 @@ import ( cursor "github.com/ahmetalpbalkan/go-cursor" "github.com/fatih/color" "github.com/pkg/errors" + "github.com/replicatedhq/troubleshoot/internal/util" analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/constants" @@ -46,6 +47,17 @@ func RunPreflights(interactive bool, output string, format string, args []string return types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, err) } + if interactive { + if len(specs.HostPreflightsV1Beta2) > 0 && !util.IsRunningAsRoot() { + fmt.Print(cursor.Show()) + if util.PromptYesNo("Some host collectors may require elevated privileges to run.\nDo you want to exit and rerun the command as a privileged user?") { + fmt.Println("Exiting...") + return nil + } + fmt.Print(cursor.Hide()) + } + } + warning := validatePreflight(specs) if warning != nil { fmt.Println(warning.Warning())