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 }
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 }
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) }