Browse Source

Generate Sphinx docs

Change-Id: I540b28d6173b30baf6ee2e6e14d8ba5ffb67b660
Closes-Bug: #1514803
changes/85/246985/7
Serge Kovaleff 7 years ago
parent
commit
292e8c9cfd
  1. 2
      .gitignore
  2. 540
      README.rst
  3. 159
      doc/Makefile
  4. 2
      doc/source/.gitignore
  5. 274
      doc/source/api/HTTP-API.rst
  6. 90
      doc/source/conf.py
  7. 241
      doc/source/deploy/install-guide.rst
  8. 3
      doc/source/dev/contributing_link.rst
  9. 73
      doc/source/index.rst
  10. 113
      doc/source/troubleshooting/troubleshooting.rst
  11. 187
      doc/source/usage/usage.rst
  12. 12
      releasenotes/notes/sphinx-docs-4d0a5886261e57bf.yaml
  13. 5
      setup.cfg
  14. 1
      test-requirements.txt
  15. 7
      tox.ini

2
.gitignore vendored

@ -6,7 +6,7 @@
# Sphinx
_build
doc/source/api/
#doc/source/api/
# release notes build
releasenotes/build

540
README.rst

@ -24,6 +24,9 @@ Refer to CONTRIBUTING.rst_ for instructions on how to contribute.
.. _Ironic: https://wiki.openstack.org/wiki/Ironic
.. _PyPI: https://pypi.python.org/pypi/ironic-inspector
.. _CONTRIBUTING.rst: https://github.com/openstack/ironic-inspector/blob/master/CONTRIBUTING.rst
.. _diskimage-builder: https://github.com/openstack/diskimage-builder
.. _ironic-discoverd-ramdisk element: https://github.com/openstack/diskimage-builder/tree/master/elements/ironic-discoverd-ramdisk
.. _Configuration: https://github.com/openstack/ironic-inspector/blob/master/doc/source/install-guide.rst
.. note::
**ironic-inspector** was called *ironic-discoverd* before version 2.0.0.
@ -66,7 +69,7 @@ Usual hardware introspection flow is as follows:
Power management credentials should be provided to Ironic at this step.
* Nodes are put in the correct state for introspection as described in
`Node States`_.
:ref:`node_states`.
* Operator sends nodes on introspection using **ironic-inspector** API or CLI
(see Usage_).
@ -110,543 +113,12 @@ Usual hardware introspection flow is as follows:
for a given node.
* Nodes are put in the correct state for deploying as described in
`Node States`_.
:ref:`node_states`.
Starting DHCP server and configuring PXE boot environment is not part of this
package and should be done separately.
.. _instack-undercloud: https://www.rdoproject.org/Deploying_an_RDO_Undercloud_with_Instack
.. _Ironic inspection documentation: http://docs.openstack.org/developer/ironic/deploy/install-guide.html#hardware-inspection
.. _Usage: https://github.com/openstack/ironic-inspector/blob/master/doc/source/usage.rst
Installation
------------
Install from PyPI_ (you may want to use virtualenv to isolate your
environment)::
pip install ironic-inspector
Also there is a `DevStack <http://docs.openstack.org/developer/devstack/>`_
plugin for **ironic-inspector** - see CONTRIBUTING.rst_ for the current status.
Finally, some distributions (e.g. Fedora) provide **ironic-inspector**
packaged, some of them - under its old name *ironic-discoverd*.
Configuration
~~~~~~~~~~~~~
Copy ``example.conf`` to some permanent place
(e.g. ``/etc/ironic-inspector/inspector.conf``).
Fill in at least these configuration values:
* ``os_username``, ``os_password``, ``os_tenant_name`` - Keystone credentials
to use when accessing other services and check client authentication tokens;
* ``os_auth_url``, ``identity_uri`` - Keystone endpoints for validating
authentication tokens and checking user roles;
* ``connection`` in the ``database`` section - SQLAlchemy connection string
for the database;
* ``dnsmasq_interface`` - interface on which ``dnsmasq`` (or another DHCP
service) listens for PXE boot requests (defaults to ``br-ctlplane`` which is
a sane default for TripleO-based installations but is unlikely to work for
other cases).
See comments inside `example.conf
<https://github.com/openstack/ironic-inspector/blob/master/example.conf>`_
for the other possible configuration options.
.. note::
Configuration file contains a password and thus should be owned by ``root``
and should have access rights like ``0600``.
**ironic-inspector** requires root rights for managing iptables. It gets them
by running ``ironic-inspector-rootwrap`` utility with ``sudo``.
To allow it, copy file ``rootwrap.conf`` and directory ``rootwrap.d`` to the
configuration directory (e.g. ``/etc/ironic-inspector/``) and create file
``/etc/sudoers.d/ironic-inspector-rootwrap`` with the following content::
stack ALL=(root) NOPASSWD: /usr/bin/ironic-inspector-rootwrap /etc/ironic-inspector/rootwrap.conf *
.. DANGER::
Be very careful about typos in ``/etc/sudoers.d/ironic-inspector-rootwrap``
as any typo will break sudo for **ALL** users on the system. Especially,
make sure there is a new line at the end of this file.
.. note::
``rootwrap.conf`` and all files in ``rootwrap.d`` must be writeable
only by root.
.. note::
If you store ``rootwrap.d`` in a different location, make sure to update
the *filters_path* option in ``rootwrap.conf`` to reflect the change.
If your ``rootwrap.conf`` is in a different location, then you need
to update the *rootwrap_config* option in ``ironic-inspector.conf``
to point to that location.
Replace ``stack`` with whatever user you'll be using to run
**ironic-inspector**.
Configuring PXE
^^^^^^^^^^^^^^^
As for PXE boot environment, you'll need:
* TFTP server running and accessible (see below for using *dnsmasq*).
Ensure ``pxelinux.0`` is present in the TFTP root.
* You need PXE boot server (e.g. *dnsmasq*) running on **the same** machine as
**ironic-inspector**. Don't do any firewall configuration:
**ironic-inspector** will handle it for you. In **ironic-inspector**
configuration file set ``dnsmasq_interface`` to the interface your
PXE boot server listens on. Here is an example *dnsmasq.conf*::
port=0
interface={INTERFACE}
bind-interfaces
dhcp-range={DHCP IP RANGE, e.g. 192.168.0.50,192.168.0.150}
enable-tftp
tftp-root={TFTP ROOT, e.g. /tftpboot}
dhcp-boot=pxelinux.0
* You have to install and configure one of 2 available ramdisks: simple
bash-based (see `Using simple ramdisk`_) or more complex based on
ironic-python-agent_ (See `Using IPA`_).
Here is *inspector.conf* you may end up with::
[DEFAULT]
debug = false
[ironic]
identity_uri = http://127.0.0.1:35357
os_auth_url = http://127.0.0.1:5000/v2.0
os_username = admin
os_password = password
os_tenant_name = admin
[firewall]
dnsmasq_interface = br-ctlplane
.. note::
Set ``debug = true`` if you want to see complete logs.
Using simple ramdisk
^^^^^^^^^^^^^^^^^^^^
* Build and put into your TFTP the kernel and ramdisk created using the
diskimage-builder_ `ironic-discoverd-ramdisk element`_::
ramdisk-image-create -o discovery fedora ironic-discoverd-ramdisk
You need diskimage-builder_ 0.1.38 or newer to do it (using the latest one
is always advised).
* Configure your ``$TFTPROOT/pxelinux.cfg/default`` with something like::
default introspect
label introspect
kernel discovery.kernel
append initrd=discovery.initramfs discoverd_callback_url=http://{IP}:5050/v1/continue
ipappend 3
Replace ``{IP}`` with IP of the machine (do not use loopback interface, it
will be accessed by ramdisk on a booting machine).
.. note::
There are some prebuilt images which use obsolete ``ironic_callback_url``
instead of ``discoverd_callback_url``. Modify ``pxelinux.cfg/default``
accordingly if you have one of these.
Using IPA
^^^^^^^^^
ironic-python-agent_ is a new ramdisk developed for Ironic. During the Liberty
cycle support for **ironic-inspector** was added. This is experimental
for now, but we plan on making IPA the default ramdisk in Mitaka cycle.
.. note::
You need at least 1.5 GiB of RAM on the machines to use this ramdisk.
To build an ironic-python-agent ramdisk, do the following:
* Get the latest diskimage-builder_::
sudo pip install -U "diskimage-builder>=1.1.2"
* Build the ramdisk::
disk-image-create ironic-agent fedora -o ironic-agent
.. note::
Replace "fedora" with your distribution of choice.
* Copy resulting files ``ironic-agent.vmlinuz`` and ``ironic-agent.initramfs``
to the TFTP root directory.
Next, set up ``$TFTPROOT/pxelinux.cfg/default`` as follows::
default introspect
label introspect
kernel ironic-agent.vmlinuz
append initrd=ironic-agent.initramfs ipa-inspection-callback-url=http://{IP}:5050/v1/continue systemd.journald.forward_to_console=yes
ipappend 3
Replace ``{IP}`` with IP of the machine (do not use loopback interface, it
will be accessed by ramdisk on a booting machine).
.. note::
While ``systemd.journald.forward_to_console=yes`` is not actually
required, it will substantially simplify debugging if something goes wrong.
.. _diskimage-builder: https://github.com/openstack/diskimage-builder
.. _ironic-discoverd-ramdisk element: https://github.com/openstack/diskimage-builder/tree/master/elements/ironic-discoverd-ramdisk
.. _ironic-python-agent: https://github.com/openstack/ironic-python-agent
Managing the **ironic-inspector** database
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**ironic-inspector** provides a command line client for managing its database,
this client can be used for upgrading, and downgrading the database using
alembic migrations.
If this is your first time running **ironic-inspector** to migrate the
database simply run:
::
ironic-inspector-dbsync --config-file /etc/ironic-inspector/inspector.conf upgrade
If you have previously run a version of **ironic-inspector** earlier than
2.2.0, the safest thing is to delete the existing SQLite database and run
``upgrade`` as shown above. If you, however, want to save the existing
database, to ensure your database will work with the migrations, you'll need to
run an extra step before upgrading the database. You only need to do this the
first time running version 2.2.0 or later.
If you are upgrading from **ironic-inspector** version 2.1.0 or lower:
::
ironic-inspector-dbsync --config-file /etc/ironic-inspector/inspector.conf stamp --revision 578f84f38d
ironic-inspector-dbsync --config-file /etc/ironic-inspector/inspector.conf upgrade
If you are upgrading from a git master install of **ironic-inspector** from
after `Introspection Rules`_ were introduced:
::
ironic-inspector-dbsync --config-file /etc/ironic-inspector/inspector.conf stamp --revision d588418040d
ironic-inspector-dbsync --config-file /etc/ironic-inspector/inspector.conf upgrade
Other available commands can be discovered by running::
ironic-inspector-dbsync --help
Running
~~~~~~~
::
ironic-inspector --config-file /etc/ironic-inspector/inspector.conf
A good starting point for writing your own *systemd* unit should be `one used
in Fedora <http://pkgs.fedoraproject.org/cgit/openstack-ironic-discoverd.git/plain/openstack-ironic-discoverd.service>`_
(note usage of old name).
Usage
-----
Refer to HTTP-API.rst_ for information on the HTTP API.
Refer to the `client page`_ for information on how to use CLI and Python
library.
.. _HTTP-API.rst: https://github.com/openstack/ironic-inspector/blob/master/HTTP-API.rst
.. _HTTP API: https://github.com/openstack/ironic-inspector/blob/master/HTTP-API.rst
.. _client page: https://pypi.python.org/pypi/python-ironic-inspector-client
Using from Ironic API
~~~~~~~~~~~~~~~~~~~~~
Ironic Kilo introduced support for hardware introspection under name of
"inspection". **ironic-inspector** introspection is supported for some generic
drivers, please refer to `Ironic inspection documentation`_ for details.
Node States
~~~~~~~~~~~
* The nodes should be moved to ``MANAGEABLE`` provision state before
introspection (requires *python-ironicclient* of version 0.5.0 or newer)::
ironic node-set-provision-state <UUID> manage
* After successful introspection and before deploying nodes should be made
available to Nova, by moving them to ``AVAILABLE`` state::
ironic node-set-provision-state <UUID> provide
.. note::
Due to how Nova interacts with Ironic driver, you should wait 1 minute
before Nova becomes aware of available nodes after issuing this command.
Use ``nova hypervisor-stats`` command output to check it.
Introspection Rules
~~~~~~~~~~~~~~~~~~~
Inspector supports a simple JSON-based DSL to define rules to run during
introspection. Inspector provides an API to manage such rules, and will run
them automatically after running all processing hooks.
A rule consists of conditions to check, and actions to run. If conditions
evaluate to true on the introspection data, then actions are run on a node.
All actions have "rollback actions" associated with them, which are run when
conditions evaluate to false. This way we can safely rerun introspection.
Available conditions and actions are defined by plugins, and can be extended,
see CONTRIBUTING.rst_ for details. See `HTTP API`_ for specific calls to define
introspection rules.
Conditions
^^^^^^^^^^
A condition is represented by an object with fields:
``op`` the type of comparison operation, default available operators include :
``eq``, ``le``, ``ge``, ``ne``, ``lt``, ``gt`` (basic comparison operators),
``in-net`` (checks that IP address is in a given network).
``field`` a `JSON path <http://goessner.net/articles/JsonPath/>`_ to the field
in the introspection data to use in comparison.
``multiple`` how to treat situations where the ``field`` query returns multiple
results (e.g. the field contains a list), available options are:
* ``any`` (the default) require any to match,
* ``all`` require all to match,
* ``first`` requrie the first to match.
All other fields are passed to the condition plugin, e.g. numeric comparison
operations require a ``value`` field to compare against.
Actions
^^^^^^^
An action is represented by an object with fields:
``action`` type of action. Possible values are defined by plugins.
All other fields are passed to the action plugin.
Default available actions include:
* ``fail`` fail introspection. Requires a ``message`` parameter for the failure
message.
* ``set-attribute`` sets an attribute on an Ironic node. Requires a ``path``
field, which is the path to the attribute as used by ironic (e.g.
``/properties/something``), and a ``value`` to set.
* ``set-capability`` sets a capability on an Ironic node. Requires ``name``
and ``value`` fields, which are the name and the value for a new capability
accordingly. Existing value for this same capability is replaced.
* ``extend-attribute`` the same as ``set-attribute``, but treats existing
value as a list and appends value to it. If optional ``unique`` parameter is
set to ``True``, nothing will be added if given value is already in a list.
Setting IPMI Credentials
~~~~~~~~~~~~~~~~~~~~~~~~
If you have physical access to your nodes, you can use **ironic-inspector** to
set IPMI credentials for them without knowing the original ones. The workflow
is as follows:
* Ensure nodes will PXE boot on the right network by default.
* Set ``enable_setting_ipmi_credentials = true`` in the **ironic-inspector**
configuration file, restart **ironic-inspector**.
* Enroll nodes in Ironic with setting their ``ipmi_address`` only (or
equivalent driver-specific property, as per ``ipmi_address_fields``
configuration option).
With Ironic Liberty use ironic API version ``1.11``, so that new node gets
into ``enroll`` provision state::
ironic --ironic-api-version 1.11 node-create -d <DRIVER> -i ipmi_address=<ADDRESS>
Providing ``ipmi_address`` allows **ironic-inspector** to distinguish nodes.
* With Ironic Kilo or older, set maintenance mode on nodes.
That's an important step, otherwise Ironic might interfere with introspection
process. This is replaced by ``enroll`` state in Ironic Liberty.
* Start introspection with providing additional parameters:
* ``new_ipmi_password`` IPMI password to set,
* ``new_ipmi_username`` IPMI user name to set, defaults to one in node
driver_info.
* Manually power on the nodes and wait.
* After introspection is finished (watch nodes power state or use
**ironic-inspector** status API) you can move node to ``manageable`` and
then ``available`` states - see `Node States`_. With Ironic Kilo you have to
move a node out of maintenance mode.
Note that due to various limitations on password value in different BMC,
**ironic-inspector** will only accept passwords with length between 1 and 20
consisting only of letters and numbers.
Plugins
~~~~~~~
**ironic-inspector** heavily relies on plugins for data processing. Even the
standard functionality is largely based on plugins. Set ``processing_hooks``
option in the configuration file to change the set of plugins to be run on
introspection data. Note that order does matter in this option.
These are plugins that are enabled by default and should not be disabled,
unless you understand what you're doing:
``ramdisk_error``
reports error, if ``error`` field is set by the ramdisk, also optionally
stores logs from ``logs`` field, see `HTTP API`_ for details.
``scheduler``
validates and updates basic hardware scheduling properties: CPU number and
architecture, memory and disk size.
``validate_interfaces``
validates network interfaces information.
Here are some plugins that can be additionally enabled:
``example``
example plugin logging it's input and output.
``raid_device`` (deprecated name ``root_device_hint``)
gathers block devices from ramdisk and exposes root device in multiple
runs.
``extra_hardware``
stores the value of the 'data' key returned by the ramdisk as a JSON
encoded string in a Swift object. The plugin will also attempt to convert
the data into a format usable by introspection rules. If this is successful
then the new format will be stored in the 'extra' key. The 'data' key is
then deleted from the introspection data, as unless converted it's assumed
unusable by introspection rules.
Refer to CONTRIBUTING.rst_ for information on how to write your own plugin.
Troubleshooting
---------------
Errors when starting introspection
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* *Invalid provision state "available"*
In Kilo release with *python-ironicclient* 0.5.0 or newer Ironic
defaults to reporting provision state ``AVAILABLE`` for newly enrolled
nodes. **ironic-inspector** will refuse to conduct introspection in
this state, as such nodes are supposed to be used by Nova for scheduling.
See `Node States`_ for instructions on how to put nodes into
the correct state.
Introspection times out
~~~~~~~~~~~~~~~~~~~~~~~
There may be 3 reasons why introspection can time out after some time
(defaulting to 60 minutes, altered by ``timeout`` configuration option):
#. Fatal failure in processing chain before node was found in the local cache.
See `Troubleshooting data processing`_ for the hints.
#. Failure to load the ramdisk on the target node. See `Troubleshooting
PXE boot`_ for the hints.
#. Failure during ramdisk run. See `Troubleshooting ramdisk run`_ for the
hints.
Troubleshooting data processing
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In this case **ironic-inspector** logs should give a good idea what went wrong.
E.g. for RDO or Fedora the following command will output the full log::
sudo journalctl -u openstack-ironic-inspector
(use ``openstack-ironic-discoverd`` for version < 2.0.0).
.. note::
Service name and specific command might be different for other Linux
distributions (and for old version of **ironic-inspector**).
If ``ramdisk_error`` plugin is enabled and ``ramdisk_logs_dir`` configuration
option is set, **ironic-inspector** will store logs received from the ramdisk
to the ``ramdisk_logs_dir`` directory. This depends, however, on the ramdisk
implementation.
Troubleshooting PXE boot
^^^^^^^^^^^^^^^^^^^^^^^^
PXE booting most often becomes a problem for bare metal environments with
several physical networks. If the hardware vendor provides a remote console
(e.g. iDRAC for DELL), use it to connect to the machine and see what is going
on. You may need to restart introspection.
Another source of information is DHCP and TFTP server logs. Their location
depends on how the servers were installed and run. For RDO or Fedora use::
$ sudo journalctl -u openstack-ironic-inspector-dnsmasq
(use ``openstack-ironic-discoverd-dnsmasq`` for version < 2.0.0).
The last resort is ``tcpdump`` utility. Use something like
::
$ sudo tcpdump -i any port 67 or port 68 or port 69
to watch both DHCP and TFTP traffic going through your machine. Replace
``any`` with a specific network interface to check that DHCP and TFTP
requests really reach it.
If you see node not attempting PXE boot or attempting PXE boot on the wrong
network, reboot the machine into BIOS settings and make sure that only one
relevant NIC is allowed to PXE boot.
If you see node attempting PXE boot using the correct NIC but failing, make
sure that:
#. network switches configuration does not prevent PXE boot requests from
propagating,
#. there is no additional firewall rules preventing access to port 67 on the
machine where *ironic-inspector* and its DHCP server are installed.
If you see node receiving DHCP address and then failing to get kernel and/or
ramdisk or to boot them, make sure that:
#. TFTP server is running and accessible (use ``tftp`` utility to verify),
#. no firewall rules prevent access to TFTP port,
#. DHCP server is correctly set to point to the TFTP server,
#. ``pxelinux.cfg/default`` within TFTP root contains correct reference to the
kernel and ramdisk.
Troubleshooting ramdisk run
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Connect to the remote console as described in `Troubleshooting PXE boot`_ to
see what is going on with the ramdisk. The ramdisk drops into emergency shell
on failure, which you can use to look around. There should be file called
``logs`` with the current ramdisk logs.
Troubleshooting DNS issues on Ubuntu
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Ubuntu uses local DNS caching, so tries localhost for DNS results first
before calling out to an external DNS server. When DNSmasq is installed and
configured for use with ironic-inspector, it can cause problems by interfering
with the local DNS cache. To fix this issue ensure that ``/etc/resolve.conf``
points to your external DNS servers and not to ``127.0.0.1``.

159
doc/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) source
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
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 " xml to make Docutils-native XML files"
@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)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(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/Heat.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Heat.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/Heat"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Heat"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The xml files are in $(BUILDDIR)/xml."
latex:
$(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:
$(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."

2
doc/source/.gitignore vendored

@ -0,0 +1,2 @@
target/
build/

274
doc/source/api/HTTP-API.rst

@ -0,0 +1,274 @@
HTTP API
--------
By default **ironic-inspector** listens on ``0.0.0.0:5050``, port
can be changed in configuration. Protocol is JSON over HTTP.
Start Introspection
~~~~~~~~~~~~~~~~~~~
``POST /v1/introspection/<UUID>`` initiate hardware introspection for node
``<UUID>``. All power management configuration for this node needs to be done
prior to calling the endpoint (except when `Setting IPMI Credentials`_).
Requires X-Auth-Token header with Keystone token for authentication.
Optional parameters:
* ``new_ipmi_password`` if set, **ironic-inspector** will try to set IPMI
password on the machine to this value. Power credentials validation will be
skipped and manual power on will be required. See `Setting IPMI
credentials`_ for details.
* ``new_ipmi_username`` provides new IPMI user name in addition to password
set by ``new_ipmi_password``. Defaults to current ``ipmi_username`` in
node ``driver_info`` field.
Response:
* 202 - accepted introspection request
* 400 - bad request
* 401, 403 - missing or invalid authentication
* 404 - node cannot be found
Get Introspection Status
~~~~~~~~~~~~~~~~~~~~~~~~
``GET /v1/introspection/<UUID>`` get hardware introspection status.
Requires X-Auth-Token header with Keystone token for authentication.
Response:
* 200 - OK
* 400 - bad request
* 401, 403 - missing or invalid authentication
* 404 - node cannot be found
Response body: JSON dictionary with keys:
* ``finished`` (boolean) whether introspection is finished
(``true`` on introspection completion or if it ends because of an error)
* ``error`` error string or ``null``
Get Introspection Data
~~~~~~~~~~~~~~~~~~~~~~
``GET /v1/introspection/<UUID>/data`` get stored data from successful
introspection.
Requires X-Auth-Token header with Keystone token for authentication.
Response:
* 200 - OK
* 400 - bad request
* 401, 403 - missing or invalid authentication
* 404 - data cannot be found or data storage not configured
Response body: JSON dictionary with introspection data
Introspection Rules
~~~~~~~~~~~~~~~~~~~
See `Introspection Rules documentation`_ for details.
All these API endpoints require X-Auth-Token header with Keystone token for
authentication.
* ``POST /v1/rules`` create a new introspection rule.
Request body: JSON dictionary with keys:
* ``conditions`` rule conditions, see `Introspection Rules documentation`_
* ``actions`` rule actions, see `Introspection Rules documentation`_
* ``description`` (optional) human-readable description
* ``uuid`` (optional) rule UUID, autogenerated if missing
Response
* 200 - OK
* 400 - bad request
Response body: JSON dictionary with introspection rule representation (the
same as above with UUID filled in).
* ``GET /v1/rules`` list all introspection rules.
Response
* 200 - OK
Response body: JSON dictionary with key ``rules`` - list of short rule
representations. Short rule representation is a JSON dictionary with keys:
* ``uuid`` rule UUID
* ``description`` human-readable description
* ``links`` list of HTTP links, use one with ``rel=self`` to get the full
rule details
* ``DELETE /v1/rules`` delete all introspection rules.
Response
* 204 - OK
* ``GET /v1/rules/<UUID>`` get one introspection rule by its ``<UUID>``.
Response
* 200 - OK
* 404 - not found
Response body: JSON dictionary with introspection rule representation
(see ``POST /v1/rules`` above).
* ``DELETE /v1/rules/<UUID>`` delete one introspection rule by its ``<UUID>``.
Response
* 204 - OK
* 404 - not found
.. _Introspection Rules documentation: https://github.com/openstack/ironic-inspector#introspection-rules
Ramdisk Callback
~~~~~~~~~~~~~~~~
``POST /v1/continue`` internal endpoint for the ramdisk to post back
discovered data. Should not be used for anything other than implementing
the ramdisk. Request body: JSON dictionary with at least these keys:
* ``cpus`` number of CPU
* ``cpu_arch`` architecture of the CPU
* ``memory_mb`` RAM in MiB
* ``local_gb`` hard drive size in GiB
* ``interfaces`` dictionary filled with data from all NIC's, keys being
interface names, values being dictionaries with keys:
* ``mac`` MAC address
* ``ip`` IP address
* ``ipmi_address`` IP address of BMC, may be missing on VM
* ``boot_interface`` optional MAC address of the NIC that the machine
PXE booted from either in standard format ``11:22:33:44:55:66`` or
in *PXELinux* ``BOOTIF`` format ``01-11-22-33-44-55-66``.
* ``error`` optional error happened during ramdisk run, interpreted by
``ramdisk_error`` plugin
* ``logs`` optional base64-encoded logs from the ramdisk
* ``block_devices`` optional block devices information for
``root_device_hint`` plugin, dictionary with keys:
* ``serials`` list of serial numbers of block devices.
.. note::
This list highly depends on enabled plugins, provided above are
expected keys for the default set of plugins. See Plugins_ for details.
.. note::
This endpoint is not expected to be versioned, though versioning will work
on it.
Response:
* 200 - OK
* 400 - bad request
* 403 - node is not on introspection
* 404 - node cannot be found or multiple nodes found
Response body: JSON dictionary. If `Setting IPMI Credentials`_ is requested,
body will contain the following keys:
* ``ipmi_setup_credentials`` boolean ``True``
* ``ipmi_username`` new IPMI user name
* ``ipmi_password`` new IPMI password
.. _Setting IPMI Credentials: https://github.com/openstack/ironic-inspector#setting-ipmi-credentials
.. _Plugins: https://github.com/openstack/ironic-inspector#plugins
Error Response
~~~~~~~~~~~~~~
If an error happens during request processing, **Ironic Inspector** returns
a response with an appropriate HTTP code set, e.g. 400 for bad request or
404 when something was not found (usually node in cache or node in ironic).
The following JSON body is returned::
{
"error": {
"message": "Full error message"
}
}
This body may be extended in the future to include details that are more error
specific.
API Versioning
~~~~~~~~~~~~~~
The API supports optional API versioning. You can query for minimum and
maximum API version supported by the server. You can also declare required API
version in your requests, so that the server rejects request of unsupported
version.
.. note::
Versioning was introduced in **Ironic Inspector 2.1.0**.
All versions must be supplied as string in form of ``X.Y``, where ``X`` is a
major version and is always ``1`` for now, ``Y`` is a minor version.
* If ``X-OpenStack-Ironic-Inspector-API-Version`` header is sent with request,
the server will check if it supports this version. HTTP error 406 will be
returned for unsupported API version.
* All HTTP responses contain
``X-OpenStack-Ironic-Inspector-API-Minimum-Version`` and
``X-OpenStack-Ironic-Inspector-API-Maximum-Version`` headers with minimum
and maximum API versions supported by the server.
API Discovery
~~~~~~~~~~~~~
The API supports API discovery. You can query different parts of the API to
discover what other endpoints are avaliable.
* ``GET /`` List API Versions
Response:
* 200 - OK
Response body: JSON dictionary containing a list of ``versions``, each
version contains:
* ``status`` Either CURRENT or SUPPORTED
* ``id`` The version identifier
* ``links`` A list of links to this version endpoint containing:
* ``href`` The URL
* ``rel`` The relationship between the version and the href
* ``GET /v1`` List API v1 resources
Response:
* 200 - OK
Response body: JSON dictionary containing a list of ``resources``, each
resource contains:
* ``name`` The name of this resources
* ``links`` A list of link to this resource containing:
* ``href`` The URL
* ``rel`` The relationship between the resource and the href
Version History
^^^^^^^^^^^^^^^
**1.0** version of API at the moment of introducing versioning.
**1.1** adds endpoint to retrieve stored introspection data.
**1.2** endpoints for manipulating introspection rules.

90
doc/source/conf.py

@ -0,0 +1,90 @@
# -*- coding: utf-8 -*-
#
# -- General configuration ----------------------------------------------------
# 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.autodoc',
'sphinx.ext.viewcode',
'oslosphinx'
]
wsme_protocols = ['restjson']
# autodoc generation is a bit aggressive and a nuisance when doing heavy
# text edit cycles.
# execute "export SPHINX_DEBUG=1" in your terminal to disable
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Ironic Inspector'
copyright = u'OpenStack Foundation'
# 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.
#from ironic import version as ironic_version
# The full version, including alpha/beta/rc tags.
#release = ironic_version.version_info.release_string()
# The short X.Y version.
#version = ironic_version.version_info.version_string()
# A list of ignored prefixes for module index sorting.
modindex_common_prefix = ['ironic.']
# 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
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# NOTE(cinerama): mock out nova modules so docs can build without warnings
#import mock
#import sys
#MOCK_MODULES = ['nova', 'nova.compute', 'nova.context']
#for module in MOCK_MODULES:
# sys.modules[module] = mock.Mock()
# -- Options for HTML output --------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
#html_theme_path = ["."]
#html_theme = '_theme'
#html_static_path = ['_static']
# Output file base name for HTML help builder.
htmlhelp_basename = '%sdoc' % project
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass
# [howto/manual]).
latex_documents = [
(
'index',
'%s.tex' % project,
u'%s Documentation' % project,
u'OpenStack Foundation',
'manual'
),
]
# -- Options for seqdiag ------------------------------------------------------
seqdiag_html_image_format = "SVG"

241
doc/source/deploy/install-guide.rst

@ -0,0 +1,241 @@
.. _install_guide:
Installation
------------
Install from PyPI_ (you may want to use virtualenv to isolate your
environment)::
pip install ironic-inspector
Also there is a `DevStack <http://docs.openstack.org/developer/devstack/>`_
plugin for **ironic-inspector** - see :ref:`contributing_link` for the current status.
Finally, some distributions (e.g. Fedora) provide **ironic-inspector**
packaged, some of them - under its old name *ironic-discoverd*.
.. _PyPI: https://pypi.python.org/pypi/ironic-inspector
Configuration
~~~~~~~~~~~~~
Copy ``example.conf`` to some permanent place
(e.g. ``/etc/ironic-inspector/inspector.conf``).
Fill in at least these configuration values:
* ``os_username``, ``os_password``, ``os_tenant_name`` - Keystone credentials
to use when accessing other services and check client authentication tokens;
* ``os_auth_url``, ``identity_uri`` - Keystone endpoints for validating
authentication tokens and checking user roles;
* ``connection`` in the ``database`` section - SQLAlchemy connection string
for the database;
* ``dnsmasq_interface`` - interface on which ``dnsmasq`` (or another DHCP
service) listens for PXE boot requests (defaults to ``br-ctlplane`` which is
a sane default for TripleO-based installations but is unlikely to work for
other cases).
See comments inside `example.conf
<https://github.com/openstack/ironic-inspector/blob/master/example.conf>`_
for the other possible configuration options.
.. note::
Configuration file contains a password and thus should be owned by ``root``
and should have access rights like ``0600``.
**ironic-inspector** requires root rights for managing iptables. It gets them
by running ``ironic-inspector-rootwrap`` utility with ``sudo``.
To allow it, copy file ``rootwrap.conf`` and directory ``rootwrap.d`` to the
configuration directory (e.g. ``/etc/ironic-inspector/``) and create file
``/etc/sudoers.d/ironic-inspector-rootwrap`` with the following content::
stack ALL=(root) NOPASSWD: /usr/bin/ironic-inspector-rootwrap /etc/ironic-inspector/rootwrap.conf *
.. DANGER::
Be very careful about typos in ``/etc/sudoers.d/ironic-inspector-rootwrap``
as any typo will break sudo for **ALL** users on the system. Especially,
make sure there is a new line at the end of this file.
.. note::
``rootwrap.conf`` and all files in ``rootwrap.d`` must be writeable
only by root.
.. note::
If you store ``rootwrap.d`` in a different location, make sure to update
the *filters_path* option in ``rootwrap.conf`` to reflect the change.
If your ``rootwrap.conf`` is in a different location, then you need
to update the *rootwrap_config* option in ``ironic-inspector.conf``
to point to that location.
Replace ``stack`` with whatever user you'll be using to run
**ironic-inspector**.
Configuring PXE
^^^^^^^^^^^^^^^
As for PXE boot environment, you'll need:
* TFTP server running and accessible (see below for using *dnsmasq*).
Ensure ``pxelinux.0`` is present in the TFTP root.
* You need PXE boot server (e.g. *dnsmasq*) running on **the same** machine as
**ironic-inspector**. Don't do any firewall configuration:
**ironic-inspector** will handle it for you. In **ironic-inspector**
configuration file set ``dnsmasq_interface`` to the interface your
PXE boot server listens on. Here is an example *dnsmasq.conf*::
port=0
interface={INTERFACE}
bind-interfaces
dhcp-range={DHCP IP RANGE, e.g. 192.168.0.50,192.168.0.150}
enable-tftp
tftp-root={TFTP ROOT, e.g. /tftpboot}
dhcp-boot=pxelinux.0
* You have to install and configure one of 2 available ramdisks: simple
bash-based (see `Using simple ramdisk`_) or more complex based on
ironic-python-agent_ (See `Using IPA`_).
Here is *inspector.conf* you may end up with::
[DEFAULT]
debug = false
[ironic]
identity_uri = http://127.0.0.1:35357
os_auth_url = http://127.0.0.1:5000/v2.0
os_username = admin
os_password = password
os_tenant_name = admin
[firewall]
dnsmasq_interface = br-ctlplane
.. note::
Set ``debug = true`` if you want to see complete logs.
Using simple ramdisk
^^^^^^^^^^^^^^^^^^^^
* Build and put into your TFTP the kernel and ramdisk created using the
diskimage-builder_ `ironic-discoverd-ramdisk element`_::
ramdisk-image-create -o discovery fedora ironic-discoverd-ramdisk
You need diskimage-builder_ 0.1.38 or newer to do it (using the latest one
is always advised).
* Configure your ``$TFTPROOT/pxelinux.cfg/default`` with something like::
default introspect
label introspect
kernel discovery.kernel
append initrd=discovery.initramfs discoverd_callback_url=http://{IP}:5050/v1/continue
ipappend 3
Replace ``{IP}`` with IP of the machine (do not use loopback interface, it
will be accessed by ramdisk on a booting machine).
.. note::
There are some prebuilt images which use obsolete ``ironic_callback_url``
instead of ``discoverd_callback_url``. Modify ``pxelinux.cfg/default``
accordingly if you have one of these.
Using IPA
^^^^^^^^^
ironic-python-agent_ is a new ramdisk developed for Ironic. During the Liberty
cycle support for **ironic-inspector** was added. This is experimental
for now, but we plan on making IPA the default ramdisk in Mitaka cycle.
.. note::
You need at least 1.5 GiB of RAM on the machines to use this ramdisk.
To build an ironic-python-agent ramdisk, do the following:
* Get the latest diskimage-builder_::
sudo pip install -U "diskimage-builder>=1.1.2"
* Build the ramdisk::
disk-image-create ironic-agent fedora -o ironic-agent
.. note::
Replace "fedora" with your distribution of choice.
* Copy resulting files ``ironic-agent.vmlinuz`` and ``ironic-agent.initramfs``
to the TFTP root directory.
Next, set up ``$TFTPROOT/pxelinux.cfg/default`` as follows::
default introspect
label introspect
kernel ironic-agent.vmlinuz
append initrd=ironic-agent.initramfs ipa-inspection-callback-url=http://{IP}:5050/v1/continue systemd.journald.forward_to_console=yes
ipappend 3
Replace ``{IP}`` with IP of the machine (do not use loopback interface, it
will be accessed by ramdisk on a booting machine).
.. note::
While ``systemd.journald.forward_to_console=yes`` is not actually
required, it will substantially simplify debugging if something goes wrong.
.. _diskimage-builder: https://github.com/openstack/diskimage-builder
.. _ironic-discoverd-ramdisk element: https://github.com/openstack/diskimage-builder/tree/master/elements/ironic-discoverd-ramdisk
.. _ironic-python-agent: https://github.com/openstack/ironic-python-agent
Managing the **ironic-inspector** database
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**ironic-inspector** provides a command line client for managing its database,
this client can be used for upgrading, and downgrading the database using
alembic migrations.
If this is your first time running **ironic-inspector** to migrate the
database simply run:
::
ironic-inspector-dbsync --config-file /etc/ironic-inspector/inspector.conf upgrade
If you have previously run a version of **ironic-inspector** earlier than
2.2.0, the safest thing is to delete the existing SQLite database and run
``upgrade`` as shown above. If you, however, want to save the existing
database, to ensure your database will work with the migrations, you'll need to
run an extra step before upgrading the database. You only need to do this the
first time running version 2.2.0 or later.
If you are upgrading from **ironic-inspector** version 2.1.0 or lower:
::
ironic-inspector-dbsync --config-file /etc/ironic-inspector/inspector.conf stamp --revision 578f84f38d
ironic-inspector-dbsync --config-file /etc/ironic-inspector/inspector.conf upgrade
If you are upgrading from a git master install of **ironic-inspector** from
after :ref:`introspection_rules` were introduced:
::
ironic-inspector-dbsync --config-file /etc/ironic-inspector/inspector.conf stamp --revision d588418040d
ironic-inspector-dbsync --config-file /etc/ironic-inspector/inspector.conf upgrade
Other available commands can be discovered by running::
ironic-inspector-dbsync --help
Running
~~~~~~~
::
ironic-inspector --config-file /etc/ironic-inspector/inspector.conf
A good starting point for writing your own *systemd* unit should be `one used
in Fedora <http://pkgs.fedoraproject.org/cgit/openstack-ironic-discoverd.git/plain/openstack-ironic-discoverd.service>`_
(note usage of old name).

