diff options
author | Michal Minar <miminar@redhat.com> | 2013-10-07 17:27:16 +0200 |
---|---|---|
committer | Michal Minar <miminar@redhat.com> | 2013-10-08 12:54:18 +0200 |
commit | 100b3e0d5747b5da7c7b07aad14506a2d7b38f39 (patch) | |
tree | acb1a0743f062127f30221645354b262776b5998 /src | |
parent | d6c05eaa4feb338305405d0ab9c7bd343544cbfb (diff) | |
download | openlmi-providers-100b3e0d5747b5da7c7b07aad14506a2d7b38f39.tar.gz openlmi-providers-100b3e0d5747b5da7c7b07aad14506a2d7b38f39.tar.xz openlmi-providers-100b3e0d5747b5da7c7b07aad14506a2d7b38f39.zip |
added admin documentation for software
Diffstat (limited to 'src')
-rw-r--r-- | src/software/doc/admin/Makefile | 159 | ||||
-rw-r--r-- | src/software/doc/admin/conf.py | 294 | ||||
-rw-r--r-- | src/software/doc/admin/dmtf.rst | 231 | ||||
-rw-r--r-- | src/software/doc/admin/index.rst | 27 | ||||
-rw-r--r-- | src/software/doc/admin/mof/Makefile | 15 | ||||
-rw-r--r-- | src/software/doc/admin/mof/header.txt | 2 | ||||
-rw-r--r-- | src/software/doc/admin/usage.rst | 617 |
7 files changed, 1345 insertions, 0 deletions
diff --git a/src/software/doc/admin/Makefile b/src/software/doc/admin/Makefile new file mode 100644 index 0000000..bad1f79 --- /dev/null +++ b/src/software/doc/admin/Makefile @@ -0,0 +1,159 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp \ + devhelp epub latex latexpdf text man changes linkcheck doctest \ + gettext mof + +help: + @echo "Please use \`make <target>' where <target> is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +mof: + make -C mof + +clean: + -rm -rf $(BUILDDIR)/* + make -C mof clean + +html: mof + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/OpenLMISoftwareProvider.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/OpenLMISoftwareProvider.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/OpenLMISoftwareProvider" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/OpenLMISoftwareProvider" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: mof + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: mof + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/src/software/doc/admin/conf.py b/src/software/doc/admin/conf.py new file mode 100644 index 0000000..16381bb --- /dev/null +++ b/src/software/doc/admin/conf.py @@ -0,0 +1,294 @@ +# -*- coding: utf-8 -*- +# +# OpenLMI Software 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. +project = u'OpenLMI Software Provider' +copyright = u'2013, Michal Minar' + +# 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. +# +# 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'Michal Minar' +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/src/software/doc/admin/dmtf.rst b/src/software/doc/admin/dmtf.rst new file mode 100644 index 0000000..d048f78 --- /dev/null +++ b/src/software/doc/admin/dmtf.rst @@ -0,0 +1,231 @@ +DMTF profiles +============= +OpenLMI Software providers implement two *DMTF* profiles: + + * `Software Inventory Profile`_ + * `Software Update 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 (not +just digits). 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 [1]_. 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. + +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 +^^^^^^^^^^^^^^^^^ +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. + +.. + *************************************************************************** +.. _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] Because internally the query is executed upon the list obtained by + enumeration of instances. diff --git a/src/software/doc/admin/index.rst b/src/software/doc/admin/index.rst new file mode 100644 index 0000000..35e57c3 --- /dev/null +++ b/src/software/doc/admin/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/src/software/doc/admin/mof/Makefile b/src/software/doc/admin/mof/Makefile new file mode 100644 index 0000000..8884274 --- /dev/null +++ b/src/software/doc/admin/mof/Makefile @@ -0,0 +1,15 @@ +src: index.rst + +TOPDIR=../../../../.. +MOFS=$(TOPDIR)/mof/60_LMI_Software.mof + +index.rst: $(MOFS) + $(TOPDIR)/tools/openlmi-doc-class2rst -H header.txt \ + -M `echo $(MOFS) | sed 's/ / -M /g'` \ + -S /usr/share/mof/cim-current/CIM_Schema.mof \ + -S $(TOPDIR)/mof/05_LMI_Qualifiers.mof \ + -S $(TOPDIR)/mof/30_LMI_Jobs.mof \ + `cat $(MOFS) | grep "^class" | cut -d ' ' -f 2 | sed 's/://'` + +clean: + rm -f *.rst diff --git a/src/software/doc/admin/mof/header.txt b/src/software/doc/admin/mof/header.txt new file mode 100644 index 0000000..cc06402 --- /dev/null +++ b/src/software/doc/admin/mof/header.txt @@ -0,0 +1,2 @@ +Class reference +=============== diff --git a/src/software/doc/admin/usage.rst b/src/software/doc/admin/usage.rst new file mode 100644 index 0000000..0f5205d --- /dev/null +++ b/src/software/doc/admin/usage.rst @@ -0,0 +1,617 @@ +*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.Linux_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 ``Linux_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 +-------------------- +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.Linux_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.Linux_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.Linux_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 +--------------- +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.Linux_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 +-------------- +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.Linux_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 +-------------------- +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.Linux_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 |