Merge lp:~jtv/juju-core/az-customdata into lp:~go-bot/juju-core/trunk

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: Jeroen T. Vermeulen
Approved revision: no longer in the source branch.
Merged at revision: 1439
Proposed branch: lp:~jtv/juju-core/az-customdata
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 198 lines (+135/-2)
6 files modified
environs/azure/customdata.go (+40/-0)
environs/azure/customdata_test.go (+90/-0)
environs/azure/environ_test.go (+2/-2)
environs/ec2/ec2.go (+1/-0)
environs/maas/util.go (+1/-0)
environs/openstack/provider.go (+1/-0)
To merge this branch: bzr merge lp:~jtv/juju-core/az-customdata
Reviewer Review Type Date Requested Status
Gavin Panella (community) Approve
Review via email: mp+174157@code.launchpad.net

Commit message

Implement custom data for Azure ("userdata").

Much of the code to generate cloudinit userdata is actually shared between
providers, hence the comments.

I also included a fix for a recent gwacl update. With this landed, devs will
have to update their copies of gwacl.

Description of the change

Implement custom data for Azure ("userdata").

Much of the code to generate cloudinit userdata is actually shared between
providers, hence the comments.

I also included a fix for a recent gwacl update. With this landed, devs will
have to update their copies of gwacl.

https://codereview.appspot.com/11158043/

To post a comment you must log in.
Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

Reviewers: mp+174157_code.launchpad.net,

Message:
Please take a look.

Description:
Implement custom data for Azure ("userdata").

Much of the code to generate cloudinit userdata is actually shared
between
providers, hence the comments.

I also included a fix for a recent gwacl update. With this landed, devs
will
have to update their copies of gwacl.

https://code.launchpad.net/~jtv/juju-core/az-customdata/+merge/174157

(do not edit description out of merge proposal)

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

Affected files:
   A [revision details]
   A environs/azure/customdata.go
   A environs/azure/customdata_test.go
   M environs/azure/environ_test.go
   M environs/ec2/ec2.go
   M environs/maas/util.go
   M environs/openstack/provider.go

Revision history for this message
Gavin Panella (allenap) wrote :

LGTM

https://codereview.appspot.com/11158043/diff/1/environs/azure/customdata_test.go
File environs/azure/customdata_test.go (right):

https://codereview.appspot.com/11158043/diff/1/environs/azure/customdata_test.go#newcode70
environs/azure/customdata_test.go:70: c.Check(string(content),
gc.Matches, "(.|\n)*"+marker+"(.|\n)*")
This regex can also be written as "(?s).*" + marker + ".*". It's a
little more readable. It might also be worth using regexp.QuoteMeta() to
make it explicit that marker is literal string, not an expression.

https://codereview.appspot.com/11158043/

Revision history for this message
Gavin Panella (allenap) :
review: Approve
Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :
Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :
Revision history for this message
Raphaël Badin (rvb) wrote :

On 2013/07/11 11:39:06, jtv.canonical wrote:
> Please take a look.

LGTM.

https://codereview.appspot.com/11158043/

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

The attempt to merge lp:~jtv/juju-core/az-customdata into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core/agent 2.485s
ok launchpad.net/juju-core/bzr 6.458s
ok launchpad.net/juju-core/cert 3.224s
ok launchpad.net/juju-core/charm 0.553s
? launchpad.net/juju-core/charm/hooks [no test files]
ok launchpad.net/juju-core/cloudinit 0.009s
ok launchpad.net/juju-core/cmd 0.240s
? launchpad.net/juju-core/cmd/builddb [no test files]
? 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 104.061s
ok launchpad.net/juju-core/cmd/jujud 42.723s
ok launchpad.net/juju-core/constraints 0.013s
ok launchpad.net/juju-core/container/lxc 0.324s
? launchpad.net/juju-core/container/lxc/mock [no test files]
ok launchpad.net/juju-core/downloader 5.366s
ok launchpad.net/juju-core/environs 1.770s
? launchpad.net/juju-core/environs/all [no test files]
# launchpad.net/juju-core/environs/azure
environs/azure/environ_test.go:608: unknown gwacl.HostedService field 'HostedServiceDescriptor' in struct literal
FAIL launchpad.net/juju-core/environs/azure [build failed]
ok launchpad.net/juju-core/environs/cloudinit 0.550s
ok launchpad.net/juju-core/environs/config 1.081s
ok launchpad.net/juju-core/environs/dummy 15.688s
ok launchpad.net/juju-core/environs/ec2 177.607s
ok launchpad.net/juju-core/environs/imagemetadata 0.266s
ok launchpad.net/juju-core/environs/instances 0.292s
ok launchpad.net/juju-core/environs/jujutest 0.204s
ok launchpad.net/juju-core/environs/local 1.182s
ok launchpad.net/juju-core/environs/localstorage 0.342s
ok launchpad.net/juju-core/environs/maas 8.823s
ok launchpad.net/juju-core/environs/openstack 8.702s
? launchpad.net/juju-core/environs/testing [no test files]
ok launchpad.net/juju-core/environs/tools 18.635s
? launchpad.net/juju-core/errors [no test files]
ok launchpad.net/juju-core/instance 0.007s
ok launchpad.net/juju-core/juju 12.085s
? launchpad.net/juju-core/juju/testing [no test files]
ok launchpad.net/juju-core/log 0.008s
ok launchpad.net/juju-core/log/syslog 0.010s
ok launchpad.net/juju-core/rpc 0.335s
ok launchpad.net/juju-core/rpc/jsoncodec 0.320s
ok launchpad.net/juju-core/schema 0.012s
ok launchpad.net/juju-core/state 61.116s
? launchpad.net/juju-core/state/api [no test files]
? launchpad.net/juju-core/state/api/common [no test files]
ok launchpad.net/juju-core/state/api/machineagent 1.476s
ok launchpad.net/juju-core/state/api/machiner 1.922s
ok launchpad.net/juju-core/state/api/params 0.021s
ok launchpad.net/juju-core/state/api/upgrader 2.775s
ok launchpad.net/juju-core/state/api/watcher 1.498s
ok launchpad.net/juju-core/state/apiserver 1.847s
ok launchpad.net/juju-core/state/apiserver/client 13.230s
ok launchpad.net/juju-core/state/apiserver/common 0.021s
ok launchpad.net/juju-core/state/apiserver/machine 3.547s
? launchpad.net/juju-core/state/apiserver/testing [no test files]
ok launchpad.net/juju-core/state/apiserver/upgrader 3.824s
ok launchpad.net/juju-core/state/multiwatcher 1.200s
ok...

