Merge lp:~thumper/juju-core/lxc-broker into lp:~go-bot/juju-core/trunk
- lxc-broker
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Tim Penhey |
Approved revision: | no longer in the source branch. |
Merged at revision: | 1330 |
Proposed branch: | lp:~thumper/juju-core/lxc-broker |
Merge into: | lp:~go-bot/juju-core/trunk |
Prerequisite: | lp:~thumper/juju-core/lxc-container |
Diff against target: |
353 lines (+229/-27) 8 files modified
container/lxc/export_test.go (+0/-19) container/lxc/lxc_test.go (+6/-5) container/lxc/mock/mock-lxc.go (+1/-1) container/lxc/test.go (+29/-0) worker/provisioner/lxc-broker.go (+64/-0) worker/provisioner/lxc-broker_test.go (+127/-0) worker/provisioner/provisioner.go (+1/-1) worker/provisioner/provisioner_task.go (+1/-1) |
To merge this branch: | bzr merge lp:~thumper/juju-core/lxc-broker |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
William Reade (community) | Approve | ||
Review via email: mp+170713@code.launchpad.net |
Commit message
Implement the lxc broker for the provisioner
Not hooked up yet.
Description of the change
Implement the lxc broker for the provisioner
Had to make some test functions and helpers exported.
Tim Penhey (thumper) wrote : | # |
Ian Booth (wallyworld) wrote : | # |
Looks good with a few suggestions.
https:/
File container/
https:/
container/
This limitation of Go really annoys me.
Could we add a big file level comment that these exported methods must
only be used for tests and not for normal business logic. I know each
method mentions the use of tests but I think a global comment would be
good too.
https:/
File worker/
https:/
worker/
To help with understanding what interface lxcBroker implements, and to
cause a compile time error if the contract is not met, the idiom we have
been using for other things is to add a line like this above the struct
definition:
var _ Broker = (*lxcBroker)(nil)
(rinse and repeat for any other implemented interfaces).
https:/
File worker/
https:/
worker/
instance.
Can we test more than this? Perhaps ensure the started instance is in
the list of running instances? Anything else we can check? Like
files/dirs created to show the instance is started?
https:/
worker/
There's more we could do here - we haven't verified the stop actually
worked. The method could be empty and just return nil and the test would
still pass. Could we perhaps list the running instances and verify it's
empty? Oh, and invoke stop on just one instance and see that the others
remain.
Tim Penhey (thumper) wrote : | # |
Please take a look.
https:/
File container/
https:/
container/
On 2013/06/21 00:19:32, wallyworld wrote:
> This limitation of Go really annoys me.
> Could we add a big file level comment that these exported methods must
only be
> used for tests and not for normal business logic. I know each method
mentions
> the use of tests but I think a global comment would be good too.
Done.
https:/
File worker/
https:/
worker/
On 2013/06/21 00:19:32, wallyworld wrote:
> To help with understanding what interface lxcBroker implements, and to
cause a
> compile time error if the contract is not met, the idiom we have been
using for
> other things is to add a line like this above the struct definition:
> var _ Broker = (*lxcBroker)(nil)
> (rinse and repeat for any other implemented interfaces).
Done.
https:/
File worker/
https:/
worker/
instance.
On 2013/06/21 00:19:32, wallyworld wrote:
> Can we test more than this? Perhaps ensure the started instance is in
the list
> of running instances? Anything else we can check? Like files/dirs
created to
> show the instance is started?
Are we getting into duplication here? Perhaps we could check that there
is a container directory with this instance id.
https:/
worker/
On 2013/06/21 00:19:32, wallyworld wrote:
> There's more we could do here - we haven't verified the stop actually
worked.
> The method could be empty and just return nil and the test would still
pass.
> Could we perhaps list the running instances and verify it's empty? Oh,
and
> invoke stop on just one instance and see that the others remain.
Done.
Ian Booth (wallyworld) wrote : | # |
William Reade (fwereade) wrote : | # |
LGTM, thanks
William Reade (fwereade) : | # |
Preview Diff
1 | === removed file 'container/lxc/export_test.go' |
2 | --- container/lxc/export_test.go 2013-06-24 00:35:22 +0000 |
3 | +++ container/lxc/export_test.go 1970-01-01 00:00:00 +0000 |
4 | @@ -1,19 +0,0 @@ |
5 | -// Copyright 2013 Canonical Ltd. |
6 | -// Licensed under the AGPLv3, see LICENCE file for details. |
7 | - |
8 | -package lxc |
9 | - |
10 | -func SetContainerDir(dir string) (old string) { |
11 | - old, containerDir = containerDir, dir |
12 | - return |
13 | -} |
14 | - |
15 | -func SetLxcContainerDir(dir string) (old string) { |
16 | - old, lxcContainerDir = lxcContainerDir, dir |
17 | - return |
18 | -} |
19 | - |
20 | -func SetRemovedContainerDir(dir string) (old string) { |
21 | - old, removedContainerDir = removedContainerDir, dir |
22 | - return |
23 | -} |
24 | |
25 | === modified file 'container/lxc/lxc_test.go' |
26 | --- container/lxc/lxc_test.go 2013-06-24 00:57:19 +0000 |
27 | +++ container/lxc/lxc_test.go 2013-06-25 22:06:25 +0000 |
28 | @@ -13,6 +13,7 @@ |
29 | . "launchpad.net/gocheck" |
30 | "launchpad.net/goyaml" |
31 | "launchpad.net/juju-core/container/lxc" |
32 | + "launchpad.net/juju-core/container/lxc/mock" |
33 | "launchpad.net/juju-core/instance" |
34 | jujutesting "launchpad.net/juju-core/juju/testing" |
35 | "launchpad.net/juju-core/state" |
36 | @@ -80,7 +81,7 @@ |
37 | } |
38 | |
39 | func (s *LxcSuite) TestStartContainer(c *C) { |
40 | - manager := lxc.NewContainerManager(MockFactory(), "") |
41 | + manager := lxc.NewContainerManager(mock.MockFactory(), "") |
42 | instance := StartContainer(c, manager, "1/lxc/0") |
43 | |
44 | name := string(instance.Id()) |
45 | @@ -108,7 +109,7 @@ |
46 | } |
47 | |
48 | func (s *LxcSuite) TestStopContainer(c *C) { |
49 | - manager := lxc.NewContainerManager(MockFactory(), "") |
50 | + manager := lxc.NewContainerManager(mock.MockFactory(), "") |
51 | instance := StartContainer(c, manager, "1/lxc/0") |
52 | |
53 | err := manager.StopContainer(instance) |
54 | @@ -122,7 +123,7 @@ |
55 | } |
56 | |
57 | func (s *LxcSuite) TestStopContainerNameClash(c *C) { |
58 | - manager := lxc.NewContainerManager(MockFactory(), "") |
59 | + manager := lxc.NewContainerManager(mock.MockFactory(), "") |
60 | instance := StartContainer(c, manager, "1/lxc/0") |
61 | |
62 | name := string(instance.Id()) |
63 | @@ -140,13 +141,13 @@ |
64 | } |
65 | |
66 | func (s *LxcSuite) TestNamedManagerPrefix(c *C) { |
67 | - manager := lxc.NewContainerManager(MockFactory(), "eric") |
68 | + manager := lxc.NewContainerManager(mock.MockFactory(), "eric") |
69 | instance := StartContainer(c, manager, "1/lxc/0") |
70 | c.Assert(string(instance.Id()), Equals, "eric-machine-1-lxc-0") |
71 | } |
72 | |
73 | func (s *LxcSuite) TestListContainers(c *C) { |
74 | - factory := MockFactory() |
75 | + factory := mock.MockFactory() |
76 | foo := lxc.NewContainerManager(factory, "foo") |
77 | bar := lxc.NewContainerManager(factory, "bar") |
78 | |
79 | |
80 | === added directory 'container/lxc/mock' |
81 | === renamed file 'container/lxc/mock-lxc_test.go' => 'container/lxc/mock/mock-lxc.go' |
82 | --- container/lxc/mock-lxc_test.go 2013-06-19 03:36:33 +0000 |
83 | +++ container/lxc/mock/mock-lxc.go 2013-06-25 22:06:25 +0000 |
84 | @@ -1,7 +1,7 @@ |
85 | // Copyright 2013 Canonical Ltd. |
86 | // Licensed under the AGPLv3, see LICENCE file for details. |
87 | |
88 | -package lxc_test |
89 | +package mock |
90 | |
91 | import ( |
92 | "fmt" |
93 | |
94 | === added file 'container/lxc/test.go' |
95 | --- container/lxc/test.go 1970-01-01 00:00:00 +0000 |
96 | +++ container/lxc/test.go 2013-06-25 22:06:25 +0000 |
97 | @@ -0,0 +1,29 @@ |
98 | +// Copyright 2013 Canonical Ltd. |
99 | +// Licensed under the AGPLv3, see LICENCE file for details. |
100 | + |
101 | +// Functions defined in this file should *ONLY* be used for testing. These |
102 | +// functions are exported for testing purposes only, and shouldn't be called |
103 | +// from code that isn't in a test file. |
104 | + |
105 | +package lxc |
106 | + |
107 | +// SetContainerDir allows tests in other packages to override the |
108 | +// containerDir. |
109 | +func SetContainerDir(dir string) (old string) { |
110 | + old, containerDir = containerDir, dir |
111 | + return |
112 | +} |
113 | + |
114 | +// SetLxcContainerDir allows tests in other packages to override the |
115 | +// lxcContainerDir. |
116 | +func SetLxcContainerDir(dir string) (old string) { |
117 | + old, lxcContainerDir = lxcContainerDir, dir |
118 | + return |
119 | +} |
120 | + |
121 | +// SetRemovedContainerDir allows tests in other packages to override the |
122 | +// removedContainerDir. |
123 | +func SetRemovedContainerDir(dir string) (old string) { |
124 | + old, removedContainerDir = removedContainerDir, dir |
125 | + return |
126 | +} |
127 | |
128 | === added file 'worker/provisioner/lxc-broker.go' |
129 | --- worker/provisioner/lxc-broker.go 1970-01-01 00:00:00 +0000 |
130 | +++ worker/provisioner/lxc-broker.go 2013-06-25 22:06:25 +0000 |
131 | @@ -0,0 +1,64 @@ |
132 | +// Copyright 2013 Canonical Ltd. |
133 | +// Licensed under the AGPLv3, see LICENCE file for details. |
134 | + |
135 | +package provisioner |
136 | + |
137 | +import ( |
138 | + "launchpad.net/golxc" |
139 | + "launchpad.net/juju-core/constraints" |
140 | + "launchpad.net/juju-core/container/lxc" |
141 | + "launchpad.net/juju-core/environs/config" |
142 | + "launchpad.net/juju-core/instance" |
143 | + "launchpad.net/juju-core/state" |
144 | + "launchpad.net/juju-core/state/api" |
145 | + "launchpad.net/loggo" |
146 | +) |
147 | + |
148 | +var lxcLogger = loggo.GetLogger("juju.provisioner.lxc") |
149 | + |
150 | +var _ Broker = (*lxcBroker)(nil) |
151 | + |
152 | +func NewLxcBroker(factory golxc.ContainerFactory, config *config.Config, tools *state.Tools) Broker { |
153 | + return &lxcBroker{ |
154 | + golxc: factory, |
155 | + manager: lxc.NewContainerManager(factory, "juju"), |
156 | + config: config, |
157 | + tools: tools, |
158 | + } |
159 | +} |
160 | + |
161 | +type lxcBroker struct { |
162 | + golxc golxc.ContainerFactory |
163 | + manager lxc.ContainerManager |
164 | + config *config.Config |
165 | + tools *state.Tools |
166 | +} |
167 | + |
168 | +func (broker *lxcBroker) StartInstance(machineId, machineNonce string, series string, cons constraints.Value, info *state.Info, apiInfo *api.Info) (instance.Instance, *instance.HardwareCharacteristics, error) { |
169 | + lxcLogger.Infof("starting lxc container for machineId: %s", machineId) |
170 | + |
171 | + inst, err := broker.manager.StartContainer(machineId, series, machineNonce, broker.tools, broker.config, info, apiInfo) |
172 | + if err != nil { |
173 | + lxcLogger.Errorf("failed to start container: %v", err) |
174 | + return nil, nil, err |
175 | + } |
176 | + return inst, nil, nil |
177 | +} |
178 | + |
179 | +// StopInstances shuts down the given instances. |
180 | +func (broker *lxcBroker) StopInstances(instances []instance.Instance) error { |
181 | + // TODO: potentially parallelise. |
182 | + for _, instance := range instances { |
183 | + lxcLogger.Infof("stopping lxc container for instance: %s", instance.Id()) |
184 | + if err := broker.manager.StopContainer(instance); err != nil { |
185 | + lxcLogger.Errorf("container did not stop: %v", err) |
186 | + return err |
187 | + } |
188 | + } |
189 | + return nil |
190 | +} |
191 | + |
192 | +// AllInstances only returns running containers. |
193 | +func (broker *lxcBroker) AllInstances() (result []instance.Instance, err error) { |
194 | + return broker.manager.ListContainers() |
195 | +} |
196 | |
197 | === added file 'worker/provisioner/lxc-broker_test.go' |
198 | --- worker/provisioner/lxc-broker_test.go 1970-01-01 00:00:00 +0000 |
199 | +++ worker/provisioner/lxc-broker_test.go 2013-06-25 22:06:25 +0000 |
200 | @@ -0,0 +1,127 @@ |
201 | +// Copyright 2013 Canonical Ltd. |
202 | +// Licensed under the AGPLv3, see LICENCE file for details. |
203 | + |
204 | +package provisioner_test |
205 | + |
206 | +import ( |
207 | + "path/filepath" |
208 | + |
209 | + . "launchpad.net/gocheck" |
210 | + "launchpad.net/golxc" |
211 | + "launchpad.net/juju-core/constraints" |
212 | + "launchpad.net/juju-core/container/lxc" |
213 | + "launchpad.net/juju-core/container/lxc/mock" |
214 | + "launchpad.net/juju-core/instance" |
215 | + jujutesting "launchpad.net/juju-core/juju/testing" |
216 | + "launchpad.net/juju-core/state" |
217 | + "launchpad.net/juju-core/testing" |
218 | + . "launchpad.net/juju-core/testing/checkers" |
219 | + "launchpad.net/juju-core/version" |
220 | + "launchpad.net/juju-core/worker/provisioner" |
221 | +) |
222 | + |
223 | +type lxcBrokerSuite struct { |
224 | + testing.LoggingSuite |
225 | + golxc golxc.ContainerFactory |
226 | + broker provisioner.Broker |
227 | + containerDir string |
228 | + removedDir string |
229 | + lxcDir string |
230 | + oldContainerDir string |
231 | + oldRemovedDir string |
232 | + oldLxcContainerDir string |
233 | +} |
234 | + |
235 | +var _ = Suite(&lxcBrokerSuite{}) |
236 | + |
237 | +func (s *lxcBrokerSuite) SetUpSuite(c *C) { |
238 | + s.LoggingSuite.SetUpSuite(c) |
239 | +} |
240 | + |
241 | +func (s *lxcBrokerSuite) TearDownSuite(c *C) { |
242 | + s.LoggingSuite.TearDownSuite(c) |
243 | +} |
244 | + |
245 | +func (s *lxcBrokerSuite) SetUpTest(c *C) { |
246 | + s.LoggingSuite.SetUpTest(c) |
247 | + s.containerDir = c.MkDir() |
248 | + s.oldContainerDir = lxc.SetContainerDir(s.containerDir) |
249 | + s.removedDir = c.MkDir() |
250 | + s.oldRemovedDir = lxc.SetRemovedContainerDir(s.removedDir) |
251 | + s.lxcDir = c.MkDir() |
252 | + s.oldLxcContainerDir = lxc.SetLxcContainerDir(s.lxcDir) |
253 | + s.golxc = mock.MockFactory() |
254 | + tools := &state.Tools{ |
255 | + Binary: version.MustParseBinary("2.3.4-foo-bar"), |
256 | + URL: "http://tools.example.com/2.3.4-foo-bar.tgz", |
257 | + } |
258 | + s.broker = provisioner.NewLxcBroker(s.golxc, testing.EnvironConfig(c), tools) |
259 | +} |
260 | + |
261 | +func (s *lxcBrokerSuite) TearDownTest(c *C) { |
262 | + lxc.SetContainerDir(s.oldContainerDir) |
263 | + lxc.SetLxcContainerDir(s.oldLxcContainerDir) |
264 | + lxc.SetRemovedContainerDir(s.oldRemovedDir) |
265 | + s.LoggingSuite.TearDownTest(c) |
266 | +} |
267 | + |
268 | +func (s *lxcBrokerSuite) startInstance(c *C, machineId string) instance.Instance { |
269 | + stateInfo := jujutesting.FakeStateInfo(machineId) |
270 | + apiInfo := jujutesting.FakeAPIInfo(machineId) |
271 | + |
272 | + series := "series" |
273 | + nonce := "fake-nonce" |
274 | + cons := constraints.Value{} |
275 | + lxc, _, err := s.broker.StartInstance(machineId, nonce, series, cons, stateInfo, apiInfo) |
276 | + c.Assert(err, IsNil) |
277 | + return lxc |
278 | +} |
279 | + |
280 | +func (s *lxcBrokerSuite) TestStartInstance(c *C) { |
281 | + machineId := "1/lxc/0" |
282 | + lxc := s.startInstance(c, machineId) |
283 | + c.Assert(lxc.Id(), Equals, instance.Id("juju-machine-1-lxc-0")) |
284 | + c.Assert(s.lxcContainerDir(lxc), IsDirectory) |
285 | + s.assertInstances(c, lxc) |
286 | +} |
287 | + |
288 | +func (s *lxcBrokerSuite) TestStopInstance(c *C) { |
289 | + lxc0 := s.startInstance(c, "1/lxc/0") |
290 | + lxc1 := s.startInstance(c, "1/lxc/1") |
291 | + lxc2 := s.startInstance(c, "1/lxc/2") |
292 | + |
293 | + err := s.broker.StopInstances([]instance.Instance{lxc0}) |
294 | + c.Assert(err, IsNil) |
295 | + s.assertInstances(c, lxc1, lxc2) |
296 | + c.Assert(s.lxcContainerDir(lxc0), DoesNotExist) |
297 | + c.Assert(s.lxcRemovedContainerDir(lxc0), IsDirectory) |
298 | + |
299 | + err = s.broker.StopInstances([]instance.Instance{lxc1, lxc2}) |
300 | + c.Assert(err, IsNil) |
301 | + s.assertInstances(c) |
302 | +} |
303 | + |
304 | +func (s *lxcBrokerSuite) TestAllInstances(c *C) { |
305 | + lxc0 := s.startInstance(c, "1/lxc/0") |
306 | + lxc1 := s.startInstance(c, "1/lxc/1") |
307 | + s.assertInstances(c, lxc0, lxc1) |
308 | + |
309 | + err := s.broker.StopInstances([]instance.Instance{lxc1}) |
310 | + c.Assert(err, IsNil) |
311 | + lxc2 := s.startInstance(c, "1/lxc/2") |
312 | + s.assertInstances(c, lxc0, lxc2) |
313 | +} |
314 | + |
315 | +func (s *lxcBrokerSuite) assertInstances(c *C, inst ...instance.Instance) { |
316 | + results, err := s.broker.AllInstances() |
317 | + c.Assert(err, IsNil) |
318 | + testing.MatchInstances(c, results, inst...) |
319 | +} |
320 | + |
321 | +func (s *lxcBrokerSuite) lxcContainerDir(inst instance.Instance) string { |
322 | + return filepath.Join(s.containerDir, string(inst.Id())) |
323 | +} |
324 | + |
325 | +func (s *lxcBrokerSuite) lxcRemovedContainerDir(inst instance.Instance) string { |
326 | + return filepath.Join(s.removedDir, string(inst.Id())) |
327 | +} |
328 | |
329 | === modified file 'worker/provisioner/provisioner.go' |
330 | --- worker/provisioner/provisioner.go 2013-06-20 11:03:10 +0000 |
331 | +++ worker/provisioner/provisioner.go 2013-06-25 22:06:25 +0000 |
332 | @@ -80,7 +80,7 @@ |
333 | // to the environment config. |
334 | machinesWatcher := p.st.WatchEnvironMachines() |
335 | environmentBroker := newEnvironBroker(p.environ) |
336 | - environmentProvisioner := newProvisionerTask( |
337 | + environmentProvisioner := NewProvisionerTask( |
338 | p.machineId, |
339 | p.st, |
340 | machinesWatcher, |
341 | |
342 | === modified file 'worker/provisioner/provisioner_task.go' |
343 | --- worker/provisioner/provisioner_task.go 2013-06-20 04:27:32 +0000 |
344 | +++ worker/provisioner/provisioner_task.go 2013-06-25 22:06:25 +0000 |
345 | @@ -34,7 +34,7 @@ |
346 | Machine(id string) (*state.Machine, error) |
347 | } |
348 | |
349 | -func newProvisionerTask( |
350 | +func NewProvisionerTask( |
351 | machineId string, |
352 | machineGetter MachineGetter, |
353 | watcher Watcher, |
Reviewers: mp+170713_ code.launchpad. net,
Message:
Please take a look.
Description:
Implement the lxc broker for the provisioner
Had to make some test functions and helpers exported.
https:/ /code.launchpad .net/~thumper/ juju-core/ lxc-broker/ +merge/ 170713
Requires: /code.launchpad .net/~thumper/ juju-core/ lxc-container/ +merge/ 169980
https:/
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/10409049/
Affected files: lxc/export_ test.go lxc/lxc_ test.go lxc/mock/ mock-lxc. go lxc/test. go provisioner/ lxc-broker. go provisioner/ lxc-broker_ test.go provisioner/ provisioner. go provisioner/ provisioner_ task.go
A [revision details]
D container/
M container/
M container/
A container/
A worker/
A worker/
M worker/
M worker/