Merge lp:~thumper/juju-core/autostart-containers-after-creation 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: 2405
Proposed branch: lp:~thumper/juju-core/autostart-containers-after-creation
Merge into: lp:~go-bot/juju-core/trunk
Prerequisite: lp:~thumper/juju-core/fast-lxc
Diff against target: 245 lines (+87/-45)
5 files modified
container/lxc/export_test.go (+4/-3)
container/lxc/lxc.go (+57/-30)
container/lxc/lxc_test.go (+8/-6)
container/lxc/mock/mock-lxc.go (+17/-5)
container/lxc/testing/test.go (+1/-1)
To merge this branch: bzr merge lp:~thumper/juju-core/autostart-containers-after-creation
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+210099@code.launchpad.net

Commit message

Set lxc autostart after creation.

Currently for a recent LXC version, the autostart is controlled
by a setting in the lxc config. We were setting this in the
config file that we use for creation. However this is not clone
friendly, as we do not specify a config file for clone.

However it is perfectly valid to modify the config for the container
once it has been created. This then becomes common for both
normally created containers and those that have been cloned.

A key here is that our template container that we want to use
as a base to clone off we do not want auto-starting, however
the containers that we clone off that may well want to auto-start
(in fact all will until we add the autostart policy for local).

https://codereview.appspot.com/73300043/

Description of the change

Set lxc autostart after creation.

Currently for a recent LXC version, the autostart is controlled
by a setting in the lxc config. We were setting this in the
config file that we use for creation. However this is not clone
friendly, as we do not specify a config file for clone.

However it is perfectly valid to modify the config for the container
once it has been created. This then becomes common for both
normally created containers and those that have been cloned.

A key here is that our template container that we want to use
as a base to clone off we do not want auto-starting, however
the containers that we clone off that may well want to auto-start
(in fact all will until we add the autostart policy for local).

https://codereview.appspot.com/73300043/

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

Reviewers: mp+210099_code.launchpad.net,

Message:
Please take a look.

Description:
Set lxc autostart after creation.

Currently for a recent LXC version, the autostart is controlled
by a setting in the lxc config. We were setting this in the
config file that we use for creation. However this is not clone
friendly, as we do not specify a config file for clone.

However it is perfectly valid to modify the config for the container
once it has been created. This then becomes common for both
normally created containers and those that have been cloned.

A key here is that our template container that we want to use
as a base to clone off we do not want auto-starting, however
the containers that we clone off that may well want to auto-start
(in fact all will until we add the autostart policy for local).

https://code.launchpad.net/~thumper/juju-core/autostart-containers-after-creation/+merge/210099

Requires:
https://code.launchpad.net/~thumper/juju-core/fast-lxc/+merge/209801

(do not edit description out of merge proposal)

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

Affected files (+71, -35 lines):
   A [revision details]
   M container/lxc/export_test.go
   M container/lxc/lxc.go
   M container/lxc/lxc_test.go
   M container/lxc/mock/mock-lxc.go
   M container/lxc/testing/test.go

Revision history for this message
Jesse Meek (waigani) wrote :

On 2014/03/09 21:29:35, thumper wrote:
> Please take a look.

LGTM

https://codereview.appspot.com/73300043/

Revision history for this message
Andrew Wilkins (axwalk) wrote :

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

https://codereview.appspot.com/73300043/diff/1/container/lxc/lxc_test.go#newcode179
container/lxc/lxc_test.go:179: name := string(instance.Id())
It's not clear why this has changed. Has something caused the contents
of the file to be different (apart from the lxc.start.auto)? I would
think it's preferable to match exactly if it's not too onerous.

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

https://codereview.appspot.com/73300043/diff/1/container/lxc/mock/mock-lxc.go#newcode87
container/lxc/mock/mock-lxc.go:87: data, err :=
ioutil.ReadFile(configFile)
There's utils.CopyFile, if you didn't know.

https://codereview.appspot.com/73300043/diff/1/container/lxc/mock/mock-lxc.go#newcode92
container/lxc/mock/mock-lxc.go:92: return
ioutil.WriteFile(configFilename, data, 0755)
0644?

https://codereview.appspot.com/73300043/

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

Please take a look.

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

