summaryrefslogtreecommitdiffstats
path: root/src/software/lmi/software/core/AffectedSoftwareJobElement.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/software/lmi/software/core/AffectedSoftwareJobElement.py')
-rw-r--r--src/software/lmi/software/core/AffectedSoftwareJobElement.py264
1 files changed, 264 insertions, 0 deletions
diff --git a/src/software/lmi/software/core/AffectedSoftwareJobElement.py b/src/software/lmi/software/core/AffectedSoftwareJobElement.py
new file mode 100644
index 0000000..90014eb
--- /dev/null
+++ b/src/software/lmi/software/core/AffectedSoftwareJobElement.py
@@ -0,0 +1,264 @@
+# -*- encoding: utf-8 -*-
+# Software Management Providers
+#
+# Copyright (C) 2012-2013 Red Hat, Inc. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""
+Just a common functionality related to AffectedSoftwareJobElement provider.
+"""
+
+import pywbem
+
+from lmi.common import cmpi_logging
+from lmi.software import util
+from lmi.software.core import ComputerSystem
+from lmi.software.core import Identity
+from lmi.software.core import IdentityFileCheck
+from lmi.software.core import Job
+from lmi.software.core import SystemCollection
+from lmi.software.yumdb import jobs
+from lmi.software.yumdb import PackageInfo
+
+class Values(object):
+ class ElementEffects(object):
+ Unknown = pywbem.Uint16(0)
+ Other = pywbem.Uint16(1)
+ Exclusive_Use = pywbem.Uint16(2)
+ Performance_Impact = pywbem.Uint16(3)
+ Element_Integrity = pywbem.Uint16(4)
+ Create = pywbem.Uint16(5)
+ _reverse_map = {
+ 0: 'Unknown',
+ 1: 'Other',
+ 2: 'Exclusive Use',
+ 3: 'Performance Impact',
+ 4: 'Element Integrity',
+ 5: 'Create'
+ }
+
+@cmpi_logging.trace_function
+def check_path(env, op):
+ """
+ Checks, whether object path is valid.
+
+ Return internal object representing job and object path of affected element
+ as a pair: ``(job, affected)``.
+ """
+ if not isinstance(op, pywbem.CIMInstanceName):
+ raise TypeError("op must be a CIMInstanceName")
+ ch = env.get_cimom_handle()
+
+ job = op['AffectingElement'] = Job.object_path2job(op['AffectingElement'])
+ affected = op['AffectedElement']
+ if ch.is_subclass(affected.namespace, sub=affected.classname,
+ super='LMI_SoftwareIdentity'):
+ pkg_info = Identity.object_path2pkg(affected, kind='all')
+ if isinstance(job, jobs.YumSpecificPackageJob):
+ if isinstance(job.pkg, PackageInfo):
+ if pkg_info != job.pkg:
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "AffectedElement does not match job's package:"
+ " \"%s\" != \"%s\"." % (pkg_info, job.pkg))
+ else:
+ flt = pkg_info.key_props
+ flt.pop('repoid', None)
+ if util.nevra2filter(job.pkg) != flt:
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "AffectedElement does not match job's package:"
+ " \"%s\" != \"%s\"." % (pkg_info, job.pkg))
+ affected = Identity.pkg2model(pkg_info)
+ elif isinstance(job, jobs.YumInstallPackageFromURI):
+ if job.state == job.COMPLETED:
+ affected = Identity.pkg2model(job.result_data)
+ else:
+ # TODO: this should be somehow obtained from downloaded
+ # package before installation
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "No SoftwareIdentity is associated to given job.")
+ else:
+ cmpi_logging.logger.error("Unsupported async job: %s", job)
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "No associated SoftwareIdentity.")
+ elif ch.is_subclass(affected.namespace, sub=affected.classname,
+ super='LMI_SystemSoftwareCollection'):
+ SystemCollection.check_path(env, affected, "AffectedElement")
+ affected = SystemCollection.get_path()
+ elif ch.is_subclass(affected.namespace, sub=affected.classname,
+ super='Linux_ComputerSystem'):
+ ComputerSystem.check_path(env, affected, "AffectedElement")
+ affected = ComputerSystem.get_path()
+ elif ch.is_subclass(affected.namespace, sub=affected.classname,
+ super='LMI_SoftwareIdentityFileCheck'):
+ if not isinstance(job, jobs.YumCheckPackage):
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "Job must point to verification job, not to: \"%s\"" % job)
+ if job.state != job.COMPLETED:
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "Associations to failed file checks for verification job"
+ " \"%s\" are not yet known, since job has not completed"
+ " yet." % op["AffectingElement"]["InstanceID"])
+ pkg_info, _ = job.result_data
+ file_check = IdentityFileCheck.object_path2file_check(affected)
+ if file_check.pkg_info.nevra != pkg_info.nevra:
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "Affected element associated to job for another package:"
+ " \"%s\" != \"%s\"." % (file_check.pkg_info, pkg_info))
+ if IdentityFileCheck.file_check_passed(file_check):
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "Given file check reference passed the verification.")
+ else:
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
+ "Expected an instance of LMI_SoftwareIdentity,"
+ " LMI_SystemSoftwareCollection or Linux_ComputerSystem.")
+ return (job, affected)
+
+@cmpi_logging.trace_function
+def job2affected_software_identity(job):
+ """
+ @return (path of SoftwareIdentity, ElementEffects array,
+ OtherElementEffectsDescriptions array)
+ """
+ effects = [Values.ElementEffects.Other]
+ descriptions = []
+ if isinstance(job, jobs.YumSpecificPackageJob):
+ if job.state == job.COMPLETED and job.result_data:
+ if isinstance(job, jobs.YumCheckPackage):
+ # get the first item out of (pkg_info, pkg_check)
+ affected = Identity.pkg2model(job.result_data[0])
+ else:
+ affected = Identity.pkg2model(job.result_data)
+ else:
+ affected = Identity.pkg2model(job.pkg)
+ if isinstance(job, jobs.YumInstallPackage):
+ descriptions.append("Installing")
+ elif isinstance(job, jobs.YumRemovePackage):
+ descriptions.append("Removing")
+ elif isinstance(job,
+ (jobs.YumUpdatePackage, jobs.YumUpdateToPackage)):
+ descriptions.append("Updating")
+ elif isinstance(job, jobs.YumCheckPackage):
+ descriptions.append("Verifying")
+ else:
+ descriptions.append("Modifying")
+ cmpi_logging.logger.error("Unhandled job: %s", job)
+ elif isinstance(job, jobs.YumInstallPackageFromURI):
+ if job.state == job.COMPLETED:
+ affected = Identity.pkg2model(job.result_data)
+ descriptions.append("Installing")
+ else:
+ # TODO: this should be somehow obtained from from downloaded
+ # package before installation
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "No SoftwareIdentity is associated to given job.")
+ else:
+ cmpi_logging.logger.error("Unsupported async job: %s", job)
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "No associated SoftwareIdentity.")
+ return (affected, effects, descriptions)
+
+@cmpi_logging.trace_function
+def fill_model_computer_system(model, job, keys_only=True):
+ """
+ Fills model's AffectedElement and all non-key properties.
+ """
+ model["AffectedElement"] = ComputerSystem.get_path()
+ if not keys_only:
+ model["ElementEffects"] = [Values.ElementEffects.Other]
+ description = "Modifying software collection."
+ if isinstance(job, (jobs.YumInstallPackage,
+ jobs.YumInstallPackageFromURI)):
+ description = "Installing software package to collection."
+ elif isinstance(job, jobs.YumRemovePackage):
+ description = "Removing package from software collection."
+ elif isinstance(job, (jobs.YumUpdatePackage, jobs.YumUpdateToPackage)):
+ description = "Updating software package."
+ model["OtherElementEffectsDescriptions"] = [description]
+ return model
+
+@cmpi_logging.trace_function
+def fill_model_system_collection(model, keys_only=True):
+ """
+ Fills model's AffectedElement and all non-key properties.
+ """
+ model["AffectedElement"] = SystemCollection.get_path()
+ if not keys_only:
+ model["ElementEffects"] = [Values.ElementEffects.Exclusive_Use]
+ model["OtherElementEffectsDescriptions"] = [
+ "Package database is locked."
+ ]
+ return model
+
+@cmpi_logging.trace_function
+def fill_model_failed_check(model, failed_check, keys_only=True):
+ """
+ Fills model's AffectedElement and all non-key properties.
+
+ :param failed_check: (``CIMInstanceName``) Is on object path of failed
+ file check.
+ """
+ if not isinstance(failed_check, pywbem.CIMInstanceName):
+ raise TypeError("failed_check must be a CIMInstanceName")
+ model["AffectedElement"] = failed_check
+ if not keys_only:
+ model["ElementEffects"] = [Values.ElementEffects.Other]
+ model["OtherElementEffectsDescriptions"] = [
+ "File did not pass the verification."
+ ]
+ return model
+
+@cmpi_logging.trace_function
+def generate_failed_checks(model, job, keys_only=True):
+ """
+ Generates associations between LMI_SoftwareVerificationJob and
+ LMI_SoftwareIdentityFileCheck for files that did not pass the check.
+ """
+ out_params = Job.get_verification_out_params(job)
+ if not "Failed" in out_params:
+ return
+ for failed in out_params["Failed"].value:
+ yield fill_model_failed_check(model, failed, keys_only)
+
+@cmpi_logging.trace_function
+def generate_models_from_job(job, keys_only=True, model=None):
+ """
+ Generates all associations between job and affected elements.
+ """
+ if not isinstance(job, jobs.YumJob):
+ raise TypeError("pkg must be an instance of PackageInfo or nevra")
+ if model is None:
+ model = pywbem.CIMInstanceName("LMI_AffectedSoftwareJobElement",
+ namespace="root/cimv2")
+ if not keys_only:
+ model = pywbem.CIMInstance("LMI_AffectedSoftwareJobElement",
+ path=model)
+ model["AffectingElement"] = Job.job2model(job)
+ (si, element_effects, element_effects_descriptions) = \
+ job2affected_software_identity(job)
+ model["AffectedElement"] = si
+ if not keys_only:
+ model["ElementEffects"] = element_effects
+ model["OtherElementEffectsDescriptions"] = \
+ element_effects_descriptions
+ yield model
+ if not isinstance(job, jobs.YumCheckPackage):
+ fill_model_system_collection(model, keys_only=keys_only)
+ yield model
+ else: # package verification - associate to failed file checks
+ for model in generate_failed_checks(model, job, keys_only=keys_only):
+ yield model
+ fill_model_computer_system(model, job, keys_only=keys_only)
+ yield model
+