diff options
author | Michal Minar <miminar@redhat.com> | 2012-10-03 19:14:42 +0200 |
---|---|---|
committer | Michal Minar <miminar@redhat.com> | 2012-10-03 19:14:42 +0200 |
commit | 35411e597042f1a88679a6f1a8fe84f9b660aede (patch) | |
tree | 6f7011abad5b44a92ca0a0194fdc43fc4f8205f2 /src | |
parent | 3c719d73efc1902edfc79d0d6de6b14670addd26 (diff) | |
download | openlmi-providers-35411e597042f1a88679a6f1a8fe84f9b660aede.tar.gz openlmi-providers-35411e597042f1a88679a6f1a8fe84f9b660aede.tar.xz openlmi-providers-35411e597042f1a88679a6f1a8fe84f9b660aede.zip |
working associations
added LMI_YumPackageFile as association between LMI_YumPackage
and LMI_FileCheck
using overrides in mof
Diffstat (limited to 'src')
-rw-r--r-- | src/yum/providers/LMI_YumInstalledPackage.py | 12 | ||||
-rw-r--r-- | src/yum/providers/LMI_YumPackage.py | 2 | ||||
-rw-r--r-- | src/yum/providers/LMI_YumPackageFile.py | 301 | ||||
-rw-r--r-- | src/yum/providers/util/common.py | 115 |
4 files changed, 366 insertions, 64 deletions
diff --git a/src/yum/providers/LMI_YumInstalledPackage.py b/src/yum/providers/LMI_YumInstalledPackage.py index 37a3afe..cf956aa 100644 --- a/src/yum/providers/LMI_YumInstalledPackage.py +++ b/src/yum/providers/LMI_YumInstalledPackage.py @@ -31,9 +31,9 @@ from util.common import * def get_computer_system_op(): return pywbem.CIMInstanceName( - classname='Linux_ComputerSystem', + classname='CIM_ComputerSystem', keybindings={ - "CreationClassName": "Linux_ComputerSystem" + "CreationClassName": "CIM_ComputerSystem" , "Name" : socket.gethostname() }, namespace="root/cimv2") @@ -81,7 +81,7 @@ class LMI_YumInstalledPackage(CIMProvider2): raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, "Unknown \"System\"") with YumDB.getInstance(env): - pkg = object_path2pkg(env, model['Software']) + pkg = YumPackage.object_path2pkg(env, model['Software']) model['Software'] = pkg2model(pkg, env, True) return model @@ -202,7 +202,7 @@ class LMI_YumInstalledPackage(CIMProvider2): "Unknown \"System\"") with YumDB.getInstance(env) as yb: - pkg = object_path2pkg(env, instance_name["Software"]) + pkg = YumPackage.object_path2pkg(env, instance_name["Software"]) logger.log_info('removing package "%s"' % pkg.nevra) yb.remove(pkg) yb.buildTransaction() @@ -277,7 +277,7 @@ class LMI_YumInstalledPackage(CIMProvider2): # of enum_instances, just leave the code below unaltered. if ch.is_subclass(object_name.namespace, sub=object_name.classname, - super='LMI_ComputerSystem') or \ + super='CIM_ComputerSystem') or \ ch.is_subclass(object_name.namespace, sub=object_name.classname, super='LMI_YumPackage'): @@ -386,7 +386,7 @@ class LMI_YumInstalledPackage(CIMProvider2): "Unknown \"System\"") with YumDB.getInstance(env) as yb: - orig = object_path2pkg(env, object_name['Software']) + orig = YumPackage.object_path2pkg(env, object_name['Software']) evr_str = [] for name, param in ( diff --git a/src/yum/providers/LMI_YumPackage.py b/src/yum/providers/LMI_YumPackage.py index 5a9750b..427e7fa 100644 --- a/src/yum/providers/LMI_YumPackage.py +++ b/src/yum/providers/LMI_YumPackage.py @@ -72,7 +72,7 @@ class LMI_YumPackage(CIMProvider2): % self.__class__.__name__) with YumDB.getInstance(env): - pkg = object_path2pkg(env, model.path, 'all') + pkg = YumPackage.object_path2pkg(env, model.path, 'all') return pkg2model(pkg, env, keys_only=False, model=model) def enum_instances(self, env, model, keys_only): diff --git a/src/yum/providers/LMI_YumPackageFile.py b/src/yum/providers/LMI_YumPackageFile.py new file mode 100644 index 0000000..a50d9a9 --- /dev/null +++ b/src/yum/providers/LMI_YumPackageFile.py @@ -0,0 +1,301 @@ +# 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_YumPackageFile + +Instruments the CIM class LMI_YumPackageFile + +""" + +import pywbem +from pywbem.cim_provider2 import CIMProvider2 +from LMI_YumFileCheck import filecheck2model +from LMI_YumPackage import pkg2model +from util.common import * + +class LMI_YumPackageFile(CIMProvider2): + """Instrument the CIM class LMI_YumPackageFile + + 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. + + """ + + def __init__ (self, env): + logger = env.get_logger() + logger.log_debug('Initializing provider %s from %s' \ + % (self.__class__.__name__, __file__)) + + 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) + + """ + + logger = env.get_logger() + logger.log_debug('Entering %s.get_instance()' \ + % self.__class__.__name__) + + vpkg = YumCheckFile.object_path2yumcheck(env, model['Check']) + model['Check'] = filecheck2model(vpkg, model['Check']['Name'], + env, keys_only=True) + model['Element'] = pkg2model(vpkg.po, env, keys_only=True) + return model + + 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) + + """ + + logger = env.get_logger() + logger.log_debug('Entering %s.enum_instances()' \ + % self.__class__.__name__) + + # 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}) + + while False: # TODO more instances? + # TODO fetch system resource + # Key properties + #model['Check'] = pywbem.CIMInstanceName(classname='LMI_YumFileCheck', ...) # TODO (type = REF (pywbem.CIMInstanceName(classname='LMI_YumFileCheck', ...)) + #model['Element'] = pywbem.CIMInstanceName(classname='LMI_YumPackage', ...) # TODO (type = REF (pywbem.CIMInstanceName(classname='LMI_YumPackage', ...)) + if keys_only: + yield model + else: + try: + yield self.get_instance(env, model) + except pywbem.CIMError, (num, msg): + if num not in (pywbem.CIM_ERR_NOT_FOUND, + pywbem.CIM_ERR_ACCESS_DENIED): + raise + + 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) + + """ + + logger = env.get_logger() + logger.log_debug('Entering %s.set_instance()' \ + % self.__class__.__name__) + # TODO create or modify the instance + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED) # Remove to implement + return instance + + 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) + + """ + + logger = env.get_logger() + logger.log_debug('Entering %s.delete_instance()' \ + % self.__class__.__name__) + + # TODO delete the resource + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED) # Remove to implement + + 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) + + """ + + logger = env.get_logger() + logger.log_debug('Entering %s.references()' \ + % self.__class__.__name__) + ch = 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(env): + if ( (not role or role.lower() == 'element') + and ch.is_subclass(object_name.namespace, + sub=object_name.classname, + super='LMI_YumPackage')): + filecheck_model = pywbem.CIMInstanceName( + classname='LMI_YumFileCheck', + namespace="root/cimv2", + host=model.path.host) + model['Element'] = object_name + + pkg = YumPackage.object_path2pkg(env, object_name) + vpkg = yum.packages._RPMVerifyPackage( + pkg, pkg.hdr.fiFromHeader(), + pkg.yumdb_info.checksum_type, [], True) + for fc in vpkg: + model['Check'] = filecheck2model( + vpkg, fc.filename, env, keys_only=True, + model=filecheck_model) + yield model + + if ( (not role or role.lower() == 'check') + and ch.is_subclass(object_name.namespace, + sub=object_name.classname, + super='LMI_YumFileCheck')): + model['Check'] = object_name + + vpkg = YumFileCheck.object_path2yumcheck(env, object_name) + model['Element'] = pkg2model( + vpkg.po, env, keys_only=True) + yield model + + class Values(object): + class Phase(object): + In_State = pywbem.Uint16(0) + Next_State = pywbem.Uint16(1) + +## end of class LMI_YumPackageFileProvider + +## get_providers() for associating CIM Class Name to python provider class name + +def get_providers(env): + lmi_yumpackagefile_prov = LMI_YumPackageFile(env) + return {'LMI_YumPackageFile': lmi_yumpackagefile_prov} diff --git a/src/yum/providers/util/common.py b/src/yum/providers/util/common.py index 7d918a4..f70d22b 100644 --- a/src/yum/providers/util/common.py +++ b/src/yum/providers/util/common.py @@ -168,63 +168,6 @@ def match_pkg(pkg, **kwargs): return False return True -def object_path2pkg(env, op, package_list='installed'): - """ - @param package_list one of {'installed', 'all', 'available'} - says, where to look for given package - """ - if not isinstance(op, pywbem.CIMInstanceName): - raise TypeError("op must be an instance of CIMInstanceName") - if not isinstance(package_list, basestring): - raise TypeError("package_list must be a string") - if not package_list in ('installed', 'all', 'available'): - raise ValueError('unsupported package list "%s"'%package_list) - - tos = get_target_operating_system()[0] - if ( not op['Name'] or not op['SoftwareElementID'] - or not op['SoftwareElementID'].startswith(op['Name']) - or op['SoftwareElementID'].find(op['Version']) == -1): - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, "Wrong keys.") -# if op['SoftwareElementState'] not in ("2", 2): -# raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, -# "Only \"Executable\" software element state supported") - if not check_target_operating_system(op['TargetOperatingSystem']): - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, - "Wrong target operating system.") - if not op['Name'] or not op['Version']: - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, - 'Both "Name" and "Version" must be given') - m = re_nevra.match(op['SoftwareElementID']) - if not m: - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, - "Wrong SotwareElementID. Expected valid nevra" - " (name-epoch:version-release.arch).") - if op['Version'] != m.group('ver'): - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, - "Version does not match version part in SoftwareElementID.") - kwargs = dict((k, m.group(k)) for k in - ('name', 'epoch', 'ver', 'rel', 'arch')) - with YumDB.getInstance(env) as yb: - if ( package_list == 'installed' - and not yb.rpmdb.installed(**kwargs)): - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, - "Package not installed") - - pl = yb.doPackageLists(package_list, - showdups=package_list != 'installed') - if package_list != 'all': - pl = getattr(pl, package_list) - else: - # NOTE: available ∩ installed = ∅ - pl = itertools.chain(pl.available, pl.installed) - exact,_,_ = yum.packages.parsePackages(pl, [op['Name']]) - for pkg in yum.misc.unique(exact): - if pkg.evra == m.group('evra'): break - else: - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, - "No matching package found") - return pkg - class YumPackage: """ Just a namespace for common function related to YumPackage provider. @@ -588,6 +531,64 @@ class YumPackage: return pywbem.Uint16(res) @staticmethod + def object_path2pkg(env, op, package_list='installed'): + """ + @param package_list one of {'installed', 'all', 'available'} + says, where to look for given package + """ + if not isinstance(op, pywbem.CIMInstanceName): + raise TypeError("op must be an instance of CIMInstanceName") + if not isinstance(package_list, basestring): + raise TypeError("package_list must be a string") + if not package_list in ('installed', 'all', 'available'): + raise ValueError('unsupported package list "%s"'%package_list) + + tos = get_target_operating_system()[0] + if ( not op['Name'] or not op['SoftwareElementID'] + or not op['SoftwareElementID'].startswith(op['Name']) + or op['SoftwareElementID'].find(op['Version']) == -1): + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, "Wrong keys.") +# if op['SoftwareElementState'] not in ("2", 2): +# raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, +# "Only \"Executable\" software element state supported") + if not check_target_operating_system(op['TargetOperatingSystem']): + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "Wrong target operating system.") + if not op['Name'] or not op['Version']: + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + 'Both "Name" and "Version" must be given') + m = re_nevra.match(op['SoftwareElementID']) + if not m: + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "Wrong SotwareElementID. Expected valid nevra" + " (name-epoch:version-release.arch).") + if op['Version'] != m.group('ver'): + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "Version does not match version part in SoftwareElementID.") + kwargs = dict((k, m.group(k)) for k in + ('name', 'epoch', 'ver', 'rel', 'arch')) + with YumDB.getInstance(env) as yb: + if ( package_list == 'installed' + and not yb.rpmdb.installed(**kwargs)): + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "Package not installed") + + pl = yb.doPackageLists(package_list, + showdups=package_list != 'installed') + if package_list != 'all': + pl = getattr(pl, package_list) + else: + # NOTE: available ∩ installed = ∅ + pl = itertools.chain(pl.available, pl.installed) + exact,_,_ = yum.packages.parsePackages(pl, [op['Name']]) + for pkg in yum.misc.unique(exact): + if pkg.evra == m.group('evra'): break + else: + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "No matching package found") + return pkg + + @staticmethod def pkg2model_wrapper(namespace, classname): """ @return a function that transforms YumAvailablePackage object |