https://codereview.appspot.com/73300043/diff/1/container/lxc/lxc_test.go#newcode179
container/lxc/lxc_test.go:179: name := string(instance.Id())
On 2014/03/11 02:24:13, axw wrote:
> It's not clear why this has changed. Has something caused the contents
of the
> file to be different (apart from the lxc.start.auto)? I would think
it's
> preferable to match exactly if it's not too onerous.

Doing an exact match now.

In order to make the match easily, I have also added in the part where
the mounting of the log dir is done after create.

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

https://codereview.appspot.com/73300043/diff/1/container/lxc/mock/mock-lxc.go#newcode87
container/lxc/mock/mock-lxc.go:87: data, err :=
ioutil.ReadFile(configFile)
On 2014/03/11 02:24:13, axw wrote:
> There's utils.CopyFile, if you didn't know.

No I didn't. Using it now.

https://codereview.appspot.com/73300043/

Revision history for this message
Andrew Wilkins (axwalk) wrote :

On 2014/03/11 03:46:16, thumper wrote:
> Please take a look.

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

https://codereview.appspot.com/73300043/diff/1/container/lxc/lxc_test.go#newcode179
> container/lxc/lxc_test.go:179: name := string(instance.Id())
> On 2014/03/11 02:24:13, axw wrote:
> > It's not clear why this has changed. Has something caused the
contents of the
> > file to be different (apart from the lxc.start.auto)? I would think
it's
> > preferable to match exactly if it's not too onerous.

> Doing an exact match now.

> In order to make the match easily, I have also added in the part where
the
> mounting of the log dir is done after create.

https://codereview.appspot.com/73300043/diff/1/container/lxc/mock/mock-lxc.go
> File container/lxc/mock/mock-lxc.go (right):

https://codereview.appspot.com/73300043/diff/1/container/lxc/mock/mock-lxc.go#newcode87
> container/lxc/mock/mock-lxc.go:87: data, err :=
ioutil.ReadFile(configFile)
> On 2014/03/11 02:24:13, axw wrote:
> > There's utils.CopyFile, if you didn't know.

> No I didn't. Using it now.

LGTM, thanks

https://codereview.appspot.com/73300043/

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

The attempt to merge lp:~thumper/juju-core/autostart-containers-after-creation into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.014s
ok launchpad.net/juju-core/agent 1.039s
ok launchpad.net/juju-core/agent/mongo 0.530s
ok launchpad.net/juju-core/agent/tools 0.172s
ok launchpad.net/juju-core/bzr 5.107s
ok launchpad.net/juju-core/cert 2.457s
ok launchpad.net/juju-core/charm 0.393s
? 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.856s
ok launchpad.net/juju-core/cmd 0.152s
ok launchpad.net/juju-core/cmd/charm-admin 0.728s
? 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.242s
ok launchpad.net/juju-core/cmd/jujud 63.233s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 9.291s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/cmd/plugins/local 0.186s
? launchpad.net/juju-core/cmd/plugins/local/juju-local [no test files]
ok launchpad.net/juju-core/constraints 0.029s
ok launchpad.net/juju-core/container 0.044s
ok launchpad.net/juju-core/container/factory 0.048s
ok launchpad.net/juju-core/container/kvm 0.183s
ok launchpad.net/juju-core/container/kvm/mock 0.041s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 0.264s
? 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.236s
ok launchpad.net/juju-core/environs 2.510s
ok launchpad.net/juju-core/environs/bootstrap 2.981s
ok launchpad.net/juju-core/environs/cloudinit 0.460s
ok launchpad.net/juju-core/environs/config 2.174s
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.712s
ok launchpad.net/juju-core/environs/imagemetadata 0.462s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.042s
ok launchpad.net/juju-core/environs/jujutest 0.202s
ok launchpad.net/juju-core/environs/manual 11.863s
ok launchpad.net/juju-core/environs/simplestreams 0.218s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 0.948s
ok launchpad.net/juju-core/environs/storage 1.024s
ok launchpad.net/juju-core/environs/sync 23.103s
ok launchpad.net/juju-core/environs/testing 0.179s
ok launchpad.net/juju-core/environs/tools 4.606s
? launchpad.net/juju-core/environs/tools/testing [no test files]
ok launchpad.net/juju-core/errors 0.012s
ok launchpad.net/juju-core/instance 0.017s
? launchpad.net/juju-core/instance/testing [no test files]
ok launchpad.net/juju-core/juju 17.731s
ok launchpad.net/juju-core/juj...

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

