Merge lp:~wallyworld/goose/RunServer-userData-fix into lp:~gophers/goose/trunk

Proposed by Ian Booth
Status: Rejected
Rejected by: Ian Booth
Proposed branch: lp:~wallyworld/goose/RunServer-userData-fix
Merge into: lp:~gophers/goose/trunk
Diff against target: 42 lines (+5/-7)
2 files modified
nova/live_test.go (+1/-2)
nova/nova.go (+4/-5)
To merge this branch: bzr merge lp:~wallyworld/goose/RunServer-userData-fix
Reviewer Review Type Date Requested Status
The Go Language Gophers Pending
Review via email: mp+145539@code.launchpad.net

Description of the change

Fix RunServerOpts Userdata

The UserData attribute of RunServerOpts was []byte, but it needs to be string to make juju bootstrap work.

All the current nova tests simply ignore this attribute - they pass in nil. I tried writing a test to set up
a cloud init config with a simple script command and introduced a deliberate error but the nova create server
operation succeeded nonetheless. Yet the huge cloud init script used by juju bootstrap fails. So I'm not sure
how to set up a small, self contained test in goose for the userData attribute. The code in this merge proposal
makes juju happy though, apart from that fact that Canonistack sometimes gives a "Resource limit exeeded" error
when bootstrapping a juju instance.

https://codereview.appspot.com/7221070/

To post a comment you must log in.
Revision history for this message
Ian Booth (wallyworld) wrote :

Reviewers: mp+145539_code.launchpad.net,

Message:
Please take a look.

Description:
Fix RunServerOpts Userdata

The UserData attribute of RunServerOpts was []byte, but it needs to be
string to make juju bootstrap work.

All the current nova tests simply ignore this attribute - they pass in
nil. I tried writing a test to set up
a cloud init config with a simple script command and introduced a
deliberate error but the nova create server
operation succeeded nonetheless. Yet the huge cloud init script used by
juju bootstrap fails. So I'm not sure
how to set up a small, self contained test in goose for the userData
attribute. The code in this merge proposal
makes juju happy though, apart from that fact that Canonistack sometimes
gives a "Resource limit exeeded" error
when bootstrapping a juju instance.

https://code.launchpad.net/~wallyworld/goose/RunServer-userData-fix/+merge/145539

(do not edit description out of merge proposal)

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

Affected files:
   A [revision details]
   M nova/live_test.go
   M nova/nova.go

Index: [revision details]
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision:
<email address hidden>
+New revision: <email address hidden>

Index: nova/live_test.go
=== modified file 'nova/live_test.go'
--- nova/live_test.go 2013-01-29 16:04:31 +0000
+++ nova/live_test.go 2013-01-30 04:40:58 +0000
@@ -67,9 +67,8 @@
    Name: name,
    FlavorId: testFlavourId,
    ImageId: testImageId,
- UserData: nil,
   }
- instance, err = s.nova.RunServer(opts)
+ instance, err = s.nova.RunServer(opts, nil)
   if err != nil {
    return nil, err
   }

Index: nova/nova.go
=== modified file 'nova/nova.go'
--- nova/nova.go 2013-01-29 16:32:50 +0000
+++ nova/nova.go 2013-01-30 04:40:58 +0000
@@ -242,19 +242,18 @@
   Name string `json:"name"` //
Required
   FlavorId string `json:"flavorRef"` //
Required
   ImageId string `json:"imageRef"` //
Required
- UserData []byte `json:"user_data"` //
Optional
+ UserData string `json:"user_data"` //
Optional
   SecurityGroupNames []SecurityGroupName `json:"security_groups"` //
Optional
  }

  // RunServer creates a new server, based on the given RunServerOpts.
