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
*.retry
# Tenks allocations file
allocations.yml
# Tenks state file
state.yml
# Tenks Galaxy roles
ansible/roles/stackhpc.*

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,7 +10,8 @@
- name: Get physical network name
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
set_fact:
@ -26,4 +27,4 @@
].macaddress }}'
--local-link-connection switch_info='{{ bridge }}'
--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:
file: "{{ state_file_path }}"
name: current_state
when: stat_result.exists
when: stat_result.stat.exists
- name: Get updated state
tenks_update_state: