diff options
Diffstat (limited to 'src/yum/providers/util/common.py')
-rw-r--r-- | src/yum/providers/util/common.py | 112 |
1 files changed, 102 insertions, 10 deletions
diff --git a/src/yum/providers/util/common.py b/src/yum/providers/util/common.py index 16c10ff..0cd5116 100644 --- a/src/yum/providers/util/common.py +++ b/src/yum/providers/util/common.py @@ -168,9 +168,6 @@ def check_computer_system_op(env, system): 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, @@ -574,6 +571,8 @@ class YumPackage: @staticmethod def object_path2pkg(env, op, package_list='installed'): """ + @param op must contain precise information of package, + otherwise a CIM_ERR_NOT_FOUND error is raised @param package_list one of {'installed', 'all', 'available'} says, where to look for given package """ @@ -630,6 +629,81 @@ class YumPackage: return pkg @staticmethod + def object_path2pkg_search(env, op): + """ + 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 op may be object of CIMInstance or CIMInstanceName and + must contain at least \"Name\" or \"SoftwareElementID\" + @return instance of yum.rpmsack.RPMInstalledPackage in case of + installed package, otherwise yum.packages.YumAvailablePackage + """ + logger = env.get_logger() + if isinstance(op, pywbem.CIMInstance): + def _get_key(k): + v = op.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 op.path[k] if k in op.path else None + elif isinstance(op, pywbem.CIMInstanceName): + _get_key = lambda k: op[k] if k in op else None + else: + raise TypeError("op must be either CIMInstance or CIMInstanceName") + + # parse and check arguments + match_props = {} # args for match_pkg + if _get_key('SoftwareElementID'): + m = re_nevra.match(_get_key('SoftwareElementID')) + if not m: + raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER, + "SoftwareElementID could not be parsed.") + match_props['nevra'] = _get_key('SoftwareElementID') + match_props['name'] = m.group('name') + else: + for matchattr, instattr in ( + ('name', 'name'), ('epoch', 'epoch'), ('version', 'ver'), + ('release', 'rel'), ('arch', 'arch')): + if _get_key(matchattr): + match_props[matchattr] = _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.") + + # get available packages + pl = YumDB.getInstance(env).doPackageLists('all', showdups=True) + # NOTE: available ∩ installed = ∅ + exact,_,_ = yum.packages.parsePackages( + itertools.chain(pl.available, pl.installed), + [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.") + for pkg in exact: # check, whether package is already installed + if isinstance(pkg, yum.rpmsack.RPMInstalledPackage): + return pkg + logger.log_info(('found multiple matching packages' + ' for query: {}' if len(exact) > 1 else + 'exact match found for query: {}') + .format(match_props)) + return exact[-1] # select highest version + + @staticmethod def pkg2model_wrapper(namespace, classname): """ @return a function that transforms YumAvailablePackage object @@ -638,7 +712,7 @@ class YumPackage: tos = pywbem.Uint16(get_target_operating_system()[0]) - def pkg2model(pkg, env, keys_only=True, model=None): + def pkg2model(env, 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 @@ -709,13 +783,17 @@ class YumFileCheck: yum.constants.RPM_CHECKSUM_TYPES.items()) @staticmethod - def pkg_checksum_type( pkg): + def pkg_checksum_type(pkg): + """ + @return integer representation of checksum type + """ 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 + return YumFileCheck.checksumtype_str2pywbem( + pkg.yumdb_info.checksum_type) @staticmethod def checksumtype_num2hash(csumt): @@ -944,17 +1022,31 @@ class YumFileCheck: def filecheck_passed(fc): if not isinstance(fc, YumFileCheck.FileCheck): raise TypeError("fc must be an instance of FileCheck") - return fc.exists and all(v[0] == v[1] - for v in fc if isinstance(v, tuple)) + return ( fc.exists + and all( v[0] == v[1] + for k, v in fc._asdict().items() if ( + isinstance(v, tuple) + and ( k != "last_modification_time" + or fc.file_type[0] == \ + YumFileCheck.filetype_str2pywbem("file") + )))) @staticmethod def filecheck_wrapper(namespace, classname): def _filecheck2model_flags(fc): flags = [] - for v in fc: + for k, v in fc._asdict().items(): if isinstance(v, tuple): - flags.append(fc.exists and v[0] == v[1]) + if ( k != "last_modification_time" + or fc.file_type[0] == YumFileCheck.filetype_str2pywbem( + 'file')): + # last_modification_time check is valid only for + # regular files + flag = fc.exists and v[0] == v[1] + else: + flag = True + flags.append(flag) elif isinstance(v, bool): flags.append(v) return flags |