-
Notifications
You must be signed in to change notification settings - Fork 228
Conversation
tracking issue: #142 |
This looks very useful Ben 👍 Out of interest, is it required for KinD to work? |
|
||
func newSSHConfig(publicKey ssh.Signer, timeout uint32) *ssh.ClientConfig { | ||
return &ssh.ClientConfig{ | ||
User: "root", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a scenario where root
may not be the user wanted for ssh - VMs with "disable root login"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so, but for the moment this matches ignite ssh
which also assumes the user is root
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The disable root login option default in most distributions prevents password-based authentication, but SSH keys should work just fine. We should also open an issue about allowing user selection in ssh
and exec
.
} | ||
|
||
// joinShellCommand joins command parts into a single string safe for passing to sh -c (or SSH) | ||
func joinShellCommand(command []string) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kind requires some way to execute commands, we could implement this in kind some other way (driving SSH? Implementing this logic there?), but I think it's more generally useful to have this in ignite. One other note vs We could implement this but I think we'd need our own flag processing step, I don't think pflag / cobra alone can support this |
cmd/ignite/run/exec.go
Outdated
return joined | ||
} | ||
for _, arg := range command[1:] { | ||
// NOTE: we need to escape nested single quotes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slightly stale comment from before using the shellescape package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can go ahead and remove the comment then 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated to a less stale comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work, thanks!
Some nits, after those are fixed, let's go ahead and merge 👍
Remember to run make tidy
again to update the doc descriptions after editing them.
cmd/ignite/cmd/vmcmd/exec.go
Outdated
"github.com/weaveworks/ignite/pkg/errutils" | ||
) | ||
|
||
// NewCmdExec exec's into a running vm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vm -> VM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
cmd/ignite/cmd/vmcmd/exec.go
Outdated
|
||
cmd := &cobra.Command{ | ||
Use: "exec <vm> <command...>", | ||
Short: "exec command in a running vm", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"execute a command in a running VM"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
cmd/ignite/cmd/vmcmd/exec.go
Outdated
Use: "exec <vm> <command...>", | ||
Short: "exec command in a running vm", | ||
Long: dedent.Dedent(` | ||
exec command in a running VM using ssh and the private key created for it during generation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Execute a command...
ssh -> SSH
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
} | ||
|
||
func addExecFlags(fs *pflag.FlagSet, ef *run.ExecFlags) { | ||
fs.StringVarP(&ef.IdentityFile, "identity", "i", "", "Override the vm's default identity file") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vm -> VM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this matches the ssh command's flags exactly at the moment, should we update it there too?
cmd/ignite/run/exec.go
Outdated
api "github.com/weaveworks/ignite/pkg/apis/ignite" | ||
"github.com/weaveworks/ignite/pkg/constants" | ||
"github.com/weaveworks/ignite/pkg/util" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this blank line and run make tidy
again 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
cmd/ignite/run/exec.go
Outdated
// TODO: we should probably configure the terminal modes | ||
modes := ssh.TerminalModes{} | ||
if err := session.RequestPty("xterm", 80, 40, modes); err != nil { | ||
return fmt.Errorf("request for psuedo terminal failed: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
psuedo -> pseudo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
// TODO: should we request something other than xterm? | ||
// TODO: we should probably configure the terminal modes | ||
modes := ssh.TerminalModes{} | ||
if err := session.RequestPty("xterm", 80, 40, modes); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Defaulting to xterm
is fine for now, we could later also allow changing this via a flag. Anyways this is non-blocking for this initial implementation.
cmd/ignite/run/exec.go
Outdated
go io.Copy(os.Stderr, stderr) | ||
stdout, err := session.StdoutPipe() | ||
if err != nil { | ||
return fmt.Errorf("failed to connect stderr: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stderr -> stdout
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
cmd/ignite/run/exec.go
Outdated
go io.Copy(os.Stdout, stdout) | ||
stdin, err := session.StdinPipe() | ||
if err != nil { | ||
return fmt.Errorf("failed to connect stderr: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stderr -> stdin
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
cmd/ignite/run/exec.go
Outdated
return joined | ||
} | ||
for _, arg := range command[1:] { | ||
// NOTE: we need to escape nested single quotes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can go ahead and remove the comment then 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addressed comments
cmd/ignite/cmd/vmcmd/exec.go
Outdated
"github.com/weaveworks/ignite/pkg/errutils" | ||
) | ||
|
||
// NewCmdExec exec's into a running vm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
cmd/ignite/cmd/vmcmd/exec.go
Outdated
|
||
cmd := &cobra.Command{ | ||
Use: "exec <vm> <command...>", | ||
Short: "exec command in a running vm", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
cmd/ignite/cmd/vmcmd/exec.go
Outdated
Use: "exec <vm> <command...>", | ||
Short: "exec command in a running vm", | ||
Long: dedent.Dedent(` | ||
exec command in a running VM using ssh and the private key created for it during generation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
cmd/ignite/run/exec.go
Outdated
api "github.com/weaveworks/ignite/pkg/apis/ignite" | ||
"github.com/weaveworks/ignite/pkg/constants" | ||
"github.com/weaveworks/ignite/pkg/util" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
ExecFlags: ef, | ||
command: command, | ||
} | ||
eo.vm, err = getVMForMatch(vmMatch) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
cmd/ignite/run/exec.go
Outdated
return fmt.Errorf("failed to dial: %v", err) | ||
} | ||
|
||
// run the command, DO NOT wrap this error as the caller can check for the command exit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
cmd/ignite/run/exec.go
Outdated
// TODO: we should probably configure the terminal modes | ||
modes := ssh.TerminalModes{} | ||
if err := session.RequestPty("xterm", 80, 40, modes); err != nil { | ||
return fmt.Errorf("request for psuedo terminal failed: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
cmd/ignite/run/exec.go
Outdated
go io.Copy(os.Stderr, stderr) | ||
stdout, err := session.StdoutPipe() | ||
if err != nil { | ||
return fmt.Errorf("failed to connect stderr: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
cmd/ignite/run/exec.go
Outdated
go io.Copy(os.Stdout, stdout) | ||
stdin, err := session.StdinPipe() | ||
if err != nil { | ||
return fmt.Errorf("failed to connect stderr: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
cmd/ignite/run/exec.go
Outdated
return joined | ||
} | ||
for _, arg := range command[1:] { | ||
// NOTE: we need to escape nested single quotes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated to a less stale comment
rebased |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks A LOT @BenTheElder ✨! This looks wonderful :)
LGTM
We can follow-up the possible improvements here in an other issue later, but for now, merging this to get us started. Next, integrate with kind 😉 |
This is a pretty simple / MVP implementation, however it is enough to perform basic exec (over ssh) against a running ignite VM.
TODO:
docker exec
options? though-i
already conflicts ...)ignite ssh
to use the same packagesHow this works:
args[1:]
are converted toargs[1] + strings.Join(shellEscape(args[2:...], " ")
and run that way (pseudo code)Additionally, the exit code from the command is preserved if possible.
Fixes #65