Merge lp:~dimitern/juju-core/lp-1308146-1.18-backport into lp:juju-core/1.18

Proposed by Dimiter Naydenov
Status: Merged
Approved by: Martin Packman
Approved revision: no longer in the source branch.
Merged at revision: 2298
Proposed branch: lp:~dimitern/juju-core/lp-1308146-1.18-backport
Merge into: lp:juju-core/1.18
Diff against target: 108 lines (+66/-1)
3 files modified
state/charm.go (+11/-0)
state/state.go (+10/-1)
state/state_test.go (+45/-0)
To merge this branch: bzr merge lp:~dimitern/juju-core/lp-1308146-1.18-backport
Reviewer Review Type Date Requested Status
Martin Packman (community) Approve
Review via email: mp+235116@code.launchpad.net

This proposal supersedes a proposal from 2014-09-18.

Commit message

Fixed lp:1308146 - backported from github/trunk

See http://pad.lv/1308146 - this fixes the issue by backporting
the already landed fix from github.com/juju/juju/ trunk - for
more info, see https://github.com/juju/juju/pull/786.

Description of the change

Fixed lp:1308146 - backported from github/trunk

See http://pad.lv/1308146 - this fixes the issue by backporting
the already landed fix from github.com/juju/juju/ trunk - for
more info, see https://github.com/juju/juju/pull/786.

EDIT: Fixed base from lp:juju-core to lp:juju-core/1.18
(lbox propose somehow managed to get it wrong)

To post a comment you must log in.
Revision history for this message
Dimiter Naydenov (dimitern) wrote : Posted in a previous version of this proposal
Download full text (10.3 KiB)

Reviewers: mp+235115_code.launchpad.net,

Message:
Please take a look.

Description:
Fixed lp:1308146 - backported from github/trunk

See http://pad.lv/1308146 - this fixes the issue by backporting
the already landed fix from github.com/juju/juju/ trunk - for
more info, see https://github.com/juju/juju/pull/786.

https://code.launchpad.net/~dimitern/juju-core/lp-1308146-1.18-backport/+merge/235115

(do not edit description out of merge proposal)

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

Affected files (+85, -12 lines):
   A [revision details]
   M agent/mongo/mongo.go
   M environs/cloudinit/cloudinit_test.go
   M environs/instances/instancetype.go
   M environs/instances/instancetype_test.go
   M environs/testing/tools.go
   M provider/ec2/image_test.go
   M scripts/win-installer/setup.iss
   M state/charm.go
   M state/state.go
   M state/state_test.go
   M version/version.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: tarmac-20140513040856-lm051mdy3n916km6
+New revision:
<email address hidden>

Index: state/state_test.go
=== modified file 'state/state_test.go'
--- state/state_test.go 2014-03-27 12:53:54 +0000
+++ state/state_test.go 2014-09-18 12:52:26 +0000
@@ -6,6 +6,7 @@
  import (
   "fmt"
   "net/url"
+ "path/filepath"
   "sort"
   "strconv"
   "time"
@@ -340,6 +341,50 @@
   c.Assert(sch.BundleSha256(), gc.Equals, "missing")
  }

+func (s *StateSuite) TestUpdateUploadedCharmEscapesSpecialCharsInConfig(c
*gc.C) {
+ // Make sure when we have mongodb special characters like "$" and
+ // "." in the name of any charm config option, we do proper
+ // escaping before storing them and unescaping after loading. See
+ // also http://pad.lv/1308146.
+
+ // Clone the dummy charm and change the config.
+ configWithProblematicKeys := []byte(`
+options:
+ $bad.key: {default: bad, description: bad, type: string}
+ not.ok.key: {description: not ok, type: int}
+ valid-key: {description: all good, type: boolean}
+ still$bad.: {description: not good, type: float}
+ $.$: {description: awful, type: string}
+ ...: {description: oh boy, type: int}
+ just$: {description: no no, type: float}
+`[1:])
+ chDir := testing.Charms.ClonedDirPath(c.MkDir(), "dummy")
+ err := utils.AtomicWriteFile(
+ filepath.Join(chDir, "config.yaml"),
+ configWithProblematicKeys,
+ 0666,
+ )
+ c.Assert(err, gc.IsNil)
+ ch, err := charm.ReadDir(chDir)
+ c.Assert(err, gc.IsNil)
+ missingCurl := charm.MustParseURL("local:quantal/missing-1")
+ bundleURL, err := url.Parse("http://bundles.testing.invalid/dummy-1")
+ c.Assert(err, gc.IsNil)
+
+ _, err = s.State.PrepareLocalCharmUpload(missingCurl)
+ c.Assert(err, gc.IsNil)
+ sch, err := s.State.UpdateUploadedCharm(ch, missingCurl,
bundleURL, "missing")
+ c.Assert(err, gc.IsNil)
+ c.Assert(sch.URL(), gc.DeepEquals, missingCurl)
+ c.Assert(sch.Revision(), gc.Equals, missingCurl.Revision)
+ c.Assert(sch.IsUploaded(), jc.IsTrue)
+ c.Assert(sch.IsPlaceholder(), jc.IsFalse)
+ c.Assert(sch.Meta(), gc.DeepEquals, ch.Meta()...

Revision history for this message
Martin Packman (gz) wrote :

Looks good to me.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'state/charm.go'
2--- state/charm.go 2014-01-29 20:57:31 +0000
3+++ state/charm.go 2014-09-18 12:58:15 +0000
4@@ -27,6 +27,17 @@
5 }
6
7 func newCharm(st *State, cdoc *charmDoc) (*Charm, error) {
8+ // Because we probably just read the doc from state, make sure we
9+ // unescape any config option names for "$" and ".". See
10+ // http://pad.lv/1308146
11+ if cdoc != nil && cdoc.Config != nil {
12+ unescapedConfig := charm.NewConfig()
13+ for optionName, option := range cdoc.Config.Options {
14+ unescapedName := unescapeReplacer.Replace(optionName)
15+ unescapedConfig.Options[unescapedName] = option
16+ }
17+ cdoc.Config = unescapedConfig
18+ }
19 return &Charm{st: st, doc: *cdoc}, nil
20 }
21
22
23=== modified file 'state/state.go'
24--- state/state.go 2014-03-26 18:37:50 +0000
25+++ state/state.go 2014-09-18 12:58:15 +0000
26@@ -855,9 +855,18 @@
27 func (st *State) updateCharmDoc(
28 ch charm.Charm, curl *charm.URL, bundleURL *url.URL, bundleSha256 string, preReq interface{}) (*Charm, error) {
29
30+ // Make sure we escape any "$" and "." in config option names
31+ // first. See http://pad.lv/1308146.
32+ cfg := ch.Config()
33+ escapedConfig := charm.NewConfig()
34+ for optionName, option := range cfg.Options {
35+ escapedName := escapeReplacer.Replace(optionName)
36+ escapedConfig.Options[escapedName] = option
37+ }
38+
39 updateFields := bson.D{{"$set", bson.D{
40 {"meta", ch.Meta()},
41- {"config", ch.Config()},
42+ {"config", escapedConfig},
43 {"bundleurl", bundleURL},
44 {"bundlesha256", bundleSha256},
45 {"pendingupload", false},
46
47=== modified file 'state/state_test.go'
48--- state/state_test.go 2014-03-27 12:53:54 +0000
49+++ state/state_test.go 2014-09-18 12:58:15 +0000
50@@ -6,6 +6,7 @@
51 import (
52 "fmt"
53 "net/url"
54+ "path/filepath"
55 "sort"
56 "strconv"
57 "time"
58@@ -340,6 +341,50 @@
59 c.Assert(sch.BundleSha256(), gc.Equals, "missing")
60 }
61
62+func (s *StateSuite) TestUpdateUploadedCharmEscapesSpecialCharsInConfig(c *gc.C) {
63+ // Make sure when we have mongodb special characters like "$" and
64+ // "." in the name of any charm config option, we do proper
65+ // escaping before storing them and unescaping after loading. See
66+ // also http://pad.lv/1308146.
67+
68+ // Clone the dummy charm and change the config.
69+ configWithProblematicKeys := []byte(`
70+options:
71+ $bad.key: {default: bad, description: bad, type: string}
72+ not.ok.key: {description: not ok, type: int}
73+ valid-key: {description: all good, type: boolean}
74+ still$bad.: {description: not good, type: float}
75+ $.$: {description: awful, type: string}
76+ ...: {description: oh boy, type: int}
77+ just$: {description: no no, type: float}
78+`[1:])
79+ chDir := testing.Charms.ClonedDirPath(c.MkDir(), "dummy")
80+ err := utils.AtomicWriteFile(
81+ filepath.Join(chDir, "config.yaml"),
82+ configWithProblematicKeys,
83+ 0666,
84+ )
85+ c.Assert(err, gc.IsNil)
86+ ch, err := charm.ReadDir(chDir)
87+ c.Assert(err, gc.IsNil)
88+ missingCurl := charm.MustParseURL("local:quantal/missing-1")
89+ bundleURL, err := url.Parse("http://bundles.testing.invalid/dummy-1")
90+ c.Assert(err, gc.IsNil)
91+
92+ _, err = s.State.PrepareLocalCharmUpload(missingCurl)
93+ c.Assert(err, gc.IsNil)
94+ sch, err := s.State.UpdateUploadedCharm(ch, missingCurl, bundleURL, "missing")
95+ c.Assert(err, gc.IsNil)
96+ c.Assert(sch.URL(), gc.DeepEquals, missingCurl)
97+ c.Assert(sch.Revision(), gc.Equals, missingCurl.Revision)
98+ c.Assert(sch.IsUploaded(), jc.IsTrue)
99+ c.Assert(sch.IsPlaceholder(), jc.IsFalse)
100+ c.Assert(sch.Meta(), gc.DeepEquals, ch.Meta())
101+ c.Assert(sch.Config(), gc.DeepEquals, ch.Config())
102+ c.Assert(sch.BundleURL(), gc.DeepEquals, bundleURL)
103+ c.Assert(sch.BundleSha256(), gc.Equals, "missing")
104+}
105+
106 func (s *StateSuite) assertPlaceholderCharmExists(c *gc.C, curl *charm.URL) {
107 // Find charm directly and verify only the charm URL and
108 // Placeholder are set.

Subscribers

People subscribed via source and target branches

to all changes: