From 4ef9ef7772d2f06f924ab6c6d23f727aa36a825a Mon Sep 17 00:00:00 2001 From: Michal Minar Date: Thu, 4 Oct 2012 14:23:43 +0200 Subject: fixed check_integrity method made more generic checking of System property of YumInstalledPackage object paths --- src/yum/providers/LMI_YumFileCheck.py | 119 ++++++++++++++------------- src/yum/providers/LMI_YumInstalledPackage.py | 37 ++------- src/yum/providers/LMI_YumPackageFile.py | 2 +- src/yum/providers/util/common.py | 60 ++++++++++++-- 4 files changed, 124 insertions(+), 94 deletions(-) (limited to 'src') diff --git a/src/yum/providers/LMI_YumFileCheck.py b/src/yum/providers/LMI_YumFileCheck.py index c5e29bc..7b11af9 100644 --- a/src/yum/providers/LMI_YumFileCheck.py +++ b/src/yum/providers/LMI_YumFileCheck.py @@ -29,12 +29,12 @@ filecheck2model = YumFileCheck.filecheck_wrapper( 'root/cimv2', 'LMI_YumFileCheck') class LMI_YumFileCheck(CIMProvider2): - """Instrument the CIM class LMI_YumFileCheck + """Instrument the CIM class LMI_YumFileCheck 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): @@ -48,24 +48,24 @@ class LMI_YumFileCheck(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) """ - + logger = env.get_logger() logger.log_debug('Entering %s.get_instance()' \ % self.__class__.__name__) @@ -79,17 +79,17 @@ class LMI_YumFileCheck(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. @@ -101,7 +101,7 @@ class LMI_YumFileCheck(CIMProvider2): logger = env.get_logger() logger.log_debug('Entering %s.enum_instances()' \ % self.__class__.__name__) - + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED) # Remove to implement def set_instance(self, env, instance, modify_existing): @@ -109,22 +109,22 @@ class LMI_YumFileCheck(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) @@ -143,22 +143,22 @@ class LMI_YumFileCheck(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) - """ + """ logger = env.get_logger() logger.log_debug('Entering %s.delete_instance()' \ @@ -166,7 +166,7 @@ class LMI_YumFileCheck(CIMProvider2): # TODO delete the resource raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED) # Remove to implement - + def cim_method_invoke(self, env, object_name): """Implements LMI_YumFileCheck.Invoke() @@ -181,11 +181,11 @@ class LMI_YumFileCheck(CIMProvider2): 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() + 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) @@ -195,11 +195,11 @@ class LMI_YumFileCheck(CIMProvider2): Possible Errors: CIM_ERR_ACCESS_DENIED - CIM_ERR_INVALID_PARAMETER (including missing, duplicate, + CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized or otherwise incorrect parameters) - CIM_ERR_NOT_FOUND (the target CIM Class or instance does not + 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 + CIM_ERR_METHOD_NOT_AVAILABLE (the CIM Server is unable to honor the invocation request) CIM_ERR_FAILED (some other unspecified error occurred) @@ -209,15 +209,16 @@ class LMI_YumFileCheck(CIMProvider2): logger.log_debug('Entering %s.cim_method_invoke()' \ % self.__class__.__name__) - vpkg = YumFileCheck.object_path2yumcheck(env, object_name) - fc = YumFileCheck.test_file(env, - YumFileCheck.checksumtype_str2pywbem( - vpkg.po.yumdb_info.checksum_type), - vpkg._files[object_name["Name"]]) - out_params = [] - ret = 0 if YumFileCheck.filecheck_passed(fc) else 2 + with YumDB.getInstance(env) as yb: + vpkg = YumFileCheck.object_path2yumcheck(env, object_name) + fc = YumFileCheck.test_file(env, + YumFileCheck.checksumtype_str2pywbem( + YumFileCheck.pkg_checksum_type(vpkg.po)), + vpkg._files[object_name["Name"]]) + out_params = [] + ret = 0 if YumFileCheck.filecheck_passed(fc) else 2 return (pywbem.Uint32(ret), out_params) - + def cim_method_invokeonsystem(self, env, object_name, param_targetsystem=None): """Implements LMI_YumFileCheck.InvokeOnSystem() @@ -230,16 +231,18 @@ class LMI_YumFileCheck(CIMProvider2): 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() + 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', ...)) + 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 @@ -248,11 +251,11 @@ class LMI_YumFileCheck(CIMProvider2): Possible Errors: CIM_ERR_ACCESS_DENIED - CIM_ERR_INVALID_PARAMETER (including missing, duplicate, + CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized or otherwise incorrect parameters) - CIM_ERR_NOT_FOUND (the target CIM Class or instance does not + 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 + CIM_ERR_METHOD_NOT_AVAILABLE (the CIM Server is unable to honor the invocation request) CIM_ERR_FAILED (some other unspecified error occurred) @@ -267,7 +270,7 @@ class LMI_YumFileCheck(CIMProvider2): out_params = [] #rval = # TODO (type pywbem.Uint32) return (rval, out_params) - + class Values(object): class TargetOperatingSystem(object): Unknown = pywbem.Uint16(0) @@ -398,9 +401,9 @@ class LMI_YumFileCheck(CIMProvider2): Block_Device = pywbem.Uint16(6) ## end of class LMI_YumFileCheckProvider - + ## get_providers() for associating CIM Class Name to python provider class name - -def get_providers(env): - lmi_yumfilecheck_prov = LMI_YumFileCheck(env) - return {'LMI_YumFileCheck': lmi_yumfilecheck_prov} + +def get_providers(env): + lmi_yumfilecheck_prov = LMI_YumFileCheck(env) + return {'LMI_YumFileCheck': lmi_yumfilecheck_prov} diff --git a/src/yum/providers/LMI_YumInstalledPackage.py b/src/yum/providers/LMI_YumInstalledPackage.py index f4c4cba..5a20b3c 100644 --- a/src/yum/providers/LMI_YumInstalledPackage.py +++ b/src/yum/providers/LMI_YumInstalledPackage.py @@ -24,20 +24,11 @@ Instruments the CIM class LMI_YumInstalledPackage import itertools import pywbem -import socket from pywbem.cim_provider2 import CIMProvider2 from LMI_YumPackage import pkg2model from LMI_YumFileCheck import filecheck2model from util.common import * -def get_computer_system_op(): - return pywbem.CIMInstanceName( - classname='CIM_ComputerSystem', - keybindings={ - "CreationClassName": "CIM_ComputerSystem" - , "Name" : socket.gethostname() }, - namespace="root/cimv2") - class LMI_YumInstalledPackage(CIMProvider2): """Instrument the CIM class LMI_YumInstalledPackage @@ -78,9 +69,7 @@ class LMI_YumInstalledPackage(CIMProvider2): logger.log_debug('Entering %s.get_instance()' \ % self.__class__.__name__) - if model['System'] != get_computer_system_op(): - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, - "Unknown \"System\"") + check_computer_system_op(env, model['System']) with YumDB.getInstance(env): pkg = YumPackage.object_path2pkg(env, model['Software']) model['Software'] = pkg2model(pkg, env, True) @@ -197,10 +186,7 @@ class LMI_YumInstalledPackage(CIMProvider2): logger.log_debug('Entering %s.delete_instance()' \ % self.__class__.__name__) - if instance_name['System'] != get_computer_system_op(): - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, - "Unknown \"System\"") - + check_computer_system_op(env, instance_name['System']) with YumDB.getInstance(env) as yb: pkg = YumPackage.object_path2pkg(env, instance_name["Software"]) logger.log_info('removing package "%s"' % pkg.nevra) @@ -326,17 +312,11 @@ class LMI_YumInstalledPackage(CIMProvider2): % self.__class__.__name__) failed = [] - with YumDB.getInstance(env): + with YumDB.getInstance(env) as yb: pkg = YumPackage.object_path2pkg(env, object_name['Software']) + csum = YumFileCheck.pkg_checksum_type(pkg) vpkg = yum.packages._RPMVerifyPackage( - pkg, pkg.hdr.fiFromHeader(), - pkg.yumdb_info.checksum_type, [], True) - filecheck_model = pywbem.CIMInstanceName( - classname='LMI_YumFileCheck', - namespace=object_name.namespace, - host=object_name.host) - csum = YumFileCheck.checksumtype_str2pywbem( - pkg.yumdb_info.checksum_type) + pkg, pkg.hdr.fiFromHeader(), csum, [], True) for vpf in vpkg: fc = YumFileCheck.test_file(env, csum, vpf) if ( fc.exists @@ -344,8 +324,7 @@ class LMI_YumInstalledPackage(CIMProvider2): for v in fc if isinstance(v, tuple))): continue failed.append(filecheck2model( - vpkg, vpf.filename, env, keys_only=True, - model=filecheck_model, fc=fc)) + vpkg, vpf.filename, env, keys_only=True, fc=fc)) out_params = [ pywbem.CIMParameter('Failed', type='reference', value=failed) ] return ( getattr(self.Values.CheckIntegrity, @@ -400,9 +379,7 @@ class LMI_YumInstalledPackage(CIMProvider2): logger.log_debug('Entering %s.cim_method_update()' \ % self.__class__.__name__) - if object_name['System'] != get_computer_system_op(): - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, - "Unknown \"System\"") + check_computer_system_op(env, object_name['System']) with YumDB.getInstance(env) as yb: orig = YumPackage.object_path2pkg(env, object_name['Software']) diff --git a/src/yum/providers/LMI_YumPackageFile.py b/src/yum/providers/LMI_YumPackageFile.py index a50d9a9..14988d3 100644 --- a/src/yum/providers/LMI_YumPackageFile.py +++ b/src/yum/providers/LMI_YumPackageFile.py @@ -269,7 +269,7 @@ class LMI_YumPackageFile(CIMProvider2): pkg = YumPackage.object_path2pkg(env, object_name) vpkg = yum.packages._RPMVerifyPackage( pkg, pkg.hdr.fiFromHeader(), - pkg.yumdb_info.checksum_type, [], True) + YumFileCheck.pkg_checksum_type(pkg), [], True) for fc in vpkg: model['Check'] = filecheck2model( vpkg, fc.filename, env, keys_only=True, diff --git a/src/yum/providers/util/common.py b/src/yum/providers/util/common.py index 00f702f..16c10ff 100644 --- a/src/yum/providers/util/common.py +++ b/src/yum/providers/util/common.py @@ -28,6 +28,7 @@ import os import platform import pwd import re +import rpm import socket import stat import pywbem @@ -89,6 +90,7 @@ class YumDB(singletonmixin.Singleton): self.update_db() return getattr(self._yum, name) + def _get_distname(): if hasattr(platform, 'linux_distribution'): return platform.linux_distribution( @@ -132,6 +134,14 @@ def get_target_operating_system(): else: return (0, 'Unknown') +def get_computer_system_op(): + return pywbem.CIMInstanceName( + classname='CIM_ComputerSystem', + keybindings={ + "CreationClassName": "CIM_ComputerSystem" + , "Name" : socket.gethostname() }, + namespace="root/cimv2") + def check_target_operating_system(system): """ @return if param system matches current target operating system @@ -153,6 +163,37 @@ def check_target_operating_system(system): return True return False +def check_computer_system_op(env, system): + if not isinstance(system, pywbem.CIMInstanceName): + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "\"System\" must be a CIMInstanceName") + our_system = get_computer_system_op() + if system.namespace != our_system.namespace: + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "\"System\" has wrong namespace") + ch = env.get_cimom_handle() + if not ch.is_subclass(system.namespace, + sub=system.classname, + super=our_system.classname): + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "Class of \"System\" must be a sublass of %s" % + our_system.classname) + if not 'CreationClassName' in system or not 'Name' in system: + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "\"System\" is missing one of keys") + if not ch.is_subclass(system.namespace, + sub=system['CreationClassName'], + super=our_system.classname): + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "CreationClassName of \"System\" must be a sublass of %s" % + our_system.classname) + if system['Name'] != our_system['Name']: + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "Name of \"System\" does not match \"%s\"" % + our_system['Name']) + return True + + def match_pkg(pkg, **kwargs): """ all not Null and not empty arguments will be matched against pkg @@ -667,6 +708,15 @@ class YumFileCheck: checksumtype_str2num = dict((v, k) for (k, v) in yum.constants.RPM_CHECKSUM_TYPES.items()) + @staticmethod + def pkg_checksum_type( pkg): + if not isinstance(pkg, yum.packages.YumAvailablePackage): + raise TypeError("pkg must be an instance of YumAvailablePackage") + if isinstance(pkg, yum.rpmsack.RPMInstalledPackage): + return pkg.hdr[rpm.RPMTAG_FILEDIGESTALGO] + with self: # ensure, that _yum is inited + return pkg.yumdb_info.checksum_type + @staticmethod def checksumtype_num2hash(csumt): return getattr(hashlib, yum.constants.RPM_CHECKSUM_TYPES[csumt]) @@ -818,8 +868,8 @@ class YumFileCheck: "No matching package installed") fi = pkg.hdr.fiFromHeader() - vpkg = yum.packages._RPMVerifyPackage( - pkg, fi, pkg.yumdb_info.checksum_type, [], True) + vpkg = yum.packages._RPMVerifyPackage(pkg, fi, + YumFileCheck.pkg_checksum_type(pkg), [], True) if not op['Name'] in vpkg: raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, "File not found in RPM package") @@ -909,7 +959,8 @@ class YumFileCheck: flags.append(v) return flags - def filecheck2model(vpkg, fn, env, keys_only=True, model=None, fc=None): + def filecheck2model(vpkg, fn, env, keys_only=True, + model=None, fc=None): if not isinstance(vpkg, yum.packages._RPMVerifyPackage): raise TypeError( "vpkg must be an instance of _RPMVerifyPackage") @@ -943,8 +994,7 @@ class YumFileCheck: #model['InstanceID'] = '' # TODO model['FileName'] = os.path.basename(vpf.filename) model['ChecksumType'] = csumt = \ - YumFileCheck.checksumtype_str2pywbem( - pkg.yumdb_info.checksum_type) + pywbem.Uint16(YumFileCheck.pkg_checksum_type(pkg)) if fc is None: fc = YumFileCheck.test_file(env, csumt, vpf) for mattr, fattr in ( -- cgit