Persist physnet indices in state file

Instead of overwriting the physnet mappings specified in the Tenks
configuration, create a separate dict that maps physnet names to their
indices. Like physnet_mappings, this will be present for each
hypervisor.
This commit is contained in:
Will Miller 2018-09-14 10:27:21 +00:00
parent da15c6f6e6
commit 99eaf48098
11 changed files with 37 additions and 37 deletions

4
.gitignore vendored
View File

@ -2,8 +2,8 @@
.* .*
# Ansible retry files # Ansible retry files
*.retry *.retry
# Tenks allocations file # Tenks state file
allocations.yml state.yml
# Tenks Galaxy roles # Tenks Galaxy roles
ansible/roles/stackhpc.* ansible/roles/stackhpc.*

View File

@ -52,48 +52,47 @@ class ActionModule(ActionBase):
self._validate_args(args) self._validate_args(args)
# Modify the state as necessary. # Modify the state as necessary.
self._map_physnets(args['state'], args['hypervisor_vars']) self._set_physnet_idxs(args['state'], args['hypervisor_vars'])
self._process_specs(task_vars['hostvars']['localhost'], args) self._process_specs(task_vars['hostvars']['localhost'], args)
# Return the modified state. # Return the modified state.
result['result'] = args['state'] result['result'] = args['state']
return result return result
def _map_physnets(self, state, hypervisor_vars): def _set_physnet_idxs(self, state, hypervisor_vars):
""" """
Set physnet mappings for each host. Set the index of each physnet for each host.
Use the specified physnet mappings and any existing physnet indices to Use the specified physnet mappings and any existing physnet indices to
ensure all physnet mappings exist in `state` with an index. ensure the generated indices are consistent.
""" """
for hostname, hostvars in six.iteritems(hypervisor_vars): for hostname, hostvars in six.iteritems(hypervisor_vars):
# The desired mappings given in the Tenks configuration. These do # The desired mappings given in the Tenks configuration. These do
# not include IDXs which are an implementation detail of Tenks. # not include IDXs which are an implementation detail of Tenks.
specified_mappings = hostvars['physnet_mappings'] specified_mappings = hostvars['physnet_mappings']
try: try:
# The mappings currently in the state file, including IDXs. # The physnet indices currently in the state file.
old_mappings = state[hostname]['physnet_mappings'] old_idxs = state[hostname]['physnet_indices']
except KeyError: except KeyError:
# The hypervisor is new since the last run. # The hypervisor is new since the last run.
state[hostname] = {} state[hostname] = {}
old_mappings = {} old_idxs = {}
# The new set of mappings to store as state. new_idxs = {}
new_mappings = {}
next_idx = 0 next_idx = 0
used_idxs = {pn['idx'] for pn in old_mappings.values()} used_idxs = old_idxs.values()
for name, dev in six.iteritems(specified_mappings): for name, dev in six.iteritems(specified_mappings):
try: try:
# We need to re-use the IDXs of any existing physnets. # We need to re-use the IDXs of any existing physnets.
idx = old_mappings[name]['idx'] idx = old_idxs[name]
except KeyError: except KeyError:
# New physnet requires a new IDX. # New physnet requires a new IDX.
while next_idx in used_idxs: while next_idx in used_idxs:
next_idx += 1 next_idx += 1
used_idxs.add(next_idx) used_idxs.append(next_idx)
idx = next_idx idx = next_idx
finally: finally:
new_mappings[name] = {'idx': idx, 'device': dev} new_idxs[name] = idx
state[hostname]['physnet_mappings'] = new_mappings state[hostname]['physnet_indices'] = new_idxs
def _process_specs(self, localhost_vars, args): def _process_specs(self, localhost_vars, args):
""" """
@ -115,8 +114,9 @@ class ActionModule(ActionBase):
# fulfil any spec. # fulfil any spec.
node['state'] = 'absent' node['state'] = 'absent'
# Now create all the required new nodes. if localhost_vars['cmd'] != 'teardown':
self._create_nodes(localhost_vars, args) # Now create all the required new nodes.
self._create_nodes(localhost_vars, args)
def _tick_off_node(self, specs, node): def _tick_off_node(self, specs, node):
""" """

View File

@ -4,12 +4,12 @@
- name: Load state from file - name: Load state from file
include_vars: include_vars:
file: "{{ state_file_path }}" file: "{{ state_file_path }}"
name: state name: tenks_state
- hosts: hypervisors - hosts: hypervisors
vars: vars:
indexed_physnet_mappings: >- physnet_indices: >-
{{ state[inventory_hostname].physnet_mappings }} {{ hostvars.localhost.tenks_state[inventory_hostname].physnet_indices }}
tasks: tasks:
- include_tasks: hypervisor_setup.yml - include_tasks: hypervisor_setup.yml

View File

