summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am22
-rw-r--r--configure.ac7
-rw-r--r--obmc/mapper/__init__.py6
-rw-r--r--obmc/mapper/bindings.py207
-rw-r--r--obmc/mapper/server.py803
-rw-r--r--obmc/mapper/utils.py130
-rw-r--r--phosphor-mapper53
-rw-r--r--setup.cfg3
-rw-r--r--setup.py.in7
9 files changed, 1 insertions, 1237 deletions
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']
- )
OpenPOWER on IntegriCloud