Merge lp:~axwalk/juju-core/add-machine-ssh-password into lp:~go-bot/juju-core/trunk

Proposed by Andrew Wilkins
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
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.

https://codereview.appspot.com/43310043/

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.

https://codereview.appspot.com/43310043/

To post a comment you must log in.
Revision history for this message
Andrew Wilkins (axwalk) wrote :

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):
   A [revision details]
   M cmd/jujud/machine_test.go
   M utils/ssh/ssh.go
   A utils/ssh/ssh_test.go

Revision history for this message
William Reade (fwereade) wrote :

LGTM

https://codereview.appspot.com/43310043/diff/1/cmd/jujud/machine_test.go
File cmd/jujud/machine_test.go (right):

https://codereview.appspot.com/43310043/diff/1/cmd/jujud/machine_test.go#newcode29
cmd/jujud/machine_test.go:29: "launchpad.net/juju-core/testing"
already imported as "coretesting", I can see you didn't do it but please
do tidy it up ;).

https://codereview.appspot.com/43310043/

Revision history for this message
Andrew Wilkins (axwalk) wrote :

Please take a look.

https://codereview.appspot.com/43310043/diff/1/cmd/jujud/machine_test.go
File cmd/jujud/machine_test.go (right):

https://codereview.appspot.com/43310043/diff/1/cmd/jujud/machine_test.go#newcode29
cmd/jujud/machine_test.go:29: "launchpad.net/juju-core/testing"
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.

https://codereview.appspot.com/43310043/

Revision history for this message
Go Bot (go-bot) wrote :
Download full text (7.9 KiB)

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.net/juju-core/agent 0.753s
ok launchpad.net/juju-core/agent/tools 0.280s
ok launchpad.net/juju-core/bzr 7.413s
ok launchpad.net/juju-core/cert 3.465s
ok launchpad.net/juju-core/charm 0.601s
? launchpad.net/juju-core/charm/hooks [no test files]
ok launchpad.net/juju-core/cloudinit 0.075s
ok launchpad.net/juju-core/cloudinit/sshinit 1.189s
ok launchpad.net/juju-core/cmd 0.412s
? launchpad.net/juju-core/cmd/charmd [no test files]
? launchpad.net/juju-core/cmd/charmload [no test files]
ok launchpad.net/juju-core/cmd/juju 185.090s
FAIL launchpad.net/juju-core/cmd/jujud [build failed]
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 2.708s
? launchpad.net/juju-core/cmd/plugins/juju-update-bootstrap [no test files]
ok launchpad.net/juju-core/constraints 0.041s
ok launchpad.net/juju-core/container 0.035s
ok launchpad.net/juju-core/container/factory 0.049s
ok launchpad.net/juju-core/container/kvm 0.293s
ok launchpad.net/juju-core/container/kvm/mock 0.035s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 0.330s
? launchpad.net/juju-core/container/lxc/mock [no test files]
? launchpad.net/juju-core/container/lxc/testing [no test files]
? launchpad.net/juju-core/container/testing [no test files]
ok launchpad.net/juju-core/downloader 5.358s
ok launchpad.net/juju-core/environs 3.084s
ok launchpad.net/juju-core/environs/bootstrap 4.468s
ok launchpad.net/juju-core/environs/cloudinit 0.857s
ok launchpad.net/juju-core/environs/config 1.046s
ok launchpad.net/juju-core/environs/configstore 0.058s
ok launchpad.net/juju-core/environs/filestorage 0.061s
ok launchpad.net/juju-core/environs/httpstorage 1.127s
ok launchpad.net/juju-core/environs/imagemetadata 0.568s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.094s
ok launchpad.net/juju-core/environs/jujutest 0.277s
ok launchpad.net/juju-core/environs/manual 5.858s
ok launchpad.net/juju-core/environs/simplestreams 0.341s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 1.167s
ok launchpad.net/juju-core/environs/storage 1.134s
ok launchpad.net/juju-core/environs/sync 31.313s
ok launchpad.net/juju-core/environs/testing 0.199s
ok launchpad.net/juju-core/environs/tools 6.931s
? launchpad.net/juju-core/environs/tools/testing [no test files]
ok launchpad.net/juju-core/errors 0.041s
ok launchpad.net/juju-core/instance 0.023s
? launchpad.net/juju-core/instance/testing [no test files]
ok launchpad.net/juju-core/juju 17.143s
ok launchpad.net/juju-core/juju/osenv 0.018s
? launchpad.net/juju-core/juju/testing [no test files]
ok launchpad.net/juju-core/log 0.015s
ok launchpad.net/juju-core/log/syslog 0.022s
ok launchpad.net/juju-core/names 0.026s
? launchpad.net/juju-core/provider [no test files]
? launchpad.net/juju-core/provider/all [no test files]
ok l...