-func (c *Client) RunServer(opts RunServerOpts) (*Entity, error) {
+func (c *Client) RunServer(opts RunServerOpts, userData []byte) (*Entity,
error) {
   var req struct {
    Server RunServerOpts `json:"server"`
   }
   req.Server = opts
- if opts.UserData != nil {
- encoded := base64.StdEncoding.EncodeToString(opts.UserData)
- req.Server.UserData = []byte(encoded)
+ if userData != nil {
+ req.Server.UserData = base64.StdEncoding.EncodeToString(userData)
   }
   var resp struct {
    Server Entity `json:"server"`

Revision history for this message
John A Meinel (jameinel) wrote :

I think this is the right fix. ISTR that if you use []byte in a data
structure, JSON.Marshal(struct) will encode "foo" as [102, 111, 111].

So I like the change, but I'd really like to see a test for it, since it
is one of those "everything seemed fine but failed in reality" issues.

https://codereview.appspot.com/7221070/

Revision history for this message
Dimiter Naydenov (dimitern) wrote :

On 2013/01/30 04:50:43, wallyworld wrote:
> Please take a look.

LGTM, but why did you move UserData out of the RunServerOpts struct?

https://codereview.appspot.com/7221070/

Revision history for this message
John A Meinel (jameinel) wrote :

On 2013/01/30 06:57:14, dimitern wrote:
> On 2013/01/30 04:50:43, wallyworld wrote:
> > Please take a look.

> LGTM, but why did you move UserData out of the RunServerOpts struct?

I don't think he removed it, he just changed its type from a []byte to a
string.
However, if you still want to pass in a []byte, you can't just shove it
in the struct, because that slot now holds a string.

Then again, we shouldn't really be using the struct for
bytes-on-the-wire as the same struct for
passing-parameters-to-the-function. Because of differences like this.

Maybe it means the conversion to string should be done at a higher level
(before passing it into this function). But it does look like the other
conversions are being done at this level.

https://codereview.appspot.com/7221070/

Revision history for this message
Dimiter Naydenov (dimitern) wrote :

On 2013/01/30 04:50:43, wallyworld wrote:
> Please take a look.

NOT LGTM - as discussed, this change is not needed, because the problem
is we shouldn't encode userData in base64, as being []byte this is done
automatically by go (see the docs). I have a CL which just removes the
encoding and will propose it shortly.

https://codereview.appspot.com/7221070/

Unmerged revisions

58. By Ian Booth

Change RunServerOpts.UserData from []byte to string to make server creation work for openstack provider

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'nova/live_test.go'
2--- nova/live_test.go 2013-01-29 16:04:31 +0000
3+++ nova/live_test.go 2013-01-30 04:51:21 +0000
4@@ -67,9 +67,8 @@
5 Name: name,
6 FlavorId: testFlavourId,
7 ImageId: testImageId,
8- UserData: nil,
9 }
10- instance, err = s.nova.RunServer(opts)
11+ instance, err = s.nova.RunServer(opts, nil)
12 if err != nil {
13 return nil, err
14 }
15
16=== modified file 'nova/nova.go'
17--- nova/nova.go 2013-01-29 16:32:50 +0000
18+++ nova/nova.go 2013-01-30 04:51:21 +0000
19@@ -242,19 +242,18 @@
20 Name string `json:"name"` // Required
21 FlavorId string `json:"flavorRef"` // Required
22 ImageId string `json:"imageRef"` // Required
23- UserData []byte `json:"user_data"` // Optional
24+ UserData string `json:"user_data"` // Optional
25 SecurityGroupNames []SecurityGroupName `json:"security_groups"` // Optional
26 }
27
28 // RunServer creates a new server, based on the given RunServerOpts.
29-func (c *Client) RunServer(opts RunServerOpts) (*Entity, error) {
30+func (c *Client) RunServer(opts RunServerOpts, userData []byte) (*Entity, error) {
31 var req struct {
32 Server RunServerOpts `json:"server"`
33 }
34 req.Server = opts
35- if opts.UserData != nil {
36- encoded := base64.StdEncoding.EncodeToString(opts.UserData)
37- req.Server.UserData = []byte(encoded)
38+ if userData != nil {
39+ req.Server.UserData = base64.StdEncoding.EncodeToString(userData)
40 }
41 var resp struct {
42 Server Entity `json:"server"`

Subscribers

People subscribed via source and target branches