Initial support for installation of ironic-inspector

This review adds the ironic-inspector as a component that can be
opted to be installed by the user.  Note, this is moderately useless
without shade support and modules to assist the users to leverage
this workflow.

If a user wishes to utilize at this time before those items exist
then they will have to move nodes in available state back to
manageable state, and then invoke the inspect state which will
return them to manageable state once done.

Change-Id: I7b4ff92fa27578a9a7b0f25fc6e8658c3f2700aa
implements: blueprint bifrost-inspector-support
Depends-On: I27caa1122a72ac655958b7a6aa14b7566964f998
This commit is contained in:
Julia Kreger 2015-10-01 10:45:23 -04:00
parent ae05e413b6
commit c1f9beac63
10 changed files with 222 additions and 3 deletions

View File

@ -129,6 +129,51 @@ enable_cors_credential_support: Boolean value, default false. This variable
noauth mode, this realistically should not
be modified.
### Hardware Inspection Support
Bifrost also supports the installation of the ironic-inspector in standalone
mode, which enables the user to allow for identification of the system
properties via a workflow.
enable_inspector: Boolean value, default false. This controls the
installation and configuration of the ironic-
inspector.
inspector_auth: Inspector authentication mode, defaulted to "noauth".
inspector_debug: Boolean Value, default true, this controls if the ironic
inspector is writing debug logging. This may change
in the future, however it is the default for initial
testing.
inspector_manage_firewall: Boolean value, default false, that controls
if the ironic-inspector is to manage the firewall
rules of the host. This is un-necessary in the
bifrost use case since the installation playbook
adds the record to permit the callback traffic.
ironic_auth_strategy: Boolean Value, default "noauth", controls the config
of the ironic-inspector for it to understand that ironic
is operating in noauth mode.
inspector_data_dir: Defaults to "/opt/stack/ironic-inspector/var", Base folder
for inspector temporary data and log files.
inspector_port_addition: Default value, 'pxe' of three possible values,
'all', 'active', and 'pxe'. Controls the logic
utilized for the addition of new port records
associated with the ironic node.
inspector_keep_ports: Default value, 'present' of three possible values,
'all', 'present', and 'added'. Controls the logic
utilized by inspector for setting ports to be
kept in association with an ironic node.
inspector_store_ramdisk_logs: Boolean value, default true. Controls if the
inspector agent will retain logs from the
ramdisk that called the inspector service.
Notes
-----

View File

@ -74,3 +74,17 @@ enable_cors_credential_support: false
# Set this to true to configure dnsmasq to respond to requests from the
# hosts in your dynamic inventory.
inventory_dhcp: False
# Settings to enable the use of inspector
enable_inspector: false
inspector_auth: "noauth"
inspector_debug: true
inspector_manage_firewall: false
ironic_auth_strategy: "noauth"
inspector_data_dir: "/opt/stack/ironic-inspector/var"
inspector_store_ramdisk_logs: true
# Note: inspector_port_addition has three valid values: all, active, pxe
inspector_port_addition: "pxe"
# Note: inspector_keep_ports has three valid values: all, present, added
inspector_keep_ports: "present"

View File

@ -5,7 +5,10 @@ chain ipxe.pxe
# load the MAC-specific file or fail if it's not found
:boot_system
chain pxelinux.cfg/${mac:hexhyp} || goto error_no_config
chain pxelinux.cfg/${mac:hexhyp} || goto inspector_ipa
:inspector_ipa
chain pxelinux.cfg/default || goto error_no_config
:error_no_config
echo PXE boot failed. No configuration found for MAC ${mac}

View File

@ -19,6 +19,7 @@
- /tftpboot
- /tftpboot/pxelinux.cfg
- "{{ http_boot_folder }}"
- "{{ http_boot_folder }}/pxelinux.cfg"
- name: "Place tftpd map-file"
copy: src=tftpboot-map-file dest=/tftpboot/map-file owner=ironic group=ironic
- name: "Disable service tftpd-hpa"
@ -53,3 +54,10 @@
- name: "Create master_images folder"
file: name=/tftpboot/master_images state=directory owner=ironic group=ironic
when: test_master_images.stat.exists == false
- name: "Inspector - Place default tftp boot file in {{ http_boot_folder}}/pxelinux.cfg/"
template:
src=inspector-default-boot-ipxe.j2
dest="{{ http_boot_folder }}/pxelinux.cfg/default"
owner=ironic
group=ironic
when: enable_inspector | bool

View File

