mapper: Generate an environment file

Mapper will soon consume four command line arguments that
limit the scope of watched path and interface namespaces.

Add tooling to generate this environment file based on a
new bitbake variables.

Add xyz-openbmc_project and org-openbmc by default in the
Phosphor layer and other layers can add additional namespaces
as needed.

Change-Id: I1c03aa91b75d03652a8a8fb80737553fef224fdf
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/meta-openbmc-machines/meta-openpower/common/recipes-phosphor/dbus/openpower-dbus-interfaces-mapper-config-native.bb b/meta-openbmc-machines/meta-openpower/common/recipes-phosphor/dbus/openpower-dbus-interfaces-mapper-config-native.bb
new file mode 100644
index 0000000..1ef4adc
--- /dev/null
+++ b/meta-openbmc-machines/meta-openpower/common/recipes-phosphor/dbus/openpower-dbus-interfaces-mapper-config-native.bb
@@ -0,0 +1,11 @@
+SUMMARY="Add /org/open_power namespace to phosphor-mapper"
+DESCRIPTION="Add the /org/open_power path namespace and \
+org.open_power interface prefix to the mapper \
+watch list."
+
+inherit phosphor-mapper
+inherit native
+inherit obmc-phosphor-license
+
+PHOSPHOR_MAPPER_NAMESPACE_append = " /org/open_power"
+PHOSPHOR_MAPPER_INTERFACE_append = " org.open_power"
diff --git a/meta-openbmc-machines/meta-openpower/common/recipes-phosphor/dbus/phosphor-mapper-config-native%.bbappend b/meta-openbmc-machines/meta-openpower/common/recipes-phosphor/dbus/phosphor-mapper-config-native%.bbappend
new file mode 100644
index 0000000..d4a9d91
--- /dev/null
+++ b/meta-openbmc-machines/meta-openpower/common/recipes-phosphor/dbus/phosphor-mapper-config-native%.bbappend
@@ -0,0 +1 @@
+PHOSPHOR_MAPPER_CONFIGS_append = " openpower-dbus-interfaces-mapper-config-native"
diff --git a/meta-phosphor/classes/phosphor-mapper.bbclass b/meta-phosphor/classes/phosphor-mapper.bbclass
new file mode 100644
index 0000000..26f369b
--- /dev/null
+++ b/meta-phosphor/classes/phosphor-mapper.bbclass
@@ -0,0 +1,52 @@
+# Common code for recipes that modify the phosphor-mapper
+# configuration.
+#
+# Typically it is not desired to monitor all dbus traffic
+# on a system and as such, the phosphor-mapper has command
+# line options to control what path namespaces and dbus
+# interfaces it will keep track of.
+#
+# The Phosphor layer by default configures the mapper to
+# watch xyz.openbmc_project interfaces and paths only.  This
+# configuration file is intended to be inherited by
+# native recipes in other layers that wish to add namespaces
+# or interfaces to the mapper watchlist.
+
+# Add path namespaces to be monitored:
+# PHOSPHOR_MAPPER_NAMESPACE_append = " /foo/bar"
+
+# Add interfaces to be monitored:
+# PHOSPHOR_MAPPER_INTERFACE_append = " foo.bar"
+
+# Blacklist paths from being monitored:
+# PHOSPHOR_MAPPER_NAMESPACE_BLACKLIST_append = " /foo/bar/baz"
+
+# Blacklist interfaces from being monitored:
+# PHOSPHOR_MAPPER_INTERFACE_BLACKLIST_append = " foo.bar.baz"
+
+inherit phosphor-mapperdir
+
+python phosphor_mapper_do_postinst() {
+    def process_var(d, var, dir):
+        for p in listvar_to_list(d, var):
+            parent = d.getVar('D', True) + d.getVar(dir, True)
+            if not os.path.exists(parent):
+                os.makedirs(parent)
+            path = os.path.join(
+                parent,
+                '-'.join(p[1:].split(os.sep)))
+            with open(path, 'w+') as fd:
+                pass
+
+    process_var(d, 'PHOSPHOR_MAPPER_NAMESPACE', 'namespace_dir')
+    process_var(d, 'PHOSPHOR_MAPPER_INTERFACE', 'interface_dir')
+    process_var(d, 'PHOSPHOR_MAPPER_NAMESPACE_BLACKLIST', 'blacklist_dir')
+    process_var(
+        d, 'PHOSPHOR_MAPPER_INTERFACE_BLACKLIST', 'interfaceblacklist_dir')
+}
+
+do_install[vardeps] += "PHOSPHOR_MAPPER_NAMESPACE"
+do_install[vardeps] += "PHOSPHOR_MAPPER_INTERFACE"
+do_install[vardeps] += "PHOSPHOR_MAPPER_NAMESPACE_BLACKLIST"
+do_install[vardeps] += "PHOSPHOR_MAPPER_INTERFACE_BLACKLIST"
+do_install[postfuncs] += "phosphor_mapper_do_postinst"
diff --git a/meta-phosphor/classes/phosphor-mapperdir.bbclass b/meta-phosphor/classes/phosphor-mapperdir.bbclass
new file mode 100644
index 0000000..591b63d
--- /dev/null
+++ b/meta-phosphor/classes/phosphor-mapperdir.bbclass
@@ -0,0 +1,4 @@
+namespace_dir="${datadir}/phosphor-mapper/namespace"
+interface_dir="${datadir}/phosphor-mapper/interface"
+blacklist_dir="${datadir}/phosphor-mapper/blacklist"
+interfaceblacklist_dir="${datadir}/phosphor-mapper/interfaceblacklist"
diff --git a/meta-phosphor/common/recipes-phosphor/dbus/phosphor-dbus-interfaces-mapper-config-native.bb b/meta-phosphor/common/recipes-phosphor/dbus/phosphor-dbus-interfaces-mapper-config-native.bb
new file mode 100644
index 0000000..c39e0a3
--- /dev/null
+++ b/meta-phosphor/common/recipes-phosphor/dbus/phosphor-dbus-interfaces-mapper-config-native.bb
@@ -0,0 +1,11 @@
+SUMMARY="Add /xyz/openbmc_project namespace to phosphor-mapper"
+DESCRIPTION="Add the /xyz/openbmc_project path namespace and \
+xyz.openbmc_project interface prefix to the mapper \
+watch list."
+
+inherit phosphor-mapper
+inherit native
+inherit obmc-phosphor-license
+
+PHOSPHOR_MAPPER_NAMESPACE_append = " /xyz/openbmc_project"
+PHOSPHOR_MAPPER_INTERFACE_append = " xyz.openbmc_project"
diff --git a/meta-phosphor/common/recipes-phosphor/dbus/phosphor-legacy-namespace-mapper-config-native.bb b/meta-phosphor/common/recipes-phosphor/dbus/phosphor-legacy-namespace-mapper-config-native.bb
new file mode 100644
index 0000000..67199f9
--- /dev/null
+++ b/meta-phosphor/common/recipes-phosphor/dbus/phosphor-legacy-namespace-mapper-config-native.bb
@@ -0,0 +1,10 @@
+SUMMARY="Add /org/openbmc namespace to phosphor-mapper"
+DESCRIPTION="Add the legacy /org/openbmc path namespace and \
+org.openbmc nterface prefix to the mapper watch list."
+
+inherit phosphor-mapper
+inherit native
+inherit obmc-phosphor-license
+
+PHOSPHOR_MAPPER_NAMESPACE_append = " /org/openbmc"
+PHOSPHOR_MAPPER_INTERFACE_append = " org.openbmc"
diff --git a/meta-phosphor/common/recipes-phosphor/dbus/phosphor-mapper-config-native.bb b/meta-phosphor/common/recipes-phosphor/dbus/phosphor-mapper-config-native.bb
new file mode 100644
index 0000000..976c59b
--- /dev/null
+++ b/meta-phosphor/common/recipes-phosphor/dbus/phosphor-mapper-config-native.bb
@@ -0,0 +1,41 @@
+SUMMARY = "Phosphor Mapper Configuration"
+DESCRIPTION = "Meta-recipe, pulling in native recipes that wish to add \
+configuration files to the native /usr/share/phosphor-mapper filesystem."
+HOMEPAGE = "http://github.com/openbmc/phosphor-objmgr"
+PR = "r1"
+
+inherit obmc-phosphor-license
+inherit native
+inherit phosphor-mapper
+
+PHOSPHOR_MAPPER_CONFIGS = " \
+        phosphor-dbus-interfaces-mapper-config-native \
+        phosphor-legacy-namespace-mapper-config-native \
+        "
+
+DEPENDS += "${PHOSPHOR_MAPPER_CONFIGS}"
+
+# To add namespaces and blacklists to the mapper configuration,
+# create a native recipe in your layer, and add it to
+# PHOSPHOR_MAPPER_CONFIGS with a bbappend to this recipe.
+# Recipes should set one of the variables below.
+# Consult phosphor-mapper.bbclass for additional information.
+
+# Add path namespaces to be monitored.
+PHOSPHOR_MAPPER_NAMESPACE = ""
+
+# Add interfaces to be monitored.
+PHOSPHOR_MAPPER_INTERFACE = ""
+
+# Blacklist paths from being monitored.
+PHOSPHOR_MAPPER_NAMESPACE_BLACKLIST = ""
+
+# Blacklist interfaces from being monitored.
+PHOSPHOR_MAPPER_INTERFACE_BLACKLIST = ""
+
+do_install() {
+        install -d ${D}/${namespace_dir}
+        install -d ${D}/${interface_dir}
+        install -d ${D}/${blacklist_dir}
+        install -d ${D}/${interfaceblacklist_dir}
+}
diff --git a/meta-phosphor/common/recipes-phosphor/dbus/phosphor-mapper.bb b/meta-phosphor/common/recipes-phosphor/dbus/phosphor-mapper.bb
index ba9f156..c515a09 100644
--- a/meta-phosphor/common/recipes-phosphor/dbus/phosphor-mapper.bb
+++ b/meta-phosphor/common/recipes-phosphor/dbus/phosphor-mapper.bb
@@ -9,11 +9,13 @@
 inherit obmc-phosphor-python-autotools
 inherit obmc-phosphor-dbus-service
 inherit obmc-phosphor-systemd
+inherit phosphor-mapperdir
 
 DEPENDS += "systemd"
 DEPENDS += "autoconf-archive-native"
 DEPENDS += "sdbusplus"
 DEPENDS += "phosphor-logging"
+DEPENDS += "${PN}-config-native"
 
 DBUS_SERVICE_${PN} += "xyz.openbmc_project.ObjectMapper.service"
 SYSTEMD_SERVICE_${PN} += " \
@@ -22,6 +24,7 @@
         "
 RDEPENDS_libmapper += "libsystemd"
 RDEPENDS_${PN} += " \
+        python-argparse \
         python-xml \
         python-dbus \
         python-pygobject \
@@ -41,3 +44,52 @@
 }
 PACKAGES_DYNAMIC += "^libmapper.*"
 FILES_${PN}_remove = "${libdir}/lib*.so.* ${libdir}/*"
+
+# Construct a systemd environment file with mapper commandline
+# from the native sysroot /usr/share/phosphor-mapper filesystem.
+python do_emit_env() {
+    path = d.getVar('STAGING_DIR_NATIVE', True) + \
+        d.getVar('namespace_dir', True)
+    paths = []
+    for p in os.listdir(path):
+        paths.append(os.sep + os.sep.join(p.split('-')))
+
+    path = d.getVar('STAGING_DIR_NATIVE', True) + \
+        d.getVar('interface_dir', True)
+    interfaces = []
+    for i in os.listdir(path):
+        interfaces.append('.'.join(i.split('-')))
+
+    path = d.getVar('STAGING_DIR_NATIVE', True) + \
+        d.getVar('blacklist_dir', True)
+    blacklists = []
+    for b in os.listdir(path):
+        blacklists.append(os.sep + os.sep.join(b.split('-')))
+
+    path = d.getVar('STAGING_DIR_NATIVE', True) + \
+        d.getVar('interfaceblacklist_dir', True)
+    interface_blacklists = []
+    for ib in os.listdir(path):
+        interface_blacklists.append('.'.join(ib.split('-')))
+
+    path = [d.getVar('D', True) + d.getVar('envfiledir', True)]
+    path.append('obmc')
+    path.append('mapper')
+    parent = os.path.join(*path[:-1])
+    path = os.path.join(*path)
+
+    if not os.path.exists(parent):
+        os.makedirs(parent)
+    with open(path, 'w+') as fd:
+        fd.write('MAPPER_NAMESPACES="{}"'.format(' '.join(paths)))
+        fd.write('\n')
+        fd.write('MAPPER_INTERFACES="{}"'.format(' '.join(interfaces)))
+        fd.write('\n')
+        fd.write('MAPPER_BLACKLISTS="{}"'.format(' '.join(blacklists)))
+        fd.write('\n')
+        fd.write('MAPPER_INTERFACEBLACKLISTS="{}"'.format(' '.join(interface_blacklists)))
+        fd.write('\n')
+}
+
+do_install[postfuncs] += "do_emit_env"
+do_install[vardeps] += "PHOSPHOR_MAPPER_NAMESPACES"
diff --git a/meta-phosphor/common/recipes-phosphor/dbus/phosphor-mapper/xyz.openbmc_project.ObjectMapper.service b/meta-phosphor/common/recipes-phosphor/dbus/phosphor-mapper/xyz.openbmc_project.ObjectMapper.service
index 5d86fcf..a9a7984 100644
--- a/meta-phosphor/common/recipes-phosphor/dbus/phosphor-mapper/xyz.openbmc_project.ObjectMapper.service
+++ b/meta-phosphor/common/recipes-phosphor/dbus/phosphor-mapper/xyz.openbmc_project.ObjectMapper.service
@@ -5,9 +5,14 @@
 [Service]
 Restart=always
 Type=dbus
-ExecStart={sbindir}/phosphor-mapper
+ExecStart={sbindir}/phosphor-mapper \
+        --path_namespaces="${{MAPPER_NAMESPACES}}" \
+        --interface_namespaces="${{MAPPER_INTERFACES}}"
+        --blacklists="${{MAPPER_BLACKLISTS}}" \
+        --interface_blacklists="${{MAPPER_INTERFACEBLACKLISTS}}"
 BusName={BUSNAME}
 TimeoutStartSec=300
+EnvironmentFile={envfiledir}/obmc/mapper
 Environment="PYTHONUNBUFFERED=1"
 
 [Install]