Merge lp:~thumper/juju-core/local-lxc-clone-settings into lp:~go-bot/juju-core/trunk

Proposed by Tim Penhey
Status: Merged
Approved by: Tim Penhey
Approved revision: no longer in the source branch.
Merged at revision: 2432
Proposed branch: lp:~thumper/juju-core/local-lxc-clone-settings
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 590 lines (+220/-57)
13 files modified
cmd/juju/help_topics.go (+18/-0)
container/lxc/initialisation_test.go (+0/-6)
container/lxc/lxc.go (+8/-2)
container/lxc/lxc_test.go (+29/-2)
container/lxc/mock/mock-lxc.go (+18/-9)
provider/local/config.go (+14/-0)
provider/local/environ.go (+9/-10)
provider/local/environprovider.go (+16/-5)
provider/local/environprovider_test.go (+100/-0)
provider/local/export_test.go (+7/-8)
provider/local/lxc.go (+0/-8)
provider/local/lxc_test.go (+0/-6)
provider/local/prereqs.go (+1/-1)
To merge this branch: bzr merge lp:~thumper/juju-core/local-lxc-clone-settings
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+211237@code.launchpad.net

Commit message

Add local options lxc-clone and lxc-clone-aufs

These new values default to the existing behaviour.
That being that if the user is on trusty or above,
they default to true, otherwise false.

The reason for these values is two-fold. Firstly,
aufs isn't working on power, and we want to be able
to test effectively there. Secondly this gives the
user on saucy the ability to try it out (not originally
planned, but a helpful side effect).

https://codereview.appspot.com/74660044/

Description of the change

Add local options lxc-clone and lxc-clone-aufs

These new values default to the existing behaviour.
That being that if the user is on trusty or above,
they default to true, otherwise false.

The reason for these values is two-fold. Firstly,
aufs isn't working on power, and we want to be able
to test effectively there. Secondly this gives the
user on saucy the ability to try it out (not originally
planned, but a helpful side effect).

https://codereview.appspot.com/74660044/

To post a comment you must log in.
Revision history for this message
Tim Penhey (thumper) wrote :

Reviewers: mp+211237_code.launchpad.net,

Message:
Please take a look.

Description:
Add local options lxc-clone and lxc-clone-aufs

These new values default to the existing behaviour.
That being that if the user is on trusty or above,
they default to true, otherwise false.

The reason for these values is two-fold. Firstly,
aufs isn't working on power, and we want to be able
to test effectively there. Secondly this gives the
user on saucy the ability to try it out (not originally
planned, but a helpful side effect).

https://code.launchpad.net/~thumper/juju-core/local-lxc-clone-settings/+merge/211237

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/74660044/

Affected files (+206, -34 lines):
   A [revision details]
   M cmd/juju/help_topics.go
   M container/lxc/initialisation_test.go
   M container/lxc/lxc.go
   M container/lxc/lxc_test.go
   M container/lxc/mock/mock-lxc.go
   M provider/local/config.go
   M provider/local/environ.go
   M provider/local/environprovider.go
   M provider/local/environprovider_test.go

Revision history for this message
Ian Booth (wallyworld) wrote :

A few initial questions in the comments.
Also, now that there are config options for clone, doesn't that mean we
can now drop JUJU_TESTING_LXC_FORCE_SLOW, since we can just use config
with lxc-clone=false?

https://codereview.appspot.com/74660044/diff/1/cmd/juju/help_topics.go
File cmd/juju/help_topics.go (right):

https://codereview.appspot.com/74660044/diff/1/cmd/juju/help_topics.go#newcode86
cmd/juju/help_topics.go:86: You can override the clone use by specifying
... the use of clone...

https://codereview.appspot.com/74660044/diff/1/cmd/juju/help_topics.go#newcode90
cmd/juju/help_topics.go:90: in the environments.yaml file for the local
block. If you have the main
They may not have called their local provider "local", or they may have
more than one defined. I'd just say "in the configuration for your local
provider".

https://codereview.appspot.com/74660044/diff/1/container/lxc/lxc.go
File container/lxc/lxc.go (right):

