summaryrefslogtreecommitdiffstats
path: root/src/software/openlmi
diff options
context:
space:
mode:
Diffstat (limited to 'src/software/openlmi')
-rw-r--r--src/software/openlmi/software/LMI_HostedSoftwareCollection.py (renamed from src/software/openlmi/software/LMI_SoftwarePackageChecks.py)221
-rw-r--r--src/software/openlmi/software/LMI_MemberOfSoftwareCollection.py279
-rw-r--r--src/software/openlmi/software/LMI_SoftwareFileCheck.py247
-rw-r--r--src/software/openlmi/software/LMI_SoftwareIdentity.py190
-rw-r--r--src/software/openlmi/software/LMI_SoftwareInstalledPackage.py451
-rw-r--r--src/software/openlmi/software/LMI_SoftwarePackage.py258
-rw-r--r--src/software/openlmi/software/LMI_SystemSoftwareCollection.py174
-rw-r--r--src/software/openlmi/software/__init__.py5
-rw-r--r--src/software/openlmi/software/cimom_entry.py28
-rw-r--r--src/software/openlmi/software/core/ComputerSystem.py5
-rw-r--r--src/software/openlmi/software/core/SoftwareFileCheck.py515
-rw-r--r--src/software/openlmi/software/core/SoftwareIdentity.py278
-rw-r--r--src/software/openlmi/software/core/SoftwareInstalledPackage.py39
-rw-r--r--src/software/openlmi/software/core/SoftwarePackage.py412
-rw-r--r--src/software/openlmi/software/core/SoftwarePackageChecks.py32
-rw-r--r--src/software/openlmi/software/core/SystemSoftwareCollection.py63
-rw-r--r--src/software/openlmi/software/core/__init__.py6
-rw-r--r--src/software/openlmi/software/util/singletonmixin.py562
-rw-r--r--src/software/openlmi/software/yumdb/__init__.py8
-rw-r--r--src/software/openlmi/software/yumdb/jobs.py16
-rw-r--r--src/software/openlmi/software/yumdb/process.py22
21 files changed, 1457 insertions, 2354 deletions
diff --git a/src/software/openlmi/software/LMI_SoftwarePackageChecks.py b/src/software/openlmi/software/LMI_HostedSoftwareCollection.py
index 48faabc..ad8b6bf 100644
--- a/src/software/openlmi/software/LMI_SoftwarePackageChecks.py
+++ b/src/software/openlmi/software/LMI_HostedSoftwareCollection.py
@@ -2,26 +2,22 @@
#
# Copyright (C) 2012 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 program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
#
-# This library is distributed in the hope that it will be useful,
+# This program 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: Michal Minar <miminar@redhat.com>
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
-"""Python Provider for LMI_SoftwarePackageChecks
+"""Python Provider for LMI_HostedSoftwareCollection
-Instruments the CIM class LMI_SoftwarePackageChecks
+Instruments the CIM class LMI_HostedSoftwareCollection
"""
@@ -29,18 +25,16 @@ import pywbem
from pywbem.cim_provider2 import CIMProvider2
from openlmi.common import cmpi_logging
-from openlmi.software.core import (SoftwarePackage, SoftwareFileCheck)
-from openlmi.software.yumdb import YumDB
+from openlmi.software.core import ComputerSystem, SystemSoftwareCollection
-class LMI_SoftwarePackageChecks(CIMProvider2):
- """Instrument the CIM class LMI_SoftwarePackageChecks
-
- This association ties a SoftwareElement to a specific Check to validate
- its state or its movement to the next state. Note that
- SoftwareElements in a running state cannot transition to another
- state. Therefore, the value of the Phase property is restricted to 0
- ("In-State") for SoftwareElements in the running state.
+class LMI_HostedSoftwareCollection(CIMProvider2):
+ """Instrument the CIM class LMI_HostedSoftwareCollection
+ HostedSoftwareCollection defines a SystemSpecificCollection in the context of a
+ scoping System. It represents a Collection that has meaning only in
+ the context of a System, a Collection whose elements are restricted by
+ the definition of the System, or both of these types of Collections.
+
"""
def __init__ (self, _env):
@@ -53,35 +47,35 @@ class LMI_SoftwarePackageChecks(CIMProvider2):
Keyword arguments:
env -- Provider Environment (pycimmb.ProviderEnvironment)
- model -- A template of the pywbem.CIMInstance to be returned. The
- key properties are set on this instance to correspond to the
+ model -- A template of the pywbem.CIMInstance to be returned. The
+ key properties are set on this instance to correspond to the
instanceName that was requested. The properties of the model
- are already filtered according to the PropertyList from the
+ are already filtered according to the PropertyList from the
request. Only properties present in the model need to be
- given values. If you prefer, you can set all of the
- values, and the instance will be filtered for you.
+ given values. If you prefer, you can set all of the
+ values, and the instance will be filtered for you.
Possible Errors:
CIM_ERR_ACCESS_DENIED
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
or otherwise incorrect parameters)
- CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
+ CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
Instance does not exist in the specified namespace)
CIM_ERR_FAILED (some other unspecified error occurred)
"""
- if not "Check" in model:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Missing Check property.")
- if not "Element" in model:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Missing Element property.")
-
- pkg_info, pkg_check, pkg_file = \
- SoftwareFileCheck.object_path2pkg_file(model['Check'])
- model['Check'] = SoftwareFileCheck.filecheck2model(
- pkg_info, pkg_check, pkg_file.path)
- model['Element'] = SoftwarePackage.pkg2model(pkg_info)
+ for key_prop in ("Antecedent", "Dependent"):
+ if not key_prop in model:
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
+ "Missing Antecedent key property!")
+ ComputerSystem.check_path_property(env, model, "Antecedent")
+ SystemSoftwareCollection.check_path_property(env, model, "Dependent")
+
+ model.path.update({"Antecedent":None, "Dependent":None})
+
+ model["Antecedent"] = ComputerSystem.get_path()
+ model["Dependent"] = SystemSoftwareCollection.get_path()
+
return model
@cmpi_logging.trace_method
@@ -89,17 +83,17 @@ class LMI_SoftwarePackageChecks(CIMProvider2):
"""Enumerate instances.
The WBEM operations EnumerateInstances and EnumerateInstanceNames
- are both mapped to this method.
+ are both mapped to this method.
This method is a python generator
Keyword arguments:
env -- Provider Environment (pycimmb.ProviderEnvironment)
- model -- A template of the pywbem.CIMInstances to be generated.
- The properties of the model are already filtered according to
- the PropertyList from the request. Only properties present in
- the model need to be given values. If you prefer, you can
- always set all of the values, and the instance will be filtered
- for you.
+ model -- A template of the pywbem.CIMInstances to be generated.
+ The properties of the model are already filtered according to
+ the PropertyList from the request. Only properties present in
+ the model need to be given values. If you prefer, you can
+ always set all of the values, and the instance will be filtered
+ for you.
keys_only -- A boolean. True if only the key properties should be
set on the generated instances.
@@ -107,8 +101,16 @@ class LMI_SoftwarePackageChecks(CIMProvider2):
CIM_ERR_FAILED (some other unspecified error occurred)
"""
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED,
- "Enumeration of instances is not supported.")
+ # Prime model.path with knowledge of the keys, so key values on
+ # the CIMInstanceName (model.path) will automatically be set when
+ # we set property values on the model.
+ model.path.update({'Dependent': None, 'Antecedent': None})
+
+ model["Antecedent"] = ComputerSystem.get_path()
+ model["Dependent"] = SystemSoftwareCollection.get_path()
+
+ yield model
+
@cmpi_logging.trace_method
def set_instance(self, env, instance, modify_existing):
@@ -116,22 +118,22 @@ class LMI_SoftwarePackageChecks(CIMProvider2):
Keyword arguments:
env -- Provider Environment (pycimmb.ProviderEnvironment)
- instance -- The new pywbem.CIMInstance. If modifying an existing
- instance, the properties on this instance have been filtered by
+ instance -- The new pywbem.CIMInstance. If modifying an existing
+ instance, the properties on this instance have been filtered by
the PropertyList from the request.
modify_existing -- True if ModifyInstance, False if CreateInstance
- Return the new instance. The keys must be set on the new instance.
+ Return the new instance. The keys must be set on the new instance.
Possible Errors:
CIM_ERR_ACCESS_DENIED
CIM_ERR_NOT_SUPPORTED
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
or otherwise incorrect parameters)
- CIM_ERR_ALREADY_EXISTS (the CIM Instance already exists -- only
+ CIM_ERR_ALREADY_EXISTS (the CIM Instance already exists -- only
valid if modify_existing is False, indicating that the operation
was CreateInstance)
- CIM_ERR_NOT_FOUND (the CIM Instance does not exist -- only valid
+ CIM_ERR_NOT_FOUND (the CIM Instance does not exist -- only valid
if modify_existing is True, indicating that the operation
was ModifyInstance)
CIM_ERR_FAILED (some other unspecified error occurred)
@@ -145,61 +147,61 @@ class LMI_SoftwarePackageChecks(CIMProvider2):
Keyword arguments:
env -- Provider Environment (pycimmb.ProviderEnvironment)
- instance_name -- A pywbem.CIMInstanceName specifying the instance
+ instance_name -- A pywbem.CIMInstanceName specifying the instance
to delete.
Possible Errors:
CIM_ERR_ACCESS_DENIED
CIM_ERR_NOT_SUPPORTED
CIM_ERR_INVALID_NAMESPACE
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
or otherwise incorrect parameters)
- CIM_ERR_INVALID_CLASS (the CIM Class does not exist in the specified
+ CIM_ERR_INVALID_CLASS (the CIM Class does not exist in the specified
namespace)
- CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
+ CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
Instance does not exist in the specified namespace)
CIM_ERR_FAILED (some other unspecified error occurred)
- """
+ """
raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
-
+
@cmpi_logging.trace_method
def references(self, env, object_name, model, result_class_name, role,
result_role, keys_only):
"""Instrument Associations.
- All four association-related operations (Associators, AssociatorNames,
- References, ReferenceNames) are mapped to this method.
+ All four association-related operations (Associators, AssociatorNames,
+ References, ReferenceNames) are mapped to this method.
This method is a python generator
Keyword arguments:
env -- Provider Environment (pycimmb.ProviderEnvironment)
- object_name -- A pywbem.CIMInstanceName that defines the source
+ object_name -- A pywbem.CIMInstanceName that defines the source
CIM Object whose associated Objects are to be returned.
model -- A template pywbem.CIMInstance to serve as a model
of the objects to be returned. Only properties present on this
- model need to be set.
- result_class_name -- If not empty, this string acts as a filter on
- the returned set of Instances by mandating that each returned
- Instances MUST represent an association between object_name
+ model need to be set.
+ result_class_name -- If not empty, this string acts as a filter on
+ the returned set of Instances by mandating that each returned
+ Instances MUST represent an association between object_name
and an Instance of a Class whose name matches this parameter
- or a subclass.
- role -- If not empty, MUST be a valid Property name. It acts as a
- filter on the returned set of Instances by mandating that each
- returned Instance MUST refer to object_name via a Property
+ or a subclass.
+ role -- If not empty, MUST be a valid Property name. It acts as a
+ filter on the returned set of Instances by mandating that each
+ returned Instance MUST refer to object_name via a Property
whose name matches the value of this parameter.
- result_role -- If not empty, MUST be a valid Property name. It acts
- as a filter on the returned set of Instances by mandating that
- each returned Instance MUST represent associations of
- object_name to other Instances, where the other Instances play
- the specified result_role in the association (i.e. the
- name of the Property in the Association Class that refers to
- the Object related to object_name MUST match the value of this
+ result_role -- If not empty, MUST be a valid Property name. It acts
+ as a filter on the returned set of Instances by mandating that
+ each returned Instance MUST represent associations of
+ object_name to other Instances, where the other Instances play
+ the specified result_role in the association (i.e. the
+ name of the Property in the Association Class that refers to
+ the Object related to object_name MUST match the value of this
parameter).
keys_only -- A boolean. True if only the key properties should be
set on the generated instances.
- The following diagram may be helpful in understanding the role,
+ The following diagram may be helpful in understanding the role,
result_role, and result_class_name parameters.
+------------------------+ +-------------------+
| object_name.classname | | result_class_name |
@@ -217,47 +219,20 @@ class LMI_SoftwarePackageChecks(CIMProvider2):
CIM_ERR_ACCESS_DENIED
CIM_ERR_NOT_SUPPORTED
CIM_ERR_INVALID_NAMESPACE
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
or otherwise incorrect parameters)
CIM_ERR_FAILED (some other unspecified error occurred)
"""
- cimhandle = env.get_cimom_handle()
-
- # Prime model.path with knowledge of the keys, so key values on
- # the CIMInstanceName (model.path) will automatically be set when
- # we set property values on the model.
- model.path.update({'Check': None, 'Element': None})
-
- with YumDB.getInstance() as ydb:
- if ( (not role or role.lower() == 'element')
- and cimhandle.is_subclass(object_name.namespace,
- sub=object_name.classname,
- super='LMI_SoftwarePackage')):
- filecheck_model = pywbem.CIMInstanceName(
- classname='LMI_SoftwareFileCheck',
- namespace="root/cimv2",
- host=model.path.host)
- pkg_info = SoftwarePackage.object_path2pkg(object_name,
- kind="installed")
- model['Element'] = SoftwarePackage.pkg2model(pkg_info)
-
- pkg_check = ydb.check_package(pkg_info)
- for file_name in pkg_check:
- model['Check'] = SoftwareFileCheck.filecheck2model(
- pkg_info, pkg_check, file_name,
- model=filecheck_model)
- yield model
-
- if ( (not role or role.lower() == 'check')
- and cimhandle.is_subclass(object_name.namespace,
- sub=object_name.classname,
- super='LMI_SoftwareFileCheck')):
- pkg_info, pkg_check, pkg_file = \
- SoftwareFileCheck.object_path2pkg_file(object_name)
- model['Check'] = SoftwareFileCheck.filecheck2model(
- pkg_info, pkg_check, pkg_file.path)
-
- model['Element'] = SoftwarePackage.pkg2model(pkg_info)
- yield model
+ ch = env.get_cimom_handle()
+ # If you want to get references for free, implemented in terms
+ # of enum_instances, just leave the code below unaltered.
+ if ch.is_subclass(object_name.namespace,
+ sub=object_name.classname,
+ super='CIM_SystemSpecificCollection') or \
+ ch.is_subclass(object_name.namespace,
+ sub=object_name.classname,
+ super='CIM_System'):
+ return self.simple_refs(env, object_name, model,
+ result_class_name, role, result_role, keys_only)
diff --git a/src/software/openlmi/software/LMI_MemberOfSoftwareCollection.py b/src/software/openlmi/software/LMI_MemberOfSoftwareCollection.py
new file mode 100644
index 0000000..ae79bf7
--- /dev/null
+++ b/src/software/openlmi/software/LMI_MemberOfSoftwareCollection.py
@@ -0,0 +1,279 @@
+# Software Management Providers
+#
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""Python Provider for LMI_MemberOfSoftwareCollection
+
+Instruments the CIM class LMI_MemberOfSoftwareCollection
+
+"""
+
+import pywbem
+from pywbem.cim_provider2 import CIMProvider2
+
+from openlmi.common import cmpi_logging
+from openlmi.software.core import SystemSoftwareCollection
+from openlmi.software.core import SoftwareIdentity
+from openlmi.software.yumdb import YumDB
+
+class LMI_MemberOfSoftwareCollection(CIMProvider2):
+ """Instrument the CIM class LMI_MemberOfSoftwareCollection
+
+ LMI_MemberOfSoftwareCollection is an aggregation used to establish membership
+ of ManagedElements in a Collection.
+
+ """
+
+ def __init__(self, _env):
+ cmpi_logging.logger.debug('Initializing provider %s from %s' \
+ % (self.__class__.__name__, __file__))
+
+ @cmpi_logging.trace_method
+ def get_instance(self, env, model):
+ """Return an instance.
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ model -- A template of the pywbem.CIMInstance to be returned. The
+ key properties are set on this instance to correspond to the
+ instanceName that was requested. The properties of the model
+ are already filtered according to the PropertyList from the
+ request. Only properties present in the model need to be
+ given values. If you prefer, you can set all of the
+ values, and the instance will be filtered for you.
+
+ Possible Errors:
+ CIM_ERR_ACCESS_DENIED
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ or otherwise incorrect parameters)
+ CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
+ Instance does not exist in the specified namespace)
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+ SystemSoftwareCollection.check_path_property(env, model, "Collection")
+
+ if not 'Member' in model:
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
+ 'Missing "Member" key property!')
+ if not isinstance(model['Member'], pywbem.CIMInstanceName):
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
+ "Expected object path for Member!")
+
+ model['Collection'] = SystemSoftwareCollection.get_path()
+ with YumDB.get_instance():
+ pkg_info = SoftwareIdentity.object_path2pkg(
+ model['Member'], 'available')
+ model['Member'] = SoftwareIdentity.pkg2model(pkg_info)
+ return model
+
+ @cmpi_logging.trace_method
+ def enum_instances(self, env, model, keys_only):
+ """Enumerate instances.
+
+ The WBEM operations EnumerateInstances and EnumerateInstanceNames
+ are both mapped to this method.
+ This method is a python generator
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ model -- A template of the pywbem.CIMInstances to be generated.
+ The properties of the model are already filtered according to
+ the PropertyList from the request. Only properties present in
+ the model need to be given values. If you prefer, you can
+ always set all of the values, and the instance will be filtered
+ for you.
+ keys_only -- A boolean. True if only the key properties should be
+ set on the generated instances.
+
+ Possible Errors:
+ CIM_ERR_FAILED (some other unspecified error occurred)
+ """
+ # Prime model.path with knowledge of the keys, so key values on
+ # the CIMInstanceName (model.path) will automatically be set when
+ # we set property values on the model.
+ model.path.update({'Member': None, 'Collection': None})
+
+ model['Collection'] = SystemSoftwareCollection.get_path()
+ member_model = pywbem.CIMInstanceName(
+ classname="LMI_SoftwareIdentity",
+ namespace="root/cimv2")
+ with YumDB.get_instance() as yb:
+ pl = yb.get_package_list('available',
+ allow_duplicates=True,
+ sort=True)
+ for pkg in pl:
+ model['Member'] = SoftwareIdentity.pkg2model(
+ pkg, model=member_model)
+ yield model
+
+ @cmpi_logging.trace_method
+ def set_instance(self, env, instance, modify_existing):
+ """Return a newly created or modified instance.
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ instance -- The new pywbem.CIMInstance. If modifying an existing
+ instance, the properties on this instance have been filtered by
+ the PropertyList from the request.
+ modify_existing -- True if ModifyInstance, False if CreateInstance
+
+ Return the new instance. The keys must be set on the new instance.
+
+ Possible Errors:
+ CIM_ERR_ACCESS_DENIED
+ CIM_ERR_NOT_SUPPORTED
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ or otherwise incorrect parameters)
+ CIM_ERR_ALREADY_EXISTS (the CIM Instance already exists -- only
+ valid if modify_existing is False, indicating that the operation
+ was CreateInstance)
+ CIM_ERR_NOT_FOUND (the CIM Instance does not exist -- only valid
+ if modify_existing is True, indicating that the operation
+ was ModifyInstance)
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
+
+ @cmpi_logging.trace_method
+ def delete_instance(self, env, instance_name):
+ """Delete an instance.
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ instance_name -- A pywbem.CIMInstanceName specifying the instance
+ to delete.
+
+ Possible Errors:
+ CIM_ERR_ACCESS_DENIED
+ CIM_ERR_NOT_SUPPORTED
+ CIM_ERR_INVALID_NAMESPACE
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ or otherwise incorrect parameters)
+ CIM_ERR_INVALID_CLASS (the CIM Class does not exist in the specified
+ namespace)
+ CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
+ Instance does not exist in the specified namespace)
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
+
+ @cmpi_logging.trace_method
+ def references(self, env, object_name, model, result_class_name, role,
+ result_role, keys_only):
+ """Instrument Associations.
+
+ All four association-related operations (Associators, AssociatorNames,
+ References, ReferenceNames) are mapped to this method.
+ This method is a python generator
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ object_name -- A pywbem.CIMInstanceName that defines the source
+ CIM Object whose associated Objects are to be returned.
+ model -- A template pywbem.CIMInstance to serve as a model
+ of the objects to be returned. Only properties present on this
+ model need to be set.
+ result_class_name -- If not empty, this string acts as a filter on
+ the returned set of Instances by mandating that each returned
+ Instances MUST represent an association between object_name
+ and an Instance of a Class whose name matches this parameter
+ or a subclass.
+ role -- If not empty, MUST be a valid Property name. It acts as a
+ filter on the returned set of Instances by mandating that each
+ returned Instance MUST refer to object_name via a Property
+ whose name matches the value of this parameter.
+ result_role -- If not empty, MUST be a valid Property name. It acts
+ as a filter on the returned set of Instances by mandating that
+ each returned Instance MUST represent associations of
+ object_name to other Instances, where the other Instances play
+ the specified result_role in the association (i.e. the
+ name of the Property in the Association Class that refers to
+ the Object related to object_name MUST match the value of this
+ parameter).
+ keys_only -- A boolean. True if only the key properties should be
+ set on the generated instances.
+
+ The following diagram may be helpful in understanding the role,
+ result_role, and result_class_name parameters.
+ +------------------------+ +-------------------+
+ | object_name.classname | | result_class_name |
+ | ~~~~~~~~~~~~~~~~~~~~~ | | ~~~~~~~~~~~~~~~~~ |
+ +------------------------+ +-------------------+
+ | +-----------------------------------+ |
+ | | [Association] model.classname | |
+ | object_name | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
+ +--------------+ object_name.classname REF role | |
+ (CIMInstanceName) | result_class_name REF result_role +------+
+ | |(CIMInstanceName)
+ +-----------------------------------+
+
+ Possible Errors:
+ CIM_ERR_ACCESS_DENIED
+ CIM_ERR_NOT_SUPPORTED
+ CIM_ERR_INVALID_NAMESPACE
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ or otherwise incorrect parameters)
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+ cimhandle = env.get_cimom_handle()
+
+ model.path.update({'Collection': None, 'Member': None})
+
+ with YumDB.get_instance() as ydb:
+ if ( (not role or role.lower() == 'collection')
+ and cimhandle.is_subclass(object_name.namespace,
+ sub=object_name.classname,
+ super='LMI_SystemSoftwareCollection')
+ and "InstanceID" in object_name):
+ if object_name["InstanceID"] == \
+ SystemSoftwareCollection.get_path()["InstanceID"]:
+ pkg_model = pywbem.CIMInstanceName(
+ classname='LMI_SoftwareIdentity',
+ namespace="root/cimv2",
+ host=model.path.host)
+ model["Collection"] = SystemSoftwareCollection.get_path()
+ for pkg_info in ydb.get_package_list('available',
+ allow_duplicates=True, sort=True):
+ model["Member"] = SoftwareIdentity.pkg2model(
+ pkg_info, model=pkg_model)
+ yield model
+
+ if ( (not role or role.lower() == 'member')
+ and cimhandle.is_subclass(object_name.namespace,
+ sub=object_name.classname,
+ super='LMI_SoftwareIdentity')):
+ try:
+ pkg_info = SoftwareIdentity.object_path2pkg(
+ object_name, kind="available")
+ model['Member'] = SoftwareIdentity.pkg2model(pkg_info)
+ model["Collection"] = SystemSoftwareCollection.get_path()
+ except pywbem.CIMError as exc:
+ if exc.args[0] == pywbem.CIM_ERR_NOT_FOUND:
+ msg = "Could not find requested package%s."
+ if "InstanceID" in object_name:
+ msg = msg % (' with InstanceID="%s"' % \
+ object_name["InstanceID"])
+ else:
+ msg = msg % ""
+ raise pywbem.CIMError(pywbem.CIM_ERR_FAILED, msg)
+ else:
+ raise
+ yield model
+
diff --git a/src/software/openlmi/software/LMI_SoftwareFileCheck.py b/src/software/openlmi/software/LMI_SoftwareFileCheck.py
deleted file mode 100644
index 58470bb..0000000
--- a/src/software/openlmi/software/LMI_SoftwareFileCheck.py
+++ /dev/null
@@ -1,247 +0,0 @@
-# Software Management Providers
-#
-# Copyright (C) 2012 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: Michal Minar <miminar@redhat.com>
-#
-
-"""Python Provider for LMI_SoftwareFileCheck
-
-Instruments the CIM class LMI_SoftwareFileCheck
-
-"""
-
-import pywbem
-from pywbem.cim_provider2 import CIMProvider2
-
-from openlmi.common import cmpi_logging
-from openlmi.software.core import SoftwareFileCheck
-from openlmi.software.yumdb import YumDB
-
-class LMI_SoftwareFileCheck(CIMProvider2):
- """Instrument the CIM class LMI_SoftwareFileCheck
-
- Identifies a file contained by RPM package. It's located in directory
- identified in FileName. The Invoke methods check for file existence
- and whether its attributes match those given by RPM package.
-
- """
-
- def __init__(self, _env):
- cmpi_logging.logger.debug('Initializing provider %s from %s' \
- % (self.__class__.__name__, __file__))
-
- @cmpi_logging.trace_method
- def get_instance(self, env, model):
- """Return an instance.
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- model -- A template of the pywbem.CIMInstance to be returned. The
- key properties are set on this instance to correspond to the
- instanceName that was requested. The properties of the model
- are already filtered according to the PropertyList from the
- request. Only properties present in the model need to be
- given values. If you prefer, you can set all of the
- values, and the instance will be filtered for you.
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
- or otherwise incorrect parameters)
- CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
- Instance does not exist in the specified namespace)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- with YumDB.getInstance():
- pkg_info, pkg_check, pkg_file = \
- SoftwareFileCheck.object_path2pkg_file(model.path)
- return SoftwareFileCheck.filecheck2model(
- pkg_info, pkg_check, pkg_file.path, keys_only=False)
-
- @cmpi_logging.trace_method
- def enum_instances(self, env, model, keys_only):
- """Enumerate instances.
-
- The WBEM operations EnumerateInstances and EnumerateInstanceNames
- are both mapped to this method.
- This method is a python generator
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- model -- A template of the pywbem.CIMInstances to be generated.
- The properties of the model are already filtered according to
- the PropertyList from the request. Only properties present in
- the model need to be given values. If you prefer, you can
- always set all of the values, and the instance will be filtered
- for you.
- keys_only -- A boolean. True if only the key properties should be
- set on the generated instances.
-
- Possible Errors:
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- # this won't be supported because of enormous amount of data
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
-
- @cmpi_logging.trace_method
- def set_instance(self, env, instance, modify_existing):
- """Return a newly created or modified instance.
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- instance -- The new pywbem.CIMInstance. If modifying an existing
- instance, the properties on this instance have been filtered by
- the PropertyList from the request.
- modify_existing -- True if ModifyInstance, False if CreateInstance
-
- Return the new instance. The keys must be set on the new instance.
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_NOT_SUPPORTED
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
- or otherwise incorrect parameters)
- CIM_ERR_ALREADY_EXISTS (the CIM Instance already exists -- only
- valid if modify_existing is False, indicating that the operation
- was CreateInstance)
- CIM_ERR_NOT_FOUND (the CIM Instance does not exist -- only valid
- if modify_existing is True, indicating that the operation
- was ModifyInstance)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
-
- @cmpi_logging.trace_method
- def delete_instance(self, env, instance_name):
- """Delete an instance.
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- instance_name -- A pywbem.CIMInstanceName specifying the instance
- to delete.
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_NOT_SUPPORTED
- CIM_ERR_INVALID_NAMESPACE
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
- or otherwise incorrect parameters)
- CIM_ERR_INVALID_CLASS (the CIM Class does not exist in the specified
- namespace)
- CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
- Instance does not exist in the specified namespace)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
-
- @cmpi_logging.trace_method
- def cim_method_invoke(self, env, object_name):
- """Implements LMI_SoftwareFileCheck.Invoke()
-
- The Invoke method evaluates this Check. The details of the
- evaluation are described by the specific subclasses of CIM_Check.
- When the SoftwareElement being checked is already installed, the
- CIM_InstalledSoftwareElement association identifies the
- CIM_ComputerSystem in whose context the Invoke is executed. If
- this association is not in place, then the InvokeOnSystem method
- should be used - since it identifies the TargetSystem as an input
- parameter of the method. \nThe results of the Invoke method are
- based on the return value. A zero is returned if the condition is
- satisfied. A one is returned if the method is not supported. Any
- other value indicates the condition is not satisfied.
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- object_name -- A pywbem.CIMInstanceName or pywbem.CIMCLassName
- specifying the object on which the method Invoke()
- should be invoked.
-
- Returns a two-tuple containing the return value (type pywbem.Uint32)
- and a list of CIMParameter objects representing the output parameters
-
- Output parameters: none
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate,
- unrecognized or otherwise incorrect parameters)
- CIM_ERR_NOT_FOUND (the target CIM Class or instance does not
- exist in the specified namespace)
- CIM_ERR_METHOD_NOT_AVAILABLE (the CIM Server is unable to honor
- the invocation request)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- with YumDB.getInstance():
- _, pkg_check, pkg_file = \
- SoftwareFileCheck.object_path2pkg_file(object_name)
- sfc = SoftwareFileCheck.test_file(
- pkg_check.file_checksum_type, pkg_file)
- out_params = []
- ret = 0 if SoftwareFileCheck.filecheck_passed(sfc) else 2
- return (pywbem.Uint32(ret), out_params)
-
- @cmpi_logging.trace_method
- def cim_method_invokeonsystem(self, env, object_name,
- param_targetsystem=None):
- """Implements LMI_SoftwareFileCheck.InvokeOnSystem()
-
- The InvokeOnSystem method evaluates this Check. The details of the
- evaluation are described by the specific subclasses of CIM_Check.
- The method\'s TargetSystem input parameter specifies the
- ComputerSystem in whose context the method is invoked. \nThe
- results of the InvokeOnSystem method are based on the return
- value. A zero is returned if the condition is satisfied. A one is
- returned if the method is not supported. Any other value indicates
- the condition is not satisfied.
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- object_name -- A pywbem.CIMInstanceName or pywbem.CIMCLassName
- specifying the object on which the method InvokeOnSystem()
- should be invoked.
- param_targetsystem -- The input parameter TargetSystem (
- type REF (pywbem.CIMInstanceName(
- classname='CIM_ComputerSystem', ...))
- Reference to ComputerSystem in whose context the method is to
- be invoked.
-
-
- Returns a two-tuple containing the return value (type pywbem.Uint32)
- and a list of CIMParameter objects representing the output parameters
-
- Output parameters: none
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate,
- unrecognized or otherwise incorrect parameters)
- CIM_ERR_NOT_FOUND (the target CIM Class or instance does not
- exist in the specified namespace)
- CIM_ERR_METHOD_NOT_AVAILABLE (the CIM Server is unable to honor
- the invocation request)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- # TODO do something
- raise pywbem.CIMError(pywbem.CIM_ERR_METHOD_NOT_AVAILABLE)
-
diff --git a/src/software/openlmi/software/LMI_SoftwareIdentity.py b/src/software/openlmi/software/LMI_SoftwareIdentity.py
new file mode 100644
index 0000000..b97ca25
--- /dev/null
+++ b/src/software/openlmi/software/LMI_SoftwareIdentity.py
@@ -0,0 +1,190 @@
+# -*- encoding: utf-8 -*-
+# Software Management Providers
+#
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""Python Provider for LMI_SoftwareIdentity
+
+Instruments the CIM class LMI_SoftwareIdentity
+
+"""
+
+import pywbem
+from pywbem.cim_provider2 import CIMProvider2
+
+from openlmi.common import cmpi_logging
+from openlmi.software.core import SoftwareIdentity
+from openlmi.software.yumdb import YumDB
+
+class LMI_SoftwareIdentity(CIMProvider2):
+ """Instrument the CIM class LMI_SoftwareIdentity
+
+ SoftwareIdentity provides descriptive information about a software
+ component for asset tracking and/or installation dependency
+ management. When the IsEntity property has the value TRUE, the
+ instance of SoftwareIdentity represents an individually identifiable
+ entity similar to Physical Element. SoftwareIdentity does NOT indicate
+ whether the software is installed, executing, etc. This extra
+ information may be provided through specialized associations to
+ Software Identity. For instance, both InstalledSoftwareIdentity and
+ ElementSoftwareIdentity may be used to indicate that the software
+ identified by this class is installed. SoftwareIdentity is used when
+ managing the software components of a ManagedElement that is the
+ management focus. Since software may be acquired, SoftwareIdentity can
+ be associated with a Product using the ProductSoftwareComponent
+ relationship. The Application Model manages the deployment and
+ installation of software via the classes, SoftwareFeatures and
+ SoftwareElements. SoftwareFeature and SoftwareElement are used when
+ the software component is the management focus. The
+ deployment/installation concepts are related to the asset/identity
+ one. In fact, a SoftwareIdentity may correspond to a Product, or to
+ one or more SoftwareFeatures or SoftwareElements - depending on the
+ granularity of these classes and the deployment model. The
+ correspondence of Software Identity to Product, SoftwareFeature or
+ SoftwareElement is indicated using the ConcreteIdentity association.
+ Note that there may not be sufficient detail or instrumentation to
+ instantiate ConcreteIdentity. And, if the association is instantiated,
+ some duplication of information may result. For example, the Vendor
+ described in the instances of Product and SoftwareIdentity MAY be the
+ same. However, this is not necessarily true, and it is why vendor and
+ similar information are duplicated in this class. Note that
+ ConcreteIdentity can also be used to describe the relationship of the
+ software to any LogicalFiles that result from installing it. As above,
+ there may not be sufficient detail or instrumentation to instantiate
+ this association.
+
+ """
+
+ def __init__ (self, _env):
+ cmpi_logging.logger.debug('Initializing provider %s from %s' \
+ % (self.__class__.__name__, __file__))
+
+ @cmpi_logging.trace_method
+ def get_instance(self, env, model):
+ """Return an instance.
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ model -- A template of the pywbem.CIMInstance to be returned. The
+ key properties are set on this instance to correspond to the
+ instanceName that was requested. The properties of the model
+ are already filtered according to the PropertyList from the
+ request. Only properties present in the model need to be
+ given values. If you prefer, you can set all of the
+ values, and the instance will be filtered for you.
+
+ Possible Errors:
+ CIM_ERR_ACCESS_DENIED
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ or otherwise incorrect parameters)
+ CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
+ Instance does not exist in the specified namespace)
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+ with YumDB.get_instance():
+ pkg_info = SoftwareIdentity.object_path2pkg(model.path, 'all')
+ return SoftwareIdentity.pkg2model(
+ pkg_info, keys_only=False, model=model)
+
+ @cmpi_logging.trace_method
+ def enum_instances(self, env, model, keys_only):
+ """Enumerate instances.
+
+ The WBEM operations EnumerateInstances and EnumerateInstanceNames
+ are both mapped to this method.
+ This method is a python generator
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ model -- A template of the pywbem.CIMInstances to be generated.
+ The properties of the model are already filtered according to
+ the PropertyList from the request. Only properties present in
+ the model need to be given values. If you prefer, you can
+ always set all of the values, and the instance will be filtered
+ for you.
+ keys_only -- A boolean. True if only the key properties should be
+ set on the generated instances.
+
+ Possible Errors:
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+ # Prime model.path with knowledge of the keys, so key values on
+ # the CIMInstanceName (model.path) will automatically be set when
+ # we set property values on the model.
+ model.path.update({'InstanceID': None})
+
+ with YumDB.get_instance() as ydb:
+ pkglist = ydb.get_package_list(
+ 'all', allow_duplicates=True, sort=True)
+ for pkg_info in pkglist:
+ yield SoftwareIdentity.pkg2model(
+ pkg_info, keys_only=keys_only, model=model)
+
+ @cmpi_logging.trace_method
+ def set_instance(self, env, instance, modify_existing):
+ """Return a newly created or modified instance.
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ instance -- The new pywbem.CIMInstance. If modifying an existing
+ instance, the properties on this instance have been filtered by
+ the PropertyList from the request.
+ modify_existing -- True if ModifyInstance, False if CreateInstance
+
+ Return the new instance. The keys must be set on the new instance.
+
+ Possible Errors:
+ CIM_ERR_ACCESS_DENIED
+ CIM_ERR_NOT_SUPPORTED
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ or otherwise incorrect parameters)
+ CIM_ERR_ALREADY_EXISTS (the CIM Instance already exists -- only
+ valid if modify_existing is False, indicating that the operation
+ was CreateInstance)
+ CIM_ERR_NOT_FOUND (the CIM Instance does not exist -- only valid
+ if modify_existing is True, indicating that the operation
+ was ModifyInstance)
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
+
+ @cmpi_logging.trace_method
+ def delete_instance(self, env, instance_name):
+ """Delete an instance.
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ instance_name -- A pywbem.CIMInstanceName specifying the instance
+ to delete.
+
+ Possible Errors:
+ CIM_ERR_ACCESS_DENIED
+ CIM_ERR_NOT_SUPPORTED
+ CIM_ERR_INVALID_NAMESPACE
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ or otherwise incorrect parameters)
+ CIM_ERR_INVALID_CLASS (the CIM Class does not exist in the specified
+ namespace)
+ CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
+ Instance does not exist in the specified namespace)
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
+
diff --git a/src/software/openlmi/software/LMI_SoftwareInstalledPackage.py b/src/software/openlmi/software/LMI_SoftwareInstalledPackage.py
deleted file mode 100644
index 4206a46..0000000
--- a/src/software/openlmi/software/LMI_SoftwareInstalledPackage.py
+++ /dev/null
@@ -1,451 +0,0 @@
-# -*- encoding: utf-8 -*-
-# Software Management Providers
-#
-# Copyright (C) 2012 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: Michal Minar <miminar@redhat.com>
-#
-
-"""Python Provider for LMI_SoftwareInstalledPackage
-
-Instruments the CIM class LMI_SoftwareInstalledPackage
-
-"""
-
-import pywbem
-from pywbem.cim_provider2 import CIMProvider2
-
-from openlmi.common import cmpi_logging
-from openlmi.software.core import (
- ComputerSystem, SoftwareFileCheck,
- SoftwareInstalledPackage, SoftwarePackage)
-from openlmi.software.yumdb import YumDB
-
-class LMI_SoftwareInstalledPackage(CIMProvider2):
- """Instrument the CIM class LMI_SoftwareInstalledPackage
-
- The InstalledSoftwareElement association allows the identification of
- the ComputerSystem on which a particular SoftwareElement is installed.
-
- """
-
- def __init__ (self, _env):
- cmpi_logging.logger.debug('Initializing provider %s from %s' \
- % (self.__class__.__name__, __file__))
-
- @cmpi_logging.trace_method
- def get_instance(self, env, model):
- """Return an instance.
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- model -- A template of the pywbem.CIMInstance to be returned. The
- key properties are set on this instance to correspond to the
- instanceName that was requested. The properties of the model
- are already filtered according to the PropertyList from the
- request. Only properties present in the model need to be
- given values. If you prefer, you can set all of the
- values, and the instance will be filtered for you.
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
- or otherwise incorrect parameters)
- CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
- Instance does not exist in the specified namespace)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- if not "Software" in model:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Missing Software property.")
- if not "System" in model:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Missing System property.")
- ComputerSystem.check_path_property(env, model, 'System')
- model['System'] = ComputerSystem.get_path()
- with YumDB.getInstance():
- pkg_info = SoftwarePackage.object_path2pkg(model['Software'],
- kind="installed")
- model['Software'] = SoftwarePackage.pkg2model(
- pkg_info, keys_only=True)
- return model
-
- @cmpi_logging.trace_method
- def enum_instances(self, env, model, keys_only):
- """Enumerate instances.
-
- The WBEM operations EnumerateInstances and EnumerateInstanceNames
- are both mapped to this method.
- This method is a python generator
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- model -- A template of the pywbem.CIMInstances to be generated.
- The properties of the model are already filtered according to
- the PropertyList from the request. Only properties present in
- the model need to be given values. If you prefer, you can
- always set all of the values, and the instance will be filtered
- for you.
- keys_only -- A boolean. True if only the key properties should be
- set on the generated instances.
-
- Possible Errors:
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- # Prime model.path with knowledge of the keys, so key values on
- # the CIMInstanceName (model.path) will automatically be set when
- # we set property values on the model.
- model.path.update({'System': None, 'Software': None})
-
- yum_package_path = pywbem.CIMInstanceName("LMI_SoftwarePackage",
- namespace=model.path.namespace,
- host=model.path.host)
- model['System'] = ComputerSystem.get_path()
- with YumDB.getInstance() as ydb:
- pkglist = ydb.get_package_list('installed')
- for pkg in pkglist:
- iname = SoftwarePackage.pkg2model(pkg, model=yum_package_path)
- model['Software'] = iname
- yield model
-
- @cmpi_logging.trace_method
- def set_instance(self, env, instance, modify_existing):
- """Return a newly created or modified instance.
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- instance -- The new pywbem.CIMInstance. If modifying an existing
- instance, the properties on this instance have been filtered by
- the PropertyList from the request.
- modify_existing -- True if ModifyInstance, False if CreateInstance
-
- Return the new instance. The keys must be set on the new instance.
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_NOT_SUPPORTED
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
- or otherwise incorrect parameters)
- CIM_ERR_ALREADY_EXISTS (the CIM Instance already exists -- only
- valid if modify_existing is False, indicating that the operation
- was CreateInstance)
- CIM_ERR_NOT_FOUND (the CIM Instance does not exist -- only valid
- if modify_existing is True, indicating that the operation
- was ModifyInstance)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- # parse and check arguments
- if modify_existing is True:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED,
- "MofifyInstance is not supported")
-
- if not "Software" in instance:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Missing Software property.")
- if not "System" in instance:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Missing System property.")
- ComputerSystem.check_path_property(env, instance, 'System')
-
- with YumDB.getInstance() as ydb:
- pkg_info = SoftwarePackage.object_path2pkg_search(
- instance['Software'])
-
- if pkg_info.installed:
- raise pywbem.CIMError(pywbem.CIM_ERR_ALREADY_EXISTS,
- "Package %s is already installed." % pkg_info)
-
- cmpi_logging.logger.info('installing package %s' % pkg_info)
- installed_pkg = ydb.install_package(pkg_info)
- cmpi_logging.logger.info('package %s installed' % pkg_info)
-
- instance["Software"] = SoftwarePackage.pkg2model(installed_pkg)
- return instance
-
- @cmpi_logging.trace_method
- def delete_instance(self, env, instance_name):
- """Delete an instance.
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- instance_name -- A pywbem.CIMInstanceName specifying the instance
- to delete.
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_NOT_SUPPORTED
- CIM_ERR_INVALID_NAMESPACE
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
- or otherwise incorrect parameters)
- CIM_ERR_INVALID_CLASS (the CIM Class does not exist in the specified
- namespace)
- CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
- Instance does not exist in the specified namespace)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- if not "Software" in instance_name:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Missing Software property.")
- if not "System" in instance_name:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Missing System property.")
- ComputerSystem.check_path_property(env, instance_name, 'System')
-
- with YumDB.getInstance() as ydb:
- pkg_info = SoftwarePackage.object_path2pkg(
- instance_name["Software"], kind="installed")
- cmpi_logging.logger.info('removing package "%s"' % pkg_info)
- ydb.remove_package(pkg_info)
- cmpi_logging.logger.info('package "%s" removed' % pkg_info)
-
- @cmpi_logging.trace_method
- def references(self, env, object_name, model, result_class_name, role,
- result_role, keys_only):
- """Instrument Associations.
-
- All four association-related operations (Associators, AssociatorNames,
- References, ReferenceNames) are mapped to this method.
- This method is a python generator
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- object_name -- A pywbem.CIMInstanceName that defines the source
- CIM Object whose associated Objects are to be returned.
- model -- A template pywbem.CIMInstance to serve as a model
- of the objects to be returned. Only properties present on this
- model need to be set.
- result_class_name -- If not empty, this string acts as a filter on
- the returned set of Instances by mandating that each returned
- Instances MUST represent an association between object_name
- and an Instance of a Class whose name matches this parameter
- or a subclass.
- role -- If not empty, MUST be a valid Property name. It acts as a
- filter on the returned set of Instances by mandating that each
- returned Instance MUST refer to object_name via a Property
- whose name matches the value of this parameter.
- result_role -- If not empty, MUST be a valid Property name. It acts
- as a filter on the returned set of Instances by mandating that
- each returned Instance MUST represent associations of
- object_name to other Instances, where the other Instances play
- the specified result_role in the association (i.e. the
- name of the Property in the Association Class that refers to
- the Object related to object_name MUST match the value of this
- parameter).
- keys_only -- A boolean. True if only the key properties should be
- set on the generated instances.
-
- The following diagram may be helpful in understanding the role,
- result_role, and result_class_name parameters.
- +------------------------+ +-------------------+
- | object_name.classname | | result_class_name |
- | ~~~~~~~~~~~~~~~~~~~~~ | | ~~~~~~~~~~~~~~~~~ |
- +------------------------+ +-------------------+
- | +-----------------------------------+ |
- | | [Association] model.classname | |
- | object_name | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
- +--------------+ object_name.classname REF role | |
- (CIMInstanceName) | result_class_name REF result_role +------+
- | |(CIMInstanceName)
- +-----------------------------------+
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_NOT_SUPPORTED
- CIM_ERR_INVALID_NAMESPACE
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
- or otherwise incorrect parameters)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- cimhandle = env.get_cimom_handle()
-
- # If you want to get references for free, implemented in terms
- # of enum_instances, just leave the code below unaltered.
- if cimhandle.is_subclass(object_name.namespace,
- sub=object_name.classname,
- super='CIM_ComputerSystem') or \
- cimhandle.is_subclass(object_name.namespace,
- sub=object_name.classname,
- super='LMI_SoftwarePackage'):
- return self.simple_refs(env, object_name, model,
- result_class_name, role, result_role, keys_only)
-
- @cmpi_logging.trace_method
- def cim_method_checkintegrity(self, env, object_name):
- """Implements LMI_SoftwarePackage.CheckIntegrity()
-
- Verify existence and attributes of files installed from RPM
- package. If all files installed exist and their attributes
- matches, method returns "Pass". "Not passed" is returned when
- arbitrary file differs in its attributes. And "Error" if
- verification could not be done.
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- object_name -- A pywbem.CIMInstanceName or pywbem.CIMCLassName
- specifying the object on which the method CheckIntegrity()
- should be invoked.
-
- Returns a two-tuple containing the return value (
- type pywbem.Uint32 SoftwareInstalledPackage.Values.CheckIntegrity)
- and a list of CIMParameter objects representing the output parameters
-
- Output parameters:
- Failed -- (type REF (pywbem.CIMInstanceName(
- classname='LMI_SoftwareFileCheck', ...))
- Array of references to LMI_SoftwareFileCheck, that did not pass
- verification.
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate,
- unrecognized or otherwise incorrect parameters)
- CIM_ERR_NOT_FOUND (the target CIM Class or instance does not
- exist in the specified namespace)
- CIM_ERR_METHOD_NOT_AVAILABLE (the CIM Server is unable to honor
- the invocation request)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- if not "Software" in object_name:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Missing Software property.")
- if not "System" in object_name:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Missing System property.")
-
- failed = []
- with YumDB.getInstance() as ydb:
- pkg_info = SoftwarePackage.object_path2pkg(object_name['Software'],
- kind="installed")
- pkg_check = ydb.check_package(pkg_info)
- for pkg_file in pkg_check.files.values():
- file_check = SoftwareFileCheck.test_file(
- pkg_check.file_checksum_type, pkg_file)
- if SoftwareFileCheck.filecheck_passed(file_check):
- continue
- failed.append(SoftwareFileCheck.filecheck2model(
- pkg_info, pkg_check, pkg_file.path,
- keys_only=True, file_check=file_check))
- out_params = [ pywbem.CIMParameter('Failed', type='reference',
- value=failed) ]
- return ( getattr(SoftwareInstalledPackage.Values.CheckIntegrity,
- 'Pass' if len(failed) == 0 else 'Not_passed')
- , out_params )
-
- @cmpi_logging.trace_method
- def cim_method_update(self, env, object_name,
- param_epoch=None,
- param_release=None,
- param_version=None):
- """Implements LMI_SoftwareInstalledPackage.Update()
-
- Updates the package to latest version. When any of "version" or
- "release" argument is given, install only matching available
- package. Otherwise try to update to newest package available.
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- object_name -- A pywbem.CIMInstanceName or pywbem.CIMCLassName
- specifying the object on which the method Update()
- should be invoked.
- param_release -- The input parameter release (type unicode)
- Specify particular release of package to update to. Update to
- newest, when empty
- param_version -- The input parameter version (type unicode)
- Specify particular version of package to update to. Update to
- newest, when empty
-
- Returns a two-tuple containing the return value (
- type pywbem.Uint16 SoftwareInstalledPackage.Values.Update)
- and a list of CIMParameter objects representing the output parameters
-
- Output parameters:
- Installed -- (type REF (pywbem.CIMInstanceName(
- classname='LMI_SoftwareInstalledPackage', ...))
- The reference to newly installed package, if installation was
- successful. Otherwise reference to current package.
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate,
- unrecognized or otherwise incorrect parameters)
- CIM_ERR_NOT_FOUND (the target CIM Class or instance does not
- exist in the specified namespace)
- CIM_ERR_METHOD_NOT_AVAILABLE (the CIM Server is unable to honor
- the invocation request)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- if not "Software" in object_name:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Missing Software property.")
- if not "System" in object_name:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Missing System property.")
- ComputerSystem.check_path_property(env, object_name, 'System')
-
- with YumDB.getInstance() as ydb:
- orig = SoftwarePackage.object_path2pkg(object_name['Software'],
- kind='installed')
-
- # NOTE: that we need to obtain all available and installed packages
- # because they are disjunctive and we want to select package
- # with highest version. Let the yum do the sorting of packages.
- pkglist = ydb.filter_packages('all',
- allow_duplicates=True, sort=True,
- name=orig.name,
- epoch=param_epoch,
- version=param_version,
- release=param_release,
- arch=orig.arch)
-
- if len(pkglist) < 1:
- cmpi_logging.logger.error(
- "desired package matching evr not found")
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "package matching desired evr not found among"
- " available packages")
- if len(pkglist) > 1:
- cmpi_logging.logger.info("multiple packages matching"
- " evr - selecting newest")
- cmpi_logging.logger.debug("matching packages (from oldest):"
- " [%s]" % ", ".join([str(p) for p in pkglist]))
- desired_pkg = pkglist[-1]
-
- out_params = [pywbem.CIMParameter('Installed', type='reference')]
- if desired_pkg.installed:
- out_params[0].value = SoftwarePackage.pkg2model(desired_pkg)
- cmpi_logging.logger.info('already up to date')
- return ( SoftwareInstalledPackage.Values.Update.Already_newest
- , out_params)
-
- cmpi_logging.logger.info(
- 'trying to update package \"%s\" to "%s"' % (
- orig, desired_pkg))
- installed_pkg = ydb.update_to_package(desired_pkg)
- cmpi_logging.logger.info('update successful')
-
- out_params[0].value = SoftwarePackage.pkg2model(installed_pkg)
-
- return ( SoftwareInstalledPackage.Values.Update.Successful_installation
- , out_params)
-
diff --git a/src/software/openlmi/software/LMI_SoftwarePackage.py b/src/software/openlmi/software/LMI_SoftwarePackage.py
deleted file mode 100644
index 17483e8..0000000
--- a/src/software/openlmi/software/LMI_SoftwarePackage.py
+++ /dev/null
@@ -1,258 +0,0 @@
-# -*- encoding: utf-8 -*-
-# Software Management Providers
-#
-# Copyright (C) 2012 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: Michal Minar <miminar@redhat.com>
-#
-
-"""Python Provider for LMI_SoftwarePackage
-
-Instruments the CIM class LMI_SoftwarePackage
-
-"""
-
-import pywbem
-from pywbem.cim_provider2 import CIMProvider2
-
-from openlmi.common import cmpi_logging
-from openlmi.software.core import SoftwarePackage
-from openlmi.software.yumdb import YumDB
-
-class LMI_SoftwarePackage(CIMProvider2):
- """Instrument the CIM class LMI_SoftwarePackage
-
- RPM package installed on particular computer system with YUM (The
- Yellowdog Updated, Modified) package manager.
-
- """
-
- def __init__(self, _env):
- cmpi_logging.logger.debug('Initializing provider %s from %s' \
- % (self.__class__.__name__, __file__))
-
- @cmpi_logging.trace_method
- def get_instance(self, env, model):
- """Return an instance.
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- model -- A template of the pywbem.CIMInstance to be returned. The
- key properties are set on this instance to correspond to the
- instanceName that was requested. The properties of the model
- are already filtered according to the PropertyList from the
- request. Only properties present in the model need to be
- given values. If you prefer, you can set all of the
- values, and the instance will be filtered for you.
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
- or otherwise incorrect parameters)
- CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
- Instance does not exist in the specified namespace)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- with YumDB.getInstance():
- pkg_info = SoftwarePackage.object_path2pkg(model.path, 'all')
- return SoftwarePackage.pkg2model(
- pkg_info, keys_only=False, model=model)
-
- @cmpi_logging.trace_method
- def enum_instances(self, env, model, keys_only):
- """Enumerate instances.
-
- The WBEM operations EnumerateInstances and EnumerateInstanceNames
- are both mapped to this method.
- This method is a python generator
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- model -- A template of the pywbem.CIMInstances to be generated.
- The properties of the model are already filtered according to
- the PropertyList from the request. Only properties present in
- the model need to be given values. If you prefer, you can
- always set all of the values, and the instance will be filtered
- for you.
- keys_only -- A boolean. True if only the key properties should be
- set on the generated instances.
-
- Possible Errors:
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- # Prime model.path with knowledge of the keys, so key values on
- # the CIMInstanceName (model.path) will automatically be set when
- # we set property values on the model.
- model.path.update({'TargetOperatingSystem': None, 'Version': None,
- 'SoftwareElementState': None, 'Name': None,
- 'SoftwareElementID': None})
-
- with YumDB.getInstance() as ydb:
- # get all packages
- pkglist = ydb.get_package_list('all',
- allow_duplicates=True, sort=True)
- for pkg in pkglist:
- yield SoftwarePackage.pkg2model(pkg,
- keys_only=keys_only, model=model)
-
- @cmpi_logging.trace_method
- def set_instance(self, env, instance, modify_existing):
- """Return a newly created or modified instance.
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- instance -- The new pywbem.CIMInstance. If modifying an existing
- instance, the properties on this instance have been filtered by
- the PropertyList from the request.
- modify_existing -- True if ModifyInstance, False if CreateInstance
-
- Return the new instance. The keys must be set on the new instance.
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_NOT_SUPPORTED
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
- or otherwise incorrect parameters)
- CIM_ERR_ALREADY_EXISTS (the CIM Instance already exists -- only
- valid if modify_existing is False, indicating that the operation
- was CreateInstance)
- CIM_ERR_NOT_FOUND (the CIM Instance does not exist -- only valid
- if modify_existing is True, indicating that the operation
- was ModifyInstance)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
-
- @cmpi_logging.trace_method
- def delete_instance(self, env, instance_name):
- """Delete an instance.
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- instance_name -- A pywbem.CIMInstanceName specifying the instance
- to delete.
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_NOT_SUPPORTED
- CIM_ERR_INVALID_NAMESPACE
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
- or otherwise incorrect parameters)
- CIM_ERR_INVALID_CLASS (the CIM Class does not exist in the specified
- namespace)
- CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
- Instance does not exist in the specified namespace)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
-
- @cmpi_logging.trace_method
- def cim_method_install(self, env, object_name):
- """Implements LMI_SoftwarePackage.Install()
-
- Will install available package.
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- object_name -- A pywbem.CIMInstanceName or pywbem.CIMCLassName
- specifying the object on which the method Update()
- should be invoked.
-
- Returns a two-tuple containing the return value (
- type pywbem.Uint32 SoftwarePackage.Values.Install)
- and a list of CIMParameter objects representing the output parameters
-
- Output parameters:
- Installed -- (type REF (pywbem.CIMInstanceName(
- classname='LMI_SoftwareInstalledPackage', ...))
- The reference to newly installed package, if installation was
- successful. Null otherwise.
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate,
- unrecognized or otherwise incorrect parameters)
- CIM_ERR_NOT_FOUND (the target CIM Class or instance does not
- exist in the specified namespace)
- CIM_ERR_METHOD_NOT_AVAILABLE (the CIM Server is unable to honor
- the invocation request)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- with YumDB.getInstance() as ydb:
- # get available packages
- pkg_info = SoftwarePackage.object_path2pkg_search(object_name)
- out_params = [ pywbem.CIMParameter('Installed', type='reference') ]
- if pkg_info.installed:
- out_params[0].value = SoftwarePackage.pkg2model(
- pkg_info, keys_only=True)
- return ( SoftwarePackage.Values.Install.Already_installed
- , out_params)
-
- cmpi_logging.logger.info('installing package %s' % pkg_info)
- installed_pkg = ydb.install_package(pkg_info)
- cmpi_logging.logger.info('package %s installed' % pkg_info)
-
- out_params[0].value = SoftwarePackage.pkg2model(
- installed_pkg, keys_only=True)
- return ( SoftwarePackage.Values.Install.Successful_installation
- , out_params)
-
- @cmpi_logging.trace_method
- def cim_method_remove(self, env, object_name):
- """Implements LMI_SoftwarePackage.Remove()
-
- Will uninstall installed package.
-
- Keyword arguments:
- env -- Provider Environment (pycimmb.ProviderEnvironment)
- object_name -- A pywbem.CIMInstanceName or pywbem.CIMCLassName
- specifying the object on which the method Remove()
- should be invoked.
-
- Returns a two-tuple containing the return value (
- type pywbem.Uint32 SoftwarePackage.Values.Remove)
- and a list of CIMParameter objects representing the output parameters
-
- Output parameters: none
-
- Possible Errors:
- CIM_ERR_ACCESS_DENIED
- CIM_ERR_INVALID_PARAMETER (including missing, duplicate,
- unrecognized or otherwise incorrect parameters)
- CIM_ERR_NOT_FOUND (the target CIM Class or instance does not
- exist in the specified namespace)
- CIM_ERR_METHOD_NOT_AVAILABLE (the CIM Server is unable to honor
- the invocation request)
- CIM_ERR_FAILED (some other unspecified error occurred)
-
- """
- with YumDB.getInstance() as ydb:
- pkg_info = SoftwarePackage.object_path2pkg(object_name, 'all')
- if pkg_info.installed:
- cmpi_logging.logger.info('removing package %s' % pkg_info)
- ydb.remove_package(pkg_info)
- cmpi_logging.logger.info('package %s removed' % pkg_info)
- rval = SoftwarePackage.Values.Remove.Successful_removal
- else:
- rval = SoftwarePackage.Values.Remove.Not_installed
- return (rval, [])
-
diff --git a/src/software/openlmi/software/LMI_SystemSoftwareCollection.py b/src/software/openlmi/software/LMI_SystemSoftwareCollection.py
new file mode 100644
index 0000000..ec2382b
--- /dev/null
+++ b/src/software/openlmi/software/LMI_SystemSoftwareCollection.py
@@ -0,0 +1,174 @@
+# Software Management Providers
+#
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""Python Provider for LMI_SystemSoftwareCollection
+
+Instruments the CIM class LMI_SystemSoftwareCollection
+"""
+
+import pywbem
+from pywbem.cim_provider2 import CIMProvider2
+
+from openlmi.common import cmpi_logging
+from openlmi.software.core import SystemSoftwareCollection
+
+class LMI_SystemSoftwareCollection(CIMProvider2):
+ """Instrument the CIM class LMI_SystemSoftwareCollection
+
+ SystemSoftwareCollection represents the general concept of a collection
+ that is scoped (or contained) by a System. It represents a Collection
+ that has meaning only in the context of a System, a Collection whose
+ elements are restricted by the definition of the System, or both of
+ these types of Collections. This meaning is explicitly described by
+ the (required) association, HostedCollection. An example of a
+ SystemSoftwareCollection is a Fibre Channel zone that collects network
+ ports, port groupings, and aliases (as required by a customer) in the
+ context of an AdminDomain. The Collection is not a part of the domain,
+ but merely an arbitrary grouping of the devices and other Collections
+ in the domain. In other words, the context of the Collection is
+ restricted to the domain, and its members are also limited by the
+ domain.
+
+ """
+
+ def __init__ (self, _env):
+ cmpi_logging.logger.debug('Initializing provider %s from %s' \
+ % (self.__class__.__name__, __file__))
+
+ @cmpi_logging.trace_method
+ def get_instance(self, env, model):
+ """Return an instance.
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ model -- A template of the pywbem.CIMInstance to be returned. The
+ key properties are set on this instance to correspond to the
+ instanceName that was requested. The properties of the model
+ are already filtered according to the PropertyList from the
+ request. Only properties present in the model need to be
+ given values. If you prefer, you can set all of the
+ values, and the instance will be filtered for you.
+
+ Possible Errors:
+ CIM_ERR_ACCESS_DENIED
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ or otherwise incorrect parameters)
+ CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
+ Instance does not exist in the specified namespace)
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+ if not 'InstanceID' in model:
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
+ "Missing InstanceID key property")
+ if model['InstanceID'] != \
+ SystemSoftwareCollection.get_path()['InstanceID']:
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "No such instance.")
+
+ model['Caption'] = "System RPM Package Collection"
+ #model['Description'] = '' # TODO
+ #model['ElementName'] = '' # TODO
+ return model
+
+ @cmpi_logging.trace_method
+ def enum_instances(self, env, model, keys_only):
+ """Enumerate instances.
+
+ The WBEM operations EnumerateInstances and EnumerateInstanceNames
+ are both mapped to this method.
+ This method is a python generator
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ model -- A template of the pywbem.CIMInstances to be generated.
+ The properties of the model are already filtered according to
+ the PropertyList from the request. Only properties present in
+ the model need to be given values. If you prefer, you can
+ always set all of the values, and the instance will be filtered
+ for you.
+ keys_only -- A boolean. True if only the key properties should be
+ set on the generated instances.
+
+ Possible Errors:
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+ # Prime model.path with knowledge of the keys, so key values on
+ # the CIMInstanceName (model.path) will automatically be set when
+ # we set property values on the model.
+ model.path.update({'InstanceID': None})
+
+ model['InstanceID'] = SystemSoftwareCollection.get_path()["InstanceID"]
+ if keys_only is False:
+ yield self.get_instance(env, model)
+ else:
+ yield model
+
+ @cmpi_logging.trace_method
+ def set_instance(self, env, instance, modify_existing):
+ """Return a newly created or modified instance.
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ instance -- The new pywbem.CIMInstance. If modifying an existing
+ instance, the properties on this instance have been filtered by
+ the PropertyList from the request.
+ modify_existing -- True if ModifyInstance, False if CreateInstance
+
+ Return the new instance. The keys must be set on the new instance.
+
+ Possible Errors:
+ CIM_ERR_ACCESS_DENIED
+ CIM_ERR_NOT_SUPPORTED
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ or otherwise incorrect parameters)
+ CIM_ERR_ALREADY_EXISTS (the CIM Instance already exists -- only
+ valid if modify_existing is False, indicating that the operation
+ was CreateInstance)
+ CIM_ERR_NOT_FOUND (the CIM Instance does not exist -- only valid
+ if modify_existing is True, indicating that the operation
+ was ModifyInstance)
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
+
+ @cmpi_logging.trace_method
+ def delete_instance(self, env, instance_name):
+ """Delete an instance.
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ instance_name -- A pywbem.CIMInstanceName specifying the instance
+ to delete.
+
+ Possible Errors:
+ CIM_ERR_ACCESS_DENIED
+ CIM_ERR_NOT_SUPPORTED
+ CIM_ERR_INVALID_NAMESPACE
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ or otherwise incorrect parameters)
+ CIM_ERR_INVALID_CLASS (the CIM Class does not exist in the specified
+ namespace)
+ CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
+ Instance does not exist in the specified namespace)
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
+
diff --git a/src/software/openlmi/software/__init__.py b/src/software/openlmi/software/__init__.py
index 2ebe827..55b7d1b 100644
--- a/src/software/openlmi/software/__init__.py
+++ b/src/software/openlmi/software/__init__.py
@@ -18,3 +18,8 @@
#
# Authors: Michal Minar <miminar@redhat.com>
#
+
+"""
+CIM providers for software management.
+Part of OpenLMI project.
+"""
diff --git a/src/software/openlmi/software/cimom_entry.py b/src/software/openlmi/software/cimom_entry.py
index 9e6e10c..156f63a 100644
--- a/src/software/openlmi/software/cimom_entry.py
+++ b/src/software/openlmi/software/cimom_entry.py
@@ -25,28 +25,34 @@ Entry module for OpenLMI Software proviers.
"""
from openlmi.common import cmpi_logging
-from openlmi.software.LMI_SoftwarePackage import LMI_SoftwarePackage
-from openlmi.software.LMI_SoftwareInstalledPackage import \
- LMI_SoftwareInstalledPackage
-from openlmi.software.LMI_SoftwareFileCheck import LMI_SoftwareFileCheck
-from openlmi.software.LMI_SoftwarePackageChecks import \
- LMI_SoftwarePackageChecks
+from openlmi.software.LMI_SoftwareIdentity import LMI_SoftwareIdentity
+from openlmi.software.LMI_SystemSoftwareCollection import \
+ LMI_SystemSoftwareCollection
+from openlmi.software.LMI_HostedSoftwareCollection import \
+ LMI_HostedSoftwareCollection
+from openlmi.software.LMI_MemberOfSoftwareCollection import \
+ LMI_MemberOfSoftwareCollection
from openlmi.software.yumdb import YumDB
def get_providers(env):
+ """
+ @return mapping of provider names to corresponding provider instances.
+ """
cmpi_logging.LogManager(env)
providers = {
- "LMI_SoftwarePackage" : LMI_SoftwarePackage(env),
- "LMI_SoftwareInstalledPackage" : LMI_SoftwareInstalledPackage(env),
- "LMI_SoftwareFileCheck" : LMI_SoftwareFileCheck(env),
- "LMI_SoftwarePackageChecks" : LMI_SoftwarePackageChecks(env)
+ "LMI_SoftwareIdentity" : LMI_SoftwareIdentity(env),
+ "LMI_SystemSoftwareCollection" : LMI_SystemSoftwareCollection(env),
+ "LMI_HostedSoftwareCollection" : LMI_HostedSoftwareCollection(env),
+ "LMI_MemberOfSoftwareCollection" : LMI_MemberOfSoftwareCollection(env)
}
return providers
def can_unload(_env):
+ """ Says, whether providers can be unlouded. """
return True
def shutdown(_env):
- YumDB.getInstance().clean_up()
+ """ Release resources upon cleanup. """
+ YumDB.get_instance().clean_up()
diff --git a/src/software/openlmi/software/core/ComputerSystem.py b/src/software/openlmi/software/core/ComputerSystem.py
index 90699a0..4f99ee3 100644
--- a/src/software/openlmi/software/core/ComputerSystem.py
+++ b/src/software/openlmi/software/core/ComputerSystem.py
@@ -40,9 +40,12 @@ def check_path_property(env, op, prop_name):
Linux_ComputerSystem corresponding to this system.
If not, an exception is raised.
"""
+ if not prop_name in op:
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
+ "Missing %s key property!" % prop_name)
system = op[prop_name]
if not isinstance(system, pywbem.CIMInstanceName):
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
"\"%s\" must be a CIMInstanceName" % prop_name)
our_system = get_path(prefix='CIM')
ch = env.get_cimom_handle()
diff --git a/src/software/openlmi/software/core/SoftwareFileCheck.py b/src/software/openlmi/software/core/SoftwareFileCheck.py
deleted file mode 100644
index 409db09..0000000
--- a/src/software/openlmi/software/core/SoftwareFileCheck.py
+++ /dev/null
@@ -1,515 +0,0 @@
-# -*- encoding: utf-8 -*-
-# Software Management Providers
-#
-# Copyright (C) 2012 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: Michal Minar <miminar@redhat.com>
-#
-
-"""
-Just a common functionality related to SoftwareFileCheck provider.
-"""
-
-import collections
-import hashlib
-import os
-import pywbem
-import stat
-import yum
-
-from openlmi.common import cmpi_logging
-from openlmi.software import util
-from openlmi.software.yumdb import YumDB
-from openlmi.software.yumdb import packageinfo
-from openlmi.software.yumdb import packagecheck
-
-PASSED_FLAGS_DESCRIPTIONS = (
- "Existence",
- "File Type",
- "File Size",
- "File Mode",
- "File Checksum",
- "Device major/minor number",
- "Symlink Target",
- "User Ownership", "Group Ownership",
- "Modify Time")
-
-# Named tuple to store results of rpm file check as pywbem values, all results
-# are in the form:
-# (expected, reality)
-# where
-# expected is value from rpm package
-# reality is value obtained from installed file
-# None means, that value could not be obtained. Except for "exists" and
-# "md5_checksum" attributes, where "exists" is boolean and "md5_checksum" is
-# a string.
-# for example:
-# file_check.file_type == (4, 3)
-FileCheck = collections.namedtuple('FileCheck', #pylint: disable=C0103
- 'exists, md5_checksum, file_type, file_size, file_mode, '
- 'file_checksum, device, link_target, user_id, group_id, '
- 'last_modification_time')
-
-@cmpi_logging.trace_function
-def checksumtype_num2hash(csumt):
- """
- @param csumt checksum type as a number obtained from package
- @return hash function object corresponding to csumt
- """
- return getattr(hashlib, yum.constants.RPM_CHECKSUM_TYPES[csumt])
-
-@cmpi_logging.trace_function
-def checksumtype_str2pywbem(alg):
- """
- @param alg is a name of algorithm used for checksum
- @return pywbem number corresponding to given alg
- """
- try:
- res = packagecheck.CHECKSUMTYPE_STR2NUM[alg.lower()]
- except KeyError:
- res = 0
- return pywbem.Uint16(res)
-
-@cmpi_logging.trace_function
-def filetype_str2pywbem(file_type):
- """
- @param file_type is a name of file type obtained from pkg headers
- @return pywbem number corresponding to thus file type
- """
- try:
- return pywbem.Uint16(
- { 'file' : Values.FileType.File
- , 'directory' : Values.FileType.Directory
- , 'symlink' : Values.FileType.Symlink
- , 'fifo' : Values.FileType.FIFO
- , 'character device' : Values.FileType.Character_Device
- , 'block device' : Values.FileType.Block_Device
- }[file_type])
- except KeyError:
- return Values.FileType.Unknown
-
-@cmpi_logging.trace_function
-def filetype_mode2pywbem(mode):
- """
- @param mode is a raw file mode as integer
- @return pywbem numeric value of file's type
- """
- for i, name in enumerate(
- ('REG', 'DIR', 'LNK', 'FIFO', 'CHR', 'BLK'), 1):
- if getattr(stat, 'S_IS' + name)(mode):
- return pywbem.Uint16(i)
- return pywbem.Uint16(0)
-
-@cmpi_logging.trace_function
-def mode2pywbem_flags(mode):
- """
- @param mode if None, file does not exist
- @return list of integer flags describing file's access permissions
- """
- if mode is None:
- return None
- flags = []
- for i, flag in enumerate((
- stat.S_IXOTH,
- stat.S_IWOTH,
- stat.S_IROTH,
- stat.S_IXGRP,
- stat.S_IWGRP,
- stat.S_IRGRP,
- stat.S_IXUSR,
- stat.S_IWUSR,
- stat.S_IRUSR,
- stat.S_ISVTX,
- stat.S_ISGID,
- stat.S_ISUID)):
- if flag & mode:
- flags.append(pywbem.Uint8(i))
- return flags
-
-@cmpi_logging.trace_function
-def hashfile(afile, hashers, blocksize=65536):
- """
- @param hashers is a list of hash objects
- @return list of digest strings (in hex format) for each hash object
- given in the same order
- """
- if not isinstance(hashers, (tuple, list, set, frozenset)):
- hashers = (hashers, )
- buf = afile.read(blocksize)
- while len(buf) > 0:
- for hashfunc in hashers:
- hashfunc.update(buf)
- buf = afile.read(blocksize)
- return [ hashfunc.hexdigest() for hashfunc in hashers ]
-
-@cmpi_logging.trace_function
-def compute_checksums(checksum_type, file_type, file_path):
- """
- @param file_type is not a file, then zeroes are returned
- @param checksum_type selected hash algorithm to compute second
- checksum
- @return (md5sum, checksum)
- both checksums are computed from file_path's content
- first one is always md5, the second one depends on checksum_type
- if file does not exists, (None, None) is returned
- """
- hashers = [hashlib.md5()] #pylint: disable=E1101
- if checksum_type != packagecheck.CHECKSUMTYPE_STR2NUM["md5"]:
- hashers.append(checksumtype_num2hash(checksum_type)())
- if file_type != filetype_str2pywbem('file'):
- rslts = ['0'*len(h.hexdigest()) for h in hashers]
- else:
- try:
- with open(file_path, 'rb') as fobj:
- rslts = hashfile(fobj, hashers)
- except (OSError, IOError) as exc:
- cmpi_logging.logger.error("could not open file \"%s\""
- " for reading: %s", file_path, exc)
- return None, None
- return (rslts[0], rslts[1] if len(rslts) > 1 else rslts[0]*2)
-
-@cmpi_logging.trace_function
-def object_path2pkg_file(objpath):
- """
- @return (package_info, package_check)
- """
- if not isinstance(objpath, pywbem.CIMInstanceName):
- raise TypeError("objpath must be instance of CIMInstanceName, "
- "not \"%s\"" % objpath.__class__.__name__)
-
- if ( not objpath['Name'] or not objpath['SoftwareElementID']
- or not objpath['CheckID']
- or not objpath['CheckID'].endswith('#'+objpath['Name'])
- or objpath['SoftwareElementID'].find(objpath['Version']) == -1):
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, "Wrong keys.")
- if objpath['SoftwareElementState'] not in ("2", 2):
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Only \"Executable\" software element state supported")
- if not util.check_target_operating_system(objpath['TargetOperatingSystem']):
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Wrong target operating system.")
- if not objpath['Name'] or not objpath['Version']:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- 'Both "Name" and "Version" must be given')
- match = util.RE_NEVRA_OPT_EPOCH.match(objpath['SoftwareElementID'])
- if not match:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Wrong SotwareElementID. Expected valid nevra"
- " (name-epoch:version-release.arch).")
- if objpath['Version'] != match.group('ver'):
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Version does not match version part in SoftwareElementID.")
-
- with YumDB.getInstance() as ydb:
- pkglist = ydb.filter_packages('installed', **util.nevra2filter(match))
- if len(pkglist) < 1:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "No matching package installed.")
- pkg = pkglist[0]
- pkg_check = ydb.check_package(pkg)
- return (pkg, pkg_check, pkg_check[objpath["Name"]])
-
-@cmpi_logging.trace_function
-def test_file(checksum_type, package_file):
- """
- @param checksum type is a pywbem value for ChecksumType property
- @return instance of FileCheck
- """
- if not isinstance(package_file, packagecheck.PackageFile):
- raise TypeError("package_file must be an instance of PackageFile"
- " not \"%s\"" % package_file.__class__.__name__)
- exists = os.path.lexists(package_file.path)
- md5_checksum = None
- expected = {
- "file_type" : filetype_str2pywbem(package_file.file_type),
- "user_id" : pywbem.Uint32(package_file.uid),
- "group_id" : pywbem.Uint32(package_file.gid),
- "file_mode" : pywbem.Uint32(package_file.mode),
- "file_size" : pywbem.Uint64(package_file.size),
- "link_target" : package_file.link_target,
- "file_checksum" : package_file.checksum,
- "device" : pywbem.Uint64(package_file.device)
- if package_file.device is not None else None,
- "last_modification_time" : pywbem.Uint64(package_file.mtime)
- }
- if not exists:
- reality = collections.defaultdict(lambda: None)
- else:
- fstat = os.lstat(package_file.path)
- reality = {
- "file_type" : filetype_mode2pywbem(fstat.st_mode),
- "user_id" : pywbem.Uint32(fstat.st_uid),
- "group_id" : pywbem.Uint32(fstat.st_gid),
- "file_mode" : pywbem.Uint32(fstat.st_mode),
- "file_size" : pywbem.Uint64(fstat.st_size),
- "last_modification_time" : pywbem.Uint64(fstat.st_mtime)
- }
- reality["device"] = (
- pywbem.Uint64(fstat.st_dev)
- if reality['file_type'] == filetype_str2pywbem("device")
- else None)
- reality["link_target"] = (os.readlink(package_file.path)
- if os.path.islink(package_file.path) else None)
- md5_checksum, checksum = compute_checksums(
- checksum_type, reality["file_type"], package_file.path)
- reality["file_checksum"] = checksum
- kwargs = dict(exists=exists, md5_checksum=md5_checksum,
- **dict((k, (expected[k], reality[k])) for k in expected))
- return FileCheck(**kwargs)
-
-@cmpi_logging.trace_function
-def _filecheck2model_flags(file_check):
- """
- @param file_check is an instance of FileCheck
- @return pywbem value for PassedFlags property
- """
- if not isinstance(file_check, FileCheck):
- raise TypeError("file_check must be an instance of FileCheck")
- flags = []
- for k, value in file_check._asdict().items(): #pylint: disable=W0212
- if isinstance(value, tuple):
- if ( k in ("last_modification_time", "file_size")
- and file_check.file_type[0] != filetype_str2pywbem('file')):
- # last_modification_time check is valid only for
- # regular files
- flag = file_check.exists
- elif ( k == "file_mode"
- and file_check.file_type[0] == filetype_str2pywbem('symlink')):
- # do not check mode of symlinks
- flag = ( file_check.exists
- and file_check.file_type[0] == file_check.file_type[1])
- else:
- flag = file_check.exists and value[0] == value[1]
- flags.append(flag)
- elif isinstance(value, bool):
- flags.append(value)
- return flags
-
-@cmpi_logging.trace_function
-def filecheck_passed(file_check):
- """
- @return True if installed file passed all checks.
- """
- return all(_filecheck2model_flags(file_check))
-
-@cmpi_logging.trace_function
-def _fill_non_key_values(model, pkg_check, pkg_file, file_check=None):
- """
- Fills a non key values into instance of SoftwareFileCheck.
- """
- model['FileName'] = os.path.basename(pkg_file.path)
- model['FileChecksumType'] = csumt = pywbem.Uint16(
- pkg_check.file_checksum_type)
- if file_check is None:
- file_check = test_file(csumt, pkg_file)
- for mattr, fattr in (
- ('FileType', 'file_type'),
- ('FileUserID', 'user_id'),
- ('FileGroupID', 'group_id'),
- ('FileMode', 'file_mode'),
- ('LastModificationTime', 'last_modification_time'),
- ('FileSize', 'file_size'),
- ('LinkTarget', 'link_target'),
- ('FileChecksum', 'file_checksum')):
- exp, rea = getattr(file_check, fattr)
- if exp is not None:
- model['Expected' + mattr] = exp
- if rea is not None:
- model[mattr] = rea
- model['ExpectedFileModeFlags'] = mode2pywbem_flags(file_check.file_mode[0])
- if file_check.exists:
- model['FileModeFlags'] = mode2pywbem_flags(file_check.file_mode[1])
- model['FileExists'] = file_check.exists
- if file_check.md5_checksum is not None:
- model['MD5Checksum'] = file_check.md5_checksum
- model['PassedFlags'] = _filecheck2model_flags(file_check)
- model['PassedFlagsDescriptions'] = list(PASSED_FLAGS_DESCRIPTIONS)
-
-@cmpi_logging.trace_function
-def filecheck2model(package_info, package_check, file_name, keys_only=True,
- model=None, file_check=None):
- """
- @param package_file is an instance of yumdb.PackageFile
- @param file_name a absolute file path contained in package
- @param keys_only if True, then only key values will be filed
- @param model if given, then this instance will be modified and
- returned
- @param file_check if not given, it will be computed
- @return instance of LMI_SoftwareFileCheck class with all desired
- values filed
- """
- if not isinstance(package_info, packageinfo.PackageInfo):
- raise TypeError(
- "package_info must be an instance ofyumdb.PackageInfo")
- if not isinstance(package_check, packagecheck.PackageCheck):
- raise TypeError(
- "package_check must be an instance of yumdb.PackageFile")
- if not file_name in package_check:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "File \"%s\" not found among package files" % file_name)
- if model is None:
- model = pywbem.CIMInstanceName("LMI_SoftwareFileCheck",
- namespace="root/cimv2")
- if not keys_only:
- model = pywbem.CIMInstance("LMI_SoftwareFileCheck", path=model)
- package_file = package_check[file_name]
- model['Name'] = package_file.path
- model['SoftwareElementID'] = package_info.nevra
- model['SoftwareElementState'] = Values.SoftwareElementState.Executable
- model['TargetOperatingSystem'] = pywbem.Uint16(
- util.get_target_operating_system()[0])
- model['Version'] = package_info.version
- model['CheckID'] = '%s#%s' % (package_info.name, package_file.path)
- if not keys_only:
- if file_check is not None:
- if not isinstance(file_check, FileCheck):
- raise TypeError("file_check must be an instance of FileCheck")
- _fill_non_key_values(model, package_check, package_file, file_check)
- return model
-
-class Values(object):
- """
- Enumerations of LMI_SoftwareFileCheck class properties.
- """
- class TargetOperatingSystem(object):
- Unknown = pywbem.Uint16(0)
- Other = pywbem.Uint16(1)
- MACOS = pywbem.Uint16(2)
- ATTUNIX = pywbem.Uint16(3)
- DGUX = pywbem.Uint16(4)
- DECNT = pywbem.Uint16(5)
- Tru64_UNIX = pywbem.Uint16(6)
- OpenVMS = pywbem.Uint16(7)
- HPUX = pywbem.Uint16(8)
- AIX = pywbem.Uint16(9)
- MVS = pywbem.Uint16(10)
- OS400 = pywbem.Uint16(11)
- OS_2 = pywbem.Uint16(12)
- JavaVM = pywbem.Uint16(13)
- MSDOS = pywbem.Uint16(14)
- WIN3x = pywbem.Uint16(15)
- WIN95 = pywbem.Uint16(16)
- WIN98 = pywbem.Uint16(17)
- WINNT = pywbem.Uint16(18)
- WINCE = pywbem.Uint16(19)
- NCR3000 = pywbem.Uint16(20)
- NetWare = pywbem.Uint16(21)
- OSF = pywbem.Uint16(22)
- DC_OS = pywbem.Uint16(23)
- Reliant_UNIX = pywbem.Uint16(24)
- SCO_UnixWare = pywbem.Uint16(25)
- SCO_OpenServer = pywbem.Uint16(26)
- Sequent = pywbem.Uint16(27)
- IRIX = pywbem.Uint16(28)
- Solaris = pywbem.Uint16(29)
- SunOS = pywbem.Uint16(30)
- U6000 = pywbem.Uint16(31)
- ASERIES = pywbem.Uint16(32)
- HP_NonStop_OS = pywbem.Uint16(33)
- HP_NonStop_OSS = pywbem.Uint16(34)
- BS2000 = pywbem.Uint16(35)
- LINUX = pywbem.Uint16(36)
- Lynx = pywbem.Uint16(37)
- XENIX = pywbem.Uint16(38)
- VM = pywbem.Uint16(39)
- Interactive_UNIX = pywbem.Uint16(40)
- BSDUNIX = pywbem.Uint16(41)
- FreeBSD = pywbem.Uint16(42)
- NetBSD = pywbem.Uint16(43)
- GNU_Hurd = pywbem.Uint16(44)
- OS9 = pywbem.Uint16(45)
- MACH_Kernel = pywbem.Uint16(46)
- Inferno = pywbem.Uint16(47)
- QNX = pywbem.Uint16(48)
- EPOC = pywbem.Uint16(49)
- IxWorks = pywbem.Uint16(50)
- VxWorks = pywbem.Uint16(51)
- MiNT = pywbem.Uint16(52)
- BeOS = pywbem.Uint16(53)
- HP_MPE = pywbem.Uint16(54)
- NextStep = pywbem.Uint16(55)
- PalmPilot = pywbem.Uint16(56)
- Rhapsody = pywbem.Uint16(57)
- Windows_2000 = pywbem.Uint16(58)
- Dedicated = pywbem.Uint16(59)
- OS_390 = pywbem.Uint16(60)
- VSE = pywbem.Uint16(61)
- TPF = pywbem.Uint16(62)
- Windows__R__Me = pywbem.Uint16(63)
- Caldera_Open_UNIX = pywbem.Uint16(64)
- OpenBSD = pywbem.Uint16(65)
- Not_Applicable = pywbem.Uint16(66)
- Windows_XP = pywbem.Uint16(67)
- z_OS = pywbem.Uint16(68)
- Microsoft_Windows_Server_2003 = pywbem.Uint16(69)
- Microsoft_Windows_Server_2003_64_Bit = pywbem.Uint16(70)
- Windows_XP_64_Bit = pywbem.Uint16(71)
- Windows_XP_Embedded = pywbem.Uint16(72)
- Windows_Vista = pywbem.Uint16(73)
- Windows_Vista_64_Bit = pywbem.Uint16(74)
- Windows_Embedded_for_Point_of_Service = pywbem.Uint16(75)
- Microsoft_Windows_Server_2008 = pywbem.Uint16(76)
- Microsoft_Windows_Server_2008_64_Bit = pywbem.Uint16(77)
- FreeBSD_64_Bit = pywbem.Uint16(78)
- RedHat_Enterprise_Linux = pywbem.Uint16(79)
- RedHat_Enterprise_Linux_64_Bit = pywbem.Uint16(80)
- Solaris_64_Bit = pywbem.Uint16(81)
- SUSE = pywbem.Uint16(82)
- SUSE_64_Bit = pywbem.Uint16(83)
- SLES = pywbem.Uint16(84)
- SLES_64_Bit = pywbem.Uint16(85)
- Novell_OES = pywbem.Uint16(86)
- Novell_Linux_Desktop = pywbem.Uint16(87)
- Sun_Java_Desktop_System = pywbem.Uint16(88)
- Mandriva = pywbem.Uint16(89)
- Mandriva_64_Bit = pywbem.Uint16(90)
- TurboLinux = pywbem.Uint16(91)
- TurboLinux_64_Bit = pywbem.Uint16(92)
- Ubuntu = pywbem.Uint16(93)
- Ubuntu_64_Bit = pywbem.Uint16(94)
- Debian = pywbem.Uint16(95)
- Debian_64_Bit = pywbem.Uint16(96)
- Linux_2_4_x = pywbem.Uint16(97)
- Linux_2_4_x_64_Bit = pywbem.Uint16(98)
- Linux_2_6_x = pywbem.Uint16(99)
- Linux_2_6_x_64_Bit = pywbem.Uint16(100)
- Linux_64_Bit = pywbem.Uint16(101)
- Other_64_Bit = pywbem.Uint16(102)
- Microsoft_Windows_Server_2008_R2 = pywbem.Uint16(103)
- VMware_ESXi = pywbem.Uint16(104)
- Microsoft_Windows_7 = pywbem.Uint16(105)
- CentOS_32_bit = pywbem.Uint16(106)
- CentOS_64_bit = pywbem.Uint16(107)
- Oracle_Enterprise_Linux_32_bit = pywbem.Uint16(108)
- Oracle_Enterprise_Linux_64_bit = pywbem.Uint16(109)
- eComStation_32_bitx = pywbem.Uint16(110)
-
- class SoftwareElementState(object):
- Deployable = pywbem.Uint16(0)
- Installable = pywbem.Uint16(1)
- Executable = pywbem.Uint16(2)
- Running = pywbem.Uint16(3)
-
- class FileType(object):
- Unknown = pywbem.Uint16(0)
- File = pywbem.Uint16(1)
- Directory = pywbem.Uint16(2)
- Symlink = pywbem.Uint16(3)
- FIFO = pywbem.Uint16(4)
- Character_Device = pywbem.Uint16(5)
- Block_Device = pywbem.Uint16(6)
-
diff --git a/src/software/openlmi/software/core/SoftwareIdentity.py b/src/software/openlmi/software/core/SoftwareIdentity.py
new file mode 100644
index 0000000..1c4b9fe
--- /dev/null
+++ b/src/software/openlmi/software/core/SoftwareIdentity.py
@@ -0,0 +1,278 @@
+# -*- encoding: utf-8 -*-
+# Software Management Providers
+#
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""
+Just a common functionality related to LMI_SoftwareIdentity provider.
+"""
+
+import pywbem
+
+from openlmi.common import cmpi_logging
+from openlmi.software import util
+from openlmi.software.yumdb import PackageInfo, YumDB
+
+class Values(object):
+ class DetailedStatus(object):
+ Not_Available = pywbem.Uint16(0)
+ No_Additional_Information = pywbem.Uint16(1)
+ Stressed = pywbem.Uint16(2)
+ Predictive_Failure = pywbem.Uint16(3)
+ Non_Recoverable_Error = pywbem.Uint16(4)
+ Supporting_Entity_in_Error = pywbem.Uint16(5)
+ # DMTF_Reserved = ..
+ # Vendor_Reserved = 0x8000..
+
+ class Status(object):
+ OK = 'OK'
+ Error = 'Error'
+ Degraded = 'Degraded'
+ Unknown = 'Unknown'
+ Pred_Fail = 'Pred Fail'
+ Starting = 'Starting'
+ Stopping = 'Stopping'
+ Service = 'Service'
+ Stressed = 'Stressed'
+ NonRecover = 'NonRecover'
+ No_Contact = 'No Contact'
+ Lost_Comm = 'Lost Comm'
+ Stopped = 'Stopped'
+
+ class HealthState(object):
+ Unknown = pywbem.Uint16(0)
+ OK = pywbem.Uint16(5)
+ Degraded_Warning = pywbem.Uint16(10)
+ Minor_failure = pywbem.Uint16(15)
+ Major_failure = pywbem.Uint16(20)
+ Critical_failure = pywbem.Uint16(25)
+ Non_recoverable_error = pywbem.Uint16(30)
+ # DMTF_Reserved = ..
+ # Vendor_Specific = 32768..65535
+
+ class Classifications(object):
+ Unknown = pywbem.Uint16(0)
+ Other = pywbem.Uint16(1)
+ Driver = pywbem.Uint16(2)
+ Configuration_Software = pywbem.Uint16(3)
+ Application_Software = pywbem.Uint16(4)
+ Instrumentation = pywbem.Uint16(5)
+ Firmware_BIOS = pywbem.Uint16(6)
+ Diagnostic_Software = pywbem.Uint16(7)
+ Operating_System = pywbem.Uint16(8)
+ Middleware = pywbem.Uint16(9)
+ Firmware = pywbem.Uint16(10)
+ BIOS_FCode = pywbem.Uint16(11)
+ Support_Service_Pack = pywbem.Uint16(12)
+ Software_Bundle = pywbem.Uint16(13)
+ # DMTF_Reserved = ..
+ # Vendor_Reserved = 0x8000..0xFFFF
+
+ class ExtendedResourceType(object):
+ Unknown = pywbem.Uint16(0)
+ Other = pywbem.Uint16(1)
+ Not_Applicable = pywbem.Uint16(2)
+ Linux_RPM = pywbem.Uint16(3)
+ HP_UX_Depot = pywbem.Uint16(4)
+ Windows_MSI = pywbem.Uint16(5)
+ Solaris_Package = pywbem.Uint16(6)
+ Macintosh_Disk_Image = pywbem.Uint16(7)
+ Debian_linux_Package = pywbem.Uint16(8)
+ VMware_vSphere_Installation_Bundle = pywbem.Uint16(9)
+ VMware_Software_Bulletin = pywbem.Uint16(10)
+ HP_Smart_Component = pywbem.Uint16(11)
+ # DMTF_Reserved = ..
+ # Vendor_Reserved = 0x8000..
+
+ class CommunicationStatus(object):
+ Unknown = pywbem.Uint16(0)
+ Not_Available = pywbem.Uint16(1)
+ Communication_OK = pywbem.Uint16(2)
+ Lost_Communication = pywbem.Uint16(3)
+ No_Contact = pywbem.Uint16(4)
+ # DMTF_Reserved = ..
+ # Vendor_Reserved = 0x8000..
+
+ class OperationalStatus(object):
+ Unknown = pywbem.Uint16(0)
+ Other = pywbem.Uint16(1)
+ OK = pywbem.Uint16(2)
+ Degraded = pywbem.Uint16(3)
+ Stressed = pywbem.Uint16(4)
+ Predictive_Failure = pywbem.Uint16(5)
+ Error = pywbem.Uint16(6)
+ Non_Recoverable_Error = pywbem.Uint16(7)
+ Starting = pywbem.Uint16(8)
+ Stopping = pywbem.Uint16(9)
+ Stopped = pywbem.Uint16(10)
+ In_Service = pywbem.Uint16(11)
+ No_Contact = pywbem.Uint16(12)
+ Lost_Communication = pywbem.Uint16(13)
+ Aborted = pywbem.Uint16(14)
+ Dormant = pywbem.Uint16(15)
+ Supporting_Entity_in_Error = pywbem.Uint16(16)
+ Completed = pywbem.Uint16(17)
+ Power_Mode = pywbem.Uint16(18)
+ Relocating = pywbem.Uint16(19)
+ # DMTF_Reserved = ..
+ # Vendor_Reserved = 0x8000..
+
+ class OperatingStatus(object):
+ Unknown = pywbem.Uint16(0)
+ Not_Available = pywbem.Uint16(1)
+ Servicing = pywbem.Uint16(2)
+ Starting = pywbem.Uint16(3)
+ Stopping = pywbem.Uint16(4)
+ Stopped = pywbem.Uint16(5)
+ Aborted = pywbem.Uint16(6)
+ Dormant = pywbem.Uint16(7)
+ Completed = pywbem.Uint16(8)
+ Migrating = pywbem.Uint16(9)
+ Emigrating = pywbem.Uint16(10)
+ Immigrating = pywbem.Uint16(11)
+ Snapshotting = pywbem.Uint16(12)
+ Shutting_Down = pywbem.Uint16(13)
+ In_Test = pywbem.Uint16(14)
+ Transitioning = pywbem.Uint16(15)
+ In_Service = pywbem.Uint16(16)
+ # DMTF_Reserved = ..
+ # Vendor_Reserved = 0x8000..
+
+ class PrimaryStatus(object):
+ Unknown = pywbem.Uint16(0)
+ OK = pywbem.Uint16(1)
+ Degraded = pywbem.Uint16(2)
+ Error = pywbem.Uint16(3)
+ # DMTF_Reserved = ..
+ # Vendor_Reserved = 0x8000..
+
+@cmpi_logging.trace_function
+def object_path2pkg(op, kind='installed'):
+ """
+ @param op must contain precise information of package,
+ otherwise an error is raised
+ @param kind one of yumdb.jobs.YumGetPackageList.SUPPORTED_KINDS
+ says, where to look for given package
+ """
+ if not isinstance(kind, basestring):
+ raise TypeError("kind must be a string")
+ if not isinstance(op, pywbem.CIMInstanceName):
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
+ "op must be an instance of CIMInstanceName")
+
+ if (not "InstanceID" in op or not op['InstanceID']):
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER, "Wrong keys.")
+ instid = op['InstanceID']
+ if not instid.lower().startswith("lmi:pkg:"):
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
+ "InstanceID must start with LMI:PKG: prefix.")
+ instid = instid[len("LMI:PKG:"):]
+ match = util.RE_NEVRA_OPT_EPOCH.match(instid)
+ if not match:
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
+ "Wrong InstanceID. Expected valid nevra"
+ ' (name-[epoch:]version-release.arch): "%s".' %
+ instid)
+
+ pkglist = YumDB.get_instance().filter_packages(kind,
+ allow_duplicates=kind not in ('installed', 'avail_reinst'),
+ **util.nevra2filter(match))
+ if len(pkglist) > 0:
+ return pkglist[0]
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ 'No matching package found for InstanceID=\"%s\".' %
+ instid)
+
+@cmpi_logging.trace_function
+def pkg2model(pkg_info, keys_only=True, model=None):
+ """
+ @param model if None, will be filled with data, otherwise
+ a new instance of CIMInstance or CIMObjectPath is created
+ """
+ if not isinstance(pkg_info, PackageInfo):
+ raise TypeError("pkg must be an instance of PackageInfo")
+ if model is None:
+ model = pywbem.CIMInstanceName("LMI_SoftwareIdentity",
+ namespace="root/cimv2")
+ if not keys_only:
+ model = pywbem.CIMInstance("LMI_SoftwareIdentity", path=model)
+ if isinstance(model, pywbem.CIMInstance):
+ def _set_key(k, value):
+ """Sets the value of key property of cim instance"""
+ model[k] = value
+ model.path[k] = value #pylint: disable=E1103
+ else:
+ _set_key = model.__setitem__
+ _set_key('InstanceID', 'LMI:PKG:'+pkg_info.nevra)
+ if not keys_only:
+ #model['BuildNumber'] = pywbem.Uint16() # TODO
+ model['Caption'] = pkg_info.summary
+ #model['ClassificationDescriptions'] = ['',] # TODO
+ model['Classifications'] = [pywbem.Uint16(0)]
+ #model['CommunicationStatus'] = \
+ # self.Values.CommunicationStatus.<VAL> # TODO
+ model['Description'] = pkg_info.description
+ #model['DetailedStatus'] = self.Values.DetailedStatus.<VAL> # TODO
+ model['ElementName'] = pkg_info.nevra
+ #model['ExtendedResourceType'] = \
+ #self.Values.ExtendedResourceType.<VAL> # TODO
+ #model['HealthState'] = self.Values.HealthState.<VAL> # TODO
+ #model['IdentityInfoType'] = ['',] # TODO
+ #model['IdentityInfoValue'] = ['',] # TODO
+ if pkg_info.installed:
+ model['InstallDate'] = pywbem.CIMDateTime(
+ pkg_info.install_time)
+ model['IsEntity'] = True
+ #model['IsLargeBuildNumber'] = bool(False) # TODO
+ #model['Languages'] = ['',] # TODO
+ #model['LargeBuildNumber'] = pywbem.Uint64() # TODO
+ #model['MajorVersion'] = pywbem.Uint16() # TODO
+ #model['Manufacturer'] = '' # TODO
+ #model['MinExtendedResourceTypeBuildNumber'] = \
+ #pywbem.Uint16() # TODO
+ #model['MinExtendedResourceTypeMajorVersion'] = \
+ #pywbem.Uint16() # TODO
+ #model['MinExtendedResourceTypeMinorVersion'] = \
+ #pywbem.Uint16() # TODO
+ #model['MinExtendedResourceTypeRevisionNumber'] = \
+ #pywbem.Uint16() # TODO
+ #model['MinorVersion'] = pywbem.Uint16() # TODO
+ model['Name'] = pkg_info.name
+ try:
+ model["Epoch"] = pywbem.Uint32(int(pkg_info.epoch))
+ except ValueError:
+ cmpi_logging.logger.error('Could not convert epoch "%s"'
+ ' to integer for package \"%s\"!' % (pkg_info.epoch, pkg_info))
+ model['Version'] = pkg_info.version
+ model['Release'] = pkg_info.release
+ model['Architecture'] = pkg_info.arch
+ #model['OperatingStatus'] = \
+ #self.Values.OperatingStatus.<VAL> # TODO
+ #model['OperationalStatus'] = \
+ #[self.Values.OperationalStatus.<VAL>,] # TODO
+ #model['OtherExtendedResourceTypeDescription'] = '' # TODO
+ #model['PrimaryStatus'] = self.Values.PrimaryStatus.<VAL> # TODO
+ #model['ReleaseDate'] = pywbem.CIMDateTime() # TODO
+ #model['RevisionNumber'] = pywbem.Uint16() # TODO
+ #model['SerialNumber'] = '' # TODO
+ #model['Status'] = self.Values.Status.<VAL> # TODO
+ #model['StatusDescriptions'] = ['',] # TODO
+ #model['TargetOperatingSystems'] = ['',] # TODO
+ #model['TargetOSTypes'] = [pywbem.Uint16(),] # TODO
+ model['TargetTypes'] = ['rpm', 'yum']
+ model['VersionString'] = pkg_info.evra
+ return model
+
diff --git a/src/software/openlmi/software/core/SoftwareInstalledPackage.py b/src/software/openlmi/software/core/SoftwareInstalledPackage.py
deleted file mode 100644
index f91fb56..0000000
--- a/src/software/openlmi/software/core/SoftwareInstalledPackage.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# -*- encoding: utf-8 -*-
-# Software Management Providers
-#
-# Copyright (C) 2012 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: Michal Minar <miminar@redhat.com>
-#
-
-"""
-Just a common functionality related to LMI_SoftwarePackage provider.
-"""
-
-import pywbem
-
-class Values(object):
- class Update(object):
- Already_newest = pywbem.Uint16(0)
- Successful_installation = pywbem.Uint16(1)
- Failed = pywbem.Uint16(2)
-
- class CheckIntegrity(object):
- Pass = pywbem.Uint32(0)
- Not_passed = pywbem.Uint32(1)
- Error = pywbem.Uint32(2)
-
diff --git a/src/software/openlmi/software/core/SoftwarePackage.py b/src/software/openlmi/software/core/SoftwarePackage.py
deleted file mode 100644
index 0ef0d31..0000000
--- a/src/software/openlmi/software/core/SoftwarePackage.py
+++ /dev/null
@@ -1,412 +0,0 @@
-# -*- encoding: utf-8 -*-
-# Software Management Providers
-#
-# Copyright (C) 2012 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: Michal Minar <miminar@redhat.com>
-#
-
-"""
-Just a common functionality related to LMI_SoftwarePackage provider.
-"""
-
-import pywbem
-
-from openlmi.common import cmpi_logging
-from openlmi.software import util
-from openlmi.software.yumdb import PackageInfo, YumDB
-
-@cmpi_logging.trace_function
-def object_path2pkg(objpath, kind='installed'):
- """
- @param objpath must contain precise information of package,
- otherwise a CIM_ERR_NOT_FOUND error is raised
- @param kind one of {'installed', 'all', 'available'}
- says, where to look for given package
- """
- if not isinstance(objpath, pywbem.CIMInstanceName):
- raise TypeError("objpath must be an instance of CIMInstanceName")
- if not isinstance(kind, basestring):
- raise TypeError("kind must be a string")
- if not kind in ('installed', 'all', 'available'):
- raise ValueError('unsupported package list "%s"' % kind)
-
- if ( not objpath['Name'] or not objpath['SoftwareElementID']
- or not objpath['SoftwareElementID'].startswith(objpath['Name'])
- or objpath['SoftwareElementID'].find(objpath['Version']) == -1):
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, "Wrong keys.")
- if not util.check_target_operating_system(objpath['TargetOperatingSystem']):
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Wrong target operating system.")
- if not objpath['Name'] or not objpath['Version']:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- 'Both "Name" and "Version" must be given')
- match = util.RE_NEVRA_OPT_EPOCH.match(objpath['SoftwareElementID'])
- if not match:
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Wrong SotwareElementID. Expected valid nevra"
- " (name-[epoch:]version-release.arch).")
- if objpath['Version'] != match.group('ver'):
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "Version does not match version part in SoftwareElementID.")
- pkglist = YumDB.getInstance().filter_packages(kind,
- allow_duplicates=kind != 'installed',
- **util.nevra2filter(match))
- if len(pkglist) > 0:
- return pkglist[0]
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "No matching package found.")
-
-@cmpi_logging.trace_function
-def object_path2pkg_search(objpath):
- """
- similar to object_path2pkg, but tries to find best suitable
- package matching keys
-
- If any matching package is already installed, it is returned.
- Otherwise available package with highest version is returned.
-
- @param objpath may be object of CIMInstance or CIMInstanceName and
- must contain at least \"Name\" or \"SoftwareElementID\"
- @return instance PackageInfo
- """
- if isinstance(objpath, pywbem.CIMInstance):
- def _get_key(k):
- """@return value of instance's key"""
- value = objpath.properties.get(k, None)
- if isinstance(value, pywbem.CIMProperty):
- return value.value
- if value is not None:
- return value
- cmpi_logging.logger.error(
- 'missing key "%s" in inst.props', k)
- return objpath.path[k] if k in objpath.path else None
- elif isinstance(objpath, pywbem.CIMInstanceName):
- _get_key = lambda k: objpath[k] if k in objpath else None
- else:
- raise TypeError("objpath must be either CIMInstance"
- "or CIMInstanceName")
-
- # parse and check arguments
- filters = {}
- if _get_key('SoftwareElementID'):
- match = util.RE_NEVRA_OPT_EPOCH.match(_get_key('SoftwareElementID'))
- if not match:
- raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
- "SoftwareElementID could not be parsed.")
- filters = util.nevra2filter(match)
- else:
- for k in ('name', 'epoch', 'version', 'release', 'arch'):
- ikey = k if k != 'arch' else "architecture"
- if _get_key(ikey):
- filters[k] = _get_key(ikey)
-
- if not filters:
- raise pywbem.CIMError(pywbem.CIM_ERR_FAILED,
- "Too few key values given (give at least a Name).")
- if not 'name' in filters:
- raise pywbem.CIMError(pywbem.CIM_ERR_FAILED,
- "Missing either Name or SoftwareElementID property.")
-
- pkglist = YumDB.getInstance().filter_packages('all',
- allow_duplicates=True, sort=True, **filters)
- if len(pkglist) == 0:
- cmpi_logging.logger.error(
- 'could not find any matching package in list: %s',
- [p.nevra for p in pkglist])
- raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
- "No matching package found.")
- for pkg in pkglist: # check, whether package is already installed
- if pkg.installed:
- return pkg
- cmpi_logging.logger.info(
- ( 'found multiple matching packages'
- if len(pkglist) > 1 else 'exact match found'))
- return pkglist[-1] # select highest version
-
-@cmpi_logging.trace_function
-def pkg2model(pkg, keys_only=True, model=None):
- """
- @param model if None, will be filled with data, otherwise
- a new instance of CIMInstance or CIMObjectPath is created
- """
- if not isinstance(pkg, PackageInfo):
- raise TypeError("pkg must be an instance of PackageInfo")
- if model is None:
- model = pywbem.CIMInstanceName('LMI_SoftwarePackage',
- namespace='root/cimv2')
- if not keys_only:
- model = pywbem.CIMInstance('LMI_SoftwarePackage', path=model)
- if isinstance(model, pywbem.CIMInstance):
- def _set_key(k, value):
- """Sets the value of key property of cim instance"""
- model[k] = value
- model.path[k] = value #pylint: disable=E1103
- else:
- _set_key = model.__setitem__
- _set_key('Name', pkg.name)
- _set_key('SoftwareElementID', pkg.nevra)
- _set_key('SoftwareElementState',
- Values.SoftwareElementState.Executable
- if pkg.installed
- else Values.SoftwareElementState.Installable)
- _set_key('TargetOperatingSystem',
- pywbem.Uint16(util.get_target_operating_system()[0]))
- _set_key('Version', pkg.version)
- if not keys_only:
- model['Caption'] = pkg.summary
- model['Description'] = pkg.description
- if pkg.installed:
- model['InstallDate'] = pywbem.CIMDateTime(pkg.install_time)
- if pkg.vendor:
- model['Manufacturer'] = pkg.vendor
- model['Release'] = pkg.release
- model['Epoch'] = pywbem.Uint16(pkg.epoch)
- model["Architecture"] = pkg.arch
- model['License'] = pkg.license
- model['Group'] = pkg.group
- model['Size'] = pywbem.Uint64(pkg.size)
- return model
-
-class Values(object):
- class DetailedStatus(object):
- Not_Available = pywbem.Uint16(0)
- No_Additional_Information = pywbem.Uint16(1)
- Stressed = pywbem.Uint16(2)
- Predictive_Failure = pywbem.Uint16(3)
- Non_Recoverable_Error = pywbem.Uint16(4)
- Supporting_Entity_in_Error = pywbem.Uint16(5)
- # DMTF_Reserved = ..
- # Vendor_Reserved = 0x8000..
-
- class Status(object):
- OK = 'OK'
- Error = 'Error'
- Degraded = 'Degraded'
- Unknown = 'Unknown'
- Pred_Fail = 'Pred Fail'
- Starting = 'Starting'
- Stopping = 'Stopping'
- Service = 'Service'
- Stressed = 'Stressed'
- NonRecover = 'NonRecover'
- No_Contact = 'No Contact'
- Lost_Comm = 'Lost Comm'
- Stopped = 'Stopped'
-
- class HealthState(object):
- Unknown = pywbem.Uint16(0)
- OK = pywbem.Uint16(5)
- Degraded_Warning = pywbem.Uint16(10)
- Minor_failure = pywbem.Uint16(15)
- Major_failure = pywbem.Uint16(20)
- Critical_failure = pywbem.Uint16(25)
- Non_recoverable_error = pywbem.Uint16(30)
- # DMTF_Reserved = ..
- # Vendor_Specific = 32768..65535
-
- class TargetOperatingSystem(object):
- Unknown = pywbem.Uint16(0)
- Other = pywbem.Uint16(1)
- MACOS = pywbem.Uint16(2)
- ATTUNIX = pywbem.Uint16(3)
- DGUX = pywbem.Uint16(4)
- DECNT = pywbem.Uint16(5)
- Tru64_UNIX = pywbem.Uint16(6)
- OpenVMS = pywbem.Uint16(7)
- HPUX = pywbem.Uint16(8)
- AIX = pywbem.Uint16(9)
- MVS = pywbem.Uint16(10)
- OS400 = pywbem.Uint16(11)
- OS_2 = pywbem.Uint16(12)
- JavaVM = pywbem.Uint16(13)
- MSDOS = pywbem.Uint16(14)
- WIN3x = pywbem.Uint16(15)
- WIN95 = pywbem.Uint16(16)
- WIN98 = pywbem.Uint16(17)
- WINNT = pywbem.Uint16(18)
- WINCE = pywbem.Uint16(19)
- NCR3000 = pywbem.Uint16(20)
- NetWare = pywbem.Uint16(21)
- OSF = pywbem.Uint16(22)
- DC_OS = pywbem.Uint16(23)
- Reliant_UNIX = pywbem.Uint16(24)
- SCO_UnixWare = pywbem.Uint16(25)
- SCO_OpenServer = pywbem.Uint16(26)
- Sequent = pywbem.Uint16(27)
- IRIX = pywbem.Uint16(28)
- Solaris = pywbem.Uint16(29)
- SunOS = pywbem.Uint16(30)
- U6000 = pywbem.Uint16(31)
- ASERIES = pywbem.Uint16(32)
- HP_NonStop_OS = pywbem.Uint16(33)
- HP_NonStop_OSS = pywbem.Uint16(34)
- BS2000 = pywbem.Uint16(35)
- LINUX = pywbem.Uint16(36)
- Lynx = pywbem.Uint16(37)
- XENIX = pywbem.Uint16(38)
- VM = pywbem.Uint16(39)
- Interactive_UNIX = pywbem.Uint16(40)
- BSDUNIX = pywbem.Uint16(41)
- FreeBSD = pywbem.Uint16(42)
- NetBSD = pywbem.Uint16(43)
- GNU_Hurd = pywbem.Uint16(44)
- OS9 = pywbem.Uint16(45)
- MACH_Kernel = pywbem.Uint16(46)
- Inferno = pywbem.Uint16(47)
- QNX = pywbem.Uint16(48)
- EPOC = pywbem.Uint16(49)
- IxWorks = pywbem.Uint16(50)
- VxWorks = pywbem.Uint16(51)
- MiNT = pywbem.Uint16(52)
- BeOS = pywbem.Uint16(53)
- HP_MPE = pywbem.Uint16(54)
- NextStep = pywbem.Uint16(55)
- PalmPilot = pywbem.Uint16(56)
- Rhapsody = pywbem.Uint16(57)
- Windows_2000 = pywbem.Uint16(58)
- Dedicated = pywbem.Uint16(59)
- OS_390 = pywbem.Uint16(60)
- VSE = pywbem.Uint16(61)
- TPF = pywbem.Uint16(62)
- Windows__R__Me = pywbem.Uint16(63)
- Caldera_Open_UNIX = pywbem.Uint16(64)
- OpenBSD = pywbem.Uint16(65)
- Not_Applicable = pywbem.Uint16(66)
- Windows_XP = pywbem.Uint16(67)
- z_OS = pywbem.Uint16(68)
- Microsoft_Windows_Server_2003 = pywbem.Uint16(69)
- Microsoft_Windows_Server_2003_64_Bit = pywbem.Uint16(70)
- Windows_XP_64_Bit = pywbem.Uint16(71)
- Windows_XP_Embedded = pywbem.Uint16(72)
- Windows_Vista = pywbem.Uint16(73)
- Windows_Vista_64_Bit = pywbem.Uint16(74)
- Windows_Embedded_for_Point_of_Service = pywbem.Uint16(75)
- Microsoft_Windows_Server_2008 = pywbem.Uint16(76)
- Microsoft_Windows_Server_2008_64_Bit = pywbem.Uint16(77)
- FreeBSD_64_Bit = pywbem.Uint16(78)
- RedHat_Enterprise_Linux = pywbem.Uint16(79)
- RedHat_Enterprise_Linux_64_Bit = pywbem.Uint16(80)
- Solaris_64_Bit = pywbem.Uint16(81)
- SUSE = pywbem.Uint16(82)
- SUSE_64_Bit = pywbem.Uint16(83)
- SLES = pywbem.Uint16(84)
- SLES_64_Bit = pywbem.Uint16(85)
- Novell_OES = pywbem.Uint16(86)
- Novell_Linux_Desktop = pywbem.Uint16(87)
- Sun_Java_Desktop_System = pywbem.Uint16(88)
- Mandriva = pywbem.Uint16(89)
- Mandriva_64_Bit = pywbem.Uint16(90)
- TurboLinux = pywbem.Uint16(91)
- TurboLinux_64_Bit = pywbem.Uint16(92)
- Ubuntu = pywbem.Uint16(93)
- Ubuntu_64_Bit = pywbem.Uint16(94)
- Debian = pywbem.Uint16(95)
- Debian_64_Bit = pywbem.Uint16(96)
- Linux_2_4_x = pywbem.Uint16(97)
- Linux_2_4_x_64_Bit = pywbem.Uint16(98)
- Linux_2_6_x = pywbem.Uint16(99)
- Linux_2_6_x_64_Bit = pywbem.Uint16(100)
- Linux_64_Bit = pywbem.Uint16(101)
- Other_64_Bit = pywbem.Uint16(102)
- Microsoft_Windows_Server_2008_R2 = pywbem.Uint16(103)
- VMware_ESXi = pywbem.Uint16(104)
- Microsoft_Windows_7 = pywbem.Uint16(105)
- CentOS_32_bit = pywbem.Uint16(106)
- CentOS_64_bit = pywbem.Uint16(107)
- Oracle_Enterprise_Linux_32_bit = pywbem.Uint16(108)
- Oracle_Enterprise_Linux_64_bit = pywbem.Uint16(109)
- eComStation_32_bitx = pywbem.Uint16(110)
-
- class Remove(object):
- Not_installed = pywbem.Uint32(0)
- Successful_removal = pywbem.Uint32(1)
- Failed = pywbem.Uint32(2)
-
- class CommunicationStatus(object):
- Unknown = pywbem.Uint16(0)
- Not_Available = pywbem.Uint16(1)
- Communication_OK = pywbem.Uint16(2)
- Lost_Communication = pywbem.Uint16(3)
- No_Contact = pywbem.Uint16(4)
- # DMTF_Reserved = ..
- # Vendor_Reserved = 0x8000..
-
- class OperationalStatus(object):
- Unknown = pywbem.Uint16(0)
- Other = pywbem.Uint16(1)
- OK = pywbem.Uint16(2)
- Degraded = pywbem.Uint16(3)
- Stressed = pywbem.Uint16(4)
- Predictive_Failure = pywbem.Uint16(5)
- Error = pywbem.Uint16(6)
- Non_Recoverable_Error = pywbem.Uint16(7)
- Starting = pywbem.Uint16(8)
- Stopping = pywbem.Uint16(9)
- Stopped = pywbem.Uint16(10)
- In_Service = pywbem.Uint16(11)
- No_Contact = pywbem.Uint16(12)
- Lost_Communication = pywbem.Uint16(13)
- Aborted = pywbem.Uint16(14)
- Dormant = pywbem.Uint16(15)
- Supporting_Entity_in_Error = pywbem.Uint16(16)
- Completed = pywbem.Uint16(17)
- Power_Mode = pywbem.Uint16(18)
- Relocating = pywbem.Uint16(19)
- # DMTF_Reserved = ..
- # Vendor_Reserved = 0x8000..
-
- class OperatingStatus(object):
- Unknown = pywbem.Uint16(0)
- Not_Available = pywbem.Uint16(1)
- Servicing = pywbem.Uint16(2)
- Starting = pywbem.Uint16(3)
- Stopping = pywbem.Uint16(4)
- Stopped = pywbem.Uint16(5)
- Aborted = pywbem.Uint16(6)
- Dormant = pywbem.Uint16(7)
- Completed = pywbem.Uint16(8)
- Migrating = pywbem.Uint16(9)
- Emigrating = pywbem.Uint16(10)
- Immigrating = pywbem.Uint16(11)
- Snapshotting = pywbem.Uint16(12)
- Shutting_Down = pywbem.Uint16(13)
- In_Test = pywbem.Uint16(14)
- Transitioning = pywbem.Uint16(15)
- In_Service = pywbem.Uint16(16)
- # DMTF_Reserved = ..
- # Vendor_Reserved = 0x8000..
-
- class SoftwareElementState(object):
- Deployable = pywbem.Uint16(0)
- Installable = pywbem.Uint16(1)
- Executable = pywbem.Uint16(2)
- Running = pywbem.Uint16(3)
-
- class PrimaryStatus(object):
- Unknown = pywbem.Uint16(0)
- OK = pywbem.Uint16(1)
- Degraded = pywbem.Uint16(2)
- Error = pywbem.Uint16(3)
- # DMTF_Reserved = ..
- # Vendor_Reserved = 0x8000..
-
- class Install(object):
- Already_installed = pywbem.Uint32(0)
- Successful_installation = pywbem.Uint32(1)
- Failed = pywbem.Uint32(2)
-
diff --git a/src/software/openlmi/software/core/SoftwarePackageChecks.py b/src/software/openlmi/software/core/SoftwarePackageChecks.py
deleted file mode 100644
index 6d39294..0000000
--- a/src/software/openlmi/software/core/SoftwarePackageChecks.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- encoding: utf-8 -*-
-# Software Management Providers
-#
-# Copyright (C) 2012 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: Michal Minar <miminar@redhat.com>
-#
-
-"""
-Just a common functionality related to LMI_SoftwarePackageChecks provider.
-"""
-
-import pywbem
-
-class Values(object):
- class Phase(object):
- In_State = pywbem.Uint16(0)
- Next_State = pywbem.Uint16(1)
diff --git a/src/software/openlmi/software/core/SystemSoftwareCollection.py b/src/software/openlmi/software/core/SystemSoftwareCollection.py
new file mode 100644
index 0000000..b7a320b
--- /dev/null
+++ b/src/software/openlmi/software/core/SystemSoftwareCollection.py
@@ -0,0 +1,63 @@
+# Software Management Providers
+#
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""
+Common utilities concerning SystemSoftwareCollection provider.
+"""
+
+import pywbem
+
+def get_path():
+ """@return instance name with prefilled properties"""
+ op = pywbem.CIMInstanceName(
+ classname="LMI_SystemSoftwareCollection",
+ namespace="root/cimv2")
+ op['InstanceID'] = "LMI:SystemSoftwareCollection"
+ return op
+
+def check_path_property(env, op, prop_name):
+ """
+ Checks, whether prop_name property of op object path is correct.
+ If not, an exception will be risen.
+ """
+ if not prop_name in op:
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
+ "Missing %s key property!" % prop_name)
+ collection = op[prop_name]
+ if not isinstance(collection, pywbem.CIMInstanceName):
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
+ "\"%s\" must be a CIMInstanceName" % prop_name)
+ our_collection = get_path()
+ ch = env.get_cimom_handle()
+ if collection.namespace != our_collection.namespace:
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ 'Namespace of "%s" does not match "%s"' % (
+ prop_name, our_collection.namespace))
+ if not ch.is_subclass(our_collection.namespace,
+ sub=collection.classname,
+ super=our_collection.classname):
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "Class of \"%s\" must be a sublass of %s" % (
+ prop_name, our_collection.classname))
+ if not 'InstanceID' in collection:
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "\"%s\" is missing InstanceID key property", prop_name)
+ if collection['InstanceID'] != our_collection['InstanceID']:
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "InstanceID of \"%s\" does not match \"%s\"" %
+ prop_name, our_collection['InstanceID'])
+ return True
diff --git a/src/software/openlmi/software/core/__init__.py b/src/software/openlmi/software/core/__init__.py
index 2ebe827..61158e1 100644
--- a/src/software/openlmi/software/core/__init__.py
+++ b/src/software/openlmi/software/core/__init__.py
@@ -18,3 +18,9 @@
#
# Authors: Michal Minar <miminar@redhat.com>
#
+
+"""
+Core functionality of particular providers.
+Each provider having functionality useful to others has a submodule
+in this subpackage with the same name except for LMI_ prefix.
+"""
diff --git a/src/software/openlmi/software/util/singletonmixin.py b/src/software/openlmi/software/util/singletonmixin.py
index 8051695..7b26b8b 100644
--- a/src/software/openlmi/software/util/singletonmixin.py
+++ b/src/software/openlmi/software/util/singletonmixin.py
@@ -1,8 +1,9 @@
+#pylint: disable-all
"""
A Python Singleton mixin class that makes use of some of the ideas
found at http://c2.com/cgi/wiki?PythonSingleton. Just inherit
from it and you have a singleton. No code is required in
-subclasses to create singleton behavior -- inheritance from
+subclasses to create singleton behavior -- inheritance from
Singleton is all that is needed.
Singleton creation is threadsafe.
@@ -11,8 +12,8 @@ USAGE:
Just inherit from Singleton. If you need a constructor, include
an __init__() method in your class as you usually would. However,
-if your class is S, you instantiate the singleton using S.getInstance()
-instead of S(). Repeated calls to S.getInstance() return the
+if your class is S, you instantiate the singleton using S.get_instance()
+instead of S(). Repeated calls to S.get_instance() return the
originally-created instance.
For example:
@@ -21,8 +22,8 @@ class S(Singleton):
def __init__(self, a, b=1):
pass
-
-S1 = S.getInstance(1, b=3)
+
+S1 = S.get_instance(1, b=3)
Most of the time, that's all you need to know. However, there are some
@@ -30,46 +31,47 @@ other useful behaviors. Read on for a full description:
1) Getting the singleton:
- S.getInstance()
-
-returns the instance of S. If none exists, it is created.
+ S.get_instance()
+
+returns the instance of S. If none exists, it is created.
2) The usual idiom to construct an instance by calling the class, i.e.
S()
-
-is disabled for the sake of clarity.
-For one thing, the S() syntax means instantiation, but getInstance()
+is disabled for the sake of clarity.
+
+For one thing, the S() syntax means instantiation, but get_instance()
usually does not cause instantiation. So the S() syntax would
be misleading.
-Because of that, if S() were allowed, a programmer who didn't
+Because of that, if S() were allowed, a programmer who didn't
happen to notice the inheritance from Singleton (or who
wasn't fully aware of what a Singleton pattern
-does) might think he was creating a new instance,
+does) might think he was creating a new instance,
which could lead to very unexpected behavior.
So, overall, it is felt that it is better to make things clearer
by requiring the call of a class method that is defined in
-Singleton. An attempt to instantiate via S() will result
+Singleton. An attempt to instantiate via S() will result
in a SingletonException being raised.
3) Use __S.__init__() for instantiation processing,
-since S.getInstance() runs S.__init__(), passing it the args it has received.
+since S.get_instance() runs S.__init__(), passing it the args it has received.
-If no data needs to be passed in at instantiation time, you don't need S.__init__().
+If no data needs to be passed in at instantiation time,
+you don't need S.__init__().
4) If S.__init__(.) requires parameters, include them ONLY in the
-first call to S.getInstance(). If subsequent calls have arguments,
+first call to S.get_instance(). If subsequent calls have arguments,
a SingletonException is raised by default.
If you find it more convenient for subsequent calls to be allowed to
-have arguments, but for those argumentsto be ignored, just include
+have arguments, but for those argumentsto be ignored, just include
'ignoreSubsequent = True' in your class definition, i.e.:
class S(Singleton):
-
+
ignoreSubsequent = True
def __init__(self, a, b=1):
@@ -77,345 +79,392 @@ have arguments, but for those argumentsto be ignored, just include
5) For testing, it is sometimes convenient for all existing singleton
instances to be forgotten, so that new instantiations can occur. For that
-reason, a forgetAllSingletons() function is included. Just call
+reason, a _forget_all_singletons() function is included. Just call
+
+ _forget_all_singletons()
- forgetAllSingletons()
-
and it is as if no earlier instantiations have occurred.
-6) As an implementation detail, classes that inherit
+6) As an implementation detail, classes that inherit
from Singleton may not have their own __new__
-methods. To make sure this requirement is followed,
+methods. To make sure this requirement is followed,
an exception is raised if a Singleton subclass includ
es __new__. This happens at subclass instantiation
time (by means of the MetaSingleton metaclass.
-By Gary Robinson, grobinson@flyfi.com. No rights reserved --
+By Gary Robinson, grobinson@flyfi.com. No rights reserved --
placed in the public domain -- which is only reasonable considering
how much it owes to other people's code and ideas which are in the
-public domain. The idea of using a metaclass came from
-a comment on Gary's blog (see
-http://www.garyrobinson.net/2004/03/python_singleto.html#comments).
+public domain. The idea of using a metaclass came from
+a comment on Gary's blog (see
+http://www.garyrobinson.net/2004/03/python_singleto.html#comments).
Other improvements came from comments and email from other
people who saw it online. (See the blog post and comments
for further credits.)
Not guaranteed to be fit for any particular purpose. Use at your
-own risk.
+own risk.
"""
import threading
class SingletonException(Exception):
+ """
+ Base exception related to singleton handling.
+ """
pass
-_stSingletons = set()
-_lockForSingletons = threading.RLock()
-_lockForSingletonCreation = threading.RLock() # Ensure only one instance of each Singleton
- # class is created. This is not bound to the
- # individual Singleton class since we need to
- # ensure that there is only one mutex for each
- # Singleton class, which would require having
- # a lock when setting up the Singleton class,
- # which is what this is anyway. So, when any
- # Singleton is created, we lock this lock and
- # then we don't need to lock it again for that
- # class.
-
-def _createSingletonInstance(cls, lstArgs, dctKwArgs):
- _lockForSingletonCreation.acquire()
+_ST_SINGLETONS = set()
+_LOCK_FOR_SINGLETONS = threading.RLock()
+# Ensure only one instance of each Singleton class is created. This is not
+# bound to the _LOCK_FOR_SINGLETON_CREATION = threading.RLock() individual
+# Singleton class since we need to ensure that there is only one mutex for each
+# Singleton class, which would require having a lock when setting up the
+# Singleton class, which is what this is anyway. So, when any Singleton is
+# created, we lock this lock and then we don't need to lock it again for that
+# class.
+_LOCK_FOR_SINGLETON_CREATION = threading.RLock()
+
+def _create_singleton_instance(cls, lst_args, dct_kw_args):
+ """
+ Creates singleton instance and stores its class in set.
+ """
+ _LOCK_FOR_SINGLETON_CREATION.acquire()
try:
- if cls._isInstantiated(): # some other thread got here first
- return
-
+ if cls._is_instantiated(): # some other thread got here first
+ return
+
instance = cls.__new__(cls)
try:
- instance.__init__(*lstArgs, **dctKwArgs)
- except TypeError, e:
- if e.message.find('__init__() takes') != -1:
- raise SingletonException, 'If the singleton requires __init__ args, supply them on first call to getInstance().'
+ instance.__init__(*lst_args, **dct_kw_args)
+ except TypeError, exc:
+ if '__init__() takes' in exc.message:
+ raise SingletonException, (
+ 'If the singleton requires __init__ args,'
+ ' supply them on first call to get_instance().')
else:
raise
- cls.cInstance = instance
- _addSingleton(cls)
+ cls.c_instance = instance
+ _add_singleton(cls)
finally:
- _lockForSingletonCreation.release()
+ _LOCK_FOR_SINGLETON_CREATION.release()
-def _addSingleton(cls):
- _lockForSingletons.acquire()
+def _add_singleton(cls):
+ """
+ Adds class to singleton set.
+ """
+ _LOCK_FOR_SINGLETONS.acquire()
try:
- assert cls not in _stSingletons
- _stSingletons.add(cls)
+ assert cls not in _ST_SINGLETONS
+ _ST_SINGLETONS.add(cls)
finally:
- _lockForSingletons.release()
+ _LOCK_FOR_SINGLETONS.release()
-def _removeSingleton(cls):
- _lockForSingletons.acquire()
+def _remove_singleton(cls):
+ """
+ Removes class from singleton set.
+ """
+ _LOCK_FOR_SINGLETONS.acquire()
try:
- if cls in _stSingletons:
- _stSingletons.remove(cls)
+ if cls in _ST_SINGLETONS:
+ _ST_SINGLETONS.remove(cls)
finally:
- _lockForSingletons.release()
-
-def forgetAllSingletons():
- '''This is useful in tests, since it is hard to know which singletons need to be cleared to make a test work.'''
- _lockForSingletons.acquire()
+ _LOCK_FOR_SINGLETONS.release()
+
+def _forget_all_singletons():
+ '''
+ This is useful in tests, since it is hard to know which singletons need
+ to be cleared to make a test work.
+ '''
+ _LOCK_FOR_SINGLETONS.acquire()
try:
- for cls in _stSingletons.copy():
- cls._forgetClassInstanceReferenceForTesting()
+ for cls in _ST_SINGLETONS.copy():
+ cls._forget_class_instance_reference_for_testing()
# Might have created some Singletons in the process of tearing down.
# Try one more time - there should be a limit to this.
- iNumSingletons = len(_stSingletons)
- if len(_stSingletons) > 0:
- for cls in _stSingletons.copy():
- cls._forgetClassInstanceReferenceForTesting()
- iNumSingletons -= 1
- assert iNumSingletons == len(_stSingletons), 'Added a singleton while destroying ' + str(cls)
- assert len(_stSingletons) == 0, _stSingletons
+ i_num_singletons = len(_ST_SINGLETONS)
+ if len(_ST_SINGLETONS) > 0:
+ for cls in _ST_SINGLETONS.copy():
+ cls._forget_class_instance_reference_for_testing()
+ i_num_singletons -= 1
+ assert i_num_singletons == len(_ST_SINGLETONS), \
+ 'Added a singleton while destroying ' + str(cls)
+ assert len(_ST_SINGLETONS) == 0, _ST_SINGLETONS
finally:
- _lockForSingletons.release()
+ _LOCK_FOR_SINGLETONS.release()
class MetaSingleton(type):
- def __new__(metaclass, strName, tupBases, dct):
+ """
+ Metaclass for Singleton base class.
+ """
+ def __new__(mcs, str_name, tup_bases, dct):
if dct.has_key('__new__'):
raise SingletonException, 'Can not override __new__ in a Singleton'
- return super(MetaSingleton, metaclass).__new__(metaclass, strName, tupBases, dct)
-
- def __call__(cls, *lstArgs, **dictArgs):
- raise SingletonException, 'Singletons may only be instantiated through getInstance()'
-
+ return super(MetaSingleton, mcs).__new__(
+ mcs, str_name, tup_bases, dct)
+
+ def __call__(cls, *lst_args, **dictArgs):
+ raise SingletonException, \
+ 'Singletons may only be instantiated through get_instance()'
+
class Singleton(object):
+ """
+ Base class for all singletons.
+ """
__metaclass__ = MetaSingleton
-
- def getInstance(cls, *lstArgs, **dctKwArgs):
+
+ def get_instance(cls, *lst_args, **dct_kw_args):
"""
Call this to instantiate an instance or retrieve the existing instance.
If the singleton requires args to be instantiated, include them the first
- time you call getInstance.
+ time you call get_instance.
"""
- if cls._isInstantiated():
- if (lstArgs or dctKwArgs) and not hasattr(cls, 'ignoreSubsequent'):
- raise SingletonException, 'Singleton already instantiated, but getInstance() called with args.'
+ if cls._is_instantiated():
+ if ( (lst_args or dct_kw_args)
+ and not hasattr(cls, 'ignoreSubsequent')):
+ raise SingletonException, (
+ 'Singleton already instantiated, but get_instance()'
+ ' called with args.')
else:
- _createSingletonInstance(cls, lstArgs, dctKwArgs)
-
- return cls.cInstance
- getInstance = classmethod(getInstance)
-
- def _isInstantiated(cls):
- # Don't use hasattr(cls, 'cInstance'), because that screws things up if there is a singleton that
- # extends another singleton. hasattr looks in the base class if it doesn't find in subclass.
- return 'cInstance' in cls.__dict__
- _isInstantiated = classmethod(_isInstantiated)
+ _create_singleton_instance(cls, lst_args, dct_kw_args)
+
+ return cls.c_instance #pylint: disable=E1101
+ get_instance = classmethod(get_instance)
+
+ def _is_instantiated(cls):
+ """
+ Don't use hasattr(cls, 'c_instance'), because that screws things
+ up if there is a singleton that extends another singleton.
+ hasattr looks in the base class if it doesn't find in subclass.
+ """
+ return 'c_instance' in cls.__dict__
+ _is_instantiated = classmethod(_is_instantiated)
# This can be handy for public use also
- isInstantiated = _isInstantiated
+ isInstantiated = _is_instantiated
- def _forgetClassInstanceReferenceForTesting(cls):
+ def _forget_class_instance_reference_for_testing(cls):
"""
- This is designed for convenience in testing -- sometimes you
+ This is designed for convenience in testing -- sometimes you
want to get rid of a singleton during test code to see what
- happens when you call getInstance() under a new situation.
-
+ happens when you call get_instance() under a new situation.
+
To really delete the object, all external references to it
also need to be deleted.
"""
try:
- if hasattr(cls.cInstance, '_prepareToForgetSingleton'):
+ if hasattr(cls.c_instance, '_prepare_to_forget_singleton'):
# tell instance to release anything it might be holding onto.
- cls.cInstance._prepareToForgetSingleton()
- del cls.cInstance
- _removeSingleton(cls)
+ cls.c_instance._prepare_to_forget_singleton()
+ del cls.c_instance
+ _remove_singleton(cls)
except AttributeError:
- # run up the chain of base classes until we find the one that has the instance
- # and then delete it there
- for baseClass in cls.__bases__:
- if issubclass(baseClass, Singleton):
- baseClass._forgetClassInstanceReferenceForTesting()
- _forgetClassInstanceReferenceForTesting = classmethod(_forgetClassInstanceReferenceForTesting)
-
-
-if __name__ == '__main__':
+ # run up the chain of base classes until we find the one that has
+ # the instance and then delete it there
+ for base_class in cls.__bases__:
+ if issubclass(base_class, Singleton):
+ base_class._forget_class_instance_reference_for_testing()
+ _forget_class_instance_reference_for_testing = classmethod(
+ _forget_class_instance_reference_for_testing)
+
+
+if __name__ == '__main__':
import unittest
import time
-
- class singletonmixin_Public_TestCase(unittest.TestCase):
- def testReturnsSameObject(self):
+
+ class SingletonMixinPublicTestCase(unittest.TestCase):
+ """
+ TestCase for singleton class.
+ """
+ def testReturnsSameObject(self): #pylint: disable=C0103
"""
- Demonstrates normal use -- just call getInstance and it returns a singleton instance
+ Demonstrates normal use -- just call get_instance and it returns a singleton instance
"""
-
- class A(Singleton):
+
+ class Foo(Singleton):
+ """Singleton child class."""
def __init__(self):
- super(A, self).__init__()
-
- a1 = A.getInstance()
- a2 = A.getInstance()
+ super(Foo, self).__init__()
+
+ a1 = Foo.get_instance()
+ a2 = Foo.get_instance()
self.assertEquals(id(a1), id(a2))
-
- def testInstantiateWithMultiArgConstructor(self):
+
+ def testInstantiateWithMultiArgConstructor(self):#pylint: disable=C0103
"""
If the singleton needs args to construct, include them in the first
call to get instances.
"""
-
- class B(Singleton):
-
+
+ class Bar(Singleton):
+ """Singleton child class."""
+
def __init__(self, arg1, arg2):
- super(B, self).__init__()
+ super(Bar, self).__init__()
self.arg1 = arg1
self.arg2 = arg2
-
- b1 = B.getInstance('arg1 value', 'arg2 value')
- b2 = B.getInstance()
+
+ b1 = Bar.get_instance('arg1 value', 'arg2 value')
+ b2 = Bar.get_instance()
self.assertEquals(b1.arg1, 'arg1 value')
self.assertEquals(b1.arg2, 'arg2 value')
self.assertEquals(id(b1), id(b2))
-
+
def testInstantiateWithKeywordArg(self):
-
- class B(Singleton):
-
+ """
+ Test instantiation with keyword arguments.
+ """
+
+ class Baz(Singleton):
+ """Singleton child class."""
def __init__(self, arg1=5):
- super(B, self).__init__()
+ super(Baz, self).__init__()
self.arg1 = arg1
-
- b1 = B.getInstance('arg1 value')
- b2 = B.getInstance()
+
+ b1 = Baz.get_instance('arg1 value')
+ b2 = Baz.get_instance()
self.assertEquals(b1.arg1, 'arg1 value')
self.assertEquals(id(b1), id(b2))
-
+
def testTryToInstantiateWithoutNeededArgs(self):
-
- class B(Singleton):
-
+ """
+ This tests, improper instantiation.
+ """
+
+ class Foo(Singleton):
+ """Singleton child class."""
def __init__(self, arg1, arg2):
- super(B, self).__init__()
+ super(Foo, self).__init__()
self.arg1 = arg1
self.arg2 = arg2
-
- self.assertRaises(SingletonException, B.getInstance)
-
+
+ self.assertRaises(SingletonException, Foo.get_instance)
+
def testPassTypeErrorIfAllArgsThere(self):
"""
- Make sure the test for capturing missing args doesn't interfere with a normal TypeError.
+ Make sure the test for capturing missing args doesn't interfere
+ with a normal TypeError.
"""
- class B(Singleton):
-
+ class Bar(Singleton):
+ """Singleton child class."""
def __init__(self, arg1, arg2):
- super(B, self).__init__()
+ super(Bar, self).__init__()
self.arg1 = arg1
self.arg2 = arg2
raise TypeError, 'some type error'
-
- self.assertRaises(TypeError, B.getInstance, 1, 2)
-
+
+ self.assertRaises(TypeError, Bar.get_instance, 1, 2)
+
def testTryToInstantiateWithoutGetInstance(self):
"""
Demonstrates that singletons can ONLY be instantiated through
- getInstance, as long as they call Singleton.__init__ during construction.
-
- If this check is not required, you don't need to call Singleton.__init__().
+ get_instance, as long as they call Singleton.__init__ during
+ construction.
+
+ If this check is not required, you don't need to call
+ Singleton.__init__().
"""
-
- class A(Singleton):
+
+ class A(Singleton):
def __init__(self):
super(A, self).__init__()
-
+
self.assertRaises(SingletonException, A)
-
+
def testDontAllowNew(self):
-
+
def instantiatedAnIllegalClass():
- class A(Singleton):
+ class A(Singleton):
def __init__(self):
super(A, self).__init__()
-
- def __new__(metaclass, strName, tupBases, dct):
- return super(MetaSingleton, metaclass).__new__(metaclass, strName, tupBases, dct)
-
+
+ def __new__(metaclass, str_name, tup_bases, dct):
+ return super(MetaSingleton, metaclass).__new__(
+ metaclass, str_name, tup_bases, dct)
+
self.assertRaises(SingletonException, instantiatedAnIllegalClass)
-
-
+
+
def testDontAllowArgsAfterConstruction(self):
- class B(Singleton):
-
+ class B(Singleton):
+
def __init__(self, arg1, arg2):
super(B, self).__init__()
self.arg1 = arg1
self.arg2 = arg2
-
- B.getInstance('arg1 value', 'arg2 value')
+
+ B.get_instance('arg1 value', 'arg2 value')
self.assertRaises(SingletonException, B, 'arg1 value', 'arg2 value')
-
+
def test_forgetClassInstanceReferenceForTesting(self):
- class A(Singleton):
+ class A(Singleton):
def __init__(self):
super(A, self).__init__()
- class B(A):
+ class B(A):
def __init__(self):
super(B, self).__init__()
-
- # check that changing the class after forgetting the instance produces
- # an instance of the new class
- a = A.getInstance()
+
+ # check that changing the class after forgetting the instance
+ # produces an instance of the new class
+ a = A.get_instance()
assert a.__class__.__name__ == 'A'
- A._forgetClassInstanceReferenceForTesting()
- b = B.getInstance()
+ A._forget_class_instance_reference_for_testing()
+ b = B.get_instance()
assert b.__class__.__name__ == 'B'
-
- # check that invoking the 'forget' on a subclass still deletes the instance
- B._forgetClassInstanceReferenceForTesting()
- a = A.getInstance()
- B._forgetClassInstanceReferenceForTesting()
- b = B.getInstance()
+
+ # check that invoking the 'forget' on a subclass still deletes
+ # the instance
+ B._forget_class_instance_reference_for_testing()
+ a = A.get_instance()
+ B._forget_class_instance_reference_for_testing()
+ b = B.get_instance()
assert b.__class__.__name__ == 'B'
-
+
def test_forgetAllSingletons(self):
# Should work if there are no singletons
- forgetAllSingletons()
-
+ _forget_all_singletons()
+
class A(Singleton):
ciInitCount = 0
def __init__(self):
super(A, self).__init__()
A.ciInitCount += 1
-
- A.getInstance()
+
+ A.get_instance()
self.assertEqual(A.ciInitCount, 1)
-
- A.getInstance()
+
+ A.get_instance()
self.assertEqual(A.ciInitCount, 1)
-
- forgetAllSingletons()
- A.getInstance()
+
+ _forget_all_singletons()
+ A.get_instance()
self.assertEqual(A.ciInitCount, 2)
-
+
def test_threadedCreation(self):
- # Check that only one Singleton is created even if multiple
- # threads try at the same time. If fails, would see assert in _addSingleton
+ # Check that only one Singleton is created even if multiple threads
+ # try at the same time. If fails, would see assert in _add_singleton
class Test_Singleton(Singleton):
def __init__(self):
super(Test_Singleton, self).__init__()
-
+
class Test_SingletonThread(threading.Thread):
def __init__(self, fTargetTime):
super(Test_SingletonThread, self).__init__()
self._fTargetTime = fTargetTime
self._eException = None
-
+
def run(self):
try:
fSleepTime = self._fTargetTime - time.time()
if fSleepTime > 0:
time.sleep(fSleepTime)
- Test_Singleton.getInstance()
- except Exception, e:
- self._eException = e
-
+ Test_Singleton.get_instance()
+ except Exception, exc:
+ self._eException = exc
+
fTargetTime = time.time() + 0.1
lstThreads = []
for _ in xrange(100):
@@ -429,80 +478,83 @@ if __name__ == '__main__':
eException = t._eException
if eException:
raise eException
-
+
def testNoInit(self):
"""
Demonstrates use with a class not defining __init__
"""
-
- class A(Singleton):
+
+ class A(Singleton):
pass
-
+
#INTENTIONALLY UNDEFINED:
#def __init__(self):
# super(A, self).__init__()
-
- A.getInstance() #Make sure no exception is raised
-
+
+ A.get_instance() #Make sure no exception is raised
+
def testMultipleGetInstancesWithArgs(self):
-
+
class A(Singleton):
-
+
ignoreSubsequent = True
-
+
def __init__(self, a, b=1):
pass
-
- a1 = A.getInstance(1)
- a2 = A.getInstance(2) # ignores the second call because of ignoreSubsequent
-
+
+ a1 = A.get_instance(1)
+ # ignores the second call because of ignoreSubsequent
+ a2 = A.get_instance(2)
+
class B(Singleton):
-
+
def __init__(self, a, b=1):
pass
-
- b1 = B.getInstance(1)
- self.assertRaises(SingletonException, B.getInstance, 2) # No ignoreSubsequent included
-
+
+ b1 = B.get_instance(1)
+ # No ignoreSubsequent included
+ self.assertRaises(SingletonException, B.get_instance, 2)
+
class C(Singleton):
-
+
def __init__(self, a=1):
pass
-
- c1 = C.getInstance(a=1)
- self.assertRaises(SingletonException, C.getInstance, a=2) # No ignoreSubsequent included
-
+
+ c1 = C.get_instance(a=1)
+ # No ignoreSubsequent included
+ self.assertRaises(SingletonException, C.get_instance, a=2)
+
def testInheritance(self):
- """
+ """
It's sometimes said that you can't subclass a singleton (see, for instance,
http://steve.yegge.googlepages.com/singleton-considered-stupid point e). This
test shows that at least rudimentary subclassing works fine for us.
"""
-
+
class A(Singleton):
-
- def setX(self, x):
+
+ def set_x(self, x):
self.x = x
-
+
def setZ(self, z):
raise NotImplementedError
-
+
class B(A):
-
- def setX(self, x):
+
+ def set_x(self, x):
self.x = -x
-
- def setY(self, y):
+
+ def set_y(self, y):
self.y = y
-
- a = A.getInstance()
- a.setX(5)
- b = B.getInstance()
- b.setX(5)
- b.setY(50)
+
+ a = A.get_instance()
+ a.set_x(5)
+ b = B.get_instance()
+ b.set_x(5)
+ b.set_y(50)
self.assertEqual((a.x, b.x, b.y), (5, -5, 50))
- self.assertRaises(AttributeError, eval, 'a.setY', {}, locals())
+ self.assertRaises(AttributeError, eval, 'a.set_y', {}, locals())
self.assertRaises(NotImplementedError, b.setZ, 500)
unittest.main()
-
+
diff --git a/src/software/openlmi/software/yumdb/__init__.py b/src/software/openlmi/software/yumdb/__init__.py
index 0dc9050..dc77689 100644
--- a/src/software/openlmi/software/yumdb/__init__.py
+++ b/src/software/openlmi/software/yumdb/__init__.py
@@ -235,21 +235,23 @@ class YumDB(singletonmixin.Singleton):
"""
Shut down the YumWorker process.
"""
- cmpi_logging.logger.info('YumDB: cleanup called')
- if self._process:
+ if self._process is not None:
cmpi_logging.logger.info('YumDB: terminating YumWorker')
self._process.uplink.put(None) # terminating command
self._process.uplink.join()
self._process.join()
cmpi_logging.logger.info('YumDB: YumWorker terminated')
self._process = None
+ else:
+ cmpi_logging.logger.warn("YunDB: clean_up called, when process"
+ " not initialized!")
@cmpi_logging.trace_method
def get_package_list(self, kind,
allow_duplicates=False,
sort=False):
"""
- @param kind is one of: {"installed", "available", "all"}
+ @param kind is one of: jobs.YumGetPackageList.SUPPORTED_KINDS
@param allow_duplicates says, whether to list all found versions
of single package
@return [pkg1, pkg2, ...], pkgi is instance of yumdb.PackageInfo
diff --git a/src/software/openlmi/software/yumdb/jobs.py b/src/software/openlmi/software/yumdb/jobs.py
index 1fdfbe3..f280a11 100644
--- a/src/software/openlmi/software/yumdb/jobs.py
+++ b/src/software/openlmi/software/yumdb/jobs.py
@@ -100,7 +100,18 @@ class YumGetPackageList(YumJob): #pylint: disable=R0903
"""
Job requesing a list of packages.
Arguments:
- kind - supported values are in SUPPORTED_KINDS tuple
+ kind - supported values are in SUPPORTED_KINDS tuple
+ * installed lists all installed packages; more packages with
+ the same name can be installed varying in their architecture
+ * avail_notinst lists all available, not installed packages;
+ allow_duplicates must be True to include older packages (but still
+ available)
+ * avail_reinst lists all installed packages, that are available;
+ package can be installed, but not available anymore due to updates
+ of repository, where only the newest packages are kept
+ * available lists a union of avail_notinst and avail_reinst
+ * all lists union of installed and avail_notinst
+
allow_duplicates - whether multiple packages can be present
in result for single (name, arch) of package differing
in their version
@@ -109,7 +120,8 @@ class YumGetPackageList(YumJob): #pylint: disable=R0903
"""
__slots__ = ('kind', 'allow_duplicates', 'sort')
- SUPPORTED_KINDS = ('installed', 'available', 'all')
+ SUPPORTED_KINDS = ( 'installed', 'available', 'avail_reinst'
+ , 'avail_notinst', 'all')
def __init__(self, kind, allow_duplicates, sort=False):
YumJob.__init__(self)
diff --git a/src/software/openlmi/software/yumdb/process.py b/src/software/openlmi/software/yumdb/process.py
index c247de7..cd70407 100644
--- a/src/software/openlmi/software/yumdb/process.py
+++ b/src/software/openlmi/software/yumdb/process.py
@@ -339,7 +339,7 @@ class YumWorker(Process):
_logger().warn("lookup of package %s with id=%d failed, trying"
" to query database", pkg, pkg.pkgid)
result = self._handle_filter_packages(
- 'installed' if pkg.installed else 'available',
+ 'installed' if pkg.installed else 'avail_reinst',
allow_duplicates=False,
sort=False,
transform=False,
@@ -428,11 +428,23 @@ class YumWorker(Process):
or original ones
@return [pkg1, pkg2, ...]
"""
- pkglist = self._yum_base.doPackageLists(kind, showdups=allow_duplicates)
- if kind == 'all':
- result = pkglist.available + pkglist.installed
+ if kind == 'avail_notinst':
+ what = 'available'
+ elif kind == 'available':
+ what = 'all'
+ elif kind == 'avail_reinst':
+ what = 'all'
else:
- result = getattr(pkglist, kind)
+ what = kind
+ pkglist = self._yum_base.doPackageLists(what, showdups=allow_duplicates)
+ if kind == 'all':
+ result = pkglist.available + pkglist.installed
+ elif kind == 'available':
+ result = pkglist.available + pkglist.reinstall_available
+ elif kind == 'avail_reinst':
+ result = pkglist.reinstall_available
+ else: # get installed or available
+ result = getattr(pkglist, what)
if sort is True:
result.sort()
_logger().debug("returning %s packages", len(result))