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:
parent
0283f26ace
commit
ea49c1d932
|
@ -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")
|
||||
|
|
|
@ -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.</small></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"><small>pxe warning</small></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.</small></property>
|
|||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
|
@ -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"><small>Failed to find a suitable default network.</small></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>
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue