-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No support for commands with sudo #21
Comments
This because sudo asks for root password and never gets one, you can connect via root if you want to run commands with root privileges. |
It should be possible to check if the stdout response is prefixed with "[sudo] password for ". If this is recognized, the password should just be sent again. Terraform is doing it so for example. |
The problem isn't the library per se, but how sudo works. When running a command with sudo, the output returns an error about sudo needing a terminal or whatever to take the input for password. To solve this I just simply asked the user to input the password via the term package and a function I modified from SO: // Taken from here: https://stackoverflow.com/a/32768479
func credentials() (string, error) {
fmt.Print("Enter Password: ")
bytePassword, err := term.ReadPassword(int(syscall.Stdin))
if err != nil {
return "", err
}
password := string(bytePassword)
return strings.TrimSpace(password), nil
} for my commands that require sudo I just did: out, err := client.Run("echo " + password + "| sudo -S apt upgrade --assume-yes")
if err != nil {
panic(err)
}
// Get your output as []byte.
fmt.Println("Output of command: \n\n", string(out)) Haven't fully tested it, and I'm tired, but it works for my test program.
Looks a little sloppy, but it works for what I need. I do think a function to at least specify a PTY properly with stdin and stdout would be nice to have, or at least some sort of example added to handle I/O going to and from the session. EDIT: SSH by default doesn't allow root login, and it isn't recommended. Also NOPASSWD in sudoers isn't recommended either. |
I solved my use case by wrapping the client struct like this. type SudoClient struct {
*goph.Client
sudoPassword string
}
func (s *SudoClient) SetPassword(password string) {
s.sudoPassword = password
}
// RunContext runs the provided command and if a non empty password is provided it
// prefixes the command with sudo.
func (g *SudoClient) RunContext(ctx context.Context, name string) ([]byte, error) {
if g.sudoPassword != "" {
name = fmt.Sprintf(`echo %s | sudo --prompt="" -S %s`, g.sudoPassword, name)
}
return g.Client.RunContext(ctx, name)
} |
When trying to execute command with sudo, e.g.
sudo sleep 3
, I receive the error:Example code:
The text was updated successfully, but these errors were encountered: