write_redhat_interfaces: pass multiple networks to output functions

This is a follow-on to I0aac3674fd17ff2bfcf3542e27097e171036c837

Prior to this we are walking the list of networks and setting them up
one-by-one.  As noted in the prior change, this fails when two
networks refer to the same interface (such as configuring ipv4 &
ipv6).

This builds a dict of interface -> [networks] mapping.  For the most
part, interfaces will only have one entry in their networks.  However,
some will have ipv4 & ipv6.

For now, we filter out the ipv6 networks; this will be addressed in a
follow-on.  This means we are effectively keeping the status-quo;
which is to ignore ipv6.  This change is intended to have no
operational changes.

Change-Id: I7eb3a4e33ae1d924a46e85035ac283a6755a74a4
This commit is contained in:
Ian Wienand 2022-05-25 14:47:29 +10:00
parent 035c808c12
commit cecc4b6658
1 changed files with 27 additions and 5 deletions

View File

@ -26,6 +26,7 @@ import subprocess
import sys
import time
from collections import defaultdict
from glean._vendor import distro
from glean import install
from glean import systemlock
@ -288,10 +289,9 @@ def write_redhat_interfaces(interfaces, sys_interfaces, args):
interfaces = _interfaces
# Sort the interfaces by id so that we'll have consistent output order
_interfaces_by_sys_name = defaultdict(list)
for iname, interface in sorted(
interfaces.items(), key=lambda x: x[1]['id']):
if interface['type'] == 'ipv6':
continue
if 'vlan_id' in interface:
# raw_macs will have a single entry if the vlan device is a
@ -311,15 +311,37 @@ def write_redhat_interfaces(interfaces, sys_interfaces, args):
else:
interface_name = sys_interfaces[interface['mac_address']]
# This is a dict that lists the networks associated with a
# device; so like:
# _interfaces_by_sys_name['eth0'] = [
# <ipv4_interface>, <ipv6_interface>
# ]
_interfaces_by_sys_name[interface_name].append(interface)
for _name, _interfaces in _interfaces_by_sys_name.items():
# NOTE(ianw) 2022-05-25 : this is all *terrible* and should
# definitely be refactored. "interfaces" is a really bad term
# used everywhere here. It's actually the "networks" key of
# the configdrive metadata. We stick to the term to avoid
# even more confusion.
# remove ipv6; we don't support them (yet). There should only
# be one set of network setup details after ipv6 is removed.
if len(_interfaces) > 1:
_interfaces = [
x for x in _interfaces if not x['type'].startswith('ipv6')]
assert(len(_interfaces) == 1)
interface = _interfaces[0]
logging.debug("Processing : %s -> %s" % (_name, interface))
if interface['type'] == 'ipv4':
files_to_write.update(
_write_rh_interface(interface_name, interface, args))
_write_rh_interface(_name, interface, args))
if interface['type'] == 'ipv4_dhcp':
files_to_write.update(
_write_rh_dhcp(interface_name, interface, args))
_write_rh_dhcp(_name, interface, args))
if interface['type'] == 'manual':
files_to_write.update(
_write_rh_manual(interface_name, interface, args))
_write_rh_manual(_name, interface, args))
if args.no_dhcp_fallback:
log.debug('DHCP fallback disabled')