summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@redhat.com>2013-06-14 23:38:56 -0400
committerJan Safranek <jsafrane@redhat.com>2013-07-18 13:39:48 +0200
commit30d91d80793392adb4c5b3890555662caa0031da (patch)
treeafc3980d82b12eb646c3a6e5d05a7a55203e0d04
parentf3cee6b1ca62752134c6c3520c3739a193753768 (diff)
downloadopenlmi-providers-30d91d80793392adb4c5b3890555662caa0031da.tar.gz
openlmi-providers-30d91d80793392adb4c5b3890555662caa0031da.tar.xz
openlmi-providers-30d91d80793392adb4c5b3890555662caa0031da.zip
PCP<->CIM bridge prototype v3
- contents properly built/packaged into openlmi-pcp subrpm - a cron.daily job conditionally (rarely) rebuilds the MOF/REG files based upon current PCP state - /usr/bin/openlmi-pcp-generate able to be run by hand, cron.daily job minimal - more run-time PCP error tolerance
-rw-r--r--README7
-rw-r--r--mof/60_LMI_PCP.mof44
-rw-r--r--openlmi-providers.spec82
-rw-r--r--src/pcp/README52
-rw-r--r--src/pcp/lmi/pcp/__init__.py25
-rw-r--r--src/pcp/lmi/pcp/metric.py167
-rw-r--r--src/pcp/openlmi-pcp-generate68
-rw-r--r--src/pcp/openlmi-pcp.cron3
-rw-r--r--src/pcp/setup.py19
9 files changed, 465 insertions, 2 deletions
diff --git a/README b/README
index 1962f17..8c51e92 100644
--- a/README
+++ b/README
@@ -64,6 +64,11 @@ Following providers are part of this sub-project:
This is a CIM interface for the RealmD daemon which allows for the Kerberos
and Active Directory realms enrollment
+* PCP
+ This is a CIM interface for the PCP (Performance Co-Pilot) daemon. Allows
+ reading of PCP metrics on the local host.
+
+
*******************************************************************************
* Build Dependencies *
*******************************************************************************
@@ -90,6 +95,8 @@ Provider specific dependencies:
* RealmD
- glib2-devel
- dbus-devel
+* PCP
+ - python-pcp
*******************************************************************************
* Compilation and installation *
diff --git a/mof/60_LMI_PCP.mof b/mof/60_LMI_PCP.mof
new file mode 100644
index 0000000..8ba122b
--- /dev/null
+++ b/mof/60_LMI_PCP.mof
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * Stub MOF for the CIM<->PCP bridge. Further MOF/REG clauses that
+ * describe the PCP PMNS details may be generated periodically using
+ * pcp2cim.sh.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Frank Ch. Eigler <fche@redhat.com>
+ */
+class PCP_MetricValue : CIM_StatisticalData
+{
+ [Description("PCP metric PMID")]
+ uint32 PMID;
+
+ [Description("PMAPI indom instance number")]
+ uint32 InstanceNumber;
+
+ [Description("PMAPI indom instance name")]
+ string InstanceName;
+
+ [Description("The metric type, as returned by pmTypeStr(3)")]
+ string Type;
+
+ [Description("The metric value, as rendered into string form by pmAtomStr() or pmPrintValue(3)")]
+ string ValueString;
+
+ [Description("The metric units, as returned by pmUnitsStr(3)")]
+ string Units;
+};
+
diff --git a/openlmi-providers.spec b/openlmi-providers.spec
index 6e6d8b7..2d181bf 100644
--- a/openlmi-providers.spec
+++ b/openlmi-providers.spec
@@ -1,6 +1,6 @@
Name: openlmi-providers
Version: 0.0.25
-Release: 5%{?dist}
+Release: 6%{?dist}
Summary: Set of basic CIM providers
License: LGPLv2+
@@ -177,6 +177,21 @@ Requires: %{name}%{?_isa} = %{version}-%{release}
%description -n openlmi-indicationmanager-libs-devel
%{summary}.
+%package -n openlmi-pcp
+Summary: pywbem providers for accessing PCP metrics
+Requires: %{name} = %{version}-%{release}
+BuildArch: noarch
+Requires: python-setuptools
+Requires: cmpi-bindings-pywbem
+Requires: python-pcp
+
+%description -n openlmi-pcp
+openlmi-pcp exposes metrics from a local PMCD (Performance Co-Pilot server)
+to the CIMOM. They appear as potentially hundreds of MOF classes, e.g.
+class "PCP_Metric_kernel__pernode__cpu__use", with instances for each PCP
+metric instance, e.g. "node0". PCP metric values and metadata are transcribed
+into strings on demand.
+
%prep
%setup -q
@@ -186,7 +201,7 @@ pushd %{_target_platform}
%{cmake} ..
popd
-make %{?_smp_mflags} -C %{_target_platform}
+make -k %{?_smp_mflags} -C %{_target_platform}
pushd src/python
%{__python} setup.py build
@@ -195,6 +210,9 @@ popd # src/python
pushd src/software
%{__python} setup.py build
popd # src/software
+pushd src/pcp
+%{__python} setup.py build
+popd
%install
make install/fast DESTDIR=$RPM_BUILD_ROOT -C %{_target_platform}
@@ -217,6 +235,21 @@ install -m 755 pycmpiLMI_Software-cimprovagt $RPM_BUILD_ROOT/%{_libexecdir}/pega
popd # src/software
cp mof/LMI_Software.reg $RPM_BUILD_ROOT/%{_datadir}/%{name}/
+# pcp
+pushd src/pcp
+%{__python} setup.py install -O1 --skip-build --root $RPM_BUILD_ROOT
+popd
+cp -p src/pcp/openlmi-pcp-generate $RPM_BUILD_ROOT/%{_bindir}/openlmi-pcp-generate
+mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/cron.daily
+cp -p src/pcp/openlmi-pcp.cron $RPM_BUILD_ROOT/%{_sysconfdir}/cron.daily/openlmi-pcp
+sed -i -e 's,^_LOCALSTATEDIR=.*,_LOCALSTATEDIR="%{_localstatedir}",' \
+ -e 's,^_DATADIR=.*,_DATADIR="%{_datadir}",' \
+ -e 's,^NAME=.*,NAME="%{name}",' \
+ -e 's,^PYTHON2_SITELIB=.*,PYTHON2_SITELIB="%{python2_sitelib}",' \
+ $RPM_BUILD_ROOT/%{_bindir}/openlmi-pcp-generate \
+ $RPM_BUILD_ROOT/%{_sysconfdir}/cron.daily/openlmi-pcp
+mkdir -p $RPM_BUILD_ROOT/%{_localstatedir}/lib/%{name}
+
%files
%doc README COPYING
@@ -290,6 +323,19 @@ cp mof/LMI_Software.reg $RPM_BUILD_ROOT/%{_datadir}/%{name}/
%{_datadir}/%{name}/70_LMI_SoftwareIndicationFilters.mof
%{_datadir}/%{name}/LMI_Software.reg
+%files -n openlmi-pcp
+%doc README COPYING
+%{_datadir}/%{name}/60_LMI_PCP.mof
+%dir %{python_sitelib}/lmi/pcp
+%{python_sitelib}/lmi/pcp/*
+%{python_sitelib}/lmi_pcp-*
+%attr(755, root, root) %{_bindir}/openlmi-pcp-generate
+%attr(755, root, root) %{_sysconfdir}/cron.daily/openlmi-pcp
+%dir %{_localstatedir}/lib/%{name}
+%ghost %{_localstatedir}/lib/%{name}/60_LMI_PCP_PMNS.mof
+%ghost %{_localstatedir}/lib/%{name}/60_LMI_PCP_PMNS.reg
+%ghost %{_localstatedir}/lib/%{name}/stamp
+
%files -n openlmi-logicalfile
%doc README COPYING
%{_libdir}/cmpi/libcmpiLMI_LogicalFile.so
@@ -435,6 +481,7 @@ if [ "$1" -gt 1 ]; then
> /dev/null 2>&1 || :;
fi
+
%pre -n openlmi-hardware
if [ "$1" -gt 1 ]; then
%{_bindir}/openlmi-mof-register unregister \
@@ -443,6 +490,15 @@ if [ "$1" -gt 1 ]; then
> /dev/null 2>&1 || :;
fi
+%pre -n openlmi-pcp
+if [ "$1" -gt 1 ]; then
+ %{_bindir}/openlmi-mof-register unregister \
+ %{_datadir}/%{name}/60_LMI_PCP.mof \
+ %{_localstatedir}/lib/%{name}/60_LMI_PCP_PMNS.mof \
+ %{_localstatedir}/lib/%{name}/60_LMI_PCP_PMNS.reg \
+ > /dev/null 2>&1 || :;
+fi
+
%post -n openlmi-fan
# Register Schema and Provider
if [ "$1" -ge 1 ]; then
@@ -518,6 +574,15 @@ if [ "$1" -gt 1 ]; then
> /dev/null 2>&1 || :;
fi
+%post -n openlmi-pcp
+if [ "$1" -gt 1 ]; then
+ %{_bindir}/openlmi-mof-register register \
+ %{_datadir}/%{name}/60_LMI_PCP.mof \
+ %{_localstatedir}/lib/%{name}/60_LMI_PCP_PMNS.mof \
+ %{_localstatedir}/lib/%{name}/60_LMI_PCP_PMNS.reg \
+ > /dev/null 2>&1 || :;
+fi
+
%preun -n openlmi-fan
# Deregister only if not upgrading
if [ "$1" -eq 0 ]; then
@@ -585,6 +650,7 @@ if [ "$1" -gt 1 ]; then
> /dev/null 2>&1 || :;
fi
+
%preun -n openlmi-hardware
if [ "$1" -gt 1 ]; then
%{_bindir}/openlmi-mof-register unregister \
@@ -593,7 +659,19 @@ if [ "$1" -gt 1 ]; then
> /dev/null 2>&1 || :;
fi
+%preun -n openlmi-pcp
+if [ "$1" -gt 1 ]; then
+ %{_bindir}/openlmi-mof-register unregister \
+ %{_datadir}/%{name}/60_LMI_PCP.mof \
+ %{_localstatedir}/lib/%{name}/60_LMI_PCP_PMNS.mof \
+ %{_localstatedir}/lib/%{name}/60_LMI_PCP_PMNS.reg \
+ > /dev/null 2>&1 || :;
+fi
+
%changelog
+* Mon Jul 08 2013 Frank Ch. Eigler <fche@redhat.com> 0.0.25-6
+- Added PCP provider in optional openlmi-pcp subrpm.
+
* Mon Jul 15 2013 Jan Synáček <jsynacek@redhat.com> - 0.0.25-5
- Added libselinux-devel to BuildRequires.
diff --git a/src/pcp/README b/src/pcp/README
new file mode 100644
index 0000000..1f5e225
--- /dev/null
+++ b/src/pcp/README
@@ -0,0 +1,52 @@
+CIM <-> PCP (http://oss.sgi.com/projects/pcp) bridge
+<fche@redhat.com>
+
+The idea of the bridge is to create a suite of CIM classes (derived from
+CIM_StatisticsData), each of which represents one PCP metric. There are
+hundreds of these. (Since PCP metrics can come and go, the MOF and REG
+files may be regenerated by a simple shell script at any with an enclosed
+shell script.)
+
+Install PCP and start the pmcd service to start. We assume you're
+already running OpenLMI / Pegasus with a client like YAWN and are far
+more familiar with this WBEM business than the author. Install the
+CIM <-> PCP bridge thusly:
+
+ vi PCP_pmns2mofreg.sh # to fix the path to pcp-metric.py
+ sh PCP_pmns2mofreg.sh mof > PCP_Metric_PMNS.mof
+ sh PCP_pmns2mofreg.sh reg > PCP_Metric_PMNS.reg
+ openlmi-mof-register register *.mof *.reg
+
+For example, whereas PCP command line tools may show these sorts of results:
+
+ % pminfo -dTf hinv.machine
+
+ hinv.machine
+ Data Type: string InDom: PM_INDOM_NULL 0xffffffff
+ Semantics: discrete Units: none
+ Help:
+ machine name, IP35 if SGI SNIA, else simply linux
+ value "linux"
+
+ % pminfo -dTf network.interface.total.bytes
+ network.interface.total.bytes
+ Data Type: 64-bit unsigned int InDom: 60.3 0xf000003
+ Semantics: counter Units: byte
+ Help:
+ network total (in+out) bytes from /proc/net/dev per network interface
+ inst [0 or "eth0"] value 585236365
+ inst [1 or "lo"] value 85894766
+
+These same metrics would show up in the CIM namespace as classes
+
+ PCP_Metric_hinv__machine
+and PCP_Metric_network__interface__total__bytes
+
+with instances with InstanceIDs such as
+
+ PCP:hinv.machine
+ PCP:network.interface.total.bytes:lo
+ PCP:network.interface.total.bytes:eth0
+
+These currently supply a string-formatted value of the respective
+metric measurement, an accurate StatisticTime, and other metadata.
diff --git a/src/pcp/lmi/pcp/__init__.py b/src/pcp/lmi/pcp/__init__.py
new file mode 100644
index 0000000..81de2e5
--- /dev/null
+++ b/src/pcp/lmi/pcp/__init__.py
@@ -0,0 +1,25 @@
+# PCP bridge Providers
+#
+# Copyright (C) 2013 Red Hat, Inc. All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Authors: Frank Ch. Eigler <fche@redhat.com>
+#
+
+"""
+CIM providers for PCP metrics.
+Part of OpenLMI project.
+"""
diff --git a/src/pcp/lmi/pcp/metric.py b/src/pcp/lmi/pcp/metric.py
new file mode 100644
index 0000000..454f54a
--- /dev/null
+++ b/src/pcp/lmi/pcp/metric.py
@@ -0,0 +1,167 @@
+"""Python Provider for PCP_Metric_*
+Instruments the CIM class family PCP_Metric_*
+"""
+
+from pywbem.cim_provider2 import CIMProvider2
+import pywbem
+from pcp import pmapi
+import cpmapi as c_api
+import datetime
+
+context = None # persistent pcp context
+
+
+# Since we serve a whole slew of PCP_Metric_** subclasses, we can't
+# use a straight classname->provider-class dictionary.
+#
+#def get_providers(env):
+# return {'PCP_Metric_****': PCP_MetricProvider}
+#
+# Instead, we implement the one-hop-higher proxy-level function calls,
+# namely the IM_* functions at the bottom.
+
+
+# Undo mangling done by PCP_pmns2mofreg.sh
+def MOFname_to_PCPmetric (op):
+ assert (op.namespace == 'root/cimv2')
+ assert (op.classname[0:11] == 'PCP_Metric_')
+ return op.classname[11:].replace('__', '.')
+
+
+# Search the given PM_ResultSet for a given instance number (if any);
+# return formatted CIM of the value (or CIM None)
+def PCP_CIMValueString (context, result, desc, inst):
+ for i in range (0,result.contents.get_numval(0)):
+ value = result.contents.get_vlist(0,i)
+ iv = value.inst
+ if (inst is not None and inst != iv):
+ continue
+ atom = context.pmExtractValue (result.contents.get_valfmt(0),
+ value,
+ desc.contents.type,
+ desc.contents.type)
+ atomValue = atom.dref(desc.contents.type) # nb: atomValue could be numeric etc.
+ return pywbem.CIMProperty(name='ValueString',
+ value=str(atomValue), # stringify it here
+ type='string')
+
+ return pywbem.CIMProperty(name='ValueString',
+ value=None,
+ type='string')
+
+
+def PCP_CIMStatisticTime (result):
+ dt = datetime.datetime.fromtimestamp(float(str(result.contents.timestamp)))
+ return pywbem.CIMDateTime(dt)
+
+
+# generic payload generator, used for
+# - iterating across instance domains (keys_only=1)
+# - fetching metric values
+# - fetching metric metadata (for those model/filter fields set)
+def get_instance (env, op, model, keys_only):
+ metric = MOFname_to_PCPmetric (op)
+ global context
+
+ try:
+ if (context == None):
+ context = pmapi.pmContext() # localhost or equivalent
+ context.pmReconnectContext() # in case it was nuked recently
+ except pmapi.pmErr, e:
+ context = None
+ raise pywbem.CIMError(pywbem.CIM_ERR_FAILED, "Unable to connect to local PMCD:" + str(e))
+
+ pmids = context.pmLookupName(metric)
+ pmid = pmids[0]
+ desc = context.pmLookupDesc(pmid)
+
+ if ('InstanceID' in model):
+ selected_instanceid = model['InstanceID']
+ else:
+ selected_instanceid = None
+
+ model.path.update({'InstanceID':None})
+
+ if (not keys_only):
+ model['PMID'] = pywbem.Uint32(pmid)
+ model['ElementName'] = metric
+ # must not fail, or else we have no metric value data worth sharing
+ try:
+ results = context.pmFetch(pmids)
+ except pmapi.pmErr, e:
+ # fatal
+ raise pywbem.CIMError(pywbem.CIM_ERR_FAILED, "PCP pmFetch failed:" + str(e))
+ # cannot fail
+ model['Units'] = context.pmUnitsStr(desc.contents.units)
+ model['Type'] = context.pmTypeStr(desc.contents.type)
+ # these may fail, but not fatally
+ try:
+ model['Caption'] = context.pmLookupText(pmid)
+ except pmapi.pmErr:
+ pass
+ try:
+ model['Description'] = context.pmLookupText(pmid, c_api.PM_TEXT_HELP)
+ except pmapi.pmErr:
+ pass
+
+ try:
+ instL, nameL = context.pmGetInDom(desc)
+ for iL, nL in zip(instL, nameL):
+ new_instanceid = 'PCP:'+metric+':'+nL
+ if (selected_instanceid is None or
+ new_instanceid == selected_instanceid):
+ model['InstanceNumber'] = pywbem.Uint32(iL)
+ model['InstanceName'] = nL
+ model['InstanceID'] = new_instanceid
+ if (not keys_only):
+ model['StatisticTime'] = PCP_CIMStatisticTime (results)
+ model['ValueString'] = PCP_CIMValueString (context, results, desc, iL)
+ yield model
+ except pmapi.pmErr: # pmGetInDom is expected to fail for non-instance (PM_INDOM_NULL) metrics
+ new_instanceid = 'PCP:'+metric
+ if (selected_instanceid is None or
+ new_instanceid == selected_instanceid):
+ model['InstanceNumber'] = pywbem.CIMProperty(name='InstanceNumber',
+ value=None,type='uint32')
+ model['InstanceName'] = pywbem.CIMProperty(name='InstanceName',
+ value=None,type='string')
+ model['InstanceID'] = new_instanceid
+ if (not keys_only):
+ model['StatisticTime'] = PCP_CIMStatisticTime (results)
+ model['ValueString'] = PCP_CIMValueString (context, results, desc, None)
+ yield model
+
+# hooks for impersonating CIMProvider2 functions
+
+
+def MI_enumInstanceNames (env, op):
+ model = pywbem.CIMInstance(classname = op.classname, path=op)
+ for x in get_instance (env, op, model, True):
+ yield x.path
+
+def MI_enumInstances (env, op, plist):
+ model = pywbem.CIMInstance(classname = op.classname, path=op)
+ return get_instance (env, op, model, False)
+
+def MI_getInstance (env, op, plist):
+ proplist = None
+ if plist is not None:
+ proplist = [s.lower() for s in propertyList]
+ proplist+= [s.lower() for s in op.keybindings.keys()]
+ model = pywbem.CIMInstance(classname=op.classname, path=op,
+ property_list=proplist)
+ model.update(model.path.keybindings)
+ for x in get_instance (env, op, model, False):
+ return x # XXX: first one
+
+def MI_createInstance (env, pinst):
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
+
+def MI_modifyInstance (env, pinst, plist):
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
+
+def MI_deleteInstance (env, piname):
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
+
+# See also extra MI_* functions for associations, etc.;
+# cmpi-bindings.git swig/python/cmpi_pywbem_bindings.py
diff --git a/src/pcp/openlmi-pcp-generate b/src/pcp/openlmi-pcp-generate
new file mode 100644
index 0000000..8c53512
--- /dev/null
+++ b/src/pcp/openlmi-pcp-generate
@@ -0,0 +1,68 @@
+#! /bin/sh
+
+# This script refreshes WBEM/CIM MOF & REG files from the current PCP PMNS,
+# if necessary, and reloads the new MOF/REGs into the CIMMON.
+#
+# The PCP PMNS changes infrequently (when the sysadmin manuall installs or
+# removes pcp PMDA (agent) modules in /var/lib/pcp/pmdas/*).
+#
+# This script encodes the PCP->CIM metric name-mapping convention of replacing
+# dots with double-underscores, which lmi/pcp/metric.py will dutifully undo.
+
+_LOCALSTATEDIR=/var
+_DATADIR=/usr/share
+NAME=openlmi-providers
+PYTHON2_SITELIB=/usr/lib/python2.7/site-packages
+
+PCP_PMNS=$_LOCALSTATEDIR/lib/pcp/pmns/root
+PCP_HOST=${1-localhost} # or local:// for pcp 3.9+
+BASEMOFFILE=$_DATADIR/$NAME/60_LMI_PCP.mof
+MOFREGDIR=$_LOCALSTATEDIR/lib/$NAME
+STAMPFILE=$MOFREGDIR/stamp
+MOFFILE=$MOFREGDIR/60_LMI_PCP_PMNS.mof
+REGFILE=$MOFREGDIR/60_LMI_PCP_PMNS.reg
+PROVIDER=$PYTHON2_SITELIB/lmi/pcp/metric.py
+
+if [ ! -f $PROVIDER ]; then
+ echo "Cannot find $PROVIDER" 1>&2
+ exit 1
+fi
+
+set -e
+
+echo Refreshing PCP_Metric CIMMON classes from current PCP PMNS
+
+# quick liveness test
+pcp -h $PCP_HOST
+
+if [ -s $PCP_PMNS -a $PCP_PMNS -nt $STAMPFILE ]; then
+ if [ -f $MOFFILE -a -f $REGFILE ]; then
+ echo Unregistering $BASEMOFFILE
+ echo Unregistering previous $MOFFILE
+ echo Unregistering previous $REGFILE
+ openlmi-mof-register unregister $BASEMOFFILE $MOFFILE $REGFILE || :
+ fi
+
+ echo Generating $MOFFILE
+ pminfo -h $PCP_HOST | sed -e 's,\.,__,g' |
+ awk '{print "class PCP_Metric_" $1 " : PCP_MetricValue { } ;" }' > $MOFFILE
+
+ echo Generating $REGFILE
+ pminfo -h $PCP_HOST | sed -e 's,\.,__,g' |
+ awk '{print "[PCP_Metric_" $1 "]"
+ print " provider: '$PROVIDER'"
+ print " location: pyCmpiProvider"
+ print " type: instance"
+ print " namespace: root/cimv2"
+ print " group: pcp"
+ print ""}' > $REGFILE
+
+ echo Registering $BASEMOFFILE
+ echo Registering new $MOFFILE
+ echo Registering new $REGFILE
+ openlmi-mof-register register $BASEMOFFILE $MOFFILE $REGFILE 2>&1 | # filter out two noise diagnostics
+ egrep -v 'Warning: the instance already exists.|In this implementation, that means it cannot be changed.' || :
+ touch $STAMPFILE
+else
+ echo Doing nothing, $PCP_PMNS older than $STAMPFILE
+fi
diff --git a/src/pcp/openlmi-pcp.cron b/src/pcp/openlmi-pcp.cron
new file mode 100644
index 0000000..a9691f0
--- /dev/null
+++ b/src/pcp/openlmi-pcp.cron
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+openlmi-pcp-generate localhost >/dev/null 2>&1
diff --git a/src/pcp/setup.py b/src/pcp/setup.py
new file mode 100644
index 0000000..9ffa320
--- /dev/null
+++ b/src/pcp/setup.py
@@ -0,0 +1,19 @@
+from setuptools import setup
+setup(
+ name='lmi-pcp',
+ description='PCP metric providers',
+ author='Frank Ch. Eigler',
+ author_email='fche@redhat.com',
+ url='https://fedorahosted.org/openlmi/',
+ version='0.1',
+ namespace_packages=['lmi'],
+ packages=[
+ 'lmi.pcp'],
+ install_requires=['lmi', 'pcp'],
+ license="LGPLv2+",
+ classifiers=[
+ 'License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)',
+ 'Operating System :: POSIX :: Linux',
+ 'Topic :: System :: Systems Administration',
+ ]
+ )