diff --git a/.gitignore b/.gitignore index 4e1528d..59f9c28 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,8 @@ .* # Ansible retry files *.retry -# Tenks allocations file -allocations.yml +# Tenks state file +state.yml # Tenks Galaxy roles ansible/roles/stackhpc.* diff --git a/ansible/action_plugins/tenks_update_state.py b/ansible/action_plugins/tenks_update_state.py index 0a531ed..8c1e162 100644 --- a/ansible/action_plugins/tenks_update_state.py +++ b/ansible/action_plugins/tenks_update_state.py @@ -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): """ diff --git a/ansible/host_setup.yml b/ansible/host_setup.yml index 2543b7a..398108e 100644 --- a/ansible/host_setup.yml +++ b/ansible/host_setup.yml @@ -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 diff --git a/ansible/hypervisor_setup.yml b/ansible/hypervisor_setup.yml index 6c3d109..df91025 100644 --- a/ansible/hypervisor_setup.yml +++ b/ansible/hypervisor_setup.yml @@ -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 diff --git a/ansible/node_bmc.yml b/ansible/node_bmc.yml index 063f614..3627e77 100644 --- a/ansible/node_bmc.yml +++ b/ansible/node_bmc.yml @@ -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: diff --git a/ansible/node_enrolment.yml b/ansible/node_enrolment.yml index d95591e..82902c1 100644 --- a/ansible/node_enrolment.yml +++ b/ansible/node_enrolment.yml @@ -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 diff --git a/ansible/node_instantiation.yml b/ansible/node_instantiation.yml index a919e3c..404e759 100644 --- a/ansible/node_instantiation.yml +++ b/ansible/node_instantiation.yml @@ -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 diff --git a/ansible/node_networking.yml b/ansible/node_networking.yml index 9dd88f7..7eafba3 100644 --- a/ansible/node_networking.yml +++ b/ansible/node_networking.yml @@ -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 diff --git a/ansible/roles/ironic-enrolment/tasks/node.yml b/ansible/roles/ironic-enrolment/tasks/node.yml index 8cf7850..6318ca6 100644 --- a/ansible/roles/ironic-enrolment/tasks/node.yml +++ b/ansible/roles/ironic-enrolment/tasks/node.yml @@ -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 }}" diff --git a/ansible/roles/ironic-enrolment/tasks/port.yml b/ansible/roles/ironic-enrolment/tasks/port.yml index b6d036d..acbfea2 100644 --- a/ansible/roles/ironic-enrolment/tasks/port.yml +++ b/ansible/roles/ironic-enrolment/tasks/port.yml @@ -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) }}' diff --git a/ansible/schedule.yml b/ansible/schedule.yml index 07b99d9..9507e19 100644 --- a/ansible/schedule.yml +++ b/ansible/schedule.yml @@ -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: