~ubuntu-branches/ubuntu/wily/juju-core/wily

« back to all changes in this revision

Viewing changes to src/launchpad.net/juju-core/utils/ssh/ssh_openssh.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-02-28 16:53:15 UTC
  • mfrom: (1.1.19)
  • Revision ID: package-import@ubuntu.com-20140228165315-g8n1ds0jrtekhxq6
Tags: 1.17.4-0ubuntu1
* New upstream point release (LP: #1261628):
  - https://launchpad.net/juju-core/trunk/1.17.4
  - d/control: Prefer juju-mongodb over mongodb-server for juju-local
    package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
        "launchpad.net/juju-core/utils"
15
15
)
16
16
 
17
 
var opensshCommonOptions = []string{"-o", "StrictHostKeyChecking no"}
 
17
var opensshCommonOptions = map[string][]string{"-o": []string{"StrictHostKeyChecking no"}}
18
18
 
19
19
// default identities will not be attempted if
20
20
// -i is specified and they are not explcitly
63
63
        return &c, nil
64
64
}
65
65
 
66
 
func opensshOptions(options *Options, commandKind opensshCommandKind) []string {
67
 
        args := append([]string{}, opensshCommonOptions...)
 
66
func opensshOptions(options *Options, commandKind opensshCommandKind) map[string][]string {
 
67
        args := make(map[string][]string)
 
68
        for k, v := range opensshCommonOptions {
 
69
                args[k] = v
 
70
        }
68
71
        if options == nil {
69
72
                options = &Options{}
70
73
        }
71
74
        if !options.passwordAuthAllowed {
72
 
                args = append(args, "-o", "PasswordAuthentication no")
 
75
                args["-o"] = append(args["-o"], "PasswordAuthentication no")
73
76
        }
74
77
        if options.allocatePTY {
75
 
                args = append(args, "-t")
 
78
                args["-t"] = []string{}
76
79
        }
77
80
        identities := append([]string{}, options.identities...)
78
81
        if pk := PrivateKeyFiles(); len(pk) > 0 {
94
97
                }
95
98
        }
96
99
        for _, identity := range identities {
97
 
                args = append(args, "-i", identity)
 
100
                args["-i"] = append(args["-i"], identity)
98
101
        }
99
102
        if options.port != 0 {
 
103
                port := fmt.Sprint(options.port)
100
104
                if commandKind == scpKind {
101
105
                        // scp uses -P instead of -p (-p means preserve).
102
 
                        args = append(args, "-P")
 
106
                        args["-P"] = []string{port}
103
107
                } else {
104
 
                        args = append(args, "-p")
 
108
                        args["-p"] = []string{port}
105
109
                }
106
 
                args = append(args, fmt.Sprint(options.port))
107
110
        }
108
111
        return args
109
112
}
110
113
 
 
114
func expandArgs(args map[string][]string, quote bool) []string {
 
115
        var list []string
 
116
        for opt, vals := range args {
 
117
                if len(vals) == 0 {
 
118
                        list = append(list, opt)
 
119
                        if opt == "-t" {
 
120
                                // In order to force a PTY to be allocated, we need to
 
121
                                // pass -t twice.
 
122
                                list = append(list, opt)
 
123
                        }
 
124
                }
 
125
                for _, val := range vals {
 
126
                        list = append(list, opt)
 
127
                        if quote {
 
128
                                val = fmt.Sprintf("%q", val)
 
129
                        }
 
130
                        list = append(list, val)
 
131
                }
 
132
        }
 
133
        return list
 
134
}
 
135
 
111
136
// Command implements Client.Command.
112
137
func (c *OpenSSHClient) Command(host string, command []string, options *Options) *Cmd {
113
 
        args := opensshOptions(options, sshKind)
 
138
        opts := opensshOptions(options, sshKind)
 
139
        args := expandArgs(opts, false)
114
140
        args = append(args, host)
115
141
        if len(command) > 0 {
116
 
                args = append(args, "--")
117
142
                args = append(args, command...)
118
143
        }
119
144
        bin, args := sshpassWrap("ssh", args)
 
145
        optsList := strings.Join(expandArgs(opts, true), " ")
 
146
        fullCommand := strings.Join(command, " ")
 
147
        logger.Debugf("running: %s %s %q '%s'", bin, optsList, host, fullCommand)
120
148
        return &Cmd{impl: &opensshCmd{exec.Command(bin, args...)}}
121
149
}
122
150
 
123
151
// Copy implements Client.Copy.
124
 
func (c *OpenSSHClient) Copy(source, dest string, userOptions *Options) error {
 
152
func (c *OpenSSHClient) Copy(targets, extraArgs []string, userOptions *Options) error {
125
153
        var options Options
126
154
        if userOptions != nil {
127
155
                options = *userOptions
128
156
                options.allocatePTY = false // doesn't make sense for scp
129
157
        }
130
 
        args := opensshOptions(&options, scpKind)
131
 
        args = append(args, source, dest)
 
158
        opts := opensshOptions(&options, scpKind)
 
159
        args := expandArgs(opts, false)
 
160
        args = append(args, extraArgs...)
 
161
        args = append(args, targets...)
132
162
        bin, args := sshpassWrap("scp", args)
133
163
        cmd := exec.Command(bin, args...)
134
164
        var stderr bytes.Buffer
135
165
        cmd.Stderr = &stderr
 
166
        allOpts := append(expandArgs(opts, true), extraArgs...)
 
167
        optsList := strings.Join(allOpts, " ")
 
168
        targetList := `"` + strings.Join(targets, `" "`) + `"`
 
169
        logger.Debugf("running: %s %s %s", bin, optsList, targetList)
136
170
        if err := cmd.Run(); err != nil {
137
171
                stderr := strings.TrimSpace(stderr.String())
138
172
                if len(stderr) > 0 {