func (c *MountCommand) mountFolder(r req.MountFolder) error { warning, err := c.Klient.RemoteMountFolder(r) if err != nil { switch { case klientctlerrors.IsExistingMountErr(err): util.MustConfirm("This folder is already mounted. Remount? [Y|n]") // unmount using mount path // // TODO: Fix abstraction leak. if err := unmount(c.Klient.GetClient(), r.Name, r.LocalPath, c.Log); err != nil { c.printfln(defaultHealthChecker.CheckAllFailureOrMessagef(FailedToUnmount)) return fmt.Errorf("Error unmounting (remounting). err:%s", err) } warning, err = c.Klient.RemoteMountFolder(r) if err != nil { c.printfln(defaultHealthChecker.CheckAllFailureOrMessagef(FailedToMount)) return fmt.Errorf("Error mounting (remounting). err:%s", err) } case klientctlerrors.IsDialFailedErr(err): c.printfln(defaultHealthChecker.CheckAllFailureOrMessagef(FailedDialingRemote)) return fmt.Errorf("Error dialing remote klient. err:%s", err) case klientctlerrors.IsMachineNotValidYetErr(err): c.printfln(defaultHealthChecker.CheckAllFailureOrMessagef(MachineNotValidYet)) return fmt.Errorf("Machine is not valid yet. err:%s", err) case klientctlerrors.IsRemotePathNotExistErr(err): c.printfln(RemotePathDoesNotExist) return fmt.Errorf("Remote path does not exist. err:%s", err) case klientctlerrors.IsMachineActionLockedErr(err): c.printfln(MachineMountActionIsLocked, r.Name) return fmt.Errorf("Machine is locked. err:%s", err) default: // catch any remaining errors c.printfln(defaultHealthChecker.CheckAllFailureOrMessagef(FailedToMount)) return fmt.Errorf("Error mounting directory. err:%s", err) } } // TODO: Remove this check? The above switch has a default case, this is useless, // right? // // catch errors other than klientctlerrors.IsExistingMountErr if err != nil { c.printfln(defaultHealthChecker.CheckAllFailureOrMessagef(FailedToMount)) return fmt.Errorf("Error mounting directory. err:%s", err) } if warning != "" { c.printfln("Warning: %s\n", warning) } return nil }
func (s *SSHCommand) Run(machine string) error { if !s.KeysExist() && s.Ask { util.MustConfirm("'ssh' command needs to create public/private rsa key pair. Continue? [Y|n]") } machine, err := shortcut.NewMachineShortcut(s.Klient).GetNameFromShortcut(machine) if err != nil { return err } userhost, port, err := s.GetSSHAddr(machine) if err != nil { return err } if err := s.PrepareForSSH(machine); err != nil { s.Log.Debug("PrepareForSSH returned err: %s", err) if strings.Contains(err.Error(), "user: unknown user") { return ErrCannotFindUser } // TODO: We're unable to log the meaningful error returned from klient, so we're // leaking possibly meaningful data here. This will be resolved once SSH gets // updated to the new (final) format. Fix this. if klientctlerrors.IsMachineNotValidYetErr(err) { return ErrMachineNotValidYet } if klientctlerrors.IsDialFailedErr(err) { return ErrRemoteDialingFailed } return ErrFailedToGetSSHKey } args := []string{ "-i", s.PrivateKeyPath(), "-o", "ServerAliveInterval=300", "-o", "ServerAliveCountMax=3", "-o", "ConnectTimeout=7", "-o", "ConnectionAttempts=1", userhost, } if port != "" { args = append(args, "-p", port) } s.Log.Debug("SSHing with command: ssh %s", strings.Join(args, " ")) cmd := exec.Command("ssh", args...) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() }