Skip to content

Commit

Permalink
Show virtual interface's TAP device
Browse files Browse the repository at this point in the history
Network interfaces that are attached to VMs have a TUN/TAP device. If
you want to check manually, e.g. why the device is not working
correctly, you need to know the interface name.
Name of the tap device is  be specified with attribute of the <target>
element. If no target dev is specified upon vnic attachement, libvirt
will create a new standard tap device with a name of the pattern "vnetN"
Shot this device in the list of VM's interfaces. In the future, we could
also allow user to choose/name a tap device during vNIC attachement.

Fixes #1047
  • Loading branch information
skobyda committed May 26, 2023
1 parent 62ef1fe commit 3503023
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 30 deletions.
75 changes: 58 additions & 17 deletions src/components/vm/nics/vmNicsCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button } from "@patternfly/react-core/dist/esm/components/Button";
import { DescriptionList, DescriptionListDescription, DescriptionListGroup, DescriptionListTerm } from "@patternfly/react-core/dist/esm/components/DescriptionList";
import { Flex, FlexItem } from "@patternfly/react-core/dist/esm/layouts/Flex";
import { Tooltip } from "@patternfly/react-core/dist/esm/components/Tooltip";
import { DialogsContext } from 'dialogs.jsx';
Expand Down Expand Up @@ -124,13 +125,46 @@ const NetworkSource = ({ network, networkId, vm, hostDevices }) => {
};
};

const singleSourceElem = source => checkDeviceAviability(source) ? <Button variant="link" isInline onClick={sourceJump(source)}>{source}</Button> : source;
const addressPortSourceElem = (source, networkId) => (<table id={`${id}-network-${networkId}-source`}>
<tbody>
<tr><td className='machines-network-source-descr'>{_("Address")}</td><td className='machines-network-source-value'>{source.address}</td></tr>
<tr><td className='machines-network-source-descr'>{_("Port")}</td><td className='machines-network-source-value'>{source.port}</td></tr>
</tbody>
</table>);
const singleSourceElem = source => {
let label = rephraseUI("networkType", network.type);
label = label.charAt(0).toUpperCase() + label.slice(1);

return (
<DescriptionListGroup>
<DescriptionListTerm>
{label}
</DescriptionListTerm>
<DescriptionListDescription>
<Flex spaceItems={{ default: 'spaceItemsSm' }} alignItems={{ default: 'alignItemsCenter' }} id={`${id}-network-${networkId}-source`}>
<FlexItem>
{checkDeviceAviability(source)
? <Button variant="link" isInline onClick={sourceJump(source)}>{source}</Button>
: source}
</FlexItem>
{needsShutdownIfaceSource(vm, network) && <NeedsShutdownTooltip iconId={`${id}-network-${networkId}-source-tooltip`} tooltipId="tip-network" />}
</Flex>
</DescriptionListDescription>
</DescriptionListGroup>
);
};
const addressPortSourceElem = source => (<>
<DescriptionListGroup>
<DescriptionListTerm>
{_("Address")}
</DescriptionListTerm>
<DescriptionListDescription id={`${id}-network-${networkId}-address`}>
{source.address}
</DescriptionListDescription>
</DescriptionListGroup>
<DescriptionListGroup>
<DescriptionListTerm>
{_("Port")}
</DescriptionListTerm>
<DescriptionListDescription id={`${id}-network-${networkId}-port`}>
{source.port}
</DescriptionListDescription>
</DescriptionListGroup>
</>);

const getSourceElem = {
direct: singleSourceElem,
Expand All @@ -142,16 +176,23 @@ const NetworkSource = ({ network, networkId, vm, hostDevices }) => {
udp: addressPortSourceElem,
};

if (getSourceElem[network.type] !== undefined) {
return (
<Flex spaceItems={{ default: 'spaceItemsSm' }} alignItems={{ default: 'alignItemsCenter' }} id={`${id}-network-${networkId}-source`}>
<FlexItem>{getSourceElem[network.type](getIfaceSourceName(network), networkId)}</FlexItem>
{needsShutdownIfaceSource(vm, network) && <NeedsShutdownTooltip iconId={`${id}-network-${networkId}-source-tooltip`} tooltipId="tip-network" />}
</Flex>
);
} else {
return null;
}
let source;
if (getSourceElem[network.type] !== undefined)
source = getSourceElem[network.type](getIfaceSourceName(network), networkId);

return (
<DescriptionList isHorizontal>
{source}
{network.target && <DescriptionListGroup>
<DescriptionListTerm>
{_("TAP device")}
</DescriptionListTerm>
<DescriptionListDescription id={`${id}-network-${networkId}-tapdevice`}>
{network.target}
</DescriptionListDescription>
</DescriptionListGroup>}
</DescriptionList>
);
};

export class VmNetworkTab extends React.Component {
Expand Down
11 changes: 0 additions & 11 deletions src/machines.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,6 @@
font-size: inherit;
}

.machines-network-source-descr {
color: var(--ct-color-subtle-copy);
text-align: right;
padding: 5px 10px !important;
}

.machines-network-source-value {
padding: 5px 10px !important;
text-align: left !important;
}

.machines-listing-actions {
display: flex;
justify-content: flex-end;
Expand Down
4 changes: 3 additions & 1 deletion test/check-machines-nics
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class TestMachinesNICs(VirtualMachinesCase):

b.wait_in_text("#vm-subVmTest1-network-1-type", "network")
b.wait_in_text("#vm-subVmTest1-network-1-source", "default")
b.wait_in_text("#vm-subVmTest1-network-1-tapdevice", "vnet0")
b.wait_in_text("#vm-subVmTest1-network-1-ipv4-address", "192.168.122.")
b.wait_in_text("#vm-subVmTest1-network-1-state", "up")
b.assert_pixels("#vm-subVmTest1-networks",
Expand All @@ -72,10 +73,11 @@ class TestMachinesNICs(VirtualMachinesCase):
self.deleteIface(1)

# Test add network
m.execute("virsh attach-interface --domain subVmTest1 --type network --source default --model virtio --mac 52:54:00:4b:73:5f --config --live")
m.execute("virsh attach-interface --domain subVmTest1 --type network --source default --target vnet1 --model virtio --mac 52:54:00:4b:73:5f --config --live")

b.wait_in_text("#vm-subVmTest1-network-1-type", "network")
b.wait_in_text("#vm-subVmTest1-network-1-source", "default")
b.wait_in_text("#vm-subVmTest1-network-1-tapdevice", "vnet1")
b.wait_in_text("#vm-subVmTest1-network-1-model", "virtio")
b.wait_in_text("#vm-subVmTest1-network-1-mac", "52:54:00:4b:73:5f")
b.wait_in_text("#vm-subVmTest1-network-1-ipv4-address", "192.168.122.")
Expand Down

0 comments on commit 3503023

Please sign in to comment.