diff --git a/playbooks/roles/bifrost-ironic-install/README.md b/playbooks/roles/bifrost-ironic-install/README.md index 34c97ea7a..492604e6f 100644 --- a/playbooks/roles/bifrost-ironic-install/README.md +++ b/playbooks/roles/bifrost-ironic-install/README.md @@ -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 ----- diff --git a/playbooks/roles/bifrost-ironic-install/defaults/main.yml b/playbooks/roles/bifrost-ironic-install/defaults/main.yml index 24c3df199..c9edfc9cc 100644 --- a/playbooks/roles/bifrost-ironic-install/defaults/main.yml +++ b/playbooks/roles/bifrost-ironic-install/defaults/main.yml @@ -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" diff --git a/playbooks/roles/bifrost-ironic-install/files/boot.ipxe b/playbooks/roles/bifrost-ironic-install/files/boot.ipxe index ce2e43054..7b52aa776 100644 --- a/playbooks/roles/bifrost-ironic-install/files/boot.ipxe +++ b/playbooks/roles/bifrost-ironic-install/files/boot.ipxe @@ -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} diff --git a/playbooks/roles/bifrost-ironic-install/tasks/create_tftpboot.yml b/playbooks/roles/bifrost-ironic-install/tasks/create_tftpboot.yml index 8a276ee45..8ec4c74f6 100644 --- a/playbooks/roles/bifrost-ironic-install/tasks/create_tftpboot.yml +++ b/playbooks/roles/bifrost-ironic-install/tasks/create_tftpboot.yml @@ -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 diff --git a/playbooks/roles/bifrost-ironic-install/tasks/inspector_install.yml b/playbooks/roles/bifrost-ironic-install/tasks/inspector_install.yml new file mode 100644 index 000000000..1de9970ca --- /dev/null +++ b/playbooks/roles/bifrost-ironic-install/tasks/inspector_install.yml @@ -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 diff --git a/playbooks/roles/bifrost-ironic-install/tasks/ironic_config.yml b/playbooks/roles/bifrost-ironic-install/tasks/ironic_config.yml index 724a8a4d0..d7edeb817 100644 --- a/playbooks/roles/bifrost-ironic-install/tasks/ironic_config.yml +++ b/playbooks/roles/bifrost-ironic-install/tasks/ironic_config.yml @@ -170,3 +170,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 diff --git a/playbooks/roles/bifrost-ironic-install/tasks/main.yml b/playbooks/roles/bifrost-ironic-install/tasks/main.yml index 70f259069..18655829f 100644 --- a/playbooks/roles/bifrost-ironic-install/tasks/main.yml +++ b/playbooks/roles/bifrost-ironic-install/tasks/main.yml @@ -136,10 +136,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'} diff --git a/playbooks/roles/bifrost-ironic-install/templates/inspector-default-boot-ipxe.j2 b/playbooks/roles/bifrost-ironic-install/templates/inspector-default-boot-ipxe.j2 new file mode 100644 index 000000000..c4bf731a1 --- /dev/null +++ b/playbooks/roles/bifrost-ironic-install/templates/inspector-default-boot-ipxe.j2 @@ -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 diff --git a/playbooks/roles/bifrost-ironic-install/templates/ironic-inspector.conf.j2 b/playbooks/roles/bifrost-ironic-install/templates/ironic-inspector.conf.j2 new file mode 100644 index 000000000..fb233d49d --- /dev/null +++ b/playbooks/roles/bifrost-ironic-install/templates/ironic-inspector.conf.j2 @@ -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 = +#} diff --git a/scripts/test-bifrost.sh b/scripts/test-bifrost.sh index bf2458d2e..ab42df8e2 100755 --- a/scripts/test-bifrost.sh +++ b/scripts/test-bifrost.sh @@ -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