Skip to content

Commit

Permalink
Merge pull request #45 from plunder-app/download
Browse files Browse the repository at this point in the history
Fixed download info and parallel execution
  • Loading branch information
thebsdbox authored Feb 4, 2019
2 parents a9cc7ab + 2d3de6f commit ffd0979
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 1 deletion.
23 changes: 22 additions & 1 deletion pkg/parlay/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,9 @@ func sequentialDeployment(action []types.Action, hostConfig ssh.HostSSHConfig) e
restore.createCheckpoint()

// Return the error
return fmt.Errorf("Upload task [%s] on host [%s] failed with error [%s]", action[y].Name, hostConfig.Host, err)
return fmt.Errorf("Download task [%s] on host [%s] failed with error [%s]", action[y].Name, hostConfig.Host, err)
}
log.Infof("Succesfully Downloaded [%s] to [%s] from [%s]", action[y].Source, action[y].Destination, hostConfig.Host)
case "command":
// Build out a configuration based upon the action
cr := parseAndExecute(action[y], &hostConfig)
Expand Down Expand Up @@ -225,7 +226,27 @@ func parallelDeployment(action []types.Action, hosts []ssh.HostSSHConfig) error
log.Infof("Succesfully uploaded [%s] to [%s] on [%s]", action[y].Source, action[y].Destination, results[i].Host)
}
case "download":
logging.writeString(fmt.Sprintf("[%s] Downloading remote file [%s] to [%s] from multiple hosts\n", time.Now().Format(time.ANSIC), action[y].Source, action[y].Destination))

results := ssh.ParalellDownload(hosts, action[y].Source, action[y].Destination, action[y].Timeout)
// Unlikely that this should happen
if len(results) == 0 {
return fmt.Errorf("No results have been returned from the parallel execution")
}
// Parse the results from the parallel updates
for i := range results {
if results[i].Error != nil {
// Set checkpoint
restore.Action = action[y].Name
restore.createCheckpoint()

logging.writeString(fmt.Sprintf("[%s] Error downloading file [%s] to [%s] to host [%s]\n", time.Now().Format(time.ANSIC), action[y].Source, action[y].Destination, results[i].Host))
logging.writeString(fmt.Sprintf("[%s] [%s]\n", time.Now().Format(time.ANSIC), results[i].Error))
return fmt.Errorf("Download task [%s] on host [%s] failed with error [%s]", action[y].Name, results[i].Host, results[i].Error)
}
logging.writeString(fmt.Sprintf("[%s] Completed uploading file [%s] to Destination [%s] to host [%s]\n", time.Now().Format(time.ANSIC), action[y].Source, action[y].Destination, results[i].Host))
log.Infof("Succesfully uploaded [%s] to [%s] on [%s]", action[y].Source, action[y].Destination, results[i].Host)
}
case "command":
logging.writeString(fmt.Sprintf("[%s] Executing command action [%s] to multiple hosts\n", time.Now().Format(time.ANSIC), action[y].Name))
command, err := buildCommand(action[y])
Expand Down
53 changes: 53 additions & 0 deletions pkg/ssh/sshTransfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,59 @@ import (
"github.com/pkg/sftp"
)

// ParalellDownload - Allow downloading a file over SFTP from multiple hosts in parallel
func ParalellDownload(hosts []HostSSHConfig, source, destination string, to int) []CommandResult {
var cmdResults []CommandResult
// Run parallel ssh session (max 10)
results := make(chan CommandResult, 10)

var d time.Duration

// Calculate the timeout
if to == 0 {
// If no timeout then default to one year (TODO)
d = time.Duration(8760) * time.Hour
} else {
d = time.Duration(to) * time.Second
}

// Set the timeout
timeout := time.After(d)

// Execute command on hosts
for _, host := range hosts {
go func(host HostSSHConfig) {
res := new(CommandResult)
res.Host = host.Host

if err := host.DownloadFile(source, destination); err != nil {
res.Error = err
} else {
res.Result = "Download completed"
}
results <- *res
}(host)
}

for i := 0; i < len(hosts); i++ {
select {
case res := <-results:
// Append the results of a succesfull command
cmdResults = append(cmdResults, res)
case <-timeout:
// In the event that a command times out then append the details
failedCommand := CommandResult{
Host: hosts[i].Host,
Error: fmt.Errorf("Download Timed out"),
Result: "",
}
cmdResults = append(cmdResults, failedCommand)

}
}
return cmdResults
}

// DownloadFile -
func (c HostSSHConfig) DownloadFile(source, destination string) error {
var err error
Expand Down

0 comments on commit ffd0979

Please sign in to comment.