summaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorJan Safranek <jsafrane@redhat.com>2013-10-18 14:45:03 +0200
committerJan Safranek <jsafrane@redhat.com>2013-10-18 14:45:03 +0200
commitc15f9ee5a0e25a91781e4c23f1cfb0ca7c5b7336 (patch)
treedc34216411938495b489368e15e22a7e5a5d0878 /doc
parent087d51a3b03815ddbacaf62bf2fa047dbcbb9537 (diff)
downloadopenlmi-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')
-rw-r--r--doc/CMakeLists.txt1
-rw-r--r--doc/admin/CMakeLists.txt138
-rw-r--r--doc/admin/README55
-rw-r--r--doc/admin/account/dmtf-profile.rst79
-rw-r--r--doc/admin/account/index.rst30
-rw-r--r--doc/admin/account/usage.rst241
-rw-r--r--doc/admin/conf.py297
-rw-r--r--doc/admin/fan/dmtf.rst144
-rw-r--r--doc/admin/fan/index.rst27
-rw-r--r--doc/admin/fan/usage.rst48
-rw-r--r--doc/admin/hardware/dmtf-profiles.rst135
-rw-r--r--doc/admin/hardware/index.rst27
-rw-r--r--doc/admin/hardware/info.rst142
-rw-r--r--doc/admin/header.txt2
-rw-r--r--doc/admin/journald/index.rst91
-rw-r--r--doc/admin/journald/usage.rst55
-rw-r--r--doc/admin/logicalfile/index.rst27
-rw-r--r--doc/admin/logicalfile/usage.rst169
-rw-r--r--doc/admin/power/concepts.rst19
-rw-r--r--doc/admin/power/index.rst21
-rw-r--r--doc/admin/power/introduction.rst16
-rwxr-xr-xdoc/admin/power/pic/make-svg.sh10
-rw-r--r--doc/admin/power/pic/plantuml.cfg3
-rw-r--r--doc/admin/power/pic/powermanagement.svg1
-rw-r--r--doc/admin/power/pic/powermanagement.uml15
-rw-r--r--doc/admin/power/usage.rst43
-rw-r--r--doc/admin/realmd/index.rst24
-rw-r--r--doc/admin/realmd/usage.rst47
-rw-r--r--doc/admin/service-dbus/index.rst27
-rw-r--r--doc/admin/service-dbus/usage.rst46
-rw-r--r--doc/admin/software/configuration.rst155
-rw-r--r--doc/admin/software/dmtf.rst300
-rw-r--r--doc/admin/software/index.rst29
-rw-r--r--doc/admin/software/introduction.rst158
-rw-r--r--doc/admin/software/pic/Makefile16
-rw-r--r--doc/admin/software/pic/software-profile.diabin0 -> 5319 bytes
-rw-r--r--doc/admin/software/pic/software-profile.svg255
-rw-r--r--doc/admin/software/usage.rst625
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
new file mode 100644
index 0000000..35638d3
--- /dev/null
+++ b/doc/admin/software/pic/software-profile.dia
Binary files differ
diff --git a/doc/admin/software/pic/software-profile.svg b/doc/admin/software/pic/software-profile.svg
new file mode 100644
index 0000000..42c2103
--- /dev/null
+++ b/doc/admin/software/pic/software-profile.svg
@@ -0,0 +1,255 @@
+<?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