From b64f9adbc68737866f19dc8b23abbe56bc81cc30 Mon Sep 17 00:00:00 2001 From: Stig Telfer Date: Tue, 8 Oct 2024 12:58:04 +0000 Subject: [PATCH] Preserve assigned MAC on subsequent invocations Tenks/libvirt was not reusing the MAC address assigned when invoked repeatedly, which was leading to errors and confusion when extending an existing Tenks deployment. Check Ansible facts for a pre-existing interface and reuse the assigned MAC if one is found. Any existing MAC is added to the data structure returned by set_libvirt_interfaces. Change-Id: If45516d06d41992e7142ca8071ddcb84160a13e5 --- ansible/filter_plugins/tenks.py | 22 ++++++++++++++----- ...es-being-regenerated-36a90e18666a2dc0.yaml | 7 ++++++ 2 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 releasenotes/notes/fix-issue-mac-addresses-being-regenerated-36a90e18666a2dc0.yaml diff --git a/ansible/filter_plugins/tenks.py b/ansible/filter_plugins/tenks.py index 544272a..4020e63 100644 --- a/ansible/filter_plugins/tenks.py +++ b/ansible/filter_plugins/tenks.py @@ -68,6 +68,12 @@ def _get_hostvar(context, var_name, inventory_hostname=None): return namespace.get(var_name) +def _get_fact(context, fact_name): + if fact_name not in context['ansible_facts']: + raise AnsibleFilterError("Fact '%s' not found" % fact_name) + return context['ansible_facts'][fact_name] + + @pass_context def set_libvirt_interfaces(context, node): """Set interfaces for a node's specified physical networks. @@ -76,11 +82,17 @@ def set_libvirt_interfaces(context, node): for physnet in node.get('physical_networks', []): # Use macvtap 'passthrough' mode, since this does not filter packets # based on MAC address of the interface. - node['interfaces'].append( - {'type': 'direct', - 'source': {'dev': source_link_name(context, node, physnet), - 'mode': 'passthrough'}} - ) + if_name = source_link_name(context, node, physnet) + if_data = {'type': 'direct', + 'source': {'dev': if_name, 'mode': 'passthrough'}} + + # Check for an existing interface. If found, pull in the existing MAC. + if_var = if_name.replace('-', '_') + if_fact = _get_fact(context, if_var) + if if_fact: + if_data['mac'] = if_fact['macaddress'] + + node['interfaces'].append(if_data) return node diff --git a/releasenotes/notes/fix-issue-mac-addresses-being-regenerated-36a90e18666a2dc0.yaml b/releasenotes/notes/fix-issue-mac-addresses-being-regenerated-36a90e18666a2dc0.yaml new file mode 100644 index 0000000..10d571a --- /dev/null +++ b/releasenotes/notes/fix-issue-mac-addresses-being-regenerated-36a90e18666a2dc0.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fixes an issue where tenks was regenerating the MAC addresses for the + network interfaces used by the backing virtual machines on each run. This + would lead to a mismatch between the MAC address set on the baremetal port + in Ironic and the MAC address of the virtual machine's network interface.