netlist: Rework the 'no network' case

Always force a network selection. If we have to fall back to
manual bridge UI because nothing else exists, show a warning.

Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
Cole Robinson 2020-08-24 14:10:49 -04:00
parent 0283f26ace
commit ea49c1d932
5 changed files with 78 additions and 103 deletions

View File

@ -762,7 +762,10 @@ class NewVM(uiutils.UITestCase):
self.forward(newvm)
combo = newvm.find(None, "combo box", "Network source:")
# For some reason atspi reports the internal combo value
assert combo.name == ''
assert combo.name == 'bridge'
warnlabel = newvm.find_fuzzy("suitable default network", "label")
assert warnlabel.onscreen
newvm.find("Device name:", "text").text = "foobr0"
newvm.find_fuzzy("Finish", "button").click()
self.app.root.find_fuzzy("vm1 on", "frame")

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<!-- Generated with glade 3.36.0 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<object class="GtkAdjustment" id="adjustment2">
@ -25,9 +25,6 @@
<property name="resizable">False</property>
<property name="type_hint">dialog</property>
<signal name="delete-event" handler="on_vmm_newcreate_delete_event" swapped="no"/>
<child type="titlebar">
<placeholder/>
</child>
<child>
<object class="GtkBox" id="vbox1">
<property name="visible">True</property>
@ -2347,42 +2344,6 @@ connections is not yet supported.&lt;/small&gt;</property>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="netdev-warn-box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-dialog-warning</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="netdev-warn-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">&lt;small&gt;pxe warning&lt;/small&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
@ -2522,5 +2483,8 @@ connections is not yet supported.&lt;/small&gt;</property>
</child>
</object>
</child>
<child type="titlebar">
<placeholder/>
</child>
</object>
</interface>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<!-- Generated with glade 3.36.0 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<object class="GtkGrid" id="net-source-box">
@ -19,7 +19,7 @@
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
@ -32,7 +32,7 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
@ -73,22 +73,34 @@
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="top_attach">3</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box2">
<object class="GtkComboBox" id="net-source">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">False</property>
<signal name="changed" handler="on_net_source_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="net-default-warn-box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkComboBox" id="net-source">
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">False</property>
<signal name="changed" handler="on_net_source_changed" swapped="no"/>
<property name="stock">gtk-dialog-warning</property>
</object>
<packing>
<property name="expand">False</property>
@ -97,10 +109,14 @@
</packing>
</child>
<child>
<object class="GtkImage" id="net-source-warn">
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-dialog-warning</property>
<property name="halign">start</property>
<property name="label" translatable="yes">&lt;small&gt;Failed to find a suitable default network.&lt;/small&gt;</property>
<property name="use_markup">True</property>
<property name="wrap">True</property>
<property name="max_width_chars">35</property>
</object>
<packing>
<property name="expand">False</property>

View File

@ -1260,23 +1260,11 @@ class vmmCreateVM(vmmGObjectUI):
def _netdev_changed(self, ignore):
ntype = self._netlist.get_network_selection()[0]
expand = (ntype != "network" and ntype != "bridge")
no_network = ntype is None
ignore, nsource, ignore = self._netlist.get_network_selection()
expand = not nsource
if expand:
self.widget("advanced-expander").set_expanded(True)
self.widget("netdev-warn-box").set_visible(False)
def _show_netdev_warn(msg):
self.widget("advanced-expander").set_expanded(True)
self.widget("netdev-warn-box").set_visible(True)
self.widget("netdev-warn-label").set_markup(
"<small>%s</small>" % msg)
if no_network:
_show_netdev_warn(_("No network selected"))
# Enable/Disable container source URL entry on checkbox click
def _container_source_toggle(self, ignore):
@ -1741,9 +1729,9 @@ class vmmCreateVM(vmmGObjectUI):
self.conn.get_backend())
net = self._netlist.build_device(macaddr)
if net:
self._netlist.validate_device(net)
self._gdata.interface = net
self._netlist.validate_device(net)
self._gdata.interface = net
return True

View File

@ -140,46 +140,52 @@ class vmmNetworkList(vmmGObjectUI):
_nettype = virtinst.DeviceInterface.TYPE_BRIDGE
_label = _("Bridge device...")
model.append(_build_manual_row(_nettype, _label))
return len(model) - 1
def _add_manual_macvtap_row():
_label = _("Macvtap device...")
_nettype = virtinst.DeviceInterface.TYPE_DIRECT
model.append(_build_manual_row(_nettype, _label))
vnets = self._find_virtual_networks()
default_bridge = virtinst.DeviceInterface.default_bridge(
self.conn.get_backend())
add_usermode = False
if self.conn.is_qemu_unprivileged():
log.debug("Using unprivileged qemu, adding usermode net")
vnets = []
default_bridge = None
add_usermode = True
if add_usermode:
nettype = virtinst.DeviceInterface.TYPE_USER
label = _pretty_network_desc(nettype)
model.append(_build_row(nettype, None, label, True))
_add_manual_bridge_row()
return
vnets = self._find_virtual_networks()
defaultnetidx = None
for row in sorted(vnets, key=lambda r: r[NET_ROW_LABEL]):
model.append(row)
if not len(model):
row = _build_label_row(_("No networking"), True)
model.insert(0, row)
if row[NET_ROW_SOURCE] == "default":
defaultnetidx = len(model) - 1
_add_manual_bridge_row()
bridgeidx = _add_manual_bridge_row()
_add_manual_macvtap_row()
# If there is a bridge device, default to that
if default_bridge:
self.widget("net-manual-source").set_text(default_bridge)
return bridgeidx
# If not, use 'default' network
if defaultnetidx is not None:
return defaultnetidx
# If not present, use first list entry
default_bridge = virtinst.DeviceInterface.default_bridge(
self.conn.get_backend())
for idx, row in enumerate(model):
nettype = row[NET_ROW_TYPE]
source = row[NET_ROW_SOURCE]
is_bridge = nettype == virtinst.DeviceInterface.TYPE_BRIDGE
is_network = nettype == virtinst.DeviceInterface.TYPE_VIRTUAL
if default_bridge:
if is_bridge and source == default_bridge:
return idx
elif is_network and source == "default":
return idx
if bridgeidx == 0:
# This means we are defaulting to something that
# requires manual intervention. Raise the warning
self.widget("net-default-warn-box").show()
return 0
def _check_network_is_running(self, net):
@ -203,13 +209,13 @@ class vmmNetworkList(vmmGObjectUI):
"Would you like to start the network "
"now?") % devname)
if not res:
return
return # pragma: no cover
# Try to start the network
try:
netobj.start()
log.debug("Started network '%s'", devname)
except Exception as e:
except Exception as e: # pragma: no cover
return self.err.show_err(
_("Could not start virtual network '%(device)s': %(error)s") % {
"device": devname,
@ -217,6 +223,11 @@ class vmmNetworkList(vmmGObjectUI):
})
def _find_rowiter_for_dev(self, net):
"""
Find the row in our current model that matches the passed in
net device (like populating the details UI for an existing VM).
If we don't find a match, we fake it a bit
"""
nettype = net.type
source = net.source
if net.network:
@ -227,6 +238,7 @@ class vmmNetworkList(vmmGObjectUI):
source = net.network
nettype = "network"
combo = self.widget("net-source")
def _find_row(_nettype, _source, _manual):
for row in combo.get_model():
if _nettype and row[NET_ROW_TYPE] != _nettype:
@ -238,7 +250,6 @@ class vmmNetworkList(vmmGObjectUI):
return row.iter
# Find the matching row in the net list
combo = self.widget("net-source")
rowiter = _find_row(nettype, source, None)
if rowiter:
return rowiter
@ -269,9 +280,6 @@ class vmmNetworkList(vmmGObjectUI):
def get_network_selection(self):
row = self._get_network_row()
if not row:
return None, None, None
net_type = row[NET_ROW_TYPE]
net_src = row[NET_ROW_SOURCE]
net_check_manual = row[NET_ROW_MANUAL]
@ -289,8 +297,6 @@ class vmmNetworkList(vmmGObjectUI):
def build_device(self, macaddr, model=None):
nettype, devname, mode = self.get_network_selection()
if nettype is None:
return None
net = virtinst.DeviceInterface(self.conn.get_backend())
net.type = nettype
@ -307,11 +313,9 @@ class vmmNetworkList(vmmGObjectUI):
net.validate()
def reset_state(self):
self._repopulate_network_list()
self.widget("net-source-warn").set_visible(False)
self.widget("net-source-warn").set_tooltip_text("")
self.widget("net-default-warn-box").set_visible(False)
self.widget("net-manual-source").set_text("")
self._repopulate_network_list()
def set_dev(self, net):
self.reset_state()
@ -364,7 +368,7 @@ class vmmNetworkList(vmmGObjectUI):
self._emit_changed()
row = self._get_network_row()
if not row:
return
return # pragma: no cover
nettype = row[NET_ROW_TYPE]
is_direct = (nettype == virtinst.DeviceInterface.TYPE_DIRECT)