Generate Sphinx docs
Change-Id: I540b28d6173b30baf6ee2e6e14d8ba5ffb67b660 Closes-Bug: #1514803
This commit is contained in:
parent
f5671a4376
commit
292e8c9cfd
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,7 +6,7 @@
|
||||
|
||||
# Sphinx
|
||||
_build
|
||||
doc/source/api/
|
||||
#doc/source/api/
|
||||
|
||||
# release notes build
|
||||
releasenotes/build
|
||||
|
540
README.rst
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
Normal file
159
doc/Makefile
Normal file
@ -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
Normal file
2
doc/source/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
target/
|
||||
build/
|
274
doc/source/api/HTTP-API.rst
Normal file
274
doc/source/api/HTTP-API.rst
Normal file
@ -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
Normal file
90
doc/source/conf.py
Normal file
@ -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
Normal file
241
doc/source/deploy/install-guide.rst
Normal file
@ -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
Normal file
3
doc/source/dev/contributing_link.rst
Normal file
@ -0,0 +1,3 @@
|
||||
.. _contributing_link:
|
||||
|
||||
.. include:: ../../../CONTRIBUTING.rst
|
73
doc/source/index.rst
Normal file
73
doc/source/index.rst
Normal file
@ -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
Normal file
113
doc/source/troubleshooting/troubleshooting.rst
Normal file
@ -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
Normal file
187
doc/source/usage/usage.rst
Normal file
@ -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:
|
||||
|
||||
``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 :ref:`contributing_link` for information on how to write your own plugin.
|
12
releasenotes/notes/sphinx-docs-4d0a5886261e57bf.yaml
Normal file
12
releasenotes/notes/sphinx-docs-4d0a5886261e57bf.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
prelude: >
|
||||
This release includes automatic `docs` generation via Sphinx.
|
||||
other:
|
||||
- |
|
||||
Introduced new docs generation via `Sphinx <http://sphinx-doc.org/contents.html>`_
|
||||
and `ReST <http://docutils.sourceforge.net/rst.html>`_.
|
||||
|
||||
* Separate `doc` folder includes `source` and `build`
|
||||
* Integration with `tox <https://testrun.org/tox/latest/index.html>`_ as `docs` target
|
||||
* `makefile` for manual building
|
||||
* `Openstack Theme <https://github.com/openstack/oslosphinx>`_ support
|
@ -66,3 +66,8 @@ input_file = ironic-inspector/locale/ironic-inspector.pot
|
||||
keywords = _ gettext ngettext l_ lazy_gettext
|
||||
mapping_file = babel.cfg
|
||||
output_file = ironic-inspector/locale/ironic-inspector.pot
|
||||
|
||||
[build_sphinx]
|
||||
all_files = 1
|
||||
build-dir = doc/build
|
||||
source-dir = doc/source
|
||||
|
@ -8,3 +8,4 @@ mock>=1.2
|
||||
sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2
|
||||
oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
|
||||
reno>=0.1.1 # Apache2
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user