Esempio n. 1
0
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
}
Esempio n. 2
0
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()
}