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
1=== modified file 'cmd/juju/help_topics.go'
2--- cmd/juju/help_topics.go 2014-03-11 12:12:53 +0000
3+++ cmd/juju/help_topics.go 2014-03-17 22:08:13 +0000
4@@ -79,6 +79,24 @@
5 juju deploy wordpress
6 juju add-relation wordpress mysql
7
8+As of trusty, the local provider will prefer to use lxc-clone to create
9+the machines. A 'template' container is created with the name
10+ juju-<series>-tempalte
11+where <series> is the OS series, for example 'juju-precise-template'.
12+You can override the use of clone by specifying
13+ use-clone: true
14+or
15+ use-clone: false
16+in the configuration for your local provider. If you have the main container
17+directory mounted on a btrfs partition, then the clone will be using btrfs
18+snapshots to create the containers. This means that the clones use up much
19+less disk space. If you do not have btrfs, lxc will attempt to use aufs
20+(which is an overlay type filesystem). You can explicitly ask Juju to create
21+full containers and not overlays by specifying the following in the provider
22+configuration:
23+ use-clone-aufs: false
24+
25+
26 References:
27
28 http://askubuntu.com/questions/65359/how-do-i-configure-juju-for-local-usage
29
30=== modified file 'container/lxc/initialisation_test.go'
31--- container/lxc/initialisation_test.go 2014-03-13 17:21:05 +0000
32+++ container/lxc/initialisation_test.go 2014-03-17 22:08:13 +0000
33@@ -4,18 +4,12 @@
34 package lxc
35
36 import (
37- stdtesting "testing"
38-
39 gc "launchpad.net/gocheck"
40
41 "launchpad.net/juju-core/testing/testbase"
42 "launchpad.net/juju-core/utils"
43 )
44
45-func Test(t *stdtesting.T) {
46- gc.TestingT(t)
47-}
48-
49 type InitialiserSuite struct {
50 testbase.LoggingSuite
51 }
52
53=== modified file 'container/lxc/lxc.go'
54--- container/lxc/lxc.go 2014-03-13 16:03:45 +0000
55+++ container/lxc/lxc.go 2014-03-17 22:08:13 +0000
56@@ -69,6 +69,7 @@
57 name string
58 logdir string
59 createWithClone bool
60+ useAUFS bool
61 backingFilesystem string
62 }
63
64@@ -91,6 +92,7 @@
65 // If it fails to parse, the value is false, and this suits
66 // us fine.
67 useClone, _ := strconv.ParseBool(conf.PopValue("use-clone"))
68+ useAUFS, _ := strconv.ParseBool(conf.PopValue("use-aufs"))
69 backingFS, err := containerDirFilesystem()
70 if err != nil {
71 // Especially in tests, or a bot, the lxc dir may not exist
72@@ -105,6 +107,7 @@
73 name: name,
74 logdir: logDir,
75 createWithClone: useClone,
76+ useAUFS: useAUFS,
77 backingFilesystem: backingFS,
78 }, nil
79 }
80@@ -158,8 +161,11 @@
81 "--userdata", userDataFilename, // Our groovey cloud-init
82 "--hostid", name, // Use the container name as the hostid
83 }
84- extraCloneArgs := []string{"--snapshot"}
85- if manager.backingFilesystem != Btrfs {
86+ var extraCloneArgs []string
87+ if manager.backingFilesystem == Btrfs || manager.useAUFS {
88+ extraCloneArgs = append(extraCloneArgs, "--snapshot")
89+ }
90+ if manager.backingFilesystem != Btrfs && manager.useAUFS {
91 extraCloneArgs = append(extraCloneArgs, "--backingstore", "aufs")
92 }
93
94
95=== modified file 'container/lxc/lxc_test.go'
96--- container/lxc/lxc_test.go 2014-03-13 07:54:56 +0000
97+++ container/lxc/lxc_test.go 2014-03-17 22:08:13 +0000
98@@ -38,6 +38,7 @@
99
100 events chan mock.Event
101 useClone bool
102+ useAUFS bool
103 }
104
105 var _ = gc.Suite(&LxcSuite{})
106@@ -95,6 +96,9 @@
107 if s.useClone {
108 params["use-clone"] = "true"
109 }
110+ if s.useAUFS {
111+ params["use-aufs"] = "true"
112+ }
113 manager, err := lxc.NewContainerManager(params)
114 c.Assert(err, gc.IsNil)
115 return manager
116@@ -226,8 +230,31 @@
117 manager := s.makeManager(c, "test")
118 instance := containertesting.StartContainer(c, manager, "1")
119 name := string(instance.Id())
120- s.AssertEvent(c, <-s.events, mock.Cloned, "juju-series-template")
121- s.AssertEvent(c, <-s.events, mock.Started, name)
122+ cloned := <-s.events
123+ s.AssertEvent(c, cloned, mock.Cloned, "juju-series-template")
124+ c.Assert(cloned.Args, gc.IsNil)
125+ s.AssertEvent(c, <-s.events, mock.Started, name)
126+}
127+
128+func (s *LxcSuite) TestStartContainerEventsWithCloneExistingTemplateAUFS(c *gc.C) {
129+ s.createTemplate(c)
130+ s.PatchValue(&s.useClone, true)
131+ s.PatchValue(&s.useAUFS, true)
132+ manager := s.makeManager(c, "test")
133+ instance := containertesting.StartContainer(c, manager, "1")
134+ name := string(instance.Id())
135+ cloned := <-s.events
136+ s.AssertEvent(c, cloned, mock.Cloned, "juju-series-template")
137+ c.Assert(cloned.Args, gc.DeepEquals, []string{"--snapshot", "--backingstore", "aufs"})
138+ s.AssertEvent(c, <-s.events, mock.Started, name)
139+}
140+
141+func (s *LxcSuite) TestStartContainerWithCloneMountsAndAutostarts(c *gc.C) {
142+ s.createTemplate(c)
143+ s.PatchValue(&s.useClone, true)
144+ manager := s.makeManager(c, "test")
145+ instance := containertesting.StartContainer(c, manager, "1")
146+ name := string(instance.Id())
147
148 autostartLink := lxc.RestartSymlink(name)
149 config, err := ioutil.ReadFile(lxc.ContainerConfigFilename(name))
150
151=== modified file 'container/lxc/mock/mock-lxc.go'
152--- container/lxc/mock/mock-lxc.go 2014-03-12 04:27:25 +0000
153+++ container/lxc/mock/mock-lxc.go 2014-03-17 22:08:13 +0000
154@@ -54,8 +54,10 @@
155 }
156
157 type Event struct {
158- Action Action
159- InstanceId string
160+ Action Action
161+ InstanceId string
162+ Args []string
163+ TemplateArgs []string
164 }
165
166 type ContainerFactory interface {
167@@ -124,7 +126,7 @@
168 return err
169 }
170 mock.setState(golxc.StateStopped)
171- mock.factory.notify(Created, mock.name)
172+ mock.factory.notify(eventArgs(Created, mock.name, extraArgs, templateArgs))
173 return nil
174 }
175
176@@ -140,7 +142,7 @@
177 filepath.Join(container.ContainerDir, mock.name, "console.log"),
178 []byte("fake console.log"), 0644)
179 mock.setState(golxc.StateRunning)
180- mock.factory.notify(Started, mock.name)
181+ mock.factory.notify(event(Started, mock.name))
182 return nil
183 }
184
185@@ -153,7 +155,7 @@
186 return fmt.Errorf("container is already stopped")
187 }
188 mock.setState(golxc.StateStopped)
189- mock.factory.notify(Stopped, mock.name)
190+ mock.factory.notify(event(Stopped, mock.name))
191 return nil
192 }
193
194@@ -183,7 +185,7 @@
195 return nil, err
196 }
197
198- mock.factory.notify(Cloned, mock.name)
199+ mock.factory.notify(eventArgs(Cloned, mock.name, extraArgs, templateArgs))
200 return container, nil
201 }
202
203@@ -209,7 +211,7 @@
204 }
205 delete(mock.factory.instances, mock.name)
206 mock.setState(golxc.StateUnknown)
207- mock.factory.notify(Destroyed, mock.name)
208+ mock.factory.notify(event(Destroyed, mock.name))
209 return nil
210 }
211
212@@ -290,8 +292,15 @@
213 return
214 }
215
216-func (mock *mockFactory) notify(action Action, instanceId string) {
217- event := Event{action, instanceId}
218+func event(action Action, instanceId string) Event {
219+ return Event{action, instanceId, nil, nil}
220+}
221+
222+func eventArgs(action Action, instanceId string, args []string, template []string) Event {
223+ return Event{action, instanceId, args, template}
224+}
225+
226+func (mock *mockFactory) notify(event Event) {
227 for _, c := range mock.listeners {
228 c <- event
229 }
230
231=== modified file 'provider/local/config.go'
232--- provider/local/config.go 2014-02-27 05:24:43 +0000
233+++ provider/local/config.go 2014-03-17 22:08:13 +0000
234@@ -25,6 +25,8 @@
235 "container": schema.String(),
236 "storage-port": schema.ForceInt(),
237 "namespace": schema.String(),
238+ "lxc-clone": schema.String(),
239+ "lxc-clone-aufs": schema.String(),
240 }
241 // The port defaults below are not entirely arbitrary. Local user web
242 // frameworks often use 8000 or 8080, so I didn't want to use either of
243@@ -37,6 +39,8 @@
244 "bootstrap-ip": schema.Omit,
245 "storage-port": 8040,
246 "namespace": "",
247+ "lxc-clone": schema.Omit,
248+ "lxc-clone-aufs": schema.Omit,
249 }
250 )
251
252@@ -103,6 +107,16 @@
253 return filepath.Join(c.rootDir(), filename)
254 }
255
256+func (c *environConfig) lxcClone() string {
257+ value, _ := c.attrs["lxc-clone"].(string)
258+ return value
259+}
260+
261+func (c *environConfig) lxcCloneAUFS() string {
262+ value, _ := c.attrs["lxc-clone-aufs"].(string)
263+ return value
264+}
265+
266 func (c *environConfig) createDirs() error {
267 for _, dirname := range []string{
268 c.storageDir(),
269
270=== modified file 'provider/local/environ.go'
271--- provider/local/environ.go 2014-03-17 08:25:06 +0000
272+++ provider/local/environ.go 2014-03-17 22:08:13 +0000
273@@ -10,7 +10,6 @@
274 "os/exec"
275 "path/filepath"
276 "regexp"
277- "strconv"
278 "strings"
279 "sync"
280 "syscall"
281@@ -61,7 +60,6 @@
282 localStorage storage.Storage
283 storageListener net.Listener
284 containerManager container.Manager
285- fastLXC bool
286 }
287
288 // GetToolsSources returns a list of sources which are used to search for simplestreams tools metadata.
289@@ -214,15 +212,16 @@
290 env.config = ecfg
291 env.name = ecfg.Name()
292 containerType := ecfg.container()
293- env.fastLXC = useFastLXC(containerType)
294-
295+ managerConfig := container.ManagerConfig{
296+ container.ConfigName: env.config.namespace(),
297+ container.ConfigLogDir: env.config.logDir(),
298+ }
299+ if containerType == instance.LXC {
300+ managerConfig["use-clone"] = env.config.lxcClone()
301+ managerConfig["use-aufs"] = env.config.lxcCloneAUFS()
302+ }
303 env.containerManager, err = factory.NewContainerManager(
304- containerType,
305- container.ManagerConfig{
306- container.ConfigName: env.config.namespace(),
307- container.ConfigLogDir: env.config.logDir(),
308- "use-clone": strconv.FormatBool(env.fastLXC),
309- })
310+ containerType, managerConfig)
311 if err != nil {
312 return err
313 }
314
315=== modified file 'provider/local/environprovider.go'
316--- provider/local/environprovider.go 2014-03-12 11:04:20 +0000
317+++ provider/local/environprovider.go 2014-03-17 22:08:13 +0000
318@@ -8,6 +8,7 @@
319 "net"
320 "os"
321 "os/user"
322+ "strconv"
323 "syscall"
324
325 "github.com/juju/loggo"
326@@ -180,15 +181,15 @@
327 localConfig := newEnvironConfig(cfg, validated)
328 // Before potentially creating directories, make sure that the
329 // root directory has not changed.
330+ containerType := localConfig.container()
331 if old != nil {
332 oldLocalConfig, err := provider.newConfig(old)
333 if err != nil {
334 return nil, fmt.Errorf("old config is not a valid local config: %v", old)
335 }
336- if localConfig.container() != oldLocalConfig.container() {
337+ if containerType != oldLocalConfig.container() {
338 return nil, fmt.Errorf("cannot change container from %q to %q",
339- oldLocalConfig.container(),
340- localConfig.container())
341+ oldLocalConfig.container(), containerType)
342 }
343 if localConfig.rootDir() != oldLocalConfig.rootDir() {
344 return nil, fmt.Errorf("cannot change root-dir from %q to %q",
345@@ -207,8 +208,8 @@
346 }
347 }
348 // Currently only supported containers are "lxc" and "kvm".
349- if localConfig.container() != instance.LXC && localConfig.container() != instance.KVM {
350- return nil, fmt.Errorf("unsupported container type: %q", localConfig.container())
351+ if containerType != instance.LXC && containerType != instance.KVM {
352+ return nil, fmt.Errorf("unsupported container type: %q", containerType)
353 }
354 dir, err := utils.NormalizePath(localConfig.rootDir())
355 if err != nil {
356@@ -220,6 +221,16 @@
357 // Always assign the normalized path.
358 localConfig.attrs["root-dir"] = dir
359
360+ if containerType != instance.KVM {
361+ fastOptionAvailable := strconv.FormatBool(useFastLXC(containerType))
362+ if _, found := localConfig.attrs["lxc-clone"]; !found {
363+ localConfig.attrs["lxc-clone"] = fastOptionAvailable
364+ }
365+ if _, found := localConfig.attrs["lxc-clone-aufs"]; !found {
366+ localConfig.attrs["lxc-clone-aufs"] = fastOptionAvailable
367+ }
368+ }
369+
370 // Apply the coerced unknown values back into the config.
371 return cfg.Apply(localConfig.attrs)
372 }
373
374=== modified file 'provider/local/environprovider_test.go'
375--- provider/local/environprovider_test.go 2014-03-09 20:48:29 +0000
376+++ provider/local/environprovider_test.go 2014-03-17 22:08:13 +0000
377@@ -8,11 +8,14 @@
378 "os/user"
379
380 "github.com/juju/loggo"
381+ jc "github.com/juju/testing/checkers"
382 gc "launchpad.net/gocheck"
383
384+ "launchpad.net/juju-core/container/kvm"
385 lxctesting "launchpad.net/juju-core/container/lxc/testing"
386 "launchpad.net/juju-core/environs"
387 "launchpad.net/juju-core/environs/config"
388+ "launchpad.net/juju-core/instance"
389 "launchpad.net/juju-core/juju/osenv"
390 "launchpad.net/juju-core/provider"
391 "launchpad.net/juju-core/provider/local"
392@@ -297,3 +300,100 @@
393 }
394 }
395 }
396+
397+func (s *prepareSuite) TestFastLXCClone(c *gc.C) {
398+ s.PatchValue(local.DetectAptProxies, func() (osenv.ProxySettings, error) {
399+ return osenv.ProxySettings{}, nil
400+ })
401+ s.PatchValue(&kvm.IsKVMSupported, func() (bool, error) {
402+ return true, nil
403+ })
404+ s.PatchValue(&local.VerifyPrerequisites, func(containerType instance.ContainerType) error {
405+ return nil
406+ })
407+ basecfg, err := config.New(config.UseDefaults, map[string]interface{}{
408+ "type": "local",
409+ "name": "test",
410+ })
411+ provider, err := environs.Provider("local")
412+ c.Assert(err, gc.IsNil)
413+
414+ type test struct {
415+ systemDefault bool
416+ extraConfig map[string]interface{}
417+ expectClone string
418+ expectAUFS string
419+ }
420+ tests := []test{{
421+ extraConfig: map[string]interface{}{
422+ "container": "lxc",
423+ },
424+ expectClone: "false",
425+ expectAUFS: "false",
426+ }, {
427+ extraConfig: map[string]interface{}{
428+ "container": "lxc",
429+ "lxc-clone": "true",
430+ },
431+ expectClone: "true",
432+ expectAUFS: "false",
433+ }, {
434+ systemDefault: true,
435+ extraConfig: map[string]interface{}{
436+ "container": "lxc",
437+ },
438+ expectClone: "true",
439+ expectAUFS: "true",
440+ }, {
441+ systemDefault: true,
442+ extraConfig: map[string]interface{}{
443+ "container": "kvm",
444+ },
445+ }, {
446+ systemDefault: true,
447+ extraConfig: map[string]interface{}{
448+ "container": "lxc",
449+ "lxc-clone": "false",
450+ },
451+ expectClone: "false",
452+ expectAUFS: "true",
453+ }, {
454+ systemDefault: true,
455+ extraConfig: map[string]interface{}{
456+ "container": "lxc",
457+ "lxc-clone-aufs": "false",
458+ },
459+ expectClone: "true",
460+ expectAUFS: "false",
461+ }}
462+
463+ for i, test := range tests {
464+ c.Logf("test %d: %v", i, test)
465+
466+ releaseVersion := "12.04"
467+ if test.systemDefault {
468+ releaseVersion = "14.04"
469+ }
470+ s.PatchValue(local.ReleaseVersion, func() string { return releaseVersion })
471+ testConfig, err := basecfg.Apply(test.extraConfig)
472+ c.Assert(err, gc.IsNil)
473+ env, err := provider.Open(testConfig)
474+ c.Assert(err, gc.IsNil)
475+ localAttributes := env.Config().UnknownAttrs()
476+
477+ if test.expectClone != "" {
478+ c.Assert(localAttributes["lxc-clone"], gc.Equals, test.expectClone)
479+ } else {
480+ _, found := localAttributes["lxc-clone"]
481+ c.Assert(found, jc.IsFalse)
482+ }
483+
484+ if test.expectAUFS != "" {
485+ c.Assert(localAttributes["lxc-clone-aufs"], gc.Equals, test.expectAUFS)
486+ } else {
487+ _, found := localAttributes["lxc-clone-aufs"]
488+ c.Assert(found, jc.IsFalse)
489+ }
490+
491+ }
492+}
493
494=== modified file 'provider/local/export_test.go'
495--- provider/local/export_test.go 2014-03-07 04:22:00 +0000
496+++ provider/local/export_test.go 2014-03-17 22:08:13 +0000
497@@ -10,14 +10,13 @@
498 )
499
500 var (
501- CheckLocalPort = &checkLocalPort
502- DetectAptProxies = &detectAptProxies
503- EnvKeyTestingForceSlow = envKeyTestingForceSlow
504- FinishBootstrap = &finishBootstrap
505- Provider = providerInstance
506- ReleaseVersion = &releaseVersion
507- UseFastLXC = useFastLXC
508- UserCurrent = &userCurrent
509+ CheckLocalPort = &checkLocalPort
510+ DetectAptProxies = &detectAptProxies
511+ FinishBootstrap = &finishBootstrap
512+ Provider = providerInstance
513+ ReleaseVersion = &releaseVersion
514+ UseFastLXC = useFastLXC
515+ UserCurrent = &userCurrent
516 )
517
518 // SetRootCheckFunction allows tests to override the check for a root user.
519
520=== modified file 'provider/local/lxc.go'
521--- provider/local/lxc.go 2014-03-07 04:24:27 +0000
522+++ provider/local/lxc.go 2014-03-17 22:08:13 +0000
523@@ -4,17 +4,12 @@
524 package local
525
526 import (
527- "os"
528 "strconv"
529
530 "launchpad.net/juju-core/instance"
531 "launchpad.net/juju-core/version"
532 )
533
534-// envKeyTestingForceSlow is an environment variable name to force the slow
535-// lxc path. Setting to any non-empty value will force the slow path.
536-const envKeyTestingForceSlow = "JUJU_TESTING_LXC_FORCE_SLOW"
537-
538 // releaseVersion is a function that returns a string representing the
539 // DISTRIB_RELEASE from the /etc/lsb-release file.
540 var releaseVersion = version.ReleaseVersion
541@@ -23,9 +18,6 @@
542 if containerType != instance.LXC {
543 return false
544 }
545- if os.Getenv(envKeyTestingForceSlow) != "" {
546- return false
547- }
548 release := releaseVersion()
549 if release == "" {
550 return false
551
552=== modified file 'provider/local/lxc_test.go'
553--- provider/local/lxc_test.go 2014-03-13 07:54:56 +0000
554+++ provider/local/lxc_test.go 2014-03-17 22:08:13 +0000
555@@ -28,7 +28,6 @@
556 message string
557 releaseVersion string
558 expected bool
559- overrideSlow string
560 }{{
561 message: "missing release file",
562 }, {
563@@ -45,14 +44,9 @@
564 }, {
565 message: "jaunty",
566 releaseVersion: "9.10",
567- }, {
568- message: "env override",
569- releaseVersion: "14.04",
570- overrideSlow: "value",
571 }} {
572 c.Logf("%v: %v", i, test.message)
573 t.PatchValue(local.ReleaseVersion, func() string { return test.releaseVersion })
574- t.PatchEnvironment(local.EnvKeyTestingForceSlow, test.overrideSlow)
575 value := local.UseFastLXC(instance.LXC)
576 c.Assert(value, gc.Equals, test.expected)
577 }
578
579=== modified file 'provider/local/prereqs.go'
580--- provider/local/prereqs.go 2014-03-06 20:35:21 +0000
581+++ provider/local/prereqs.go 2014-03-17 22:08:13 +0000
582@@ -85,7 +85,7 @@
583 // VerifyPrerequisites verifies the prerequisites of
584 // the local machine (machine 0) for running the local
585 // provider.
586-func VerifyPrerequisites(containerType instance.ContainerType) error {
587+var VerifyPrerequisites = func(containerType instance.ContainerType) error {
588 if goos != "linux" {
589 return fmt.Errorf(errUnsupportedOS, goos)
590 }

Subscribers

People subscribed via source and target branches

to status/vote changes: