github.com/pingcap/chaos@v0.0.0-20190710112158-c86faf4b3719/pkg/util/ssh/ssh.go (about) 1 package ssh 2 3 import ( 4 "context" 5 "flag" 6 "fmt" 7 "log" 8 "os/exec" 9 ) 10 11 var ( 12 verbose = flag.Bool("ssh-verbose", false, "show the verbose of SSH command") 13 ) 14 15 // Exec executes the cmd on the remote node. 16 // Here we assume we can run with `ssh node cmd` directly 17 // TODO: add a SSH config? 18 func Exec(ctx context.Context, node string, cmd string, args ...string) error { 19 _, err := CombinedOutput(ctx, node, cmd, args...) 20 return err 21 } 22 23 // CombinedOutput executes the cmd on the remote node and returns its combined standard 24 // output and standard error. 25 func CombinedOutput(ctx context.Context, node string, cmd string, args ...string) ([]byte, error) { 26 v := []string{ 27 node, 28 cmd, 29 } 30 v = append(v, args...) 31 if *verbose { 32 log.Printf("run %s %v on node %s", cmd, args, node) 33 } 34 data, err := exec.CommandContext(ctx, "ssh", v...).CombinedOutput() 35 if err != nil { 36 // For debug 37 if *verbose { 38 log.Printf("fail to run %v %q %v", v, data, err) 39 } 40 } 41 return data, err 42 } 43 44 // Upload uploads files from local path to remote node path. 45 func Upload(ctx context.Context, localPath string, node string, remotePath string) error { 46 return exec.CommandContext(ctx, "scp", "-r", localPath, fmt.Sprintf("%s:%s", node, remotePath)).Run() 47 } 48 49 // Download downloads files from remote node path to local path. 50 func Download(ctx context.Context, localPath string, node string, remotePath string) error { 51 return exec.CommandContext(ctx, "scp", "-r", fmt.Sprintf("%s:%s", node, remotePath), localPath).Run() 52 }