Merge lp:~axwalk/juju-core/add-machine-ssh-password into lp:~go-bot/juju-core/trunk
- add-machine-ssh-password
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Andrew Wilkins |
Approved revision: | no longer in the source branch. |
Merged at revision: | 2160 |
Proposed branch: | lp:~axwalk/juju-core/add-machine-ssh-password |
Merge into: | lp:~go-bot/juju-core/trunk |
Diff against target: |
251 lines (+108/-16) 3 files modified
cmd/jujud/machine_test.go (+13/-14) utils/ssh/ssh.go (+29/-2) utils/ssh/ssh_test.go (+66/-0) |
To merge this branch: | bzr merge lp:~axwalk/juju-core/add-machine-ssh-password |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju Engineering | Pending | ||
Review via email: mp+199233@code.launchpad.net |
Commit message
utils/ssh: use sshpass if found and $SSHPASS set
This enables scripted manual provisioning when all
that's available is a password. This is not as secure
as using a key pair, or when using a real TTY; that's
a security consideration the user must make.
Description of the change
utils/ssh: use sshpass if found and $SSHPASS set
This enables scripted manual provisioning when all
that's available is a password. This is not as secure
as using a key pair, or when using a real TTY; that's
a security consideration the user must make.
Andrew Wilkins (axwalk) wrote : | # |
William Reade (fwereade) wrote : | # |
LGTM
https:/
File cmd/jujud/
https:/
cmd/jujud/
already imported as "coretesting", I can see you didn't do it but please
do tidy it up ;).
Andrew Wilkins (axwalk) wrote : | # |
Please take a look.
https:/
File cmd/jujud/
https:/
cmd/jujud/
On 2013/12/18 15:01:03, fwereade wrote:
> already imported as "coretesting", I can see you didn't do it but
please do tidy
> it up ;).
Done.
Go Bot (go-bot) wrote : | # |
The attempt to merge lp:~axwalk/juju-core/add-machine-ssh-password into lp:juju-core failed. Below is the output from the failed tests.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
? launchpad.
ok launchpad.
FAIL launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
? launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
? launchpad.
ok l...
Go Bot (go-bot) wrote : | # |
The attempt to merge lp:~axwalk/juju-core/add-machine-ssh-password into lp:juju-core failed. Below is the output from the failed tests.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
? launchpad.
ok launchpad.
FAIL launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
? launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
? launchpad.
ok l...
Andrew Wilkins (axwalk) wrote : | # |
I don't get it, I removed that import. It's in the branch. It's not in the diff though...
Andrew Wilkins (axwalk) wrote : | # |
Please take a look.
Preview Diff
1 | === modified file 'cmd/jujud/machine_test.go' |
2 | --- cmd/jujud/machine_test.go 2013-12-18 15:38:24 +0000 |
3 | +++ cmd/jujud/machine_test.go 2013-12-19 02:24:09 +0000 |
4 | @@ -26,7 +26,6 @@ |
5 | "launchpad.net/juju-core/state/api/params" |
6 | statetesting "launchpad.net/juju-core/state/testing" |
7 | "launchpad.net/juju-core/state/watcher" |
8 | - "launchpad.net/juju-core/testing" |
9 | coretesting "launchpad.net/juju-core/testing" |
10 | jc "launchpad.net/juju-core/testing/checkers" |
11 | "launchpad.net/juju-core/testing/testbase" |
12 | @@ -236,7 +235,7 @@ |
13 | // The deployer actually removes the unit just after |
14 | // removing its deployment, so we need to poll here |
15 | // until it actually happens. |
16 | - for attempt := testing.LongAttempt.Start(); attempt.Next(); { |
17 | + for attempt := coretesting.LongAttempt.Start(); attempt.Next(); { |
18 | err := u0.Refresh() |
19 | if err == nil && attempt.HasNext() { |
20 | continue |
21 | @@ -346,7 +345,7 @@ |
22 | addrs := []instance.Address{instance.NewAddress("1.2.3.4")} |
23 | dummy.SetInstanceAddresses(insts[0], addrs) |
24 | |
25 | - for a := testing.LongAttempt.Start(); a.Next(); { |
26 | + for a := coretesting.LongAttempt.Start(); a.Next(); { |
27 | if !a.HasNext() { |
28 | c.Logf("final machine addresses: %#v", m.Addresses()) |
29 | c.Fatalf("timed out waiting for machine to get address") |
30 | @@ -368,7 +367,7 @@ |
31 | c.Assert(err, gc.IsNil) |
32 | w := m.Watch() |
33 | defer w.Stop() |
34 | - timeout := time.After(testing.LongWait) |
35 | + timeout := time.After(coretesting.LongWait) |
36 | for { |
37 | select { |
38 | case <-timeout: |
39 | @@ -395,8 +394,8 @@ |
40 | } |
41 | |
42 | var fastDialOpts = api.DialOpts{ |
43 | - Timeout: testing.LongWait, |
44 | - RetryDelay: testing.ShortWait, |
45 | + Timeout: coretesting.LongWait, |
46 | + RetryDelay: coretesting.ShortWait, |
47 | } |
48 | |
49 | func (s *MachineSuite) waitStopped(c *gc.C, job state.MachineJob, a *MachineAgent, done chan error) { |
50 | @@ -448,7 +447,7 @@ |
51 | case agentAPI := <-agentAPIs: |
52 | c.Assert(agentAPI, gc.NotNil) |
53 | test(conf, agentAPI) |
54 | - case <-time.After(testing.LongWait): |
55 | + case <-time.After(coretesting.LongWait): |
56 | c.Fatalf("API not opened") |
57 | } |
58 | |
59 | @@ -481,7 +480,7 @@ |
60 | case agentState := <-agentStates: |
61 | c.Assert(agentState, gc.NotNil) |
62 | test(conf, agentState) |
63 | - case <-time.After(testing.LongWait): |
64 | + case <-time.After(coretesting.LongWait): |
65 | c.Fatalf("state not opened") |
66 | } |
67 | |
68 | @@ -522,12 +521,12 @@ |
69 | // Trigger a sync on the state used by the agent, and wait |
70 | // for the unit to be removed. |
71 | agentState.StartSync() |
72 | - timeout := time.After(testing.LongWait) |
73 | + timeout := time.After(coretesting.LongWait) |
74 | for done := false; !done; { |
75 | select { |
76 | case <-timeout: |
77 | c.Fatalf("unit not cleaned up") |
78 | - case <-time.After(testing.ShortWait): |
79 | + case <-time.After(coretesting.ShortWait): |
80 | s.State.StartSync() |
81 | case <-w.Changes(): |
82 | err := unit.Refresh() |
83 | @@ -555,12 +554,12 @@ |
84 | // Trigger a sync on the state used by the agent, and wait for the unit |
85 | // to be created. |
86 | agentState.StartSync() |
87 | - timeout := time.After(testing.LongWait) |
88 | + timeout := time.After(coretesting.LongWait) |
89 | for { |
90 | select { |
91 | case <-timeout: |
92 | c.Fatalf("unit not created") |
93 | - case <-time.After(testing.ShortWait): |
94 | + case <-time.After(coretesting.ShortWait): |
95 | s.State.StartSync() |
96 | case <-w.Changes(): |
97 | units, err := service.AllUnits() |
98 | @@ -590,13 +589,13 @@ |
99 | |
100 | // Wait for ssh keys file to be updated. |
101 | s.State.StartSync() |
102 | - timeout := time.After(testing.LongWait) |
103 | + timeout := time.After(coretesting.LongWait) |
104 | sshKeyWithCommentPrefix := sshtesting.ValidKeyOne.Key + " Juju:user@host" |
105 | for { |
106 | select { |
107 | case <-timeout: |
108 | c.Fatalf("timeout while waiting for authorised ssh keys to change") |
109 | - case <-time.After(testing.ShortWait): |
110 | + case <-time.After(coretesting.ShortWait): |
111 | keys, err := ssh.ListKeys(ssh.FullKeys) |
112 | c.Assert(err, gc.IsNil) |
113 | keysStr := strings.Join(keys, "\n") |
114 | |
115 | === modified file 'utils/ssh/ssh.go' |
116 | --- utils/ssh/ssh.go 2013-12-03 05:20:25 +0000 |
117 | +++ utils/ssh/ssh.go 2013-12-19 02:24:09 +0000 |
118 | @@ -1,9 +1,16 @@ |
119 | // Copyright 2013 Canonical Ltd. |
120 | // Licensed under the AGPLv3, see LICENCE file for details. |
121 | |
122 | +// Package ssh contains utilities for dealing with SSH connections, |
123 | +// key management, and so on. All SSH-based command executions in |
124 | +// Juju should use the Command/ScpCommand functions in this package. |
125 | +// |
126 | +// TODO(axw) use PuTTY/plink if it's available on Windows. |
127 | +// TODO(axw) fallback to go.crypto/ssh if no native client is available. |
128 | package ssh |
129 | |
130 | import ( |
131 | + "os" |
132 | "os/exec" |
133 | ) |
134 | |
135 | @@ -20,7 +27,22 @@ |
136 | NoPasswordAuthentication Option = []string{"-o", "PasswordAuthentication no"} |
137 | ) |
138 | |
139 | +// sshpassWrap wraps the command/args with sshpass if it is found in $PATH |
140 | +// and the SSHPASS environment variable is set. Otherwise, the original |
141 | +// command/args are returned. |
142 | +func sshpassWrap(cmd string, args []string) (string, []string) { |
143 | + if os.Getenv("SSHPASS") != "" { |
144 | + if path, err := exec.LookPath("sshpass"); err == nil { |
145 | + return path, append([]string{"-e", cmd}, args...) |
146 | + } |
147 | + } |
148 | + return cmd, args |
149 | +} |
150 | + |
151 | // Command initialises an os/exec.Cmd to execute the native ssh program. |
152 | +// |
153 | +// If the SSHPASS environment variable is set, and the sshpass program |
154 | +// is available in $PATH, then the ssh command will be run with "sshpass -e". |
155 | func Command(host string, command []string, options ...Option) *exec.Cmd { |
156 | args := append([]string{}, commonOptions...) |
157 | for _, option := range options { |
158 | @@ -31,15 +53,20 @@ |
159 | args = append(args, "--") |
160 | args = append(args, command...) |
161 | } |
162 | - return exec.Command("ssh", args...) |
163 | + bin, args := sshpassWrap("ssh", args) |
164 | + return exec.Command(bin, args...) |
165 | } |
166 | |
167 | // ScpCommand initialises an os/exec.Cmd to execute the native scp program. |
168 | +// |
169 | +// If the SSHPASS environment variable is set, and the sshpass program |
170 | +// is available in $PATH, then the scp command will be run with "sshpass -e". |
171 | func ScpCommand(source, destination string, options ...Option) *exec.Cmd { |
172 | args := append([]string{}, commonOptions...) |
173 | for _, option := range options { |
174 | args = append(args, option...) |
175 | } |
176 | args = append(args, source, destination) |
177 | - return exec.Command("scp", args...) |
178 | + bin, args := sshpassWrap("scp", args) |
179 | + return exec.Command(bin, args...) |
180 | } |
181 | |
182 | === added file 'utils/ssh/ssh_test.go' |
183 | --- utils/ssh/ssh_test.go 1970-01-01 00:00:00 +0000 |
184 | +++ utils/ssh/ssh_test.go 2013-12-19 02:24:09 +0000 |
185 | @@ -0,0 +1,66 @@ |
186 | +// Copyright 2013 Canonical Ltd. |
187 | +// Licensed under the AGPLv3, see LICENCE file for details. |
188 | + |
189 | +package ssh_test |
190 | + |
191 | +import ( |
192 | + "io/ioutil" |
193 | + "os" |
194 | + "path/filepath" |
195 | + |
196 | + gc "launchpad.net/gocheck" |
197 | + |
198 | + "launchpad.net/juju-core/testing/testbase" |
199 | + "launchpad.net/juju-core/utils/ssh" |
200 | +) |
201 | + |
202 | +type SSHCommandSuite struct { |
203 | + testbase.LoggingSuite |
204 | + testbin string |
205 | + fakessh string |
206 | +} |
207 | + |
208 | +var _ = gc.Suite(&SSHCommandSuite{}) |
209 | + |
210 | +func (s *SSHCommandSuite) SetUpTest(c *gc.C) { |
211 | + s.LoggingSuite.SetUpTest(c) |
212 | + s.testbin = c.MkDir() |
213 | + s.fakessh = filepath.Join(s.testbin, "ssh") |
214 | + err := ioutil.WriteFile(s.fakessh, nil, 0755) |
215 | + c.Assert(err, gc.IsNil) |
216 | + s.PatchEnvironment("PATH", s.testbin) |
217 | +} |
218 | + |
219 | +func (s *SSHCommandSuite) TestCommand(c *gc.C) { |
220 | + s.assertCommandArgs(c, "localhost", []string{"echo", "123"}, []string{ |
221 | + "ssh", "-o", "StrictHostKeyChecking no", "localhost", "--", "echo", "123", |
222 | + }) |
223 | +} |
224 | + |
225 | +func (s *SSHCommandSuite) assertCommandArgs(c *gc.C, hostname string, command []string, expected []string) { |
226 | + cmd := ssh.Command("localhost", []string{"echo", "123"}) |
227 | + c.Assert(cmd, gc.NotNil) |
228 | + c.Assert(cmd.Args, gc.DeepEquals, expected) |
229 | +} |
230 | + |
231 | +func (s *SSHCommandSuite) TestCommandSSHPass(c *gc.C) { |
232 | + // First create a fake sshpass, but don't set SSHPASS |
233 | + fakesshpass := filepath.Join(s.testbin, "sshpass") |
234 | + err := ioutil.WriteFile(fakesshpass, nil, 0755) |
235 | + s.assertCommandArgs(c, "localhost", []string{"echo", "123"}, []string{ |
236 | + "ssh", "-o", "StrictHostKeyChecking no", "localhost", "--", "echo", "123", |
237 | + }) |
238 | + |
239 | + // Now set SSHPASS. |
240 | + s.PatchEnvironment("SSHPASS", "anyoldthing") |
241 | + s.assertCommandArgs(c, "localhost", []string{"echo", "123"}, []string{ |
242 | + fakesshpass, "-e", "ssh", "-o", "StrictHostKeyChecking no", "localhost", "--", "echo", "123", |
243 | + }) |
244 | + |
245 | + // Finally, remove sshpass from $PATH. |
246 | + err = os.Remove(fakesshpass) |
247 | + c.Assert(err, gc.IsNil) |
248 | + s.assertCommandArgs(c, "localhost", []string{"echo", "123"}, []string{ |
249 | + "ssh", "-o", "StrictHostKeyChecking no", "localhost", "--", "echo", "123", |
250 | + }) |
251 | +} |
Reviewers: mp+199233_ code.launchpad. net,
Message:
Please take a look.
Description:
utils/ssh: use sshpass if found and $SSHPASS set
This enables scripted manual provisioning when all
that's available is a password. This is not as secure
as using a key pair, or when using a real TTY; that's
a security consideration the user must make.
https:/ /code.launchpad .net/~axwalk/ juju-core/ add-machine- ssh-password/ +merge/ 199233
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/43310043/
Affected files (+98, -3 lines): machine_ test.go ssh_test. go
A [revision details]
M cmd/jujud/
M utils/ssh/ssh.go
A utils/ssh/