From 487948d820fc2717184daa96bebf2f8c6ffd4e01 Mon Sep 17 00:00:00 2001 From: Kun Yi Date: Wed, 27 Mar 2019 09:23:54 -0700 Subject: cleanup: Remove Python code and build files Remove Python code and build files now that we switched to C++ mapper Tested: built mapper package and no Python file is included Signed-off-by: Kun Yi Change-Id: Ia8832eaae52ed85b4c1620a5d0db181e6b744ac7 --- Makefile.am | 22 -- configure.ac | 7 +- obmc/mapper/__init__.py | 6 - obmc/mapper/bindings.py | 207 ------------- obmc/mapper/server.py | 803 ------------------------------------------------ obmc/mapper/utils.py | 130 -------- phosphor-mapper | 53 ---- setup.cfg | 3 - setup.py.in | 7 - 9 files changed, 1 insertion(+), 1237 deletions(-) delete mode 100644 obmc/mapper/__init__.py delete mode 100644 obmc/mapper/bindings.py delete mode 100644 obmc/mapper/server.py delete mode 100644 obmc/mapper/utils.py delete mode 100644 phosphor-mapper delete mode 100644 setup.cfg delete mode 100644 setup.py.in diff --git a/Makefile.am b/Makefile.am index fe71472..5fe5662 100644 --- a/Makefile.am +++ b/Makefile.am @@ -36,28 +36,6 @@ mapperx_CXXFLAGS = $(SYSTEMD_CFLAGS) -DBOOST_SYSTEM_NO_DEPRECATED -DBOOST_ERROR_ include_HEADERS = libmapper/mapper.h -if HAVE_PYTHON - -all-local: - $(AM_V_at)$(PYTHON) ${top_builddir}/setup.py build - -clean-local: - rm -rfv ${top_builddir}/build - -install-exec-hook: - $(AM_V_at)$(PYTHON) ${top_builddir}/setup.py install \ - --prefix=$(DESTDIR)${prefix} \ - --install-data=$(DESTDIR)${datadir} \ - --install-lib=$(DESTDIR)$(PYTHONDIR) \ - --install-scripts=$(DESTDIR)${sbindir} \ - --record=${top_builddir}/python_install.log - -uninstall-hook: - cat ${top_builddir}/python_install.log \ - | $(AWK) '{print "$(DESTDIR)"$$1}' | xargs rm -fv - -endif - SUBDIRS = fail-monitor check_PROGRAMS = diff --git a/configure.ac b/configure.ac index 030e72a..104c2df 100644 --- a/configure.ac +++ b/configure.ac @@ -18,11 +18,6 @@ AM_PROG_AR AC_PROG_INSTALL AC_PROG_MAKE_SET AC_PROG_AWK -# Python -AM_PATH_PYTHON([2.7], [AC_SUBST([PYTHON], [echo "$PYTHON"])], [AC_MSG_ERROR([Could not find python-2.7 installed...python-2.7 is required])]) -AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != :]) -AC_SUBST([HAVE_PYTHON]) -AC_SUBST([PYTHONDIR], ${pythondir}) # Checks for libraries. PKG_CHECK_MODULES([SDBUSPLUS], [sdbusplus]) @@ -166,5 +161,5 @@ AS_IF([test "x$enable_unpatched_systemd" == "xyes"], ) # Create configured output -AC_CONFIG_FILES([Makefile setup.py fail-monitor/Makefile]) +AC_CONFIG_FILES([Makefile fail-monitor/Makefile]) AC_OUTPUT diff --git a/obmc/mapper/__init__.py b/obmc/mapper/__init__.py deleted file mode 100644 index 679b9c8..0000000 --- a/obmc/mapper/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -import obmc.mapper.bindings -from obmc.mapper.bindings import Mapper -from obmc.mapper.bindings import MAPPER_NAME -from obmc.mapper.bindings import MAPPER_IFACE -from obmc.mapper.bindings import MAPPER_PATH -from obmc.mapper.bindings import MAPPER_NOT_FOUND diff --git a/obmc/mapper/bindings.py b/obmc/mapper/bindings.py deleted file mode 100644 index 8024105..0000000 --- a/obmc/mapper/bindings.py +++ /dev/null @@ -1,207 +0,0 @@ -# Contributors Listed Below - COPYRIGHT 2016 -# [+] International Business Machines Corp. -# -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. See the License for the specific language governing -# permissions and limitations under the License. - -import dbus -import obmc.dbuslib.enums -import obmc.utils.pathtree - - -MAPPER_NAME = 'xyz.openbmc_project.ObjectMapper' -MAPPER_IFACE = MAPPER_NAME -MAPPER_PATH = '/xyz/openbmc_project/object_mapper' -MAPPER_NOT_FOUND = 'org.freedesktop.DBus.Error.FileNotFound' - -# The default D-Bus interfaces that we don't need to get -# properties on during an enumerate. -DEFAULT_IFACES = ['org.freedesktop.DBus.Introspectable', - 'org.freedesktop.DBus.Peer', - 'org.freedesktop.DBus.Properties'] - - -class Mapper: - def __init__(self, bus): - self.bus = bus - obj = bus.get_object(MAPPER_NAME, MAPPER_PATH, introspect=False) - self.iface = dbus.Interface( - obj, dbus_interface=MAPPER_IFACE) - - @staticmethod - def retry(func, retries, interval): - e = None - count = 0 - while count < retries: - try: - return func() - except dbus.exceptions.DBusException as e: - if e.get_dbus_name() not in \ - ['org.freedesktop.DBus.Error.ObjectPathInUse', - 'org.freedesktop.DBus.Error.LimitsExceeded']: - raise - - count += 1 - if interval > 0: - from time import sleep - sleep(interval) - if e: - raise e - - def get_object(self, path, retries=5, interfaces=[], interval=0.2): - return self.retry( - lambda: self.iface.GetObject( - path, interfaces, signature='sas'), - retries, interval) - - def get_subtree_paths( - self, path='/', depth=0, retries=5, interfaces=[], interval=0.2): - return self.retry( - lambda: self.iface.GetSubTreePaths( - path, depth, interfaces, signature='sias'), - retries, interval) - - def get_subtree( - self, path='/', depth=0, retries=5, interfaces=[], interval=0.2): - return self.retry( - lambda: self.iface.GetSubTree( - path, depth, interfaces, signature='sias'), - retries, interval) - - def get_ancestors(self, path, retries=5, interfaces=[], interval=0.2): - return self.retry( - lambda: self.iface.GetAncestors( - path, interfaces, signature='sas'), - retries, interval) - - @staticmethod - def __try_properties_interface(f, *a): - try: - return f(*a) - except dbus.exceptions.DBusException as e: - if obmc.dbuslib.enums.DBUS_UNKNOWN_INTERFACE in \ - e.get_dbus_name(): - # interface doesn't have any properties - return None - if obmc.dbuslib.enums.DBUS_UNKNOWN_METHOD == e.get_dbus_name(): - # properties interface not implemented at all - return None - raise - - @staticmethod - def __get_properties_on_iface(properties_iface, iface): - properties = Mapper.__try_properties_interface( - properties_iface.GetAll, iface) - if properties is None: - return {} - return properties - - def __get_properties_on_bus(self, path, bus, interfaces, match): - properties = {} - obj = self.bus.get_object(bus, path, introspect=False) - properties_iface = dbus.Interface( - obj, dbus_interface=dbus.PROPERTIES_IFACE) - for i in interfaces: - if match and not match(i): - continue - if i in DEFAULT_IFACES: - continue - properties.update(self.__get_properties_on_iface( - properties_iface, i)) - - return properties - - def enumerate_object( - self, path, - match=lambda x: x != dbus.BUS_DAEMON_IFACE + '.ObjectManager', - mapper_data=None): - if mapper_data is None: - mapper_data = {path: self.get_object(path)} - - obj = {} - - for owner, interfaces in mapper_data[path].items(): - obj.update( - self.__get_properties_on_bus( - path, owner, interfaces, match)) - - return obj - - def enumerate_subtree( - self, path='/', - match=lambda x: x != dbus.BUS_DAEMON_IFACE + '.ObjectManager', - mapper_data=None): - if mapper_data is None: - mapper_data = self.get_subtree(path) - managers = {} - owners = [] - - # look for objectmanager implementations as they result - # in fewer dbus calls - for path, bus_data in mapper_data.items(): - for owner, interfaces in bus_data.items(): - owners.append(owner) - if dbus.BUS_DAEMON_IFACE + '.ObjectManager' in interfaces: - managers[owner] = path - - # also look in the parent objects - ancestors = self.get_ancestors(path) - - # finally check the root for one too - try: - ancestors.update({path: self.get_object(path)}) - except dbus.exceptions.DBusException as e: - if e.get_dbus_name() != MAPPER_NOT_FOUND: - raise - - for path, bus_data in ancestors.items(): - for owner, interfaces in bus_data.items(): - if dbus.BUS_DAEMON_IFACE + '.ObjectManager' in interfaces: - managers[owner] = path - - mapper_keys = set(mapper_data.keys()) - - # make all the manager gmo (get managed objects) calls - results = {} - for owner, path in managers.items(): - if owner not in owners: - continue - obj = self.bus.get_object(owner, path, introspect=False) - iface = dbus.Interface( - obj, dbus.BUS_DAEMON_IFACE + '.ObjectManager') - - # flatten (remove interface names) gmo results - for path, interfaces in \ - iface.GetManagedObjects().items(): - if path not in mapper_keys: - continue - properties = {} - for iface, props in interfaces.items(): - properties.update(props) - results.setdefault(path, {}).setdefault(owner, properties) - - # make dbus calls for any remaining objects - for path, bus_data in mapper_data.items(): - for owner, interfaces in bus_data.items(): - if results.setdefault(path, {}).setdefault(owner, {}): - continue - results[path][owner].update( - self.__get_properties_on_bus( - path, owner, interfaces, match)) - - objs = obmc.utils.pathtree.PathTree() - for path, owners in results.items(): - for owner, properties in owners.items(): - objs.setdefault(path, {}).update(properties) - - return objs diff --git a/obmc/mapper/server.py b/obmc/mapper/server.py deleted file mode 100644 index 4a6ce16..0000000 --- a/obmc/mapper/server.py +++ /dev/null @@ -1,803 +0,0 @@ -# Contributors Listed Below - COPYRIGHT 2017 -# [+] International Business Machines Corp. -# -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. See the License for the specific language governing -# permissions and limitations under the License. - -import dbus -import dbus.service -import dbus.exceptions -import dbus.mainloop.glib -# TODO: openbmc/openbmc#2994 remove python 2 support -try: # python 2 - import gobject -except ImportError: # python 3 - from gi.repository import GObject as gobject -import xml.etree.ElementTree as ET -import obmc.utils.pathtree -import obmc.mapper -import obmc.dbuslib.bindings -import obmc.dbuslib.enums -import sys -import traceback -from itertools import chain - - -class MapperNotFoundException(dbus.exceptions.DBusException): - _dbus_error_name = obmc.mapper.MAPPER_NOT_FOUND - - def __init__(self, path): - super(MapperNotFoundException, self).__init__( - "path or object not found: %s" % path) - - -def find_dbus_interfaces(conn, service, path, callback, error_callback, **kw): - iface_match = kw.pop('iface_match', bool) - - class _FindInterfaces(object): - def __init__(self): - self.results = {} - self.introspect_pending = [] - self.gmo_pending = [] - self.assoc_pending = [] - - @staticmethod - def _to_path(elements): - return '/' + '/'.join(elements) - - @staticmethod - def _to_path_elements(path): - return filter(bool, path.split('/')) - - def __call__(self, path): - try: - self._find_interfaces(path) - except Exception as e: - error_callback(service, path, e) - - @staticmethod - def _match(iface): - return iface == dbus.BUS_DAEMON_IFACE + '.ObjectManager' \ - or iface_match(iface) - - def check_done(self): - if any([ - self.introspect_pending, - self.gmo_pending, - self.assoc_pending]): - return - - callback(service, self.results) - - def _assoc_callback(self, path, associations): - try: - iface = obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE - self.assoc_pending.remove(path) - self.results[path][iface]['associations'] = associations - except Exception as e: - error_callback(service, path, e) - return None - - self.check_done() - - def _gmo_callback(self, path, objs): - try: - self.gmo_pending.remove(path) - for k, v in objs.items(): - self.results[k] = dict(x for x in v.items() - if iface_match(x[0])) - except Exception as e: - error_callback(service, path, e) - return None - - self.check_done() - - def _introspect_callback(self, path, data): - self.introspect_pending.remove(path) - if data is None: - self.check_done() - return - - try: - path_elements = self._to_path_elements(path) - root = ET.fromstring(data) - all_ifaces = root.findall('interface') - ifaces = filter(self._match, - [x.attrib.get('name') for x in all_ifaces]) - ifaces = {x: {} for x in ifaces} - self.results[path] = ifaces - - if obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE in ifaces: - obj = conn.get_object(service, path, introspect=False) - iface = dbus.Interface(obj, dbus.PROPERTIES_IFACE) - self.assoc_pending.append(path) - iface.Get.call_async( - obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE, - 'associations', - reply_handler=lambda x: self._assoc_callback( - path, x), - error_handler=lambda e: error_callback( - service, path, e)) - - if dbus.BUS_DAEMON_IFACE + '.ObjectManager' in ifaces: - obj = conn.get_object(service, path, introspect=False) - iface = dbus.Interface( - obj, dbus.BUS_DAEMON_IFACE + '.ObjectManager') - self.gmo_pending.append(path) - iface.GetManagedObjects.call_async( - reply_handler=lambda x: self._gmo_callback( - path, x), - error_handler=lambda e: error_callback( - service, path, e)) - else: - children = filter( - bool, - [x.attrib.get('name') for x in root.findall('node')]) - children = [ - self._to_path(chain(path_elements, - self._to_path_elements(x))) - for x in sorted(children)] - for child in children: - if child not in self.results: - self._find_interfaces(child) - except Exception as e: - error_callback(service, path, e) - return None - - self.check_done() - - def _find_interfaces(self, path): - path = self._to_path(self._to_path_elements(path)) - obj = conn.get_object(service, path, introspect=False) - iface = dbus.Interface(obj, dbus.INTROSPECTABLE_IFACE) - self.introspect_pending.append(path) - iface.Introspect.call_async( - reply_handler=lambda x: self._introspect_callback(path, x), - error_handler=lambda x: error_callback(service, path, x)) - - return _FindInterfaces()(path) - - -@obmc.dbuslib.bindings.add_interfaces([obmc.dbuslib.enums.OBMC_ASSOC_IFACE]) -class Association(obmc.dbuslib.bindings.DbusProperties): - """Implementation of org.openbmc.Association.""" - - iface = obmc.dbuslib.enums.OBMC_ASSOC_IFACE - - def __init__(self, bus, path, endpoints): - """Construct an Association. - - Arguments: - bus -- The python-dbus connection to host the interface - path -- The D-Bus object path on which to implement the interface - endpoints -- A list of the initial association endpoints - """ - super(Association, self).__init__(conn=bus, object_path=path) - self.properties = {self.iface: {'endpoints': endpoints}} - self.unmask_signals() - - -class Manager(obmc.dbuslib.bindings.DbusObjectManager): - def __init__(self, bus, path): - super(Manager, self).__init__(conn=bus, object_path=path) - - -class ObjectMapper(dbus.service.Object): - def __init__( - self, bus, path, namespaces, service_namespaces, - interface_namespaces, blacklist, service_blacklist, - interface_blacklist): - super(ObjectMapper, self).__init__(bus, path) - self.cache = obmc.utils.pathtree.PathTree() - self.bus = bus - self.service = None - self.index = {} - self.manager = Manager(bus, obmc.dbuslib.bindings.OBJ_PREFIX) - self.bus_map = {} - self.defer_signals = {} - self.namespaces = namespaces - self.service_namespaces = service_namespaces - self.interface_namespaces = interface_namespaces - self.blacklist = blacklist - self.blacklist.append(obmc.mapper.MAPPER_PATH) - self.service_blacklist = service_blacklist - self.interface_blacklist = interface_blacklist - - # add my object mananger instance - self.add_new_objmgr( - obmc.dbuslib.bindings.OBJ_PREFIX, obmc.mapper.MAPPER_NAME) - - self.bus.add_signal_receiver( - self.bus_handler, - dbus_interface=dbus.BUS_DAEMON_IFACE, - signal_name='NameOwnerChanged') - self.bus.add_signal_receiver( - self.interfaces_added_handler, - dbus_interface=dbus.BUS_DAEMON_IFACE + '.ObjectManager', - signal_name='InterfacesAdded', - sender_keyword='sender', - path_keyword='sender_path') - self.bus.add_signal_receiver( - self.interfaces_removed_handler, - dbus_interface=dbus.BUS_DAEMON_IFACE + '.ObjectManager', - signal_name='InterfacesRemoved', - sender_keyword='sender', - path_keyword='sender_path') - self.bus.add_signal_receiver( - self.properties_changed_handler, - dbus_interface=dbus.PROPERTIES_IFACE, - signal_name='PropertiesChanged', - arg0=obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE, - path_keyword='path', - sender_keyword='sender') - - print("ObjectMapper startup complete. Discovery in progress...") - self.discover() - gobject.idle_add(self.claim_name) - - def claim_name(self): - if len(self.defer_signals): - return True - print("ObjectMapper discovery complete") - self.service = dbus.service.BusName( - obmc.mapper.MAPPER_NAME, self.bus) - self.manager.unmask_signals() - return False - - def discovery_callback(self, owner, items): - if owner in self.defer_signals: - self.add_items(owner, items) - pending = self.defer_signals[owner] - del self.defer_signals[owner] - - for x in pending: - x() - self.IntrospectionComplete(owner) - - def discovery_error(self, owner, path, e): - '''Log a message and remove all traces of the service - we were attempting to introspect.''' - - if owner in self.defer_signals: - - # Safe to add a reference to the traceback here, - # since it cannot contain the discovery_error frame. - exctype, value, tb = sys.exc_info() - sys.stderr.write( - '{} discovery failure on {}\n'.format(owner, path)) - if tb: - traceback.print_exception(exctype, value, tb, file=sys.stderr) - else: - sys.stderr.write('{}: {}\n'.format(e.__class__.__name__, e)) - - del self.defer_signals[owner] - del self.bus_map[owner] - - def cache_get(self, path): - cache_entry = self.cache.get(path, {}) - if cache_entry is None: - # hide path elements without any interfaces - cache_entry = {} - return cache_entry - - def add_new_objmgr(self, path, owner): - # We don't get a signal for the ObjectManager - # interface itself, so if we see a signal from - # make sure its in our cache, and add it if not. - cache_entry = self.cache_get(path) - old = self.interfaces_get(cache_entry, owner) - new = set(old).union([dbus.BUS_DAEMON_IFACE + '.ObjectManager']) - self.update_interfaces(path, owner, old, new) - - def defer_signal(self, owner, callback): - self.defer_signals.setdefault(owner, []).append(callback) - - def interfaces_added_handler(self, path, iprops, **kw): - path = str(path) - owner = self.bus_normalize(str(kw['sender'])) - if not owner: - return - interfaces = self.filter_signal_interfaces(iprops.keys()) - if not interfaces: - return - - if owner not in self.defer_signals: - self.add_new_objmgr(str(kw['sender_path']), owner) - cache_entry = self.cache_get(path) - old = self.interfaces_get(cache_entry, owner) - new = set(interfaces).union(old) - new = {x: iprops.get(x, {}) for x in new} - self.update_interfaces(path, owner, old, new) - else: - self.defer_signal( - owner, - lambda: self.interfaces_added_handler( - path, iprops, **kw)) - - def interfaces_removed_handler(self, path, interfaces, **kw): - path = str(path) - owner = self.bus_normalize(str(kw['sender'])) - if not owner: - return - interfaces = self.filter_signal_interfaces(interfaces) - if not interfaces: - return - - if owner not in self.defer_signals: - self.add_new_objmgr(str(kw['sender_path']), owner) - cache_entry = self.cache_get(path) - old = self.interfaces_get(cache_entry, owner) - new = set(old).difference(interfaces) - self.update_interfaces(path, owner, old, new) - else: - self.defer_signal( - owner, - lambda: self.interfaces_removed_handler( - path, interfaces, **kw)) - - def properties_changed_handler(self, interface, new, old, **kw): - owner = self.bus_normalize(str(kw['sender'])) - path = str(kw['path']) - if not owner: - return - interfaces = self.filter_signal_interfaces([interface]) - if not self.is_association(interfaces): - return - associations = new.get('associations', None) - if associations is None: - return - - if owner not in self.defer_signals: - associations = [ - (str(x), str(y), str(z)) for x, y, z in associations] - self.update_associations( - path, owner, - self.index_get_associations(path, [owner]), - associations) - else: - self.defer_signal( - owner, - lambda: self.properties_changed_handler( - interface, new, old, **kw)) - - def process_new_owner(self, owned_name, owner): - # unique name - try: - if self.busname_match(owned_name): - self.discover([(owned_name, owner)]) - except dbus.exceptions.DBusException as e: - if obmc.dbuslib.enums.DBUS_UNKNOWN_SERVICE \ - not in e.get_dbus_name(): - raise - - def process_old_owner(self, owned_name, owner): - if owner in self.bus_map: - del self.bus_map[owner] - - for path, item in self.cache.dataitems(): - old = self.interfaces_get(item, owned_name) - if old: - # remove all interfaces for this service - self.update_interfaces( - path, owned_name, old=old, new=[]) - - def bus_handler(self, owned_name, old, new): - if obmc.dbuslib.bindings.is_unique(owned_name) or \ - owned_name == obmc.mapper.MAPPER_NAME: - return - - if new: - self.process_new_owner(owned_name, new) - if old: - # discard any unhandled signals - # or in progress discovery - if owned_name in self.defer_signals: - del self.defer_signals[owned_name] - - self.process_old_owner(owned_name, old) - - def update_interfaces(self, path, owner, old, new): - # __xx -> intf list - # xx -> intf dict - if isinstance(old, dict): - __old = old.keys() - else: - __old = old - old = {x: {} for x in old} - if isinstance(new, dict): - __new = new.keys() - else: - __new = new - new = {x: {} for x in new} - - cache_entry = self.cache.setdefault(path, {}) - created = [] if self.has_interfaces(cache_entry) else [path] - added = set(__new).difference(__old) - removed = set(__old).difference(__new) - self.interfaces_append(cache_entry, owner, added) - self.interfaces_remove(cache_entry, owner, removed, path) - destroyed = [] if self.has_interfaces(cache_entry) else [path] - - # react to anything that requires association updates - new_assoc = [] - old_assoc = [] - if self.is_association(added): - iface = obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE - new_assoc = new[iface]['associations'] - if self.is_association(removed): - old_assoc = self.index_get_associations(path, [owner]) - self.update_associations( - path, owner, old_assoc, new_assoc, created, destroyed) - - def add_items(self, owner, bus_items): - for path, items in bus_items.items(): - self.update_interfaces(path, str(owner), old=[], new=items) - - def busname_match(self, busname): - match = False - - if not any([x for x in self.service_blacklist if x in busname]): - # not blacklisted - - if any([x for x in self.service_namespaces if x in busname]): - # a watched busname contains the path - match = True - elif any([busname for x in self.service_namespaces - if busname in x]): - # the busname contains a watched namespace - match = True - - return match - - def interface_match(self, interface): - match = True - - if any([x for x in self.interface_blacklist if x in interface]): - # not blacklisted - match = False - elif not any([x for x in self.interface_namespaces if x in interface]): - # the interface contains a watched interface namespace - match = False - - return match - - def discovery_error_retry(self, owner, path, e): - sys.stderr.write( - '{} discovery failure on {} - retry\n'.format(owner, path)) - find_dbus_interfaces(self.bus, owner, '/', - self.discovery_callback, - self.discovery_error, - iface_match=self.interface_match) - - def discover(self, owners=None): - if owners is None: - owners = [] - - def get_owner(name): - try: - return (name, self.bus.get_name_owner(name)) - except Exception: - traceback.print_exception(*sys.exc_info()) - - if not owners: - owned_names = [ - x for x in filter(self.busname_match, self.bus.list_names()) - if not obmc.dbuslib.bindings.is_unique(x)] - owners = filter(bool, (get_owner(name) for name in owned_names)) - for owned_name, o in owners: - if not self.bus_normalize(owned_name): - continue - self.bus_map[o] = owned_name - self.defer_signals[owned_name] = [] - find_dbus_interfaces( - self.bus, owned_name, '/', - self.discovery_callback, - self.discovery_error_retry, - iface_match=self.interface_match) - - def bus_normalize(self, name): - ''' - Normalize on well-known names and filter signals - originating from the mapper. - ''' - - if obmc.dbuslib.bindings.is_unique(name): - name = self.bus_map.get(name) - - if name == obmc.mapper.MAPPER_NAME: - return None - - return name - - def filter_signal_interfaces(self, interfaces): - return [str(x) for x in interfaces if self.interface_match(x)] - - @staticmethod - def interfaces_get(item, owner, default=None): - if default is None: - default = [] - return item.get(owner, default) - - @staticmethod - def interfaces_append(item, owner, append): - interfaces = item.setdefault(owner, []) - item[owner] = list(set(append).union(interfaces)) - - def interfaces_remove(self, item, owner, remove, path): - interfaces = item.get(owner, []) - item[owner] = list(set(interfaces).difference(remove)) - - if not item[owner]: - # remove the owner if there aren't any interfaces left - del item[owner] - - if item: - # other owners remain - return - - if self.cache.get_children(path): - # there are still references to this path - # from objects further down the tree. - # mark it for removal if that changes - self.cache.demote(path) - else: - # delete the entire path if everything is gone - del self.cache[path] - - @staticmethod - def filter_interfaces(item, ifaces): - return ObjectMapper._filter_interfaces(item, set(ifaces)) - - @staticmethod - def _filter_interfaces(item, ifaces): - if isinstance(item, dict): - # Called with a single object. - if not ifaces: - return item - - filtered = dict() - for k, v in item.items(): - isec = ifaces.intersection(v) - if isec: - filtered[k] = isec - - return filtered - - # Called with a list of path/object tuples. - if not ifaces: - return dict(item) - - if not item: - return dict() - - filtered = dict() - for i in item: - children = ObjectMapper._filter_interfaces(i[1], ifaces) - if children: - filtered[i[0]] = children - - return filtered - - @dbus.service.method(obmc.mapper.MAPPER_IFACE, 'sas', 'a{sas}') - def GetObject(self, path, interfaces): - o = self.cache_get(path) - if not o: - raise MapperNotFoundException(path) - - return self.filter_interfaces(o, interfaces) - - @dbus.service.method(obmc.mapper.MAPPER_IFACE, 'sias', 'as') - def GetSubTreePaths(self, path, depth, interfaces): - try: - return self.filter_interfaces( - self.cache.iteritems(path, depth), - interfaces) - except KeyError: - raise MapperNotFoundException(path) - - @dbus.service.method(obmc.mapper.MAPPER_IFACE, 'sias', 'a{sa{sas}}') - def GetSubTree(self, path, depth, interfaces): - try: - return self.filter_interfaces( - self.cache.dataitems(path, depth), - interfaces) - except KeyError: - raise MapperNotFoundException(path) - - @staticmethod - def has_interfaces(item): - return any(item.values()) - - @staticmethod - def is_association(interfaces): - return obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE in interfaces - - def index_get(self, index, path, owners): - items = [] - item = self.index.get(index, {}) - item = item.get(path, {}) - for o in owners: - items.extend(item.get(o, [])) - return items - - def index_append(self, index, path, owner, assoc): - item = self.index.setdefault(index, {}) - item = item.setdefault(path, {}) - item = item.setdefault(owner, []) - item.append(assoc) - - def index_remove(self, index, path, owner, assoc): - index = self.index.get(index, {}) - owners = index.get(path, {}) - items = owners.get(owner, []) - if assoc in items: - items.remove(assoc) - if not items: - del owners[owner] - if not owners: - del index[path] - - def index_get_associations(self, path, owners=[], direction='forward'): - forward = 'forward' if direction == 'forward' else 'reverse' - reverse = 'reverse' if direction == 'forward' else 'forward' - - associations = [] - if not owners: - index = self.index.get(forward, {}) - owners = index.get(path, {}).keys() - - # f: forward - # r: reverse - for rassoc in self.index_get(forward, path, owners): - elements = rassoc.split('/') - rtype = ''.join(elements[-1:]) - fendpoint = '/'.join(elements[:-1]) - for fassoc in self.index_get(reverse, fendpoint, owners): - elements = fassoc.split('/') - ftype = ''.join(elements[-1:]) - rendpoint = '/'.join(elements[:-1]) - if rendpoint != path: - continue - associations.append((ftype, rtype, fendpoint)) - - return associations - - def update_association(self, path, removed, added): - iface = obmc.dbuslib.enums.OBMC_ASSOC_IFACE - assoc = self.manager.get(path, None) - - old_endpoints = set(assoc.Get(iface, 'endpoints') if assoc else []) - new_endpoints = old_endpoints.union(added).difference(removed) - - if old_endpoints == new_endpoints: - return - - create = [] if old_endpoints else [iface] - delete = [] if new_endpoints else [iface] - - if create: - self.manager.add( - path, Association(self.bus, path, list(new_endpoints))) - elif delete: - self.manager.remove(path) - else: - assoc.Set(iface, 'endpoints', list(new_endpoints)) - - if create != delete: - self.update_interfaces( - path, obmc.mapper.MAPPER_NAME, delete, create) - - def update_associations( - self, path, owner, old, new, created=[], destroyed=[]): - added = set(new).difference(old) - removed = set(old).difference(new) - for forward, reverse, endpoint in added: - if not endpoint: - # skip associations without an endpoint - continue - - # update the index - forward_path = str(path + '/' + forward) - reverse_path = str(endpoint + '/' + reverse) - self.index_append( - 'forward', path, owner, reverse_path) - self.index_append( - 'reverse', endpoint, owner, forward_path) - - # create the association if the endpoint exists - if not self.cache_get(endpoint): - continue - - self.update_association(forward_path, [], [endpoint]) - self.update_association(reverse_path, [], [path]) - - for forward, reverse, endpoint in removed: - # update the index - forward_path = str(path + '/' + forward) - reverse_path = str(endpoint + '/' + reverse) - self.index_remove( - 'forward', path, owner, reverse_path) - self.index_remove( - 'reverse', endpoint, owner, forward_path) - - # destroy the association if it exists - self.update_association(forward_path, [endpoint], []) - self.update_association(reverse_path, [path], []) - - # If the associations interface endpoint comes - # or goes create or destroy the appropriate - # associations - for path in created: - for forward, reverse, endpoint in \ - self.index_get_associations(path, direction='reverse'): - forward_path = str(path + '/' + forward) - reverse_path = str(endpoint + '/' + reverse) - self.update_association(forward_path, [], [endpoint]) - self.update_association(reverse_path, [], [path]) - - for path in destroyed: - for forward, reverse, endpoint in \ - self.index_get_associations(path, direction='reverse'): - forward_path = str(path + '/' + forward) - reverse_path = str(endpoint + '/' + reverse) - self.update_association(forward_path, [endpoint], []) - self.update_association(reverse_path, [path], []) - - @dbus.service.method(obmc.mapper.MAPPER_IFACE, 'sas', 'a{sa{sas}}') - def GetAncestors(self, path, interfaces): - if not self.cache_get(path): - raise MapperNotFoundException(path) - - objs = {} - - def parents(path): - yield "/" - parent = "" - for elem in (x for x in list(filter(bool, path.split('/')))[:-1]): - parent += "/" + elem - yield parent - - for parent in parents(path): - obj = self.cache_get(parent) - if not obj: - continue - objs[parent] = obj - - return self.filter_interfaces(objs.items(), interfaces) - - @dbus.service.signal(obmc.mapper.MAPPER_IFACE + '.Private', 's') - def IntrospectionComplete(self, name): - pass - - -def server_main( - path_namespaces, - service_namespaces, - interface_namespaces, - blacklists, - service_blacklists, - interface_blacklists): - dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) - bus = dbus.SystemBus() - o = ObjectMapper( - bus, - obmc.mapper.MAPPER_PATH, - path_namespaces, - service_namespaces, - interface_namespaces, - blacklists, - service_blacklists, - interface_blacklists) - loop = gobject.MainLoop() - - loop.run() diff --git a/obmc/mapper/utils.py b/obmc/mapper/utils.py deleted file mode 100644 index a7b93b2..0000000 --- a/obmc/mapper/utils.py +++ /dev/null @@ -1,130 +0,0 @@ -# Contributors Listed Below - COPYRIGHT 2016 -# [+] International Business Machines Corp. -# -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. See the License for the specific language governing -# permissions and limitations under the License. - -import sys -import dbus -import dbus.mainloop.glib -# TODO: openbmc/openbmc#2994 remove python 2 support -try: # python 2 - import gobject -except ImportError: # python 3 - from gi.repository import GObject as gobject -import obmc.mapper - - -class Wait(object): - def __init__(self, bus, waitlist, *a, **kw): - self.bus = bus - self.waitlist = dict(list(zip(waitlist, [None] * len(waitlist)))) - mapper = bus.get_object( - obmc.mapper.MAPPER_NAME, - obmc.mapper.MAPPER_PATH, - introspect=False) - self.iface = dbus.Interface( - mapper, dbus_interface=obmc.mapper.MAPPER_IFACE) - self.done = False - self.callback = kw.pop('callback', None) - self.error_callback = kw.pop('error_callback', self.default_error) - self.busy_retries = kw.pop('busy_retries', 20) - self.busy_retry_delay_milliseconds = kw.pop( - 'busy_retry_delay_milliseconds', 500) - self.waitlist_keyword = kw.pop('waitlist_keyword', None) - - self.bus.add_signal_receiver( - self.introspection_handler, - dbus_interface=obmc.mapper.MAPPER_IFACE + '.Private', - signal_name='IntrospectionComplete') - self.bus.add_signal_receiver( - self.introspection_handler, - dbus_interface=dbus.BUS_DAEMON_IFACE + '.ObjectManager') - - self.introspection_handler() - - @staticmethod - def default_error(e): - raise e - - def force_done(self): - if self.done: - return - - self.done = True - self.bus.remove_signal_receiver( - self.introspection_handler, - dbus_interface=obmc.mapper.MAPPER_IFACE + '.Private', - signal_name='IntrospectionComplete') - self.bus.remove_signal_receiver( - self.introspection_handler, - dbus_interface=dbus.BUS_DAEMON_IFACE + '.ObjectManager', - signal_name='InterfacesAdded') - - def check_done(self): - if not all(self.waitlist.values()) or self.done: - return - - self.force_done() - - if self.callback: - kwargs = {} - if self.waitlist_keyword: - kwargs[waitlist_keyword] = self.waitlist - self.callback(**kwargs) - - def get_object_async(self, path, retry): - method = getattr(self.iface, 'GetObject') - method.call_async( - path, - [], - signature='sas', - reply_handler=lambda x: self.get_object_callback( - path, x), - error_handler=lambda x: self.get_object_error( - path, retry, x)) - return False - - def get_object_error(self, path, retry, e): - if self.done: - return - - if e.get_dbus_name() == 'org.freedesktop.DBus.Error.FileNotFound': - pass - elif e.get_dbus_name() in \ - ['org.freedesktop.DBus.Error.ObjectPathInUse', - 'org.freedesktop.DBus.Error.LimitsExceeded']: - if retry > self.busy_retries: - self.force_done() - self.error_callback(e) - else: - gobject.timeout_add( - self.busy_retry_delay_milliseconds, - self.get_object_async, - path, - retry + 1) - else: - self.force_done() - self.error_callback(e) - - def get_object_callback(self, path, info): - self.waitlist[path] = list(info)[0] - self.check_done() - - def introspection_handler(self, *a, **kw): - if self.done: - return - - for path in [ - x for x in list(self.waitlist.keys()) if not self.waitlist[x]]: - self.get_object_async(path, 0) diff --git a/phosphor-mapper b/phosphor-mapper deleted file mode 100644 index 4303434..0000000 --- a/phosphor-mapper +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python - -# Contributors Listed Below - COPYRIGHT 2016 -# [+] International Business Machines Corp. -# -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. See the License for the specific language governing -# permissions and limitations under the License. - -import sys -import obmc.mapper.server -from argparse import ArgumentParser - -if __name__ == '__main__': - parser = ArgumentParser() - parser.add_argument( - '-p', '--path_namespaces', - default="") - parser.add_argument( - '-s', '--service_namespaces', - required=True) - parser.add_argument( - '-i', '--interface_namespaces', - required=True) - parser.add_argument( - '-b', '--blacklists', - default="") - parser.add_argument( - '-x', '--service_blacklists', - default="") - parser.add_argument( - '-n', '--interface_blacklists', - default="") - - args = parser.parse_args() - - sys.exit( - obmc.mapper.server.server_main( - path_namespaces=args.path_namespaces.split(), - service_namespaces=args.service_namespaces.split(), - interface_namespaces=args.interface_namespaces.split(), - blacklists=args.blacklists.split(), - service_blacklists=args.service_blacklists.split(), - interface_blacklists=args.interface_blacklists.split())) diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index dedc13f..0000000 --- a/setup.cfg +++ /dev/null @@ -1,3 +0,0 @@ -[pycodestyle] -max-line-length = 80 -ignore = E731 diff --git a/setup.py.in b/setup.py.in deleted file mode 100644 index b2f3907..0000000 --- a/setup.py.in +++ /dev/null @@ -1,7 +0,0 @@ -from distutils.core import setup -setup(name='obmc.mapper', - version='1.0', - package_dir={'':'@top_srcdir@'}, - packages=['obmc.mapper'], - scripts=['@top_srcdir@/phosphor-mapper'] - ) -- cgit v1.2.1