mojo bundle-show doesn't properly merge/update config files
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Mojo: Continuous Delivery for Juju |
Fix Released
|
High
|
Unassigned |
Bug Description
(Quickly-filed bug due to impending EOD< feel free to mark incomplete, I plan to flesh it out and propose a proper patch with tests next week):
One of our specs uses two config files, one has stuff like:
templates:
applications:
sca-app:
charm: {{charm_
num_units: 1
constraints: mem=2G
loadbalancer: sca-app-
options:
active: false
the other has stuff like:
templates:
applications:
sca-app:
options:
sca-worker:
options:
What we found is that, when this is converted to Python dicts and merged by Mojo's BundlePhase.show() logic, because it uses Python dictionary update() which is not recursive, the resulting dict looks like:
'templates': {'applications': {'sca-app': {'options': {'metrics_target': ''}},
So what's happening is each subsequent file's contents overwrite, rather than being merged, with the first-level values in the destination.
This patch to mojo makes config file/dict merging/updating sane by doing it recursively, note the recursive dict update function was shamelessly taken from stackoverflow.
=== modified file 'mojo/phase.py'
--- mojo/phase.py 2020-07-09 13:36:06 +0000
+++ mojo/phase.py 2020-07-10 20:09:20 +0000
@@ -25,6 +25,18 @@
JUJU_EXE_PATH, _ = get_command("juju")
+# Python update don't suffice, must be cleverer than the wolf
+from collections.abc import Mapping
+def update(orig_dict, new_dict):
+ for key, val in new_dict.items():
+ if isinstance(val, Mapping):
+ tmp = update(
+ orig_dict[key] = tmp
+ elif isinstance(val, list):
+ orig_dict[key] = (orig_dict.get(key, []) + val)
+ else:
+ orig_dict[key] = new_dict[key]
+ return orig_dict
class NoSuchPhaseErro
pass
@@ -1392,10 +1404,11 @@
for config in configs:
with open(config, 'r') as f:
- output.
+ # Use wolf update here
+ output = update(output, config_yaml)
if return_output:
return output
- print(output)
+ print(yaml.
class BundleDiff(
Related branches
- Stuart Bishop (community): Approve
- Daniel Manrique (community): Approve
- Canonical IS Reviewers: Pending requested
-
Diff: 101 lines (+30/-8)3 files modifiedmojo/phase.py (+6/-6)
mojo/tests/test_utils.py (+7/-1)
mojo/utils.py (+17/-1)
Changed in mojo: | |
status: | New → Triaged |
importance: | Undecided → High |
This has been fixed.