diff options
-rw-r--r-- | mof/LMI_Yum.mof | 101 | ||||
-rw-r--r-- | src/yum/providers/LMI_YumInstalledPackage.py | 358 | ||||
-rw-r--r-- | src/yum/providers/LMI_YumPackage.py | 294 | ||||
-rw-r--r-- | src/yum/providers/util/common.py | 165 | ||||
-rw-r--r-- | src/yum/test/test_common.sh | 15 | ||||
-rwxr-xr-x | src/yum/test/yum_package.sh | 84 |
6 files changed, 589 insertions, 428 deletions
diff --git a/mof/LMI_Yum.mof b/mof/LMI_Yum.mof index 5e24598..bdc2a9e 100644 --- a/mof/LMI_Yum.mof +++ b/mof/LMI_Yum.mof @@ -377,47 +377,15 @@ class LMI_YumPackage : CIM_SoftwareElement { uint64 Size; [ Description ( - "Updates the package to latest version." - " When any of \"epoch\", \"version\" or \"release\" argument is given" - ", install only matching available package. Otherwise try" - " to update to newest package available." - " If the \"epoch\", \"version\" and \"release\" of package is" - " already installed, or no newer package is available," - " \"Already newest\" value is returned."), + "Will install available package."), ValueMap { "0", "1", "2" }, - Values { "Already newest", "Successful installation", "Failed" } ] - uint16 Update( - [ IN(true), Description ( - "Specify particular epoch of package to update to." - " Update to newest, when empty.") ] - String Epoch, - [ IN(true), Description ( - "Specify particular version of package to update to." - " Update to newest, when empty") ] - String Version, - [ IN(true), Description ( - "Specify particular release of package to update to." - " Update to newest, when empty.") ] - String Release, + Values { "Already installed", "Successful installation", "Failed" } ] + uint32 Install( [ IN(false), OUT, Description ( "The reference to newly installed package, if installation was" - " successful. Otherwise reference to current package.") ] - LMI_YumPackage REF Installed - ); - - [ Description ( - "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."), - ValueMap { "0", "1", "2" }, - Values { "Pass", "Not passed", "Error" } ] - uint32 CheckIntegrity( - [ IN(false), OUT, Description ( - "Array of references to LMI_YumFileCheck, that did not pass" - " verification.") ] - LMI_YumFileCheck REF Failed[] + " successful. Reference to current package if it is already" + " installed and Null otherwise.") ] + LMI_YumInstalledPackage REF Installed ); }; @@ -568,6 +536,7 @@ class LMI_YumFileCheck : CIM_FileSpecification { // =================================================================== [ Association ] class LMI_YumInstalledPackage : CIM_InstalledSoftwareElement { + [ Key, Description ( "Reference to the installed RPM package.")] LMI_YumPackage REF Software; @@ -577,5 +546,61 @@ class LMI_YumInstalledPackage : CIM_InstalledSoftwareElement { "Reference to the ComputerSystem hosting a particular" " RPM package.")] LMI_ComputerSystem REF System; + + [ Description ( + "Updates the package to latest version." + " When any of \"epoch\", \"version\" or \"release\" argument is given" + ", install only matching available package. Otherwise try" + " to update to newest package available." + " If the \"epoch\", \"version\" and \"release\" of package is" + " already installed, or no newer package is available," + " \"Already newest\" value is returned."), + ValueMap { "0", "1", "2" }, + Values { "Already newest", "Successful installation", "Failed" } ] + uint16 Update( + [ IN(true), Description ( + "Specify particular epoch of package to update to." + " Update to newest, when empty.") ] + String Epoch, + [ IN(true), Description ( + "Specify particular version of package to update to." + " Update to newest, when empty") ] + String Version, + [ IN(true), Description ( + "Specify particular release of package to update to." + " Update to newest, when empty.") ] + String Release, + [ IN(false), OUT, Description ( + "The reference to newly installed package, if installation was" + " successful. Otherwise reference to current package.") ] + LMI_YumInstalledPackage REF Installed + ); + + [ Description ( + "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."), + ValueMap { "0", "1", "2" }, + Values { "Pass", "Not passed", "Error" } ] + uint32 CheckIntegrity( + [ IN(false), OUT, Description ( + "Array of references to LMI_YumFileCheck, that did not pass" + " verification.") ] + LMI_YumFileCheck REF Failed[] + ); + +}; + +[ Association ] +class LMI_YumPackageFile : CIM_SoftwareElementChecks { + + [ Key, Aggregate, Min(1), Max(1), + Description ("The RPM package being checked")] + LMI_YumPackage REF Element; + + [ Key, Weak, Description("The Check for the element.") ] + LMI_YumFileCheck REF Check; }; diff --git a/src/yum/providers/LMI_YumInstalledPackage.py b/src/yum/providers/LMI_YumInstalledPackage.py index cb432d2..37a3afe 100644 --- a/src/yum/providers/LMI_YumInstalledPackage.py +++ b/src/yum/providers/LMI_YumInstalledPackage.py @@ -1,3 +1,4 @@ +# -*- encoding: utf-8 -*- # Software Management Providers # # Copyright (C) 2012 Red Hat, Inc. All rights reserved. @@ -21,17 +22,27 @@ Instruments the CIM class LMI_YumInstalledPackage """ +import itertools import pywbem import socket from pywbem.cim_provider2 import CIMProvider2 -from LMI_YumPackage import LMI_YumPackage +from LMI_YumPackage import LMI_YumPackage, pkg2model +from util.common import * + +def get_computer_system_op(): + return pywbem.CIMInstanceName( + classname='Linux_ComputerSystem', + keybindings={ + "CreationClassName": "Linux_ComputerSystem" + , "Name" : socket.gethostname() }, + namespace="root/cimv2") class LMI_YumInstalledPackage(CIMProvider2): - """Instrument the CIM class LMI_YumInstalledPackage + """Instrument the CIM class LMI_YumInstalledPackage The InstalledSoftwareElement association allows the identification of the ComputerSystem on which a particular SoftwareElement is installed. - + """ def __init__ (self, env): @@ -44,50 +55,51 @@ class LMI_YumInstalledPackage(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__) - - - # TODO fetch system resource matching the following keys: - # model['System'] - # model['Software'] + if model['System'] != get_computer_system_op(): + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "Unknown \"System\"") + with YumDB.getInstance(env): + pkg = object_path2pkg(env, model['Software']) + model['Software'] = pkg2model(pkg, env, 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. + 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. @@ -99,59 +111,52 @@ class LMI_YumInstalledPackage(CIMProvider2): 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. + # we set property values on the model. model.path.update({'System': None, 'Software': None}) - + yum_package = LMI_YumPackage(env) yum_package_path = pywbem.CIMInstanceName("LMI_YumPackage", namespace=model.path.namespace, host=model.path.host) - yum_package_model = pywbem.CIMInstance(classname="LMI_YumPackage", - path=yum_package_path) - for iname in yum_package.enum_instances( - env, yum_package_model, True): - model['System'] = pywbem.CIMInstanceName( - classname='Linux_ComputerSystem', - keybindings={ - "CreationClassName": "Linux_ComputerSystem" - , "Name" : socket.gethostname() }, - host=model.path.host, - namespace=model.path.namespace) - model['Software'] = iname.path - 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 + model['System'] = get_computer_system_op() + with YumDB.getInstance(env) as yb: + for rpm in yb.rpmdb: + iname = pkg2model(rpm, env, True, yum_package_path) + model['Software'] = iname + 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 + 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) @@ -162,7 +167,8 @@ class LMI_YumInstalledPackage(CIMProvider2): 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 + # Remove to implement + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED) return instance def delete_instance(self, env, instance_name): @@ -170,66 +176,75 @@ class LMI_YumInstalledPackage(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()' \ % self.__class__.__name__) - # TODO delete the resource - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED) # Remove to implement - + if instance_name['System'] != get_computer_system_op(): + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "Unknown \"System\"") + + with YumDB.getInstance(env) as yb: + pkg = object_path2pkg(env, instance_name["Software"]) + logger.log_info('removing package "%s"' % pkg.nevra) + yb.remove(pkg) + yb.buildTransaction() + yb.processTransaction() + logger.log_info('package "%s" removed' % pkg.nevra) + 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 | @@ -247,7 +262,7 @@ class LMI_YumInstalledPackage(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) @@ -258,9 +273,9 @@ class LMI_YumInstalledPackage(CIMProvider2): % self.__class__.__name__) ch = env.get_cimom_handle() - # If you want to get references for free, implemented in terms + # 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, + if ch.is_subclass(object_name.namespace, sub=object_name.classname, super='LMI_ComputerSystem') or \ ch.is_subclass(object_name.namespace, @@ -269,10 +284,173 @@ class LMI_YumInstalledPackage(CIMProvider2): return self.simple_refs(env, object_name, model, result_class_name, role, result_role, keys_only) -## end of class LMI_YumInstalledPackageProvider - + def cim_method_checkintegrity(self, env, object_name): + """Implements LMI_YumPackage.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 self.Values.CheckIntegrity) + and a list of CIMParameter objects representing the output parameters + + Output parameters: + Failed -- (type REF (pywbem.CIMInstanceName( + classname='LMI_YumFileCheck', ...)) + Array of references to LMI_YumFileCheck, 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) + + """ + + logger = env.get_logger() + logger.log_debug('Entering %s.cim_method_checkintegrity()' \ + % self.__class__.__name__) + + # TODO do something + raise pywbem.CIMError(pywbem.CIM_ERR_METHOD_NOT_AVAILABLE) # Remove to implemented + out_params = [] + #out_params+= [pywbem.CIMParameter('failed', type='reference', + # value=[pywbem.CIMInstanceName(classname='LMI_YumFileCheck', ...),])] # TODO + #rval = # TODO (type pywbem.Uint32 self.Values.CheckIntegrity) + return (rval, out_params) + + def cim_method_update(self, env, object_name, + param_epoch=None, + param_release=None, + param_version=None): + """Implements LMI_YumInstalledPackage.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 self.Values.Update) + and a list of CIMParameter objects representing the output parameters + + Output parameters: + Installed -- (type REF (pywbem.CIMInstanceName( + classname='LMI_YumInstalledPackage', ...)) + 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) + + """ + + logger = env.get_logger() + 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\"") + + with YumDB.getInstance(env) as yb: + orig = object_path2pkg(env, object_name['Software']) + + evr_str = [] + for name, param in ( + ('epoch', param_epoch), + ('version', param_version), + ('release', param_release)): + evr_str.append("%s(%s)"%(name,param)) + if len(evr_str): + evr_str = "specific "+'-'.join(evr_str) + else: + evr_str = "the newest version-release" + + logger.log_info('trying to update to %s of package \"%s\"' % + (evr_str, object_name["Software"]["Name"])) + + pl = yb.doPackageLists('all', showdups=True) + exact,_,_ = yum.packages.parsePackages( + itertools.chain(pl.available, pl.installed), + [orig.name]) + # NOTE: available ∩ installed = ∅ + exact = sorted(exact, key=lambda a:a.evra) + + try: + pkg = [ p for p in exact + if (not param_epoch or param_epoch == p.epoch) + and (not param_version or param_version == p.ver) + and (not param_release or param_release == p.rel) ] [-1] + except IndexError: + logger.log_error( + 'could not find any matching available package') + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND) + out_params = [pywbem.CIMParameter('Installed', type='reference', + value=pkg2model(pkg, env, True))] + if orig.evra == pkg.evra: + logger.log_info('already up to date') + return (self.Values.Update.Already_newest, out_params) + + yb.update(update_to=True, + name=pkg.name, + epoch=pkg.epoch, + version=pkg.version, + release=pkg.release) + yb.buildTransaction() + yb.processTransaction() + logger.log_info('package {} updated to: {}'.format( + orig.name, pkg.evra)) + + return (self.Values.Update.Successful_installation, out_params) + + 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) + +## end of class LMI_YumInstalledPackage + ## get_providers() for associating CIM Class Name to python provider class name - -def get_providers(env): - lmi_yuminstalledpackage_prov = LMI_YumInstalledPackage(env) - return {'LMI_YumInstalledPackage': lmi_yuminstalledpackage_prov} + +def get_providers(env): + lmi_yuminstalledpackage_prov = LMI_YumInstalledPackage(env) + return {'LMI_YumInstalledPackage': lmi_yuminstalledpackage_prov} diff --git a/src/yum/providers/LMI_YumPackage.py b/src/yum/providers/LMI_YumPackage.py index f1441b0..5a9750b 100644 --- a/src/yum/providers/LMI_YumPackage.py +++ b/src/yum/providers/LMI_YumPackage.py @@ -1,3 +1,4 @@ +# -*- encoding: utf-8 -*- # Software Management Providers # # Copyright (C) 2012 Red Hat, Inc. All rights reserved. @@ -70,8 +71,9 @@ class LMI_YumPackage(CIMProvider2): logger.log_debug('Entering %s.get_instance()' \ % self.__class__.__name__) - pkg = YumPackage.object_path2pkg(env, model.path) - return pkg2model(pkg, env, keys_only=False, model=model) + with YumDB.getInstance(env): + pkg = object_path2pkg(env, model.path, 'all') + return pkg2model(pkg, env, keys_only=False, model=model) def enum_instances(self, env, model, keys_only): """Enumerate instances. @@ -108,7 +110,11 @@ class LMI_YumPackage(CIMProvider2): 'SoftwareElementID': None}) with YumDB.getInstance(env) as yb: - for pkg in yb.rpmdb: + # get all packages + pl = yb.doPackageLists('all', showdups=True) + pl = itertools.chain(pl.installed, pl.available) + # NOTE: available ∩ installed = ∅ + for pkg in sorted(pl, key=lambda a:a.evra): yield pkg2model(pkg, env, keys_only, model) def set_instance(self, env, instance, modify_existing): @@ -141,84 +147,9 @@ class LMI_YumPackage(CIMProvider2): logger = env.get_logger() logger.log_debug('Entering %s.set_instance()' \ % self.__class__.__name__) - - _has_key = lambda k: k in instance.properties or ( - instance.path is not None and k in instance.path) - def _get_key(k): - v = instance.properties.get(k, None) - if isinstance(v, pywbem.CIMProperty): return v.value - if v is not None: return v - logger.log_error('missing key "{}" in inst.props'.format(k)) - return instance.path[k] if k in instance.path else None - - # parse and check arguments - if modify_existing is True: - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, - "MofifyInstance is not supported") - match_props = {} # args for match_pkg - installed_kwargs = {} # args for rpmdb.installed - if instance['SoftwareElementID']: - m = re_nevra.match(instance['SoftwareElementID']) - if not m: - raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER, - "SoftwareElementID could not be parsed.") - match_props['nevra'] = instance['SoftwareElementID'] - match_props['name'] = m.group('name') - for a in ('name', 'epoch', 'ver', 'rel', 'arch'): - installed_kwargs[a] = m.group(a) - else: - for matchattr, instattr in ( - ('name', 'name'), ('epoch', 'epoch'), ('version', 'ver'), - ('release', 'rel'), ('arch', 'arch')): - if _has_key(matchattr) and _get_key(matchattr): - match_props[matchattr] = installed_kwargs[instattr] = \ - _get_key(matchattr) - - if not match_props: - raise pywbem.CIMError(pywbem.CIM_ERR_FAILED, - "Too few key values given (give at least a Name).") - if not 'name' in match_props and not 'nevra' in match_props: - raise pywbem.CIMError(pywbem.CIM_ERR_FAILED, - "Missing either Name or SoftwareElementID property.") - - with YumDB.getInstance(env) as yb: - # check already installed - if yb.rpmdb.installed(**installed_kwargs): - raise pywbem.CIMError(pywbem.CIM_ERR_ALREADY_EXISTS, - "Package is already installed.") - - # get available packages - pl = yb.doPackageLists('available', showdups=True) - exact, matched, unmatched = yum.packages.parsePackages( - pl.available, [match_props['name']]) - exact_orig = exact - exact = sorted( [ p for p in exact if match_pkg(p, **match_props) ] - , key=lambda a: a.evra) - if len(exact) == 0: - logger.log_error('could not find any package for query: {}' - ' in list: {}' - .format(match_props, [p.nevra for p in exact_orig])) - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, - "No matching package found.") - if len(exact) > 1: - logger.log_info('found multiple matching packages' - ' for query: {}'.format(match_props)) - pkg = exact[-1] # select highest version - else: - logger.log_debug('exact match found for query: {}' - .format(match_props)) - pkg = exact[0] - - logger.log_info('installing package {}'.format(pkg.nevra)) - # install - yb.install(pkg) - yb.buildTransaction() - yb.processTransaction() - logger.log_info('package installed'.format(pkg.nevra)) - - # return instance - instance = pkg2model(pkg, env, True, instance) - return self.get_instance(env, instance) + # 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. @@ -246,92 +177,29 @@ class LMI_YumPackage(CIMProvider2): logger.log_debug('Entering %s.delete_instance()' \ % self.__class__.__name__) - with YumDB.getInstance(env) as yb: - pkg = YumPackage.object_path2pkg(env, instance_name) - logger.log_info('removing package "%s"' % pkg.nevra) - yb.remove(pkg) - yb.buildTransaction() - yb.processTransaction() - logger.log_info('package "%s" removed' % pkg.nevra) - - def cim_method_checkintegrity(self, env, object_name): - """Implements LMI_YumPackage.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 self.Values.CheckIntegrity) - and a list of CIMParameter objects representing the output parameters - - Output parameters: - Failed -- (type REF (pywbem.CIMInstanceName(classname='LMI_YumFileCheck', ...)) - Array of references to LMI_YumFileCheck, that did not pass - verification. - + # TODO delete the resource + # Remove to implement + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED) - 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) - - """ - - logger = env.get_logger() - logger.log_debug('Entering %s.cim_method_checkintegrity()' \ - % self.__class__.__name__) + def cim_method_install(self, env, object_name): + """Implements LMI_YumPackage.Install() - # TODO do something - raise pywbem.CIMError(pywbem.CIM_ERR_METHOD_NOT_AVAILABLE) # Remove to implemented - out_params = [] - #out_params+= [pywbem.CIMParameter('failed', type='reference', - # value=[pywbem.CIMInstanceName(classname='LMI_YumFileCheck', ...),])] # TODO - #rval = # TODO (type pywbem.Uint32 self.Values.CheckIntegrity) - return (rval, out_params) - - def cim_method_update(self, env, object_name, - param_epoch=None, - param_release=None, - param_version=None): - """Implements LMI_YumPackage.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. + 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. - 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 self.Values.Update) + + Returns a two-tuple containing the return value (type pywbem.Uint32 self.Values.Install) and a list of CIMParameter objects representing the output parameters Output parameters: - Installed -- (type REF (pywbem.CIMInstanceName(classname='LMI_YumPackage', ...)) + Installed -- (type REF (pywbem.CIMInstanceName( + classname='LMI_YumInstalledPackage', ...)) The reference to newly installed package, if installation was - successful. Otherwise reference to current package. + successful. Null otherwise. Possible Errors: CIM_ERR_ACCESS_DENIED @@ -344,60 +212,73 @@ class LMI_YumPackage(CIMProvider2): CIM_ERR_FAILED (some other unspecified error occurred) """ - logger = env.get_logger() - logger.log_debug('Entering %s.cim_method_update()' \ + logger.log_debug('Entering %s.cim_method_install()' \ % self.__class__.__name__) - with YumDB.getInstance(env) as yb: - orig = YumPackage.object_path2pkg(env, object_name) - - evr_str = [] - for name, param in ( - ('epoch', param_epoch), - ('version', param_version), - ('release', param_release)): - evr_str.append("%s(%s)"%(name,param)) - if len(evr_str): - evr_str = "specific "+'-'.join(evr_str) - else: - evr_str = "the newest version-release" + # parse and check arguments + match_props = {} # args for match_pkg + if object_name['SoftwareElementID']: + m = re_nevra.match(object_name['SoftwareElementID']) + if not m: + raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER, + "SoftwareElementID could not be parsed.") + match_props['nevra'] = object_name['SoftwareElementID'] + match_props['name'] = m.group('name') + else: + for matchattr, instattr in ( + ('name', 'name'), ('epoch', 'epoch'), ('version', 'ver'), + ('release', 'rel'), ('arch', 'arch')): + if object_name.get(matchattr, None): + match_props[matchattr] = object_name[matchattr] - logger.log_info('trying to update to %s of package \"%s\"' % - (evr_str, object_name["Name"])) + if not match_props: + raise pywbem.CIMError(pywbem.CIM_ERR_FAILED, + "Too few key values given (give at least a Name).") + if not 'name' in match_props and not 'nevra' in match_props: + raise pywbem.CIMError(pywbem.CIM_ERR_FAILED, + "Missing either Name or SoftwareElementID property.") + with YumDB.getInstance(env) as yb: + # get available packages pl = yb.doPackageLists('all', showdups=True) - exact, matched, unmatched = yum.packages.parsePackages( + exact,_,_ = yum.packages.parsePackages( itertools.chain(pl.available, pl.installed), - [orig.name]) - exact = sorted(exact, key=lambda a:a.evra) - - try: - pkg = [p for p in exact - if (not param_epoch or param_epoch == p.epoch) - and (not param_version or param_version == p.ver) - and (not param_release or param_release == p.rel)] [-1] - except IndexError: - logger.log_error( - 'could not find any matching available package') - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND) - out_params = [pywbem.CIMParameter('Installed', type='reference', - value=pkg2model(pkg, env, True))] - if orig.evra == pkg.evra: - logger.log_info('already up to date') - return (self.Values.Update.Already_newest, out_params) - - yb.update(update_to=True, - name=pkg.name, - epoch=pkg.epoch, - version=pkg.version, - release=pkg.release) + [match_props['name']]) + exact = yum.misc.unique(exact) + exact_orig = exact + exact = sorted( [ p for p in exact if match_pkg(p, **match_props) ] + , key=lambda a: a.evra) + if len(exact) == 0: + logger.log_error('could not find any package for query: {}' + ' in list: {}' + .format(match_props, [p.nevra for p in exact_orig])) + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "No matching package found.") + out_params = [ pywbem.CIMParameter('Installed', type='reference') ] + for pkg in exact: # check, whether package is already installed + if yb.rpmdb.installed(po=pkg): + out_params[0].value = pkg2model(pkg, env, True) + return (self.Values.Install.Already_installed, out_params) + if len(exact) > 1: # should not happen + logger.log_info('found multiple matching packages' + ' for query: {}'.format(match_props)) + pkg = exact[-1] # select highest version + else: + logger.log_debug('exact match found for query: {}' + .format(match_props)) + pkg = exact[0] + + logger.log_info('installing package {}'.format(pkg.nevra)) + # install + yb.install(pkg) yb.buildTransaction() yb.processTransaction() - logger.log_info('package {} updated to: {}'.format( - orig.name, pkg.evra)) + logger.log_info('package installed'.format(pkg.nevra)) - return (self.Values.Update.Successful_installation, out_params) + # return object_name + out_params[0].value = pkg2model(pkg, env, True, object_name) + return (self.Values.Install.Successful_installation, out_params) class Values(object): class DetailedStatus(object): @@ -549,11 +430,6 @@ class LMI_YumPackage(CIMProvider2): Oracle_Enterprise_Linux_64_bit = pywbem.Uint16(109) eComStation_32_bitx = pywbem.Uint16(110) - class Update(object): - Already_newest = pywbem.Uint16(0) - Successful_installation = pywbem.Uint16(1) - Failed = pywbem.Uint16(2) - class CommunicationStatus(object): Unknown = pywbem.Uint16(0) Not_Available = pywbem.Uint16(1) @@ -622,12 +498,12 @@ class LMI_YumPackage(CIMProvider2): # DMTF_Reserved = .. # Vendor_Reserved = 0x8000.. - class CheckIntegrity(object): - Pass = pywbem.Uint32(0) - Not_passed = pywbem.Uint32(1) - Error = pywbem.Uint32(2) + class Install(object): + Already_installed = pywbem.Uint32(0) + Successful_installation = pywbem.Uint32(1) + Failed = pywbem.Uint32(2) -## end of class LMI_YumPackageProvider +## end of class LMI_YumPackage ## get_providers() for associating CIM Class Name to python provider class name diff --git a/src/yum/providers/util/common.py b/src/yum/providers/util/common.py index 1519a9a..7d918a4 100644 --- a/src/yum/providers/util/common.py +++ b/src/yum/providers/util/common.py @@ -1,3 +1,4 @@ +# -*- encoding: utf-8 -*- # Software Management Providers # # Copyright (C) 2012 Red Hat, Inc. All rights reserved. @@ -22,6 +23,7 @@ import collections from datetime import datetime import grp import hashlib +import itertools import os import platform import pwd @@ -48,7 +50,8 @@ class YumDB(singletonmixin.Singleton): if not isinstance(env, pycimmb.ProviderEnvironment): raise TypeError("env must be instance of" " pycimmb.ProviderEnvironment") - self._yum = yum.YumBase(*args, **kwargs) + self._yum_args = (args, kwargs) + self._yum = None self._db_mtime = 0 self._lock_cnt = 0 self.env = env @@ -70,15 +73,15 @@ class YumDB(singletonmixin.Singleton): def __enter__(self): self._lock_cnt += 1 if self._lock_cnt < 2: + self._yum = yum.YumBase(*self._yum_args[0], **self._yum_args[1]) if not self.is_locked() and self.is_dirty(): self.update_db() self._yum.doLock() return self def __exit__(self, exc_type, exc_value, traceback): - if self._lock_cnt > 0: - self._yum.closeRpmDB() - self._yum.doUnlock() + if self._lock_cnt == 1: + del self._yum self._lock_cnt -= 1 def __getattr__(self, name): @@ -165,6 +168,63 @@ 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. @@ -528,50 +588,6 @@ class YumPackage: return pywbem.Uint16(res) @staticmethod - def object_path2pkg(env, op): - if not isinstance(op, pywbem.CIMInstanceName): - raise TypeError("op must be an instance of CIMInstanceName") - 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 not yb.rpmdb.installed(**kwargs): - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, - "Package not installed") - - pl = yb.doPackageLists('installed') - exact, matched, unmatched = yum.packages.parsePackages( - pl.installed, [op['Name']]) - exact = yum.misc.unique(exact) - for pkg in exact: - if pkg.evra == m.group('evra'): break - else: - raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, - "No matching package installed") - return pkg - - @staticmethod def pkg2model_wrapper(namespace, classname): """ @return a function that transforms YumAvailablePackage object @@ -594,26 +610,39 @@ class YumPackage: model = pywbem.CIMInstanceName(classname, namespace=namespace) if not keys_only: model = pywbem.CIMInstance(classname, path=model) - model['Name'] = pkg.name - model['SoftwareElementID'] = pkg.nevra - model['SoftwareElementState'] = pywbem.Uint16(2) - model['TargetOperatingSystem'] = tos - model['Version'] = pkg.version - if not keys_only: - model['Caption'] = pkg.summary - model['Description'] = pkg.description - model['InstallDate'] = pywbem.CIMDateTime( - datetime.fromtimestamp(pkg.installtime)) - if pkg.vendor: - model['Manufacturer'] = pkg.vendor - model['Release'] = pkg.release - model['Epoch'] = pywbem.Uint16(pkg.epoch) - model["Architecture"] = YumPackage.parse_arch(pkg.arch, env) - model['License'] = YumPackage.parse_license(pkg.license, env) - model['LicenseString']= pkg.license - model['Group'] = YumPackage.parse_group(pkg.group, env) - model['GroupString'] = pkg.group - model['Size'] = pywbem.Uint64(pkg.size) + if isinstance(model, pywbem.CIMInstance): + def _set_key(k, v): + model[k] = v + model.path[k] = v + else: + _set_key = model.__setitem__ + with YumDB.getInstance(env): + _set_key('Name', pkg.name) + _set_key('SoftwareElementID', pkg.nevra) + _set_key('SoftwareElementState', pywbem.Uint16(2 + if isinstance(pkg, yum.rpmsack.RPMInstalledPackage) + else 1)) + _set_key('TargetOperatingSystem', tos) + _set_key('Version', pkg.version) + if not keys_only: + model['Caption'] = pkg.summary + model['Description'] = pkg.description + if isinstance(pkg, yum.rpmsack.RPMInstalledPackage): + model['InstallDate'] = pywbem.CIMDateTime( + datetime.fromtimestamp(pkg.installtime)) + if pkg.vendor: + model['Manufacturer'] = pkg.vendor + model['Release'] = pkg.release + model['Epoch'] = pywbem.Uint16(pkg.epoch) + model["Architecture"] = YumPackage.parse_arch( + pkg.arch, env) + model['License'] = YumPackage.parse_license( + pkg.license, env) + model['LicenseString']= pkg.license + model['Group'] = YumPackage.parse_group( + pkg.group, env) + model['GroupString'] = pkg.group + model['Size'] = pywbem.Uint64(pkg.size) return model return pkg2model diff --git a/src/yum/test/test_common.sh b/src/yum/test/test_common.sh index 25d931f..1e5cd98 100644 --- a/src/yum/test/test_common.sh +++ b/src/yum/test/test_common.sh @@ -6,8 +6,7 @@ if [ -z $CLASS_NAME ]; then fi -url="http://localhost:5988/root/cimv2" -op="${url}:${cls}" +url="http://localhost:5988" fedora_release=`sed 's/Fedora release\s*\([0-9]\+\).*/\1/' \ /etc/fedora-release` @@ -18,6 +17,18 @@ function make_nevra() { printf "%s-%s:%s-%s.%s" $@ } +function make_op() { + local class_name keys + read class_name keys <<< "$@" + [ -n "$keys" ] && keys=".$keys" + printf "root/cimv2:$class_name$keys" +} + +computer_system_keys="CreationClassName=\"Linux_ComputerSystem\"" +computer_system_keys+=",Name=$(hostname)" +computer_system_op=`make_op Linux_ComputerSystem "$computer_system_keys"` +op=`make_op ${CLASS_NAME}` + function make_rpm_name() { local name epoch ver rel arch; if [ $# -ge 5 ]; then diff --git a/src/yum/test/yum_package.sh b/src/yum/test/yum_package.sh index c13cbe4..5d81955 100755 --- a/src/yum/test/yum_package.sh +++ b/src/yum/test/yum_package.sh @@ -4,6 +4,7 @@ dir=`dirname $0` [ -z "$dir" ] && dir=. CLASS_NAME="LMI_YumPackage" +. $dir/test_common.sh declare -A pkg1 pkg2 if [[ "$fedora_release" = 16 ]]; then @@ -84,10 +85,22 @@ test_install() { fi local keys=`make_inst_keys ${nevra_arr[@]}` - local url="$op.${keys}" - echo "creating instance of $CLASS_NAME: $url" - wbemerr ci "$url" "${keys},Release=\"$rel\"" - + local url="$url/$op.${keys}" + + echo "trying to get instance" + if ! wbemerr gi "$url" |& \ + grep -q '\<SoftwareElementState="\?1"\?'; then + echo "wrong SoftwareElementState" + exit 1 + fi + + echo "installing $CLASS_NAME: $url" + if ! wbemerr cm "$url" Install |& \ + grep -q '\<Install:\s*1\s\+Installed'; then + echo "wrong return code" + exit 1 + fi + if is_installed $name; then echo "successful installation" else @@ -95,10 +108,19 @@ test_install() { exit 1 fi + echo "checking get instance" + if ! wbemerr gi "$url" |& \ + grep -q '\<SoftwareElementState="\?2"\?'; then + echo "wrong SoftwareElementState" + exit 1 + fi + echo "testing installation of already installed package" - wbemcli ci "${url}" "${keys},Release=\"rel\"" |& \ - grep -q CIM_ERR_ALREADY_EXISTS && - echo "success" || echo "failed" + if ! wbemcli cm "${url}" Install |& \ + grep -q '\<Install:\s*0\s\+Installed'; then + echo "wrong return code" + exit 1 + fi } test_update() { @@ -126,9 +148,9 @@ test_update() { fi local keys=`make_inst_keys ${nevra_arr[@]}` - local url="$op.${keys}" - echo "intalling older package with $CLASS_NAME: $url" - wbemerr ci "$url" "${keys},Release=\"$rel\"" + local package_url="$url/$op.$keys" + echo "intalling older package with $CLASS_NAME: $package_url" + wbemerr cm "$package_url" Install if is_installed $name; then echo "successful installation" @@ -137,9 +159,15 @@ test_update() { exit 1 fi - echo "updating with ${CLASS_NAME}.Update()" - wbemerr cm "$url" "Update" | grep -q '\<Update:\s*1\s\+Installed' || \ + echo "updating with LMI_YumInstalledPackage.Update()" + + local installed_keys="Software=$op.$keys,System=$computer_system_op" + local installed_url="$url/`make_op LMI_YumInstalledPackage $installed_keys`" + if ! wbemerr cm "$installed_url" "Update" | \ + grep -q '\<Update:\s*1\s\+Installed'; then echo "wrong return code" + exit 1 + fi if is_installed_nevra $name $up_epoch $up_ver $up_rel $arch; then echo "successful update" @@ -149,13 +177,17 @@ test_update() { fi keys=`make_inst_keys $name $up_epoch $up_ver $up_rel $arch` - url2="${op}.${keys}" - echo "trying to update once more to: $url2" - wbemerr cm "$url2" "Update" | grep -q '\<Update:\s*0\s\+Installed' || \ + installed_keys="Software=$op.$keys,System=$computer_system_op" + local installed_url2="$url/`make_op LMI_YumInstalledPackage $installed_keys`" + echo "trying to update once more to: $installed_url2" + if ! wbemerr cm "$installed_url2" "Update" | \ + grep -q '\<Update:\s*0\s\+Installed'; then echo "wrong return code" + exit 1 + fi echo "removing updated package" - wbemerr di "$url2" + wbemerr di "$installed_url2" if is_installed $name; then echo "failed to remove ${name}" exit 1 @@ -167,11 +199,12 @@ test_update() { install_pkg "$@" || exit 1 echo "trying to update to not existing version-release" - wbemerr cm "$url" "Update.Version=\"not-existing-version\"" |& + wbemerr cm "$installed_url" "Update.Version=\"not-existing-version\"" |& grep -q CIM_ERR_NOT_FOUND && echo "ok" || echo "failed" echo "trying to update to the same version-release" - wbemerr cm "$url" "Update.Version=\"${ver}\",Release=\"${rel}\"" | \ + wbemerr cm "$installed_url" \ + "Update.Version=\"${ver}\",Release=\"${rel}\"" | \ grep -q '\<Update:\s*0\s\+Installed' || \ echo "wrong return code" @@ -183,7 +216,8 @@ test_update() { fi echo "trying to update to the specific version" - wbemerr cm "$url" "Update.Version=\"${up_ver}\",Release=\"${up_rel}\"" | + wbemerr cm "$installed_url" \ + "Update.Version=\"${up_ver}\",Release=\"${up_rel}\"" | grep -q '\<Update:\s*1\s\+Installed' || \ echo "wrong return code" @@ -210,13 +244,21 @@ test_remove() { fi local keys=`make_inst_keys ${nevra_arr[@]}` - local url="$op.${keys}" - wbemerr di "$url" + local installed_keys="Software=$op.$keys,System=$computer_system_op" + local installed_url="$url/`make_op LMI_YumInstalledPackage $installed_keys`" + wbemerr di "$installed_url" if is_installed $name; then echo "failed to remove ${name}" + exit 1 else echo "success" fi + local url="$url/$op.$keys" + if ! wbemerr gi "$url" |& \ + grep -q '\<SoftwareElementState="\?1"\?'; then + echo "wrong SoftwareElementState" + exit 1 + fi } |