Skip to content

Commit

Permalink
undercloud_and_charm_setup: Add support for LXD.
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
fnordahl committed Oct 11, 2024
1 parent 115c4e7 commit c48d750
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
4 changes: 4 additions & 0 deletions zaza/openstack/charm_tests/neutron/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"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
Expand Down Expand Up @@ -116,6 +117,9 @@ 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":
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.'
Expand Down
4 changes: 3 additions & 1 deletion zaza/openstack/utilities/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -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:
Expand Down
65 changes: 65 additions & 0 deletions zaza/openstack/utilities/openstack.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import json
import juju_wait
import logging
import netaddr
import os
import paramiko
import pathlib
Expand Down Expand Up @@ -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):
Expand Down

0 comments on commit c48d750

Please sign in to comment.