From c87bb1cf9b504b913f6ffde6489918c1419fd1fa Mon Sep 17 00:00:00 2001 From: Michal Minar Date: Thu, 21 Mar 2013 16:45:13 +0100 Subject: added new providers providers added: * LMI_AffectedSoftwareJobElement * LMI_AssociatedSoftwareJobMethodResult * LMI_OwningSoftwareJobElement * LMI_SoftwareMethodResult subclassed job classes defined in LMI_Jobs.mof --- .../software/LMI_AffectedSoftwareJobElement.py | 235 +++++++++++++++++++ .../LMI_AssociatedSoftwareJobMethodResult.py | 248 +++++++++++++++++++++ .../software/LMI_OwningSoftwareJobElement.py | 223 ++++++++++++++++++ .../openlmi/software/LMI_SoftwareMethodResult.py | 162 ++++++++++++++ .../software/core/AffectedSoftwareJobElement.py | 205 +++++++++++++++++ src/software/openlmi/software/core/MethodResult.py | 84 +++++++ 6 files changed, 1157 insertions(+) create mode 100644 src/software/openlmi/software/LMI_AffectedSoftwareJobElement.py create mode 100644 src/software/openlmi/software/LMI_AssociatedSoftwareJobMethodResult.py create mode 100644 src/software/openlmi/software/LMI_OwningSoftwareJobElement.py create mode 100644 src/software/openlmi/software/LMI_SoftwareMethodResult.py create mode 100644 src/software/openlmi/software/core/AffectedSoftwareJobElement.py create mode 100644 src/software/openlmi/software/core/MethodResult.py (limited to 'src/software') diff --git a/src/software/openlmi/software/LMI_AffectedSoftwareJobElement.py b/src/software/openlmi/software/LMI_AffectedSoftwareJobElement.py new file mode 100644 index 0000000..ec1c0ab --- /dev/null +++ b/src/software/openlmi/software/LMI_AffectedSoftwareJobElement.py @@ -0,0 +1,235 @@ +# -*- 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 . + +"""Python Provider for LMI_AffectedSoftwareJobElement + +Instruments the CIM class LMI_AffectedSoftwareJobElement +""" + +import pywbem +from pywbem.cim_provider2 import CIMProvider2 + +from openlmi.common import cmpi_logging +from openlmi.software.core import AffectedSoftwareJobElement +from openlmi.software.core import InstallationJob +from openlmi.software.yumdb import YumDB + +class LMI_AffectedSoftwareJobElement(CIMProvider2): + """Instrument the CIM class LMI_AffectedSoftwareJobElement + + AffectedJobElement represents an association between a Job and the + ManagedElement(s) that may be affected by its execution. It may not be + feasible for the Job to describe all of the affected elements. The + main purpose of this association is to provide information when a Job + requires exclusive use of the 'affected' ManagedElment(s) or when + describing that side effects may result. + """ + + def __init__(self, _env): + cmpi_logging.logger.debug('Initializing provider %s from %s' \ + % (self.__class__.__name__, __file__)) + self.values = AffectedSoftwareJobElement.Values + + @cmpi_logging.trace_method + 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) + """ + (job, affected) = AffectedSoftwareJobElement.check_path(env, model.path) + model['AffectingElement'] = InstallationJob.job2model(job) + if affected.classname == "LMI_SoftwareIdentity": + _, effects, descriptions = AffectedSoftwareJobElement. \ + job2affected_software_identity(job) + model["AffectedElement"] = affected + model["ElementEffects"] = effects + model["OtherElementEffectsDescriptions"] = descriptions + elif affected.classname == "LMI_ComputerSystem": + AffectedSoftwareJobElement.fill_model_computer_system( + model, env, keys_only=False) + elif affected.classname == "LMI_ComputerSystem": + AffectedSoftwareJobElement.fill_model_system_collection( + model, keys_only=False) + else: + cmpi_logging.logger.error("Unhandled classname: %s", + affected.classname) + return model + + @cmpi_logging.trace_method + 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) + """ + model.path.update({'AffectedElement': None, 'AffectingElement': None}) + for job in YumDB.get_instance().get_job_list(): + for mdl in AffectedSoftwareJobElement.generate_models_from_job( + job, keys_only=keys_only, model=model): + yield mdl + + @cmpi_logging.trace_method + 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) + """ + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED) + + @cmpi_logging.trace_method + 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) + """ + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED) + + @cmpi_logging.trace_method + 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) + """ + ch = env.get_cimom_handle() + + if ch.is_subclass(object_name.namespace, + sub=object_name.classname, + super='CIM_ManagedElement') or \ + ch.is_subclass(object_name.namespace, + sub=object_name.classname, + super='CIM_Job'): + return self.simple_refs(env, object_name, model, + result_class_name, role, result_role, keys_only) diff --git a/src/software/openlmi/software/LMI_AssociatedSoftwareJobMethodResult.py b/src/software/openlmi/software/LMI_AssociatedSoftwareJobMethodResult.py new file mode 100644 index 0000000..ace38b5 --- /dev/null +++ b/src/software/openlmi/software/LMI_AssociatedSoftwareJobMethodResult.py @@ -0,0 +1,248 @@ +# -*- 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 . + +"""Python Provider for LMI_AssociatedSoftwareJobMethodResult + +Instruments the CIM class LMI_AssociatedSoftwareJobMethodResult +""" + +import pywbem +from pywbem.cim_provider2 import CIMProvider2 + +from openlmi.common import cmpi_logging +from openlmi.software.core import generate_references +from openlmi.software.core import InstallationJob +from openlmi.software.core import MethodResult +from openlmi.software.yumdb import YumDB + +@cmpi_logging.trace_function +def generate_job_referents(_env, object_name, model, _keys_only): + """ + Handler for referents enumeration request. + """ + job = InstallationJob.object_path2job(object_name) + + model["Job"] = InstallationJob.job2model(job) + model["JobParameters"] = MethodResult.job2model(job) + yield model + +@cmpi_logging.trace_function +def generate_result_referents(_env, object_name, model, _keys_only): + """ + Handler for referents enumeration request. + """ + job = MethodResult.object_path2job(object_name) + + model["Job"] = InstallationJob.job2model(job) + model["JobParameters"] = MethodResult.job2model(job) + yield model + +class LMI_AssociatedSoftwareJobMethodResult(CIMProvider2): + """Instrument the CIM class LMI_AssociatedSoftwareJobMethodResult + + AssociatedJobMethodResult represents an association between a + ConcreteJob and the MethodResult expressing the parameters for the Job + when the job was created by side-effect of the execution of an + extrinsic method. + + """ + + def __init__ (self, _env): + cmpi_logging.logger.debug('Initializing provider %s from %s' \ + % (self.__class__.__name__, __file__)) + + @cmpi_logging.trace_method + 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) + """ + job = InstallationJob.object_path2job(model['Job']) + jobid = MethodResult.object_path2jobid(model['JobParameters']) + if job.jobid != jobid: + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "Job id of Job(%d) does not match JobParameters(%d)." % + (job.jobid, jobid)) + model["Job"] = InstallationJob.job2model(job) + model["JobParameters"] = MethodResult.job2model(job) + return model + + @cmpi_logging.trace_method + 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) + """ + model.path.update({'Job': None, 'JobParameters': None}) + + for job in YumDB.get_instance().get_job_list(): + model['Job'] = InstallationJob.job2model(job) + model['JobParameters'] = MethodResult.job2model(job) + yield model + + @cmpi_logging.trace_method + 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) + """ + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED) + + @cmpi_logging.trace_method + 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) + """ + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED) + + @cmpi_logging.trace_method + 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) + """ + handlers = [ + ("Job", "LMI_SoftwareInstallationJob", generate_job_referents), + ("JobParameters", "LMI_SoftwareMethodResult", + generate_result_referents) + ] + + for ref in generate_references(env, object_name, model, + result_class_name, role, result_role, keys_only, handlers): + yield ref + diff --git a/src/software/openlmi/software/LMI_OwningSoftwareJobElement.py b/src/software/openlmi/software/LMI_OwningSoftwareJobElement.py new file mode 100644 index 0000000..8768c0e --- /dev/null +++ b/src/software/openlmi/software/LMI_OwningSoftwareJobElement.py @@ -0,0 +1,223 @@ +# -*- 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 . + +"""Python Provider for LMI_OwningSoftwareJobElement + +Instruments the CIM class LMI_OwningSoftwareJobElement +""" + +import pywbem +from pywbem.cim_provider2 import CIMProvider2 + +from openlmi.common import cmpi_logging +from openlmi.software.core import InstallationService +from openlmi.software.core import InstallationJob +from openlmi.software.yumdb import YumDB + +class LMI_OwningSoftwareJobElement(CIMProvider2): + """Instrument the CIM class LMI_OwningSoftwareJobElement + + OwningJobElement represents an association between a Job and the + ManagedElement responsible for the creation of the Job. This + association may not be possible, given that the execution of jobs can + move between systems and that the lifecycle of the creating entity may + not persist for the total duration of the job. However, this can be + very useful information when available. This association defines a + more specific 'owner' than is provided by the CIM_Job.Owner string. + """ + + def __init__ (self, _env): + cmpi_logging.logger.debug('Initializing provider %s from %s' \ + % (self.__class__.__name__, __file__)) + + @cmpi_logging.trace_method + 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) + """ + InstallationService.check_path_property(env, model, "OwningElement") + model['OwningElement'] = InstallationService.get_path() + job = InstallationJob.object_path2job(model['OwnedElement']) + model['OwnedElement'] = InstallationJob.job2model(job) + return model + + @cmpi_logging.trace_method + 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) + """ + model.path.update({'OwningElement': None, 'OwnedElement': None}) + model['OwningElement'] = InstallationService.get_path() + for job in YumDB.get_instance().get_job_list(): + model['OwnedElement'] = InstallationJob.job2model(job) + yield model + + @cmpi_logging.trace_method + 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) + """ + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED) + + @cmpi_logging.trace_method + 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) + + """ + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED) + + @cmpi_logging.trace_method + 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) + """ + ch = env.get_cimom_handle() + + if ch.is_subclass(object_name.namespace, + sub=object_name.classname, + super='LMI_SoftwareInstallationService') or \ + ch.is_subclass(object_name.namespace, + sub=object_name.classname, + super='LMI_SoftwareInstallationJob'): + return self.simple_refs(env, object_name, model, + result_class_name, role, result_role, keys_only) diff --git a/src/software/openlmi/software/LMI_SoftwareMethodResult.py b/src/software/openlmi/software/LMI_SoftwareMethodResult.py new file mode 100644 index 0000000..71c3ca9 --- /dev/null +++ b/src/software/openlmi/software/LMI_SoftwareMethodResult.py @@ -0,0 +1,162 @@ +# -*- 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 . + +"""Python Provider for LMI_SoftwareMethodResult + +Instruments the CIM class LMI_SoftwareMethodResult + +""" + +import pywbem +from pywbem.cim_provider2 import CIMProvider2 + +from openlmi.common import cmpi_logging +from openlmi.software.core import MethodResult +from openlmi.software.yumdb import YumDB +class LMI_SoftwareMethodResult(CIMProvider2): + """Instrument the CIM class LMI_SoftwareMethodResult + + Jobs are sometimes used to represent extrinsic method invocations that + execute for times longer than the length of time is reasonable to + require a client to wait. The method executing continues beyond the + method return to the client. The class provides the result of the + execution of a Job that was itself started by the side-effect of this + extrinsic method invocation. The indication instances embedded an + instance of this class shall be the same indications delivered to + listening clients or recorded, all or in part, to logs. Basically, + this approach is a corollary to the functionality provided by an + instance of ListenerDestinationLog (as defined in the Interop Model). + The latter provides a comprehensive, persistent mechanism for + recording Job results, but is also more resource-intensive and + requires supporting logging functionality. Both the extra resources + and logging may not be available in all environments (for example, + embedded environments). Therefore, this instance-based approach is + also provided. The MethodResult instances shall not exist after the + associated ConcreteJob is deleted. + + """ + + def __init__ (self, _env): + cmpi_logging.logger.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) + + """ + job = MethodResult.object_path2job(model.path) + return MethodResult.job2model(job, keys_only=False, model=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) + + """ + # 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({'InstanceID': None}) + + for job in YumDB.get_instance().get_job_list(): + yield MethodResult.job2model(job, keys_only=keys_only, model=model) + + 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) + + """ + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED) + + 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) + + """ + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED) diff --git a/src/software/openlmi/software/core/AffectedSoftwareJobElement.py b/src/software/openlmi/software/core/AffectedSoftwareJobElement.py new file mode 100644 index 0000000..2530104 --- /dev/null +++ b/src/software/openlmi/software/core/AffectedSoftwareJobElement.py @@ -0,0 +1,205 @@ +# -*- 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 . + +""" +Just a common functionality related to AffectedSoftwareJobElement provider. +""" + +import pywbem + +from openlmi.common import cmpi_logging +from openlmi.software import util +from openlmi.software.core import ComputerSystem +from openlmi.software.core import Identity +from openlmi.software.core import InstallationJob +from openlmi.software.core import SystemCollection +from openlmi.software.yumdb import jobs +from openlmi.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 affected object path + """ + if not isinstance(op, pywbem.CIMInstanceName): + raise TypeError("op must be a CIMInstanceName") + ch = env.get_cimom_handle() + + job = op['AffectingElement'] = InstallationJob.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 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() + 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: + 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("Checking") + 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 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"] = InstallationJob.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 + fill_model_system_collection(model, keys_only=keys_only) + yield model + fill_model_computer_system(model, job, keys_only=keys_only) + yield model + diff --git a/src/software/openlmi/software/core/MethodResult.py b/src/software/openlmi/software/core/MethodResult.py new file mode 100644 index 0000000..7bfdac5 --- /dev/null +++ b/src/software/openlmi/software/core/MethodResult.py @@ -0,0 +1,84 @@ +# -*- 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 . + +""" +Just a common functionality related to class LMI_SoftwareMethodResult. +""" + +import pywbem + +from openlmi.common import cmpi_logging +from openlmi.software.yumdb import jobs, errors, YumDB + +@cmpi_logging.trace_function +def object_path2jobid(op): + """ + @param op must contain precise InstanceID of job + """ + if not isinstance(op, pywbem.CIMInstanceName): + raise TypeError("op must be a CIMInstanceName") + if not op["InstanceID"].lower().startswith('lmi:softwaremethodresult:'): + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "Missing 'LMI:SoftwareMethodResult:' prefix in InstanceID.") + instid = op['InstanceID'][len('LMI:SoftwareMethodResult:'):] + try: + instid = int(instid) + except ValueError: + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "Failed to parse InstanceID.") + return instid + +@cmpi_logging.trace_function +def object_path2job(op): + """ + @param op must contain precise InstanceID of job + """ + instid = object_path2jobid(op) + try: + return YumDB.get_instance().get_job(instid) + except errors.JobNotFound: + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, "No such job.") + +@cmpi_logging.trace_function +def job2model(job, keys_only=True, model=None): + """ + This accepts job's id and produces corresponding result model. + """ + if not isinstance(job, jobs.YumJob): + raise TypeError("job must be an instance of YumJob") + if model is None: + model = pywbem.CIMInstanceName("LMI_SoftwareMethodResult", + namespace="root/cimv2") + if not keys_only: + model = pywbem.CIMInstance("LMI_SoftwareMethodResult", path=model) + model['InstanceID'] = "LMI:SoftwareMethodResult:"+str(job.jobid) + if not keys_only: + model.path['InstanceID'] = model['InstanceID'] #pylint: disable=E1103 + model['Caption'] = 'Result of method %s' % job.metadata['method_name'] + model['Description'] = ( + 'Result of asynchronous job number %d created upon invocation' + " of %s's %s method." % (job.jobid, + "LMI_SoftwareInstallationService", + job.metadata['method_name'])) + model['ElementName'] = 'MethodResult-%d' % job.jobid + #model['PostCallIndication'] = \ # TODO + #pywbem.CIMInstance(classname='CIM_InstMethodCall', ...) + #model['PreCallIndication'] = \ # TODO + #pywbem.CIMInstance(classname='CIM_InstMethodCall', ...) + return model + -- cgit