Example #1
0
func (c *Command) runCp() error {
	// parse the user input Source and Destination, obtaining the remote and local
	// paths, machine name, etc.
	//
	// This provides UX on error!
	machineName, localPath, remotePath, localToRemote, err := c.parseSourceAndDest()
	if err != nil {
		return err
	}

	// Get the machineName from a shortcut, if any was used.
	//
	// This provides UX on error!
	if machineName, err = c.machineFromShortcut(machineName); err != nil {
		return err
	}

	if localPath, err = filepath.Abs(localPath); err != nil {
		c.Stdout.Printlnf(errormessages.GenericInternalErrorNoMsg)
		return err
	}

	c.Log.Debug(
		"Parsed source and dest. machineName:%s, localPath:%s, remotePath%s, localToRemote:%t",
		machineName, localPath, remotePath, localToRemote,
	)

	// This provides UX!
	sshKey, err := c.getSSHKey()
	if err != nil {
		return err
	}

	remoteUsername, err := sshKey.GetUsername(machineName)
	if err != nil {
		c.Stdout.Printlnf(errormessages.FailedGetSSHKey)
		return fmt.Errorf("Error getting remote username. err:%s", err)
	}

	// UX not needed on failure, prepareForSSH prints UX to user.
	if err := c.prepareForSSH(machineName, sshKey); err != nil {
		return err
	}

	c.Stdout.Printlnf(
		"Copying file or directory...",
	)

	sshAuthSock, err := agent.NewClient().GetAuthSock()
	if err != nil || sshAuthSock == "" {
		sshAuthSock = util.GetEnvByKey(os.Environ(), "SSH_AUTH_SOCK")
	}

	cacheReq := req.Cache{
		Debug:             c.Options.Debug,
		Name:              machineName,
		LocalPath:         localPath,
		RemotePath:        remotePath,
		LocalToRemote:     localToRemote,
		Interval:          0, // No interval! Important.
		Username:          remoteUsername,
		SSHAuthSock:       sshAuthSock,
		SSHPrivateKeyPath: sshKey.PrivateKeyPath(),
		// This allows the user to copy files, not just dirs.
		// See option docs for details.
		IncludePath: true,
	}

	cb, err := mount.NewCacheCallback(mount.CacheCallbackInit{
		Log:    c.Log,
		Stdout: c.Stdout,
	})
	if err != nil {
		c.Stdout.Printlnf(errormessages.GenericInternalErrorNoMsg)
		return err
	}

	// UX not needed on error, remoteCache handles that.
	//
	// Note that because we used a callback, this is async - updates are sent to the
	// callback and progress bar. We'll wait and block, below.
	if err := c.callRemoteCache(cacheReq, cb.Callback); err != nil {
		return err
	}

	// Wait until the async callback is done, then check for an error.
	if err := cb.WaitUntilDone(); err != nil {
		c.Stdout.Printlnf(
			c.HealthChecker.CheckAllFailureOrMessagef(errormessages.FailedSyncFolder),
		)
		return fmt.Errorf("remote.cacheFolder returned an error. err:%s", err)
	}

	c.Stdout.Printlnf("Copy complete.")

	return nil
}
Example #2
0
func (c *Command) runSync() error {
	sshKey, err := c.getSSHKey()
	if err != nil {
		return err
	}

	remoteUsername, err := sshKey.GetUsername(c.Options.MountName)
	if err != nil {
		c.Stdout.Printlnf(errormessages.FailedGetSSHKey)
		return fmt.Errorf("Error getting remote username. err:%s", err)
	}

	// UX not needed on failure, prepareForSSH prints UX to user.
	if err := c.prepareForSSH(sshKey); err != nil {
		return err
	}

	c.Stdout.Printlnf(
		"Downloading initial contents...Please don't interrupt this process while in progress.",
	)

	sshAuthSock, err := agent.NewClient().GetAuthSock()
	if err != nil || sshAuthSock == "" {
		sshAuthSock = util.GetEnvByKey(os.Environ(), "SSH_AUTH_SOCK")
	}

	cacheReq := req.Cache{
		Debug:             c.Options.Debug,
		Name:              c.Options.MountName,
		LocalPath:         c.mountInfo.LocalPath,
		RemotePath:        c.mountInfo.RemotePath,
		LocalToRemote:     c.Options.SyncDirection == localToRemote,
		Interval:          0, // No interval! Important.
		Username:          remoteUsername,
		SSHAuthSock:       sshAuthSock,
		SSHPrivateKeyPath: sshKey.PrivateKeyPath(),
	}

	cb, err := mount.NewCacheCallback(mount.CacheCallbackInit{
		Log:    c.Log,
		Stdout: c.Stdout,
	})
	if err != nil {
		c.Stdout.Printlnf(errormessages.GenericInternalErrorNoMsg)
		return err
	}

	// UX not needed on error, remoteCache handles that.
	//
	// Note that because we used a callback, this is async - updates are sent to the
	// callback and progress bar. We'll wait and block, below.
	if err := c.callRemoteCache(cacheReq, cb.Callback); err != nil {
		return err
	}

	// Wait until the async callback is done, then check for an error.
	if err := cb.WaitUntilDone(); err != nil {
		c.Stdout.Printlnf(
			c.HealthChecker.CheckAllFailureOrMessagef(errormessages.FailedSyncFolder),
		)
		return fmt.Errorf("remote.cacheFolder returned an error. err:%s", err)
	}

	c.Stdout.Printlnf("Sync complete.")

	return nil
}
Example #3
0
func (c *MountCommand) useSync() error {
	c.Log.Debug("#useSync")

	// If the cachePath exists, move it to the mount location.
	// No need to fail on an error during rename, we can just log it.
	cachePath := getCachePath(c.Options.Name)
	if err := os.Rename(cachePath, c.Options.LocalPath); err != nil {
		c.Log.Warning(
			"Failed to move cache path to mount path. cachePath:%s, localPath:%s, err:%s",
			cachePath, c.Options.LocalPath, err,
		)
	}

	sshKey, err := c.getSSHKey()
	if err != nil {
		return err
	}

	remoteUsername, err := sshKey.GetUsername(c.Options.Name)
	if err != nil {
		c.printfln(FailedGetSSHKey)
		return fmt.Errorf("Error getting remote username. err:%s", err)
	}

	// UX not needed on failure, prepareForSSH prints UX to user.
	if err := c.prepareForSSH(sshKey); err != nil {
		return err
	}

	c.printfln("Downloading initial contents...Please don't interrupt this process while in progress.")

	sshAuthSock, err := agent.NewClient().GetAuthSock()
	if err != nil || sshAuthSock == "" {
		sshAuthSock = util.GetEnvByKey(os.Environ(), "SSH_AUTH_SOCK")
	}

	cacheReq := req.Cache{
		Debug:             c.Options.Debug,
		Name:              c.Options.Name,
		LocalPath:         c.Options.LocalPath,
		RemotePath:        c.Options.RemotePath,
		Interval:          0,
		Username:          remoteUsername,
		SSHAuthSock:       sshAuthSock,
		SSHPrivateKeyPath: sshKey.PrivateKeyPath(),
	}

	if err := c.cacheWithProgress(cacheReq); err != nil {
		return err
	}

	// Modify our cache request with the interval only settings.
	cacheReq.Interval = time.Duration(c.Options.OneWayInterval) * time.Second
	if cacheReq.Interval == 0 {
		cacheReq.Interval = 2 * time.Second
	}

	cacheReq.OnlyInterval = true
	cacheReq.LocalToRemote = true
	cacheReq.IgnoreFile = c.getIgnoreFile(c.Options.LocalPath)

	// c.callRemoteCache handles UX
	return c.callRemoteCache(cacheReq, nil)
}