undercloud_and_charm_setup: Add support for LXD.

This adds basic LXD support that allows adding second NIC to
instances hosting networking charms as well as populating said
charms configuration with the second NIC MAC address.

Signed-off-by: Frode Nordahl <fnordahl@ubuntu.com>
This commit is contained in:
Frode Nordahl
2024-10-11 22:52:18 +02:00
parent 115c4e7e6c
commit a5ad00acf1
3 changed files with 75 additions and 1 deletions
@@ -66,6 +66,7 @@ DEFAULT_UNDERCLOUD_NETWORK_CONFIG = {
"external_dns": "10.5.0.2",
"external_net_cidr": "10.5.0.0/16",
"default_gateway": "10.5.0.1",
"lxd_network_name": "second",
}
# For Neutron Dynamic Tests it is useful to avoid relying on the directly
@@ -116,6 +117,12 @@ def undercloud_and_charm_setup(limit_gws=None):
# Perform charm based OVS configuration
openstack_utils.configure_charmed_openstack_on_maas(
network_config, limit_gws=limit_gws)
elif provider_type == "lxd" or provider_type is None:
# NOTE(fnordahl): When juju is bootstrapped towards the special
# `localhost` LXD cloud, get_provider_type() has no `clouds.yaml` to
# inspect and returns None.
openstack_utils.configure_charmed_openstack_on_lxd(
network_config, limit_gws=limit_gws)
else:
logging.warning('Unknown Juju provider type, "{}", will not perform'
' charm network configuration.'
+3 -1
View File
@@ -190,6 +190,7 @@ def get_undercloud_env_vars():
_vars['external_dns'] = os.environ.get('TEST_NAME_SERVER')
_vars['default_gateway'] = os.environ.get('TEST_GATEWAY')
_vars['external_net_cidr'] = os.environ.get('TEST_CIDR_EXT')
_vars['lxd_network_name'] = os.environ.get('TEST_LXD_NETWORK_NAME')
# Take FIP_RANGE and create start and end floating ips
_fip_range = os.environ.get('TEST_FIP_RANGE')
@@ -205,7 +206,8 @@ def get_undercloud_env_vars():
'start_floating_ip',
'end_floating_ip',
'external_dns',
'external_net_cidr']
'external_net_cidr',
'lxd_network_name']
for _key in _keys:
_val = os.environ.get(_key)
if _val:
+65
View File
@@ -25,6 +25,7 @@ import itertools
import json
import juju_wait
import logging
import netaddr
import os
import paramiko
import pathlib
@@ -1169,6 +1170,70 @@ def configure_charmed_openstack_on_maas(network_config, limit_gws=None):
networking_data, macs, use_juju_wait=False)
def lxd_maybe_add_nic(instance, ifname, network):
"""Add NIC to instance.
:param instance: Name of instance.
:type instance: str
:param ifname: Name of interface inside instance, note that name is only
preserved in containers, interfaces in virtual machines are
subject to udev rules inside the instance.
:type: ifname: str
:param network: Name of network.
:type network: str
"""
try:
subprocess.check_call([
"lxc", "config", "device", "add", instance,
ifname, "nic", "name={}".format(ifname),
"network={}".format(network)])
except subprocess.CalledProcessError:
logging.info("Unable to add device {} to {}, already added?"
.format(ifname, instance))
def lxd_get_nic_hwaddr(instance, device_name):
"""Add NIC to instance.
:param instance: Name of instance.
:type instance: str
:param device_name: Name of device config.
:type device_name: str
:rtype: netaddr.EUI
:raises: netaddr.core.AddrFormatError in the event nic does not exist.
"""
# lxc config get succeeds even for non-existing keys.
output = subprocess.check_output([
"lxc", "config", "get", instance,
"volatile.{}.hwaddr".format(device_name)],
universal_newlines=True)
mac = netaddr.EUI(output)
mac.dialect = netaddr.mac_unix_expanded
return mac
def configure_charmed_openstack_on_lxd(network_config, limit_gws=None):
"""Configure networking charms for charm-based OVS config on LXD provider.
:param network_config: Network configuration as provided in environment.
:type network_config: Dict[str]
:param limit_gws: Limit the number of gateways that get a port attached
:type limit_gws: Optional[int]
"""
networking_data = get_charm_networking_data(limit_gws=limit_gws)
ifname = "eth1"
macs = []
for instance in networking_data.unit_machine_ids:
lxd_maybe_add_nic(instance, ifname,
network_config.get("lxd_network_name"))
macs.append(str(lxd_get_nic_hwaddr(instance, ifname)))
if macs:
configure_networking_charms(
networking_data, macs, use_juju_wait=False)
@tenacity.retry(wait=tenacity.wait_exponential(multiplier=1, max=60),
reraise=True, retry=tenacity.retry_if_exception_type(KeyError))
def get_mac_from_port(port, neutronclient):