From c15f9ee5a0e25a91781e4c23f1cfb0ca7c5b7336 Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Fri, 18 Oct 2013 14:45:03 +0200 Subject: Rework documentation. - Everything is in openlmi-providers/doc/admin directory. - 'make doc' automatically builds documentation of all enabled providers. - Documentation shares one 'conf.py' for sphinx. - All documentation uses the same directory structure. There is only one CMakefile.txt to generate all the docs. --- doc/CMakeLists.txt | 1 + doc/admin/CMakeLists.txt | 138 ++++++ doc/admin/README | 55 +++ doc/admin/account/dmtf-profile.rst | 79 ++++ doc/admin/account/index.rst | 30 ++ doc/admin/account/usage.rst | 241 +++++++++++ doc/admin/conf.py | 297 +++++++++++++ doc/admin/fan/dmtf.rst | 144 +++++++ doc/admin/fan/index.rst | 27 ++ doc/admin/fan/usage.rst | 48 +++ doc/admin/hardware/dmtf-profiles.rst | 135 ++++++ doc/admin/hardware/index.rst | 27 ++ doc/admin/hardware/info.rst | 142 +++++++ doc/admin/header.txt | 2 + doc/admin/journald/index.rst | 91 ++++ doc/admin/journald/usage.rst | 55 +++ doc/admin/logicalfile/index.rst | 27 ++ doc/admin/logicalfile/usage.rst | 169 ++++++++ doc/admin/power/concepts.rst | 19 + doc/admin/power/index.rst | 21 + doc/admin/power/introduction.rst | 16 + doc/admin/power/pic/make-svg.sh | 10 + doc/admin/power/pic/plantuml.cfg | 3 + doc/admin/power/pic/powermanagement.svg | 1 + doc/admin/power/pic/powermanagement.uml | 15 + doc/admin/power/usage.rst | 43 ++ doc/admin/realmd/index.rst | 24 ++ doc/admin/realmd/usage.rst | 47 +++ doc/admin/service-dbus/index.rst | 27 ++ doc/admin/service-dbus/usage.rst | 46 ++ doc/admin/software/configuration.rst | 155 +++++++ doc/admin/software/dmtf.rst | 300 +++++++++++++ doc/admin/software/index.rst | 29 ++ doc/admin/software/introduction.rst | 158 +++++++ doc/admin/software/pic/Makefile | 16 + doc/admin/software/pic/software-profile.dia | Bin 0 -> 5319 bytes doc/admin/software/pic/software-profile.svg | 255 ++++++++++++ doc/admin/software/usage.rst | 625 ++++++++++++++++++++++++++++ 38 files changed, 3518 insertions(+) create mode 100644 doc/CMakeLists.txt create mode 100644 doc/admin/CMakeLists.txt create mode 100644 doc/admin/README create mode 100644 doc/admin/account/dmtf-profile.rst create mode 100644 doc/admin/account/index.rst create mode 100644 doc/admin/account/usage.rst create mode 100644 doc/admin/conf.py create mode 100644 doc/admin/fan/dmtf.rst create mode 100644 doc/admin/fan/index.rst create mode 100644 doc/admin/fan/usage.rst create mode 100644 doc/admin/hardware/dmtf-profiles.rst create mode 100644 doc/admin/hardware/index.rst create mode 100644 doc/admin/hardware/info.rst create mode 100644 doc/admin/header.txt create mode 100644 doc/admin/journald/index.rst create mode 100644 doc/admin/journald/usage.rst create mode 100644 doc/admin/logicalfile/index.rst create mode 100644 doc/admin/logicalfile/usage.rst create mode 100644 doc/admin/power/concepts.rst create mode 100644 doc/admin/power/index.rst create mode 100644 doc/admin/power/introduction.rst create mode 100755 doc/admin/power/pic/make-svg.sh create mode 100644 doc/admin/power/pic/plantuml.cfg create mode 100644 doc/admin/power/pic/powermanagement.svg create mode 100644 doc/admin/power/pic/powermanagement.uml create mode 100644 doc/admin/power/usage.rst create mode 100644 doc/admin/realmd/index.rst create mode 100644 doc/admin/realmd/usage.rst create mode 100644 doc/admin/service-dbus/index.rst create mode 100644 doc/admin/service-dbus/usage.rst create mode 100644 doc/admin/software/configuration.rst create mode 100644 doc/admin/software/dmtf.rst create mode 100644 doc/admin/software/index.rst create mode 100644 doc/admin/software/introduction.rst create mode 100644 doc/admin/software/pic/Makefile create mode 100644 doc/admin/software/pic/software-profile.dia create mode 100644 doc/admin/software/pic/software-profile.svg create mode 100644 doc/admin/software/usage.rst (limited to 'doc') diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 0000000..df7e47e --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(admin) diff --git a/doc/admin/CMakeLists.txt b/doc/admin/CMakeLists.txt new file mode 100644 index 0000000..887fe4f --- /dev/null +++ b/doc/admin/CMakeLists.txt @@ -0,0 +1,138 @@ +# Array of names of provider directories. +set(PROVIDERS "") + +# Array of names of the providers +set(PROVIDER_CAPTIONS "") + +# Array of MOF files to generate class references from +set(PROVIDER_MOFS "") + +# Collect properties of enabled providers +if (WITH-ACCOUNT) + set(PROVIDERS ${PROVIDERS} "account") + set(PROVIDER_CAPTIONS ${PROVIDER_CAPTIONS} "Account") + set(PROVIDER_MOFS ${PROVIDER_MOFS} "60_LMI_Account.mof") +endif (WITH-ACCOUNT) + +if (WITH-FAN) + set(PROVIDERS ${PROVIDERS} "fan") + set(PROVIDER_CAPTIONS ${PROVIDER_CAPTIONS} "Fan") + set(PROVIDER_MOFS ${PROVIDER_MOFS} "60_LMI_Fan.mof") +endif (WITH-FAN) + +if (WITH-HARDWARE) + set(PROVIDERS ${PROVIDERS} "hardware") + set(PROVIDER_CAPTIONS ${PROVIDER_CAPTIONS} "Hardware") + set(PROVIDER_MOFS ${PROVIDER_MOFS} "60_LMI_Hardware.mof") +endif (WITH-HARDWARE) + +if (WITH-JOURNALD) + set(PROVIDERS ${PROVIDERS} "journald") + set(PROVIDER_CAPTIONS ${PROVIDER_CAPTIONS} "journald") + set(PROVIDER_MOFS ${PROVIDER_MOFS} "60_LMI_Journald.mof") +endif (WITH-JOURNALD) + +if (WITH-LOGICALFILE) + set(PROVIDERS ${PROVIDERS} "logicalfile") + set(PROVIDER_CAPTIONS ${PROVIDER_CAPTIONS} "Logical File") + set(PROVIDER_MOFS ${PROVIDER_MOFS} "60_LMI_LogicalFile.mof") +endif (WITH-LOGICALFILE) + +if (WITH-POWER) + set(PROVIDERS ${PROVIDERS} "power") + set(PROVIDER_CAPTIONS ${PROVIDER_CAPTIONS} "Power Management") + set(PROVIDER_MOFS ${PROVIDER_MOFS} "60_LMI_PowerManagement.mof") +endif (WITH-POWER) + +if (WITH-REALMD) + set(PROVIDERS ${PROVIDERS} "realmd") + set(PROVIDER_CAPTIONS ${PROVIDER_CAPTIONS} "Realmd") + set(PROVIDER_MOFS ${PROVIDER_MOFS} "60_LMI_Realmd.mof") +endif (WITH-REALMD) + +if (WITH-SERVICE) + set(PROVIDERS ${PROVIDERS} "service-dbus") + set(PROVIDER_CAPTIONS ${PROVIDER_CAPTIONS} "Service") + set(PROVIDER_MOFS ${PROVIDER_MOFS} "60_LMI_Service.mof") +endif (WITH-SERVICE) + +if (WITH-SOFTWARE) + set(PROVIDERS ${PROVIDERS} "software") + set(PROVIDER_CAPTIONS ${PROVIDER_CAPTIONS} "Software") + set(PROVIDER_MOFS ${PROVIDER_MOFS} "60_LMI_Software.mof") +endif (WITH-SOFTWARE) + +list(LENGTH PROVIDERS LEN) +math(EXPR LEN '${LEN}-1') + +set(DOC_DEPS "") + +find_program(PLANTUML plantuml) + +# For each provider, define these targets: +# PROVIDER-doc-mof-dir - creates all directories +# PROVIDER-doc-mof - create .rst from .mof +# PROVIDER-doc-pic - create .svg from .uml (if needed) +# PROVIDER-doc - create .html from .rst +foreach(I RANGE ${LEN}) + list(GET PROVIDERS ${I} PROVIDER) + list(GET PROVIDER_CAPTIONS ${I} CAPTION) + list(GET PROVIDER_MOFS ${I} MOF) + add_custom_target(${PROVIDER}-doc-mof-dir + COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/${PROVIDER}/mof + COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/${PROVIDER}/pic + ) + + add_custom_target(${PROVIDER}-doc-mof + COMMAND openlmi-doc-class2rst + -H ${CMAKE_CURRENT_SOURCE_DIR}/header.txt + --schema /usr/share/mof/cim-current/CIM_Schema.mof + --schema /usr/share/openlmi-providers/05_LMI_Qualifiers.mof + --schema /usr/share/openlmi-providers/30_LMI_Jobs.mof + --mof ${CMAKE_SOURCE_DIR}/mof/${MOF} + CIM_ComputerSystem + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${PROVIDER}/mof + DEPENDS ${PROVIDER}-doc-mof-dir + ) + + if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${PROVIDER}/pic) + if (PLANTUML AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${PROVIDER}/pic/make-svg.sh) + # We have plantuml, svgs will be regenerated + add_custom_target(${PROVIDER}-doc-pic-gen + COMMENT "Regenerating pictures using ${CMAKE_CURRENT_SOURCE_DIR}/${PROVIDER}/pic/make-svg.sh" + COMMAND ./make-svg.sh + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${PROVIDER}/pic + ) + else (PLANTUML AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${PROVIDER}/pic/make-svg.sh) + # We don't have plantuml, so we depend on svgs in tarball + add_custom_target(${PROVIDER}-doc-pic-gen) + endif (PLANTUML AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${PROVIDER}/pic/make-svg.sh) + + add_custom_target(${PROVIDER}-doc-pic + # copy the pictures + COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/${PROVIDER}/pic/*.svg ${CMAKE_CURRENT_BINARY_DIR}/${PROVIDER}/pic/ + DEPENDS ${PROVIDER}-doc-mof-dir + DEPENDS ${PROVIDER}-doc-pic-gen + ) + + else (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${PROVIDER}/pic) + add_custom_target(${PROVIDER}-doc-pic) + endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${PROVIDER}/pic) + + add_custom_target(${PROVIDER}-doc + COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/${PROVIDER}/*.rst ${CMAKE_CURRENT_BINARY_DIR}/${PROVIDER} + + COMMAND sphinx-build + -b html + -c ${CMAKE_CURRENT_SOURCE_DIR} + -D "version=${OPENLMI_VERSION}" -D "release=${OPENLMI_VERSION}" -D "project=OpenLMI ${CAPTION} provider" -D "epub_title=OpenLMI ${CAPTION} provider" + ${CMAKE_CURRENT_BINARY_DIR}/${PROVIDER} ${CMAKE_CURRENT_BINARY_DIR}/${PROVIDER}/html + DEPENDS ${PROVIDER}-doc-mof ${PROVIDER}-doc-pic + ) + set(DOC_DEPS ${DOC_DEPS} ${PROVIDER}-doc) +endforeach(I RANGE ${LEN}) + +# Finally, create 'doc' target to run all the previous *doc targets +add_custom_target(doc + DEPENDS ${DOC_DEPS} +) diff --git a/doc/admin/README b/doc/admin/README new file mode 100644 index 0000000..fd229cb --- /dev/null +++ b/doc/admin/README @@ -0,0 +1,55 @@ +Documentation compilation +========================= + +Using standard cmake in openlmi-providers top level directory: + +$ mkdir build && cd build +$ cmake .. +$ make doc + +See top-level README for list of dependencies. + + +Adding documentation of new provider +==================================== + +We use cmake magic to generate: +- .rst files from .mof files +- .svg files from .uml files +- .html files from all .rst+.svg files + +1) Place *all* images into /pic directory. + Use following code to include them in your .rst files: + + .. figure:: pic/powermanagement.svg + + If there is /usr/bin/plantuml available at the time of running cmake + and /pic/make-svg.sh exists, it will be executed to refresh + the .svg files. + +2) .rst files generated out of .mof file(s) will be available in mof/ + subdirectory. Reference them using following code: + + .. ifconfig:: includeClasses + + OpenLMI Service CIM Classes: + + .. toctree:: + :maxdepth: 1 + + mof/tree + mof/index + + +3) Update CMakeLists.txt in this directory: + + PROVIDERS array - Add name of the provider directory. It will be used as + the in the examples above. + + PROVIDER_CAPTIONS array - Add human-friendly name of the provider. + It will be used as HTML title of the generated + documentation. + + PROVIDER_MOFS array - Add name of the MOF file, from which class + reference and inheritance tree will be generated. + diff --git a/doc/admin/account/dmtf-profile.rst b/doc/admin/account/dmtf-profile.rst new file mode 100644 index 0000000..51ab366 --- /dev/null +++ b/doc/admin/account/dmtf-profile.rst @@ -0,0 +1,79 @@ +.. _dmtf-profile: + +DMTF profile +============= +The provider implements DMTF's `Simple Identity Management Profile `_, +version 1.0.1. + +Profile adjustment +------------------ +The settings classes are not implemented. Necessary settings are done directly +in methods of :ref:`LMI_AccountManagementService `. +:ref:`LMI_AccountManagementService ` is +subclass of :ref:`CIM_SecurityService `, because +there is a change in method parameters as follows: + +* :ref:`CreateAccount ` does + not take EmbeddedInstance as parameter, but a list of parameters. + +Implementation +-------------- +All mandatory classes are implemented. + +Classes +^^^^^^^ +Implemented DMTF classes: + +.. generated by for file in *Provider.c; do prov="${file%%Provider.c}"; printf '* :ref:`%s <%s>`\n\n' "$prov" "${prov/_/-}"; done + +* :ref:`LMI_AccountCapabilities ` + +* :ref:`LMI_AccountInstanceCreationIndication ` + +* :ref:`LMI_AccountInstanceDeletionIndication ` + +* :ref:`LMI_AccountManagementCapabilities ` + +* :ref:`LMI_AccountManagementServiceCapabilities ` + +* :ref:`LMI_AccountManagementService ` + +* :ref:`LMI_AccountManagementServiceSettingData ` + +* :ref:`LMI_AccountOnSystem ` + +* :ref:`LMI_Account ` + +* :ref:`LMI_AccountSettingData ` + +* :ref:`LMI_AssignedAccountIdentity ` + +* :ref:`LMI_AssignedGroupIdentity ` + +* :ref:`LMI_EnabledAccountCapabilities ` + +* :ref:`LMI_Group ` + +* :ref:`LMI_HostedAccountManagementService ` + +* :ref:`LMI_Identity ` + +* :ref:`LMI_MemberOfGroup ` + +* :ref:`LMI_OwningGroup ` + +* :ref:`LMI_ServiceAffectsIdentity ` + +* :ref:`LMI_SettingsDefineAccountCapabilities ` + +* :ref:`LMI_SettingsDefineManagementCapabilities ` + +Methods +^^^^^^^ +Implemented: + +* :ref:`CreateAccount ` + +Additional methods: + +* :ref:`CreateGroup ` diff --git a/doc/admin/account/index.rst b/doc/admin/account/index.rst new file mode 100644 index 0000000..1ee6561 --- /dev/null +++ b/doc/admin/account/index.rst @@ -0,0 +1,30 @@ +.. OpenLMI Account documentation master file, created by + sphinx-quickstart on Wed Aug 21 16:15:23 2013. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +OpenLMI Account Provider documentation +=========================================== +OpenLMI Account is CIM provider which manages POSIX accounts. +It allows to create, delete and modify users and groups. + +The provider implements DMTF identity profile, for more details read +:ref:`DMTF profile `. + +Contents: + +.. toctree:: + :maxdepth: 2 + + dmtf-profile + usage + +.. ifconfig:: includeClasses + + OpenLMI Account CIM Classes: + + .. toctree:: + :maxdepth: 1 + + mof/tree + mof/index diff --git a/doc/admin/account/usage.rst b/doc/admin/account/usage.rst new file mode 100644 index 0000000..f8a5e89 --- /dev/null +++ b/doc/admin/account/usage.rst @@ -0,0 +1,241 @@ +OpenLMI Account usage +===================== + +General manipulation of users and groups are done with the objects +from following classes: + +* :ref:`LMI_AccountManagementService ` + +* :ref:`LMI_Account ` + +* :ref:`LMI_Group ` + +* :ref:`LMI_MemberOfGroup ` + +* :ref:`LMI_Identity ` + +* :ref:`LMI_AccountInstanceCreationIndication ` + +* :ref:`LMI_AccountInstanceDeletionIndication ` + +Some common use cases are described in the following parts + +List users +---------- +List of users are provided by :ref:`LMI_Account `. Each one object +of this class represents one user on the system. Both system and non-sytem users +are directly in :ref:`LMI_Account ` class:: + + # List user by name + print c.root.cimv2.LMI_Account.first_instance({"Name": "root"}) + # List user by id + print c.root.cimv2.LMI_Account.first_instance({"UserID": "0"}) + + +List groups +----------- +Similarly like users, groups are represented by objects +of :ref:`LMI_Group ` class:: + + # List group by name + print c.root.cimv2.LMI_Group.first_instance({"Name": "root"}) + # List group by id + print c.root.cimv2.LMI_Group.first_instance({"InstanceID": "LMI:GID:0"}) + + +List group members +------------------ +:ref:`LMI_Identity ` is class representing users and groups +on the system. Group membership is represented +by :ref:`LMI_MemberOfGroup ` association. It associates +:ref:`LMI_Group ` and :ref:`LMI_Identity `, where +:ref:`LMI_Identity ` is associated +by :ref:`LMI_AssignedAccountIdentity ` with +:ref:`LMI_Account `:: + + # Get users from root group + # 1) Get root group object + root_group = c.root.cimv2.LMI_Group.first_instance({"Name": "root") + # 2) Get LMI_Identity objects associated with root group + identities = root_group.associators(ResultClass="LMI_Identity", AssocClass="LMI_MemberOfGroup") + # 3) go through all identites, get LMI_Account associated with identity and print user name + # Note: associators returns a list, but there is just one LMI_Account + for i in identities: + print i.first_associator(ResultClass="LMI_Account").Name + +Create user +----------- +For user creation we have to use +:ref:`LMI_AccountManagementService `. There is +:ref:`CreateAccount ` method, +which will create user with descired attributes:: + + # get computer system + cs = c.root.cimv2.PG_ComputerSystem.first_instance() + # get service + lams = c.root.cimv2.LMI_AccountManagementService.first_instance() + # invoke method, print result + lams.CreateAccount(Name="lmishell-user", System=cs) + +Create group +------------ +Similarly like creating user, creating groups are don in +:ref:`LMI_AccountManagementService `, using +:ref:`CreateGroup ` method:: + + # get computer system + cs = c.root.cimv2.PG_ComputerSystem.first_instance() + # get service + lams = c.root.cimv2.LMI_AccountManagementService.first_instance() + # invoke method, print result + print lams.CreateGroup(Name="lmishell-group", System=cs) + + +Delete user +----------- +User deletion is done with :ref:`DeleteUser ` +method on the desired :ref:`LMI_Account ` object. + +:: + + # get the desired user + acci = c.root.cimv2.LMI_Account.first_instance({"Name": "tobedeleted"}) + # delete the user + acci.DeleteUser() + +.. note:: + + Previous releases allowed to use ``DeleteInstance`` intrinsic method to + delete ``LMI_Account``. This method is now deprecated and + will be removed from future releases of OpenLMI Account. The reason is that + ``DeleteInstance`` cannot have parameters; it is equivalent to call + ``DeleteAccount`` without specifying parameters. + + +Delete group +------------ +Group deletion is done with :ref:`DeleteGroup ` +method on the desired :ref:`LMI_Group ` object, + +:: + + # get the desired group + grp = c.root.cimv2.LMI_Group.first_instance({"Name": "tobedeleted"}) + # delete the group + grp.DeleteGroup() + +.. note:: + + Previous releases allowed to use ``DeleteInstance`` intrinsic method to + delete ``LMI_Group``. This method is now deprecated and + will be removed from future releases of OpenLMI Account. The reason is that + we want to have consistent way to delete user and group. + + +Add user to group +----------------- +Adding user to group is done with ``CreateInstance`` intrinsic method on the +:ref:`LMI_MemberOfGroup ` class, which requires reference +to :ref:`LMI_Group ` and :ref:`LMI_Identity `:: + + # We will add root user to pegasus group + # get group pegasus + grp = c.root.cimv2.LMI_Group.first_instance({"Name": "pegasus"}) + # get user root + acc = c.root.cimv2.LMI_Account.first_instance({"Name": "root"}) + # get identity of root user + identity = acc.first_associator(ResultClass="LMI_Identity") + # create instance of LMI_MemberOfGroup with the above references + c.root.cimv2.LMI_MemberOfGroup.create_instance({"Member":identity.path, "Collection":grp.path}) + +Remove user from group +---------------------- +Removing user from group is done with ``DeleteInstance`` intrinsic method +on the desired :ref:`LMI_MemberOfGroup ` object:: + + # We will remove root user from pegasus group + # get group pegasus + grp = c.root.cimv2.LMI_Group.first_instance({"Name": "pegasus"}) + # get user root + acc = c.root.cimv2.LMI_Account.first_instance({"Name": "root"}) + # get identity of root user + identity = acc.associators(ResultClass="LMI_Identity")[0] + # iterate through all LMI_MemberOfGroup associated with identity and remove the one with our group + for mog in identity.references(ResultClass="LMI_MemberOfGroup"): + if mog.Collection == grp.path: + mog.delete() + +Modify user +----------- +It is also possible to modify user details and it is done by ``ModifyInstance`` +intrinsic method on the desired :ref:`LMI_Account ` object:: + + # Change login shell of test user + acci = c.root.cimv2.LMI_Account.first_instance({"Name": "test"}) + acci.LoginShell = '/bin/sh' + # propagate changes + acci.push() + +Indications +----------- +OpenLMI Account supports the following indications: + +* :ref:`LMI_AccountInstanceCreationIndication ` + +* :ref:`LMI_AccountInstanceDeletionIndication ` + +Both indications works only on the following classes: + +* :ref:`LMI_Account ` + +* :ref:`LMI_Group ` + +* :ref:`LMI_Identity ` + +See more below. + +Creation Indication +^^^^^^^^^^^^^^^^^^^ +Client can be notified when instance of class has been created. It is done with +:ref:`LMI_AccountInstanceCreationIndication `. The indication filter query must be in the following form: +``SELECT * FROM LMI_AccountInstanceCreationIndication WHERE SOURCEINSTANCE ISA class_name``, where ``class_name`` is one of the allowed classes. + +The following example creates filter, handler and subscription (lmi shell do it in one step), which will notify client when user is created: + +:: + + # Notify when a user is created + c.root.interop.create_indication( + FilterCreationClassName="CIM_IndicationFilter", + FilterSystemCreationClassName="CIM_ComputerSystem", + FilterSourceNamespace="root/cimv2", + QueryLanguage="WQL", + Query='SELECT * FROM LMI_AccountInstanceCreationIndication WHERE SOURCEINSTANCE ISA LMI_Account', + Name="account_creation", + HandlerCreationClassName="CIM_IndicationHandlerCIMXML", + HandlerSystemCreationClassName="CIM_ComputerSystem", + Destination="http://192.168.122.1:5988" # this is the destination computer, where all the indications will be delivered + ) + + +Deletion Indication +^^^^^^^^^^^^^^^^^^^ +Client can be notified when instance is deleted. The same rules like in `Creation Indication`_ applies here: + +:: + + # Notify when a user is deleted + c.root.interop.create_indication( + FilterCreationClassName="CIM_IndicationFilter", + FilterSystemCreationClassName="CIM_ComputerSystem", + FilterSourceNamespace="root/cimv2", + QueryLanguage="WQL", + Query='SELECT * FROM LMI_AccountInstanceDeletionIndication WHERE SOURCEINSTANCE ISA LMI_Account', + Name="account_creation", + HandlerCreationClassName="CIM_IndicationHandlerCIMXML", + HandlerSystemCreationClassName="CIM_ComputerSystem", + Destination="http://192.168.122.1:5988" # this is the destination computer, where all the indications will be delivered + ) + +.. note:: + Both indications uses indication manager and polling. diff --git a/doc/admin/conf.py b/doc/admin/conf.py new file mode 100644 index 0000000..89bed50 --- /dev/null +++ b/doc/admin/conf.py @@ -0,0 +1,297 @@ +# -*- coding: utf-8 -*- +# +# OpenLMI generic Provider documentation build configuration file, created by +# sphinx-quickstart on Thu Oct 3 14:25:59 2013. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +def setup(app): + # Register new option to include class list and class tree in index.rst + app.add_config_value('includeClasses', 'True', True) +includeClasses = True + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. + +copyright = u'2013, OpenLMI' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +############################################### +# This will be set by cmake +# The short X.Y version. +#version = '0.3.0' +# The full version, including alpha/beta/rc tags. +#release = '0.3.0' +############################################### + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'openlmitheme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +html_theme_path = ["../../../../tools"] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +#htmlhelp_basename = 'OpenLMISoftwareProviderdoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +#latex_documents = [ +# ('index', 'OpenLMISoftwareProvider.tex', u'OpenLMI Software Provider Documentation', +# u'Michal Minar', 'manual'), +#] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +#man_pages = [ +# ('index', 'openlmisoftwareprovider', u'OpenLMI Software Provider Documentation', +# [u'Michal Minar'], 1) +#] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +#texinfo_documents = [ +# ('index', 'OpenLMISoftwareProvider', u'OpenLMI Software Provider Documentation', +# u'Michal Minar', 'OpenLMISoftwareProvider', 'One line description of project.', +# 'Miscellaneous'), +#] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + + +# -- Options for Epub output --------------------------------------------------- + +# Bibliographic Dublin Core info. +#epub_title = u'OpenLMI Software Provider' +#epub_author = u'Michal Minar' +epub_publisher = u'OpenLMI.org' +#epub_copyright = u'2013, Michal Minar' + +# The language of the text. It defaults to the language option +# or en if the language is not set. +#epub_language = '' + +# The scheme of the identifier. Typical schemes are ISBN or URL. +#epub_scheme = '' + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +#epub_identifier = '' + +# A unique identification for the text. +#epub_uid = '' + +# A tuple containing the cover image and cover page html template filenames. +#epub_cover = () + +# HTML files that should be inserted before the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_pre_files = [] + +# HTML files shat should be inserted after the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_post_files = [] + +# A list of files that should not be packed into the epub file. +#epub_exclude_files = [] + +# The depth of the table of contents in toc.ncx. +#epub_tocdepth = 3 + +# Allow duplicate toc entries. +#epub_tocdup = True + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/doc/admin/fan/dmtf.rst b/doc/admin/fan/dmtf.rst new file mode 100644 index 0000000..cb8234d --- /dev/null +++ b/doc/admin/fan/dmtf.rst @@ -0,0 +1,144 @@ +.. _dmtf_profiles: + +DMTF profiles +============= +*OpenLMI Fan* provider implements *Fan Profile* + +Fan Profile +-------------------------- +Implemented *DMTF* version: ``1.0.1`` + +Described by `DSP1013`_ + +It defines the classes used to describe the fans and the possible redundancy +of the fans in a managed system. The document also defines association +classes that describe the relationship of the fan to the fan’s physical +aspects (such as FRU data) to the sensors monitoring the fans, to other +cooling devices, to redundancy status, and to DMTF profile version +information. The information in this specification is intended to be +sufficient for a provider or consumer of this data to identify unambiguously +the classes, properties, methods, and values that are mandatory to be +instantiated and manipulated to represent and manage fans and redundant fans +of managed systems and subsystems that are modeled using the DMTF CIM core +and extended model definitions. + +Not implemented features +~~~~~~~~~~~~~~~~~~~~~~~~ +*DMTF* profile defines many classes that are not instrumented due to +limitations of low level libraries giving informations about fans. +Here is a list of not implemented classes: + + ``CIM_ManagedSystemElement`` + Models the piece of hardware being cooled by particular fan. It's + associated with :ref:`LMI_Fan` through ``CIM_AssociatedColling`` which + is also not instrumented. + + ``CIM_RedundancySet`` + Represents redundacy of fans belonging to particular computer + system. It's associated with :ref:`LMI_Fan` through + ``CIM_MemberOfCollection`` and ``CIM_IsSpare`` associations. + There is no way how to detect whether the fan is spare or not. + +Classes that shall be implemented +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +There are still classes missing implementation and are planned to +be delivered in future versions. + + ``CIM_SystemDevice`` + Associates :ref:`LMI_Fan` to ``CIM_ComputerSystem``. + + ``CIM_EnabledLogicalElementCapacilities`` + Represents the capabilities of associated fan. It's associated + to :ref:`LMI_Fan` through ``CIM_ElementCapabilities``. + +Not implemented optional features +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +*Physical Asset* association from :ref:`LMI_Fan` to ``CIM_PhysicalPackage`` +through ``CIM_Realizes`` association class is not instrumented. +This is an optional feature. It may be implemented later. + +*Physical Asset* is a related profile implemented by *OpenLMI Hardware* +provider. + +Class overview +~~~~~~~~~~~~~~ + + +---------------------------------------------------------+---------------------------------------------------+------------------+ + | Class-name | Parent_class | Type | + +=========================================================+===================================================+==================+ + | :ref:`LMI_Fan` | :ref:`CIM_Fan` | Plain | + +---------------------------------------------------------+---------------------------------------------------+------------------+ + | :ref:`LMI_FanSensor` | :ref:`CIM_NumericSensor` | Plain | + +---------------------------------------------------------+---------------------------------------------------+------------------+ + | :ref:`LMI_FanAssociatedSensor` | :ref:`CIM_AssociatedSensor` | Association | + +---------------------------------------------------------+---------------------------------------------------+------------------+ + +LMI_Fan +^^^^^^^ +Represents the the fan installed and connected to computer. +One of the most important keys is :ref:`DeviceID`. It's a +*sys* path to kernel driver's abstraction for fan combined with its name. + +Typical sys directory for fan looks like this: :: + + /sys/class/hwmon/hwmon1/device/ + ├── driver -> ../../../bus/platform/drivers/thinkpad_hwmon + ├── fan1_input + ├── hwmon + │   └── hwmon1 + │   ├── device -> ../../../thinkpad_hwmon + │   ├── power + │   │   ├── async + │   │   ├── autosuspend_delay_ms + │   │   ├── control + │   │   ├── runtime_active_kids + │   │   ├── runtime_active_time + │   │   ├── runtime_enabled + │   │   ├── runtime_status + │   │   ├── runtime_suspended_time + │   │   └── runtime_usage + │   ├── subsystem -> ../../../../../class/hwmon + │   └── uevent + ├── modalias + ├── name + ├── power + │   ├── async + │   ├── autosuspend_delay_ms + │   ├── control + │   ├── runtime_active_kids + │   ├── runtime_active_time + │   ├── runtime_enabled + │   ├── runtime_status + │   ├── runtime_suspended_time + │   └── runtime_usage + ├── pwm1 + ├── pwm1_enable + ├── subsystem -> ../../../bus/platform + └── uevent + +Corresponding ``DeviceID`` is ``/sys/class/hwmon/hwmon1/device/fan1``. The fan +name is the prefix of ``*_input`` file which gives the current +:abbr:`RPM(Revolutions per minute)` value. + +It has several other interesting properties: + + :ref:`OtherIdentifyingInfo` : ``string []`` + Has the name of chip controlling the fan as the first item. + +LMI_FanSensor +^^^^^^^^^^^^^ +Represents a sensor measuring a speed of particular fan. It's exactly the same +keys and values except for +:ref:`CreationClassName` containg the name +of corresponding class ``LMI_Fan``. + +It inherts many methods that are not supported because underlying library does +not offer such functionality. Controlling of fans is very hardware dependent. +Different drivers may provide different ways and possibilities to manage +connected fans. + +.. + *************************************************************************** + +.. _DSP1013: http://www.dmtf.org/sites/default/files/standards/documents/DSP1013_1.0.1.pdf + diff --git a/doc/admin/fan/index.rst b/doc/admin/fan/index.rst new file mode 100644 index 0000000..35e57c3 --- /dev/null +++ b/doc/admin/fan/index.rst @@ -0,0 +1,27 @@ +.. OpenLMI Software Provider documentation master file, created by + sphinx-quickstart on Thu Oct 3 14:25:59 2013. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to OpenLMI Software Provider's documentation! +===================================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + dmtf + usage + +.. ifconfig:: includeClasses + + OpenLMI Storage CIM classes: + + .. toctree:: + :maxdepth: 1 + + mof/tree + mof/index + + diff --git a/doc/admin/fan/usage.rst b/doc/admin/fan/usage.rst new file mode 100644 index 0000000..3a34b51 --- /dev/null +++ b/doc/admin/fan/usage.rst @@ -0,0 +1,48 @@ +*OpenLMI Fan* usage +=================== +Examples for common use cases listed below are written in `lmishell`_. + +Set up +------ +*OpenLMI Fan* provider uses `lm-sensors`_ to find, observe and manage installed +fans. In order to make the fans exposed to it, one operation needs to be done: + +.. code-block:: sh + + sensors-detect + +``sensors-detect`` is a script shiped with ``lm_sensors`` package in *Fedora* +which tries to load correct modules for various sensor devices found in system. +It also writes a config used by ``sensors`` library which is utilised in this +provider. Please refer to its *sensors-detect (8)* man-page. + +Examples +-------- +Listing installed fans +~~~~~~~~~~~~~~~~~~~~~~ +:: + + c = connect("host", "user", "pass") + for fan in c.root.cimv2.LMI_Fan.instances(): + print(fan.ElementName) + +.. seealso:: + :ref:`LMI_Fan` + +Getting fan's speed +~~~~~~~~~~~~~~~~~~~ +Current value can be read from :ref:`CurrentReading` +property. It's measured in *revolutions per minute*. + +:: + + c = connect("host", "user", "pass") + for fan in c.root.cimv2.LMI_FanSensor.instances(): + print("%s:\t%s RPM" % (fan.Name, fan.CurrentReading)) + +.. seealso:: + :ref:`LMI_FanSensor` + +.. ***************************************************************************** +.. _lmishell: https://fedorahosted.org/openlmi/wiki/shell +.. _lm-sensors: http://lm-sensors.org/ diff --git a/doc/admin/hardware/dmtf-profiles.rst b/doc/admin/hardware/dmtf-profiles.rst new file mode 100644 index 0000000..7f38a2f --- /dev/null +++ b/doc/admin/hardware/dmtf-profiles.rst @@ -0,0 +1,135 @@ +.. _dmtf-profiles: + +DMTF profiles +============= +The provider is partially implementing DMTF's +`Computer System Profile `_, +version 1.0.2, with addition of multiple hardware related profiles. Complete list +of implemented profiles can be found below. + +CPU Profile +----------- +`CPU DMTF Profile `_, +version 1.0.1. + +Classes +^^^^^^^ +Implemented DMTF classes: + +.. generated by for file in *Provider.c; do prov="${file%%Provider.c}"; printf '* :ref:`%s <%s>`\n\n' "$prov" "${prov/_/-}"; done + +* :ref:`LMI_Processor ` + +* :ref:`LMI_ProcessorCapabilities ` + +* :ref:`LMI_ProcessorElementCapabilities ` + +* :ref:`LMI_ProcessorCacheMemory ` + +* :ref:`LMI_AssociatedProcessorCacheMemory ` + +* :ref:`LMI_ProcessorChip ` + +* :ref:`LMI_ProcessorChipRealizes ` + +* :ref:`LMI_ProcessorChipContainer ` + +* :ref:`LMI_ProcessorSystemDevice ` + +System Memory Profile +--------------------- +`System Memory DMTF Profile `_, +version 1.0.1. + +Classes +^^^^^^^ +Implemented DMTF classes: + +.. generated by for file in *Provider.c; do prov="${file%%Provider.c}"; printf '* :ref:`%s <%s>`\n\n' "$prov" "${prov/_/-}"; done + +* :ref:`LMI_Memory ` + +* :ref:`LMI_MemoryPhysicalPackage ` + +* :ref:`LMI_PhysicalMemory ` + +* :ref:`LMI_PhysicalMemoryRealizes ` + +* :ref:`LMI_PhysicalMemoryContainer ` + +* :ref:`LMI_MemorySlot ` + +* :ref:`LMI_MemorySlotContainer ` + +* :ref:`LMI_MemoryPhysicalPackageInConnector ` + +* :ref:`LMI_MemorySystemDevice ` + +Physical Asset Profile +---------------------- +`Physical Asset DMTF Profile `_, +version 1.0.2. + +Classes +^^^^^^^ +Implemented DMTF classes: + +.. generated by for file in *Provider.c; do prov="${file%%Provider.c}"; printf '* :ref:`%s <%s>`\n\n' "$prov" "${prov/_/-}"; done + +* :ref:`LMI_Chassis ` + +* :ref:`LMI_Baseboard ` + +* :ref:`LMI_BaseboardContainer ` + +* :ref:`LMI_PointingDevice ` + +* :ref:`LMI_PortPhysicalConnector ` + +* :ref:`LMI_PortPhysicalConnectorContainer ` + +* :ref:`LMI_SystemSlot ` + +* :ref:`LMI_SystemSlotContainer ` + +* :ref:`LMI_ChassisComputerSystemPackage ` + +Battery Profile +--------------- +`Battery DMTF Profile `_, +version 1.0.0. + +Classes +^^^^^^^ +Implemented DMTF classes: + +.. generated by for file in *Provider.c; do prov="${file%%Provider.c}"; printf '* :ref:`%s <%s>`\n\n' "$prov" "${prov/_/-}"; done + +* :ref:`LMI_Battery ` + +* :ref:`LMI_BatteryPhysicalPackage ` + +* :ref:`LMI_PhysicalBatteryContainer ` + +* :ref:`LMI_PhysicalBatteryRealizes ` + +* :ref:`LMI_BatterySystemDevice ` + +PCI Device Profile +------------------ +`PCI Device DMTF Profile `_, +version 1.0.0. + +Classes +^^^^^^^ +Implemented DMTF classes: + +.. generated by for file in *Provider.c; do prov="${file%%Provider.c}"; printf '* :ref:`%s <%s>`\n\n' "$prov" "${prov/_/-}"; done + +* :ref:`LMI_PCIDevice ` + +* :ref:`LMI_PCIDeviceSystemDevice ` + +* :ref:`LMI_PCIBridge ` + +* :ref:`LMI_PCIBridgeSystemDevice ` diff --git a/doc/admin/hardware/index.rst b/doc/admin/hardware/index.rst new file mode 100644 index 0000000..6913b46 --- /dev/null +++ b/doc/admin/hardware/index.rst @@ -0,0 +1,27 @@ +.. OpenLMI Hardware documentation + +OpenLMI Hardware Provider documentation +======================================= +OpenLMI Hardware is CIM provider which can provide hardware information. + +The provider is partially implementing DMTF Computer System Profile with +addition of multiple hardware related profiles. For more information see +:ref:`DMTF profiles `. + +Contents: + +.. toctree:: + :maxdepth: 2 + + dmtf-profiles + info + +.. ifconfig:: includeClasses + + OpenLMI Hardware CIM Classes: + + .. toctree:: + :maxdepth: 1 + + mof/tree + mof/index diff --git a/doc/admin/hardware/info.rst b/doc/admin/hardware/info.rst new file mode 100644 index 0000000..3dfa91e --- /dev/null +++ b/doc/admin/hardware/info.rst @@ -0,0 +1,142 @@ +.. _info: + +OpenLMI Hardware information +============================ +OpenLMI Hardware provider contains hardware information, it does not +implement any methods. List of provided information divided by DMTF profiles +can be found below. + +CPU Profile +----------- +CPU Profile provides information about CPU and associated cache: + +* Processor + + - Number of CPUs, cores, threads + - Model + - Clock and FSB speeds + - Data and Address width + - Architecture + - Flags + - Family + - Stepping + - FRU data (Manufacturer, Model, Serial Number, Part Number) + +* Processor Cache + + - Level + - Size + - Type (Data / Instruction / Unified) + +Used Resources +^^^^^^^^^^^^^^ +* dmidecode program *[from dmidecode package]* +* lscpu program *[from util-linux package]* +* /proc/cpuinfo file +* /sys/devices/system/cpu/* files + +System Memory Profile +--------------------- +System Memory Profile provides information about system memory and slots: + +* Memory + + - Size + - Speed (in both MHz and ns) + - Size of standard memory page + - All supported sizes of huge pages + - Current state of transparent huge pages [Unsupported, Never, Madvise, Always] + - Detection of NUMA layout + +* Memory slots + modules + + - Number of slots and modules + - In which slots are modules plugged in + - Size of modules + - Speed of modules + - Data and Total width + - Module type and form factor + - FRU data + +Used Resources +^^^^^^^^^^^^^^ +* dmidecode program *[from dmidecode package]* +* /proc/meminfo file +* /sys/devices/system/node/* files +* /sys/kernel/mm/hugepages/* files +* /sys/kernel/mm/transparent_hugepage/* files + +Physical Asset Profile +---------------------- +Physical Asset Profile provides basic information about physical assets +in system, usually with FRU data, currently for following hardware +(with associations): + +* System chassis +* Baseboard (motherboard) +* Chassis ports (USB, LAN, VGA..) +* Chassis slots (Media card slot, Express card slot..) +* Pointing devices on chassis (Touch pad, Track point..) + +Used Resources +^^^^^^^^^^^^^^ +* dmidecode program *[from dmidecode package]* + +Battery Profile +--------------- +Battery Profile provides basic information about battery: + +* Capacity +* Voltage +* Chemistry +* FRU data + +Used Resources +^^^^^^^^^^^^^^ +* dmidecode program *[from dmidecode package]* + +PCI Device Profile +------------------ +PCI Device Profile provides information about PCI devices: + +* PCI Devices: + + - Bus Number + - Device Number + - Function Number + - PCI Device ID + - PCI Device Name + - Vendor ID + - Vendor Name + - Subsystem ID + - Subsystem Name + - Subsystem Vendor ID + - Subsystem Vendor Name + - Revision ID + - Base Address + - Cache Line Size + - Capabilities + - Class Code + - Command Register + - Device Select Timing + - Interrupt Pin + - Latency Timer + - Expansion ROM Base Address + +* PCI Bridges (all of the above, plus): + + - Bridge Type + - Primary Bus Number + - Secondary Bus Number + - Subordinate Bus Number + - Secondary Latency Timer + - IO Base + - IO Limit + - Memory Base + - Memory Limit + - Prefetch Memory Base + - Prefetch Memory Limit + +Used Resources +^^^^^^^^^^^^^^ +* libpci library *[from pciutils package, pci/pci.h header file]* diff --git a/doc/admin/header.txt b/doc/admin/header.txt new file mode 100644 index 0000000..cc06402 --- /dev/null +++ b/doc/admin/header.txt @@ -0,0 +1,2 @@ +Class reference +=============== diff --git a/doc/admin/journald/index.rst b/doc/admin/journald/index.rst new file mode 100644 index 0000000..ddb93e4 --- /dev/null +++ b/doc/admin/journald/index.rst @@ -0,0 +1,91 @@ +OpenLMI Journald Provider documentation +======================================= + +OpenLMI Journald is a CIM provider exposing `systemd `_ +journald log records and basic means of iteration and log writing. + +Classes used by the provider were chosen to mimic the sblim-cmpi-syslog provider +set of classes allowing drop-in replacement in production tools. We haven't been +able to find a profile it conforms to though. There's a related DMTF profile +`DSP1010 "Record Log Profile" `_ +which may be subject to extension of this provider in the future. +As a benefit, by using the parent classes (e.g. :ref:`CIM_LogRecord`), one is able +to mix log records from orthodox syslog and journald together. + + +Provider features +------------------ + +This is a short list of provider features: + * log records reading + * log record iteration using persistent iterators + * new records indication + * writing new log records + +For the moment, global journal is used, all journal files are mixed together. + +The provider also comes with a test suite covering most of its functionality. + + +.. _inst-enum-limit: + +Number of LMI_JournalLogRecord instances enumerated limitation +-------------------------------------------------------------- + +Testing the provider showed up an issue with enumeration of :ref:`LMI_JournalLogRecord` +instances. On the testing machine there was 199583 journal records, which is +simply too much for the CIMOM, exceeding memory and the resulting XML reply +limits. + +An artificial limit has been set, currently to 1000 most recent records. This +limit is set by the ``JOURNAL_MAX_INSTANCES_NUM`` define in ``Journal.h`` source +file. + +The :ref:`LMI_JournalMessageLog` class provides several +methods for iterating and seeking in a complete log. + + +New log records writing security concerns +----------------------------------------- + +The provider has an ability to send new messages to the log. This may be percieved +as a security issue in someone's eyes as long as you can specify custom message +format that is sent to the log. The only obstacle preventing anyone in sending +spoof messages is the rather weak CIM authentication model. + +However, as long as journald is a structured logging system, further information +is stored along every log record. Messages sent through the OpenLMI Journald +provider may be identified by supplemental fields such as ``_COMM`` and ``_EXE``, +pointing to a CIMOM that had been running the provider code or even the ``CODE_FUNC`` +field, pointing to a specific function that invoked the journald library code. + + +Potential indications endless loop +---------------------------------- + +Just a note for implementing a system processing the indications. Having no +specific filter for the indication subscription and performing an action +within the indication handler that involves a message being sent to syslog +may result in an endless loop as long such action generates another indication +for the fresh syslog message. Even a CIMOM in certain situations (i.e. debugging +in verbose mode) may generate additional messages while sending an indication +that in turn will generate another one. + + +Contents +--------- + +.. toctree:: + :maxdepth: 2 + + usage + +.. ifconfig:: includeClasses + + OpenLMI Journald CIM Classes: + + .. toctree:: + :maxdepth: 1 + + mof/tree + mof/index diff --git a/doc/admin/journald/usage.rst b/doc/admin/journald/usage.rst new file mode 100644 index 0000000..69fe48b --- /dev/null +++ b/doc/admin/journald/usage.rst @@ -0,0 +1,55 @@ +OpenLMI Journald usage +====================== + +The OpenLMI Journald provider depends on running journald daemon. See the `systemd +`_ +manual for how to enable the journald service. + + +Listing a log +------------- + +This example shows simple enumeration through available :ref:`LMI_JournalLogRecord` +instances in classic syslog-like format:: + + #!/usr/bin/lmishell + c = connect("localhost", "pegasus", "test") + for rec in c.root.cimv2.LMI_JournalMessageLog.first_instance().associators(): + print "%s %s %s" % (rec.MessageTimestamp.datetime.ctime(), rec.HostName, rec.DataFormat) + +.. note:: + Only a limited number of records are being enumerated and printed out, please + see the :ref:`inst-enum-limit` remark. + + +Iterating through the log +------------------------- + +This example uses iterator methods of the :ref:`LMI_JournalMessageLog` +class to continuously go through the whole journal:: + + #!/usr/bin/lmishell + c = connect("localhost", "pegasus", "test") + inst = c.root.cimv2.LMI_JournalMessageLog.first_instance() + r = inst.PositionToFirstRecord() + iter_id = r.rparams['IterationIdentifier'] + while True: + x = inst.GetRecord(IterationIdentifier=iter_id, PositionToNext=True) + if x.rval != 0: + break + print "".join(map(chr, x.rparams['RecordData'])) + iter_id = x.rparams['IterationIdentifier'] + + +Sending new message to log +-------------------------- + +Simple example that uses :ref:`LMI_JournalLogRecord.create_instance()` +CIM method to send a new message in the log:: + + #!/usr/bin/lmishell + c = connect("localhost", "pegasus", "test") + c.root.cimv2.LMI_JournalLogRecord.create_instance({"CreationClassName": "LMI_JournalLogRecord", + "LogCreationClassName": "LMI_JournalMessageLog", + "LogName": "Journal", + "DataFormat": ""}) diff --git a/doc/admin/logicalfile/index.rst b/doc/admin/logicalfile/index.rst new file mode 100644 index 0000000..5ee12ca --- /dev/null +++ b/doc/admin/logicalfile/index.rst @@ -0,0 +1,27 @@ +OpenLMI LogicalFile Provider documentation +========================================== +OpenLMI LogicalFile is a CIM provider which provides a way to read information +about files and directories. The provider also allows to traverse the file +hierarchy, create and remove empty directories. + +The provider implements a part of the +`CIM System schema `_ (sections "Local +File Systems" and "Unix System"). + + +Contents: + +.. toctree:: + :maxdepth: 2 + + usage + +.. ifconfig:: includeClasses + + OpenLMI LogicalFile CIM Classes: + + .. toctree:: + :maxdepth: 1 + + mof/tree + mof/index diff --git a/doc/admin/logicalfile/usage.rst b/doc/admin/logicalfile/usage.rst new file mode 100644 index 0000000..70cc3fe --- /dev/null +++ b/doc/admin/logicalfile/usage.rst @@ -0,0 +1,169 @@ +OpenLMI LogicalFile usage +========================= + +There are two basic types of classes in the LogicalFile provider. + +:ref:`CIM_LogicalFile ` subclasses: + +* :ref:`LMI_FIFOPipeFile ` +* :ref:`LMI_UnixDeviceFile ` +* :ref:`LMI_UnixDirectory ` +* :ref:`LMI_UnixSocket ` +* :ref:`LMI_DataFile ` +* :ref:`LMI_SymbolicLink ` + +Subclasses derived from :ref:`CIM_LogicalFile ` represent basic types of files and their +system independent properties, such as if the file is readable or its +modification time. The classes' names are self-explanatory. :ref:`LMI_SymbolicLink +` represents symbolic link files, :ref:`LMI_UnixDeviceFile +` represents unix device files, etc. + +The other type of class is :ref:`LMI_UnixFile `. It is used in the +Unix-like environment. Its properties are tied to the system -- Linux in our +case. For example, the group id of the owner or the inode number are among those +properties. + +To provide ways to connect the file subclasses together, LogicalFile also +defines a few associations. + +Association classes: + +* :ref:`LMI_RootDirectory ` +* :ref:`LMI_FileIdentity ` +* :ref:`LMI_DirectoryContainsFile ` + +:ref:`LMI_RootDirectory ` is used to connect the computer +system to its root directory. + +:ref:`LMI_FileIdentity ` associates the system-independent +:ref:`CIM_LogicalFile ` subclasses to their respective +:ref:`LMI_UnixFile ` equivalents that are dependent on the +system. + +:ref:`LMI_DirectoryContainsFile ` serves as a tool to +show contents of a directory. Note that directory is usually just a type of +file. + +Deviations from the schema +-------------------------- + +No classes that represent files have the ``EnumerateInstances`` method +implemented. The reason for this is that it would be very resource intensive to +list all the files on the given filesystem. Even more so, for example, all the +symlinks on the filesystem. For that reason, every LogicalFile class +implements only its ``GetInstance`` method. + +The objectpath of the logical file classes consists of these properties: + +* :ref:`CSCreationClassName ` +* :ref:`CSName ` +* :ref:`FSCreationClassName ` +* :ref:`FSName ` +* :ref:`CreationClassName ` + (:ref:`LFCreationClassName ` for + :ref:`LMI_UnixFile `) +* :ref:`Name ` (:ref:`LFName ` for + :ref:`LMI_UnixFile `) + +When getting an instance, it's usually required that all of the key properties +are specified. However, it is impossible, or at least needlessly complicated, to +know some of them when querying remote machines. For example, if I want to see +information about the file '/home/user/myfile' on a remote computer, I don't +want to specify the filesystem it resides on or the type of the file. + +Therefore, the only mandatory key properties are :ref:`CSCreationClassName +`, :ref:`CSName ` +and :ref:`Name ` (of :ref:`LFName ` +in case of :ref:`LMI_UnixFile `). :ref:`FSName +`, :ref:`FSCreationClassName +` and :ref:`CreationClassName +` are ignored. They are correctly filled in +after the instance has been properly returned. + +To have an entry point into the Unix filesystems, an association has been +added. It binds the computer system and its root directory. See +:ref:`LMI_RootDirectory `. + +:ref:`LMI_UnixFile ` has been extended to hold additional +properties. Currently, those are :ref:`SELinuxCurrentContext +` and :ref:`SELinuxExpectedContext +`. Should there be need for more +additions, this class can be easily extended. + +Getting files +------------- +All further code assumes that a connection object has been created and the +default namespace (root/cimv2) is used. Also, the system's instance must have +been acquired. + +:: + + # plain http connections will likely be refused + c = connect('https://myhost') + # namespace alias for convenience + ns = c.root.cimv2 + system = ns.PG_ComputerSystem.first_instance() + +Get an instance of the home directory:: + + name_dict = {'CSCreationClassName':system.classname, + 'CSName':system.name, + 'CreationClassName':'ignored', + 'FSCreationClassName':'ignored', + 'FSName':'ignored', + 'Name':'/home/jsynacek'} + name = ns.LMI_UnixDirectory.new_instance_name(name_dict) + home = name.to_instance() + print home.Name + +Get an instance of a temporary file and see its selinux contexts using the +:ref:`LMI_FileIdentity `:: + + name_dict = {'CSCreationClassName':system.classname, + 'CSName':system.name, + 'LFCreationClassName':'ignored', + 'FSCreationClassName':'ignored', + 'FSName':'ignored', + 'LFName':'/var/tmp/data_file'} + name = ns.LMI_UnixFile.new_instance_name(name_dict) + unixdata = name.to_instance() + data = unixdata.first_associator(AssocClass='LMI_FileIdentity') + print unixdata.SELinuxCurrentContext + print unixdata.SELinuxExpectedContext + print data.Readable + print data.Writeable + print data.Executable + +Get an instance of a symlink and check where it points to:: + + name_dict = {'CSCreationClassName':system.classname, + 'CSName':system.name, + 'LFCreationClassName':'ignored', + 'FSCreationClassName':'ignored', + 'FSName':'ignored', + 'LFName':'/home/jsynacek/test-link'} + name = ns.LMI_UnixFile.new_instance_name(name_dict) + unixsymlink = name.to_instance() + symlink = unixsymlink.first_associator(AssocClass='LMI_FileIdentity') + print symlink.TargetFile + +Association classes examples +---------------------------- + +List a directory:: + + files = home.associators(AssocClass='LMI_DirectoryContainsFile') + for f in sorted(files, key=lambda x: x.Name): + print f.Name + + +Get the root directory:: + + root = system.first_associator(AssocClass='LMI_RootDirectory') + print root.Name + +.. note:: + + For a more complex example of how to use the LogicalFile provider, please + refer to the `OpenLMI LogicalFile script + `_. diff --git a/doc/admin/power/concepts.rst b/doc/admin/power/concepts.rst new file mode 100644 index 0000000..3693815 --- /dev/null +++ b/doc/admin/power/concepts.rst @@ -0,0 +1,19 @@ +.. _concepts: + +Power Management API concepts +============================= + +.. figure:: pic/powermanagement.svg + + Class diagram for Power Management provider. + +Base class of this provider is +:ref:`LMI_PowerManagementService `. +This class has method +:ref:`RequestPowerStateChange ` +that can be used for changing between power states. + +For list of available power states, see property +:ref:`PowerStatesSupported ` +of the class +:ref:`LMI_PowerManagementCapabilities ` diff --git a/doc/admin/power/index.rst b/doc/admin/power/index.rst new file mode 100644 index 0000000..7471cb7 --- /dev/null +++ b/doc/admin/power/index.rst @@ -0,0 +1,21 @@ +OpenLMI Power Management Provider Documentation +=============================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + introduction + concepts + usage + +.. ifconfig:: includeClasses + + OpenLMI Power Management CIM classes: + + .. toctree:: + :maxdepth: 1 + + mof/tree + mof/index diff --git a/doc/admin/power/introduction.rst b/doc/admin/power/introduction.rst new file mode 100644 index 0000000..779f184 --- /dev/null +++ b/doc/admin/power/introduction.rst @@ -0,0 +1,16 @@ +.. _introduction: + +Introduction +============ +*OpenLMI Power Management Provider* allows to manage power states of +the managed system. Key functionality is ability to reboot, power off, suspend +and hibernate managed system. + +This provider is based on following `DMTF `_ standard: + +* `DSP1027 - Power State Management Profile `_ + +The knowledge of this standard is not necessary, but it can help a lot. + +Application developers should first get familiar with :ref:`Power Management API concepts ` +and then look at :ref:`usage of OpenLMI Power Management `. diff --git a/doc/admin/power/pic/make-svg.sh b/doc/admin/power/pic/make-svg.sh new file mode 100755 index 0000000..edffa6e --- /dev/null +++ b/doc/admin/power/pic/make-svg.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +dir=$(dirname $0) + +for uml in $dir/*.uml; +do + echo Compiling $uml + plantuml -failonerror -config $dir/plantuml.cfg -tsvg $uml -o $(pwd) || exit 1 +done + diff --git a/doc/admin/power/pic/plantuml.cfg b/doc/admin/power/pic/plantuml.cfg new file mode 100644 index 0000000..917cf04 --- /dev/null +++ b/doc/admin/power/pic/plantuml.cfg @@ -0,0 +1,3 @@ +skinparam defaultFontName Courier +skinparam defaultFontSize 10 + diff --git a/doc/admin/power/pic/powermanagement.svg b/doc/admin/power/pic/powermanagement.svg new file mode 100644 index 0000000..0578eb4 --- /dev/null +++ b/doc/admin/power/pic/powermanagement.svg @@ -0,0 +1 @@ +CIM_ComputerSystemLMI_PowerManagementServiceRequestPowerStateChange()LMI_PowerManagementCapabilitiesPowerStatesSupportedValues = [OffSoftGraceful, OffSoft, ...]LMI_AssociatedPowerManagementServiceLMI_HostedPowerManagementServiceLMI_ElementCapabilities \ No newline at end of file diff --git a/doc/admin/power/pic/powermanagement.uml b/doc/admin/power/pic/powermanagement.uml new file mode 100644 index 0000000..ab4bb63 --- /dev/null +++ b/doc/admin/power/pic/powermanagement.uml @@ -0,0 +1,15 @@ +@startuml + +object "CIM_ComputerSystem" as cs + +object "LMI_PowerManagementService" as pms +pms : RequestPowerStateChange() + +object "LMI_PowerManagementCapabilities" as pmc +pmc : PowerStatesSupportedValues = [OffSoftGraceful, OffSoft, ...] + +cs -- pms : LMI_AssociatedPowerManagementService +pms -- cs : LMI_HostedPowerManagementService +pms -- pmc : LMI_ElementCapabilities + +@enduml diff --git a/doc/admin/power/usage.rst b/doc/admin/power/usage.rst new file mode 100644 index 0000000..67a7f2e --- /dev/null +++ b/doc/admin/power/usage.rst @@ -0,0 +1,43 @@ +.. _usage: + +OpenLMI Power Management usage +============================== + +All example scripts are for ``lmishell``. See it's documentation_ on OpenLMI_ +page. + +.. _documentation: https://fedorahosted.org/openlmi/wiki/shell +.. _OpenLMI: https://fedorahosted.org/openlmi/ + +We also assume that ``lmishell`` is connected to the CIMOM and the +connection is stored in ``connection`` variable:: + + connection = connect("server", "username", "password") + ns = connection.root.cimv2 + +Enumeration of available power states +------------------------------------- + +To see the available power states on given managed system, use following:: + + capabilities = ns.LMI_PowerManagementCapabilities.first_instance() + for state in capabilities.PowerStatesSupported: + print ns.LMI_PowerManagementCapabilities.PowerStatesSupportedValues.value_name(state) + +Setting the power state +----------------------- + +Let's say we want to power off the system gracefully:: + + # Check if the power state is available first + capabilities = ns.LMI_PowerManagementCapabilities.first_instance() + if not ns.LMI_PowerManagementCapabilities.PowerStatesSupportedValues.OffSoftGraceful in capabilities.PowerStatesSupported: + print "OffSoftGraceful state is not supported" + return + # Get the PowerManagement service + service = ns.LMI_PowerManagementService.first_instance() + # Invoke the state change + service.RequestPowerStateChange(PowerState=ns.LMI_PowerManagementCapabilities.PowerStatesSupportedValues.OffSoftGraceful) + +Note that the job returned from this function is not much usable because +when system is shutting down, the CIMOM is terminated as well. diff --git a/doc/admin/realmd/index.rst b/doc/admin/realmd/index.rst new file mode 100644 index 0000000..d6d516f --- /dev/null +++ b/doc/admin/realmd/index.rst @@ -0,0 +1,24 @@ +OpenLMI Realmd Provider documentation +=========================================== +OpenLMI Realmd is a CIM provider for managing the systems Active Direcory or +Kerberos realms membership through the Realmd system service. + +It provides only the basic functionality: join or leave a domain and query the +domain membership. + +Contents: + +.. toctree:: + :maxdepth: 2 + + usage + +.. ifconfig:: includeClasses + + OpenLMI Realmd CIM Classes: + + .. toctree:: + :maxdepth: 1 + + mof/tree + mof/index diff --git a/doc/admin/realmd/usage.rst b/doc/admin/realmd/usage.rst new file mode 100644 index 0000000..1613373 --- /dev/null +++ b/doc/admin/realmd/usage.rst @@ -0,0 +1,47 @@ +OpenLMI Realmd usage +===================== + +The OpenLMI Realmd provider allows for basic configuration of the managed +systems Active Directory or Kerberos realms membership. It relies on the Realmd +system service. + +Querying a domain membership +---------------------------- + +To verify if the remote machine is part of the domain, it is enough to query the +value of the :ref:`LMI_RealmdService.Domain` property: +If non-NULL it contains the name of the joined domain:: + + #!/usr/bin/lmishell + c = connect("localhost", "pegasus", "test") + realmsrv = c.root.cimv2.LMI_RealmdService.first_instance() + dom = realmsrv.Domain + if (dom): + print "Joined to the domain: " + dom + else: + print "No domain joined." + +Joining a domain +---------------- + +The :ref:`LMI_RealmdService.JoinDomain()` method +can be used to join a domain. It takes three mandatory arguments: username and +password for the authentication and the domain name:: + + #!/usr/bin/lmishell + c = connect("localhost", "pegasus", "test") + realmsrv = c.root.cimv2.LMI_RealmdService.first_instance() + realmsrv.JoinDomain(Password='ZisIzSECRET', User='admin', Domain='AD.EXAMPLE.COM') + +Leaving a domain +---------------- + +Similarly to joining a domain the +:ref:`LMI_RealmdService.LeaveDomain()` can be used +to leave the joined domain. It requires the same arguments as the +:ref:`JoinDomain()` method:: + + #!/usr/bin/lmishell + c = connect("localhost", "pegasus", "test") + realmsrv = c.root.cimv2.LMI_RealmdService.first_instance() + realmsrv.LeaveDomain(Password='ZisIzSECRET', User='admin', Domain='AD.EXAMPLE.COM') diff --git a/doc/admin/service-dbus/index.rst b/doc/admin/service-dbus/index.rst new file mode 100644 index 0000000..dab439a --- /dev/null +++ b/doc/admin/service-dbus/index.rst @@ -0,0 +1,27 @@ +OpenLMI Service Provider documentation +=========================================== +OpenLMI Service is CIM provider for managing Linux system services (using +the systemd D-Bus interface). + +It allows to enumerate system services and get their status, start/stop/restart/... +a service and enable/disable a service. + +The provider should be also able to do event based monitoring of service status +(emit indication event upon service status change) in the future. + +Contents: + +.. toctree:: + :maxdepth: 2 + + usage + +.. ifconfig:: includeClasses + + OpenLMI Service CIM Classes: + + .. toctree:: + :maxdepth: 1 + + mof/tree + mof/index diff --git a/doc/admin/service-dbus/usage.rst b/doc/admin/service-dbus/usage.rst new file mode 100644 index 0000000..2d8c706 --- /dev/null +++ b/doc/admin/service-dbus/usage.rst @@ -0,0 +1,46 @@ +OpenLMI Service usage +===================== + +Some common use cases are described in the following parts. + +List services +------------- +List all services available on managed machine, print whether the service has been +started (TRUE), or stopped (FALSE) and print status string of the service:: + + for service in c.root.cimv2.LMI_Service.instances(): + print "%s:\t%s" % (service.Name, service.Status) + +List only enabled by default services (automatically started on boot). Note that value +of EnabledDefault property is '2' for enabled services (and it's '3' for disabled services):: + + service_cls = c.root.cimv2.LMI_Service + for service in service_cls.instances(): + if service.EnabledDefault == service_cls.EnabledDefaultValues.Enabled: + print service.Name + +See available information about the 'cups' service:: + + cups = c.root.cimv2.LMI_Service.first_instance({"Name" : "cups.service"}) + cups.doc() + + +Start/stop service +------------------ +Start and stop 'cups' service, see status:: + + cups = c.root.cimv2.LMI_Service.first_instance({"Name" : "cups.service"}) + cups.StartService() + print cups.Status + cups.StopService() + print cups.Status + +Enable/disable service +---------------------- +Disable and enable 'cups' service, print EnabledDefault property:: + + cups = c.root.cimv2.LMI_Service.first_instance({"Name" : "cups.service"}) + cups.TurnServiceOff() + print cups.EnabledDefault + cups.TurnServiceOn() + print cups.EnabledDefault diff --git a/doc/admin/software/configuration.rst b/doc/admin/software/configuration.rst new file mode 100644 index 0000000..028f399 --- /dev/null +++ b/doc/admin/software/configuration.rst @@ -0,0 +1,155 @@ +Configuration +============= +There are various options affecting behaviour of *OpenLMI Software* provider. +All of them can be fine-tuned using two configuration files. The main one is +located at: :: + + /etc/openlmi/software/software.conf + +The other one is a global configuration file for all providers in *OpenLMI* +project and serves as a fallback, for options not specified in the main one. +It's located in: :: + + /etc/openlmi/openlmi.conf + +Since this is a common setup for all *OpenLMI* providers, administator can +specify options common to all in the global configuration file, while the +values specific for particular provider can be overriden in its main one +(``/etc/openlmi/${provider}/${provider}.conf``). + +.. + TODO: once we have a stable hosting for all OpenLMI documetation, let's + just point to top-level Configuration page. + +Treating boolean values +----------------------- +Options expecting boolean values treat following strings as valid ``True`` +values: + + * ``True`` + * ``1`` + * ``yes`` + * ``on`` + +While the following are considered ``False``: + + * ``0`` + * ``no`` + * ``False`` + * ``off`` + +These words are checked in a case-insensitive way. Any other value isn't +considered valid [1]_. + +Options +------- +Follows a list of valid options with sections enclosed in square brackets. + +*CIM* options +~~~~~~~~~~~~~ + + ``[CIM] Namespace`` : defaults to ``root/cimv2`` + Is a *CIM* namespace, where *CIM* classes of this provider are + registered. + + ``[CIM] SystemClassName`` : defaults to ``PG_ComputerSystem`` + Sets the class name used to refer to computer system. Different cimmoms + can instrument variously named computer systems and some may not + instrument any at all. `Sfcb`_ is an example of the later, it needs the + ``sblim-cmpi-base`` package installed providing the basic set of + providers containing ``Linux_ComputerSystem``. So in case you run a + ``Sfcb`` or you preferr to use providers from ``sblim-cmpi-base`` + package, you need to change this to ``Linux_ComputerSystem``. + +*YUM* options +~~~~~~~~~~~~~ +Options related to the use of *YUM* API and its configuration. + + ``[Yum] LockWaitInterval`` : defaults to 0.5 + Number of seconds to wait before next try to lock yum package database. + This applies, when yum database is locked by another process. + + ``[Yum] FreeDatabaseTimeout = 60`` : defaults to 60 + Number of seconds to keep package cache in memory after the last use + (caused by user request). Package cache takes up a lot of memory. + +*Log* options +~~~~~~~~~~~~~ + + ``[Yum] Level`` : defaults to ``ERROR`` + Can be set to one of the following: + + * ``CRITICAL`` + * ``ERROR`` + * ``WARNING`` + * ``INFO`` + * ``DEBUG`` + * ``TRACE_WARNING`` + * ``TRACE_INFO`` + * ``TRACE_VERBOSE`` + + It specifies the minimum severity of messages that shall be logged. + Messages having ``DEBUG`` or more severe level are sent to *CIMOM* + using standard function ``CMLogMessage()``. Tracing messages (whose + level names start with ``TRACE_`` use the ``CMTraceMessage()`` instead. + + Please consult the documentation of your *CIMOM* to see, how these + messages can be treated and logged to different facilities. + + .. note:: + This does not have any effect if the ``[Log] FileConfig`` option is + set. + + ``[Yum] Stderr`` : defaults to ``False`` + Whether to enable logging to standard error output. This does not + affect logging to *CIMOM* which stays enabled independently of this + option. + + This is mostly usefull when debugging with *CIMOM* running on + foreground. + + .. note:: + This does not have any effect if the ``[Log] FileConfig`` option is + set. + + .. seealso:: + Since this accepts boolean values, refer to + `Treating boolean values`_ for details. + + ``[Yum] FileConfig`` : defaults to empty string + This option overrides any other logging option. It provides complete + control over what is logged, when and where. It's a path to a logging + configuration file with format specified in: + http://docs.python.org/2/library/logging.config.html#configuration-file-format + Path can be absolute or relative. In the latter case it's relative to + a directory of this configuration file. + +*YumWorkerLog* options +~~~~~~~~~~~~~~~~~~~~~~ +This section is targeted mostly on developpers of *OpenLMI Software* provider. +*YUM* API is accessed exclusively from separated process called ``YumWorker``. +Because separated process can not send its log messages to *CIMOM*, its +logging configuration needs to be configured extra. + + ``[YumWorkerLog] OutputFile`` : defaults to empty string + This is an absolute or relative path to a file, where the logging + will be done. Without this option set, logging of ``YumWorker`` is + disabled (assuming the ``[YumWorkerLog] FileConfig`` option is also + unset). + + ``[YumWorkerLog] Level`` : defaults to ``DEBUG`` + This has generally the same meaning as ``Level`` in previous section + (`Log options`_). Except this affects only logging of ``YumWorker`` + process. + + ``[YumWorkerLog] FileConfig`` : defaults to empty string + Similar to the ``FileConfig`` option in `Log options`_. This overrides + any other option in this section. + +------------------------------------------------------------------------------- + +.. [1] Default value will be used as a fallback. This applies also to other + non-boolean options in case of invalid value. + +.. **************************************************************************** +.. _Sfcb: http://sourceforge.net/apps/mediawiki/sblim/index.php?title=Sfcb diff --git a/doc/admin/software/dmtf.rst b/doc/admin/software/dmtf.rst new file mode 100644 index 0000000..9aa460c --- /dev/null +++ b/doc/admin/software/dmtf.rst @@ -0,0 +1,300 @@ +.. _dmtf_profiles: + +DMTF profiles +============= +OpenLMI Software providers implement two *DMTF* profiles: + + * `Software Inventory Profile`_ + * `Software Update Profile`_ + +.. _software_inventory_profile: + +Software Inventory Profile +-------------------------- +Implemented *DMTF* version: ``1.0.1`` + +Described by `DSP1023`_ + +The Software Inventory Profile describes the CIM schema elements required to +provide an inventory of installed BIOS, firmware, drivers, and related +software in a managed system. This profile also describes the CIM schema +elements required to represent the software that can be installed on a +managed system. + + +Not implemented optional features +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This implementation does not support: + + Representing a Software Bundle + Software bundle is represented by LMI_SoftwareIndentity instance + having ``"Software Bundle"`` value present in its ``Classifications`` + property. It shall prepresent software groups. It extends the profile + for subclasses of ``CIM_OrderedComponent``. + + Representing Installation Dependencies + Dependencies between software packages are also unimplemented. This + also extends the profile for subclasses of ``CIM_OrderedDependency`` + referencing :ref:`CIM-SoftwareIdentity` instances. + +Deviations +~~~~~~~~~~ +Version Comparison +^^^^^^^^^^^^^^^^^^ +Version comparison is based on different approach than in *Software Inventory +Profile* where the following properties are present to uniquely specify +package version: + + * ``uint16`` :ref:`MajorVersion` + * ``uint16`` :ref:`MinorVersion` + * ``uint16`` :ref:`RevisionNumber` + * ``uint16`` :ref:`BuildNumber` + +And also a :ref:`VersionString` property +which is a composition of previous ones separed with dots. + +Unfortunately versioning of RPM packages is incompatible with this scheme. +Version of RPM package is composed of following properties: + +.. _version_properties: + + * ``uint32`` :ref:`Epoch` + * ``string`` :ref:`Version` + * ``string`` :ref:`Release` + +Where ``Version`` and ``Release`` can contain arbitrary set of characters [1]_. +These attributes were added to ``LMI_SoftwareIdentity`` class and will be +filled for every RPM package. On the other hand ``MajorVersion``, +``MinorVersion``, ``RevisionNumber`` and ``BuildNumber`` will not be filled. + +This implementetion composes ``VersionString`` in following way: :: + + :-. + +The algorithm for comparing two RPM packages version is following: + + 1. Compare the ``Epoch`` (which is a number) of both packages. The one + with higher epoch is newer. If they match, continue to point 2. + 2. Compare their ``Version`` attributes with `rpmvercmp`_ algorithm. + Package with larger ``Version`` (according to `rpmvercmp`_) is newer. + If they match, continue to point 3. + 3. Compare their ``Release`` attributes with `rpmvercmp`_ algorithm. + Package with larger ``Release`` string is newer. Otherwise packages + have the same version. + +Relationships between *Software Identity* and *Managed Element* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +are not modeled. RPM package database does not provide such informations +that would allow to associate particular package with a piece of hardware +it relates to. + +Querying for packages +^^^^^^^^^^^^^^^^^^^^^ +Since enumeration of *Software Identities* is disabled due to a huge +amount of data generated by large package database, the query +execution on them is also disallowed [2]_. The only way how to search +for packages is using the method +:ref:`LMI_SoftwareInstallationService.FindIdentity`. + +.. _identifying_software_identity: + +Identifying software identity +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +:ref:`InstanceID` key property is the one +and only identification string of :ref:`LMI-SoftwareIdentity` instances +representing RPM packages. It's composed of following strings: :: + + LMI:LMI_SoftwareIdentity:-:-. + +Where the prefix ``"LMI:LMI_SoftwareIdentity:"`` is compared case-insensitively. +The rest is also known as a *NEVRA*. When calling ``GetInstance()`` on this +class, the ``":"`` part can be omitted in the ``InstanceID`` key property +of passed ``InstanceName``. + +Example +^^^^^^^ +Take for example package ``vim-enhanced`` installed on Fedora 18: :: + + $ yum info vim-enhanced + Installed Packages + Name : vim-enhanced + Arch : x86_64 + Epoch : 2 + Version : 7.4.027 + Release : 2.fc18 + Size : 2.1 M + Repo : installed + From repo : updates-testing + +The output has been shortened. This package is represented by +an instance of ``LMI_SoftwareIdentity`` with ``InstanceID`` equal to: :: + + LMI:LMI_SoftwareIdentity:vim-enhanced-2:7.4.027-2.fc18.x86_64 + +Profile extensions +~~~~~~~~~~~~~~~~~~ +List of additional attributes of ``LMI_SoftwareIdentity``: + + * version properties mentioned above (`version_properties`_) + * ``string Architecture`` - Target machine architecture. Packages + with architecture independent content will have ``"noarch"`` value + set. + +List of additional attributes of ``LMI_SoftwareIdentityResource``: + + ``Cost`` : sint32 + Relative cost of accessing this repository. + ``GPGCheck`` : boolean + Whether the GPG signature check should be performed. + ``TimeOfLastUpdate`` : datetime + Time of repository's last update on server. + +Class overview +~~~~~~~~~~~~~~ + + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + | Class-name | Parent_class | Type | + +===============================================================================+=====================================================================+==================+ + | :ref:`LMI_SoftwareIdentity` | :ref:`CIM_SoftwareIdentity` | Plain | + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + | :ref:`LMI_SystemSoftwareCollection` | :ref:`CIM_SystemSpecificCollection` | Plain | + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + | :ref:`LMI_SoftwareIdentityResource` | :ref:`CIM_SoftwareIdentityResource` | Plain | + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + | :ref:`LMI_HostedSoftwareCollection` | :ref:`CIM_HostedCollection` | Association | + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + | :ref:`LMI_InstalledSoftwareIdentity` | :ref:`CIM_InstalledSoftwareIdentity` | Association | + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + | :ref:`LMI_HostedSoftwareIdentityResource` | :ref:`CIM_HostedAccessPoint` | Association | + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + | :ref:`LMI_ResourceForSoftwareIdentity` | :ref:`CIM_SAPAvailableForElement` | Association | + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + | :ref:`LMI_MemberOfSoftwareCollection` | :ref:`CIM_MemberOfCollection` | Aggregation | + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + + .. seealso:: + Class model in :ref:`introduction` where above classes are coloured blue. + +.. _software_update_profile: + +Software Update Profile +----------------------- +Implemented *DMTF* version: ``1.0.0`` + +Described by `DSP1025`_. + +The Software Update Profile describes the classes, associations, properties, +and methods used to support the installation and update of BIOS, firmware, +drivers and related software on a managed element within a managed system. + + +Implemented optional features +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This implementation supports: + + Advertising the Location Information of a Software Identity + This optional feature provides association of *Software Identity* to + its resource. In other words each available package is associated to + a corresponding repository defined in configuration files of *YUM*. + Repositories are represented with + :ref:`LMI_SoftwareIdentityResource` and + are associated to :ref:`LMI_SoftwareIdentity` + via + :ref:`LMI_ResourceForSoftwareIdentity`. + +Not implemented features +~~~~~~~~~~~~~~~~~~~~~~~~ +Following methods are not implemented: + + * :ref:`CIM_SoftwareInstallationService.InstallFromByteStream` + * :ref:`LMI_SoftwareInstallationService.CheckSoftwareIdentity` + +Profile extensions +~~~~~~~~~~~~~~~~~~ + +RPM package verification +^^^^^^^^^^^^^^^^^^^^^^^^ +*Software Inventory* and *Softare Update* profiles don't allow for software +verification. That is quite useful and desired operation done on RPM packages. +Following additions has been added to provide such a functionality. + +Following classes have been added: + + :ref:`LMI_SoftwareIdentityFileCheck` + Represents single file contained and installed by *RPM* package. + It contains properties allowing for comparison of installed file + attributes with those stored in a package database. In case those + attributes do not match, file fails the verification test. + + :ref:`LMI_SoftwareIdentityChecks` + Associates *Software Identity File Check* to corresponding + *Software Identity*. + +Following methods have been added: + + :ref:`LMI_SoftwareInstallationService.VerifyInstalledIdentity` + This allows to run verification test on particular *Software Identity* + and returns a list of files that failed. + +.. _package_searching: + +Package searching +^^^^^^^^^^^^^^^^^ +On modern Linux distributions we have thousands of software packages +available for installation making it nearly impossible for *CIMOM* to +enumerate them all because it consumes a lot of resources. That's why +the ``EnumerateInstances()`` and ``EnumerateInstanceNames()`` calls have been +disabled *Software Identities*. As a consequence the ``ExecQuery()`` call is prohibited also. + +But the ability to search for packages is so important that a fallback +solution has been provided. Method +:ref:`FindIdentity()` has been +added to +:ref:`LMI_SoftwareInstallationService` +allowing to create complex queries on package database. + +Class overview +~~~~~~~~~~~~~~ + + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | Class-name | Parent_class | Type | + +=====================================================================================================+=========================================================================+====================+ + | :ref:`LMI_SoftwareInstallationService` | :ref:`CIM_SoftwareInstallationService` | Plain | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_SoftwareJob` | :ref:`LMI_ConcreteJob` | Plain | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_SoftwareInstallationJob` | :ref:`LMI_SoftwareJob` | Plain | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_SoftwareVerificationJob` | :ref:`LMI_SoftwareJob` | Association | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_SoftwareMethodResult` | :ref:`LMI_MethodResult` | Association | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_SoftwareIdentityFileCheck` | :ref:`CIM_FileSpecification` | Association | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_SoftwareInstallationServiceAffectsElement` | :ref:`CIM_ServiceAffectsElement` | Association | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_SoftwareIdentityChecks` | | Aggregation | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_HostedSoftwareInstallationService` | :ref:`CIM_HostedService` | Plain | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_AffectedSoftwareJobElement` | :ref:`CIM_AffectedJobElement` | Plain | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_OwningSoftwareJobElement` | :ref:`LMI_OwningJobElement` | Plain | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_AssociatedSoftwareJobMethodResult` | :ref:`LMI_AssociatedJobMethodResult` | Plain | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + + .. seealso:: + Class model in :ref:`introduction` where above classes are coloured blue. + +.. + *************************************************************************** +.. _DSP1023: http://www.dmtf.org/sites/default/files/standards/documents/DSP1023_1.0.1.pdf +.. _DSP1025: http://www.dmtf.org/sites/default/files/standards/documents/DSP1025_1.0.0.pdf +.. _rpmvercmp: http://fedoraproject.org/wiki/Tools/RPM/VersionComparison + +------------------------------------------------------------------------------ + +.. [1] Precisely they must match following regular expression `r"[\w.+{}]+"`. +.. [2] Because internally the query is executed upon the list obtained by + enumeration of instances. diff --git a/doc/admin/software/index.rst b/doc/admin/software/index.rst new file mode 100644 index 0000000..1fd392a --- /dev/null +++ b/doc/admin/software/index.rst @@ -0,0 +1,29 @@ +.. OpenLMI Software Provider documentation master file, created by + sphinx-quickstart on Thu Oct 3 14:25:59 2013. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +OpenLMI Software Provider's documentation +========================================= + +Contents: + +.. toctree:: + :maxdepth: 2 + + introduction + dmtf + configuration + usage + +.. ifconfig:: includeClasses + + OpenLMI Storage CIM classes: + + .. toctree:: + :maxdepth: 1 + + mof/tree + mof/index + + diff --git a/doc/admin/software/introduction.rst b/doc/admin/software/introduction.rst new file mode 100644 index 0000000..21cead0 --- /dev/null +++ b/doc/admin/software/introduction.rst @@ -0,0 +1,158 @@ +.. _introduction: + +Introduction +============ +*OpenLMI Software* provider allows to query and manipulate software package +database on remote hosts. They utilize :abbr:`YUM (Yellowdog Updater +Modified)` which is a standard package manager for several *GNU/Linux* +distributions. They provide the subset of its functionality. + +*RPM* database, repositories and the package manager itself are modeled with +*CIM* classes according to several *DMTF* profiles described +:ref:`later`. To make a query on database, install, update a +remove some *RPM* package means to trigger some operation on one or several +*CIM* classes. This page explains the mapping of mentioned objects to +corresponding classes. + +.. figure:: pic/software-profile.svg + :alt: OpenLMI Software class model + :width: 800px + + This model shows classes representing various objects taking role in + software management provided by *OpenLMI Software* provider. + +Classes with the blue background belong to :ref:`software_inventory_profile`. +Classes painted yellow belong to :ref:`software_update_profile` that builds on +the former one. Classes painted red/pink are extensions not beloning to any +*DMTF* profile. + +Mapping of objects to *CIM* classes +----------------------------------- +*RPM* package : :ref:`LMI_SoftwareIdentity` + Is represented by ``LMI_SoftwareIdentity``. It's identified by a single + key property called + :ref:`LMI_SoftwareIdentity.InstanceID`. + This is a composition of some *CIM* related prefix with package's *NEVRA* + string. It's the similar string you may see, when listing package with + ``rpm`` tool: :: + + $ rpm -qa 'openlmi-*' vim-enhanced + openlmi-python-base-0.3.0_5_gf056906-2.fc21.noarch + openlmi-providers-0.3.0_5_gf056906-2.fc21.x86_64 + openlmi-indicationmanager-libs-0.3.0_5_gf056906-2.fc21.x86_64 + openlmi-account-0.3.0_5_gf056906-2.fc21.x86_64 + openlmi-service-0.3.0_5_gf056906-2.fc21.x86_64 + vim-enhanced-7.4.027-2.fc20.x86_64 + openlmi-logicalfile-0.3.0_5_gf056906-2.fc21.x86_64 + openlmi-storage-0.6.0-2.fc20.noarch + openlmi-python-providers-0.3.0_5_gf056906-2.fc21.noarch + openlmi-providers-debuginfo-0.3.0_5_gf056906-2.fc21.x86_64 + openlmi-software-0.3.0_5_gf056906-2.fc21.noarch + + except for *Epoch* part, which is omitted by ``rpm`` tool but is + required to be present in ``InstanceID`` by instrumenting provider. + To get the expected output, the above command needs to be modified: :: + + $ rpm --qf '%{NAME}-%{EPOCH}:%{VERSION}-%{RELEASE}.%{ARCH}\n' -qa 'openlmi-*' | sed 's/(none)/0/' + openlmi-python-base-0:0.3.0_5_gf056906-2.fc21.noarch + openlmi-providers-0:0.3.0_5_gf056906-2.fc21.x86_64 + openlmi-indicationmanager-libs-0:0.3.0_5_gf056906-2.fc21.x86_64 + openlmi-account-0:0.3.0_5_gf056906-2.fc21.x86_64 + openlmi-service-0:0.3.0_5_gf056906-2.fc21.x86_64 + vim-enhanced-2:7.4.027-2.fc20.x86_64 + openlmi-logicalfile-0:0.3.0_5_gf056906-2.fc21.x86_64 + openlmi-storage-0:0.6.0-2.fc20.noarch + openlmi-python-providers-0:0.3.0_5_gf056906-2.fc21.noarch + openlmi-providers-debuginfo-0:0.3.0_5_gf056906-2.fc21.x86_64 + openlmi-software-0:0.3.0_5_gf056906-2.fc21.noarch + + Some *RPM* packages do not define *Epoch* part, which means its 0 although + ``rpm`` returns ``(none)``. + + When installing, updating or removing package, we operate upon an + instance or object path of this class. + + .. seealso:: + :ref:`identifying_software_identity` + +Repository : :ref:`LMI_SoftwareIdentityResource` + Is represented by ``LMI_SoftwareIdentityResource``. What distinguishes + particular repository from others on the same system is a + :ref:`LMI_SoftwareIdentityResource.Name` + key property. It's the name of repository written in square brackets in + repository config. Not the configuration file name, not the ``name`` + option, but a the name of section. See the example of ``OpenLMI Nightly`` + repository: :: + + $ cat /etc/yum.repos.d/openlmi-nightly.repo + [openlmi-nightly] + name=OpenLMI Nightly + baseurl=http://openlmi-rnovacek.rhcloud.com/rpm/rawhide/ + gpgcheck=0 + enabled = 1 + + The ``Name`` property of corresponding *Software Identity Resource* will + be ``openlmi-nightly``. + +Installed file : :ref:`LMI_SoftwareIdentityFileCheck` + Is represented by ``LMI_SoftwareIdentityFileCheck``. Represents a + verification check of particular file installed by *RPM* package. It contains + attributes being checked, like: + + * ``User ID``, ``Group ID`` + * ``Checksum`` + * ``Link Target`` + * ``File Mode`` and others + + Each is present twice. One property represents the current value of + installed file and the other the value stored in *RPM* package, that the + file should have. The later properties have ``Original`` suffix. So for + example: + + * :ref:`UserID` vs + :ref:`UserIDOriginal` + * :ref:`FileChecksum` vs + :ref:`FileChecksumOriginal` + + Mentioned attributes are compared when the package verification is done. + Single file can also be easily checked. Either by running + :ref:`LMI_SoftwareIdentityFileCheck.Invoke()` + method on particular object path or by testing the + :ref:`FailedFlags` property for + emptiness. If its empty, the file or directory passed the verification test. + +*RPM* database : :ref:`LMI_SystemSoftwareCollection` + Is represented by ``LMI_SystemSoftwareCollection``. Administrator probably + won't be interested in this class. The + :ref:`LMI_MemberOfSoftwareCollection` + association class associates this collection with available and installed + *Software Identities*. It can not be enumerated --- due to the same reason + as in case of :ref:`LMI_SoftwareIdentity` (see the + explanation in :ref:`package_searching`). + +*YUM* package manager : :ref:`LMI_SoftwareInstallationService` + Is represented by ``LMI_SoftwareInstallationService``. Allows to query the + database, install, update, verify and remove *RPM* packages. All of this can + be achieved by invocations of its methods: + + :ref:`FindIdentity()` + Allows to query the database for matching packages. + + :ref:`InstallFromSoftwareIdentity()` + Allows to install, update or remove *RPM* package represented by an + instance of *Software Identity*. + + :ref:`InstallFromURI()` + Allows to install or update *RPM* package located with particular + URI string. + + :ref:`VerifyInstalledIdentity()`. + Runs a verification check on given *Software Identity*. + + .. seealso:: + Examples on using above methods: + + * :ref:`package_installation` + * :ref:`package_update` + * :ref:`package_removal` + * :ref:`package_verification` diff --git a/doc/admin/software/pic/Makefile b/doc/admin/software/pic/Makefile new file mode 100644 index 0000000..6603451 --- /dev/null +++ b/doc/admin/software/pic/Makefile @@ -0,0 +1,16 @@ +FIGS=$(wildcard *.eps *.svg *.dia) +TARGETS=$(foreach f,$(filter %.dia,$(FIGS)),$(basename $(f)).svg) + +all: $(TARGETS) + +%.pdf: %.eps + epstopdf $^ --outfile=$@ + +%.eps: %.dia + dia -t eps -e $@ $? + +%.svg: %.dia + dia -t svg -e $@ $? + +%.pdf: %.svg + inkscape --export-pdf=$@ -f $? diff --git a/doc/admin/software/pic/software-profile.dia b/doc/admin/software/pic/software-profile.dia new file mode 100644 index 0000000..35638d3 Binary files /dev/null and b/doc/admin/software/pic/software-profile.dia differ diff --git a/doc/admin/software/pic/software-profile.svg b/doc/admin/software/pic/software-profile.svg new file mode 100644 index 0000000..42c2103 --- /dev/null +++ b/doc/admin/software/pic/software-profile.svg @@ -0,0 +1,255 @@ + + + + + + + SoftwareIdentity + + + +* InstanceID: string + +Caption: string + +Classifications: uint16[] + +Description: string + +ElementName: string + +InstallDate: datetime + +IsEntity: boolean + +Name: string + +TargetTypes: string[] + +VersionString: string + +Epoch: uint32 + +Version: string + +Release: string + +Architecture: string + + + + + SoftwareIdentityResource + + + +* CreationClassName: string + +* Name: string + +* SystemCreationClassName: string + +* SystemName: string + +AccessContext: uint16 + +AccessInfo: string + +AvailableRequestedStates: uint16[] + +Caption: string + +Cost: sint32 + +Description: string + +ElementName: string + +EnabledDefault: uint16 + +EnabledState: uint16 + +ExtendedResourceType: uint16 + +Generation: uint64 + +HealthState: uint16 + +GPGCheck: boolean + +InfoFormat: uint16 + +InstanceID: string + +MirrorList: string + +OperationalStatus: uint16[] + +OtherAccessContext: string + +PrimaryStatus: uint16 + +RepoGPGCheck: boolean + +RequestedState: uint16 + +ResourceType: uint16 + +StatusDescriptions: string[] + +TimeOfLastStateChange: datetime + +TimeOfLastUpdate: datetime + +TransitioningToState: uin16 + + + +RequestStateChange(): uint32 + + + + + SystemSoftwareCollection + + + +* InstanceID: string + +Caption: string + + + + + CIM_ComputerSystem + + + +* CreationClassName: string + +* Name: string + + + + + + InstalledSoftwareIdentity + System + * + InstalledSoftware + * + + + + + SoftwareInstallationService + + + +* CreationClassName: string + +* Name: string + +* SystemCreationClassName: string + +* SystemName: string + +Caption: string + +CommunicationStatus: uint16 + +Description: string + +DetailedStatus: uint16 + +EnabledDefault: uint16 + +HealthState: uint16 + +InstanceID: string + +OperatingStatus: uint16 + +OperationalStatus: uint16[] + +PrimaryStatus: string + +RequestedState: uint16 + +Started: boolean + +TransitioningToState: uint16 + + + +CheckSoftwareIdentity(): uint32 + +InstallFromSoftwareIdentity(): uint32 + +InstallFromURI(): uint32 + +VerifyInstalledIdentity(): uint32 + + + + HostedSoftwareCollection + Antecedent + 1 + Dependent + 0..1 + + + + HostedSoftwareInstallationService + Antecedent + 1 + Dependent + * + + + + SoftwareInstallationServiceAffectsElement + AffectedElement + 1..* + AffectingElement + * + + + + ResourceForSoftwareIdentity + ManagedElement + 1 + AvailableSAP + 0..1 + + + + HostedSoftwareIdentityResource + Antecedent + 1 + Dependent + * + + + + + + MemberOfSoftwareCollection + + Member + * + Collection + * + + + + + InstallationServiceCapabilities + + + +* InstanceID: string + +CanAddToCollection: boolean + +SupportedTargetTypes: string[] + +SupportedInstallOptions: uint16 + +Description: string + +SupportedURISchemes + + + + AssociatedSoftwareInstallationServiceCapabilities + ManagedElement + 1..* + Capabilities + 1 + + + + SoftwareInstallationServiceAffectsElement + AffectedElement + * + AffectingElement + * + + + + + SoftwareIdentityFileCheck + + + +* Name: string + +* CheckID: string + +* SoftwareElementID: string + +* SoftwareElementState: uint16 + +* TargetOperatingSystem: uint16 + +* Version: string + +CheckMode: boolean + +ChecksumType: uint16 + +FailedFlags: uint16[] + +FileChecksum: string + +FileChecksumOriginal: string + +FileExists: boolean + +FileMode: uint32 + +FileModeOriginal: uint32 + +FileModeFlags: uint8[] + +FileModeFlagsOriginal: uint8[] + +FileName: string + +FileSize: uint64 + +FileSizeOriginal: uint64 + +FileType: uint16 + +FileTypeOriginal: uint16 + +GroupID: uint32 + +GroupIDOriginal: uint32 + +MD5Checksum: string + +LastModificationTime: uint64 + +LastModificationTimeOriginal: uint64 + +LinkTarget: string + +LinkTargetOriginal: string + +UserID: uint32 + +UserIDOriginal: uint32 + + + +Invoke(): uin32 + +InvokeOnSystem(): uint32 + + + + + + FileIdentityChecks + + Element + 1 + Check + * + + diff --git a/doc/admin/software/usage.rst b/doc/admin/software/usage.rst new file mode 100644 index 0000000..5bc034f --- /dev/null +++ b/doc/admin/software/usage.rst @@ -0,0 +1,625 @@ +*OpenLMI Software* usage +======================== +Examples for common use cases listed below are written in `lmishell`_. Where +appropriate, an example for ``lmi`` meta-command, which is a part of +*OpenLMI-Scripts* project, is added. Please refer to its `documentation`_ +for installation notes and usage. + +Listing installed packages +-------------------------- +Simple +~~~~~~ +Simple but very slow way: :: + + c = connect("host", "user", "pass") + cs = c.root.cimv2.PG_ComputerSystem.first_instance() + for identity in cs.associators( + AssocClass="LMI_InstalledSoftwareIdentity", + Role="System", + ResultRole="InstalledSoftware", + ResultClass="LMI_SoftwareIdentity"): + print(identity.ElementName) + +.. note:: + Here we use ``PG_ComputerSystem`` as a class representing computer + system. It is part of ``sblim-cmpi-base`` package, which is obsoleted. + If you use *Pegasus* as your *CIMOM* you may safely switch to + ``PG_ComputerSystem``. + +.. seealso:: + :ref:`LMI_InstalledSoftwareIdentity` + +Faster +~~~~~~ +This is much faster. Here we enumerate association class +:ref:`LMI_InstalledSoftwareIdentity` and +get information from its key properties. :: + + c = connect("host", "user", "pass") + for iname in c.root.cimv2.LMI_InstalledSoftwareIdentity.instance_names(): + print(iname.path["InstalledSoftware"]["InstanceID"] + [len("LMI:LMI_SoftwareIdentity:"):]) + +.. note:: + Whole instance is not available. To get it from association instance name, + you need to add: :: + + iname.path["InstalledSoftware"].to_instance() + + +``lmi`` meta-command +~~~~~~~~~~~~~~~~~~~~ +:: + + lmi -h $HOST sw list pkgs + +Listing repositories +-------------------- +lmishell +~~~~~~~~ +:: + + c = connect("host", "user", "pass") + for repo in c.root.cimv2.LMI_SoftwareIdentityResource.instance_names(): + print(repo.path["Name"]) + +.. seealso:: + :ref:`LMI_SoftwareIdentityResource` + +``lmi`` meta-command +~~~~~~~~~~~~~~~~~~~~ +:: + + lmi -h $HOST sw list pkgs + +Listing available packages +-------------------------- +lmishell +~~~~~~~~ +Enumerating of :ref:`LMI_SoftwareIdentity` is +disabled due to a huge amount of data being generated. That's why we +enumerate them for particular repository represented by +:ref:`LMI_SoftwareIdentityResource`. :: + + c = connect("host", "user", "pass") + for repo in c.root.cimv2.LMI_SoftwareIdentityResource.instances(): + if repo.EnabledState != 2: # != Enabled + continue # skip disabled repositories + print(repo.Name) + for identity in repo.associator_names( + AssocClass="LMI_ResourceForSoftwareIdentity", + Role="AvailableSAP", + ResultRole="ManagedElement", + ResultClass="LMI_SoftwareIdentity"): + print(" " + identity.path["InstanceID"] + [len("LMI:LMI_SoftwareIdentity:"):]) + +.. seealso:: + :ref:`LMI_ResourceForSoftwareIdentity` + +``lmi`` meta-command +~~~~~~~~~~~~~~~~~~~~ +:: + + lmi -h $HOST sw list --available pkgs + +Listing files of package +------------------------ +Let's list files of packages ``openlmi-tools``. Note that package must +be installed on system in order to list its files. + +lmishell +~~~~~~~~ +We need to know exact *NEVRA* [1]_ of package we want to operate on. If +we don't know it, we can find out using +:ref:`FindIdentity()` method. +See example under `Searching for packages`_. :: + + c = connect("host", "user", "pass") + identity = c.root.cimv2.LMI_SoftwareIdentity.new_instance_name( + {"InstanceID" : "LMI:LMI_SoftwareIdentity:openlmi-tools-0:0.5-2.fc18.noarch"}) + for filecheck in identity.to_instance().associator_names( + AssocClass="LMI_SoftwareIdentityChecks", + Role="Element", + ResultRole="Check", + ResultClass="LMI_SoftwareIdentityFileCheck"): + print("%s" % filecheck.path["Name"]) + +.. seealso:: + :ref:`LMI_SoftwareIdentityFileCheck` + +``lmi`` meta-command +~~~~~~~~~~~~~~~~~~~~ +:: + + lmi -h $HOST sw list files openlmi-tools + +Searching for packages +---------------------- +If we know just a fraction of informations needed to identify a package, +we may query package database in the following way. + +``lmishell`` +~~~~~~~~~~~~ +:: + + c = connect("host", "user", "pass") + service = LMI_SoftwareInstallationService.first_instance() + # let's find all packages with "openlmi" in Name or Summary without + # architecture specific code + ret = service.FindIdentity(Name="openlmi", Architecture="noarch") + for identity in ret.rparams["Matches"]: + # we've got only references to instances + print identity.path["Name"][len("LMI:LMI_SoftwareIdentity:"):] + +.. seealso:: + :ref:`FindIdentity()` method + +Please don't use this method to get an instance of package you know +precisely. If you know all the identification details, you may just +construct the instance name this way: :: + + c = connect("host", "user", "pass") + iname = c.root.cimv2.LMI_SoftwareIdentity.new_instance_name( + {"InstanceID" : "LMI:LMI_SoftwareIdentity:openlmi-software-0:0.1.1-2.fc20.noarch"}) + identity = iname.to_instance() + +``lmi`` meta-command +~~~~~~~~~~~~~~~~~~~~ +See help on ``sw`` command for more information on this. :: + + lmi -h $HOST sw list pkgs openlmi + +.. _package_installation: + +Package installation +-------------------- +There are two approaches to package installation. One is synchronous +and the other asynchronous. + +Synchronous installation +~~~~~~~~~~~~~~~~~~~~~~~~ +This is a very simple and straightforward approach. We install package by +creating a new instance of +:ref:`LMI_InstalledSoftwareIdentity` +with a reference to some available software identity. :: + + c = connect("host", "user", "pass") + identity = c.root.cimv2.LMI_SoftwareIdentity.new_instance_name( + {"InstanceID" : "LMI:LMI_SoftwareIdentity:sblim-sfcb-0:1.3.16-3.fc19.x86_64"}) + cs = c.root.cimv2.PG_ComputerSystem.first_instance_name() + installed_assoc = c.root.cimv2.LMI_InstalledSoftwareIdentity.create_instance( + properties={ + "InstalledSoftware" : identity.path, + "System" : cs.path + }) + +If the package is already installed, this operation will fail with +the :py:class:`pywbem.CIMError` exception being raised initialized with +``CIM_ERR_ALREADY_EXISTS`` error code. + +Asynchronous installation +~~~~~~~~~~~~~~~~~~~~~~~~~ +Method +:ref:`InstallFromSoftwareIdentity()` +needs to be invoked with desired options. After the options are checked +by provider, a job will be returned representing installation process running +at background. Please refer to `Asynchronous Jobs`_ for more details. + +:: + + c = connect("host", "user", "pass") + service = c.root.cimv2.LMI_SoftwareInstallationService.first_instance() + identity = c.root.cimv2.LMI_SoftwareIdentity.new_instance_name( + {"InstanceID" : "LMI:LMI_SoftwareIdentity:sblim-sfcb-0:1.3.16-5.fc19.x86_64"}) + cs = c.root.cimv2.PG_ComputerSystem.first_instance_name() + ret = service.InstallFromSoftwareIdentity( + Source=identity.path, + Target=cs.path, + # these options request to install available, not installed package + InstallOptions=[4] # [Install] + # this will force installation if package is already installed + # (possibly in different version) + #InstallOptions=[4, 3] # [Install, Force installation] + ) + +The result can be checked by polling resulting job for finished status: :: + + finished_statuses = { + c.root.cimv2.CIM_ConcreteJob.JobState.Completed + , c.root.cimv2.CIM_ConcreteJob.JobState.Exception + , c.root.cimv2.CIM_ConcreteJob.JobState.Terminated + } + job = ret.rparams["Job"].to_instance() + while job.JobStatus not in finished_statuses: + # wait for job to complete + time.sleep(1) + job.refresh() + print c.root.cimv2.LMI_SoftwareJob.JobStateValues.value_name(job.JobState) + # get an associated job method result and check the return value + print "result: %s" % job.first_associator( + AssocClass='LMI_AssociatedSoftwareJobMethodResult').__ReturnValue + # get installed software identity + installed = job.first_associator( + Role='AffectingElement', + ResultRole='AffectedElement', + AssocClass="LMI_AffectedSoftwareJobElement", + ResultClass='LMI_SoftwareIdentity') + print "installed %s at %s" % (installed.ElementName, installed.InstallDate) + +You may also subscribe to indications related to +:ref:`LMI_SoftwareInstallationJob` and listen for +events instead of the polling done above + +As you can see, you may force the installation allowing for reinstallation +of already installed package. For more options please refer to the +documentation of this method. + +Combined way +~~~~~~~~~~~~ +We can combine both approaches by utilizing a feature of lmishell_. Method +above can be called in a synchronous way (from the perspective of script's +code). It's done like this: :: + + # note the use of "Sync" prefix + ret = service.SyncInstallFromSoftwareIdentity( + Source=identity.path, + Target=cs.path, + # these options request to install available, not installed package + InstallOptions=[4] # [Install] + # this will force installation if package is already installed + # (possibly in different version) + #InstallOptions=[4, 3] # [Install, Force installation] + ) + print "result: %s" % ret.rval + +The value of +:ref:`LMI_SoftwareMethodResult` ``.__ReturnValue`` is +placed to the ``ret.rval`` attribute. Waiting for job's completion is taken care +of by lmishell_. But we lose the reference to the job itself and we can not +enumerate affected elements (that contain, among other things, installed +package). + +Installation from URI +~~~~~~~~~~~~~~~~~~~~~ +This is also possible with: :: + + c = connect("host", "user", "pass") + service = c.root.cimv2.LMI_SoftwareInstallationService.first_instance() + cs = c.root.cimv2.PG_ComputerSystem.first_instance_name() + ret = service.to_instance().InstallFromSoftwareURI( + Source="http://someserver.com/fedora/repo/package.rpm", + Target=cs.path, + InstallOptions=[4]) # [Install] + +Supported *URI* schemes are: + + * ``http`` + * ``https`` + * ``ftp`` + * ``file`` + +In the last cast, the file must be located on the remote system hosting +the *CIMOM*. + + +.. seealso:: + :ref:`InstallFromURI()` + method + + Please refer to `Asynchronous installation`_ above for the consequent + procedure and how to deal with ``ret`` value. + +``lmi`` meta-command +~~~~~~~~~~~~~~~~~~~~ +:: + + lmi -h $HOST sw install sblim-sfcb + +.. _package_removal: + +Package removal +--------------- +Again both asynchronous and synchronous approaches are available. + +Synchronous removal +~~~~~~~~~~~~~~~~~~~ +The aim is achieved by issuing an opposite operation than before. The instance +of :ref:`LMI_InstalledSoftwareIdentity` is +deleted here. :: + + c = connect("host", "user", "pass") + identity = c.root.cimv2.LMI_SoftwareIdentity.new_instance_name( + {"InstanceID" : "LMI:LMI_SoftwareIdentity:sblim-sfcb-0:1.3.16-3.fc19.x86_64"}) + installed_assocs = identity.to_instance().reference_names( + Role="InstalledSoftware", + ResultClass="LMI_InstalledSoftwareIdentity") + if len(installed_assocs) > 0: + for assoc in installed_assocs: + assoc.to_instance().delete() + print("deleted %s" % assoc.path["InstalledSoftware"]["InstanceID"]) + else: + print("no package removed") + +Asynchronous removal +~~~~~~~~~~~~~~~~~~~~ +:: + + c = connect("host", "user", "pass") + service = c.root.cimv2.LMI_SoftwareInstallationService.first_instance() + identity = c.root.cimv2.LMI_SoftwareIdentity.new_instance_name( + {"InstanceID" : "LMI:LMI_SoftwareIdentity:sblim-sfcb-0:1.3.16-5.fc19.x86_64"}) + cs = c.root.cimv2.PG_ComputerSystem.first_instance_name() + ret = service.InstallFromSoftwareIdentity( + Source=identity.path, + Target=cs.path, + InstallOptions=[9]) # [Uninstall] + +Again please refer to `Asynchronous installation`_ for examples on how to +deal with the ``ret`` value. + +``lmi`` meta-command +~~~~~~~~~~~~~~~~~~~~ +:: + + lmi -h $HOST sw remove sblim-sfcb + +.. _package_update: + +Package update +-------------- +Only asynchronous method is provided for this purpose. But with the possibility +of synchronous invocation. + +``lmishell`` +~~~~~~~~~~~~ +Example below shows the synchronous invocation of asynchronous method. :: + + c = connect("host", "user", "pass") + service = c.root.cimv2.LMI_SoftwareInstallationService.first_instance() + identity = c.root.cimv2.LMI_SoftwareIdentity.new_instance_name( + {"InstanceID" : "LMI:LMI_SoftwareIdentity:sblim-sfcb-0:1.3.16-5.fc19.x86_64"}) + cs = c.root.cimv2.PG_ComputerSystem.first_instance_name() + ret = service.SyncInstallFromSoftwareIdentity( + Source=identity.path, + Target=cs.path, + InstallOptions=[5] # [Update] + # to force update, when package is not installed + #InstallOptions=[4, 5] # [Install, Update] + ) + print "installation " + ("successful" if rval == 0 else "failed") + +``lmi`` meta-command +~~~~~~~~~~~~~~~~~~~~ +:: + + lmi -h $HOST sw update sblim-sfcb + +.. _package_verification: + +Package verification +-------------------- +Installed *RPM* packages can be verified. Attributes of installed files +are compared with those stored in particular *RPM* package. If some value +of attribute does not match or the file does not exist, it fails the +verification test. Following attributes come into play in this process: + + * File size - in case of regular file + * User ID + * Group ID + * Last modification time + * Mode + * Device numbers - in case of device file + * Link Target - in case the file is a symbolic link + * Checksum - in case of regular file + +``lmishell`` +~~~~~~~~~~~~ +It's done via invocation of +:ref:`VerifyInstalledIdentity()`. +This is an asynchronous method. We can not use synchronous invocation +if we want to be able to list failed files. + +:: + + c = connect("host", "user", "pass") + service = ns.LMI_SoftwareInstallationService.first_instance() + identity = c.root.cimv2.LMI_SoftwareIdentity.new_instance_name( + {"InstanceID" : "LMI:LMI_SoftwareIdentity:sblim-sfcb-0:1.3.16-5.fc19.x86_64"}) + results = service.VerifyInstalledIdentity( + Source=identity.path, + Target=ns.PG_ComputerSystem.first_instance().path) + nevra = ( identity.path['InstanceId'] + if isinstance(identity, LMIInstanceName) + else identity.InstanceId)[len('LMI:LMI_SoftwareIdentity:'):] + if results.rval != 4096: + msg = 'failed to verify identity "%s (rval=%d)"' % (nevra, results.rval) + if results.errorstr: + msg += ': ' + results.errorstr + raise Exception(msg) + + job = results.rparams['Job'].to_instance() + + # wait by polling or listening for indication + wait_for_job_finished(job) + + if not LMIJob.lmi_is_job_completed(job): + msg = 'failed to verify package "%s"' % nevra + if job.ErrorDescription: + msg += ': ' + job.ErrorDescription + raise Exception(msg) + + # get the failed files + failed = job.associators( + AssocClass="LMI_AffectedSoftwareJobElement", + Role='AffectingElement', + ResultRole='AffectedElement', + ResultClass='LMI_SoftwareIdentityFileCheck') + for iname in failed: + print iname.Name # print their paths + +Polling, as a way of waiting for job completion, has been already shown in the +example under `Asynchronous installation`_. + +.. seealso:: + :ref:`LMI_SoftwareIdentityFileCheck` + +``lmi`` meta-command +~~~~~~~~~~~~~~~~~~~~ +:: + + lmi -h $HOST sw verify sblim-sfcb + +Enable and disable repository +----------------------------- + +``lmishell`` +~~~~~~~~~~~~ +:: + + c = connect("host", "user", "pass") + repo = c.root.cimv2.LMI_SoftwareIdentityResource.first_instance_name( + key="Name", + value="fedora-updates-testing") + # disable repository + repo.to_instance().RequestStateChange( + RequestedState=c.root.cimv2.LMI_SoftwareIdentityResource. \ + RequestedStateValues.Disabled) + repo = c.root.cimv2.LMI_SoftwareIdentityResource.first_instance_name( + key="Name", + value="fedora-updates") + # enable repository + repo.to_instance().RequestStateChange( + RequestedState=c.root.cimv2.LMI_SoftwareIdentityResource. \ + RequestedStateValues.Enabled) + +``lmi`` meta-command +~~~~~~~~~~~~~~~~~~~~ +:: + + lmi -h $HOST sw disable fedora-updates-testing + lmi -h $HOST sw enable fedora-updates + + +Supported event filters +----------------------- +There are various events related to asynchronous job you may be interested +about. All of them can be suscribed to with static filters presented below. +Usage of custom query strings is not supported due to a complexity of +its parsing. These filters should be already registered in *CIMOM* if +*OpenLMI Software* providers are installed. You may check them by enumerating +``LMI_IndicationFilter`` class located in ``root/interop`` namespace. +All of them apply to two different software job classes you may want to +subscribe to: + + :ref:`LMI_SoftwareInstallationJob` + Represents a job requesting to install, update or remove some package. + + :ref:`LMI_SoftwareVerificationJob` + Represents a job requesting verification of installed package. + +Filters below are written for :ref:`LMI_SoftwareInstallationJob` only. If you deal with the other one, just replace the +class name right after the ``ISA`` operator and classname in filter's name. + +Percent Updated +~~~~~~~~~~~~~~~ +Indication is sent when the +:ref:`LMI_SoftwareJob.PercentComplete` +property of a job changes. + +:: + + SELECT * FROM LMI_SoftwareInstModification WHERE + SourceInstance ISA LMI_SoftwareInstallationJob AND + SourceInstance.CIM_ConcreteJob::PercentComplete <> + PreviousInstance.CIM_ConcreteJob::PercentComplete + +Registered under filter name +``"LMI:LMI_SoftwareInstallationJob:PercentUpdated"``. + +Job state change +~~~~~~~~~~~~~~~~ +Indication is sent when the +:ref:`LMI_SoftwareJob.JobState` +property of a job changes. + +:: + + SELECT * FROM LMI_SoftwareInstModification WHERE + SourceInstance ISA LMI_SoftwareInstallationJob AND + SourceInstance.CIM_ConcreteJob::JobState <> + PreviousInstance.CIM_ConcreteJob::JobState + +Registered under filter name ``"LMI:LMI_SoftwareInstallationJob:Changed"``. + +Job Completed +~~~~~~~~~~~~~ +This event occurs when the state of job becomes ``COMPLETED/OK`` [2]_. + +:: + + SELECT * FROM LMI_SoftwareInstModification WHERE + SourceInstance ISA LMI_SoftwareInstallationJob AND + SourceInstance.CIM_ConcreteJob::JobState = 17 + +Registered under filter name ``"LMI:LMI_SoftwareInstallationJob:Succeeded"``. + +Error +~~~~~ +This event occurs when the state of job becomes ``COMPLETED/Error`` [3]_. + +:: + + SELECT * FROM LMI_SoftwareInstModification WHERE + SourceInstance ISA LMI_SoftwareInstallationJob AND + SourceInstance.CIM_ConcreteJob::JobState = 10 + +Registered under filter name ``"LMI:LMI_SoftwareInstallationJob:Failed"``. + +New Job +~~~~~~~ +This event occurs when the new instance of +:ref:`LMI_SoftwareJob` is created. + +:: + + SELECT * FROM LMI_SoftwareInstCreation WHERE + SourceInstance ISA LMI_SoftwareInstallationJob + +Registered under filter name ``"LMI:LMI_SoftwareInstallationJob:Created"``. + +------------------------------------------------------------------------------ + +.. [1] Stands for + + .. raw:: html + + Name, Epoch, Version, Release, + Architecure. + + .. raw:: latex + + \textbf{N}ame, \textbf{E}poch, \textbf{V}ersion, \textbf{R}elease, + \textbf{A}rchitecture. + + .. only:: not html and not latex + + Name, Epoch, Version, Release, Architecure. + + Please refer to :ref:`identifying_software_identity` for more details. + +.. [2] This is a composition of values in + :ref:`OperationalStatus` array. + It corresponds to value ``Completed`` of + :ref:`JobState` property. + +.. [3] This is a composition of values in + :ref:`OperationalStatus` array. + It corresponds to value ``Exception`` of + :ref:`JobState` property. + + +.. ***************************************************************************** +.. _documentation: https://fedorahosted.org/openlmi/wiki/scripts +.. _lmishell: https://fedorahosted.org/openlmi/wiki/shell +.. _`Asynchronous Jobs`: http://jsafrane.fedorapeople.org/openlmi-storage/api/0.6.0/concept-job.html#asynchronous-jobs -- cgit