~dstroppa/juju-core/joyent-provider-storage

« back to all changes in this revision

Viewing changes to utils/ssh/ssh.go

  • Committer: Daniele Stroppa
  • Date: 2014-01-08 15:58:10 UTC
  • mfrom: (1953.1.231 juju-core)
  • Revision ID: daniele.stroppa@joyent.com-20140108155810-xecbwrqkb5i0fyoe
Merging trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// Copyright 2013 Canonical Ltd.
2
2
// Licensed under the AGPLv3, see LICENCE file for details.
3
3
 
4
 
package manual
 
4
// Package ssh contains utilities for dealing with SSH connections,
 
5
// key management, and so on. All SSH-based command executions in
 
6
// Juju should use the Command/ScpCommand functions in this package.
 
7
//
 
8
// TODO(axw) use PuTTY/plink if it's available on Windows.
 
9
// TODO(axw) fallback to go.crypto/ssh if no native client is available.
 
10
package ssh
5
11
 
6
12
import (
 
13
        "os"
7
14
        "os/exec"
8
15
)
9
16
 
10
 
type sshOption []string
11
 
 
12
 
var allocateTTY sshOption = []string{"-t"}
13
 
 
14
 
// TODO(axw) 2013-09-12 bug #1224230
15
 
// Move this to a common package for use in cmd/juju, and others.
16
 
var commonSSHOptions = []string{"-o", "StrictHostKeyChecking no"}
17
 
 
18
 
func sshCommand(host string, command string, options ...sshOption) *exec.Cmd {
19
 
        args := append([]string{}, commonSSHOptions...)
20
 
        for _, option := range options {
21
 
                args = append(args, option...)
22
 
        }
23
 
        args = append(args, host, "--", command)
24
 
        return exec.Command("ssh", args...)
 
17
type Option []string
 
18
 
 
19
var (
 
20
        commonOptions Option = []string{"-o", "StrictHostKeyChecking no"}
 
21
 
 
22
        // AllocateTTY forces pseudo-TTY allocation, which is required,
 
23
        // for example, for sudo password prompts on the target host.
 
24
        AllocateTTY Option = []string{"-t"}
 
25
 
 
26
        // NoPasswordAuthentication disallows password-based authentication.
 
27
        NoPasswordAuthentication Option = []string{"-o", "PasswordAuthentication no"}
 
28
)
 
29
 
 
30
// sshpassWrap wraps the command/args with sshpass if it is found in $PATH
 
31
// and the SSHPASS environment variable is set. Otherwise, the original
 
32
// command/args are returned.
 
33
func sshpassWrap(cmd string, args []string) (string, []string) {
 
34
        if os.Getenv("SSHPASS") != "" {
 
35
                if path, err := exec.LookPath("sshpass"); err == nil {
 
36
                        return path, append([]string{"-e", cmd}, args...)
 
37
                }
 
38
        }
 
39
        return cmd, args
 
40
}
 
41
 
 
42
// Command initialises an os/exec.Cmd to execute the native ssh program.
 
43
//
 
44
// If the SSHPASS environment variable is set, and the sshpass program
 
45
// is available in $PATH, then the ssh command will be run with "sshpass -e".
 
46
func Command(host string, command []string, options ...Option) *exec.Cmd {
 
47
        args := append([]string{}, commonOptions...)
 
48
        for _, option := range options {
 
49
                args = append(args, option...)
 
50
        }
 
51
        args = append(args, host)
 
52
        if len(command) > 0 {
 
53
                args = append(args, "--")
 
54
                args = append(args, command...)
 
55
        }
 
56
        bin, args := sshpassWrap("ssh", args)
 
57
        return exec.Command(bin, args...)
 
58
}
 
59
 
 
60
// ScpCommand initialises an os/exec.Cmd to execute the native scp program.
 
61
//
 
62
// If the SSHPASS environment variable is set, and the sshpass program
 
63
// is available in $PATH, then the scp command will be run with "sshpass -e".
 
64
func ScpCommand(source, destination string, options ...Option) *exec.Cmd {
 
65
        args := append([]string{}, commonOptions...)
 
66
        for _, option := range options {
 
67
                args = append(args, option...)
 
68
        }
 
69
        args = append(args, source, destination)
 
70
        bin, args := sshpassWrap("scp", args)
 
71
        return exec.Command(bin, args...)
25
72
}