Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(548)

Side by Side Diff: environs/manual/sshresponse_test.go

Issue 13635044: Implement manual bootstrapping
Patch Set: Implement manual bootstrapping Created 11 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 Canonical Ltd.
2 // Licensed under the AGPLv3, see LICENCE file for details.
3
4 package manual
5
6 import (
7 "fmt"
8 "io/ioutil"
9 "os"
10 "path/filepath"
11 "strings"
12
13 gc "launchpad.net/gocheck"
14
15 "launchpad.net/juju-core/testing"
16 )
17
18 // sshscript should only print the result on the first execution,
19 // to handle the case where it's called multiple times. On
20 // subsequent executions, it should find the next 'ssh' in $PATH
21 // and exec that.
22 var sshscript = `#!/bin/bash
23 if [ ! -e "$0.run" ]; then
24 touch "$0.run"
25 diff "$0.expected-input" -
26 exitcode=$?
27 if [ $exitcode -ne 0 ]; then
28 echo "ERROR: did not match expected input" >&2
29 exit $exitcode
30 fi
31 %s
32 exit %d
33 else
34 export PATH=${PATH#*:}
35 exec ssh $*
36 fi`
37
38 // sshresponse creates a fake "ssh" command in a new $PATH,
39 // updates $PATH, and returns a function to reset $PATH to
40 // its original value when called.
41 func sshresponse(c *gc.C, input, output string, rc int) func() {
rog 2013/09/14 07:28:03 I found these names quite confusing; the respond m
axw1 2013/09/16 04:56:48 Done.
42 fakebin := c.MkDir()
43 ssh := filepath.Join(fakebin, "ssh")
44 sshexpectedinput := ssh + ".expected-input"
45 if output != "" {
46 output = fmt.Sprintf("cat<<EOF\n%s\nEOF", output)
47 }
48 script := fmt.Sprintf(sshscript, output, rc)
49 err := ioutil.WriteFile(ssh, []byte(script), 0777)
50 c.Assert(err, gc.IsNil)
51 err = ioutil.WriteFile(sshexpectedinput, []byte(input), 0644)
52 c.Assert(err, gc.IsNil)
53 return testing.PatchEnvironment("PATH", fakebin+":"+os.Getenv("PATH"))
thumper 2013/09/16 03:02:08 I've been thinking of better ways to get test code
axw1 2013/09/16 04:56:48 That sounds fine. Since there's no way in hell our
54 }
55
56 // sshsesponder wraps the invocation of sshresponse based on the parameters.
57 type sshresponder struct {
58 series string
59 arch string
60
61 // exit code for the machine agent provisioning script.
62 provisionAgentExitCode int
63
64 // there are conditions other than error in the above
65 // that might cause provisioning to not go ahead, such
66 // as tools being missing.
67 skipProvisionAgent bool
68 }
69
70 func (r sshresponder) respond(c *gc.C) func() {
rog 2013/09/14 07:28:03 I'd like to see a doc comment on this please.
axw1 2013/09/16 04:56:48 Done.
71 series := r.series
72 if series == "" {
73 series = "precise"
74 }
75 arch := r.arch
76 if arch == "" {
77 arch = "amd64"
78 }
79 detectionoutput := strings.Join([]string{
80 series,
81 arch,
82 "MemTotal: 4096 kB",
83 "processor: 0",
84 }, "\n")
85 // Responses are elicited conditionally, hence this mess of dynamicity.
86 add := func(oldf func(), input, output string, rc int) func() {
87 f := sshresponse(c, input, output, rc)
rog 2013/09/14 07:28:03 I think things can be simpler here. How about some
axw1 2013/09/16 04:56:48 Much nicer, thank you.
88 if oldf != nil {
89 newf := f
90 f = func() {
91 newf()
92 oldf()
93 }
94 }
95 return f
96 }
97 var f func()
98 if !r.skipProvisionAgent {
99 f = add(f, "", "", r.provisionAgentExitCode)
100 }
101 f = add(f, detectionScript, detectionoutput, 0)
102 return add(f, checkProvisionedScript, "", 0)
103 }
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b