https://codereview.appspot.com/74660044/diff/1/container/lxc/lxc.go#newcode165
container/lxc/lxc.go:165: if manager.backingFilesystem == Btrfs ||
manager.useAUFS {
This logic looks different that what was there before? We are adding an
extra "manager.backingFilesystem == Btrfs" check?

https://codereview.appspot.com/74660044/diff/1/provider/local/config.go
File provider/local/config.go (right):

https://codereview.appspot.com/74660044/diff/1/provider/local/config.go#newcode29
provider/local/config.go:29: "lxc-clone-aufs": schema.String(),
why not schema.Bool()?
(used with schema.Defaults to ensure default is true)

https://codereview.appspot.com/74660044/diff/1/provider/local/config.go#newcode110
provider/local/config.go:110: func (c *environConfig) lxcClone() string
{
so this would return bool as per previous comment

https://codereview.appspot.com/74660044/diff/1/provider/local/config.go#newcode115
provider/local/config.go:115: func (c *environConfig) lxcCloneAUFS()
string {
ditto

https://codereview.appspot.com/74660044/

Revision history for this message
Tim Penhey (thumper) wrote :

Please take a look.

https://codereview.appspot.com/74660044/diff/1/cmd/juju/help_topics.go
File cmd/juju/help_topics.go (right):

https://codereview.appspot.com/74660044/diff/1/cmd/juju/help_topics.go#newcode86
cmd/juju/help_topics.go:86: You can override the clone use by specifying
On 2014/03/17 03:08:52, wallyworld wrote:
> ... the use of clone...

Done.

https://codereview.appspot.com/74660044/diff/1/cmd/juju/help_topics.go#newcode90
cmd/juju/help_topics.go:90: in the environments.yaml file for the local
block. If you have the main
On 2014/03/17 03:08:52, wallyworld wrote:
> They may not have called their local provider "local", or they may
have more
> than one defined. I'd just say "in the configuration for your local
provider".

Done.

https://codereview.appspot.com/74660044/diff/1/container/lxc/lxc.go
File container/lxc/lxc.go (right):

https://codereview.appspot.com/74660044/diff/1/container/lxc/lxc.go#newcode165
container/lxc/lxc.go:165: if manager.backingFilesystem == Btrfs ||
manager.useAUFS {
On 2014/03/17 03:08:52, wallyworld wrote:
> This logic looks different that what was there before? We are adding
an extra
> "manager.backingFilesystem == Btrfs" check?

What was there before was related to the second check below where
we now also check that the manager has useAUFS as true in order to
specify the aufs backingstore.

This first check is the one were we only want to specify --snapshot
when we have btrfs or aufs, but not in the case where we want to clone
without aufs.

https://codereview.appspot.com/74660044/diff/1/provider/local/config.go
File provider/local/config.go (right):

https://codereview.appspot.com/74660044/diff/1/provider/local/config.go#newcode29
provider/local/config.go:29: "lxc-clone-aufs": schema.String(),
On 2014/03/17 03:08:52, wallyworld wrote:
> why not schema.Bool()?
> (used with schema.Defaults to ensure default is true)

Because there wasn't an easy way to identify whether
it was set or not. I needed three states, yes, no and
missing. If it is missing, and the container is lxc then
we specify values. If they are specified, we use them.

https://codereview.appspot.com/74660044/

Revision history for this message
Tim Penhey (thumper) wrote :
Revision history for this message
Ian Booth (wallyworld) wrote :

LGTM with typo fix

https://codereview.appspot.com/74660044/diff/10011/cmd/juju/help_topics.go
File cmd/juju/help_topics.go (right):

https://codereview.appspot.com/74660044/diff/10011/cmd/juju/help_topics.go#newcode90
cmd/juju/help_topics.go:90: in the configuration for you local provider.
  If you have the main container
s/you/your

https://codereview.appspot.com/74660044/

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

The attempt to merge lp:~thumper/juju-core/local-lxc-clone-settings into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.013s
ok launchpad.net/juju-core/agent 1.115s
ok launchpad.net/juju-core/agent/mongo 0.573s
ok launchpad.net/juju-core/agent/tools 0.201s
ok launchpad.net/juju-core/bzr 5.255s
ok launchpad.net/juju-core/cert 3.003s
ok launchpad.net/juju-core/charm 0.406s
? launchpad.net/juju-core/charm/hooks [no test files]
? launchpad.net/juju-core/charm/testing [no test files]
ok launchpad.net/juju-core/cloudinit 0.029s
ok launchpad.net/juju-core/cloudinit/sshinit 0.842s
ok launchpad.net/juju-core/cmd 0.166s
ok launchpad.net/juju-core/cmd/charm-admin 0.756s
? 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 189.681s
ok launchpad.net/juju-core/cmd/jujud 65.901s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 8.555s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/cmd/plugins/local 0.199s
? launchpad.net/juju-core/cmd/plugins/local/juju-local [no test files]
ok launchpad.net/juju-core/constraints 0.028s
ok launchpad.net/juju-core/container 0.038s
ok launchpad.net/juju-core/container/factory 0.044s
ok launchpad.net/juju-core/container/kvm 0.214s
ok launchpad.net/juju-core/container/kvm/mock 0.042s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 4.289s
? 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.250s
ok launchpad.net/juju-core/environs 2.069s
ok launchpad.net/juju-core/environs/bootstrap 3.346s
ok launchpad.net/juju-core/environs/cloudinit 0.446s
ok launchpad.net/juju-core/environs/config 3.191s
ok launchpad.net/juju-core/environs/configstore 0.037s
ok launchpad.net/juju-core/environs/filestorage 0.024s
ok launchpad.net/juju-core/environs/httpstorage 0.717s
ok launchpad.net/juju-core/environs/imagemetadata 0.433s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.044s
ok launchpad.net/juju-core/environs/jujutest 0.185s
ok launchpad.net/juju-core/environs/manual 15.968s
ok launchpad.net/juju-core/environs/simplestreams 0.230s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 1.053s
ok launchpad.net/juju-core/environs/storage 0.872s
ok launchpad.net/juju-core/environs/sync 43.766s
ok launchpad.net/juju-core/environs/testing 0.126s
ok launchpad.net/juju-core/environs/tools 4.533s
? launchpad.net/juju-core/environs/tools/testing [no test files]
ok launchpad.net/juju-core/errors 0.011s
ok launchpad.net/juju-core/instance 0.020s
? launchpad.net/juju-core/instance/testing [no test files]
ok launchpad.net/juju-core/juju 18.101s
ok launchpad.net/juju-core/juju/arch 0.02...

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

The attempt to merge lp:~thumper/juju-core/local-lxc-clone-settings into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.013s
ok launchpad.net/juju-core/agent 1.090s
ok launchpad.net/juju-core/agent/mongo 0.531s
ok launchpad.net/juju-core/agent/tools 0.283s
ok launchpad.net/juju-core/bzr 5.355s
ok launchpad.net/juju-core/cert 2.371s
ok launchpad.net/juju-core/charm 0.401s
? launchpad.net/juju-core/charm/hooks [no test files]
? launchpad.net/juju-core/charm/testing [no test files]
ok launchpad.net/juju-core/cloudinit 0.028s
ok launchpad.net/juju-core/cloudinit/sshinit 0.773s
ok launchpad.net/juju-core/cmd 0.160s
ok launchpad.net/juju-core/cmd/charm-admin 0.780s
? 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 188.131s
ok launchpad.net/juju-core/cmd/jujud 64.931s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 7.722s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/cmd/plugins/local 0.188s
? launchpad.net/juju-core/cmd/plugins/local/juju-local [no test files]
ok launchpad.net/juju-core/constraints 0.026s
ok launchpad.net/juju-core/container 0.038s
ok launchpad.net/juju-core/container/factory 0.040s
ok launchpad.net/juju-core/container/kvm 0.193s
ok launchpad.net/juju-core/container/kvm/mock 0.068s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 4.298s
? 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.221s
ok launchpad.net/juju-core/environs 2.130s
ok launchpad.net/juju-core/environs/bootstrap 3.189s
ok launchpad.net/juju-core/environs/cloudinit 0.451s
ok launchpad.net/juju-core/environs/config 1.909s
ok launchpad.net/juju-core/environs/configstore 0.029s
ok launchpad.net/juju-core/environs/filestorage 0.025s
ok launchpad.net/juju-core/environs/httpstorage 0.750s
ok launchpad.net/juju-core/environs/imagemetadata 0.467s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.045s
ok launchpad.net/juju-core/environs/jujutest 0.158s
ok launchpad.net/juju-core/environs/manual 11.327s
ok launchpad.net/juju-core/environs/simplestreams 0.247s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 1.004s
ok launchpad.net/juju-core/environs/storage 1.004s
ok launchpad.net/juju-core/environs/sync 43.452s
ok launchpad.net/juju-core/environs/testing 0.139s
ok launchpad.net/juju-core/environs/tools 4.795s
? launchpad.net/juju-core/environs/tools/testing [no test files]
ok launchpad.net/juju-core/errors 0.011s
ok launchpad.net/juju-core/instance 0.020s
? launchpad.net/juju-core/instance/testing [no test files]
ok launchpad.net/juju-core/juju 17.708s
ok launchpad.net/juju-core/juju/arch 0.02...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'cmd/juju/help_topics.go'
--- cmd/juju/help_topics.go 2014-03-11 12:12:53 +0000
+++ cmd/juju/help_topics.go 2014-03-17 22:08:13 +0000
@@ -79,6 +79,24 @@
79 juju deploy wordpress79 juju deploy wordpress
80 juju add-relation wordpress mysql80 juju add-relation wordpress mysql
8181
82As of trusty, the local provider will prefer to use lxc-clone to create
83the machines. A 'template' container is created with the name
84 juju-<series>-tempalte
85where <series> is the OS series, for example 'juju-precise-template'.
86You can override the use of clone by specifying
87 use-clone: true
88or
89 use-clone: false
90in the configuration for your local provider. If you have the main container
91directory mounted on a btrfs partition, then the clone will be using btrfs
92snapshots to create the containers. This means that the clones use up much
93less disk space. If you do not have btrfs, lxc will attempt to use aufs
94(which is an overlay type filesystem). You can explicitly ask Juju to create
95full containers and not overlays by specifying the following in the provider
96configuration:
97 use-clone-aufs: false
98
99
82References:100References:
83101
84 http://askubuntu.com/questions/65359/how-do-i-configure-juju-for-local-usage102 http://askubuntu.com/questions/65359/how-do-i-configure-juju-for-local-usage
85103
=== modified file 'container/lxc/initialisation_test.go'
--- container/lxc/initialisation_test.go 2014-03-13 17:21:05 +0000
+++ container/lxc/initialisation_test.go 2014-03-17 22:08:13 +0000
@@ -4,18 +4,12 @@
4package lxc4package lxc
55
6import (6import (
7 stdtesting "testing"
8
9 gc "launchpad.net/gocheck"7 gc "launchpad.net/gocheck"
108
11 "launchpad.net/juju-core/testing/testbase"9 "launchpad.net/juju-core/testing/testbase"
12 "launchpad.net/juju-core/utils"10 "launchpad.net/juju-core/utils"
13)11)
1412
15func Test(t *stdtesting.T) {
16 gc.TestingT(t)
17}
18
19type InitialiserSuite struct {13type InitialiserSuite struct {
20 testbase.LoggingSuite14 testbase.LoggingSuite
21}15}
2216
=== modified file 'container/lxc/lxc.go'
--- container/lxc/lxc.go 2014-03-13 16:03:45 +0000
+++ container/lxc/lxc.go 2014-03-17 22:08:13 +0000
@@ -69,6 +69,7 @@
69 name string69 name string
70 logdir string70 logdir string
71 createWithClone bool71 createWithClone bool
72 useAUFS bool
72 backingFilesystem string73 backingFilesystem string
73}74}
7475
@@ -91,6 +92,7 @@
91 // If it fails to parse, the value is false, and this suits92 // If it fails to parse, the value is false, and this suits
92 // us fine.93 // us fine.
93 useClone, _ := strconv.ParseBool(conf.PopValue("use-clone"))94 useClone, _ := strconv.ParseBool(conf.PopValue("use-clone"))
95 useAUFS, _ := strconv.ParseBool(conf.PopValue("use-aufs"))
94 backingFS, err := containerDirFilesystem()96 backingFS, err := containerDirFilesystem()
95 if err != nil {97 if err != nil {
96 // Especially in tests, or a bot, the lxc dir may not exist98 // Especially in tests, or a bot, the lxc dir may not exist
@@ -105,6 +107,7 @@
105 name: name,107 name: name,
106 logdir: logDir,108 logdir: logDir,
107 createWithClone: useClone,109 createWithClone: useClone,
110 useAUFS: useAUFS,
108 backingFilesystem: backingFS,111 backingFilesystem: backingFS,
109 }, nil112 }, nil
110}113}
@@ -158,8 +161,11 @@
158 "--userdata", userDataFilename, // Our groovey cloud-init161 "--userdata", userDataFilename, // Our groovey cloud-init
159 "--hostid", name, // Use the container name as the hostid162 "--hostid", name, // Use the container name as the hostid
160 }163 }
161 extraCloneArgs := []string{"--snapshot"}164 var extraCloneArgs []string
162 if manager.backingFilesystem != Btrfs {165 if manager.backingFilesystem == Btrfs || manager.useAUFS {
166 extraCloneArgs = append(extraCloneArgs, "--snapshot")
167 }
168 if manager.backingFilesystem != Btrfs && manager.useAUFS {
163 extraCloneArgs = append(extraCloneArgs, "--backingstore", "aufs")169 extraCloneArgs = append(extraCloneArgs, "--backingstore", "aufs")
164 }170 }
165171
166172
=== modified file 'container/lxc/lxc_test.go'
--- container/lxc/lxc_test.go 2014-03-13 07:54:56 +0000
+++ container/lxc/lxc_test.go 2014-03-17 22:08:13 +0000
@@ -38,6 +38,7 @@
3838
39 events chan mock.Event39 events chan mock.Event
40 useClone bool40 useClone bool
41 useAUFS bool
41}42}
4243
43var _ = gc.Suite(&LxcSuite{})44var _ = gc.Suite(&LxcSuite{})
@@ -95,6 +96,9 @@
95 if s.useClone {96 if s.useClone {
96 params["use-clone"] = "true"97 params["use-clone"] = "true"
97 }98 }
99 if s.useAUFS {
100 params["use-aufs"] = "true"
101 }
98 manager, err := lxc.NewContainerManager(params)102 manager, err := lxc.NewContainerManager(params)
99 c.Assert(err, gc.IsNil)103 c.Assert(err, gc.IsNil)
100 return manager104 return manager
@@ -226,8 +230,31 @@
226 manager := s.makeManager(c, "test")230 manager := s.makeManager(c, "test")
227 instance := containertesting.StartContainer(c, manager, "1")231 instance := containertesting.StartContainer(c, manager, "1")
228 name := string(instance.Id())232 name := string(instance.Id())
229 s.AssertEvent(c, <-s.events, mock.Cloned, "juju-series-template")233 cloned := <-s.events
230 s.AssertEvent(c, <-s.events, mock.Started, name)234 s.AssertEvent(c, cloned, mock.Cloned, "juju-series-template")
235 c.Assert(cloned.Args, gc.IsNil)
236 s.AssertEvent(c, <-s.events, mock.Started, name)
237}
238
239func (s *LxcSuite) TestStartContainerEventsWithCloneExistingTemplateAUFS(c *gc.C) {
240 s.createTemplate(c)
241 s.PatchValue(&s.useClone, true)
242 s.PatchValue(&s.useAUFS, true)
243 manager := s.makeManager(c, "test")
244 instance := containertesting.StartContainer(c, manager, "1")
245 name := string(instance.Id())
246 cloned := <-s.events
247 s.AssertEvent(c, cloned, mock.Cloned, "juju-series-template")
248 c.Assert(cloned.Args, gc.DeepEquals, []string{"--snapshot", "--backingstore", "aufs"})
249 s.AssertEvent(c, <-s.events, mock.Started, name)
250}
251
252func (s *LxcSuite) TestStartContainerWithCloneMountsAndAutostarts(c *gc.C) {
253 s.createTemplate(c)
254 s.PatchValue(&s.useClone, true)
255 manager := s.makeManager(c, "test")
256 instance := containertesting.StartContainer(c, manager, "1")
257 name := string(instance.Id())
231258
232 autostartLink := lxc.RestartSymlink(name)259 autostartLink := lxc.RestartSymlink(name)
233 config, err := ioutil.ReadFile(lxc.ContainerConfigFilename(name))260 config, err := ioutil.ReadFile(lxc.ContainerConfigFilename(name))
234261
=== modified file 'container/lxc/mock/mock-lxc.go'
--- container/lxc/mock/mock-lxc.go 2014-03-12 04:27:25 +0000
+++ container/lxc/mock/mock-lxc.go 2014-03-17 22:08:13 +0000
@@ -54,8 +54,10 @@
54}54}
5555
56type Event struct {56type Event struct {
57 Action Action57 Action Action
58 InstanceId string58 InstanceId string
59 Args []string
60 TemplateArgs []string
59}61}
6062
61type ContainerFactory interface {63type ContainerFactory interface {
@@ -124,7 +126,7 @@
124 return err126 return err
125 }127 }
126 mock.setState(golxc.StateStopped)128 mock.setState(golxc.StateStopped)
127 mock.factory.notify(Created, mock.name)129 mock.factory.notify(eventArgs(Created, mock.name, extraArgs, templateArgs))
128 return nil130 return nil
129}131}
130132
@@ -140,7 +142,7 @@
140 filepath.Join(container.ContainerDir, mock.name, "console.log"),142 filepath.Join(container.ContainerDir, mock.name, "console.log"),
141 []byte("fake console.log"), 0644)143 []byte("fake console.log"), 0644)
142 mock.setState(golxc.StateRunning)144 mock.setState(golxc.StateRunning)
143 mock.factory.notify(Started, mock.name)145 mock.factory.notify(event(Started, mock.name))
144 return nil146 return nil
145}147}
146148
@@ -153,7 +155,7 @@
153 return fmt.Errorf("container is already stopped")155 return fmt.Errorf("container is already stopped")
154 }156 }
155 mock.setState(golxc.StateStopped)157 mock.setState(golxc.StateStopped)
156 mock.factory.notify(Stopped, mock.name)158 mock.factory.notify(event(Stopped, mock.name))
157 return nil159 return nil
158}160}
159161
@@ -183,7 +185,7 @@
183 return nil, err185 return nil, err
184 }186 }
185187
186 mock.factory.notify(Cloned, mock.name)188 mock.factory.notify(eventArgs(Cloned, mock.name, extraArgs, templateArgs))
187 return container, nil189 return container, nil
188}190}
189191
@@ -209,7 +211,7 @@
209 }211 }
210 delete(mock.factory.instances, mock.name)212 delete(mock.factory.instances, mock.name)
211 mock.setState(golxc.StateUnknown)213 mock.setState(golxc.StateUnknown)
212 mock.factory.notify(Destroyed, mock.name)214 mock.factory.notify(event(Destroyed, mock.name))
213 return nil215 return nil
214}216}
215217
@@ -290,8 +292,15 @@
290 return292 return
291}293}
292294
293func (mock *mockFactory) notify(action Action, instanceId string) {295func event(action Action, instanceId string) Event {
294 event := Event{action, instanceId}296 return Event{action, instanceId, nil, nil}
297}
298
299func eventArgs(action Action, instanceId string, args []string, template []string) Event {
300 return Event{action, instanceId, args, template}
301}
302
303func (mock *mockFactory) notify(event Event) {
295 for _, c := range mock.listeners {304 for _, c := range mock.listeners {
296 c <- event305 c <- event
297 }306 }
298307
=== modified file 'provider/local/config.go'
--- provider/local/config.go 2014-02-27 05:24:43 +0000
+++ provider/local/config.go 2014-03-17 22:08:13 +0000
@@ -25,6 +25,8 @@
25 "container": schema.String(),25 "container": schema.String(),
26 "storage-port": schema.ForceInt(),26 "storage-port": schema.ForceInt(),
27 "namespace": schema.String(),27 "namespace": schema.String(),
28 "lxc-clone": schema.String(),
29 "lxc-clone-aufs": schema.String(),
28 }30 }
29 // The port defaults below are not entirely arbitrary. Local user web31 // The port defaults below are not entirely arbitrary. Local user web
30 // frameworks often use 8000 or 8080, so I didn't want to use either of32 // frameworks often use 8000 or 8080, so I didn't want to use either of
@@ -37,6 +39,8 @@
37 "bootstrap-ip": schema.Omit,39 "bootstrap-ip": schema.Omit,
38 "storage-port": 8040,40 "storage-port": 8040,
39 "namespace": "",41 "namespace": "",
42 "lxc-clone": schema.Omit,
43 "lxc-clone-aufs": schema.Omit,
40 }44 }
41)45)
4246
@@ -103,6 +107,16 @@
103 return filepath.Join(c.rootDir(), filename)107 return filepath.Join(c.rootDir(), filename)
104}108}
105109
110func (c *environConfig) lxcClone() string {
111 value, _ := c.attrs["lxc-clone"].(string)
112 return value
113}
114
115func (c *environConfig) lxcCloneAUFS() string {
116 value, _ := c.attrs["lxc-clone-aufs"].(string)
117 return value
118}
119
106func (c *environConfig) createDirs() error {120func (c *environConfig) createDirs() error {
107 for _, dirname := range []string{121 for _, dirname := range []string{
108 c.storageDir(),122 c.storageDir(),
109123
=== modified file 'provider/local/environ.go'
--- provider/local/environ.go 2014-03-17 08:25:06 +0000
+++ provider/local/environ.go 2014-03-17 22:08:13 +0000
@@ -10,7 +10,6 @@
10 "os/exec"10 "os/exec"
11 "path/filepath"11 "path/filepath"
12 "regexp"12 "regexp"
13 "strconv"
14 "strings"13 "strings"
15 "sync"14 "sync"
16 "syscall"15 "syscall"
@@ -61,7 +60,6 @@
61 localStorage storage.Storage60 localStorage storage.Storage
62 storageListener net.Listener61 storageListener net.Listener
63 containerManager container.Manager62 containerManager container.Manager
64 fastLXC bool
65}63}
6664
67// GetToolsSources returns a list of sources which are used to search for simplestreams tools metadata.65// GetToolsSources returns a list of sources which are used to search for simplestreams tools metadata.
@@ -214,15 +212,16 @@
214 env.config = ecfg212 env.config = ecfg
215 env.name = ecfg.Name()213 env.name = ecfg.Name()
216 containerType := ecfg.container()214 containerType := ecfg.container()
217 env.fastLXC = useFastLXC(containerType)215 managerConfig := container.ManagerConfig{
218216 container.ConfigName: env.config.namespace(),
217 container.ConfigLogDir: env.config.logDir(),
218 }
219 if containerType == instance.LXC {
220 managerConfig["use-clone"] = env.config.lxcClone()
221 managerConfig["use-aufs"] = env.config.lxcCloneAUFS()
222 }
219 env.containerManager, err = factory.NewContainerManager(223 env.containerManager, err = factory.NewContainerManager(
220 containerType,224 containerType, managerConfig)
221 container.ManagerConfig{
222 container.ConfigName: env.config.namespace(),
223 container.ConfigLogDir: env.config.logDir(),
224 "use-clone": strconv.FormatBool(env.fastLXC),
225 })
226 if err != nil {225 if err != nil {
227 return err226 return err
228 }227 }
229228
=== modified file 'provider/local/environprovider.go'
--- provider/local/environprovider.go 2014-03-12 11:04:20 +0000
+++ provider/local/environprovider.go 2014-03-17 22:08:13 +0000
@@ -8,6 +8,7 @@
8 "net"8 "net"
9 "os"9 "os"
10 "os/user"10 "os/user"
11 "strconv"
11 "syscall"12 "syscall"
1213
13 "github.com/juju/loggo"14 "github.com/juju/loggo"
@@ -180,15 +181,15 @@
180 localConfig := newEnvironConfig(cfg, validated)181 localConfig := newEnvironConfig(cfg, validated)
181 // Before potentially creating directories, make sure that the182 // Before potentially creating directories, make sure that the
182 // root directory has not changed.183 // root directory has not changed.
184 containerType := localConfig.container()
183 if old != nil {185 if old != nil {
184 oldLocalConfig, err := provider.newConfig(old)186 oldLocalConfig, err := provider.newConfig(old)
185 if err != nil {187 if err != nil {
186 return nil, fmt.Errorf("old config is not a valid local config: %v", old)188 return nil, fmt.Errorf("old config is not a valid local config: %v", old)
187 }189 }
188 if localConfig.container() != oldLocalConfig.container() {190 if containerType != oldLocalConfig.container() {
189 return nil, fmt.Errorf("cannot change container from %q to %q",191 return nil, fmt.Errorf("cannot change container from %q to %q",
190 oldLocalConfig.container(),192 oldLocalConfig.container(), containerType)
191 localConfig.container())
192 }193 }
193 if localConfig.rootDir() != oldLocalConfig.rootDir() {194 if localConfig.rootDir() != oldLocalConfig.rootDir() {
194 return nil, fmt.Errorf("cannot change root-dir from %q to %q",195 return nil, fmt.Errorf("cannot change root-dir from %q to %q",
@@ -207,8 +208,8 @@
207 }208 }
208 }209 }
209 // Currently only supported containers are "lxc" and "kvm".210 // Currently only supported containers are "lxc" and "kvm".
210 if localConfig.container() != instance.LXC && localConfig.container() != instance.KVM {211 if containerType != instance.LXC && containerType != instance.KVM {
211 return nil, fmt.Errorf("unsupported container type: %q", localConfig.container())212 return nil, fmt.Errorf("unsupported container type: %q", containerType)
212 }213 }
213 dir, err := utils.NormalizePath(localConfig.rootDir())214 dir, err := utils.NormalizePath(localConfig.rootDir())
214 if err != nil {215 if err != nil {
@@ -220,6 +221,16 @@
220 // Always assign the normalized path.221 // Always assign the normalized path.
221 localConfig.attrs["root-dir"] = dir222 localConfig.attrs["root-dir"] = dir
222223
224 if containerType != instance.KVM {
225 fastOptionAvailable := strconv.FormatBool(useFastLXC(containerType))
226 if _, found := localConfig.attrs["lxc-clone"]; !found {
227 localConfig.attrs["lxc-clone"] = fastOptionAvailable
228 }
229 if _, found := localConfig.attrs["lxc-clone-aufs"]; !found {
230 localConfig.attrs["lxc-clone-aufs"] = fastOptionAvailable
231 }
232 }
233
223 // Apply the coerced unknown values back into the config.234 // Apply the coerced unknown values back into the config.
224 return cfg.Apply(localConfig.attrs)235 return cfg.Apply(localConfig.attrs)
225}236}
226237
=== modified file 'provider/local/environprovider_test.go'
--- provider/local/environprovider_test.go 2014-03-09 20:48:29 +0000
+++ provider/local/environprovider_test.go 2014-03-17 22:08:13 +0000
@@ -8,11 +8,14 @@
8 "os/user"8 "os/user"
99
10 "github.com/juju/loggo"10 "github.com/juju/loggo"
11 jc "github.com/juju/testing/checkers"
11 gc "launchpad.net/gocheck"12 gc "launchpad.net/gocheck"
1213
14 "launchpad.net/juju-core/container/kvm"
13 lxctesting "launchpad.net/juju-core/container/lxc/testing"15 lxctesting "launchpad.net/juju-core/container/lxc/testing"
14 "launchpad.net/juju-core/environs"16 "launchpad.net/juju-core/environs"
15 "launchpad.net/juju-core/environs/config"17 "launchpad.net/juju-core/environs/config"
18 "launchpad.net/juju-core/instance"
16 "launchpad.net/juju-core/juju/osenv"19 "launchpad.net/juju-core/juju/osenv"
17 "launchpad.net/juju-core/provider"20 "launchpad.net/juju-core/provider"
18 "launchpad.net/juju-core/provider/local"21 "launchpad.net/juju-core/provider/local"
@@ -297,3 +300,100 @@
297 }300 }
298 }301 }
299}302}
303
304func (s *prepareSuite) TestFastLXCClone(c *gc.C) {
305 s.PatchValue(local.DetectAptProxies, func() (osenv.ProxySettings, error) {
306 return osenv.ProxySettings{}, nil
307 })
308 s.PatchValue(&kvm.IsKVMSupported, func() (bool, error) {
309 return true, nil
310 })
311 s.PatchValue(&local.VerifyPrerequisites, func(containerType instance.ContainerType) error {
312 return nil
313 })
314 basecfg, err := config.New(config.UseDefaults, map[string]interface{}{
315 "type": "local",
316 "name": "test",
317 })
318 provider, err := environs.Provider("local")
319 c.Assert(err, gc.IsNil)
320
321 type test struct {
322 systemDefault bool
323 extraConfig map[string]interface{}
324 expectClone string
325 expectAUFS string
326 }
327 tests := []test{{
328 extraConfig: map[string]interface{}{
329 "container": "lxc",
330 },
331 expectClone: "false",
332 expectAUFS: "false",
333 }, {
334 extraConfig: map[string]interface{}{
335 "container": "lxc",
336 "lxc-clone": "true",
337 },
338 expectClone: "true",
339 expectAUFS: "false",
340 }, {
341 systemDefault: true,
342 extraConfig: map[string]interface{}{
343 "container": "lxc",
344 },
345 expectClone: "true",
346 expectAUFS: "true",
347 }, {
348 systemDefault: true,
349 extraConfig: map[string]interface{}{
350 "container": "kvm",
351 },
352 }, {
353 systemDefault: true,
354 extraConfig: map[string]interface{}{
355 "container": "lxc",
356 "lxc-clone": "false",
357 },
358 expectClone: "false",
359 expectAUFS: "true",
360 }, {
361 systemDefault: true,
362 extraConfig: map[string]interface{}{
363 "container": "lxc",
364 "lxc-clone-aufs": "false",
365 },
366 expectClone: "true",
367 expectAUFS: "false",
368 }}
369
370 for i, test := range tests {
371 c.Logf("test %d: %v", i, test)
372
373 releaseVersion := "12.04"
374 if test.systemDefault {
375 releaseVersion = "14.04"
376 }
377 s.PatchValue(local.ReleaseVersion, func() string { return releaseVersion })
378 testConfig, err := basecfg.Apply(test.extraConfig)
379 c.Assert(err, gc.IsNil)
380 env, err := provider.Open(testConfig)
381 c.Assert(err, gc.IsNil)
382 localAttributes := env.Config().UnknownAttrs()
383
384 if test.expectClone != "" {
385 c.Assert(localAttributes["lxc-clone"], gc.Equals, test.expectClone)
386 } else {
387 _, found := localAttributes["lxc-clone"]
388 c.Assert(found, jc.IsFalse)
389 }
390
391 if test.expectAUFS != "" {
392 c.Assert(localAttributes["lxc-clone-aufs"], gc.Equals, test.expectAUFS)
393 } else {
394 _, found := localAttributes["lxc-clone-aufs"]
395 c.Assert(found, jc.IsFalse)
396 }
397
398 }
399}
300400
=== modified file 'provider/local/export_test.go'
--- provider/local/export_test.go 2014-03-07 04:22:00 +0000
+++ provider/local/export_test.go 2014-03-17 22:08:13 +0000
@@ -10,14 +10,13 @@
10)10)
1111
12var (12var (
13 CheckLocalPort = &checkLocalPort13 CheckLocalPort = &checkLocalPort
14 DetectAptProxies = &detectAptProxies14 DetectAptProxies = &detectAptProxies
15 EnvKeyTestingForceSlow = envKeyTestingForceSlow15 FinishBootstrap = &finishBootstrap
16 FinishBootstrap = &finishBootstrap16 Provider = providerInstance
17 Provider = providerInstance17 ReleaseVersion = &releaseVersion
18 ReleaseVersion = &releaseVersion18 UseFastLXC = useFastLXC
19 UseFastLXC = useFastLXC19 UserCurrent = &userCurrent
20 UserCurrent = &userCurrent
21)20)
2221
23// SetRootCheckFunction allows tests to override the check for a root user.22// SetRootCheckFunction allows tests to override the check for a root user.
2423
=== modified file 'provider/local/lxc.go'
--- provider/local/lxc.go 2014-03-07 04:24:27 +0000
+++ provider/local/lxc.go 2014-03-17 22:08:13 +0000
@@ -4,17 +4,12 @@
4package local4package local
55
6import (6import (
7 "os"
8 "strconv"7 "strconv"
98
10 "launchpad.net/juju-core/instance"9 "launchpad.net/juju-core/instance"
11 "launchpad.net/juju-core/version"10 "launchpad.net/juju-core/version"
12)11)
1312
14// envKeyTestingForceSlow is an environment variable name to force the slow
15// lxc path. Setting to any non-empty value will force the slow path.
16const envKeyTestingForceSlow = "JUJU_TESTING_LXC_FORCE_SLOW"
17
18// releaseVersion is a function that returns a string representing the13// releaseVersion is a function that returns a string representing the
19// DISTRIB_RELEASE from the /etc/lsb-release file.14// DISTRIB_RELEASE from the /etc/lsb-release file.
20var releaseVersion = version.ReleaseVersion15var releaseVersion = version.ReleaseVersion
@@ -23,9 +18,6 @@
23 if containerType != instance.LXC {18 if containerType != instance.LXC {
24 return false19 return false
25 }20 }
26 if os.Getenv(envKeyTestingForceSlow) != "" {
27 return false
28 }
29 release := releaseVersion()21 release := releaseVersion()
30 if release == "" {22 if release == "" {
31 return false23 return false
3224
=== modified file 'provider/local/lxc_test.go'
--- provider/local/lxc_test.go 2014-03-13 07:54:56 +0000
+++ provider/local/lxc_test.go 2014-03-17 22:08:13 +0000
@@ -28,7 +28,6 @@
28 message string28 message string
29 releaseVersion string29 releaseVersion string
30 expected bool30 expected bool
31 overrideSlow string
32 }{{31 }{{
33 message: "missing release file",32 message: "missing release file",
34 }, {33 }, {
@@ -45,14 +44,9 @@
45 }, {44 }, {
46 message: "jaunty",45 message: "jaunty",
47 releaseVersion: "9.10",46 releaseVersion: "9.10",
48 }, {
49 message: "env override",
50 releaseVersion: "14.04",
51 overrideSlow: "value",
52 }} {47 }} {
53 c.Logf("%v: %v", i, test.message)48 c.Logf("%v: %v", i, test.message)
54 t.PatchValue(local.ReleaseVersion, func() string { return test.releaseVersion })49 t.PatchValue(local.ReleaseVersion, func() string { return test.releaseVersion })
55 t.PatchEnvironment(local.EnvKeyTestingForceSlow, test.overrideSlow)
56 value := local.UseFastLXC(instance.LXC)50 value := local.UseFastLXC(instance.LXC)
57 c.Assert(value, gc.Equals, test.expected)51 c.Assert(value, gc.Equals, test.expected)
58 }52 }
5953
=== modified file 'provider/local/prereqs.go'
--- provider/local/prereqs.go 2014-03-06 20:35:21 +0000
+++ provider/local/prereqs.go 2014-03-17 22:08:13 +0000
@@ -85,7 +85,7 @@
85// VerifyPrerequisites verifies the prerequisites of85// VerifyPrerequisites verifies the prerequisites of
86// the local machine (machine 0) for running the local86// the local machine (machine 0) for running the local
87// provider.87// provider.
88func VerifyPrerequisites(containerType instance.ContainerType) error {88var VerifyPrerequisites = func(containerType instance.ContainerType) error {
89 if goos != "linux" {89 if goos != "linux" {
90 return fmt.Errorf(errUnsupportedOS, goos)90 return fmt.Errorf(errUnsupportedOS, goos)
91 }91 }

Subscribers

People subscribed via source and target branches

to status/vote changes: