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
1=== modified file 'deployer/action/diff.py'
2--- deployer/action/diff.py 2016-07-12 23:43:08 +0000
3+++ deployer/action/diff.py 2016-12-14 10:48:27 +0000
4@@ -122,28 +122,39 @@
5 delta['modified'][cs] = mod
6 return delta
7
8- def _diff_service(self, e_s, d_s, charm):
9+ def _diff_service(self, env_service, dep_service, charm):
10 mod = {}
11- d_sc = parse_constraints(d_s.get('constraints', ''))
12+
13+ # Start by diffing the constraints.
14+ dep_constraints = parse_constraints(dep_service.get('constraints', ''))
15 # 'tags' is a special case, as it can be multi-valued: convert to list
16- # if cfg one is a string
17- if isinstance(d_sc.get('tags'), six.string_types):
18- d_sc['tags'] = [d_sc['tags']]
19- if d_sc != e_s['constraints']:
20- mod['env-constraints'] = e_s['constraints']
21- mod['cfg-constraints'] = d_sc
22- for k, v in d_s.get('options', {}).items():
23- # Deploy options not known to the env may originate
24- # from charm version delta or be an invalid config.
25- if k not in e_s['options']:
26- continue
27- e_v = e_s['options'].get(k, {}).get('value')
28- if e_v != v:
29- mod.setdefault('env-config', {}).update({k: e_v})
30- mod.setdefault('cfg-config', {}).update({k: v})
31+ # if the deployment specifies just a string
32+ if isinstance(dep_constraints.get('tags'), six.string_types):
33+ dep_constraints['tags'] = [dep_constraints['tags']]
34+ if dep_constraints != env_service['constraints']:
35+ mod['env-constraints'] = env_service['constraints']
36+ mod['cfg-constraints'] = dep_constraints
37+
38+ # Now collect all the options from both services and diff them.
39+ all_options = set(dep_service.get('options', {}).keys() +
40+ env_service.get('options', {}).keys())
41+ for key in all_options:
42+ dep_value = dep_service.get('options', {}).get(key)
43+ # Assume the charm default if the deployment specifies no value.
44+ if dep_value is None:
45+ dep_value = charm.config.get(key, {}).get('default', None)
46+ env_value = env_service['options'].get(key, {}).get('value')
47+ if env_value != dep_value:
48+ mod.setdefault('env-config', {}).update({key: env_value})
49+ mod.setdefault('cfg-config', {}).update({key: dep_value})
50+
51+ # Finally, compare the unit counts if appropriate.
52 if not charm or not charm.is_subordinate():
53- if e_s['unit_count'] != d_s.get('num_units', 1):
54- mod['num_units'] = e_s['unit_count'] - d_s.get('num_units', 1)
55+ # XXX: The num_units default policy should really be
56+ # implemented centrally.
57+ dep_unit_count = dep_service.get('num_units', 1)
58+ if env_service['unit_count'] != dep_unit_count:
59+ mod['num_units'] = env_service['unit_count'] - dep_unit_count
60 return mod
61
62 def do_diff(self):
63
64=== modified file 'deployer/tests/test_diff.py'
65--- deployer/tests/test_diff.py 2016-05-07 23:48:30 +0000
66+++ deployer/tests/test_diff.py 2016-12-14 10:48:27 +0000
67@@ -79,26 +79,24 @@
68 def test_diff_config(self):
69 dpl = self.get_deployment()
70 env = MemoryEnvironment(dpl.name, dpl)
71- env.set_config('blog', {'tuning': 'bare'})
72- diff = Diff(env, dpl, {}).do_diff()
73- mod_blog = diff['services']['modified']['blog']
74- self.assertTrue(mod_blog['env-config']['tuning'] !=
75- mod_blog['cfg-config']['tuning'])
76- self.assertEquals(mod_blog['env-config']['tuning'], 'bare')
77-
78- def test_diff_config_many(self):
79- dpl = self.get_deployment()
80- env = MemoryEnvironment(dpl.name, dpl)
81- env.set_config('blog', {'tuning': 'bare', 'engine': 'duck'})
82- diff = Diff(env, dpl, {}).do_diff()
83- mod_blog = diff['services']['modified']['blog']
84- self.assertEqual(
85- set(mod_blog['env-config'].keys()),
86- set(['tuning', 'engine']))
87- self.assertTrue(mod_blog['env-config']['tuning'] !=
88- mod_blog['cfg-config']['tuning'])
89- self.assertTrue(mod_blog['env-config']['engine'] !=
90- mod_blog['cfg-config']['engine'])
91+ # Reconfigure the environment to have a couple of explicit
92+ # changes (tuning and engine), one that differs from the charm
93+ # default (debug), and an option that no longer exists in the
94+ # charm (obsolete).
95+ env.set_config(
96+ 'blog',
97+ {'tuning': 'bare', 'engine': 'duck', 'debug': 'please',
98+ 'obsolete': 'for ages'})
99+ diff = Diff(env, dpl, {}).do_diff()
100+ mod_blog = diff['services']['modified']['blog']
101+ self.assertEqual(
102+ mod_blog['env-config'],
103+ {'engine': 'duck', 'tuning': 'bare', 'debug': 'please',
104+ 'obsolete': 'for ages'})
105+ self.assertEqual(
106+ mod_blog['cfg-config'],
107+ {'engine': 'nginx', 'tuning': 'optimized', 'debug': 'no',
108+ 'obsolete': None})
109
110 def test_diff_constraints(self):
111 dpl = self.get_deployment()

Subscribers

People subscribed via source and target branches