Read more...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'environs/azure/customdata.go'
2--- environs/azure/customdata.go 1970-01-01 00:00:00 +0000
3+++ environs/azure/customdata.go 2013-07-11 11:40:35 +0000
4@@ -0,0 +1,40 @@
5+// Copyright 2013 Canonical Ltd.
6+// Licensed under the AGPLv3, see LICENCE file for details.
7+
8+package azure
9+
10+import (
11+ "encoding/base64"
12+ "fmt"
13+
14+ "launchpad.net/juju-core/environs/cloudinit"
15+ "launchpad.net/juju-core/utils"
16+)
17+
18+// userData returns a zipped cloudinit config.
19+// TODO(bug 1199847): Some of this work can be shared between providers.
20+func userData(cfg *cloudinit.MachineConfig) ([]byte, error) {
21+ cloudcfg, err := cloudinit.New(cfg)
22+ if err != nil {
23+ return nil, fmt.Errorf("problem with cloudinit config: %v", err)
24+ }
25+ data, err := cloudcfg.Render()
26+ if err != nil {
27+ return nil, fmt.Errorf("problem with cloudinit config: %v", err)
28+ }
29+ cdata := utils.Gzip(data)
30+ logger.Debugf("user data; %d bytes", len(cdata))
31+ return cdata, nil
32+}
33+
34+// makeCustomData produces custom data for Azure. This is a base64-encoded
35+// zipfile of cloudinit userdata.
36+func makeCustomData(cfg *cloudinit.MachineConfig) (string, error) {
37+ zipData, err := userData(cfg)
38+ if err != nil {
39+ return "", fmt.Errorf("failure while generating custom data: %v", err)
40+ }
41+ encodedData := base64.StdEncoding.EncodeToString(zipData)
42+ logger.Debugf("base64-encoded custom data: %d bytes", len(encodedData))
43+ return encodedData, nil
44+}
45
46=== added file 'environs/azure/customdata_test.go'
47--- environs/azure/customdata_test.go 1970-01-01 00:00:00 +0000
48+++ environs/azure/customdata_test.go 2013-07-11 11:40:35 +0000
49@@ -0,0 +1,90 @@
50+// Copyright 2013 Canonical Ltd.
51+// Licensed under the AGPLv3, see LICENCE file for details.
52+
53+package azure
54+
55+import (
56+ "encoding/base64"
57+
58+ gc "launchpad.net/gocheck"
59+
60+ "launchpad.net/juju-core/environs/cloudinit"
61+ "launchpad.net/juju-core/state"
62+ "launchpad.net/juju-core/state/api"
63+ "launchpad.net/juju-core/testing"
64+ "launchpad.net/juju-core/utils"
65+)
66+
67+type CustomDataSuite struct{}
68+
69+var _ = gc.Suite(&CustomDataSuite{})
70+
71+// makeMachineConfig produces a valid cloudinit machine config.
72+func makeMachineConfig(c *gc.C) *cloudinit.MachineConfig {
73+ dir := c.MkDir()
74+ machineID := "0"
75+ return &cloudinit.MachineConfig{
76+ MachineId: machineID,
77+ MachineNonce: "gxshasqlnng",
78+ DataDir: dir,
79+ Tools: &state.Tools{URL: "file://" + dir},
80+ StateInfo: &state.Info{
81+ CACert: []byte(testing.CACert),
82+ Addrs: []string{"127.0.0.1:123"},
83+ Tag: state.MachineTag(machineID),
84+ },
85+ APIInfo: &api.Info{
86+ CACert: []byte(testing.CACert),
87+ Addrs: []string{"127.0.0.1:123"},
88+ Tag: state.MachineTag(machineID),
89+ },
90+ }
91+}
92+
93+// makeBadMachineConfig produces a cloudinit machine config that cloudinit
94+// will reject as invalid.
95+func makeBadMachineConfig() *cloudinit.MachineConfig {
96+ // As it happens, a default-initialized config is invalid.
97+ return &cloudinit.MachineConfig{}
98+}
99+
100+func (*CustomDataSuite) TestUserDataFailsOnBadData(c *gc.C) {
101+ _, err := userData(makeBadMachineConfig())
102+ c.Assert(err, gc.NotNil)
103+ c.Check(err, gc.ErrorMatches, "problem with cloudinit config: .*")
104+}
105+
106+func (*CustomDataSuite) TestUserDataProducesZipFile(c *gc.C) {
107+ marker := "recognizable_text"
108+ cfg := makeMachineConfig(c)
109+ cfg.MachineNonce = marker
110+
111+ data, err := userData(cfg)
112+ c.Assert(err, gc.IsNil)
113+
114+ content, err := utils.Gunzip(data)
115+ c.Assert(err, gc.IsNil)
116+ // The regex syntax is weird here. It's a trick to work around
117+ // gocheck's matcher prefixing "^" to the regex and suffixing "$".
118+ // With this trick, we can scan for a pattern in a multi-line input.
119+ c.Check(string(content), gc.Matches, "(?s).*"+marker+".*")
120+}
121+
122+func (*CustomDataSuite) TestMakeCustomDataPropagatesError(c *gc.C) {
123+ _, err := makeCustomData(makeBadMachineConfig())
124+ c.Assert(err, gc.NotNil)
125+ c.Check(err, gc.ErrorMatches, "failure while generating custom data: problem with cloudinit config: .*")
126+}
127+
128+func (*CustomDataSuite) TestMakeCustomDataEncodesUserData(c *gc.C) {
129+ cfg := makeMachineConfig(c)
130+
131+ encodedData, err := makeCustomData(cfg)
132+ c.Assert(err, gc.IsNil)
133+
134+ data, err := base64.StdEncoding.DecodeString(encodedData)
135+ c.Assert(err, gc.IsNil)
136+ reference, err := userData(cfg)
137+ c.Assert(err, gc.IsNil)
138+ c.Check(data, gc.DeepEquals, reference)
139+}
140
141=== modified file 'environs/azure/environ_test.go'
142--- environs/azure/environ_test.go 2013-07-10 05:37:46 +0000
143+++ environs/azure/environ_test.go 2013-07-11 11:40:35 +0000
144@@ -604,8 +604,8 @@
145 }
146
147 func makeAzureService(name string) (*gwacl.HostedService, *gwacl.HostedServiceDescriptor) {
148- service1 := &gwacl.HostedService{ServiceName: name}
149 service1Desc := &gwacl.HostedServiceDescriptor{ServiceName: name}
150+ service1 := &gwacl.HostedService{HostedServiceDescriptor: *service1Desc}
151 return service1, service1Desc
152 }
153
154@@ -665,7 +665,7 @@
155 cleanup := setDummyStorage(c, env)
156 defer cleanup()
157
158- // Simulate 2 nodes corresponding to two Azure services.
159+ // Simulate 2 instances corresponding to two Azure services.
160 prefix := env.getEnvPrefix()
161 service1Name := prefix + "service1"
162 service2Name := prefix + "service2"
163
164=== modified file 'environs/ec2/ec2.go'
165--- environs/ec2/ec2.go 2013-07-10 11:11:12 +0000
166+++ environs/ec2/ec2.go 2013-07-11 11:40:35 +0000
167@@ -302,6 +302,7 @@
168 })
169 }
170
171+// TODO(bug 1199847): Some of this work can be shared between providers.
172 func (e *environ) userData(scfg *startInstanceParams, tools *state.Tools) ([]byte, error) {
173 mcfg := &cloudinit.MachineConfig{
174 MachineId: scfg.machineId,
175
176=== modified file 'environs/maas/util.go'
177--- environs/maas/util.go 2013-06-16 23:07:00 +0000
178+++ environs/maas/util.go 2013-07-11 11:40:35 +0000
179@@ -35,6 +35,7 @@
180 }
181
182 // userData returns a zipped cloudinit config.
183+// TODO(bug 1199847): Some of this work can be shared between providers.
184 func userData(cfg *cloudinit.MachineConfig, scripts ...string) ([]byte, error) {
185 cloudcfg := cloudinit_core.New()
186 for _, script := range scripts {
187
188=== modified file 'environs/openstack/provider.go'
189--- environs/openstack/provider.go 2013-07-10 11:11:12 +0000
190+++ environs/openstack/provider.go 2013-07-11 11:40:35 +0000
191@@ -629,6 +629,7 @@
192 withPublicIP bool
193 }
194
195+// TODO(bug 1199847): Some of this work can be shared between providers.
196 func (e *environ) userData(scfg *startInstanceParams, tools *state.Tools) ([]byte, error) {
197 mcfg := &cloudinit.MachineConfig{
198 MachineId: scfg.machineId,

Subscribers

People subscribed via source and target branches

to status/vote changes: