diff options
author | Sergey Solomin <sergey.solomin@us.ibm.com> | 2016-10-13 10:40:27 -0500 |
---|---|---|
committer | Sergey Solomin <sergey.solomin@us.ibm.com> | 2016-11-08 13:41:12 -0600 |
commit | 62b55f35fde5e057bb7b0294f2e2d8ad66170e2d (patch) | |
tree | 2c4c11fc345e971505c95b242a8b90ec20384380 | |
parent | 4a2433fdb0628871795c563f056c6d3f37560078 (diff) | |
download | phosphor-settingsd-62b55f35fde5e057bb7b0294f2e2d8ad66170e2d.tar.gz phosphor-settingsd-62b55f35fde5e057bb7b0294f2e2d8ad66170e2d.zip |
Create top categories dynamically based on inventory object.
Presently, the settingsd code will statically create objects 'host0',
'bmc0' and 'bmc0/clock' from top-level categories Host and Bmc
in the YAML file. This code provides a 1-to-1 mapping between
YAML categories and inventory objects and changes filename format
to correspond to an inventory object.
Resolves openbmc/openbmc#638
Change-Id: I462cf4c7b7cf042b37e1006a73b36bf11fa52b43
Signed-off-by: Sergey Solomin <sergey.solomin@us.ibm.com>
-rw-r--r-- | README.txt | 17 | ||||
-rw-r--r-- | settings.yaml | 130 | ||||
-rw-r--r-- | settings_manager.py | 61 |
3 files changed, 125 insertions, 83 deletions
diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..7e7c1b6 --- /dev/null +++ b/README.txt @@ -0,0 +1,17 @@ +How to use 'query' in the YAML file +'query' contains information for settings_manager.py to search for +and match inventory objects: + +query: + name: type + keyregex: "dimm" + subtree: "/org/openbmc/inventory" + matchregex: "/(dimm\d*)$" + +In the example above setting_manager.py will explore all existing +objects at /org/openbmc/inventory that relate to the 'dimm' main +category in the YAML file. +The 'matchregex' will identify all objects with names that start with 'dimm', +followed by any number of digits. The name should be at the end of the path. +settings_manager.py will create a corresponding object with the same name, +which is a group (dimm\d*). diff --git a/settings.yaml b/settings.yaml index ca26840..7e88be0 100644 --- a/settings.yaml +++ b/settings.yaml @@ -1,68 +1,74 @@ --- # Settings Config File org.openbmc.settings.Host: - powercap: - name: power_cap - type: i - default: 0 - min: 0 - max: 1000 - unit: watts - validation: range - bootflags: - name: boot_flags - type: s - default: "default" - validation: list - allowed: ["Network", "Disk", "Safe", "CDROM", "Setup", "default"] - sysstate: - name: system_state - type: s - default: "" - validation: None - powerpolicy: - name: power_policy - type: s - default: "RESTORE_LAST_STATE" - validation: list - allowed: ["ALWAYS_POWER_ON", "RESTORE_LAST_STATE", "LEAVE_OFF"] - restrictedmode: - name: restricted_mode - type: b - default: false - min: 0 - max: 1 - validation: range - bootpolicy: - name: boot_policy - type: s - default: "ONETIME" - validation: list - allowed: ["ONETIME", "PERMANENT"] - networkconfig: - name: network_config - type: s - default: "ipaddress=,prefix=,gateway=,mac=,addr_type=" - validation: custom - method: validate_net_config - TimeMode: - name: time_mode - type: s - default: "NTP" - validation: list - allowed: ["NTP", "MANUAL"] - TimeOwner: - name: time_owner - type: s - default: "BMC" - validation: list - allowed: ["BMC", "HOST", "SPLIT", "BOTH"] - UseDhcpNtp: - name: use_dhcp_ntp - type: s - default: "yes" - validation: list - allowed: ["yes", "no"] + settings: + powercap: + name: power_cap + type: i + default: 0 + min: 0 + max: 1000 + unit: watts + validation: range + bootflags: + name: boot_flags + type: s + default: "default" + validation: list + allowed: ["Network", "Disk", "Safe", "CDROM", "Setup", "default"] + sysstate: + name: system_state + type: s + default: "" + validation: None + powerpolicy: + name: power_policy + type: s + default: "RESTORE_LAST_STATE" + validation: list + allowed: ["ALWAYS_POWER_ON", "RESTORE_LAST_STATE", "LEAVE_OFF"] + restrictedmode: + name: restricted_mode + type: b + default: false + min: 0 + max: 1 + validation: range + bootpolicy: + name: boot_policy + type: s + default: "ONETIME" + validation: list + allowed: ["ONETIME", "PERMANENT"] + networkconfig: + name: network_config + type: s + default: "ipaddress=,prefix=,gateway=,mac=,addr_type=" + validation: custom + method: validate_net_config + TimeMode: + name: time_mode + type: s + default: "NTP" + validation: list + allowed: ["NTP", "MANUAL"] + TimeOwner: + name: time_owner + type: s + default: "BMC" + validation: list + allowed: ["BMC", "HOST", "SPLIT", "BOTH"] + UseDhcpNtp: + name: use_dhcp_ntp + type: s + default: "yes" + validation: list + allowed: ["yes", "no"] + query: + type: instance_query + keyregex: "host" + subtree: "/org/openbmc/control" + matchregex: "control/(host\d*)$" # Example of using regex # macaddress: diff --git a/settings_manager.py b/settings_manager.py index 3e09ce5..77e200b 100644 --- a/settings_manager.py +++ b/settings_manager.py @@ -17,6 +17,7 @@ settings_file_path = os.path.join( sys.path.insert(1, settings_file_path) import settings_file as s import re +import obmc.mapper DBUS_NAME = 'org.openbmc.settings.Host' CONTROL_INTF = 'org.openbmc.Settings' @@ -37,26 +38,42 @@ def walk_nest(d, keys =()): def create_object(settings): """Create and format objects. - Parse dictionary file and return all objects and main properties - (name, type, default) for each attribute in the following format: - [obj_name, attr_ name, attr_ type, default] + Parse dictionary file and return all objects and settings + in the following format: {obj_name {settings}} """ + mapper = obmc.mapper.Mapper(bus) allobjects = {} + queries = {} for compound_key, val in walk_nest(settings): obj_name = compound_key[0].lower() obj_name = obj_name.replace(".","/") obj_name = "/" + obj_name + "0" - for i in compound_key[1:len(compound_key)-2]: + for i in compound_key[2:len(compound_key)-2]: obj_name = obj_name + "/" + i setting = compound_key[len(compound_key) - 2] attribute = compound_key[len(compound_key) - 1] - - o = allobjects.setdefault(obj_name, {}) - s = o.setdefault(setting, {'name': None, 'type': None, 'default': None}) + if settings.get(compound_key[0], {}).get('query', {}): + q = queries.setdefault(obj_name, {}) + s = q.setdefault( + setting, {'name': None, 'type': None, 'default': None}) + else: + o = allobjects.setdefault(obj_name, {}) + s = o.setdefault( + setting, {'name': None, 'type': None, 'default': None}) s[attribute] = val - + for settings in queries.itervalues(): + for setting in settings.itervalues(): + if setting['type'] is not 'instance_query': + continue + paths = mapper.get_subtree_paths(setting['subtree'], 0) + for path in paths: + m = re.search(setting['matchregex'], path) + if not m: + continue + allobjects.setdefault( + "/org/openbmc/settings/" + m.group(1), settings) return allobjects class HostSettingsObject(DbusProperties): @@ -69,6 +86,7 @@ class HostSettingsObject(DbusProperties): self.path = path self.name = name self.settings = settings + fname = name[name.rfind("/")+1:] + '-' # Needed to ignore the validation on default networkconfig values as # opposed to user giving the same. @@ -86,15 +104,16 @@ class HostSettingsObject(DbusProperties): # Create the dbus properties for setting in settings.itervalues(): - self.set_settings_property(setting['name'], - setting['type'], - setting['default']) + if setting['type'] is 'instance_query': + continue + self.set_settings_property( + setting['name'], setting['type'], setting['default'], fname) # Done with consuming factory settings. self.adminmode = False - def get_bmc_value(self, name): + def get_bmc_value(self, name, fname): try: - with open(path.join(self.path, name), 'r') as f: + with open(path.join(self.path, fname + name), 'r') as f: return f.read() except (IOError): pass @@ -104,8 +123,8 @@ class HostSettingsObject(DbusProperties): # This will be either a value previously set, # or the default file value if the BMC value # does not exist. - def set_settings_property(self, attr_name, attr_type, value): - bmcv = self.get_bmc_value(attr_name) + def set_settings_property(self, attr_name, attr_type, value, fname): + bmcv = self.get_bmc_value(attr_name, fname) if bmcv: value = bmcv if attr_type == "i": @@ -117,19 +136,20 @@ class HostSettingsObject(DbusProperties): # Save the settings to the BMC. This will write the settings value in # individual files named by the property name to the BMC. - def set_system_settings(self, name, value): - bmcv = self.get_bmc_value(name) + def set_system_settings(self, name, value, fname): + bmcv = self.get_bmc_value(name, fname) if bmcv != value: - filepath = path.join(self.path, name) + filepath = path.join(self.path, fname + name) with open(filepath, 'w') as f: f.write(str(value)) # Signal handler for when one ore more settings properties were updated. # This will sync the changes to the BMC. def settings_signal_handler( - self, interface_name, changed_properties, invalidated_properties): + self, interface_name, changed_properties, invalidated_properties, + fname): for name, value in changed_properties.items(): - self.set_system_settings(name, value) + self.set_system_settings(name, value, fname) # Placeholder signal. Needed to register the settings interface. @dbus.service.signal(DBUS_NAME, signature='s') @@ -227,7 +247,6 @@ if __name__ == '__main__': for o, settings in allobjects.iteritems(): objs.append(HostSettingsObject(bus, o, settings, "/var/lib/obmc/")) objs[-1].unmask_signals() - mainloop = gobject.MainLoop() name = dbus.service.BusName(DBUS_NAME, bus) print "Running HostSettingsService" |