The attempt to merge lp:~thumper/juju-core/autostart-containers-after-creation into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.012s
ok launchpad.net/juju-core/agent 0.987s
ok launchpad.net/juju-core/agent/mongo 0.561s
ok launchpad.net/juju-core/agent/tools 0.191s
ok launchpad.net/juju-core/bzr 4.808s
ok launchpad.net/juju-core/cert 2.287s
ok launchpad.net/juju-core/charm 0.392s
? 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.033s
ok launchpad.net/juju-core/cloudinit/sshinit 0.799s
ok launchpad.net/juju-core/cmd 0.170s
ok launchpad.net/juju-core/cmd/charm-admin 0.730s
? 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 194.479s
ok launchpad.net/juju-core/cmd/jujud 62.786s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 9.924s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/cmd/plugins/local 0.151s
? launchpad.net/juju-core/cmd/plugins/local/juju-local [no test files]
ok launchpad.net/juju-core/constraints 0.019s
ok launchpad.net/juju-core/container 0.038s
ok launchpad.net/juju-core/container/factory 0.050s
ok launchpad.net/juju-core/container/kvm 0.236s
ok launchpad.net/juju-core/container/kvm/mock 0.041s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 0.251s
? 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.491s
ok launchpad.net/juju-core/environs/bootstrap 3.082s
ok launchpad.net/juju-core/environs/cloudinit 0.444s
ok launchpad.net/juju-core/environs/config 3.589s
ok launchpad.net/juju-core/environs/configstore 0.028s
ok launchpad.net/juju-core/environs/filestorage 0.026s
ok launchpad.net/juju-core/environs/httpstorage 0.592s
ok launchpad.net/juju-core/environs/imagemetadata 0.405s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.049s
ok launchpad.net/juju-core/environs/jujutest 0.156s
ok launchpad.net/juju-core/environs/manual 10.074s
ok launchpad.net/juju-core/environs/simplestreams 0.226s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 0.961s
ok launchpad.net/juju-core/environs/storage 0.910s
ok launchpad.net/juju-core/environs/sync 23.657s
ok launchpad.net/juju-core/environs/testing 0.176s
ok launchpad.net/juju-core/environs/tools 4.828s
? 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.016s
? launchpad.net/juju-core/instance/testing [no test files]
ok launchpad.net/juju-core/juju 20.596s
ok launchpad.net/juju-core/juj...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'container/lxc/export_test.go'
2--- container/lxc/export_test.go 2013-10-01 02:21:52 +0000
3+++ container/lxc/export_test.go 2014-03-11 03:19:30 +0000
4@@ -4,7 +4,8 @@
5 package lxc
6
7 var (
8- NetworkConfigTemplate = networkConfigTemplate
9- GenerateNetworkConfig = generateNetworkConfig
10- RestartSymlink = restartSymlink
11+ NetworkConfigTemplate = networkConfigTemplate
12+ GenerateNetworkConfig = generateNetworkConfig
13+ RestartSymlink = restartSymlink
14+ ContainerConfigFilename = containerConfigFilename
15 )
16
17=== modified file 'container/lxc/lxc.go'
18--- container/lxc/lxc.go 2014-03-10 02:51:31 +0000
19+++ container/lxc/lxc.go 2014-03-11 03:19:30 +0000
20@@ -96,7 +96,7 @@
21 return nil, nil, err
22 }
23 logger.Tracef("write the lxc.conf file")
24- configFile, err := writeLxcConfig(network, directory, manager.logdir)
25+ configFile, err := writeLxcConfig(network, directory)
26 if err != nil {
27 logger.Errorf("failed to write config file: %v", err)
28 return nil, nil, err
29@@ -113,25 +113,14 @@
30 logger.Errorf("lxc container creation failed: %v", err)
31 return nil, nil, err
32 }
33- // Make sure that the mount dir has been created.
34- logger.Tracef("make the mount dir for the shard logs")
35- if err := os.MkdirAll(internalLogDir(name), 0755); err != nil {
36- logger.Errorf("failed to create internal /var/log/juju mount dir: %v", err)
37- return nil, nil, err
38- }
39 logger.Tracef("lxc container created")
40- // Now symlink the config file into the restart directory, if it exists.
41- // This is for backwards compatiblity. From Trusty onwards, the auto start
42- // option should be set in the LXC config file, this is done in the networkConfigTemplate
43- // function below.
44- if useRestartDir() {
45- containerConfigFile := filepath.Join(LxcContainerDir, name, "config")
46- if err := os.Symlink(containerConfigFile, restartSymlink(name)); err != nil {
47- return nil, nil, err
48- }
49- logger.Tracef("auto-restart link created")
50- }
51
52+ if err := autostartContainer(name); err != nil {
53+ return nil, nil, err
54+ }
55+ if err := mountHostLogDir(name, manager.logdir); err != nil {
56+ return nil, nil, err
57+ }
58 // Start the lxc container with the appropriate settings for grabbing the
59 // console output and a log file.
60 consoleFile := filepath.Join(directory, "console.log")
61@@ -153,6 +142,50 @@
62 return &lxcInstance{lxcContainer, name}, hardware, nil
63 }
64
65+func appendToContainerConfig(name, line string) error {
66+ file, err := os.OpenFile(
67+ containerConfigFilename(name), os.O_RDWR|os.O_APPEND, 0644)
68+ if err != nil {
69+ return err
70+ }
71+ defer file.Close()
72+ _, err = file.WriteString(line)
73+ return err
74+}
75+
76+func autostartContainer(name string) error {
77+ // Now symlink the config file into the restart directory, if it exists.
78+ // This is for backwards compatiblity. From Trusty onwards, the auto start
79+ // option should be set in the LXC config file, this is done in the networkConfigTemplate
80+ // function below.
81+ if useRestartDir() {
82+ if err := os.Symlink(
83+ containerConfigFilename(name),
84+ restartSymlink(name),
85+ ); err != nil {
86+ return err
87+ }
88+ logger.Tracef("auto-restart link created")
89+ } else {
90+ logger.Tracef("Setting auto start to true in lxc config.")
91+ return appendToContainerConfig(name, "lxc.start.auto = 1\n")
92+ }
93+ return nil
94+}
95+
96+func mountHostLogDir(name, logDir string) error {
97+ // Make sure that the mount dir has been created.
98+ logger.Tracef("make the mount dir for the shared logs")
99+ if err := os.MkdirAll(internalLogDir(name), 0755); err != nil {
100+ logger.Errorf("failed to create internal /var/log/juju mount dir: %v", err)
101+ return err
102+ }
103+ line := fmt.Sprintf(
104+ "lxc.mount.entry=%s var/log/juju none defaults,bind 0 0\n",
105+ logDir)
106+ return appendToContainerConfig(name, line)
107+}
108+
109 func (manager *containerManager) StopContainer(instance instance.Instance) error {
110 name := string(instance.Id())
111 lxcContainer := LxcObjectFactory.New(name)
112@@ -205,9 +238,9 @@
113 return filepath.Join(LxcRestartDir, name+".conf")
114 }
115
116-const localConfig = `%s
117-lxc.mount.entry=%s var/log/juju none defaults,bind 0 0
118-`
119+func containerConfigFilename(name string) string {
120+ return filepath.Join(LxcContainerDir, name, "config")
121+}
122
123 const networkTemplate = `
124 lxc.network.type = %s
125@@ -216,12 +249,7 @@
126 `
127
128 func networkConfigTemplate(networkType, networkLink string) string {
129- networkConfig := fmt.Sprintf(networkTemplate, networkType, networkLink)
130- if !useRestartDir() {
131- networkConfig += "lxc.start.auto = 1\n"
132- logger.Tracef("Setting auto start to true in lxc config.")
133- }
134- return networkConfig
135+ return fmt.Sprintf(networkTemplate, networkType, networkLink)
136 }
137
138 func generateNetworkConfig(network *container.NetworkConfig) string {
139@@ -240,11 +268,10 @@
140 }
141 }
142
143-func writeLxcConfig(network *container.NetworkConfig, directory, logdir string) (string, error) {
144+func writeLxcConfig(network *container.NetworkConfig, directory string) (string, error) {
145 networkConfig := generateNetworkConfig(network)
146 configFilename := filepath.Join(directory, "lxc.conf")
147- configContent := fmt.Sprintf(localConfig, networkConfig, logdir)
148- if err := ioutil.WriteFile(configFilename, []byte(configContent), 0644); err != nil {
149+ if err := ioutil.WriteFile(configFilename, []byte(networkConfig), 0644); err != nil {
150 return "", err
151 }
152 return configFilename, nil
153
154=== modified file 'container/lxc/lxc_test.go'
155--- container/lxc/lxc_test.go 2014-03-10 02:51:31 +0000
156+++ container/lxc/lxc_test.go 2014-03-11 03:19:30 +0000
157@@ -185,16 +185,18 @@
158
159 manager := s.makeManager(c, "test")
160 instance := containertesting.StartContainer(c, manager, "1/lxc/0")
161- autostartLink := lxc.RestartSymlink(string(instance.Id()))
162-
163- config := lxc.NetworkConfigTemplate("foo", "bar")
164+ name := string(instance.Id())
165+ autostartLink := lxc.RestartSymlink(name)
166+ config, err := ioutil.ReadFile(lxc.ContainerConfigFilename(name))
167+ c.Assert(err, gc.IsNil)
168 expected := `
169-lxc.network.type = foo
170-lxc.network.link = bar
171+lxc.network.type = veth
172+lxc.network.link = nic42
173 lxc.network.flags = up
174 lxc.start.auto = 1
175+lxc.mount.entry=/var/log/juju var/log/juju none defaults,bind 0 0
176 `
177- c.Assert(config, gc.Equals, expected)
178+ c.Assert(string(config), gc.Equals, expected)
179 c.Assert(autostartLink, jc.DoesNotExist)
180 }
181
182
183=== modified file 'container/lxc/mock/mock-lxc.go'
184--- container/lxc/mock/mock-lxc.go 2013-09-30 01:50:43 +0000
185+++ container/lxc/mock/mock-lxc.go 2014-03-11 03:19:30 +0000
186@@ -5,8 +5,12 @@
187
188 import (
189 "fmt"
190+ "os"
191+ "path/filepath"
192
193 "launchpad.net/golxc"
194+
195+ "launchpad.net/juju-core/utils"
196 )
197
198 // This file provides a mock implementation of the golxc interfaces
199@@ -44,13 +48,15 @@
200 }
201
202 type mockFactory struct {
203- instances map[string]golxc.Container
204- listeners []chan<- Event
205+ containerDir string
206+ instances map[string]golxc.Container
207+ listeners []chan<- Event
208 }
209
210-func MockFactory() ContainerFactory {
211+func MockFactory(containerDir string) ContainerFactory {
212 return &mockFactory{
213- instances: make(map[string]golxc.Container),
214+ containerDir: containerDir,
215+ instances: make(map[string]golxc.Container),
216 }
217 }
218
219@@ -74,7 +80,13 @@
220 }
221 mock.state = golxc.StateStopped
222 mock.factory.instances[mock.name] = mock
223- return nil
224+ // Create the container directory.
225+ containerDir := filepath.Join(mock.factory.containerDir, mock.name)
226+ if err := os.MkdirAll(containerDir, 0755); err != nil {
227+ return err
228+ }
229+ containerConfig := filepath.Join(containerDir, "config")
230+ return utils.CopyFile(containerConfig, configFile)
231 }
232
233 // Start runs the container as a daemon.
234
235=== modified file 'container/lxc/testing/test.go'
236--- container/lxc/testing/test.go 2013-11-11 22:45:29 +0000
237+++ container/lxc/testing/test.go 2014-03-11 03:19:30 +0000
238@@ -33,6 +33,6 @@
239 s.PatchValue(&lxc.LxcContainerDir, s.LxcDir)
240 s.RestartDir = c.MkDir()
241 s.PatchValue(&lxc.LxcRestartDir, s.RestartDir)
242- s.Factory = mock.MockFactory()
243+ s.Factory = mock.MockFactory(s.LxcDir)
244 s.PatchValue(&lxc.LxcObjectFactory, s.Factory)
245 }

Subscribers

People subscribed via source and target branches

to status/vote changes: