Merge lp:~axwalk/juju-core/lp1204094-verify-local-prereqs into lp:~go-bot/juju-core/trunk
- lp1204094-verify-local-prereqs
- Merge into trunk
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Andrew Wilkins | ||||||||
Approved revision: | no longer in the source branch. | ||||||||
Merged at revision: | 1632 | ||||||||
Proposed branch: | lp:~axwalk/juju-core/lp1204094-verify-local-prereqs | ||||||||
Merge into: | lp:~go-bot/juju-core/trunk | ||||||||
Diff against target: |
247 lines (+227/-0) 3 files modified
environs/local/environprovider.go (+4/-0) environs/local/prereqs.go (+122/-0) environs/local/prereqs_test.go (+101/-0) |
||||||||
To merge this branch: | bzr merge lp:~axwalk/juju-core/lp1204094-verify-local-prereqs | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju Engineering | Pending | ||
Review via email: mp+178496@code.launchpad.net |
Commit message
local: verify mongod and lxc prereqs
This change introduces basic verification
of the local provider's external prerequisites,
mongod and LXC userspace tools.
If either prerequisite does not exist,
return an error message which directs the
user to install the appropriate package.
Description of the change
local: verify mongod and lxc prereqs
This change introduces basic verification
of the local provider's external prerequisites,
mongod and LXC userspace tools.
If either prerequisite does not exist,
return an error message which directs the
user to install the appropriate package.
Andrew Wilkins (axwalk) wrote : | # |
Dimiter Naydenov (dimitern) wrote : | # |
LGTM with some suggestions below.
https:/
File environs/
https:/
environs/
if err := VerifyPrerequis
...
}
https:/
File environs/
https:/
environs/
provider is currently only available for Linux`)
No need for ` quotes here, just use ".
https:/
environs/
the local provider:
...and it has to be a specific version, with TLS, so not sure this will
help. It needs more specific instruction what PPA to add and which
package to install. Maybe you can refer to the README file here?
https:/
environs/
server.`
See above about the mongo+tls.
https:/
environs/
This might better be defined outside as:
errUnsupportedOS = ...
https:/
environs/
if err := verifyMongo(); err != nil { ...
https:/
environs/
// TODO(axw): ...
https:/
File environs/
https:/
environs/
gc "launchpad.
https:/
environs/
`Unsupported operating system: windows(.|\n)*`)
No need for ` quotes here, use ".
https:/
environs/
`(.|\n)*MongoDB server must be installed(.|\n)*`)
And here.
https:/
environs/
`(.|\n)*apt-get install mongodb-
Here.
https:/
environs/
`(.|\n)*MongoDB server must be installed(.|\n)*`)
Here.
https:/
environs/
`(.|\n)*apt...
John A Meinel (jameinel) wrote : | # |
I'm a little concerned that bits of this will fail on the bot testing
machine (where mongodb is in /usr/local/bin and lxc is not installed).
Otherwise, LGTM.
https:/
File environs/
https:/
environs/
This will fail on the tarmac bot, where we have mongo installed as
"/usr/local/
Do we have a better way than assuming mongo is in /usr/bin?
Though I guess for the local provider itself, we might need it to be
/usr/bin because of the Upstart job that we write?
https:/
File environs/
https:/
environs/
On 2013/08/08 15:42:25, dimitern wrote:
> gc "launchpad.
To be clear, we changed away from using '.' for imports, and just
haven't cleaned up all existing code yet. But we do try to make sure new
code doesn't use it.
https:/
environs/
TestLxcPrereq(c *C) {
We also intentionally (today) don't have 'lxc' installed on the bot
machine (so that we don't accidentally have tests that actually start
and stop containers).
So I think we need a bit of you change for mongodPath for lxc-ls.
Alternatively, you can use containers/lxc/* code to detect lxc, and then
just inherit from lxc.TestingSuite which always shows that lxc is
available.
Andrew Wilkins (axwalk) wrote : | # |
Please take a look.
Go Bot (go-bot) wrote : | # |
The attempt to merge lp:~axwalk/juju-core/lp1204094-verify-local-prereqs into lp:juju-core failed. Below is the output from the failed tests.
ok launchpad.
-------
PANIC: diskmanager_
... Panic: Couldn't create temporary directory: mkdir /tmp/gocheck-
/usr/lib/
in panic
/home/tarmac/
in tempDir.newPath
/home/tarmac/
in C.MkDir
diskmanager_
in DiskManagerSuit
-------
PANIC: diskmanager_
... Panic: Fixture has panicked (see related PANIC)
2013-08-09 06:48:34 ERROR juju.agent.tools list.go:100 cannot match tools.Filter{
2013-08-09 06:48:34 ERROR juju.agent.tools list.go:100 cannot match tools.Filter{
2013-08-09 06:48:34 ERROR juju.agent.tools list.go:100 cannot match tools.Filter{
2013-08-09 06:48:34 ERROR juju.agent.tools list.go:100 cannot match tools.Filter{
OOPS: 24 passed, 1 FIXTURE-PANICKED, 2 MISSED
--- FAIL: Test (21.10 seconds)
FAIL
FAIL launchpad.
ok launchpad.
ok launchpad.
-------
PANIC: dir_test.go:45: DirSuite.
... Panic: Couldn't create temporary directory: mkdir /tmp/gocheck-
/usr/lib/
in panic
/home/tarmac/
in tempDir.newPath
/home/tarmac/
in C.MkDir
dir_test.go:46
in DirSuite.
OOPS: 76 passed, 1 PANICKED
--- FAIL: Test (0.31 seconds)
FAIL
FAIL launchpad.
? launchpad.
ok launchpad.
-------
PANIC: filevar_test.go:24: FileVarSuite.
... Panic: Couldn't create temporary directory: mkdir /tmp/gocheck-
/usr/lib/
in panic
/home/tarmac/
in tempDir.newPath
/home/tarmac/
in C.MkDir
/home/tarmac/
in Context
filevar_test.go:25
in FileVarSuite.
-------
PANIC: filevar_test.go:47: FileVarSuite.T...
Go Bot (go-bot) wrote : | # |
The attempt to merge lp:~axwalk/juju-core/lp1204094-verify-local-prereqs into lp:juju-core failed. Below is the output from the failed tests.
ok launchpad.
-------
PANIC: diskmanager_
... Panic: Couldn't create temporary directory: mkdir /tmp/gocheck-
/usr/lib/
in panic
/home/tarmac/
in tempDir.newPath
/home/tarmac/
in C.MkDir
diskmanager_
in DiskManagerSuit
-------
PANIC: diskmanager_
... Panic: Fixture has panicked (see related PANIC)
2013-08-09 07:01:41 ERROR juju.agent.tools list.go:100 cannot match tools.Filter{
2013-08-09 07:01:41 ERROR juju.agent.tools list.go:100 cannot match tools.Filter{
2013-08-09 07:01:41 ERROR juju.agent.tools list.go:100 cannot match tools.Filter{
2013-08-09 07:01:41 ERROR juju.agent.tools list.go:100 cannot match tools.Filter{
OOPS: 24 passed, 1 FIXTURE-PANICKED, 2 MISSED
--- FAIL: Test (20.92 seconds)
FAIL
FAIL launchpad.
ok launchpad.
ok launchpad.
-------
PANIC: dir_test.go:45: DirSuite.
... Panic: Couldn't create temporary directory: mkdir /tmp/gocheck-
/usr/lib/
in panic
/home/tarmac/
in tempDir.newPath
/home/tarmac/
in C.MkDir
dir_test.go:46
in DirSuite.
OOPS: 76 passed, 1 PANICKED
--- FAIL: Test (0.31 seconds)
FAIL
FAIL launchpad.
? launchpad.
ok launchpad.
-------
PANIC: filevar_test.go:24: FileVarSuite.
... Panic: Couldn't create temporary directory: mkdir /tmp/gocheck-
/usr/lib/
in panic
/home/tarmac/
in tempDir.newPath
/home/tarmac/
in C.MkDir
/home/tarmac/
in Context
filevar_test.go:25
in FileVarSuite.
-------
PANIC: filevar_test.go:47: FileVarSuite.T...
Go Bot (go-bot) wrote : | # |
The attempt to merge lp:~axwalk/juju-core/lp1204094-verify-local-prereqs 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.
? launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok 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.
? launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
Preview Diff
1 | === modified file 'environs/local/environprovider.go' |
2 | --- environs/local/environprovider.go 2013-07-18 02:09:43 +0000 |
3 | +++ environs/local/environprovider.go 2013-08-09 06:44:29 +0000 |
4 | @@ -38,6 +38,10 @@ |
5 | return nil, err |
6 | } |
7 | } |
8 | + if err := VerifyPrerequisites(); err != nil { |
9 | + logger.Errorf("failed verification of local provider prerequisites: %v", err) |
10 | + return nil, err |
11 | + } |
12 | environ := &localEnviron{name: cfg.Name()} |
13 | err = environ.SetConfig(cfg) |
14 | if err != nil { |
15 | |
16 | === added file 'environs/local/prereqs.go' |
17 | --- environs/local/prereqs.go 1970-01-01 00:00:00 +0000 |
18 | +++ environs/local/prereqs.go 2013-08-09 06:44:29 +0000 |
19 | @@ -0,0 +1,122 @@ |
20 | +// Copyright 2013 Canonical Ltd. |
21 | +// Licensed under the AGPLv3, see LICENCE file for details. |
22 | + |
23 | +package local |
24 | + |
25 | +import ( |
26 | + "errors" |
27 | + "fmt" |
28 | + "os" |
29 | + "os/exec" |
30 | + "runtime" |
31 | + "strings" |
32 | + |
33 | + "launchpad.net/juju-core/version" |
34 | +) |
35 | + |
36 | +var notLinuxError = errors.New("The local provider is currently only available for Linux") |
37 | + |
38 | +const installMongodUbuntu = "MongoDB server must be installed to enable the local provider:" |
39 | +const aptAddRepositoryJujuStable = ` |
40 | + sudo apt-add-repository ppa:juju/stable # required for MongoDB SSL support |
41 | + sudo apt-get update` |
42 | +const aptGetInstallMongodbServer = ` |
43 | + sudo apt-get install mongodb-server` |
44 | + |
45 | +const installMongodGeneric = ` |
46 | +MongoDB server must be installed to enable the local provider. |
47 | +Please consult your operating system distribution's documentation |
48 | +for instructions on installing the MongoDB server. Juju requires |
49 | +a MongoDB server built with SSL support. |
50 | +` |
51 | + |
52 | +const installLxcUbuntu = ` |
53 | +Linux Containers (LXC) userspace tools must be |
54 | +installed to enable the local provider: |
55 | + |
56 | + sudo apt-get install lxc` |
57 | + |
58 | +const installLxcGeneric = ` |
59 | +Linux Containers (LXC) userspace tools must be installed to enable the |
60 | +local provider. Please consult your operating system distribution's |
61 | +documentation for instructions on installing the LXC userspace tools.` |
62 | + |
63 | +const errUnsupportedOS = `Unsupported operating system: %s |
64 | +The local provider is currently only available for Linux` |
65 | + |
66 | +// mongodPath is the path to "mongod", the MongoDB server. |
67 | +// This is a variable only to support unit testing. |
68 | +var mongodPath = "/usr/bin/mongod" |
69 | + |
70 | +// lxclsPath is the path to "lxc-ls", an LXC userspace tool |
71 | +// we check the presence of to determine whether the |
72 | +// tools are installed. This is a variable only to support |
73 | +// unit testing. |
74 | +var lxclsPath = "lxc-ls" |
75 | + |
76 | +// The operating system the process is running in. |
77 | +// This is a variable only to support unit testing. |
78 | +var goos = runtime.GOOS |
79 | + |
80 | +// VerifyPrerequisites verifies the prerequisites of |
81 | +// the local machine (machine 0) for running the local |
82 | +// provider. |
83 | +func VerifyPrerequisites() error { |
84 | + if goos != "linux" { |
85 | + return fmt.Errorf(errUnsupportedOS, goos) |
86 | + } |
87 | + if err := verifyMongod(); err != nil { |
88 | + return err |
89 | + } |
90 | + return verifyLxc() |
91 | +} |
92 | + |
93 | +func verifyMongod() error { |
94 | + if _, err := os.Stat(mongodPath); err != nil { |
95 | + if os.IsNotExist(err) { |
96 | + return wrapMongodNotExist(err) |
97 | + } else { |
98 | + return err |
99 | + } |
100 | + } |
101 | + // TODO(axw) verify version/SSL capabilities |
102 | + return nil |
103 | +} |
104 | + |
105 | +func verifyLxc() error { |
106 | + _, err := exec.LookPath(lxclsPath) |
107 | + if err != nil { |
108 | + return wrapLxcNotFound(err) |
109 | + } |
110 | + return nil |
111 | +} |
112 | + |
113 | +func isUbuntu() bool { |
114 | + out, err := exec.Command("lsb_release", "-i", "-s").CombinedOutput() |
115 | + if err != nil { |
116 | + return false |
117 | + } |
118 | + return strings.TrimSpace(string(out)) == "Ubuntu" |
119 | +} |
120 | + |
121 | +func wrapMongodNotExist(err error) error { |
122 | + if isUbuntu() { |
123 | + series := version.Current.Series |
124 | + args := []interface{}{err, installMongodUbuntu} |
125 | + format := "%v\n%s\n%s" |
126 | + if series == "precise" || series == "quantal" { |
127 | + format += "%s" |
128 | + args = append(args, aptAddRepositoryJujuStable) |
129 | + } |
130 | + args = append(args, aptGetInstallMongodbServer) |
131 | + return fmt.Errorf(format, args...) |
132 | + } |
133 | + return fmt.Errorf("%v\n%s", err, installMongodGeneric) |
134 | +} |
135 | + |
136 | +func wrapLxcNotFound(err error) error { |
137 | + if isUbuntu() { |
138 | + return fmt.Errorf("%v\n%s", err, installLxcUbuntu) |
139 | + } |
140 | + return fmt.Errorf("%v\n%s", err, installLxcGeneric) |
141 | +} |
142 | |
143 | === added file 'environs/local/prereqs_test.go' |
144 | --- environs/local/prereqs_test.go 1970-01-01 00:00:00 +0000 |
145 | +++ environs/local/prereqs_test.go 2013-08-09 06:44:29 +0000 |
146 | @@ -0,0 +1,101 @@ |
147 | +// Copyright 2013 Canonical Ltd. |
148 | +// Licensed under the AGPLv3, see LICENCE file for details. |
149 | + |
150 | +package local |
151 | + |
152 | +import ( |
153 | + "io/ioutil" |
154 | + "os" |
155 | + "path/filepath" |
156 | + |
157 | + gc "launchpad.net/gocheck" |
158 | + |
159 | + "launchpad.net/juju-core/testing" |
160 | +) |
161 | + |
162 | +type prereqsSuite struct { |
163 | + testing.LoggingSuite |
164 | + tmpdir string |
165 | + oldpath string |
166 | +} |
167 | + |
168 | +var _ = gc.Suite(&prereqsSuite{}) |
169 | + |
170 | +const lsbrelease = `#!/bin/sh |
171 | +echo $JUJUTEST_LSB_RELEASE_ID |
172 | +` |
173 | + |
174 | +func init() { |
175 | + // Set the paths to mongod and lxc-ls to |
176 | + // something we know exists. This allows |
177 | + // all of the non-prereqs tests to pass |
178 | + // even when mongodb and lxc-ls can't be |
179 | + // found. |
180 | + mongodPath = "/bin/true" |
181 | + lxclsPath = "/bin/true" |
182 | +} |
183 | + |
184 | +func (s *prereqsSuite) SetUpTest(c *gc.C) { |
185 | + s.LoggingSuite.SetUpTest(c) |
186 | + s.tmpdir = c.MkDir() |
187 | + s.oldpath = os.Getenv("PATH") |
188 | + mongodPath = filepath.Join(s.tmpdir, "mongod") |
189 | + lxclsPath = filepath.Join(s.tmpdir, "lxc-ls") |
190 | + os.Setenv("PATH", s.tmpdir) |
191 | + os.Setenv("JUJUTEST_LSB_RELEASE_ID", "Ubuntu") |
192 | + err := ioutil.WriteFile(filepath.Join(s.tmpdir, "lsb_release"), []byte(lsbrelease), 0777) |
193 | + c.Assert(err, gc.IsNil) |
194 | +} |
195 | + |
196 | +func (s *prereqsSuite) TearDownTest(c *gc.C) { |
197 | + os.Setenv("PATH", s.oldpath) |
198 | + mongodPath = "/bin/true" |
199 | + lxclsPath = "/bin/true" |
200 | + s.LoggingSuite.TearDownTest(c) |
201 | +} |
202 | + |
203 | +func (*prereqsSuite) TestSupportedOS(c *gc.C) { |
204 | + defer func(old string) { |
205 | + goos = old |
206 | + }(goos) |
207 | + goos = "windows" |
208 | + err := VerifyPrerequisites() |
209 | + c.Assert(err, gc.ErrorMatches, "Unsupported operating system: windows(.|\n)*") |
210 | +} |
211 | + |
212 | +func (s *prereqsSuite) TestMongoPrereq(c *gc.C) { |
213 | + err := VerifyPrerequisites() |
214 | + c.Assert(err, gc.ErrorMatches, "(.|\n)*MongoDB server must be installed(.|\n)*") |
215 | + c.Assert(err, gc.ErrorMatches, "(.|\n)*apt-get install mongodb-server(.|\n)*") |
216 | + |
217 | + os.Setenv("JUJUTEST_LSB_RELEASE_ID", "NotUbuntu") |
218 | + err = VerifyPrerequisites() |
219 | + c.Assert(err, gc.ErrorMatches, "(.|\n)*MongoDB server must be installed(.|\n)*") |
220 | + c.Assert(err, gc.Not(gc.ErrorMatches), "(.|\n)*apt-get install(.|\n)*") |
221 | + |
222 | + err = ioutil.WriteFile(mongodPath, nil, 0777) |
223 | + c.Assert(err, gc.IsNil) |
224 | + err = ioutil.WriteFile(filepath.Join(s.tmpdir, "lxc-ls"), nil, 0777) |
225 | + c.Assert(err, gc.IsNil) |
226 | + err = VerifyPrerequisites() |
227 | + c.Assert(err, gc.IsNil) |
228 | +} |
229 | + |
230 | +func (s *prereqsSuite) TestLxcPrereq(c *gc.C) { |
231 | + err := ioutil.WriteFile(mongodPath, nil, 0777) |
232 | + c.Assert(err, gc.IsNil) |
233 | + |
234 | + err = VerifyPrerequisites() |
235 | + c.Assert(err, gc.ErrorMatches, "(.|\n)*Linux Containers \\(LXC\\) userspace tools must be\ninstalled(.|\n)*") |
236 | + c.Assert(err, gc.ErrorMatches, "(.|\n)*apt-get install lxc(.|\n)*") |
237 | + |
238 | + os.Setenv("JUJUTEST_LSB_RELEASE_ID", "NotUbuntu") |
239 | + err = VerifyPrerequisites() |
240 | + c.Assert(err, gc.ErrorMatches, "(.|\n)*Linux Containers \\(LXC\\) userspace tools must be installed(.|\n)*") |
241 | + c.Assert(err, gc.Not(gc.ErrorMatches), "(.|\n)*apt-get install(.|\n)*") |
242 | + |
243 | + err = ioutil.WriteFile(lxclsPath, nil, 0777) |
244 | + c.Assert(err, gc.IsNil) |
245 | + err = VerifyPrerequisites() |
246 | + c.Assert(err, gc.IsNil) |
247 | +} |
Reviewers: mp+178496_ code.launchpad. net,
Message:
Please take a look.
Description:
local: verify mongod and lxc prereqs
This change introduces basic verification
of the local provider's external prerequisites,
mongod and LXC userspace tools.
If either prerequisite does not exist,
return an error message which directs the
user to install the appropriate package.
https:/ /code.launchpad .net/~axwalk/ juju-core/ lp1204094- verify- local-prereqs/ +merge/ 178496
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/12336044/
Affected files: local/environpr ovider. go local/prereqs. go local/prereqs_ test.go
A [revision details]
M environs/
A environs/
A environs/