summaryrefslogtreecommitdiffstats
path: root/doc/admin/software
diff options
context:
space:
mode:
Diffstat (limited to 'doc/admin/software')
-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
8 files changed, 1538 insertions, 0 deletions
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