Support removing VM interfaces by MAC

Provides a way to handle multiple interfaces in the same network
gracefully, while making the previous behaviour explicit.
This commit is contained in:
Joshua Boniface 2021-10-27 13:17:35 -04:00
parent dfca998adf
commit 3a6f442856
2 changed files with 33 additions and 9 deletions

View File

@ -813,9 +813,9 @@ def vm_networks_add(config, vm, network, macaddr, model, sriov, sriov_mode, live
return retcode, retmsg
def vm_networks_remove(config, vm, network, sriov, live, restart):
def vm_networks_remove(config, vm, network, macaddr, sriov, live, restart):
"""
Remove a network to the VM
Remove a network from the VM, optionally by MAC
Calls vm_info to get the VM XML.
@ -826,6 +826,9 @@ def vm_networks_remove(config, vm, network, sriov, live, restart):
from lxml.objectify import fromstring
from lxml.etree import tostring
if network is None and macaddr is None:
return False, "A network or MAC address must be specified for removal."
status, domain_information = vm_info(config, vm)
if not status:
return status, domain_information
@ -845,17 +848,26 @@ def vm_networks_remove(config, vm, network, sriov, live, restart):
if sriov:
if interface.attrib.get('type') == 'hostdev':
if_dev = str(interface.sriov_device)
if network == if_dev:
if macaddr is None and network == if_dev:
interface.getparent().remove(interface)
changed = True
elif macaddr is not None and macaddr == interface.mac.attrib.get('address'):
interface.getparent().remove(interface)
changed = True
elif interface.attrib.get('type') == 'direct':
if_dev = str(interface.source.attrib.get('dev'))
if network == if_dev:
if macaddr is None and network == if_dev:
interface.getparent().remove(interface)
changed = True
elif macaddr is not None and macaddr == interface.mac.attrib.get('address'):
interface.getparent().remove(interface)
changed = True
else:
if_vni = re.match(r'[vm]*br([0-9a-z]+)', interface.source.attrib.get('bridge')).group(1)
if network == if_vni:
if macaddr is None and network == if_vni:
interface.getparent().remove(interface)
changed = True
elif macaddr is not None and macaddr == interface.mac.attrib.get('address'):
interface.getparent().remove(interface)
changed = True
if changed:
@ -866,8 +878,12 @@ def vm_networks_remove(config, vm, network, sriov, live, restart):
new_xml = tostring(parsed_xml, pretty_print=True)
except Exception:
return False, 'ERROR: Failed to dump XML data.'
else:
elif not changed and network is not None:
return False, 'ERROR: Network "{}" does not exist on VM.'.format(network)
elif not changed and macaddr is not None:
return False, 'ERROR: Interface with MAC "{}" does not exist on VM.'.format(macaddr)
else:
return False, 'ERROR: Unspecified error finding interface to remove.'
modify_retcode, modify_retmsg = vm_modify(config, vm, new_xml, restart)

View File

@ -1541,7 +1541,11 @@ def vm_network_add(domain, net, macaddr, model, sriov_flag, sriov_mode, live_fla
'domain'
)
@click.argument(
'net'
'net', required=False, default=None
)
@click.option(
'-m', '--mac-address', 'macaddr', default=None,
help='Remove an interface with this MAC address; required if NET is unspecified.'
)
@click.option(
'-s', '--sriov', 'sriov_flag', is_flag=True, default=False,
@ -1561,11 +1565,15 @@ def vm_network_add(domain, net, macaddr, model, sriov_flag, sriov_mode, live_fla
help='Confirm the restart.'
)
@cluster_req
def vm_network_remove(domain, net, sriov_flag, live_flag, restart_flag, confirm_flag):
def vm_network_remove(domain, net, macaddr, sriov_flag, live_flag, restart_flag, confirm_flag):
"""
Remove the network NET from the virtual machine DOMAIN.
NET may be a PVC network VNI, which is added as a bridged device, or a SR-IOV VF device connected in the given mode.
NET is optional if the '-m'/'--mac-address' option is specified. If it is, then the specific device with that MAC address is removed instead.
If multiple interfaces are present on the VM in network NET, and '-m'/'--mac-address' is not specified, then all interfaces in that network will be removed.
"""
if restart_flag and live_flag:
click.echo('WARNING: Live flag and restart flag both specified; this can cause unintended behaviour. To disable live changes, use "--no-live".')
@ -1577,7 +1585,7 @@ def vm_network_remove(domain, net, sriov_flag, live_flag, restart_flag, confirm_
except Exception:
restart_flag = False
retcode, retmsg = pvc_vm.vm_networks_remove(config, domain, net, sriov_flag, live_flag, restart_flag)
retcode, retmsg = pvc_vm.vm_networks_remove(config, domain, net, macaddr, sriov_flag, live_flag, restart_flag)
cleanup(retcode, retmsg)