diff options
author | Jan Safranek <jsafrane@redhat.com> | 2013-10-18 14:45:03 +0200 |
---|---|---|
committer | Jan Safranek <jsafrane@redhat.com> | 2013-10-18 14:45:03 +0200 |
commit | c15f9ee5a0e25a91781e4c23f1cfb0ca7c5b7336 (patch) | |
tree | dc34216411938495b489368e15e22a7e5a5d0878 /doc | |
parent | 087d51a3b03815ddbacaf62bf2fa047dbcbb9537 (diff) | |
download | openlmi-providers-c15f9ee5a0e25a91781e4c23f1cfb0ca7c5b7336.tar.gz openlmi-providers-c15f9ee5a0e25a91781e4c23f1cfb0ca7c5b7336.tar.xz openlmi-providers-c15f9ee5a0e25a91781e4c23f1cfb0ca7c5b7336.zip |
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.
Diffstat (limited to 'doc')
38 files changed, 3518 insertions, 0 deletions
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 <provider>/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 <provider>/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 <providername> 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 <http://www.dmtf.org/sites/default/files/standards/documents/DSP1034_1.0.1.pdf>`_, +version 1.0.1. + +Profile adjustment +------------------ +The settings classes are not implemented. Necessary settings are done directly +in methods of :ref:`LMI_AccountManagementService <LMI-AccountManagementService>`. +:ref:`LMI_AccountManagementService <LMI-AccountManagementService>` is +subclass of :ref:`CIM_SecurityService <CIM-SecurityService>`, because +there is a change in method parameters as follows: + +* :ref:`CreateAccount <LMI-AccountManagementService-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 <LMI-AccountCapabilities>` + +* :ref:`LMI_AccountInstanceCreationIndication <LMI-AccountInstanceCreationIndication>` + +* :ref:`LMI_AccountInstanceDeletionIndication <LMI-AccountInstanceDeletionIndication>` + +* :ref:`LMI_AccountManagementCapabilities <LMI-AccountManagementCapabilities>` + +* :ref:`LMI_AccountManagementServiceCapabilities <LMI-AccountManagementServiceCapabilities>` + +* :ref:`LMI_AccountManagementService <LMI-AccountManagementService>` + +* :ref:`LMI_AccountManagementServiceSettingData <LMI-AccountManagementServiceSettingData>` + +* :ref:`LMI_AccountOnSystem <LMI-AccountOnSystem>` + +* :ref:`LMI_Account <LMI-Account>` + +* :ref:`LMI_AccountSettingData <LMI-AccountSettingData>` + +* :ref:`LMI_AssignedAccountIdentity <LMI-AssignedAccountIdentity>` + +* :ref:`LMI_AssignedGroupIdentity <LMI-AssignedGroupIdentity>` + +* :ref:`LMI_EnabledAccountCapabilities <LMI-EnabledAccountCapabilities>` + +* :ref:`LMI_Group <LMI-Group>` + +* :ref:`LMI_HostedAccountManagementService <LMI-HostedAccountManagementService>` + +* :ref:`LMI_Identity <LMI-Identity>` + +* :ref:`LMI_MemberOfGroup <LMI-MemberOfGroup>` + +* :ref:`LMI_OwningGroup <LMI-OwningGroup>` + +* :ref:`LMI_ServiceAffectsIdentity <LMI-ServiceAffectsIdentity>` + +* :ref:`LMI_SettingsDefineAccountCapabilities <LMI-SettingsDefineAccountCapabilities>` + +* :ref:`LMI_SettingsDefineManagementCapabilities <LMI-SettingsDefineManagementCapabilities>` + +Methods +^^^^^^^ +Implemented: + +* :ref:`CreateAccount <LMI-AccountManagementService-CreateAccount>` + +Additional methods: + +* :ref:`CreateGroup <LMI-AccountManagementService-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 <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 <LMI-AccountManagementService>` + +* :ref:`LMI_Account <LMI-Account>` + +* :ref:`LMI_Group <LMI-Group>` + +* :ref:`LMI_MemberOfGroup <LMI-MemberOfGroup>` + +* :ref:`LMI_Identity <LMI-Identity>` + +* :ref:`LMI_AccountInstanceCreationIndication <LMI-AccountInstanceCreationIndication>` + +* :ref:`LMI_AccountInstanceDeletionIndication <LMI-AccountInstanceDeletionIndication>` + +Some common use cases are described in the following parts + +List users +---------- +List of users are provided by :ref:`LMI_Account <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 <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 <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 <LMI-Identity>` is class representing users and groups +on the system. Group membership is represented +by :ref:`LMI_MemberOfGroup <LMI-MemberOfGroup>` association. It associates +:ref:`LMI_Group <LMI-Group>` and :ref:`LMI_Identity <LMI-Identity>`, where +:ref:`LMI_Identity <LMI-Identity>` is associated +by :ref:`LMI_AssignedAccountIdentity <LMI-AssignedAccountIdentity>` with +:ref:`LMI_Account <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 <LMI-AccountManagementService>`. There is +:ref:`CreateAccount <LMI-AccountManagementService-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 <LMI-AccountManagementService>`, using +:ref:`CreateGroup <LMI-AccountManagementService-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 <LMI-Account-DeleteUser>` +method on the desired :ref:`LMI_Account <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 <LMI-Group-DeleteGroup>` +method on the desired :ref:`LMI_Group <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 <LMI-MemberOfGroup>` class, which requires reference +to :ref:`LMI_Group <LMI-Group>` and :ref:`LMI_Identity <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 <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 <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 <LMI-AccountInstanceCreationIndication>` + +* :ref:`LMI_AccountInstanceDeletionIndication <LMI-AccountInstanceDeletionIndication>` + +Both indications works only on the following classes: + +* :ref:`LMI_Account <LMI-Account>` + +* :ref:`LMI_Group <LMI-Group>` + +* :ref:`LMI_Identity <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 <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 +# "<project> v<release> 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 <link> 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<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<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<LMI-Fan>` to ``CIM_ComputerSystem``. + + ``CIM_EnabledLogicalElementCapacilities`` + Represents the capabilities of associated fan. It's associated + to :ref:`LMI_Fan<LMI-Fan>` through ``CIM_ElementCapabilities``. + +Not implemented optional features +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +*Physical Asset* association from :ref:`LMI_Fan<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<LMI-Fan>` | :ref:`CIM_Fan<CIM-Fan>` | Plain | + +---------------------------------------------------------+---------------------------------------------------+------------------+ + | :ref:`LMI_FanSensor<LMI-FanSensor>` | :ref:`CIM_NumericSensor<CIM-NumericSensor>` | Plain | + +---------------------------------------------------------+---------------------------------------------------+------------------+ + | :ref:`LMI_FanAssociatedSensor<LMI-FanAssociatedSensor>` | :ref:`CIM_AssociatedSensor<CIM-AssociatedSensor>` | Association | + +---------------------------------------------------------+---------------------------------------------------+------------------+ + +LMI_Fan +^^^^^^^ +Represents the the fan installed and connected to computer. +One of the most important keys is :ref:`DeviceID<LMI-Fan-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<CIM-LogicalDevice-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<CIM-LogicalDevice-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<LMI-Fan>` + +Getting fan's speed +~~~~~~~~~~~~~~~~~~~ +Current value can be read from :ref:`CurrentReading<CIM-NumericSensor-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<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 <http://www.dmtf.org/sites/default/files/standards/documents/DSP1052_1.0.2.pdf>`_, +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 <http://www.dmtf.org/sites/default/files/standards/documents/DSP1022_1.0.1.pdf>`_, +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 <LMI-Processor>` + +* :ref:`LMI_ProcessorCapabilities <LMI-ProcessorCapabilities>` + +* :ref:`LMI_ProcessorElementCapabilities <LMI-ProcessorElementCapabilities>` + +* :ref:`LMI_ProcessorCacheMemory <LMI-ProcessorCacheMemory>` + +* :ref:`LMI_AssociatedProcessorCacheMemory <LMI-AssociatedProcessorCacheMemory>` + +* :ref:`LMI_ProcessorChip <LMI-ProcessorChip>` + +* :ref:`LMI_ProcessorChipRealizes <LMI-ProcessorChipRealizes>` + +* :ref:`LMI_ProcessorChipContainer <LMI-ProcessorChipContainer>` + +* :ref:`LMI_ProcessorSystemDevice <LMI-ProcessorSystemDevice>` + +System Memory Profile +--------------------- +`System Memory DMTF Profile <http://www.dmtf.org/sites/default/files/standards/documents/DSP1026_1.0.1.pdf>`_, +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 <LMI-Memory>` + +* :ref:`LMI_MemoryPhysicalPackage <LMI-MemoryPhysicalPackage>` + +* :ref:`LMI_PhysicalMemory <LMI-PhysicalMemory>` + +* :ref:`LMI_PhysicalMemoryRealizes <LMI-PhysicalMemoryRealizes>` + +* :ref:`LMI_PhysicalMemoryContainer <LMI-PhysicalMemoryContainer>` + +* :ref:`LMI_MemorySlot <LMI-MemorySlot>` + +* :ref:`LMI_MemorySlotContainer <LMI-MemorySlotContainer>` + +* :ref:`LMI_MemoryPhysicalPackageInConnector <LMI-MemoryPhysicalPackageInConnector>` + +* :ref:`LMI_MemorySystemDevice <LMI-MemorySystemDevice>` + +Physical Asset Profile +---------------------- +`Physical Asset DMTF Profile <http://www.dmtf.org/sites/default/files/standards/documents/DSP1011_1.0.2.pdf>`_, +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 <LMI-Chassis>` + +* :ref:`LMI_Baseboard <LMI-Baseboard>` + +* :ref:`LMI_BaseboardContainer <LMI-BaseboardContainer>` + +* :ref:`LMI_PointingDevice <LMI-PointingDevice>` + +* :ref:`LMI_PortPhysicalConnector <LMI-PortPhysicalConnector>` + +* :ref:`LMI_PortPhysicalConnectorContainer <LMI-PortPhysicalConnectorContainer>` + +* :ref:`LMI_SystemSlot <LMI-SystemSlot>` + +* :ref:`LMI_SystemSlotContainer <LMI-SystemSlotContainer>` + +* :ref:`LMI_ChassisComputerSystemPackage <LMI-ChassisComputerSystemPackage>` + +Battery Profile +--------------- +`Battery DMTF Profile <http://www.dmtf.org/sites/default/files/standards/documents/DSP1030_1.0.0.pdf>`_, +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 <LMI-Battery>` + +* :ref:`LMI_BatteryPhysicalPackage <LMI-BatteryPhysicalPackage>` + +* :ref:`LMI_PhysicalBatteryContainer <LMI-PhysicalBatteryContainer>` + +* :ref:`LMI_PhysicalBatteryRealizes <LMI-PhysicalBatteryRealizes>` + +* :ref:`LMI_BatterySystemDevice <LMI-BatterySystemDevice>` + +PCI Device Profile +------------------ +`PCI Device DMTF Profile <http://www.dmtf.org/sites/default/files/standards/documents/DSP1075_1.0.0.pdf>`_, +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 <LMI-PCIDevice>` + +* :ref:`LMI_PCIDeviceSystemDevice <LMI-PCIDeviceSystemDevice>` + +* :ref:`LMI_PCIBridge <LMI-PCIBridge>` + +* :ref:`LMI_PCIBridgeSystemDevice <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 <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 <http://freedesktop.org/wiki/Software/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" <http://www.dmtf.org/sites/default/files/standards/documents/DSP1010_2.0.0.pdf>`_ +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<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<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<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 +<http://www.freedesktop.org/software/systemd/man/systemd-journald.service.html>`_ +manual for how to enable the journald service. + + +Listing a log +------------- + +This example shows simple enumeration through available :ref:`LMI_JournalLogRecord<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<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()<LMI-JournalLogRecord>` +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 <http://dmtf.org/standards/cim/schemas>`_ (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 <CIM-LogicalFile>` subclasses: + +* :ref:`LMI_FIFOPipeFile <LMI-FIFOPipeFile>` +* :ref:`LMI_UnixDeviceFile <LMI-UnixDeviceFile>` +* :ref:`LMI_UnixDirectory <LMI-UnixDirectory>` +* :ref:`LMI_UnixSocket <LMI-UnixSocket>` +* :ref:`LMI_DataFile <LMI-DataFile>` +* :ref:`LMI_SymbolicLink <LMI-SymbolicLink>` + +Subclasses derived from :ref:`CIM_LogicalFile <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 +<LMI-SymbolicLink>` represents symbolic link files, :ref:`LMI_UnixDeviceFile +<LMI-UnixDeviceFile>` represents unix device files, etc. + +The other type of class is :ref:`LMI_UnixFile <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 <LMI-RootDirectory>` +* :ref:`LMI_FileIdentity <LMI-FileIdentity>` +* :ref:`LMI_DirectoryContainsFile <LMI-DirectoryContainsFile>` + +:ref:`LMI_RootDirectory <LMI-RootDirectory>` is used to connect the computer +system to its root directory. + +:ref:`LMI_FileIdentity <LMI-FileIdentity>` associates the system-independent +:ref:`CIM_LogicalFile <CIM-LogicalFile>` subclasses to their respective +:ref:`LMI_UnixFile <LMI-UnixFile>` equivalents that are dependent on the +system. + +:ref:`LMI_DirectoryContainsFile <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 <CIM-LogicalFile-CSCreationClassName>` +* :ref:`CSName <CIM-LogicalFile-CSName>` +* :ref:`FSCreationClassName <CIM-LogicalFile-FSCreationClassName>` +* :ref:`FSName <CIM-LogicalFile-FSName>` +* :ref:`CreationClassName <CIM-LogicalFile-CreationClassName>` + (:ref:`LFCreationClassName <CIM-UnixFile-LFCreationClassName>` for + :ref:`LMI_UnixFile <LMI-UnixFile>`) +* :ref:`Name <CIM-LogicalFile-Name>` (:ref:`LFName <CIM-UnixFile-LFName>` for + :ref:`LMI_UnixFile <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 +<CIM-LogicalFile-CSCreationClassName>`, :ref:`CSName <CIM-LogicalFile-CSName>` +and :ref:`Name <CIM-LogicalFile-Name>` (of :ref:`LFName <CIM-UnixFile-LFName>` +in case of :ref:`LMI_UnixFile <LMI-UnixFile>`). :ref:`FSName +<CIM-UnixFile-FSName>`, :ref:`FSCreationClassName +<CIM-LogicalFile-FSCreationClassName>` and :ref:`CreationClassName +<CIM-LogicalFile-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 <LMI-RootDirectory>`. + +:ref:`LMI_UnixFile <LMI-UnixFile>` has been extended to hold additional +properties. Currently, those are :ref:`SELinuxCurrentContext +<LMI-UnixFile-SELinuxCurrentContext>` and :ref:`SELinuxExpectedContext +<LMI-UnixFile-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 <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 + <https://github.com/openlmi/openlmi-scripts/tree/master/commands/logicalfile/lmi/scripts/logicalfile>`_. 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 <LMI-PowerManagementService>`. +This class has method +:ref:`RequestPowerStateChange <LMI-PowerManagementService-RequestPowerStateChange>` +that can be used for changing between power states. + +For list of available power states, see property +:ref:`PowerStatesSupported <LMI-PowerManagementCapabilities-PowerStatesSupported>` +of the class +:ref:`LMI_PowerManagementCapabilities <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 <http://dmtf.org>`_ standard: + +* `DSP1027 - Power State Management Profile <http://dmtf.org/sites/default/files/standards/documents/DSP1027_2.0.0.pdf>`_ + +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 <concepts>` +and then look at :ref:`usage of OpenLMI Power Management <usage>`. 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 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="268pt" style="width:480px;height:268px;" version="1.1" viewBox="0 0 480 268" width="480pt"><defs><filter height="300%" id="f1" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4" dy="4" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#FEFECE" filter="url(#f1)" height="31.6406" style="stroke: #A80036; stroke-width: 1.5;" width="122" x="131" y="8"/><text fill="#000000" font-family="Courier" font-size="10" lengthAdjust="spacingAndGlyphs" textLength="108" x="138" y="20">CIM_ComputerSystem</text><line style="stroke: #A80036; stroke-width: 1.5;" x1="132" x2="252" y1="23.6406" y2="23.6406"/><rect fill="#FEFECE" filter="url(#f1)" height="35.2813" style="stroke: #A80036; stroke-width: 1.5;" width="170" x="107" y="114.5"/><text fill="#000000" font-family="Courier" font-size="10" lengthAdjust="spacingAndGlyphs" textLength="156" x="114" y="126.5">LMI_PowerManagementService</text><line style="stroke: #A80036; stroke-width: 1.5;" x1="108" x2="276" y1="130.1406" y2="130.1406"/><text fill="#000000" font-family="Courier" font-size="10" lengthAdjust="spacingAndGlyphs" textLength="150" x="113" y="144.1406">RequestPowerStateChange()</text><rect fill="#FEFECE" filter="url(#f1)" height="35.2813" style="stroke: #A80036; stroke-width: 1.5;" width="372" x="6" y="224.5"/><text fill="#000000" font-family="Courier" font-size="10" lengthAdjust="spacingAndGlyphs" textLength="186" x="99" y="236.5">LMI_PowerManagementCapabilities</text><line style="stroke: #A80036; stroke-width: 1.5;" x1="7" x2="377" y1="240.1406" y2="240.1406"/><text fill="#000000" font-family="Courier" font-size="10" lengthAdjust="spacingAndGlyphs" textLength="360" x="12" y="254.1406">PowerStatesSupportedValues = [OffSoftGraceful, OffSoft, ...]</text><path d="M130.726,30.309 C104.4864,35.976 76.2035,47.357 60,70 C42.0764,95.047 71.215,110.075 106.63,118.945 " fill="none" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="Courier" font-size="10" lengthAdjust="spacingAndGlyphs" textLength="216" x="61" y="81">LMI_AssociatedPowerManagementService</text><path d="M251.059,114.435 C275.313,104.368 295.192,89.631 283,70 C274.538,56.375 260.593,46.751 246.133,40.004 " fill="none" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="Courier" font-size="10" lengthAdjust="spacingAndGlyphs" textLength="192" x="287" y="81">LMI_HostedPowerManagementService</text><path d="M192,149.875 C192,170.1646 192,204.0069 192,224.2435 " fill="none" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="Courier" font-size="10" lengthAdjust="spacingAndGlyphs" textLength="138" x="193" y="191">LMI_ElementCapabilities</text></g></svg>
\ 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<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()<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()<LMI-RealmdService-LeaveDomain>` can be used +to leave the joined domain. It requires the same arguments as the +:ref:`JoinDomain()<LMI-RealmdService-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<CIM-SoftwareIdentity-MajorVersion>` + * ``uint16`` :ref:`MinorVersion<CIM-SoftwareIdentity-MinorVersion>` + * ``uint16`` :ref:`RevisionNumber<CIM-SoftwareIdentity-RevisionNumber>` + * ``uint16`` :ref:`BuildNumber<CIM-SoftwareIdentity-BuildNumber>` + +And also a :ref:`VersionString<LMI-SoftwareIdentity-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<LMI-SoftwareIdentity-Epoch>` + * ``string`` :ref:`Version<LMI-SoftwareIdentity-Version>` + * ``string`` :ref:`Release<LMI-SoftwareIdentity-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: :: + + <Epoch>:<Version>-<Release>.<Architecture> + +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<LMI-SoftwareInstallationService-FindIdentity>`. + +.. _identifying_software_identity: + +Identifying software identity +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +:ref:`InstanceID<LMI-SoftwareIdentity-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:<Name>-<Epoch>:<Version>-<Release>.<Architecture> + +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 ``"<Epoch>:"`` 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<LMI-SoftwareIdentity>` | :ref:`CIM_SoftwareIdentity<CIM-SoftwareIdentity>` | Plain | + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + | :ref:`LMI_SystemSoftwareCollection<LMI-SystemSoftwareCollection>` | :ref:`CIM_SystemSpecificCollection<CIM-SystemSpecificCollection>` | Plain | + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + | :ref:`LMI_SoftwareIdentityResource<LMI-SoftwareIdentityResource>` | :ref:`CIM_SoftwareIdentityResource<CIM-SoftwareIdentityResource>` | Plain | + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + | :ref:`LMI_HostedSoftwareCollection<LMI-HostedSoftwareCollection>` | :ref:`CIM_HostedCollection<CIM-HostedCollection>` | Association | + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + | :ref:`LMI_InstalledSoftwareIdentity<LMI-InstalledSoftwareIdentity>` | :ref:`CIM_InstalledSoftwareIdentity<CIM-InstalledSoftwareIdentity>` | Association | + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + | :ref:`LMI_HostedSoftwareIdentityResource<LMI-HostedSoftwareIdentityResource>` | :ref:`CIM_HostedAccessPoint<CIM-HostedAccessPoint>` | Association | + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + | :ref:`LMI_ResourceForSoftwareIdentity<LMI-ResourceForSoftwareIdentity>` | :ref:`CIM_SAPAvailableForElement<CIM-SAPAvailableForElement>` | Association | + +-------------------------------------------------------------------------------+---------------------------------------------------------------------+------------------+ + | :ref:`LMI_MemberOfSoftwareCollection<LMI-MemberOfSoftwareCollection>` | :ref:`CIM_MemberOfCollection<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<LMI-SoftwareIdentityResource>` and + are associated to :ref:`LMI_SoftwareIdentity<LMI-SoftwareIdentity>` + via + :ref:`LMI_ResourceForSoftwareIdentity<LMI-ResourceForSoftwareIdentity>`. + +Not implemented features +~~~~~~~~~~~~~~~~~~~~~~~~ +Following methods are not implemented: + + * :ref:`CIM_SoftwareInstallationService.InstallFromByteStream<CIM-SoftwareInstallationService-InstallFromByteStream>` + * :ref:`LMI_SoftwareInstallationService.CheckSoftwareIdentity<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<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<LMI-SoftwareIdentityChecks>` + Associates *Software Identity File Check* to corresponding + *Software Identity*. + +Following methods have been added: + + :ref:`LMI_SoftwareInstallationService.VerifyInstalledIdentity<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()<LMI-SoftwareInstallationService-FindIdentity>` has been +added to +:ref:`LMI_SoftwareInstallationService<LMI-SoftwareInstallationService>` +allowing to create complex queries on package database. + +Class overview +~~~~~~~~~~~~~~ + + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | Class-name | Parent_class | Type | + +=====================================================================================================+=========================================================================+====================+ + | :ref:`LMI_SoftwareInstallationService<LMI-SoftwareInstallationService>` | :ref:`CIM_SoftwareInstallationService<CIM-SoftwareInstallationService>` | Plain | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_SoftwareJob<LMI-SoftwareJob>` | :ref:`LMI_ConcreteJob<LMI-ConcreteJob>` | Plain | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_SoftwareInstallationJob<LMI-SoftwareInstallationJob>` | :ref:`LMI_SoftwareJob<LMI-SoftwareJob>` | Plain | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_SoftwareVerificationJob<LMI-SoftwareVerificationJob>` | :ref:`LMI_SoftwareJob<LMI-SoftwareJob>` | Association | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_SoftwareMethodResult<LMI-SoftwareMethodResult>` | :ref:`LMI_MethodResult<LMI-MethodResult>` | Association | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_SoftwareIdentityFileCheck<LMI-SoftwareIdentityFileCheck>` | :ref:`CIM_FileSpecification<CIM-FileSpecification>` | Association | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_SoftwareInstallationServiceAffectsElement<LMI-SoftwareInstallationServiceAffectsElement>` | :ref:`CIM_ServiceAffectsElement<CIM-ServiceAffectsElement>` | Association | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_SoftwareIdentityChecks<LMI-SoftwareIdentityChecks>` | | Aggregation | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_HostedSoftwareInstallationService<LMI-HostedSoftwareInstallationService>` | :ref:`CIM_HostedService<CIM-HostedService>` | Plain | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_AffectedSoftwareJobElement<LMI-AffectedSoftwareJobElement>` | :ref:`CIM_AffectedJobElement<CIM-AffectedJobElement>` | Plain | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_OwningSoftwareJobElement<LMI-OwningSoftwareJobElement>` | :ref:`LMI_OwningJobElement<LMI-OwningJobElement>` | Plain | + +-----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------+--------------------+ + | :ref:`LMI_AssociatedSoftwareJobMethodResult<LMI-AssociatedSoftwareJobMethodResult>` | :ref:`LMI_AssociatedJobMethodResult<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<dmtf_profiles>`. 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<LMI-SoftwareIdentity>` + Is represented by ``LMI_SoftwareIdentity``. It's identified by a single + key property called + :ref:`LMI_SoftwareIdentity.InstanceID<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<LMI-SoftwareIdentityResource>` + Is represented by ``LMI_SoftwareIdentityResource``. What distinguishes + particular repository from others on the same system is a + :ref:`LMI_SoftwareIdentityResource.Name<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<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<LMI-SoftwareIdentityFileCheck-UserID>` vs + :ref:`UserIDOriginal<LMI-SoftwareIdentityFileCheck-UserIDOriginal>` + * :ref:`FileChecksum<LMI-SoftwareIdentityFileCheck-FileChecksum>` vs + :ref:`FileChecksumOriginal<LMI-SoftwareIdentityFileCheck-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()<LMI-SoftwareIdentityFileCheck-Invoke>` + method on particular object path or by testing the + :ref:`FailedFlags<LMI-SoftwareIdentityFileCheck-FailedFlags>` property for + emptiness. If its empty, the file or directory passed the verification test. + +*RPM* database : :ref:`LMI_SystemSoftwareCollection<LMI-SystemSoftwareCollection>` + Is represented by ``LMI_SystemSoftwareCollection``. Administrator probably + won't be interested in this class. The + :ref:`LMI_MemberOfSoftwareCollection<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<LMI-SoftwareIdentity>` (see the + explanation in :ref:`package_searching`). + +*YUM* package manager : :ref:`LMI_SoftwareInstallationService<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()<LMI-SoftwareInstallationService-FindIdentity>` + Allows to query the database for matching packages. + + :ref:`InstallFromSoftwareIdentity()<LMI-SoftwareInstallationService-InstallFromSoftwareIdentity>` + Allows to install, update or remove *RPM* package represented by an + instance of *Software Identity*. + + :ref:`InstallFromURI()<LMI-SoftwareInstallationService-InstallFromURI>` + Allows to install or update *RPM* package located with particular + URI string. + + :ref:`VerifyInstalledIdentity()<LMI-SoftwareInstallationService-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 Binary files differnew file mode 100644 index 0000000..35638d3 --- /dev/null +++ b/doc/admin/software/pic/software-profile.dia 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 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd"> +<svg width="65cm" height="57cm" viewBox="46 600 1299 1127" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <g> + <rect style="fill: #ade5ff" x="667.338" y="833.972" width="210.2" height="28"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="667.338" y="833.972" width="210.2" height="28"/> + <text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="772.438" y="852.972">SoftwareIdentity</text> + <rect style="fill: #ade5ff" x="667.338" y="861.972" width="210.2" height="228"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="667.338" y="861.972" width="210.2" height="228"/> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="670.338" y="875.972">+* InstanceID: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="670.338" y="891.972">+Caption: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="670.338" y="907.972">+Classifications: uint16[]</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="670.338" y="923.972">+Description: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="670.338" y="939.972">+ElementName: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="670.338" y="955.972">+InstallDate: datetime</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="670.338" y="971.972">+IsEntity: boolean</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="670.338" y="987.972">+Name: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="670.338" y="1003.97">+TargetTypes: string[]</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="670.338" y="1019.97">+VersionString: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="670.338" y="1035.97">+Epoch: uint32</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="670.338" y="1051.97">+Version: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="670.338" y="1067.97">+Release: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="670.338" y="1083.97">+Architecture: string</text> + </g> + <g> + <rect style="fill: #ade5ff" x="973.838" y="995.604" width="279.5" height="28"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="973.838" y="995.604" width="279.5" height="28"/> + <text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="1113.59" y="1014.6">SoftwareIdentityResource</text> + <rect style="fill: #ade5ff" x="973.838" y="1023.6" width="279.5" height="484"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="973.838" y="1023.6" width="279.5" height="484"/> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1037.6">+* CreationClassName: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1053.6">+* Name: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1069.6">+* SystemCreationClassName: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1085.6">+* SystemName: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1101.6">+AccessContext: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1117.6">+AccessInfo: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1133.6">+AvailableRequestedStates: uint16[]</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1149.6">+Caption: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1165.6">+Cost: sint32</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1181.6">+Description: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1197.6">+ElementName: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1213.6">+EnabledDefault: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1229.6">+EnabledState: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1245.6">+ExtendedResourceType: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1261.6">+Generation: uint64</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1277.6">+HealthState: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1293.6">+GPGCheck: boolean</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1309.6">+InfoFormat: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1325.6">+InstanceID: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1341.6">+MirrorList: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1357.6">+OperationalStatus: uint16[]</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1373.6">+OtherAccessContext: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1389.6">+PrimaryStatus: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1405.6">+RepoGPGCheck: boolean</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1421.6">+RequestedState: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1437.6">+ResourceType: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1453.6">+StatusDescriptions: string[]</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1469.6">+TimeOfLastStateChange: datetime</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1485.6">+TimeOfLastUpdate: datetime</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1501.6">+TransitioningToState: uin16</text> + <rect style="fill: #ade5ff" x="973.838" y="1507.6" width="279.5" height="20"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="973.838" y="1507.6" width="279.5" height="20"/> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="976.838" y="1521.6">+RequestStateChange(): uint32</text> + </g> + <g> + <rect style="fill: #ade5ff" x="989.738" y="661.988" width="247.7" height="28"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="989.738" y="661.988" width="247.7" height="28"/> + <text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="1113.59" y="680.988">SystemSoftwareCollection</text> + <rect style="fill: #ade5ff" x="989.738" y="689.988" width="247.7" height="36"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="989.738" y="689.988" width="247.7" height="36"/> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="992.738" y="703.988">+* InstanceID: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="992.738" y="719.988">+Caption: string</text> + </g> + <g> + <rect style="fill: #ffffff" x="246.578" y="657.988" width="225.6" height="28"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="246.578" y="657.988" width="225.6" height="28"/> + <text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="359.378" y="676.988">CIM_ComputerSystem</text> + <rect style="fill: #ffffff" x="246.578" y="685.988" width="225.6" height="36"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="246.578" y="685.988" width="225.6" height="36"/> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="249.578" y="699.988">+* CreationClassName: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="249.578" y="715.988">+* Name: string</text> + <rect style="fill: #ffffff" x="246.578" y="721.988" width="225.6" height="8"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="246.578" y="721.988" width="225.6" height="8"/> + </g> + <g> + <polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" points="359.378,729.988 359.378,818.898 522.536,818.898 522.536,903.972 667.338,903.972 "/> + <text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="440.957" y="815.898">InstalledSoftwareIdentity</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="363.378" y="741.988"> System</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="363.378" y="757.988">*</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="663.338" y="900.972"> InstalledSoftware</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="663.338" y="916.972">*</text> + </g> + <g> + <rect style="fill: #ffffbd" x="208.078" y="1075.6" width="302.6" height="28"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="208.078" y="1075.6" width="302.6" height="28"/> + <text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="359.378" y="1094.6">SoftwareInstallationService</text> + <rect style="fill: #ffffbd" x="208.078" y="1103.6" width="302.6" height="276"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="208.078" y="1103.6" width="302.6" height="276"/> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1117.6">+* CreationClassName: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1133.6">+* Name: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1149.6">+* SystemCreationClassName: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1165.6">+* SystemName: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1181.6">+Caption: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1197.6">+CommunicationStatus: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1213.6">+Description: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1229.6">+DetailedStatus: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1245.6">+EnabledDefault: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1261.6">+HealthState: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1277.6">+InstanceID: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1293.6">+OperatingStatus: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1309.6">+OperationalStatus: uint16[]</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1325.6">+PrimaryStatus: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1341.6">+RequestedState: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1357.6">+Started: boolean</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1373.6">+TransitioningToState: uint16</text> + <rect style="fill: #ffffbd" x="208.078" y="1379.6" width="302.6" height="68"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="208.078" y="1379.6" width="302.6" height="68"/> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1393.6">+CheckSoftwareIdentity(): uint32</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1409.6">+InstallFromSoftwareIdentity(): uint32</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1425.6">+InstallFromURI(): uint32</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="211.078" y="1441.6">+VerifyInstalledIdentity(): uint32</text> + </g> + <g> + <polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" points="473.185,693.988 474.185,693.988 987.73,693.988 988.73,693.988 "/> + <text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="730.958" y="690.988">HostedSoftwareCollection</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="477.185" y="690.988"> Antecedent</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="477.185" y="706.988">1</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="984.73" y="690.988"> Dependent</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="984.73" y="706.988">0..1</text> + </g> + <g> + <polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" points="246.578,711.988 110.142,711.988 110.142,1145.6 208.078,1145.6 "/> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="112.142" y="925.796">HostedSoftwareInstallationService</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="242.578" y="708.988"> Antecedent</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="242.578" y="724.988">1</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="204.078" y="1142.6"> Dependent</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="204.078" y="1158.6">*</text> + </g> + <g> + <polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" points="246.578,671.988 47.8936,671.988 47.8936,1261.6 207.086,1261.6 "/> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="49.8936" y="963.796">SoftwareInstallationServiceAffectsElement</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="242.578" y="668.988"> AffectedElement</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="242.578" y="684.988">1..*</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="203.086" y="1258.6"> AffectingElement</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="203.086" y="1274.6">*</text> + </g> + <g> + <polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" points="877.538,847.972 877.538,847.972 1110.78,847.972 1110.78,847.972 1113.59,847.972 1113.59,995.604 "/> + <text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="1110.78" y="844.972">ResourceForSoftwareIdentity</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="881.538" y="844.972"> ManagedElement</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="881.538" y="860.972">1</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="1117.59" y="975.604"> AvailableSAP</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="1117.59" y="991.604">0..1</text> + </g> + <g> + <polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" points="359.378,657.988 359.378,615.242 1344.25,615.242 1344.25,1261.6 1254.33,1261.6 "/> + <text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="851.813" y="612.242">HostedSoftwareIdentityResource</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="363.378" y="637.988"> Antecedent</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="363.378" y="653.988">1</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="1258.33" y="1258.6"> Dependent</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="1258.33" y="1274.6">*</text> + </g> + <g> + <polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #00ff00" points="772.438,832.964 772.438,786.98 1113.59,786.98 1113.59,752.168 "/> + <polygon style="fill: #ffffff" points="1113.59,726.996 1118.39,740.996 1113.59,754.996 1108.79,740.996 "/> + <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #00ff00" points="1113.59,726.996 1118.39,740.996 1113.59,754.996 1108.79,740.996 "/> + <text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="943.013" y="783.98">MemberOfSoftwareCollection</text> + <polygon style="fill: #00ff00" points="838.913,783.98 838.913,775.98 830.913,779.98 "/> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="776.438" y="812.964"> Member</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="776.438" y="828.964">*</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="1124.59" y="738.996"> Collection</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="1124.59" y="754.996">*</text> + </g> + <g> + <rect style="fill: #ffffbd" x="216.654" y="1598.02" width="285.45" height="28"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="216.654" y="1598.02" width="285.45" height="28"/> + <text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="359.379" y="1617.02">InstallationServiceCapabilities</text> + <rect style="fill: #ffffbd" x="216.654" y="1626.02" width="285.45" height="100"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="216.654" y="1626.02" width="285.45" height="100"/> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="219.654" y="1640.02">+* InstanceID: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="219.654" y="1656.02">+CanAddToCollection: boolean</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="219.654" y="1672.02">+SupportedTargetTypes: string[]</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="219.654" y="1688.02">+SupportedInstallOptions: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="219.654" y="1704.02">+Description: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="219.654" y="1720.02">+SupportedURISchemes</text> + </g> + <g> + <polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" points="208.078,1389.6 76.875,1389.6 76.875,1668.02 216.654,1668.02 "/> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="78.875" y="1525.81">AssociatedSoftwareInstallationServiceCapabilities</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="204.078" y="1386.6"> ManagedElement</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="204.078" y="1402.6">1..*</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="212.654" y="1665.02"> Capabilities</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="212.654" y="1681.02">1</text> + </g> + <g> + <polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" points="667.338,967.972 667.338,967.972 311.152,967.972 311.152,1043.85 359.378,1043.85 359.378,1075.6 "/> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="313.152" y="1002.91">SoftwareInstallationServiceAffectsElement</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="663.338" y="964.972"> AffectedElement</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="663.338" y="980.972">*</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="363.378" y="1055.6"> AffectingElement</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="363.378" y="1071.6">*</text> + </g> + <g> + <rect style="fill: #ffbfb3" x="624.988" y="1178.02" width="294.9" height="28"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="624.988" y="1178.02" width="294.9" height="28"/> + <text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="772.438" y="1197.02">SoftwareIdentityFileCheck</text> + <rect style="fill: #ffbfb3" x="624.988" y="1206.02" width="294.9" height="484"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="624.988" y="1206.02" width="294.9" height="484"/> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1220.02">+* Name: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1236.02">+* CheckID: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1252.02">+* SoftwareElementID: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1268.02">+* SoftwareElementState: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1284.02">+* TargetOperatingSystem: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1300.02">+* Version: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1316.02">+CheckMode: boolean</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1332.02">+ChecksumType: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1348.02">+FailedFlags: uint16[]</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1364.02">+FileChecksum: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1380.02">+FileChecksumOriginal: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1396.02">+FileExists: boolean</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1412.02">+FileMode: uint32</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1428.02">+FileModeOriginal: uint32</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1444.02">+FileModeFlags: uint8[]</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1460.02">+FileModeFlagsOriginal: uint8[]</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1476.02">+FileName: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1492.02">+FileSize: uint64</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1508.02">+FileSizeOriginal: uint64</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1524.02">+FileType: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1540.02">+FileTypeOriginal: uint16</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1556.02">+GroupID: uint32</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1572.02">+GroupIDOriginal: uint32</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1588.02">+MD5Checksum: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1604.02">+LastModificationTime: uint64</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1620.02">+LastModificationTimeOriginal: uint64</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1636.02">+LinkTarget: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1652.02">+LinkTargetOriginal: string</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1668.02">+UserID: uint32</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1684.02">+UserIDOriginal: uint32</text> + <rect style="fill: #ffbfb3" x="624.988" y="1690.02" width="294.9" height="36"/> + <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="624.988" y="1690.02" width="294.9" height="36"/> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1704.02">+Invoke(): uin32</text> + <text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="627.988" y="1720.02">+InvokeOnSystem(): uint32</text> + </g> + <g> + <polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #00ff00" points="772.438,1116.12 772.438,1141.11 772.438,1141.11 772.438,1177.05 "/> + <polygon style="fill: #ffffff" points="772.438,1090.95 777.238,1104.95 772.438,1118.95 767.638,1104.95 "/> + <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #00ff00" points="772.438,1090.95 777.238,1104.95 772.438,1118.95 767.638,1104.95 "/> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="774.438" y="1138.11">FileIdentityChecks</text> + <polygon style="fill: #00ff00" points="915.038,1138.11 915.038,1130.11 923.038,1134.11 "/> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="783.438" y="1102.95"> Element</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="783.438" y="1118.95">1</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="776.438" y="1157.05"> Check</text> + <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="776.438" y="1173.05">*</text> + </g> +</svg> 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<LMI-InstalledSoftwareIdentity>` + +Faster +~~~~~~ +This is much faster. Here we enumerate association class +:ref:`LMI_InstalledSoftwareIdentity<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-SoftwareIdentityResource>` + +``lmi`` meta-command +~~~~~~~~~~~~~~~~~~~~ +:: + + lmi -h $HOST sw list pkgs + +Listing available packages +-------------------------- +lmishell +~~~~~~~~ +Enumerating of :ref:`LMI_SoftwareIdentity<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<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-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()<LMI-SoftwareInstallationService-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-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()<LMI-SoftwareInstallationService-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<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()<LMI-SoftwareInstallationService-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<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<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()<LMI-SoftwareInstallationService-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<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()<LMI-SoftwareInstallationService-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-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<LMI-SoftwareInstallationJob>` + Represents a job requesting to install, update or remove some package. + + :ref:`LMI_SoftwareVerificationJob<LMI-SoftwareVerificationJob>` + Represents a job requesting verification of installed package. + +Filters below are written for :ref:`LMI_SoftwareInstallationJob<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<LMI-ConcreteJob-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<LMI-ConcreteJob-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<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 + + <b>N</b>ame, <b>E</b>poch, <b>V</b>ersion, <b>R</b>elease, + <b>A</b>rchitecure. + + .. 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<LMI-ConcreteJob-OperationalStatus>` array. + It corresponds to value ``Completed`` of + :ref:`JobState<LMI-ConcreteJob-JobState>` property. + +.. [3] This is a composition of values in + :ref:`OperationalStatus<LMI-ConcreteJob-OperationalStatus>` array. + It corresponds to value ``Exception`` of + :ref:`JobState<LMI-ConcreteJob-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 |