Read more...

Revision history for this message
Go Bot (go-bot) wrote :
Download full text (7.9 KiB)

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.net/juju-core/agent 1.726s
ok launchpad.net/juju-core/agent/tools 0.224s
ok launchpad.net/juju-core/bzr 7.541s
ok launchpad.net/juju-core/cert 3.263s
ok launchpad.net/juju-core/charm 0.562s
? launchpad.net/juju-core/charm/hooks [no test files]
ok launchpad.net/juju-core/cloudinit 0.069s
ok launchpad.net/juju-core/cloudinit/sshinit 1.143s
ok launchpad.net/juju-core/cmd 0.240s
? launchpad.net/juju-core/cmd/charmd [no test files]
? launchpad.net/juju-core/cmd/charmload [no test files]
ok launchpad.net/juju-core/cmd/juju 184.368s
FAIL launchpad.net/juju-core/cmd/jujud [build failed]
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 2.802s
? launchpad.net/juju-core/cmd/plugins/juju-update-bootstrap [no test files]
ok launchpad.net/juju-core/constraints 0.028s
ok launchpad.net/juju-core/container 0.037s
ok launchpad.net/juju-core/container/factory 0.049s
ok launchpad.net/juju-core/container/kvm 0.273s
ok launchpad.net/juju-core/container/kvm/mock 0.095s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 0.324s
? launchpad.net/juju-core/container/lxc/mock [no test files]
? launchpad.net/juju-core/container/lxc/testing [no test files]
? launchpad.net/juju-core/container/testing [no test files]
ok launchpad.net/juju-core/downloader 5.292s
ok launchpad.net/juju-core/environs 3.034s
ok launchpad.net/juju-core/environs/bootstrap 4.542s
ok launchpad.net/juju-core/environs/cloudinit 0.852s
ok launchpad.net/juju-core/environs/config 1.975s
ok launchpad.net/juju-core/environs/configstore 0.043s
ok launchpad.net/juju-core/environs/filestorage 0.032s
ok launchpad.net/juju-core/environs/httpstorage 0.889s
ok launchpad.net/juju-core/environs/imagemetadata 0.541s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.070s
ok launchpad.net/juju-core/environs/jujutest 0.255s
ok launchpad.net/juju-core/environs/manual 5.924s
ok launchpad.net/juju-core/environs/simplestreams 0.319s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 1.367s
ok launchpad.net/juju-core/environs/storage 1.151s
ok launchpad.net/juju-core/environs/sync 30.983s
ok launchpad.net/juju-core/environs/testing 0.216s
ok launchpad.net/juju-core/environs/tools 6.933s
? launchpad.net/juju-core/environs/tools/testing [no test files]
ok launchpad.net/juju-core/errors 0.017s
ok launchpad.net/juju-core/instance 0.023s
? launchpad.net/juju-core/instance/testing [no test files]
ok launchpad.net/juju-core/juju 17.149s
ok launchpad.net/juju-core/juju/osenv 0.018s
? launchpad.net/juju-core/juju/testing [no test files]
ok launchpad.net/juju-core/log 0.015s
ok launchpad.net/juju-core/log/syslog 0.021s
ok launchpad.net/juju-core/names 0.026s
? launchpad.net/juju-core/provider [no test files]
? launchpad.net/juju-core/provider/all [no test files]
ok l...

Read more...

Revision history for this message
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...

Revision history for this message
Andrew Wilkins (axwalk) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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+}

Subscribers

People subscribed via source and target branches

to status/vote changes: