func NewRemote(machine string) (*Remote, error) { log := logging.NewLogger("fusetest") opts := sshCmd.SSHCommandOpts{Ask: true} s, err := sshCmd.NewSSHCommand(log, opts) if err != nil { return nil, err } info, err := getMachineInfo(s, machine) if err != nil { return nil, err } if len(info.Mounts) == 0 { return nil, errors.New("Machine has no mount. Please mount and try again.") } conn, err := dialSSH(s.PrivateKeyPath(), info.Hostname, info.IP) if err != nil { return nil, err } return &Remote{ SSHConn: conn, remote: info.Mounts[0].RemotePath, local: info.Mounts[0].LocalPath, }, nil }
// SSHCommandFactory is the factory method for SSHCommand. func SSHCommandFactory(c *cli.Context, log logging.Logger, _ string) int { if len(c.Args()) != 1 { cli.ShowCommandHelp(c, "ssh") return 1 } if c.Bool("debug") { log.SetLevel(logging.DEBUG) } opts := ssh.SSHCommandOpts{ Debug: c.Bool("debug") || config.Konfig.Debug, RemoteUsername: c.String("username"), Ask: true, } cmd, err := ssh.NewSSHCommand(log, opts) mountName := c.Args()[0] // TODO: Refactor SSHCommand instance to require no initialization, // and thus avoid needing to log an error in a weird place. if err != nil { log.Error("Error initializing ssh: %s", err) switch err { case ssh.ErrLocalDialingFailed: fmt.Println( defaultHealthChecker.CheckAllFailureOrMessagef(KlientIsntRunning), ) default: fmt.Println(GenericInternalError) } metrics.TrackSSHFailed(mountName, err.Error(), config.VersionNum()) return 1 } now := time.Now() // track metrics go func() { metrics.TrackSSH(mountName, config.VersionNum()) }() err = cmd.Run(mountName) switch err { case nil: metrics.TrackSSHEnd(mountName, "", -now.Sub(now).Minutes(), config.VersionNum()) return 0 case ssh.ErrMachineNotFound: fmt.Println(MachineNotFound) case ssh.ErrCannotFindUser: fmt.Println(CannotFindSSHUser) metrics.TrackSSHFailed(mountName, err.Error(), config.VersionNum()) case ssh.ErrFailedToGetSSHKey: fmt.Println(FailedGetSSHKey) metrics.TrackSSHFailed(mountName, err.Error(), config.VersionNum()) case ssh.ErrMachineNotValidYet: fmt.Println(defaultHealthChecker.CheckAllFailureOrMessagef(MachineNotValidYet)) metrics.TrackSSHFailed(mountName, err.Error(), config.VersionNum()) case ssh.ErrRemoteDialingFailed: fmt.Println(defaultHealthChecker.CheckAllFailureOrMessagef(FailedDialingRemote)) metrics.TrackSSHFailed(mountName, err.Error(), config.VersionNum()) case shortcut.ErrMachineNotFound: fmt.Println(MachineNotFound) metrics.TrackSSHFailed(mountName, err.Error(), config.VersionNum()) } log.Error("SSHCommand.Run returned err:%s", err) // ssh returns `exit status 255` on disconnection; so we also send how long // session has been running for to indicate if ssh was successful at least // once and the failed due to disconnection metrics.TrackSSHEnd(mountName, err.Error(), -now.Sub(now).Minutes(), config.VersionNum()) return 1 }