mirror of
https://github.com/podman-container-tools/podman.git
synced 2026-08-07 01:15:44 +00:00
allow users to specify what username to use when ssh-ing into the vm. If the username flag is set, the username will be the flag value. If the flag is not set and the the vm name is specified, the default user of the vm will be used. if the flag is not set, and the vm name is not specified, then the username of the default connection will be used. Signed-off-by: Ashley Cui <acui@redhat.com>
116 lines
2.5 KiB
Go
116 lines
2.5 KiB
Go
// +build amd64,!windows arm64,!windows
|
|
|
|
package machine
|
|
|
|
import (
|
|
"net/url"
|
|
|
|
"github.com/containers/common/pkg/completion"
|
|
"github.com/containers/common/pkg/config"
|
|
"github.com/containers/podman/v3/cmd/podman/registry"
|
|
"github.com/containers/podman/v3/pkg/machine"
|
|
"github.com/containers/podman/v3/pkg/machine/qemu"
|
|
"github.com/pkg/errors"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var (
|
|
sshCmd = &cobra.Command{
|
|
Use: "ssh [options] [NAME] [COMMAND [ARG ...]]",
|
|
Short: "SSH into an existing machine",
|
|
Long: "SSH into a managed virtual machine ",
|
|
RunE: ssh,
|
|
Example: `podman machine ssh myvm
|
|
podman machine ssh myvm echo hello`,
|
|
ValidArgsFunction: autocompleteMachineSSH,
|
|
}
|
|
)
|
|
|
|
var (
|
|
sshOpts machine.SSHOptions
|
|
)
|
|
|
|
func init() {
|
|
sshCmd.Flags().SetInterspersed(false)
|
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
|
Command: sshCmd,
|
|
Parent: machineCmd,
|
|
})
|
|
flags := sshCmd.Flags()
|
|
usernameFlagName := "username"
|
|
flags.StringVar(&sshOpts.Username, usernameFlagName, "", "Username to use when ssh-ing into the VM.")
|
|
_ = sshCmd.RegisterFlagCompletionFunc(usernameFlagName, completion.AutocompleteNone)
|
|
}
|
|
|
|
func ssh(cmd *cobra.Command, args []string) error {
|
|
var (
|
|
err error
|
|
validVM bool
|
|
vm machine.VM
|
|
vmType string
|
|
)
|
|
|
|
// Set the VM to default
|
|
vmName := defaultMachineName
|
|
|
|
// If len is greater than 0, it means we may have been
|
|
// provided the VM name. If so, we check. The VM name,
|
|
// if provided, must be in args[0].
|
|
if len(args) > 0 {
|
|
switch vmType {
|
|
default:
|
|
validVM, err = qemu.IsValidVMName(args[0])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if validVM {
|
|
vmName = args[0]
|
|
} else {
|
|
sshOpts.Args = append(sshOpts.Args, args[0])
|
|
}
|
|
}
|
|
}
|
|
|
|
// If len is greater than 1, it means we might have been
|
|
// given a vmname and args or just args
|
|
if len(args) > 1 {
|
|
if validVM {
|
|
sshOpts.Args = args[1:]
|
|
} else {
|
|
sshOpts.Args = args
|
|
}
|
|
}
|
|
|
|
if !validVM && sshOpts.Username == "" {
|
|
sshOpts.Username, err = remoteConnectionUsername()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
switch vmType {
|
|
default:
|
|
vm, err = qemu.LoadVMByName(vmName)
|
|
}
|
|
if err != nil {
|
|
return errors.Wrapf(err, "vm %s not found", vmName)
|
|
}
|
|
return vm.SSH(vmName, sshOpts)
|
|
}
|
|
|
|
func remoteConnectionUsername() (string, error) {
|
|
cfg, err := config.ReadCustomConfig()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
dest, _, err := cfg.ActiveDestination()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
uri, err := url.Parse(dest)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
username := uri.User.String()
|
|
return username, nil
|
|
}
|