From c1f9beac6358efd70a4197f57f71ef98499fa7d6 Mon Sep 17 00:00:00 2001 From: Julia Kreger Date: Thu, 1 Oct 2015 10:45:23 -0400 Subject: [PATCH] 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 --- .../roles/bifrost-ironic-install/README.md | 45 ++++++++++ .../bifrost-ironic-install/defaults/main.yml | 14 +++ .../bifrost-ironic-install/files/boot.ipxe | 5 +- .../tasks/create_tftpboot.yml | 8 ++ .../tasks/inspector_install.yml | 86 +++++++++++++++++++ .../tasks/ironic_config.yml | 7 ++ .../bifrost-ironic-install/tasks/main.yml | 5 +- .../templates/inspector-default-boot-ipxe.j2 | 10 +++ .../templates/ironic-inspector.conf.j2 | 37 ++++++++ scripts/test-bifrost.sh | 8 +- 10 files changed, 222 insertions(+), 3 deletions(-) create mode 100644 playbooks/roles/bifrost-ironic-install/tasks/inspector_install.yml create mode 100644 playbooks/roles/bifrost-ironic-install/templates/inspector-default-boot-ipxe.j2 create mode 100644 playbooks/roles/bifrost-ironic-install/templates/ironic-inspector.conf.j2 diff --git a/playbooks/roles/bifrost-ironic-install/README.md b/playbooks/roles/bifrost-ironic-install/README.md index a1292da14..981496ce6 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 721073af2..31107f901 100644 --- a/playbooks/roles/bifrost-ironic-install/tasks/ironic_config.yml +++ b/playbooks/roles/bifrost-ironic-install/tasks/ironic_config.yml @@ -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 diff --git a/playbooks/roles/bifrost-ironic-install/tasks/main.yml b/playbooks/roles/bifrost-ironic-install/tasks/main.yml index 9add31d33..5eed1f349 100644 --- a/playbooks/roles/bifrost-ironic-install/tasks/main.yml +++ b/playbooks/roles/bifrost-ironic-install/tasks/main.yml @@ -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'} 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