diff options
author | Gonéri Le Bouder <goneri@lebouder.net> | 2019-12-20 13:45:17 -0500 |
---|---|---|
committer | Daniel Watkins <oddbloke@ubuntu.com> | 2019-12-20 13:45:17 -0500 |
commit | 9bfb2ba7268e2c3c932023fc3d3020cdc6d6cc18 (patch) | |
tree | e2370783dd4e86e7abfa8167fc8b254ad48918b5 /cloudinit/net/__init__.py | |
parent | 87f2cb0acc7e802f93fa71ff3432dfd6708717ca (diff) | |
download | vyos-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__.py | 66 |
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.""" |