diff options
-rw-r--r-- | meta-phosphor/common/recipes-phosphor/settings/phosphor-settings.bb | 29 | ||||
-rwxr-xr-x | meta-phosphor/common/recipes-phosphor/settings/phosphor-settings/merge_settings.py | 58 |
2 files changed, 87 insertions, 0 deletions
diff --git a/meta-phosphor/common/recipes-phosphor/settings/phosphor-settings.bb b/meta-phosphor/common/recipes-phosphor/settings/phosphor-settings.bb index 686f3c083..d03eca86d 100644 --- a/meta-phosphor/common/recipes-phosphor/settings/phosphor-settings.bb +++ b/meta-phosphor/common/recipes-phosphor/settings/phosphor-settings.bb @@ -7,6 +7,7 @@ inherit allarch inherit obmc-phosphor-license inherit setuptools inherit obmc-phosphor-dbus-service +inherit pythonnative DBUS_SERVICE_${PN} = "org.openbmc.settings.Host.service" @@ -16,7 +17,35 @@ PROVIDES += "virtual/obmc-settings-mgmt" RPROVIDES_${PN} += "virtual-obmc-settings-mgmt" SRC_URI += "git://github.com/openbmc/phosphor-settingsd" +SRC_URI += "file://merge_settings.py" SRCREV = "3b8d055ca761a68c74dad01a306f238674d71878" S = "${WORKDIR}/git" + +# Collect files in SRC_URI that end in ".override.yml" and call a script that +# writes their contents over that of settings.yaml, which is then updated to +# the merged data values. +# This doesn't correctly handle globs in ".override.yml" entries in SRC_URI. +python do_merge_settings () { + import subprocess + + # TODO: Perform the merge in a temporary directory? + workdir = d.getVar('WORKDIR', True) + cmd = [] + cmd.append(os.path.join(workdir, 'merge_settings.py')) + cmd.append(os.path.join(d.getVar('S', True), 'settings.yaml')) + + fetch = bb.fetch2.Fetch([], d) + override_urls = filter(lambda f: f.endswith('.override.yml'), fetch.urls) + for url in override_urls: + bb.debug(2, 'Overriding with source: ' + url) + local_base = os.path.basename(fetch.localpath(url)) + filename = os.path.join(workdir, local_base) + cmd.append(filename) + + # Invoke the script and don't catch any resulting exception. + subprocess.check_call(cmd) +} +# python-pyyaml-native is installed by do_configure, so put this task after +addtask merge_settings after do_configure before do_compile diff --git a/meta-phosphor/common/recipes-phosphor/settings/phosphor-settings/merge_settings.py b/meta-phosphor/common/recipes-phosphor/settings/phosphor-settings/merge_settings.py new file mode 100755 index 000000000..01f5e3552 --- /dev/null +++ b/meta-phosphor/common/recipes-phosphor/settings/phosphor-settings/merge_settings.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +"""Loads a "target" YAML file and overwrites its values with values from +"override" YAML files. + +Override files are processed in the order given. + +Usage: + merge_settings.py <target yaml> [override yamls] +""" +import sys +import yaml +import copy + +def dict_merge(target, source): + """Deep merge for dicts. + + Works like dict.update() that recursively updates any dict values present in + both parameters. + + Args: + target (dict): Values to be overwritten by corresponding values from + `source`. + source (dict): Overriding values. Not changed by call. + + Returns: + `target` with values overwritten from those in `source` at any and all + levels of nested dicts. + """ + if not isinstance(source, dict): + return source + for k, v in source.iteritems(): + if k in target and isinstance(target[k], dict): + dict_merge(target[k], v) + else: + target[k] = copy.deepcopy(v) + return target + +if len(sys.argv) < 2: + sys.exit('Argument required: target yaml') + +if len(sys.argv) == 2: + # No overrides to handle + sys.exit() + +target_filename = sys.argv[1] +with open(target_filename) as target_file: + data = yaml.safe_load(target_file) + print('Loaded target YAML file ' + target_filename) + +for override_filename in sys.argv[2:]: + with open(override_filename) as override_file: + override = yaml.safe_load(override_file) + dict_merge(data, override) + print('Merged override YAML file ' + override_filename) + +with open(target_filename, 'w') as target_file: + yaml.dump(data, target_file) + print('Wrote merged target YAML file ' + target_filename) |