3
doc/source/dev/contributing_link.rst

@ -0,0 +1,3 @@
.. _contributing_link:
.. include:: ../../../CONTRIBUTING.rst

73
doc/source/index.rst

@ -0,0 +1,73 @@
Hardware introspection for OpenStack Bare Metal
===============================================
This is an auxiliary service for discovering hardware properties for a
node managed by `Ironic`_. Hardware introspection or hardware
properties discovery is a process of getting hardware parameters required for
scheduling from a bare metal node, given it's power management credentials
(e.g. IPMI address, user name and password).
A special ramdisk is required to collect the information on a
node. The default one can be built using diskimage-builder_ and
`ironic-discoverd-ramdisk element`_ (see :ref:`install_guide`).
* Free software: Apache license
* Source: http://git.openstack.org/cgit/openstack/ironic-inspector
* Bugs: http://bugs.launchpad.net/ironic-inspector
* Blueprints: https://blueprints.launchpad.net/ironic-inspector
* Downloads: https://pypi.python.org/pypi/ironic-inspector
* Python client library and CLI tool: `python-ironic-inspector-client
<https://pypi.python.org/pypi/python-ironic-inspector-client>`_.
.. _Ironic: https://wiki.openstack.org/wiki/Ironic
.. _PyPI: https://pypi.python.org/pypi/ironic-inspector
.. _diskimage-builder: https://github.com/openstack/diskimage-builder
.. _ironic-discoverd-ramdisk element: https://github.com/openstack/diskimage-builder/tree/master/elements/ironic-discoverd-ramdisk
.. note::
**ironic-inspector** was called *ironic-discoverd* before version 2.0.0.
For information on any current or prior version, see `the release
notes`_ and `the wiki pages`_.
.. _the release notes: releasenotes/index.html
.. _the wiki pages: https://wiki.openstack.org/wiki/Ironic/ReleaseNotes
Admin Guide
===========
Overview
--------
.. toctree::
:maxdepth: 1
Installation Guide <deploy/install-guide>
Usage <usage/usage>
Troubleshooting <troubleshooting/troubleshooting>
Developer Guide
===============
Introduction
------------
.. toctree::
:maxdepth: 1
Contribution Guide <dev/contributing_link>
API References
--------------
.. toctree::
:maxdepth: 1
HTTP API description <api/HTTP-API>
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

113
doc/source/troubleshooting/troubleshooting.rst

@ -0,0 +1,113 @@
Troubleshooting
===============
Errors when starting introspection
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* *Invalid provision state "available"*
In Kilo release with *python-ironicclient* 0.5.0 or newer Ironic
defaults to reporting provision state ``AVAILABLE`` for newly enrolled
nodes. **ironic-inspector** will refuse to conduct introspection in
this state, as such nodes are supposed to be used by Nova for scheduling.
See :ref:`node_states` for instructions on how to put nodes into
the correct state.
Introspection times out
~~~~~~~~~~~~~~~~~~~~~~~
There may be 3 reasons why introspection can time out after some time
(defaulting to 60 minutes, altered by ``timeout`` configuration option):
#. Fatal failure in processing chain before node was found in the local cache.
See `Troubleshooting data processing`_ for the hints.
#. Failure to load the ramdisk on the target node. See `Troubleshooting
PXE boot`_ for the hints.
#. Failure during ramdisk run. See `Troubleshooting ramdisk run`_ for the
hints.
Troubleshooting data processing
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In this case **ironic-inspector** logs should give a good idea what went wrong.
E.g. for RDO or Fedora the following command will output the full log::
sudo journalctl -u openstack-ironic-inspector
(use ``openstack-ironic-discoverd`` for version < 2.0.0).
.. note::
Service name and specific command might be different for other Linux
distributions (and for old version of **ironic-inspector**).
If ``ramdisk_error`` plugin is enabled and ``ramdisk_logs_dir`` configuration
option is set, **ironic-inspector** will store logs received from the ramdisk
to the ``ramdisk_logs_dir`` directory. This depends, however, on the ramdisk
implementation.
Troubleshooting PXE boot
^^^^^^^^^^^^^^^^^^^^^^^^
PXE booting most often becomes a problem for bare metal environments with
several physical networks. If the hardware vendor provides a remote console
(e.g. iDRAC for DELL), use it to connect to the machine and see what is going
on. You may need to restart introspection.
Another source of information is DHCP and TFTP server logs. Their location
depends on how the servers were installed and run. For RDO or Fedora use::
$ sudo journalctl -u openstack-ironic-inspector-dnsmasq
(use ``openstack-ironic-discoverd-dnsmasq`` for version < 2.0.0).
The last resort is ``tcpdump`` utility. Use something like
::
$ sudo tcpdump -i any port 67 or port 68 or port 69
to watch both DHCP and TFTP traffic going through your machine. Replace
``any`` with a specific network interface to check that DHCP and TFTP
requests really reach it.
If you see node not attempting PXE boot or attempting PXE boot on the wrong
network, reboot the machine into BIOS settings and make sure that only one
relevant NIC is allowed to PXE boot.
If you see node attempting PXE boot using the correct NIC but failing, make
sure that:
#. network switches configuration does not prevent PXE boot requests from
propagating,
#. there is no additional firewall rules preventing access to port 67 on the
machine where *ironic-inspector* and its DHCP server are installed.
If you see node receiving DHCP address and then failing to get kernel and/or
ramdisk or to boot them, make sure that:
#. TFTP server is running and accessible (use ``tftp`` utility to verify),
#. no firewall rules prevent access to TFTP port,
#. DHCP server is correctly set to point to the TFTP server,
#. ``pxelinux.cfg/default`` within TFTP root contains correct reference to the
kernel and ramdisk.
Troubleshooting ramdisk run
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Connect to the remote console as described in `Troubleshooting PXE boot`_ to
see what is going on with the ramdisk. The ramdisk drops into emergency shell
on failure, which you can use to look around. There should be file called
``logs`` with the current ramdisk logs.
Troubleshooting DNS issues on Ubuntu
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Ubuntu uses local DNS caching, so tries localhost for DNS results first
before calling out to an external DNS server. When DNSmasq is installed and
configured for use with ironic-inspector, it can cause problems by interfering
with the local DNS cache. To fix this issue ensure that ``/etc/resolve.conf``
points to your external DNS servers and not to ``127.0.0.1``.

187
doc/source/usage/usage.rst

@ -0,0 +1,187 @@
Usage
=====
Refer to HTTP-API.rst_ for information on the HTTP API.
Refer to the `client page`_ for information on how to use CLI and Python
library.
.. _HTTP-API.rst: https://github.com/openstack/ironic-inspector/blob/master/HTTP-API.rst
.. _HTTP API: https://github.com/openstack/ironic-inspector/blob/master/HTTP-API.rst
.. _client page: https://pypi.python.org/pypi/python-ironic-inspector-client
Using from Ironic API
~~~~~~~~~~~~~~~~~~~~~
Ironic Kilo introduced support for hardware introspection under name of
"inspection". **ironic-inspector** introspection is supported for some generic
drivers, please refer to `Ironic inspection documentation`_ for details.
.. _Ironic inspection documentation: http://docs.openstack.org/developer/ironic/deploy/install-guide.html#hardware-inspection
.. _node_states:
Node States
~~~~~~~~~~~
* The nodes should be moved to ``MANAGEABLE`` provision state before
introspection (requires *python-ironicclient* of version 0.5.0 or newer)::
ironic node-set-provision-state <UUID> manage
* After successful introspection and before deploying nodes should be made
available to Nova, by moving them to ``AVAILABLE`` state::
ironic node-set-provision-state <UUID> provide
.. note::
Due to how Nova interacts with Ironic driver, you should wait 1 minute
before Nova becomes aware of available nodes after issuing this command.
Use ``nova hypervisor-stats`` command output to check it.
.. _introspection_rules:
Introspection Rules
~~~~~~~~~~~~~~~~~~~
Inspector supports a simple JSON-based DSL to define rules to run during
introspection. Inspector provides an API to manage such rules, and will run
them automatically after running all processing hooks.
A rule consists of conditions to check, and actions to run. If conditions
evaluate to true on the introspection data, then actions are run on a node.
All actions have "rollback actions" associated with them, which are run when
conditions evaluate to false. This way we can safely rerun introspection.
Available conditions and actions are defined by plugins, and can be extended,
see :ref:`contributing_link` for details. See `HTTP API`_ for specific calls to define
introspection rules.
Conditions
^^^^^^^^^^
A condition is represented by an object with fields:
``op`` the type of comparison operation, default available operators include :
``eq``, ``le``, ``ge``, ``ne``, ``lt``, ``gt`` (basic comparison operators),
``in-net`` (checks that IP address is in a given network).
``field`` a `JSON path <http://goessner.net/articles/JsonPath/>`_ to the field
in the introspection data to use in comparison.
``multiple`` how to treat situations where the ``field`` query returns multiple
results (e.g. the field contains a list), available options are:
* ``any`` (the default) require any to match,
* ``all`` require all to match,
* ``first`` requrie the first to match.
All other fields are passed to the condition plugin, e.g. numeric comparison
operations require a ``value`` field to compare against.
Actions
^^^^^^^
An action is represented by an object with fields: