Skip to content

Commit 9121fb8

Browse files
committed
feat: add ironic environment mixins
Introduce the `stack-ironic` environment mixin. This environment is intended to be used as an environment mixin that other environments depend upon. It implements configuration for the `Ironic` service such that hardware support for `idrac`, `ipmi` and `redfish`. - Drop in support for ironic configuration - Apply sensible tweaks to `ironic` services - Add playbook for adding port groups Signed-off-by: Jack Hodgkiss <jack@stackhpc.com>
1 parent 78b7409 commit 9121fb8

File tree

14 files changed

+379
-0
lines changed

14 files changed

+379
-0
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
---
2+
- name: Add Ironic Port Groups
3+
hosts: controllers[0]
4+
vars:
5+
venv: "{{ virtualenv_path }}/openstack-cli"
6+
tasks:
7+
- name: Set up openstack cli virtualenv
8+
pip:
9+
virtualenv: "{{ venv }}"
10+
name:
11+
- python-openstackclient
12+
- python-ironicclient
13+
state: latest
14+
virtualenv_command: "python3.{{ ansible_facts.python.version.minor }} -m venv"
15+
extra_args: "{% if pip_upper_constraints_file %}-c {{ pip_upper_constraints_file }}{% endif %}"
16+
17+
- name: Ensure Ironic port groups exist
18+
hosts: baremetal-compute-is-bonded
19+
gather_facts: false
20+
max_fail_percentage: >-
21+
{{ baremetal_compute_register_max_fail_percentage |
22+
default(baremetal_compute_max_fail_percentage) |
23+
default(kayobe_max_fail_percentage) |
24+
default(100) }}
25+
tags:
26+
- baremetal
27+
vars:
28+
venv: "{{ virtualenv_path }}/openstack-cli"
29+
controller_host: "{{ groups['controllers'][0] }}"
30+
tasks:
31+
- name: Check Ironic variables are defined
32+
ansible.builtin.assert:
33+
that:
34+
- ironic_bond_physical_network_name is defined
35+
- ironic_bond_mode is defined
36+
- ironic_bond_miimon is defined
37+
- ironic_bond_xmit_hash_policy is defined
38+
- ironic_bond_is_standalone_ports is defined
39+
fail_msg: One or more Ironic variables are undefined.
40+
41+
- block:
42+
- name: Show baremetal node
43+
ansible.builtin.command:
44+
cmd: "{{ venv }}/bin/openstack baremetal node show {{ inventory_hostname }} -f json"
45+
register: node_show
46+
failed_when:
47+
- '"HTTP 404" in node_show.stderr'
48+
- node_show.rc != 0
49+
changed_when: false
50+
51+
- name: Set baremetal_uuid fact
52+
ansible.builtin.set_fact:
53+
baremetal_uuid: "{{ (node_show.stdout | from_json).uuid }}"
54+
55+
- name: Get baremetal port
56+
ansible.builtin.command:
57+
cmd: "{{ venv }}/bin/openstack baremetal port list --long --node {{ baremetal_uuid }} -f json --sort-column Address"
58+
register: port_list
59+
changed_when: false
60+
61+
- name: Set port facts
62+
ansible.builtin.set_fact:
63+
baremetal_ports: "{{ baremetal_ports | default([]) + [item] }}"
64+
loop: "{{ port_list.stdout | from_json | community.general.json_query(_query) }}"
65+
vars:
66+
_query: "[?\"Physical Network\"=='{{ ironic_bond_physical_network_name }}'].{uuid: UUID, mac_address: Address, port_group: \"Portgroup UUID\"}"
67+
68+
- name: List existing port groups
69+
ansible.builtin.command:
70+
cmd: "{{ venv }}/bin/openstack baremetal port group list"
71+
register: existing_port_groups
72+
changed_when: false
73+
74+
- name: Create port group
75+
ansible.builtin.command:
76+
cmd: >
77+
{{ venv }}/bin/openstack baremetal port group create
78+
--node {{ baremetal_uuid }}
79+
--name {{ inventory_hostname }}
80+
--address {{ baremetal_ports[0].mac_address }}
81+
--mode {{ ironic_bond_mode }}
82+
--property miimon={{ ironic_bond_miimon }}
83+
--property xmit_hash_policy="{{ ironic_bond_xmit_hash_policy }}"
84+
{{ '--support-standalone-ports' if ironic_bond_is_standalone_ports | bool else '' }}
85+
register: create_port_group
86+
when:
87+
- "inventory_hostname not in existing_port_groups.stdout"
88+
- "baremetal_ports[0].mac_address not in existing_port_groups.stdout"
89+
changed_when:
90+
- create_port_group.rc == 0
91+
92+
- name: Show port group uuid
93+
ansible.builtin.command:
94+
cmd: "{{ venv }}/bin/openstack baremetal port group show {{ inventory_hostname }} -f value -c uuid"
95+
register: port_group_show
96+
changed_when: false
97+
98+
- name: Set port group uuid fact
99+
ansible.builtin.set_fact:
100+
port_group_uuid: "{{ port_group_show.stdout }}"
101+
102+
- block:
103+
- name: Enter maintenance mode
104+
ansible.builtin.command: |
105+
{{ venv }}/bin/openstack
106+
baremetal node maintenance set {{ inventory_hostname }}
107+
{{ '--reason ' + maintenance_reason | default('None', true) | quote }}
108+
vars:
109+
maintenance_reason: "Maintenance entered at {{ '%Y-%m-%d %H:%M:%S' | strftime() }} for port group association"
110+
111+
- name: Associate port group with ports
112+
ansible.builtin.command:
113+
cmd: "{{ venv }}/bin/openstack baremetal port set --port-group {{ port_group_uuid }} {{ item.uuid }}"
114+
register: associate_port_group
115+
loop: "{{ baremetal_ports }}"
116+
changed_when:
117+
- associate_port_group.rc == 0
118+
119+
- name: Exit maintenance mode
120+
ansible.builtin.command: |
121+
{{ venv }}/bin/openstack
122+
baremetal node maintenance unset {{ inventory_hostname }}
123+
when: >
124+
baremetal_ports | selectattr('port_group', 'undefined') | list | length > 0 or
125+
baremetal_ports | selectattr('port_group', 'none') | list | length > 0
126+
delegate_to: "{{ controller_host }}"
127+
vars:
128+
# NOTE: Without this, the controller's ansible_host variable will not
129+
# be respected when using delegate_to.
130+
ansible_host: "{{ hostvars[controller_host].ansible_host | default(controller_host) }}"
131+
environment: "{{ openstack_auth_env }}"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
###############################################################################
3+
# Ironic inspector processing configuration.
4+
5+
# List of of additional inspector processing plugins.
6+
inspector_processing_hooks_extra:
7+
- system_name_llc
8+
- system_name_physnet
9+
10+
# Which MAC addresses to add as ports during introspection. One of 'all',
11+
# 'active' or 'pxe'.
12+
inspector_add_ports: all
13+
14+
# Which ports to keep after introspection. One of 'all', 'present', or 'added'.
15+
inspector_keep_ports: added
16+
17+
# Whether to enable discovery of nodes not managed by Ironic.
18+
inspector_enable_discovery: false
19+
20+
# The Ironic driver with which to register newly discovered nodes.
21+
inspector_discovery_enroll_node_driver: redfish
22+
23+
###############################################################################
24+
# Inspection store configuration.
25+
# The inspection store provides a Swift-like service for storing inspection
26+
# data which may be useful in environments without Swift.
27+
28+
# Whether the inspection data store is enabled.
29+
inspector_store_enabled: false
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
ironic_properties:
3+
capabilities: "{{ ironic_capabilities }}"
4+
5+
ironic_capabilities: "boot_option:local,boot_mode:uefi"
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
ironic_driver: idrac
3+
4+
ironic_driver_info:
5+
redfish_address: "{{ ironic_redfish_address }}"
6+
redfish_username: "{{ ironic_redfish_username }}"
7+
redfish_password: "{{ ironic_redfish_password }}"
8+
redfish_verify_ca: "{{ ironic_redfish_verify_ca }}"
9+
10+
ironic_redfish_verify_ca: false
11+
ironic_redfish_address: "{{ redfish_address }}"
12+
ironic_redfish_username: "{{ secrets_idrac_baremetal_username }}"
13+
ironic_redfish_password: "{{ secrets_idrac_baremetal_password }}"
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
ironic_driver: ipmi
3+
4+
ironic_driver_info:
5+
ipmi_address: "{{ ironic_ipmi_address }}"
6+
ipmi_username: "{{ ironic_ipmi_username }}"
7+
ipmi_password: "{{ ironic_ipmi_password }}"
8+
ipmi_verify_ca: "{{ ironic_ipmi_verify_ca }}"
9+
10+
ironic_ipmi_verify_ca: false
11+
ironic_ipmi_address: "{{ ipmi_address }}"
12+
ironic_ipmi_username: "{{ secrets_ipmi_baremetal_username }}"
13+
ironic_ipmi_password: "{{ secrets_ipmi_baremetal_password }}"
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
ironic_driver: redfish
3+
4+
ironic_driver_info:
5+
redfish_address: "{{ ironic_redfish_address }}"
6+
redfish_username: "{{ ironic_redfish_username }}"
7+
redfish_password: "{{ ironic_redfish_password }}"
8+
redfish_verify_ca: "{{ ironic_redfish_verify_ca }}"
9+
10+
ironic_redfish_verify_ca: false
11+
ironic_redfish_address: "{{ redfish_address }}"
12+
ironic_redfish_username: "{{ secrets_redfish_baremetal_username }}"
13+
ironic_redfish_password: "{{ secrets_redfish_baremetal_password }}"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
# Use policy-based routing on the admin API network for ironic. This ensures
3+
# that during provisioning and cleaning, nodes accessing the admin API network
4+
# can be routed to without routing asymmetrically which would cause packets to be
5+
# dropped by the kernel.
6+
network_route_tables:
7+
- name: admin-api
8+
id: 1
9+
10+
# IP routing rule to process all packets from the admin API subnet using the
11+
# admin-api routing table.
12+
internal_rules:
13+
- from {{ internal_net_name | net_cidr }} table 1
14+
15+
# IP routes for the admin-api routing table.
16+
internal_routes:
17+
- cidr: "{{ internal_net_name | net_cidr }}"
18+
table: 1
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[baremetal-idrac]
2+
[baremetal-ipmi]
3+
[baremetal-redfish]
4+
5+
[baremetal-compute:children]
6+
baremetal-idrac
7+
baremetal-ipmi
8+
baremetal-redfish

etc/kayobe/environments/stack-ironic/inventory/hosts

Whitespace-only changes.
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
---
2+
###############################################################################
3+
# Ironic configuration.
4+
5+
# Specify the list of hardware types to load during service initialization.
6+
kolla_ironic_enabled_hardware_types:
7+
- idrac
8+
- ipmi
9+
- redfish
10+
11+
# Specify the list of bios interfaces to load during service initialization.
12+
kolla_ironic_enabled_bios_interfaces:
13+
- idrac-redfish
14+
- no-bios
15+
- redfish
16+
17+
# Default bios interface to be used for nodes that do not have bios_interface
18+
# field set.
19+
kolla_ironic_default_bios_interface:
20+
21+
# Specify the list of boot interfaces to load during service initialization.
22+
kolla_ironic_enabled_boot_interfaces:
23+
- idrac-redfish-virtual-media
24+
- ipxe
25+
- pxe
26+
- redfish-virtual-media
27+
28+
# Default boot interface to be used for nodes that do not have boot_interface
29+
# field set.
30+
kolla_ironic_default_boot_interface:
31+
32+
# Specify the list of console interfaces to load during service initialization.
33+
kolla_ironic_enabled_console_interfaces:
34+
- ipmitool-socat
35+
- no-console
36+
37+
# Default console interface to be used for nodes that do not have
38+
# console_interface field set.
39+
kolla_ironic_default_console_interface:
40+
41+
# Specify the list of deploy interfaces to load during service initialization.
42+
kolla_ironic_enabled_deploy_interfaces:
43+
- direct
44+
- ramdisk
45+
46+
# Default deploy interface to be used for nodes that do not have
47+
# deploy_interface field set.
48+
kolla_ironic_default_deploy_interface:
49+
50+
# Specify the list of inspect interfaces to load during service initialization.
51+
kolla_ironic_enabled_inspect_interfaces:
52+
- inspector
53+
- no-inspect
54+
55+
# Default inspect interface to be used for nodes that do not have
56+
# inspect_interface field set.
57+
kolla_ironic_default_inspect_interface:
58+
59+
# Specify the list of management interfaces to load during service
60+
# initialization.
61+
kolla_ironic_enabled_management_interfaces:
62+
- idrac-redfish
63+
- ipmitool
64+
- noop
65+
- redfish
66+
67+
# Default management interface to be used for nodes that do not have
68+
# management_interface field set.
69+
kolla_ironic_default_management_interface:
70+
71+
# Specify the list of network interfaces to load during service initialization.
72+
kolla_ironic_enabled_network_interfaces:
73+
- flat
74+
- neutron
75+
- noop
76+
77+
# Default network interface to be used for nodes that do not have
78+
# network_interface field set.
79+
kolla_ironic_default_network_interface:
80+
81+
# Specify the list of power interfaces to load during service initialization.
82+
kolla_ironic_enabled_power_interfaces:
83+
- idrac-redfish
84+
- ipmitool
85+
- redfish
86+
87+
# Default power interface to be used for nodes that do not have power_interface
88+
# field set.
89+
kolla_ironic_default_power_interface:
90+
91+
# Specify the list of raid interfaces to load during service initialization.
92+
kolla_ironic_enabled_raid_interfaces:
93+
- agent
94+
- idrac-redfish
95+
- no-raid
96+
- redfish
97+
98+
# Default raid interface to be used for nodes that do not have
99+
# raid_interface field set.
100+
kolla_ironic_default_raid_interface:
101+
102+
# Specify the list of rescue interfaces to load during service initialization.
103+
kolla_ironic_enabled_rescue_interfaces:
104+
- agent
105+
- no-rescue
106+
107+
# Default rescue interface to be used for nodes that do not have
108+
# rescue_interface field set.
109+
kolla_ironic_default_rescue_interface:
110+
111+
# Specify the list of storage interfaces to load during
112+
# service initialization.
113+
kolla_ironic_enabled_storage_interfaces:
114+
115+
# Default storage interface to be used for nodes that do not
116+
# have storage_interface field set.
117+
kolla_ironic_default_storage_interface:
118+
119+
# Specify the list of vendor interfaces to load during service initialization.
120+
kolla_ironic_enabled_vendor_interfaces:
121+
- no-vendor
122+
123+
# Default vendor interface to be used for nodes that do not have
124+
# vendor_interface field set.
125+
kolla_ironic_default_vendor_interface:
126+
127+
# Name of the Neutron network to use for cleaning.
128+
kolla_ironic_cleaning_network: "{{ kolla_ironic_provisioning_network if cleaning_net_name == provision_wl_net_name else 'cleaning-net' }}"
129+
130+
# Name of the Neutron network to use for provisioning.
131+
kolla_ironic_provisioning_network: 'provision-net'
132+
133+
# List of default kernel parameters to append for baremetal PXE boot.
134+
kolla_ironic_pxe_append_params_default:
135+
- nofb
136+
- nomodeset
137+
- vga=normal
138+
- console=tty0
139+
- console=ttyS0,115200n8
140+
- "ipa-ntp-server={{ provision_wl_net_name | net_ip(inventory_hostname=groups['controllers'][0]) }}"
141+
- "ipa-insecure=1"

0 commit comments

Comments
 (0)