diff options
author | Peter Schiffer <pschiffe@redhat.com> | 2013-04-17 14:53:52 +0200 |
---|---|---|
committer | Peter Schiffer <pschiffe@redhat.com> | 2013-04-17 14:53:52 +0200 |
commit | e50932e4ae49d9fbb4848197763851211b404227 (patch) | |
tree | 8f1e08e01fb4d17bb3a37c0e81dd07d03c720794 | |
parent | a8b751d7c530e103910885c757a2e36abefe625d (diff) | |
parent | c14bd833b7b1b3b1283d116a87b6f293377f129b (diff) | |
download | openlmi-providers-e50932e4ae49d9fbb4848197763851211b404227.tar.gz openlmi-providers-e50932e4ae49d9fbb4848197763851211b404227.tar.xz openlmi-providers-e50932e4ae49d9fbb4848197763851211b404227.zip |
Merge branch 'master' of ssh://git.fedorahosted.org/git/openlmi-providers
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | cmake/modules/FindOpenLMI.cmake | 21 | ||||
-rw-r--r-- | src/CMakeLists.txt | 16 | ||||
-rw-r--r-- | src/fan/LMI_FanAssociatedSensorProvider.c | 2 | ||||
-rw-r--r-- | src/fan/LMI_FanSensorProvider.c | 2 | ||||
-rw-r--r-- | src/globals.h | 19 | ||||
-rw-r--r-- | src/hardware/dmidecode.h | 1 | ||||
-rw-r--r-- | src/hardware/lscpu.h | 1 | ||||
-rw-r--r-- | src/hardware/procfs.h | 1 | ||||
-rw-r--r-- | src/hardware/sysfs.h | 1 | ||||
-rw-r--r-- | src/openlmi.c (renamed from src/globals.c) | 69 | ||||
-rw-r--r-- | src/openlmi.h | 80 | ||||
-rw-r--r-- | src/openlmi.pc.in | 10 | ||||
-rw-r--r-- | src/python/openlmi/common/IndicationManager.py | 2 | ||||
-rw-r--r-- | src/python/openlmi/common/JobManager.py | 161 |
15 files changed, 293 insertions, 94 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 230ed26..b42debc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,3 +39,4 @@ install(PROGRAMS openlmi-register-pegasus DESTINATION libexec) install(FILES cmake/modules/OpenLMIMacros.cmake DESTINATION share/cmake/Modules) install(FILES cmake/modules/FindCMPI.cmake DESTINATION share/cmake/Modules) install(FILES cmake/modules/FindKonkretCMPI.cmake DESTINATION share/cmake/Modules) +install(FILES cmake/modules/FindOpenLMI.cmake DESTINATION share/cmake/Modules) diff --git a/cmake/modules/FindOpenLMI.cmake b/cmake/modules/FindOpenLMI.cmake new file mode 100644 index 0000000..d4338ca --- /dev/null +++ b/cmake/modules/FindOpenLMI.cmake @@ -0,0 +1,21 @@ + +find_path(OPENLMI_INCLUDE_DIR + NAMES openlmi.h + HINTS $ENV{OPENLMI_INCLUDE_DIR} + PATH_SUFFIXES include/openlmi + PATHS /usr /usr/local +) + +find_library(OPENLMICOMMON_LIBRARY + NAMES openlmicommon + HINTS $ENV{OPENLMI_LIB_DIR} + PATH_SUFFIXES lib64 lib + PATHS /usr /usr/local +) + +set(OPENLMI_LIBRARIES ${OPENLMICOMMON_LIBRARY}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OPENLMI DEFAULT_MSG OPENLMI_LIBRARIES OPENLMI_INCLUDE_DIR) + +mark_as_advanced(OPENLMI_INCLUDE_DIR OPENLMI_LIBRARIES) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7318911..d5335a6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,13 +1,21 @@ -include_directories(.) +include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMPI_INCLUDE_DIR}) add_library(openlmicommon SHARED - globals.c + openlmi.c ) -set_target_properties(openlmicommon PROPERTIES SOVERSION 0.0.1) +set(OPENLMICOMMON_VERSION_MAJOR 0) +set(OPENLMICOMMON_VERSION_MINOR 0) +set(OPENLMICOMMON_VERSION_PATCH 1) +set(OPENLMICOMMON_VERSION "${OPENLMICOMMON_VERSION_MAJOR}.${OPENLMICOMMON_VERSION_MINOR}.${OPENLMICOMMON_VERSION_PATCH}") + +set_target_properties(openlmicommon PROPERTIES VERSION ${OPENLMICOMMON_VERSION}) +set_target_properties(openlmicommon PROPERTIES SOVERSION ${OPENLMICOMMON_VERSION_MAJOR}) install(TARGETS openlmicommon DESTINATION lib${LIB_SUFFIX}) -install(FILES globals.h DESTINATION include/openlmi) +install(FILES openlmi.h DESTINATION include/openlmi) +configure_file(openlmi.pc.in openlmi.pc @ONLY) +install(FILES openlmi.pc DESTINATION lib${LIB_SUFFIX}/pkgconfig) if (WITH-FAN) add_subdirectory(fan) diff --git a/src/fan/LMI_FanAssociatedSensorProvider.c b/src/fan/LMI_FanAssociatedSensorProvider.c index d75bf5c..b462e83 100644 --- a/src/fan/LMI_FanAssociatedSensorProvider.c +++ b/src/fan/LMI_FanAssociatedSensorProvider.c @@ -21,7 +21,7 @@ #include <konkret/konkret.h> #include "LMI_FanAssociatedSensor.h" #include "fan.h" -#include <globals.h> +#include "globals.h" static const CMPIBroker* _cb; diff --git a/src/fan/LMI_FanSensorProvider.c b/src/fan/LMI_FanSensorProvider.c index 47bd9d5..e63d266 100644 --- a/src/fan/LMI_FanSensorProvider.c +++ b/src/fan/LMI_FanSensorProvider.c @@ -22,7 +22,7 @@ #include <konkret/konkret.h> #include "LMI_FanSensor.h" #include "fan.h" -#include <globals.h> +#include "globals.h" static const CMPIBroker* _cb = NULL; diff --git a/src/globals.h b/src/globals.h index a1cb18c..094602f 100644 --- a/src/globals.h +++ b/src/globals.h @@ -21,19 +21,16 @@ #ifndef GLOBALS_H #define GLOBALS_H -const char *get_system_name(); +#include "openlmi.h" -const char *get_system_creation_class_name(); - -int log_level(void); -void set_log_level(int level); - -enum { NONE=0, ERROR, WARN, DEBUG }; -void _debug(int level, const char *file, int line, const char *format, ...); -#define debug(...) _debug(DEBUG, __FILE__, __LINE__, __VA_ARGS__) -#define warn(...) _debug(WARN, __FILE__, __LINE__, __VA_ARGS__) -#define error(...) _debug(ERROR, __FILE__, __LINE__, __VA_ARGS__) +// Shortcuts for functions and macros from openlmicommon library +#define get_system_creation_class_name lmi_get_system_creation_class_name +#define get_system_name lmi_get_system_name +#define debug lmi_debug +#define warn lmi_warn +#define error lmi_error #define ORGID "LMI" + #endif diff --git a/src/hardware/dmidecode.h b/src/hardware/dmidecode.h index 91eda85..d3320ea 100644 --- a/src/hardware/dmidecode.h +++ b/src/hardware/dmidecode.h @@ -24,7 +24,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "globals.h" #include "utils.h" diff --git a/src/hardware/lscpu.h b/src/hardware/lscpu.h index 5dc5bd5..39c85b6 100644 --- a/src/hardware/lscpu.h +++ b/src/hardware/lscpu.h @@ -24,7 +24,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "globals.h" #include "utils.h" diff --git a/src/hardware/procfs.h b/src/hardware/procfs.h index 4bcdf61..3545398 100644 --- a/src/hardware/procfs.h +++ b/src/hardware/procfs.h @@ -24,7 +24,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "globals.h" #include "utils.h" diff --git a/src/hardware/sysfs.h b/src/hardware/sysfs.h index 0e0b523..028b559 100644 --- a/src/hardware/sysfs.h +++ b/src/hardware/sysfs.h @@ -27,7 +27,6 @@ #include <dirent.h> #include <errno.h> #include <limits.h> -#include "globals.h" #include "utils.h" #define SYSFS_CPU_PATH "/sys/devices/system/cpu" diff --git a/src/globals.c b/src/openlmi.c index 7e58817..786bdd2 100644 --- a/src/globals.c +++ b/src/openlmi.c @@ -18,7 +18,7 @@ * Authors: Radek Novacek <rnovacek@redhat.com> */ -#include "globals.h" +#include "openlmi.h" #include <stdlib.h> #include <stdarg.h> @@ -27,11 +27,14 @@ #include <string.h> #include <netdb.h> #include <stdio.h> +#include <cmpimacs.h> static char *_fqdn = NULL; -static int _log_level = DEBUG; +static int _log_level = _LMI_DEBUG_DEBUG; +static const CMPIBroker *_cb = NULL; +static char *_log_id = NULL; -char *getFQDN(void) +static char *getFQDN(void) { struct utsname uts; if ((uname(&uts) > 0) && (uts.nodename != NULL)) { @@ -66,7 +69,7 @@ char *getFQDN(void) return strdup(hostname); } -const char *get_system_name() +const char *lmi_get_system_name() { if (_fqdn == NULL) { _fqdn = getFQDN(); @@ -74,25 +77,63 @@ const char *get_system_name() return _fqdn; } -const char *get_system_creation_class_name() +const char *lmi_get_system_creation_class_name() { return "Linux_ComputerSystem"; } -void _debug(int level, const char *file, int line, const char *format, ...) +void lmi_init_logging(const char *log_id, const CMPIBroker *cb) { - if (level > _log_level) { - return; + if (_log_id != NULL) { + free(_log_id); + } + _log_id = strdup(log_id); + _cb = cb; +} + +int lmi_log_level(void) +{ + return _log_level; +} + +void lmi_set_log_level(int level) +{ + _log_level = level; +} + +void _lmi_debug(int level, const char *file, int line, const char *format, ...) +{ + const char *lvl[] = { "NONE", "ERROR", "INFO", "WARNING", "DEBUG" }; + if (level > 4) { + level = 4; + } + if (level < 1) { + level = 1; } - FILE *trace_file = stderr; - const char *lvl[] = { "NONE", "ERROR", "WARNING", "DEBUG" }; - // TODO: use logger from sfcbd and pegasus - fprintf(trace_file, "[%s] %s:%d\t", lvl[level], file, line); + char *message, *text; va_list args; va_start(args, format); - vfprintf(stderr, format, args); + vasprintf(&message, format, args); va_end(args); + asprintf(&text, "[%s] %s:%d\t%s", lvl[level], file, line, message); + free(message); + + CMPIStatus rc; + rc.rc = CMPI_RC_OK; + if (_cb != NULL) { + // try to use standard CMPI logging + rc = _cb->eft->trace(_cb, CMPI_LEV_INFO, _log_id, text, NULL); + } + + if (_cb == NULL || rc.rc != CMPI_RC_OK) { + // Fallback to stderr + if (level > _log_level) { + free(text); + return; + } - fprintf(stderr, "\n"); + fprintf(stderr, "%s\n", text); + } + free(text); } diff --git a/src/openlmi.h b/src/openlmi.h new file mode 100644 index 0000000..9b27d07 --- /dev/null +++ b/src/openlmi.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2012-2013 Red Hat, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Radek Novacek <rnovacek@redhat.com> + */ + +#ifndef OPENLMI_H +#define OPENLMI_H + +#include <cmpidt.h> + +/** + * This function returns FQDN (fully qualified domain name) of the machine + * + * @note Use this in the SystemName property of all provider created instances. + * + * @return The scoping System's Name. + */ +const char *lmi_get_system_name(); + +/** + * This function returns system creation class name + * + * @note Use this in the SystemCreationClassName property of all provider + * created instances. + * + * @return The scoping System's Creation class name. + */ +const char *lmi_get_system_creation_class_name(); + +/** + * To use standard CIMOM logging facility, broker must be assigned. Without + * calling this function, logging will go to stderr. + * + * \p log_id Identification of log messages + * \p cb CMPIBroker + */ +void lmi_init_logging(const char *log_id, const CMPIBroker *cb); + +/** + * Get currently set logging level + * + * @return logging level + */ +int lmi_log_level(void); + +/** + * Set logging level + * + * @param level new logging level + */ +void lmi_set_log_level(int level); + +enum { + _LMI_DEBUG_NONE=0, _LMI_DEBUG_ERROR, _LMI_DEBUG_WARN, + _LMI_DEBUG_INFO, _LMI_DEBUG_DEBUG +}; + +void _lmi_debug(int level, const char *file, int line, const char *format, ...); + +#define lmi_debug(...) _lmi_debug(_LMI_DEBUG_DEBUG, __FILE__, __LINE__, __VA_ARGS__) +#define lmi_info(...) _lmi_debug(_LMI_DEBUG_INFO, __FILE__, __LINE__, __VA_ARGS__) +#define lmi_warn(...) _lmi_debug(_LMI_DEBUG_WARN, __FILE__, __LINE__, __VA_ARGS__) +#define lmi_error(...) _lmi_debug(_LMI_DEBUG_ERROR, __FILE__, __LINE__, __VA_ARGS__) + +#endif diff --git a/src/openlmi.pc.in b/src/openlmi.pc.in new file mode 100644 index 0000000..939d672 --- /dev/null +++ b/src/openlmi.pc.in @@ -0,0 +1,10 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +includedir=${prefix}/include +libdir=${exec_prefix}/lib@LIB_SUFFIX@ + +Name: openlmi +Description: OpenLMI provider support +Version: @OPENLMICOMMON_VERSION@ +Libs: -L${libdir} -lopenlmicommon +CFlags: -I${includedir}/openlmi diff --git a/src/python/openlmi/common/IndicationManager.py b/src/python/openlmi/common/IndicationManager.py index dbe25f3..b517373 100644 --- a/src/python/openlmi/common/IndicationManager.py +++ b/src/python/openlmi/common/IndicationManager.py @@ -252,6 +252,7 @@ class IndicationManager(singletonmixin.Singleton): """ SEVERITY_INFO = pywbem.Uint16(2) # CIM_Indication.PerceivedSeverity + @cmpi_logging.trace_method def __init__(self, env, nameprefix, namespace, ns_interop=None, queue=None): """ @@ -668,7 +669,6 @@ class IndicationManager(singletonmixin.Singleton): return ( class_name in self._filters and fltr_id in self._filters[class_name]) - @cmpi_logging.trace_method def _send_indications_loop(self, broker): """ This method runs in its own thread. It just sends all enqueued diff --git a/src/python/openlmi/common/JobManager.py b/src/python/openlmi/common/JobManager.py index a923f29..bb6fed8 100644 --- a/src/python/openlmi/common/JobManager.py +++ b/src/python/openlmi/common/JobManager.py @@ -49,6 +49,7 @@ import pywbem import openlmi.common.cmpi_logging as cmpi_logging from pywbem.cim_provider2 import CIMProvider2 import socket +import traceback # Too many instance attributes # pylint: disable-msg=R0902 @@ -208,7 +209,7 @@ class Job(object): @cmpi_logging.trace_method def finish_method(self, new_state, return_value=None, return_type=None, - output_arguments=None, error=None): + output_arguments=None, error=None, affected_elements=None): """ Mark the job as finished, with given return value, output parameters and error. @@ -224,12 +225,18 @@ class Job(object): any output parameters. :param error: (``CIMError``) Error raised by the job. Can be None, when the job finished successfully. + :param affected_elements: (``array of CIMInstanceName``) New list of + affected elements to generate LMI_<name>JobAffectedElement + association. If None, the old list, passed to constructor, remains + untouched. """ self.lock() self.return_value = return_value self.return_value_type = return_type self.output_arguments = output_arguments self.error = error + if affected_elements is not None: + self.affected_elements = affected_elements self.change_state(new_state, 100) self.unlock() @@ -310,14 +317,13 @@ class Job(object): self._restart_timer() self.unlock() - @cmpi_logging.trace_method def _expire(self): """ Callback when a Job completes and time_before_removal second passed. The job gets removed from its JobManager. """ - cmpi_logging.logger.debug("Got timeout for job %s: '%s', removing" - " the job" % (self.the_id, self.job_name)) + # We cannot log here, this method is executed in job's Timer thread, + # which is not registered at the cimom. self.job_manager.remove_job(self) @cmpi_logging.trace_method @@ -370,8 +376,16 @@ class Job(object): try: self._execute(*(self._execargs), **(self._execkwargs)) except pywbem.CIMError, error: + cmpi_logging.logger.trace_warn("Job.execute caught an CIMError %s", + str(error)) + cmpi_logging.logger.trace_verbose("traceback: %s", + traceback.format_exc()) self.finish_method(Job.STATE_FAILED, error=error) except Exception, ex: + cmpi_logging.logger.trace_warn("Job.execute caught an Exception %s", + str(ex)) + cmpi_logging.logger.trace_verbose("traceback: %s", + traceback.format_exc()) error = pywbem.CIMError(pywbem.CIM_ERR_FAILED, str(ex)) self.finish_method(Job.STATE_FAILED, error=error) @@ -455,18 +469,14 @@ class Job(object): namespace=self.job_manager.namespace) inst = pywbem.CIMInstance( classname="CIM_InstMethodCall", - path=path, - properties={ - 'MethodName' : self.method_name, - 'MethodParameters' : pywbem.CIMProperty( - name="MethodParameters", - type='instance', - value=self._get_method_params(False)), - 'PreCall' : True, - }) + path=path) src_instance = self._get_cim_instance() inst['SourceInstance'] = src_instance inst['SourceInstanceModelPath'] = str(src_instance.path) + inst['MethodName'] = self.method_name + inst['MethodParameters'] = self.get_method_params( + '__MethodParameters', True, False) + inst['PreCall'] = True return inst @cmpi_logging.trace_method @@ -484,22 +494,31 @@ class Job(object): namespace=self.job_manager.namespace) inst = pywbem.CIMInstance( classname="CIM_InstMethodCall", - path=path, - properties={ - 'MethodName' : self.method_name, - 'MethodParameters' : self._get_method_params(True), - 'PreCall' : False - }) + path=path) + src_instance = self._get_cim_instance() inst['SourceInstance'] = src_instance inst['SourceInstanceModelPath'] = str(src_instance.path) + inst['MethodName'] = self.method_name + inst['MethodParameters'] = self.get_method_params( + '__MethodParameters', True, True) + inst['PreCall'] = False if self.return_value_type is not None: inst['ReturnValueType'] = self.return_value_type if self.return_value is not None: - inst['ReturnValue'] = self.return_value + inst['ReturnValue'] = str(self.return_value) if self.error is not None: - inst['Error'] = self.error + path = pywbem.CIMInstanceName( + classname="CIM_Error", + host=socket.gethostname(), + namespace=self.job_manager.namespace) + err = pywbem.CIMInstance( + classname="CIM_Error", + path=path) + err['CIMStatusCode'] = pywbem.Uint32(self.error[0]) + err['Message'] = self.error[1] + inst['Error'] = [err, ] return inst @cmpi_logging.trace_method @@ -512,20 +531,31 @@ class Job(object): return self.job_manager.get_job_instance(self) @cmpi_logging.trace_method - def _get_method_params(self, output=True): + def get_method_params(self, class_name, include_input, include_output): """ - Assemble __MethodParameters for CIM_InstMethodCall indication. - - :rtype: CIMInstance of __MethodParameters. + Create a class of given name with all input or output parameters + of the asynchronous method. Typically used to assemble + CIM_ConcreteJob.JobInParameters or CIM_InstMethodCall.MethodParameters + values. + + :param class_name: (``string``) Name of the class to create. + :param input: (``boolean``) Whether input parameters should be + included in the returned class + :param output: (``boolean``) Whether output parameters should be + included in the returned class + :rtype: CIMInstance of the created class. """ + # TODO: this is workaround for bug #920763, use class_name + # when it's fixed + clsname = "CIM_ManagedElement" path = pywbem.CIMInstanceName( - classname="__MethodParameters", - namespace=self.job_manager.namespace, - keybindings={}) - inst = pywbem.CIMInstance(classname="__MethodParameters", path=path) - for (name, value) in self.input_arguments.iteritems(): - inst[name] = value - if output: + classname=clsname, + namespace=self.job_manager.namespace) + inst = pywbem.CIMInstance(classname=clsname, path=path) + if include_input and self.input_arguments: + for (name, value) in self.input_arguments.iteritems(): + inst[name] = value + if include_output and self.output_arguments: # overwrite any input parameter for (name, value) in self.output_arguments.iteritems(): inst[name] = value @@ -599,11 +629,11 @@ class JobManager(object): timeout. """ - IND_JOB_PERCENT_UPDATED = "JobPercentUpdated" - IND_JOB_SUCCEEDED = "JobSucceeded" - IND_JOB_FAILED = "JobFailed" - IND_JOB_CHANGED = "JobChanged" - IND_JOB_CREATED = "JobCreated" + IND_JOB_PERCENT_UPDATED = "PercentUpdated" + IND_JOB_SUCCEEDED = "Succeeded" + IND_JOB_FAILED = "Failed" + IND_JOB_CHANGED = "Changed" + IND_JOB_CREATED = "Created" @cmpi_logging.trace_method def __init__(self, name, namespace, indication_manager): @@ -633,7 +663,7 @@ class JobManager(object): # Start the worker thread (don't forget to register it at CIMOM) self.worker = threading.Thread(target=self._worker_main) - self.worker.daemon=True + self.worker.daemon = True self.worker.start() # Various classnames for job-related classes, with correct infixes. @@ -656,7 +686,7 @@ class JobManager(object): filters = { self.IND_JOB_PERCENT_UPDATED: { "Query" : "SELECT * FROM CIM_InstModification WHERE " - "SourceInstance ISA CIM_ConcreteJob AND " + "SourceInstance ISA %(classname)s AND " "SourceInstance.CIM_ConcreteJob::PercentComplete <> " "PreviousInstance.CIM_ConcreteJob::PercentComplete", "Description" : "Modification of Percentage Complete for a " @@ -664,36 +694,35 @@ class JobManager(object): }, self.IND_JOB_SUCCEEDED: { "Query" : "SELECT * FROM CIM_InstModification WHERE " - "SourceInstance ISA CIM_ConcreteJob AND ANY " - "SourceInstance.CIM_ConcreteJob::OperationalStatus[*] = 17 " - "AND ANY " - "SourceInstance.CIM_ConcreteJob::OperationalStatus[*] = 2", - "Description": "Modification of Operational Status for a " - "Concrete Job to 'Complete' and 'OK'.", + "SourceInstance ISA %(classname)s AND " + "SourceInstance.CIM_ConcreteJob::JobState = 17", + "Description": "Modification of Job State for a " + "Concrete Job to 'Complete'.", }, self.IND_JOB_FAILED: { "Query" : "SELECT * FROM CIM_InstModification WHERE " - "SourceInstance ISA CIM_ConcreteJob AND ANY " - "SourceInstance.CIM_ConcreteJob::OperationalStatus[*] = 17 " - "AND ANY " - "SourceInstance.CIM_ConcreteJob::OperationalStatus[*] = 6", - "Description": "Modification of Operational Status for a " - "Concrete Job to 'Complete' and 'Error'.", + "SourceInstance ISA %(classname)s AND " + "SourceInstance.CIM_ConcreteJob::JobState = 10", + "Description": "Modification of Job State for a " + "Concrete Job to 'Exception'.", }, self.IND_JOB_CHANGED: { "Query" : "SELECT * FROM CIM_InstModification WHERE " - "SourceInstance ISA CIM_ConcreteJob AND " + "SourceInstance ISA %(classname)s AND " "SourceInstance.CIM_ConcreteJob::JobState <> " "PreviousInstance.CIM_ConcreteJob::JobState", "Description": "Modification of Job State for a ConcreteJob.", }, self.IND_JOB_CREATED: { "Query" : "SELECT * FROM CIM_InstCreation WHERE " - "SourceInstance ISA CIM_ConcreteJob", + "SourceInstance ISA %(classname)s", "Description": "Creation of a ConcreteJob.", }, } - self.indication_manager.add_filters(filters) + # add class name + for f in filters.itervalues(): + f['Query'] = f['Query'] % {"classname" : self.job_classname } + self.indication_manager.add_filters(self.job_classname, filters) @cmpi_logging.trace_method def get_providers(self): @@ -745,7 +774,8 @@ class JobManager(object): self.jobs[job.the_id] = job self.queue.put(job) # send indication - if self.indication_manager.is_subscribed(self.IND_JOB_CREATED): + if self.indication_manager.is_subscribed( + self.job_classname, self.IND_JOB_CREATED): job_instance = self.get_job_instance(job) self.indication_manager.send_instcreation( job_instance, self.IND_JOB_CREATED) @@ -765,7 +795,6 @@ class JobManager(object): self.indication_manager.send_instmodification(prev_instance, current_instance, _id) - @cmpi_logging.trace_method def remove_job(self, job): """ Remove existing job. Note that jobs are removed automatically after a @@ -773,8 +802,8 @@ class JobManager(object): :param job: (``Job``) Job to remove. """ - cmpi_logging.logger.debug("Removing job %s: '%s'" - % (job.the_id, job.job_name)) + # We cannot log here, this method is executed in job's Timer thread, + # which is not registered at the cimom. del self.jobs[job.the_id] # The job may still be in the queue! # There is no way, how to remove it, it will be skipped by the @@ -964,6 +993,17 @@ class LMI_ConcreteJob(CIMProvider2): value=None, type='datetime') + if job.input_arguments: + model['JobInParameters'] = job.get_method_params( + "__JobInParameters", True, False) + + if job.job_state in Job.FINAL_STATES: + # assemble output parameters with return value + outparams = job.get_method_params("__JobOutParameters", False, True) + if job.return_value is not None: + outparams['__ReturnValue'] = job.return_value + model['JobOutParameters'] = outparams + model['TimeSubmitted'] = pywbem.CIMDateTime(job.time_submitted) # set correct state jobstate, opstate = self.get_job_states(job) @@ -1383,6 +1423,9 @@ class LMI_AffectedJobElement(CIMProvider2): raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, "AffectingElement not found.") + if job.affected_elements is None: + raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, + "The AffectingElement has no AffectedElement.") if model['AffectedElement'] not in job.affected_elements: raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, "AffectedElement is not associated to AffectingElement.") @@ -1394,6 +1437,8 @@ class LMI_AffectedJobElement(CIMProvider2): """Enumerate instances.""" model.path.update({'AffectingElement': None, 'AffectedElement': None}) for job in self.job_manager.jobs.values(): + if job.affected_elements is None: + continue for element in job.affected_elements: model['AffectingElement'] = job.get_name() model['AffectedElement'] = element |