summaryrefslogtreecommitdiff
path: root/cloudinit/net/__init__.py
diff options
context:
space:
mode:
authorGonéri Le Bouder <goneri@lebouder.net>2019-12-20 13:45:17 -0500
committerDaniel Watkins <oddbloke@ubuntu.com>2019-12-20 13:45:17 -0500
commit9bfb2ba7268e2c3c932023fc3d3020cdc6d6cc18 (patch)
treee2370783dd4e86e7abfa8167fc8b254ad48918b5 /cloudinit/net/__init__.py
parent87f2cb0acc7e802f93fa71ff3432dfd6708717ca (diff)
downloadvyos-cloud-init-9bfb2ba7268e2c3c932023fc3d3020cdc6d6cc18.tar.gz
vyos-cloud-init-9bfb2ba7268e2c3c932023fc3d3020cdc6d6cc18.zip
freebsd: introduce the freebsd renderer (#61)
* freebsd: introduce the freebsd renderer Refactoring of the FreeBSD code base to provide a real network renderer for FreeBSD. Use the generic update_sysconfig_file() from rhel_util to handle the access to /etc/rc.conf. Interfaces are not automatically renamed by FreeBSD using the following configuration in /etc/rc.conf: ``` ifconfig_fxp0_name="eth0" ``` * freesd: use regex named groups Reduce the complexity of `get_interfaces_by_mac_on_freebsd()` with named groups. * freebsd: breaks up _write_network() in tree small functions - `_write_ifconfig_entries()` - `_write_route_entries()` - `_write_resolve_conf()` * extend find_fallback_nic() to support FreeBSD this uses `route -n show default` to find the default interface * freebsd: use dns keys from NetworkState class The NetworkState class (settings instance) exposes the DNS configuration in two keys: - `dns_nameservers` - `dns_searchdomains` On OpenStack, these keys are set when a global DNS server is set. The alternative is the `dns_nameservers` and `dns_search` keys from each subdomain. We continue to read those. * freebsd: properly target the /etc/resolv.conf file * freebsd: ignore 'service routing restart' ret code On FreeBSD 10, the restart of routing and dhclient is likely to fail because - routing: it cannot remove the loopback route, but it will still set up the default route as expected. - dhclient: it cannot stop the dhclient started by the netif service. In both case, the situation is ok, and we can proceed. * freebsd: handle case when metadata MAC local locally Handle the case where the metadata configuration comes with a MAC that does not exist locally. See: - https://github.com/canonical/cloud-init/pull/61/files/635ce14b3153934ba1041be48b7245062f21e960#r359600604 - https://github.com/canonical/cloud-init/pull/61/files/635ce14b3153934ba1041be48b7245062f21e960#r359600966 * freebsd: show up a warning if several subnet found The FreeBSD provider currently only allow one subnet per interface. * freebsd: honor the target parameter in _write_network * freebsd: log when a bad route is found * freebsd: pass _postcmds to start_services() * freebsd: updatercconf() is depercated Replace `updatercconf()` by `rhel_util.update_sysconfig_file()`. * freebsd: ensure gateway is ipv4 before using it With the legacy ENI format, an IPv6 gateway may be pushed. This instead of the expected IPv4. * freebsd: find_fallback_nic, support FB10 On FreeBSD <= 10, `ifconfig -l` ignores the down interfaces. * freebsd: use util.target_path() to load resolv.conf Ensure we access `/etc/resolv.conf`, not `etc/resolv.conf`. * freebsd: skip subnet without netmask Those are likely to be either invalid of in IPv6 format. IPv6 support will be addressed later in a new patchset. * freebsd: get_devicelist returns netif list Ensure `get_devicelist()` returns the list of known netif on FreeBSD. * replace rhel_util.update_sysconfig_file wrapper call, with a wrapper function * reverse if condition to remove an indent Co-authored-by: Igor Galić <me+github@igalic.co>
Diffstat (limited to 'cloudinit/net/__init__.py')
-rw-r--r--cloudinit/net/__init__.py66
1 files changed, 66 insertions, 0 deletions
diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
index bd806378..1d5eb535 100644
--- a/cloudinit/net/__init__.py
+++ b/cloudinit/net/__init__.py
@@ -307,6 +307,9 @@ def device_devid(devname):
def get_devicelist():
+ if util.is_FreeBSD():
+ return list(get_interfaces_by_mac().values())
+
try:
devs = os.listdir(get_sys_class_path())
except OSError as e:
@@ -329,6 +332,35 @@ def is_disabled_cfg(cfg):
def find_fallback_nic(blacklist_drivers=None):
"""Return the name of the 'fallback' network device."""
+ if util.is_FreeBSD():
+ return find_fallback_nic_on_freebsd(blacklist_drivers)
+ else:
+ return find_fallback_nic_on_linux(blacklist_drivers)
+
+
+def find_fallback_nic_on_freebsd(blacklist_drivers=None):
+ """Return the name of the 'fallback' network device on FreeBSD.
+
+ @param blacklist_drivers: currently ignored
+ @return default interface, or None
+
+
+ we'll use the first interface from ``ifconfig -l -u ether``
+ """
+ stdout, _stderr = util.subp(['ifconfig', '-l', '-u', 'ether'])
+ values = stdout.split()
+ if values:
+ return values[0]
+ # On FreeBSD <= 10, 'ifconfig -l' ignores the interfaces with DOWN
+ # status
+ values = list(get_interfaces_by_mac().values())
+ values.sort()
+ if values:
+ return values[0]
+
+
+def find_fallback_nic_on_linux(blacklist_drivers=None):
+ """Return the name of the 'fallback' network device on Linux."""
if not blacklist_drivers:
blacklist_drivers = []
@@ -765,6 +797,40 @@ def get_ib_interface_hwaddr(ifname, ethernet_format):
def get_interfaces_by_mac():
+ if util.is_FreeBSD():
+ return get_interfaces_by_mac_on_freebsd()
+ else:
+ return get_interfaces_by_mac_on_linux()
+
+
+def get_interfaces_by_mac_on_freebsd():
+ (out, _) = util.subp(['ifconfig', '-a', 'ether'])
+
+ # flatten each interface block in a single line
+ def flatten(out):
+ curr_block = ''
+ for l in out.split('\n'):
+ if l.startswith('\t'):
+ curr_block += l
+ else:
+ if curr_block:
+ yield curr_block
+ curr_block = l
+ yield curr_block
+
+ # looks for interface and mac in a list of flatten block
+ def find_mac(flat_list):
+ for block in flat_list:
+ m = re.search(
+ r"^(?P<ifname>\S*): .*ether\s(?P<mac>[\da-f:]{17}).*",
+ block)
+ if m:
+ yield (m.group('mac'), m.group('ifname'))
+ results = {mac: ifname for mac, ifname in find_mac(flatten(out))}
+ return results
+
+
+def get_interfaces_by_mac_on_linux():
"""Build a dictionary of tuples {mac: name}.
Bridges and any devices that have a 'stolen' mac are excluded."""