@ -0,0 +1,86 @@
# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
- name: "Inspector - PIP Install"
pip:
name=ironic-inspector
state=latest
- name: "Inspector - PIP client install"
pip:
name=python-ironic-inspector-client
state=latest
# Note(TheJulia): Until support exists in the inspector database schema, to
# allow for inspector to define its preferred database engine, MySQL cannot
# be used with the default engine in the OpenStack CI.
# See: https://bugs.launchpad.net/ironic-inspector/+bug/1506160
#- name: "MySQL - Create database"
# mysql_db:
# login_user={{ mysql_username }}
# login_password={{ mysql_password }}
# name=inspector
# state=present
# encoding=utf8
# register: test_created_inspector_db
#- name: "MySQL - Create user for inspector"
# mysql_user:
# login_user={{ mysql_username }}
# login_password={{ mysql_password }}
# name=inspector
# password={{ ironic_db_password }}
# priv=inspector.*:ALL
# state=present
- name: "Inspector - Ensure /etc/ironic-inspector/ exists"
file:
dest=/etc/ironic-inspector
owner=ironic
group=ironic
mode=0755
state=directory
- name: "Inspector - Place Configuration"
template:
src=ironic-inspector.conf.j2
dest=/etc/ironic-inspector/inspector.conf
owner=ironic
group=ironic
mode=0740
- name: "Inspector - create data folder"
file:
name="{{ inspector_data_dir }}"
state=directory
owner=ironic
group=ironic
mode=0755
- name: "Inspector - create log folder"
file:
name="{{ inspector_data_dir }}/log"
state=directory
owner=ironic
group=ironic
mode=0755
- name: "Upgrade inspector DB Schema"
command: su ironic -c "ironic-inspector-dbsync --config-file /etc/ironic-inspector/inspector.conf upgrade"
- name: "Inspector - Get ironic-inspector install location"
shell: echo $(dirname $(which ironic-inspector))
register: ironic_install_prefix
- name: "Inspector - Place service"
template: src={{ init_template }} dest={{ init_dest_dir }}{{item.service_name}}{{ init_ext }} owner=root group=root
with_items:
- { service_path: "{{ ironic_install_prefix.stdout }}", service_name: 'ironic-inspector', username: 'ironic', args: '--config-file /etc/ironic-inspector/inspector.conf'}
- name: "Inspector - Explicitly permit TCP/5050 for ironic-inspector callback"
command: iptables -I INPUT -p tcp --dport 5050 -i {{network_interface}} -j ACCEPT
- name: "Inspector - (re)starting ironic-inspector service"
service:
name=ironic-inspector
state=restarted

View File

@ -176,3 +176,10 @@
insertafter="[ilo]"
regexp='^(.*)use_web_server_for_images=(.*)$'
line="use_web_server_for_images=true"
- name: "Enable Inspector"
lineinfile:
dest=/etc/ironic/ironic.conf
insertafter="[inspector]"
regexp='(^#|^)enabled( |)=(.*)$'
line="enabled = True"
when: enable_inspector | bool

View File

@ -138,10 +138,13 @@
- name: "Create authorized_keys file for ironic user"
command: cp -p /home/ironic/.ssh/id_rsa.pub /home/ironic/.ssh/authorized_keys
when: testing == true
- name: "Install ironic-inspector to permit use of inspection interface"
include: inspector_install.yml
when: enable_inspector | bool
- name: "Get ironic-api & ironic-conductor install location"
shell: echo $(dirname $(which ironic-api))
register: ironic_install_prefix
- name: "Place services"
- name: "Place ironic services"
template: src={{ init_template }} dest={{ init_dest_dir }}{{item.service_name}}{{ init_ext }} owner=root group=root
with_items:
- { service_path: "{{ ironic_install_prefix.stdout }}", service_name: 'ironic-api', username: 'ironic', args: '--config-file /etc/ironic/ironic.conf'}

View File

@ -0,0 +1,10 @@
#!ipxe
dhcp
goto introspect
:introspect
kernel http://{{ hostvars[inventory_hostname]['ansible_' + network_interface]['ipv4']['address'] }}:{{ nginx_port }}/ipa.vmlinuz ipa-inspection-callback-url=http://{{ hostvars[inventory_hostname]['ansible_' + network_interface]['ipv4']['address'] }}:5050/v1/continue systemd.journald.forward_to_console=yes ip=${ip}:${next-server}:${gateway}:${netmask} BOOTIF=${mac} nofb nomodeset vga=normal console=ttyS0
initrd http://{{ hostvars[inventory_hostname]['ansible_' + network_interface]['ipv4']['address'] }}:{{ nginx_port }}/ipa.initramfs
boot

View File

@ -0,0 +1,37 @@
{#
# Note(TheJulia): This file is based upon the file format provided by the git
# committed example located at:
# http://git.openstack.org/cgit/openstack/ironic-inspector/tree/example.conf
#}
[DEFAULT]
auth_strategy = {{ inspector_auth }}
debug = {{ inspector_debug | bool }}
[database]
connection=sqlite:///{{ inspector_data_dir }}/inspector.sqlite
[firewall]
manage_firewall = {{ inspector_manage_firewall | bool }}
[ironic]
auth_strategy = {{ ironic_auth_strategy }}
{#
# Note(TheJulia) preserving ironic_url in the configuration
# in case future changes allow breaking of the deployment across
# multiple nodes.
#ironic_url = http://localhost:6385/
#}
[processing]
add_ports = {{ inspector_port_addition | default('pxe') }}
keep_ports = {{ inspector_keep_ports | default('present') }}
ramdisk_logs_dir = {{ inspector_data_dir }}/log
always_store_ramdisk_logs = {{ inspector_store_ramdisk_logs | default('true') | bool }}
{#
# Note(TheJulia): Preserving node_not_found_hook for potential future
# use by bifrost.
# The name of the hook to run when inspector receives inspection
# information from a node it isn't already aware of. This hook is
# ignored by default. (string value)
#node_not_found_hook = <None>
#}

View File

@ -43,7 +43,13 @@ export BIFROST_INVENTORY_SOURCE=/tmp/baremetal.csv
# interfaces file out to the configuration drive as cirros does
# not support the network_info.json format file placed in the
# configuration drive.
ansible-playbook -vvvv -i inventory/bifrost_inventory.py test-bifrost-dynamic.yaml -e use_cirros=true -e testing_user=cirros -e write_interfaces_file=true
ansible-playbook -vvvv \
-i inventory/bifrost_inventory.py \
test-bifrost-dynamic.yaml \
-e use_cirros=true \
-e testing_user=cirros \
-e write_interfaces_file=true \
-e enable_inspector=true
EXITCODE=$?
if [ $EXITCODE != 0 ]; then