Merge lp:~wgrant/juju-deployer/diff-all-options into lp:juju-deployer

Proposed by William Grant
Status: Merged
Merged at revision: 204
Proposed branch: lp:~wgrant/juju-deployer/diff-all-options
Merge into: lp:juju-deployer
Diff against target: 111 lines (+48/-39)
2 files modified
deployer/action/diff.py (+30/-19)
deployer/tests/test_diff.py (+18/-20)
To merge this branch: bzr merge lp:~wgrant/juju-deployer/diff-all-options
Reviewer Review Type Date Requested Status
Tim Van Steenburgh (community) Approve
Review via email: mp+313208@code.launchpad.net

Commit message

Fix service config diffs to include all keys and respect charm defaults.

Description of the change

Fix service config diffs to include all keys and respect charm defaults.

Cherrypicked and adapted from jjo's multiple relations branch.

To post a comment you must log in.
Revision history for this message
Tim Van Steenburgh (tvansteenburgh) wrote :

LGTM, thanks.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'deployer/action/diff.py'
--- deployer/action/diff.py 2016-07-12 23:43:08 +0000
+++ deployer/action/diff.py 2016-12-14 10:48:27 +0000
@@ -122,28 +122,39 @@
122 delta['modified'][cs] = mod122 delta['modified'][cs] = mod
123 return delta123 return delta
124124
125 def _diff_service(self, e_s, d_s, charm):125 def _diff_service(self, env_service, dep_service, charm):
126 mod = {}126 mod = {}
127 d_sc = parse_constraints(d_s.get('constraints', ''))127
128 # Start by diffing the constraints.
129 dep_constraints = parse_constraints(dep_service.get('constraints', ''))
128 # 'tags' is a special case, as it can be multi-valued: convert to list130 # 'tags' is a special case, as it can be multi-valued: convert to list
129 # if cfg one is a string131 # if the deployment specifies just a string
130 if isinstance(d_sc.get('tags'), six.string_types):132 if isinstance(dep_constraints.get('tags'), six.string_types):
131 d_sc['tags'] = [d_sc['tags']]133 dep_constraints['tags'] = [dep_constraints['tags']]
132 if d_sc != e_s['constraints']:134 if dep_constraints != env_service['constraints']:
133 mod['env-constraints'] = e_s['constraints']135 mod['env-constraints'] = env_service['constraints']
134 mod['cfg-constraints'] = d_sc136 mod['cfg-constraints'] = dep_constraints
135 for k, v in d_s.get('options', {}).items():137
136 # Deploy options not known to the env may originate138 # Now collect all the options from both services and diff them.
137 # from charm version delta or be an invalid config.139 all_options = set(dep_service.get('options', {}).keys() +
138 if k not in e_s['options']:140 env_service.get('options', {}).keys())
139 continue141 for key in all_options:
140 e_v = e_s['options'].get(k, {}).get('value')142 dep_value = dep_service.get('options', {}).get(key)
141 if e_v != v:143 # Assume the charm default if the deployment specifies no value.
142 mod.setdefault('env-config', {}).update({k: e_v})144 if dep_value is None:
143 mod.setdefault('cfg-config', {}).update({k: v})145 dep_value = charm.config.get(key, {}).get('default', None)
146 env_value = env_service['options'].get(key, {}).get('value')
147 if env_value != dep_value:
148 mod.setdefault('env-config', {}).update({key: env_value})
149 mod.setdefault('cfg-config', {}).update({key: dep_value})
150
151 # Finally, compare the unit counts if appropriate.
144 if not charm or not charm.is_subordinate():152 if not charm or not charm.is_subordinate():
145 if e_s['unit_count'] != d_s.get('num_units', 1):153 # XXX: The num_units default policy should really be
146 mod['num_units'] = e_s['unit_count'] - d_s.get('num_units', 1)154 # implemented centrally.
155 dep_unit_count = dep_service.get('num_units', 1)
156 if env_service['unit_count'] != dep_unit_count:
157 mod['num_units'] = env_service['unit_count'] - dep_unit_count
147 return mod158 return mod
148159
149 def do_diff(self):160 def do_diff(self):
150161
=== modified file 'deployer/tests/test_diff.py'
--- deployer/tests/test_diff.py 2016-05-07 23:48:30 +0000
+++ deployer/tests/test_diff.py 2016-12-14 10:48:27 +0000
@@ -79,26 +79,24 @@
79 def test_diff_config(self):79 def test_diff_config(self):
80 dpl = self.get_deployment()80 dpl = self.get_deployment()
81 env = MemoryEnvironment(dpl.name, dpl)81 env = MemoryEnvironment(dpl.name, dpl)
82 env.set_config('blog', {'tuning': 'bare'})82 # Reconfigure the environment to have a couple of explicit
83 diff = Diff(env, dpl, {}).do_diff()83 # changes (tuning and engine), one that differs from the charm
84 mod_blog = diff['services']['modified']['blog']84 # default (debug), and an option that no longer exists in the
85 self.assertTrue(mod_blog['env-config']['tuning'] !=85 # charm (obsolete).
86 mod_blog['cfg-config']['tuning'])86 env.set_config(
87 self.assertEquals(mod_blog['env-config']['tuning'], 'bare')87 'blog',
8888 {'tuning': 'bare', 'engine': 'duck', 'debug': 'please',
89 def test_diff_config_many(self):89 'obsolete': 'for ages'})
90 dpl = self.get_deployment()90 diff = Diff(env, dpl, {}).do_diff()
91 env = MemoryEnvironment(dpl.name, dpl)91 mod_blog = diff['services']['modified']['blog']
92 env.set_config('blog', {'tuning': 'bare', 'engine': 'duck'})92 self.assertEqual(
93 diff = Diff(env, dpl, {}).do_diff()93 mod_blog['env-config'],
94 mod_blog = diff['services']['modified']['blog']94 {'engine': 'duck', 'tuning': 'bare', 'debug': 'please',
95 self.assertEqual(95 'obsolete': 'for ages'})
96 set(mod_blog['env-config'].keys()),96 self.assertEqual(
97 set(['tuning', 'engine']))97 mod_blog['cfg-config'],
98 self.assertTrue(mod_blog['env-config']['tuning'] !=98 {'engine': 'nginx', 'tuning': 'optimized', 'debug': 'no',
99 mod_blog['cfg-config']['tuning'])99 'obsolete': None})
100 self.assertTrue(mod_blog['env-config']['engine'] !=
101 mod_blog['cfg-config']['engine'])
102100
103 def test_diff_constraints(self):101 def test_diff_constraints(self):
104 dpl = self.get_deployment()102 dpl = self.get_deployment()

Subscribers

People subscribed via source and target branches