@ -42,9 +42,9 @@
include_tasks: physical_network.yml include_tasks: physical_network.yml
vars: vars:
network_name: "{{ pn.key }}" network_name: "{{ pn.key }}"
tenks_bridge: "{{ bridge_prefix ~ pn.value.idx }}" tenks_bridge: "{{ bridge_prefix ~ (pn.key | physnet_name_to_index) }}"
source_interface: "{{ pn.value.device }}" source_interface: "{{ pn.value }}"
state: "{{ 'absent' if cmd == 'teardown' else 'present' }}" state: "{{ 'absent' if cmd == 'teardown' else 'present' }}"
loop: "{{ query('dict', indexed_physnet_mappings) }}" loop: "{{ query('dict', physnet_mappings) }}"
loop_control: loop_control:
loop_var: pn loop_var: pn

View File

@ -4,13 +4,13 @@
- name: Load state from file - name: Load state from file
include_vars: include_vars:
file: "{{ state_file_path }}" file: "{{ state_file_path }}"
name: state name: tenks_state
- name: Perform Virtual BMC configuration - name: Perform Virtual BMC configuration
hosts: libvirt hosts: libvirt
vars: vars:
vbmc_nodes: >- vbmc_nodes: >-
{{ hostvars.localhost.state[inventory_hostname].nodes {{ hostvars.localhost.tenks_state[inventory_hostname].nodes
| default([]) | selectattr('ironic_driver', 'eq', | default([]) | selectattr('ironic_driver', 'eq',
bmc_emulators.virtualbmc) | list }} bmc_emulators.virtualbmc) | list }}
tasks: tasks:

View File

@ -3,7 +3,7 @@
- name: Load state from file - name: Load state from file
include_vars: include_vars:
file: "{{ state_file_path }}" file: "{{ state_file_path }}"
name: state name: tenks_state
- name: Check that OpenStack credentials exist in the environment - name: Check that OpenStack credentials exist in the environment
fail: fail:
@ -30,6 +30,6 @@
ironic_virtualenv_path: "{{ virtualenv_path }}" ironic_virtualenv_path: "{{ virtualenv_path }}"
ironic_python_upper_constraints_url: >- ironic_python_upper_constraints_url: >-
{{ python_upper_constraints_url }} {{ python_upper_constraints_url }}
loop: "{{ query('dict', state) }}" loop: "{{ query('dict', tenks_state) }}"
loop_control: loop_control:
loop_var: alloc loop_var: alloc

View File

@ -4,12 +4,12 @@
- name: Load state from file - name: Load state from file
include_vars: include_vars:
file: "{{ state_file_path }}" file: "{{ state_file_path }}"
name: state name: tenks_state
- hosts: libvirt - hosts: libvirt
vars: vars:
nodes: >- nodes: >-
{{ hostvars.localhost.state[inventory_hostname].nodes {{ hostvars.localhost.tenks_state[inventory_hostname].nodes
| default([]) }} | default([]) }}
tasks: tasks:
- name: Configure VMs - name: Configure VMs

View File

@ -3,12 +3,12 @@
- name: Load state from file - name: Load state from file
include_vars: include_vars:
file: "{{ state_file_path }}" file: "{{ state_file_path }}"
name: state name: tenks_state
- hosts: hypervisors - hosts: hypervisors
vars: vars:
nodes: >- nodes: >-
{{ hostvars.localhost.state[inventory_hostname].nodes {{ hostvars.localhost.tenks_state[inventory_hostname].nodes
| default([]) }} | default([]) }}
tasks: tasks:
- name: Configure veth pairs for each node - name: Configure veth pairs for each node

View File

@ -40,8 +40,7 @@
- name: Configure node in Ironic - name: Configure node in Ironic
os_ironic: os_ironic:
auth_type: password auth_type: password
driver: >- driver: "{{ node.ironic_driver }}"
{{ node.ironic_config.ironic_driver | default(default_ironic_driver) }}
driver_info: driver_info:
power: power:
ipmi_address: "{{ hostvars[ironic_hypervisor].ipmi_address }}" ipmi_address: "{{ hostvars[ironic_hypervisor].ipmi_address }}"

View File

@ -10,7 +10,8 @@
- name: Get physical network name - name: Get physical network name
set_fact: set_fact:
physnet: "{{ source_interface | source_link_to_physnet_name }}" physnet: "{{ source_interface | source_link_to_physnet_name(
inventory_hostname=ironic_hypervisor) }}"
- name: Get bridge name - name: Get bridge name
set_fact: set_fact:
@ -26,4 +27,4 @@
].macaddress }}' ].macaddress }}'
--local-link-connection switch_info='{{ bridge }}' --local-link-connection switch_info='{{ bridge }}'
--local-link-connection port_id='{{ source_interface --local-link-connection port_id='{{ source_interface
| source_to_ovs_link_name }}' | source_to_ovs_link_name(inventory_hostname=ironic_hypervisor) }}'

View File

@ -30,7 +30,7 @@
include_vars: include_vars:
file: "{{ state_file_path }}" file: "{{ state_file_path }}"
name: current_state name: current_state
when: stat_result.exists when: stat_result.stat.exists
- name: Get updated state - name: Get updated state
tenks_update_state: tenks_update_state: