Break out shared network list UI to netlist.py

Use this to show vport stuff in addhw, give a warning about macvtap
networking, and allow macvtap from the create wizard.
This commit is contained in:
Cole Robinson 2014-01-27 16:58:45 -05:00
parent 53a57fcdd8
commit 169ae1203d
10 changed files with 1156 additions and 1195 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.0 on Sun Jan 12 16:48:36 2014 -->
<!-- Generated with glade 3.16.1 -->
<interface>
<!-- interface-requires gtk+ 3.0 -->
<requires lib="gtk+" version="3.0"/>
<object class="GtkAdjustment" id="adjustment1">
<property name="upper">67000</property>
<property name="step_increment">1</property>
@ -575,210 +575,166 @@
</packing>
</child>
<child>
<object class="GtkGrid" id="table31">
<object class="GtkBox" id="box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">9</property>
<property name="column_spacing">6</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkHBox" id="hbox2">
<object class="GtkGrid" id="table31">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<property name="row_spacing">9</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkCheckButton" id="mac-address">
<object class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0.5</property>
<property name="draw_indicator">True</property>
<signal name="clicked" handler="on_mac_address_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="create-mac-address">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="max_length">17</property>
<property name="invisible_char">●</property>
<property name="text" translatable="yes">aa:bb:cc:dd:ee:ff</property>
<child internal-child="accessible">
<object class="AtkObject" id="create-mac-address-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">MAC Address Field</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkCheckButton" id="mac-address">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
<signal name="clicked" handler="on_mac_address_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="create-mac-address">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="max_length">17</property>
<property name="invisible_char">●</property>
<property name="text" translatable="yes">aa:bb:cc:dd:ee:ff</property>
<child internal-child="accessible">
<object class="AtkObject" id="create-mac-address-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">MAC Address Field</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label22">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="yalign">0.23999999463558197</property>
<property name="label" translatable="yes">_Host device:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">net-list</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label386">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_MAC address:</property>
<property name="use_markup">True</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">create-mac-address</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">D_evice model:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">net-model</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="net-bridge-box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label2">
<object class="GtkLabel" id="label386">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Bridge name:</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_MAC address:</property>
<property name="use_markup">True</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">net-bridge</property>
<property name="mnemonic_widget">create-mac-address</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="net-bridge">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</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">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkComboBox" id="net-list">
<object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Device mode_l:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">net-model</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkImage" id="net-list-warn">
<object class="GtkComboBox" id="net-model">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-dialog-warning</property>
<property name="halign">start</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="network-source-label-align">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">False</property>
<property name="vexpand">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="network-source-ui-align">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">False</property>
<property name="vexpand">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="net-model">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment5">
<object class="GtkAlignment" id="network-vport-align">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">False</property>
<property name="vexpand">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.0 on Wed Oct 2 12:11:37 2013 -->
<!-- Generated with glade 3.16.1 -->
<interface>
<!-- interface-requires gtk+ 3.0 -->
<requires lib="gtk+" version="3.0"/>
<object class="GtkAdjustment" id="adjustment1">
<property name="upper">1000000</property>
<property name="step_increment">0.10000000000000001</property>
@ -2651,12 +2651,60 @@ is not yet supported.&lt;/small&gt;</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkVBox" id="vbox17">
<object class="GtkGrid" id="grid17">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkHBox" id="config-netdev-warn-box">
<object class="GtkCheckButton" id="config-set-macaddr">
<property name="label" translatable="yes">Set a fixed _MAC address</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_config_set_macaddr_toggled" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="config-macaddr">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">start</property>
<property name="hexpand">False</property>
<property name="width_chars">20</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="config-netdev-ui-align">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="config-netdev-warn-box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
@ -2676,122 +2724,8 @@ is not yet supported.&lt;/small&gt;</property>
<object class="GtkLabel" id="config-netdev-warn-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label">warn</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkHBox" id="hbox8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkComboBox" id="config-netdev">
<property name="visible">True</property>
<property name="can_focus">False</property>
<signal name="changed" handler="on_config_netdev_changed" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkImage" id="config-netdev-warn-icon">
<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">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment21">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="top_padding">6</property>
<property name="left_padding">12</property>
<child>
<object class="GtkGrid" id="table8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkHBox" id="config-netdev-bridge-box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label39">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Bridge name:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">config-netdev-bridge</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="config-netdev-bridge">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</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">3</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
<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>
@ -2801,63 +2735,10 @@ is not yet supported.&lt;/small&gt;</property>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="config-set-macaddr">
<property name="label" translatable="yes">Set a fixed _MAC address</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0.5</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_config_set_macaddr_toggled" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox13">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkEntry" id="config-macaddr">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment15">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>

View File

@ -4024,21 +4024,7 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label397">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Source device:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
@ -4049,12 +4035,12 @@
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="yalign">0.47999998927116394</property>
<property name="label" translatable="yes">Device m_odel:</property>
<property name="label" translatable="yes">Device mode_l:</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
@ -4069,95 +4055,7 @@
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label427">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Source mode:</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="network-bridge-box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label34">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Bridge name:</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="network-bridge">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<signal name="changed" handler="on_network_bridge_changed" swapped="no"/>
</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">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="network-source-mode">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="has_entry">True</property>
<signal name="changed" handler="on_network-source-mode-combo_changed" swapped="no"/>
<child internal-child="entry">
<object class="GtkEntry" id="combobox-entry6">
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
@ -4166,6 +4064,8 @@
<object class="GtkComboBox" id="network-model">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">False</property>
<property name="has_entry">True</property>
<signal name="changed" handler="on_network_model_combo_changed" swapped="no"/>
<child internal-child="entry">
@ -4176,16 +4076,37 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="network-source">
<object class="GtkAlignment" id="network-source-label-align">
<property name="visible">True</property>
<property name="can_focus">False</property>
<signal name="changed" handler="on_network_source_combo_changed" swapped="no"/>
<property name="hexpand">False</property>
<property name="vexpand">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="network-source-ui-align">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">False</property>
<property name="vexpand">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">1</property>
@ -4214,199 +4135,15 @@
</packing>
</child>
<child>
<object class="GtkExpander" id="vport-expander">
<property name="can_focus">True</property>
<object class="GtkAlignment" id="network-vport-align">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkHBox" id="hbox1124">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">2</property>
<child>
<object class="GtkTable" id="table10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">5</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">3</property>
<child>
<object class="GtkEntry" id="vport-instanceid">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="width_chars">30</property>
<signal name="changed" handler="on_vport_instanceid_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="vport-instanceid-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Instance id:</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="vport-typeidversion">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="width_chars">30</property>
<signal name="changed" handler="on_vport_typeidversion_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="vport-typeidversion-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Typeid version:</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="vport-typeid">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="width_chars">30</property>
<signal name="changed" handler="on_vport_typeid_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="vport-typeid-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Typeid:</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="vport-managerid">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="width_chars">30</property>
<signal name="changed" handler="on_vport_managerid_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="vport-managerid-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Managerid:</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="label33">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="yalign">0.47999998927116394</property>
<property name="label" translatable="yes">Type:</property>
<property name="use_markup">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="vport-type">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="width_chars">30</property>
<signal name="changed" handler="on_vport_type_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Virtual port</property>
<property name="use_markup">True</property>
</object>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>

365
ui/netlist.ui Normal file
View File

@ -0,0 +1,365 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<object class="GtkGrid" id="net-source-box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_Bridge name:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">net-bridge-name</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Source m_ode:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">net-source-mode</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="net-bridge-name">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<signal name="changed" handler="on_net_bridge_name_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="net-macvtap-warn-box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">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="label19">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;small&gt;In most configurations, macvtap does not work for host to guest network communication.&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>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">2</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="net-source-mode">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="has_entry">True</property>
<signal name="changed" handler="on_net_source_mode_changed" swapped="no"/>
<child internal-child="entry">
<object class="GtkEntry" id="combobox-entry">
<property name="can_focus">False</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<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="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkImage" id="net-source-warn">
<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">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">2</property>
<property name="height">1</property>
</packing>
</child>
</object>
<object class="GtkLabel" id="net-source-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">_Network source:</property>
<property name="use_underline">True</property>
</object>
<object class="GtkExpander" id="vport-expander">
<property name="can_focus">True</property>
<child>
<object class="GtkHBox" id="hbox1124">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">2</property>
<child>
<object class="GtkTable" id="table10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">5</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">3</property>
<child>
<object class="GtkEntry" id="vport-instanceid">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="width_chars">30</property>
<signal name="changed" handler="on_vport_instanceid_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="vport-instanceid-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Instance id:</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="vport-typeidversion">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="width_chars">30</property>
<signal name="changed" handler="on_vport_typeidversion_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="vport-typeidversion-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Typeid version:</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="vport-typeid">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="width_chars">30</property>
<signal name="changed" handler="on_vport_typeid_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="vport-typeid-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Typeid:</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="vport-managerid">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="width_chars">30</property>
<signal name="changed" handler="on_vport_managerid_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="vport-managerid-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Managerid:</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="label33">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="yalign">0.47999998927116394</property>
<property name="label" translatable="yes">Type:</property>
<property name="use_markup">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="vport-type">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="width_chars">30</property>
<signal name="changed" handler="on_vport_type_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Virtual port</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
</interface>

View File

@ -37,6 +37,7 @@ from virtinst import VirtualController
from virtManager import sharedui
from virtManager import uiutil
from virtManager.fsdetails import vmmFSDetails
from virtManager.netlist import vmmNetworkList
from virtManager.asyncjob import vmmAsyncJob
from virtManager.storagebrowse import vmmStorageBrowser
from virtManager.baseclass import vmmGObjectUI
@ -68,12 +69,15 @@ class vmmAddHardware(vmmGObjectUI):
self.is_customize_dialog = is_customize_dialog
self.storage_browser = None
self.fs_units = "mb"
self._dev = None
self.fsDetails = vmmFSDetails(vm, self.builder, self.topwin)
self.widget("fs-box").add(self.fsDetails.top_box)
self.netlist = vmmNetworkList(self.conn, self.builder, self.topwin)
self.widget("network-source-label-align").add(self.netlist.top_label)
self.widget("network-source-ui-align").add(self.netlist.top_box)
self.widget("network-vport-align").add(self.netlist.top_vport)
self.builder.connect_signals({
"on_create_cancel_clicked" : self.close,
@ -134,6 +138,9 @@ class vmmAddHardware(vmmGObjectUI):
self.storage_browser = None
self.fsDetails.cleanup()
self.fsDetails = None
self.netlist.cleanup()
self.netlist = None
def is_visible(self):
return self.topwin.get_visible()
@ -172,13 +179,8 @@ class vmmAddHardware(vmmGObjectUI):
hw_col.add_attribute(text, 'sensitive', 3)
hw_list.append_column(hw_col)
# Virtual network list
net_list = self.widget("net-list")
bridge_box = self.widget("net-bridge-box")
sharedui.build_network_list(net_list, bridge_box)
# Network model list
netmodel_list = self.widget("net-model")
netmodel_list = self.widget("net-model")
self.build_network_model_combo(self.vm, netmodel_list)
# Disk bus type
@ -415,16 +417,7 @@ class vmmAddHardware(vmmGObjectUI):
self.widget("create-mac-address").set_text(newmac)
self.change_macaddr_use()
net_list = self.widget("net-list")
net_warn = self.widget("net-list-warn")
sharedui.populate_network_list(net_list, self.conn)
error = self.conn.netdev_error
if error:
net_warn.show()
net_warn.set_tooltip_text(error)
else:
net_warn.hide()
self.netlist.reset_state()
netmodel = self.widget("net-model")
self.populate_network_model_combo(self.vm, netmodel)
@ -586,27 +579,6 @@ class vmmAddHardware(vmmGObjectUI):
if len(model) > 0:
combo.set_active(0)
@staticmethod
def populate_network_source_mode_combo(vm, combo):
ignore = vm
model = combo.get_model()
model.clear()
# [xml value, label]
model.append(["bridge", "Bridge"])
model.append(["vepa", "VEPA"])
model.append(["private", "Private"])
model.append(["passthrough", "Passthrough"])
@staticmethod
def build_network_source_mode_combo(vm, combo):
model = Gtk.ListStore(str, str)
combo.set_model(model)
uiutil.set_combo_text_column(combo, 1)
vmmAddHardware.populate_network_source_mode_combo(vm, combo)
combo.set_active(0)
@staticmethod
def populate_network_model_combo(vm, combo):
model = combo.get_model()
@ -1059,15 +1031,6 @@ class vmmAddHardware(vmmGObjectUI):
return self.widget("graphics-password").get_text()
# Network getters
def get_config_network(self):
net_list = self.widget("net-list")
bridge_ent = self.widget("net-bridge")
net_type, net_src = sharedui.get_network_selection(net_list,
bridge_ent)
return net_type, net_src
def get_config_net_model(self):
return uiutil.get_list_selection(self.widget("net-model"))[0]
@ -1689,7 +1652,7 @@ class vmmAddHardware(vmmGObjectUI):
def validate_page_network(self):
nettype, devname = self.get_config_network()
nettype = self.netlist.get_network_selection()[0]
mac = self.get_config_macaddr()
model = self.get_config_net_model()
@ -1701,8 +1664,7 @@ class vmmAddHardware(vmmGObjectUI):
return self.err.val_err(_("Invalid MAC address"),
_("A MAC address must be entered."))
ret = sharedui.validate_network(self.err, self.conn,
nettype, devname, mac, model)
ret = self.netlist.validate_network(mac, model)
if ret is False:
return False

View File

@ -39,6 +39,7 @@ from virtManager.asyncjob import vmmAsyncJob
from virtManager.storagebrowse import vmmStorageBrowser
from virtManager.details import vmmDetails
from virtManager.domain import vmmDomainVirtinst
from virtManager.netlist import vmmNetworkList
# Number of seconds to wait for media detection
DETECT_TIMEOUT = 20
@ -107,6 +108,10 @@ class vmmCreate(vmmGObjectUI):
self.config_window = None
self.config_window_signals = []
self.netlist = vmmNetworkList(self.conn, self.builder, self.topwin)
self.widget("config-netdev-ui-align").add(self.netlist.top_box)
self.netlist.connect("changed", self.netdev_changed)
self.builder.connect_signals({
"on_vmm_newcreate_delete_event" : self.close,
@ -145,7 +150,6 @@ class vmmCreate(vmmGObjectUI):
"on_config_storage_browse_clicked": self.browse_storage,
"on_config_storage_select_toggled": self.toggle_storage_select,
"on_config_netdev_changed": self.netdev_changed,
"on_config_set_macaddr_toggled": self.toggle_macaddr,
"on_config_hv_changed": self.hv_changed,
@ -209,6 +213,7 @@ class vmmCreate(vmmGObjectUI):
self.remove_conn()
self.conn = newconn
self.netlist.conn = self.conn
if self.conn:
self.set_conn_state()
@ -288,12 +293,6 @@ class vmmCreate(vmmGObjectUI):
cd_list = self.widget("install-local-cdrom-combo")
sharedui.build_mediadev_combo(cd_list)
# Networking
# [ interface type, device name, label, sensitive ]
net_list = self.widget("config-netdev")
bridge_box = self.widget("config-netdev-bridge-box")
sharedui.build_network_list(net_list, bridge_box)
# Archtecture
# [value, label]
archList = self.widget("config-arch")
@ -617,40 +616,13 @@ class vmmCreate(vmmGObjectUI):
storage_area.set_tooltip_text(storage_tooltip or "")
# Networking
net_list = self.widget("config-netdev")
net_warn_icon = self.widget("config-netdev-warn-icon")
net_warn_box = self.widget("config-netdev-warn-box")
net_expander = self.widget("config-advanced-expander")
net_warn_icon.hide()
net_warn_box.hide()
net_expander.set_expanded(False)
do_warn = sharedui.populate_network_list(net_list, self.conn, False)
self.set_net_warn(self.conn.netdev_error or do_warn,
self.conn.netdev_error, True)
newmac = virtinst.VirtualNetworkInterface.generate_mac(
self.conn.get_backend())
self.widget("config-set-macaddr").set_active(bool(newmac))
self.widget("config-macaddr").set_text(newmac)
def set_net_warn(self, show_warn, msg, do_tooltip):
net_warn_icon = self.widget("config-netdev-warn-icon")
net_warn_box = self.widget("config-netdev-warn-box")
net_warn_label = self.widget("config-netdev-warn-label")
net_expander = self.widget("config-advanced-expander")
if show_warn:
net_expander.set_expanded(True)
if do_tooltip:
net_warn_icon.set_visible(bool(show_warn))
if msg:
net_warn_icon.set_tooltip_text(show_warn and msg or "")
else:
net_warn_box.set_visible(show_warn)
markup = show_warn and ("<small>%s</small>" % msg) or ""
net_warn_label.set_markup(markup)
self.widget("config-advanced-expander").set_expanded(False)
self.netlist.reset_state()
def populate_hv(self):
hv_list = self.widget("config-hv")
@ -979,6 +951,8 @@ class vmmCreate(vmmGObjectUI):
self.widget("summary-cpu").set_text(cpu)
self.widget("summary-storage").set_markup(storage)
self.netdev_changed(None)
# get_* methods
def get_config_name(self):
return self.widget("create-vm-name").get_text()
@ -1104,16 +1078,6 @@ class vmmCreate(vmmGObjectUI):
return (path, size, sparse)
def get_config_network_info(self):
net_list = self.widget("config-netdev")
bridge_ent = self.widget("config-netdev-bridge")
macaddr = self.widget("config-macaddr").get_text()
net_type, net_src = sharedui.get_network_selection(net_list,
bridge_ent)
return net_type, net_src, macaddr.strip()
def get_config_customize(self):
return self.widget("summary-customize").get_active()
def is_detect_active(self):
@ -1146,17 +1110,16 @@ class vmmCreate(vmmGObjectUI):
self.widget("config-dtb-warn-virtio"), show_dtb_virtio)
def netdev_changed(self, ignore):
self.check_network_selection()
def check_network_selection(self):
row = uiutil.get_list_selection(self.widget("config-netdev"))
row = self.netlist.get_network_row()
show_pxe_warn = True
pxe_install = (self.get_config_install_page() == INSTALL_PAGE_PXE)
expand = False
if row:
ntype = row[0]
key = row[6]
expand = (ntype != "network" and ntype != "bridge")
if (ntype is None or
ntype == virtinst.VirtualNetworkInterface.TYPE_USER):
show_pxe_warn = True
@ -1166,11 +1129,13 @@ class vmmCreate(vmmGObjectUI):
obj = self.conn.get_net(key)
show_pxe_warn = not obj.can_pxe()
if not (show_pxe_warn and pxe_install):
return
show_warn = (show_pxe_warn and pxe_install)
self.set_net_warn(True,
_("Network selection does not support PXE"), False)
if expand or show_warn:
self.widget("config-advanced-expander").set_expanded(True)
self.widget("config-netdev-warn-box").set_visible(show_warn)
self.widget("config-netdev-warn-label").set_markup(
"<small>%s</small>" % _("Network selection does not support PXE"))
def hv_changed(self, src):
hv = uiutil.get_list_selection(src, 1)
@ -1424,7 +1389,6 @@ class vmmCreate(vmmGObjectUI):
elif pagenum == PAGE_FINISH:
self.widget("create-finish").grab_focus()
self.populate_summary()
self.widget("config-netdev").emit("changed")
for nr in range(self.widget("create-pages").get_n_pages()):
page = self.widget("create-pages").get_nth_page(nr)
@ -1822,7 +1786,8 @@ class vmmCreate(vmmGObjectUI):
if not self.validate_storage_page():
return False
nettype, devname, macaddr = self.get_config_network_info()
macaddr = self.widget("config-macaddr").get_text().strip()
nettype = self.netlist.get_network_selection()[0]
if nettype is None:
# No network device available
@ -1838,8 +1803,7 @@ class vmmCreate(vmmGObjectUI):
_("Network device required for %s install.") %
methname)
nic = sharedui.validate_network(self.err,
self.conn, nettype, devname, macaddr)
nic = self.netlist.validate_network(macaddr)
if nic is False:
return False

View File

@ -31,17 +31,18 @@ import libvirt
from virtManager import sharedui
from virtManager import uiutil
from virtManager.storagebrowse import vmmStorageBrowser
from virtManager.baseclass import vmmGObjectUI
from virtManager.addhardware import vmmAddHardware
from virtManager.choosecd import vmmChooseCD
from virtManager.snapshots import vmmSnapshotPage
from virtManager.graphwidgets import Sparkline
from virtManager.fsdetails import vmmFSDetails
from virtinst import VirtualRNGDevice
from virtManager.netlist import vmmNetworkList
from virtManager.snapshots import vmmSnapshotPage
from virtManager.storagebrowse import vmmStorageBrowser
from virtManager.graphwidgets import Sparkline
import virtinst
from virtinst import util
from virtinst import VirtualRNGDevice
# Parameters that can be editted in the details window
@ -386,6 +387,15 @@ class vmmDetails(vmmGObjectUI):
self.fsDetails.connect("changed",
lambda *x: self.enable_apply(x, EDIT_FS))
self.netlist = vmmNetworkList(self.conn, self.builder, self.topwin)
self.widget("network-source-label-align").add(self.netlist.top_label)
self.widget("network-source-ui-align").add(self.netlist.top_box)
self.widget("network-vport-align").add(self.netlist.top_vport)
self.netlist.connect("changed",
lambda x: self.enable_apply(x, EDIT_NET_SOURCE))
self.netlist.connect("changed-vport",
lambda x: self.enable_apply(x, EDIT_NET_VPORT))
# Set default window size
w, h = self.vm.get_details_window_size()
self.topwin.set_default_size(w or 800, h or 600)
@ -487,21 +497,8 @@ class vmmDetails(vmmGObjectUI):
"on_disk_serial_changed": lambda *x: self.enable_apply(x, EDIT_DISK_SERIAL),
"on_disk_iotune_changed": self.iotune_changed,
"on_network_source_combo_changed": lambda *x: self.enable_apply(x, EDIT_NET_SOURCE),
"on_network_bridge_changed": lambda *x: self.enable_apply(x, EDIT_NET_SOURCE),
"on_network-source-mode-combo_changed": lambda *x: self.enable_apply(x, EDIT_NET_SOURCE),
"on_network_model_combo_changed": lambda *x: self.enable_apply(x, EDIT_NET_MODEL),
"on_vport_type_changed": lambda *x: self.enable_apply(x, EDIT_NET_VPORT),
"on_vport_managerid_changed": lambda *x: self.enable_apply(x,
EDIT_NET_VPORT),
"on_vport_typeid_changed": lambda *x: self.enable_apply(x,
EDIT_NET_VPORT),
"on_vport_typeidversion_changed": lambda *x: self.enable_apply(x,
EDIT_NET_VPORT),
"on_vport_instanceid_changed": lambda *x: self.enable_apply(x,
EDIT_NET_VPORT),
"on_gfx_type_combo_changed": lambda *x: self.enable_apply(x, EDIT_GFX_TYPE),
"on_vnc_keymap_combo_changed": lambda *x: self.enable_apply(x,
EDIT_GFX_KEYMAP),
@ -583,6 +580,9 @@ class vmmDetails(vmmGObjectUI):
self.addhwmenu = None
self.fsDetails.cleanup()
self.fsDetails = None
self.netlist.cleanup()
self.netlist = None
def show(self):
logging.debug("Showing VM details: %s", self.vm)
@ -926,18 +926,6 @@ class vmmDetails(vmmGObjectUI):
if not (self.conn.is_qemu() or self.conn.is_test_conn()):
self.widget("iotune-expander").set_visible(False)
# Network source
net_source = self.widget("network-source")
net_bridge = self.widget("network-bridge-box")
source_mode_combo = self.widget("network-source-mode")
vport_expander = self.widget("vport-expander")
sharedui.build_network_list(net_source, net_bridge,
source_mode_combo, vport_expander)
# source mode
source_mode = self.widget("network-source-mode")
vmmAddHardware.build_network_source_mode_combo(self.vm, source_mode)
# Network model
net_model = self.widget("network-model")
vmmAddHardware.build_network_model_combo(self.vm, net_model)
@ -988,33 +976,6 @@ class vmmDetails(vmmGObjectUI):
combo.set_active(-1)
def set_combo_entry(self, widget, value, label="", comparefunc=None):
label = label or value
model_combo = self.widget(widget)
idx = -1
if comparefunc:
model_in_list, idx = comparefunc(model_combo.get_model(), value)
else:
model_list = [x[0] for x in model_combo.get_model()]
model_in_list = (value in model_list)
if model_in_list:
idx = model_list.index(value)
model_combo.set_active(idx)
if idx == -1 and model_combo.get_has_entry():
model_combo.get_child().set_text(value or "")
def get_combo_entry(self, widgetname):
combo = self.widget(widgetname)
ret = uiutil.get_list_selection(combo, 0)
if ret:
return ret
if not combo.get_has_entry():
return None
return combo.get_child().get_text().strip()
##########################
# Window state listeners #
##########################
@ -1906,7 +1867,7 @@ class vmmDetails(vmmGObjectUI):
add_hotplug(self.vm.hotplug_title, title)
if self.edited(EDIT_MACHTYPE):
machtype = self.get_combo_entry("machine-type")
machtype = uiutil.get_combo_entry(self.widget("machine-type"))
add_define(self.vm.define_machtype, machtype)
if self.edited(EDIT_DESC):
@ -2045,15 +2006,15 @@ class vmmDetails(vmmGObjectUI):
add_define(self.vm.define_disk_removable, dev_id_info, do_removable)
if self.edited(EDIT_DISK_CACHE):
cache = self.get_combo_entry("disk-cache")
cache = uiutil.get_combo_entry(self.widget("disk-cache"))
add_define(self.vm.define_disk_cache, dev_id_info, cache)
if self.edited(EDIT_DISK_IO):
io = self.get_combo_entry("disk-io")
io = uiutil.get_combo_entry(self.widget("disk-io"))
add_define(self.vm.define_disk_io, dev_id_info, io)
if self.edited(EDIT_DISK_FORMAT):
fmt = self.get_combo_entry("disk-format")
fmt = uiutil.get_combo_entry(self.widget("disk-format"))
add_define(self.vm.define_disk_driver_type, dev_id_info, fmt)
if self.edited(EDIT_DISK_SERIAL):
@ -2077,7 +2038,7 @@ class vmmDetails(vmmGObjectUI):
# Do this last since it can change uniqueness info of the dev
if self.edited(EDIT_DISK_BUS):
bus = self.get_combo_entry("disk-bus")
bus = uiutil.get_combo_entry(self.widget("disk-bus"))
addr = None
if bus == "spapr-vscsi":
bus = "scsi"
@ -2092,7 +2053,7 @@ class vmmDetails(vmmGObjectUI):
ignore = add_hotplug
if self.edited(EDIT_SOUND_MODEL):
model = self.get_combo_entry("sound-model")
model = uiutil.get_combo_entry(self.widget("sound-model"))
if model:
add_define(self.vm.define_sound_model, dev_id_info, model)
@ -2104,7 +2065,7 @@ class vmmDetails(vmmGObjectUI):
ignore = add_hotplug
if self.edited(EDIT_SMARTCARD_MODE):
model = self.get_combo_entry("smartcard-mode")
model = uiutil.get_combo_entry(self.widget("smartcard-mode"))
if model:
add_define(self.vm.define_smartcard_mode, dev_id_info, model)
@ -2116,30 +2077,20 @@ class vmmDetails(vmmGObjectUI):
ignore = add_hotplug
if self.edited(EDIT_NET_MODEL):
model = self.get_combo_entry("network-model")
model = uiutil.get_combo_entry(self.widget("network-model"))
addr = None
if model == "spapr-vlan":
addr = "spapr-vio"
add_define(self.vm.define_network_model, dev_id_info, model, addr)
if self.edited(EDIT_NET_SOURCE):
mode = None
net_list = self.widget("network-source")
net_bridge = self.widget("network-bridge")
nettype, source = sharedui.get_network_selection(net_list,
net_bridge)
if nettype == "direct":
mode = self.get_combo_entry("network-source-mode")
nettype, source, mode = self.netlist.get_network_selection()
add_define(self.vm.define_network_source, dev_id_info,
nettype, source, mode)
if self.edited(EDIT_NET_VPORT):
vport_type = self.get_text("vport-type")
vport_managerid = self.get_text("vport-managerid")
vport_typeid = self.get_text("vport-typeid")
vport_idver = self.get_text("vport-typeidversion")
vport_instid = self.get_text("vport-instanceid")
(vport_type, vport_managerid, vport_typeid,
vport_idver, vport_instid) = self.netlist.get_vport()
add_define(self.vm.define_virtualport, dev_id_info,
vport_type, vport_managerid, vport_typeid,
@ -2162,12 +2113,12 @@ class vmmDetails(vmmGObjectUI):
passwd)
if self.edited(EDIT_GFX_KEYMAP):
keymap = self.get_combo_entry("gfx-keymap")
keymap = uiutil.get_combo_entry(self.widget("gfx-keymap"))
add_define(self.vm.define_graphics_keymap, dev_id_info, keymap)
# Do this last since it can change graphics unique ID
if self.edited(EDIT_GFX_TYPE):
gtype = self.get_combo_entry("gfx-type")
gtype = uiutil.get_combo_entry(self.widget("gfx-type"))
add_define(self.vm.define_graphics_type, dev_id_info, gtype)
return self._change_config_helper(df, da, hf, ha)
@ -2178,7 +2129,7 @@ class vmmDetails(vmmGObjectUI):
ignore = add_hotplug
if self.edited(EDIT_VIDEO_MODEL):
model = self.get_combo_entry("video-model")
model = uiutil.get_combo_entry(self.widget("video-model"))
if model:
add_define(self.vm.define_video_model, dev_id_info, model)
@ -2190,7 +2141,7 @@ class vmmDetails(vmmGObjectUI):
ignore = add_hotplug
if self.edited(EDIT_CONTROLLER_MODEL):
model = self.get_combo_entry("controller-model")
model = uiutil.get_combo_entry(self.widget("controller-model"))
if model:
add_define(self.vm.define_controller_model, dev_id_info, model)
@ -2202,11 +2153,11 @@ class vmmDetails(vmmGObjectUI):
ignore = add_hotplug
if self.edited(EDIT_WATCHDOG_MODEL):
model = self.get_combo_entry("watchdog-model")
model = uiutil.get_combo_entry(self.widget("watchdog-model"))
add_define(self.vm.define_watchdog_model, dev_id_info, model)
if self.edited(EDIT_WATCHDOG_ACTION):
action = self.get_combo_entry("watchdog-action")
action = uiutil.get_combo_entry(self.widget("watchdog-action"))
add_define(self.vm.define_watchdog_action, dev_id_info, action)
return self._change_config_helper(df, da, hf, ha)
@ -2400,7 +2351,7 @@ class vmmDetails(vmmGObjectUI):
machtype = self.vm.get_machtype()
if not arch in ["i686", "x86_64"]:
if machtype is not None:
self.set_combo_entry("machine-type", machtype)
uiutil.set_combo_entry(self.widget("machine-type"), machtype)
def refresh_inspection_page(self):
inspection_supported = self.config.support_inspection
@ -2640,8 +2591,8 @@ class vmmDetails(vmmGObjectUI):
uiutil.set_grid_row_visible(self.widget("disk-removable"),
can_set_removable)
self.widget("disk-size").set_text(size)
self.set_combo_entry("disk-cache", cache)
self.set_combo_entry("disk-io", io)
uiutil.set_combo_entry(self.widget("disk-cache"), cache)
uiutil.set_combo_entry(self.widget("disk-io"), io)
self.widget("disk-format").set_sensitive(show_format)
self.widget("disk-format").get_child().set_text(driver_type)
@ -2649,7 +2600,7 @@ class vmmDetails(vmmGObjectUI):
no_default = not self.is_customize_dialog
self.populate_disk_bus_combo(devtype, no_default)
self.set_combo_entry("disk-bus", bus)
uiutil.set_combo_entry(self.widget("disk-bus"), bus)
self.widget("disk-serial").set_text(serial or "")
self.widget("disk-iotune-rbs").set_value(iotune_rbs)
@ -2675,70 +2626,12 @@ class vmmDetails(vmmGObjectUI):
if not net:
return
nettype = net.type
source = net.source
source_mode = net.source_mode
model = net.model
netobj = None
if nettype == virtinst.VirtualNetworkInterface.TYPE_VIRTUAL:
name_dict = {}
for uuid in self.conn.list_net_uuids():
vnet = self.conn.get_net(uuid)
name = vnet.get_name()
name_dict[name] = vnet
if source and source in name_dict:
netobj = name_dict[source]
desc = sharedui.pretty_network_desc(nettype, source, netobj)
vmmAddHardware.populate_network_model_combo(
self.vm, self.widget("network-model"))
uiutil.set_combo_entry(self.widget("network-model"), net.model)
self.widget("network-mac-address").set_text(net.macaddr)
sharedui.populate_network_list(
self.widget("network-source"),
self.conn)
self.widget("network-source").set_active(-1)
self.widget("network-bridge").set_text("")
def compare_network(model, info):
for idx in range(len(model)):
row = model[idx]
if row[0] == info[0] and row[1] == info[1]:
return True, idx
if info[0] == virtinst.VirtualNetworkInterface.TYPE_BRIDGE:
idx = (len(model) - 1)
self.widget("network-bridge").set_text(str(info[1]))
return True, idx
return False, 0
self.set_combo_entry("network-source",
(nettype, source), label=desc,
comparefunc=compare_network)
is_direct = (nettype == "direct")
uiutil.set_grid_row_visible(self.widget("network-source-mode"),
is_direct)
self.widget("vport-expander").set_visible(is_direct)
# source mode
vmmAddHardware.populate_network_source_mode_combo(self.vm,
self.widget("network-source-mode"))
self.set_combo_entry("network-source-mode", source_mode)
# Virtualport config
vport = net.virtualport
self.widget("vport-type").set_text(vport.type or "")
self.widget("vport-managerid").set_text(str(vport.managerid or ""))
self.widget("vport-typeid").set_text(str(vport.typeid or ""))
self.widget("vport-typeidversion").set_text(
str(vport.typeidversion or ""))
self.widget("vport-instanceid").set_text(vport.instanceid or "")
vmmAddHardware.populate_network_model_combo(self.vm,
self.widget("network-model"))
self.set_combo_entry("network-model", model)
self.netlist.set_dev(net)
def refresh_input_page(self):
inp = self.get_hw_selection(HW_LIST_COL_DEVICE)
@ -2807,7 +2700,7 @@ class vmmDetails(vmmGObjectUI):
self.widget("gfx-port").set_text(port_to_string(gfx.port))
self.widget("gfx-address").set_text(gfx.listen or "127.0.0.1")
self.set_combo_entry("gfx-keymap", gfx.keymap or None)
uiutil.set_combo_entry(self.widget("gfx-keymap"), gfx.keymap or None)
self.widget("gfx-password").set_text(gfx.passwd or "")
self.widget("gfx-use-password").set_active(use_passwd)
@ -2832,7 +2725,7 @@ class vmmDetails(vmmGObjectUI):
if settype:
show_row("gfx-type")
self.set_combo_entry("gfx-type", gtype, label=settype)
uiutil.set_combo_entry(self.widget("gfx-type"), gtype)
self.widget("graphics-title").set_markup("<b>%s</b>" % title)
@ -2842,14 +2735,14 @@ class vmmDetails(vmmGObjectUI):
if not sound:
return
self.set_combo_entry("sound-model", sound.model)
uiutil.set_combo_entry(self.widget("sound-model"), sound.model)
def refresh_smartcard_page(self):
sc = self.get_hw_selection(HW_LIST_COL_DEVICE)
if not sc:
return
self.set_combo_entry("smartcard-mode", sc.mode)
uiutil.set_combo_entry(self.widget("smartcard-mode"), sc.mode)
def refresh_redir_page(self):
rd = self.get_hw_selection(HW_LIST_COL_DEVICE)
@ -3064,8 +2957,7 @@ class vmmDetails(vmmGObjectUI):
self.widget("video-ram").set_text(ramlabel)
self.widget("video-heads").set_text(heads and str(heads) or "-")
self.set_combo_entry("video-model", model,
label=vid.pretty_model(model))
uiutil.set_combo_entry(self.widget("video-model"), model)
def refresh_watchdog_page(self):
watch = self.get_hw_selection(HW_LIST_COL_DEVICE)
@ -3075,8 +2967,8 @@ class vmmDetails(vmmGObjectUI):
model = watch.model
action = watch.action
self.set_combo_entry("watchdog-model", model)
self.set_combo_entry("watchdog-action", action)
uiutil.set_combo_entry(self.widget("watchdog-model"), model)
uiutil.set_combo_entry(self.widget("watchdog-action"), action)
def refresh_controller_page(self):
dev = self.get_hw_selection(HW_LIST_COL_DEVICE)
@ -3105,7 +2997,8 @@ class vmmDetails(vmmGObjectUI):
else:
self.widget("config-remove").set_sensitive(True)
self.set_combo_entry("controller-model", dev.model or "default")
uiutil.set_combo_entry(self.widget("controller-model"),
dev.model or "default")
def refresh_filesystem_page(self):
dev = self.get_hw_selection(HW_LIST_COL_DEVICE)

466
virtManager/netlist.py Normal file
View File

@ -0,0 +1,466 @@
#
# Copyright (C) 2014 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
#
import logging
# pylint: disable=E0611
from gi.repository import Gtk
from gi.repository import GObject
# pylint: enable=E0611
import virtinst
from virtManager import uiutil
from virtManager.baseclass import vmmGObjectUI
class vmmNetworkList(vmmGObjectUI):
__gsignals__ = {
"changed": (GObject.SignalFlags.RUN_FIRST, None, []),
"changed-vport": (GObject.SignalFlags.RUN_FIRST, None, [])
}
def __init__(self, conn, builder, topwin):
vmmGObjectUI.__init__(self, "netlist.ui",
None, builder=builder, topwin=topwin)
self.conn = conn
self.builder.connect_signals({
"on_net_source_changed": self._on_net_source_changed,
"on_net_source_mode_changed": self._emit_changed,
"on_net_bridge_name_changed": self._emit_changed,
"on_vport_type_changed": self._emit_vport_changed,
"on_vport_managerid_changed": self._emit_vport_changed,
"on_vport_typeid_changed": self._emit_vport_changed,
"on_vport_typeidversion_changed": self._emit_vport_changed,
"on_vport_instanceid_changed": self._emit_vport_changed,
})
self._init_ui()
self.top_label = self.widget("net-source-label")
self.top_box = self.widget("net-source-box")
self.top_vport = self.widget("vport-expander")
def _cleanup(self):
self.conn = None
##########################
# Initialization methods #
##########################
def _init_ui(self):
# [ network type, source name, label, sensitive?, net is active,
# manual bridge, net instance]
model = Gtk.ListStore(str, str, str, bool, bool, bool, object)
combo = self.widget("net-source")
combo.set_model(model)
text = Gtk.CellRendererText()
combo.pack_start(text, True)
combo.add_attribute(text, 'text', 2)
combo.add_attribute(text, 'sensitive', 3)
combo = self.widget("net-source-mode")
# [xml value, label]
model = Gtk.ListStore(str, str)
combo.set_model(model)
uiutil.set_combo_text_column(combo, 1)
model.append(["bridge", "Bridge"])
model.append(["vepa", "VEPA"])
model.append(["private", "Private"])
model.append(["passthrough", "Passthrough"])
combo.set_active(0)
def _pretty_network_desc(self, nettype, source=None, netobj=None):
if nettype == virtinst.VirtualNetworkInterface.TYPE_USER:
return _("Usermode networking")
extra = None
if nettype == virtinst.VirtualNetworkInterface.TYPE_BRIDGE:
ret = _("Bridge")
elif nettype == virtinst.VirtualNetworkInterface.TYPE_VIRTUAL:
ret = _("Virtual network")
if netobj:
extra = ": %s" % netobj.pretty_forward_mode()
else:
ret = nettype.capitalize()
if source:
ret += " '%s'" % source
if extra:
ret += " %s" % extra
return ret
def _build_source_row(self, nettype, name,
label, is_sensitive, is_running, manual_bridge=False, key=None):
return [nettype, name, label,
is_sensitive, is_running, manual_bridge,
key]
def _find_virtual_networks(self):
vnet_dict = {}
vnet_bridges = []
hasNet = False
netIdxLabel = None
for uuid in self.conn.list_net_uuids():
net = self.conn.get_net(uuid)
nettype = virtinst.VirtualNetworkInterface.TYPE_VIRTUAL
label = self._pretty_network_desc(nettype, net.get_name(), net)
if not net.is_active():
label += " (%s)" % _("Inactive")
hasNet = True
# FIXME: Should we use 'default' even if it's inactive?
# FIXME: This preference should be configurable
if net.get_name() == "default":
netIdxLabel = label
vnet_dict[label] = self._build_source_row(
nettype, net.get_name(), label, True,
net.is_active(), key=net.get_uuid())
# Build a list of vnet bridges, so we know not to list them
# in the physical interface list
vnet_bridge = net.get_bridge_device()
if vnet_bridge:
vnet_bridges.append(vnet_bridge)
if not hasNet:
label = _("No virtual networks available")
vnet_dict[label] = self._build_source_row(
None, None, label, False, False)
return vnet_dict, vnet_bridges, netIdxLabel
def _find_physical_devices(self, vnet_bridges):
vnet_taps = []
for vm in self.conn.vms.values():
for nic in vm.get_network_devices(refresh_if_nec=False):
if nic.target_dev and nic.target_dev not in vnet_taps:
vnet_taps.append(nic.target_dev)
bridge_dict = {}
iface_dict = {}
hasShared = False
brIdxLabel = None
skip_ifaces = ["lo"]
for name in self.conn.list_net_device_paths():
br = self.conn.get_net_device(name)
bridge_name = br.get_bridge()
nettype = virtinst.VirtualNetworkInterface.TYPE_BRIDGE
if ((bridge_name in vnet_bridges) or
(br.get_name() in vnet_bridges) or
(br.get_name() in vnet_taps) or
(br.get_name() in [v + "-nic" for v in vnet_bridges]) or
(br.get_name() in skip_ifaces)):
# Don't list this, as it is basically duplicating
# virtual net info
continue
if br.is_shared():
sensitive = True
if br.get_bridge():
hasShared = True
brlabel = "(%s)" % self._pretty_network_desc(nettype,
bridge_name)
else:
bridge_name = name
brlabel = _("(Empty bridge)")
else:
if self.conn.check_support(
self.conn.SUPPORT_CONN_DIRECT_INTERFACE):
sensitive = True
nettype = virtinst.VirtualNetworkInterface.TYPE_DIRECT
bridge_name = name
brlabel = ": %s" % _("macvtap")
else:
sensitive = False
brlabel = "(%s)" % _("Not bridged")
label = _("Host device %s %s") % (br.get_name(), brlabel)
if hasShared and not brIdxLabel:
brIdxLabel = label
row = self._build_source_row(
nettype, bridge_name, label, sensitive, True,
key=br.get_name())
if sensitive:
bridge_dict[label] = row
else:
iface_dict[label] = row
return bridge_dict, iface_dict, brIdxLabel
def _populate_network_list(self):
net_list = self.widget("net-source")
model = net_list.get_model()
model.clear()
# For qemu:///session
if self.conn.is_qemu_session():
nettype = virtinst.VirtualNetworkInterface.TYPE_USER
r = self._build_source_row(
nettype, None, self._pretty_network_desc(nettype), True, True)
model.append(r)
net_list.set_active(0)
return
(vnet_dict, vnet_bridges, netIdxLabel) = self._find_virtual_networks()
(bridge_dict, iface_dict, brIdxLabel) = self._find_physical_devices(
vnet_bridges)
for indict in [bridge_dict, vnet_dict, iface_dict]:
keylist = indict.keys()
keylist.sort()
rowlist = [indict[k] for k in keylist]
for row in rowlist:
model.append(row)
# If there is a bridge device, default to that
# If not, use 'default' network
# If not present, use first list entry
# If list empty, use no network devices
label = brIdxLabel or netIdxLabel
default = 0
if not len(model):
row = self._build_source_row(
None, None, _("No networking"), True, False)
model.insert(0, row)
default = 0
elif label:
default = [idx for idx in range(len(model)) if
model[idx][2] == label][0]
# After all is said and done, add a manual bridge option
manual_row = self._build_source_row(
None, None, _("Specify shared device name"),
True, False, manual_bridge=True)
model.append(manual_row)
net_list.set_active(default)
###############
# Public APIs #
###############
def get_network_row(self):
return uiutil.get_list_selection(self.widget("net-source"))
def get_network_selection(self):
net_list = self.widget("net-source")
bridge_entry = self.widget("net-bridge-name")
row = uiutil.get_list_selection(net_list)
if not row:
return None, None, None
net_type = row[0]
net_src = row[1]
net_check_bridge = row[5]
if net_check_bridge and bridge_entry:
net_type = virtinst.VirtualNetworkInterface.TYPE_BRIDGE
net_src = bridge_entry.get_text()
mode = None
if self.widget("net-source-mode").is_visible():
mode = uiutil.get_list_selection(self.widget("net-source-mode"), 0)
return net_type, net_src, mode
def get_vport(self):
vport_type = self.widget("vport-type").get_text()
vport_managerid = self.widget("vport-managerid").get_text()
vport_typeid = self.widget("vport-typeid").get_text()
vport_idver = self.widget("vport-typeidversion").get_text()
vport_instid = self.widget("vport-instanceid").get_text()
return (vport_type, vport_managerid, vport_typeid,
vport_idver, vport_instid)
def validate_network(self, macaddr, model=None):
nettype, devname, mode = self.get_network_selection()
if nettype is None:
return None
net = None
# Make sure VirtualNetwork is running
netobj = None
if nettype == virtinst.VirtualNetworkInterface.TYPE_VIRTUAL:
for net in self.conn.nets.values():
if net.get_name() == devname:
netobj = net
break
if netobj and not netobj.is_active():
res = self.err.yes_no(_("Virtual Network is not active."),
_("Virtual Network '%s' is not active. "
"Would you like to start the network "
"now?") % devname)
if not res:
return False
# Try to start the network
try:
netobj.start()
netobj.tick()
logging.info("Started network '%s'", devname)
except Exception, e:
return self.err.show_err(_("Could not start virtual network "
"'%s': %s") % (devname, str(e)))
# Create network device
try:
net = virtinst.VirtualNetworkInterface(self.conn.get_backend())
net.type = nettype
net.source = devname
net.macaddr = macaddr
net.model = model
net.source_mode = mode
if net.model == "spapr-vlan":
net.address.set_addrstr("spapr-vio")
if net.type == "direct":
(vport_type, vport_managerid, vport_typeid,
vport_idver, vport_instid) = self.get_vport()
net.virtualport.type = vport_type or None
net.virtualport.managerid = vport_managerid or None
net.virtualport.typeid = vport_typeid or None
net.virtualport.typeidversion = vport_idver or None
net.virtualport.instanceid = vport_instid or None
except Exception, e:
return self.err.val_err(_("Error with network parameters."), e)
# Make sure there is no mac address collision
isfatal, errmsg = net.is_conflict_net(net.conn, net.macaddr)
if isfatal:
return self.err.val_err(_("Mac address collision."), errmsg)
elif errmsg is not None:
retv = self.err.yes_no(_("Mac address collision."),
_("%s Are you sure you want to use this address?") % errmsg)
if not retv:
return False
return net
def reset_state(self):
self._populate_network_list()
net_warn = self.widget("net-source-warn")
net_err = self.conn.netdev_error
net_warn.set_visible(bool(net_err))
net_warn.set_tooltip_text(net_err or "")
self.widget("net-bridge-name").set_text("")
self.widget("net-source-mode").set_active(0)
self.widget("vport-type").set_text("")
self.widget("vport-managerid").set_text("")
self.widget("vport-typeid").set_text("")
self.widget("vport-typeidversion").set_text("")
self.widget("vport-instanceid").set_text("")
def set_dev(self, net):
self.reset_state()
nettype = net.type
source = net.source
source_mode = net.source_mode
is_direct = (net.type == "direct")
uiutil.set_combo_entry(self.widget("net-source-mode"), source_mode)
# Virtualport config
self.widget("vport-expander").set_visible(is_direct)
vport = net.virtualport
self.widget("vport-type").set_text(vport.type or "")
self.widget("vport-managerid").set_text(str(vport.managerid or ""))
self.widget("vport-typeid").set_text(str(vport.typeid or ""))
self.widget("vport-typeidversion").set_text(
str(vport.typeidversion or ""))
self.widget("vport-instanceid").set_text(vport.instanceid or "")
# Find the matching row in the net list
combo = self.widget("net-source")
rowiter = None
for row in combo.get_model():
if row[0] == nettype and row[1] == source:
rowiter = row.iter
break
if not rowiter:
if nettype == "bridge":
rowiter = combo.get_model()[-1].iter
self.widget("net-bridge-name").set_text(source)
if not rowiter:
desc = self._pretty_network_desc(nettype, source)
combo.get_model().insert(0,
self._build_source_row(nettype, source, desc, True, True))
rowiter = combo.get_model()[0].iter
combo.set_active_iter(rowiter)
combo.emit("changed")
#############
# Listeners #
#############
def _emit_changed(self, *args, **kwargs):
ignore = args
ignore = kwargs
self.emit("changed")
def _emit_vport_changed(self, *args, **kwargs):
ignore = args
ignore = kwargs
self.emit("changed-vport")
def _on_net_source_changed(self, src):
self._emit_changed()
row = uiutil.get_list_selection(src)
if not row:
return
is_direct = (row[0] == virtinst.VirtualNetworkInterface.TYPE_DIRECT)
self.widget("vport-expander").set_visible(is_direct)
uiutil.set_grid_row_visible(self.widget("net-source-mode"), is_direct)
uiutil.set_grid_row_visible(
self.widget("net-macvtap-warn-box"), is_direct)
if is_direct and self.widget("net-source-mode").get_active() == -1:
self.widget("net-source-mode").set_active(0)
show_bridge = row[5]
uiutil.set_grid_row_visible(
self.widget("net-bridge-name"), show_bridge)

View File

@ -29,7 +29,6 @@ from gi.repository import Gtk
import virtinst
from virtManager import config
from virtManager import uiutil
############################################################
@ -224,299 +223,6 @@ def check_path_search_for_qemu(err, conn, path):
config.running_config.add_perms_fix_ignore(errors.keys())
#########################################
# VM <interface> device listing helpers #
#########################################
def _net_list_changed(net_list, bridge_box,
source_mode_combo, vport_expander):
if not bridge_box:
return
row = uiutil.get_list_selection(net_list)
if not row:
return
if source_mode_combo is not None:
doshow = (row[0] == virtinst.VirtualNetworkInterface.TYPE_DIRECT)
uiutil.set_grid_row_visible(source_mode_combo, doshow)
vport_expander.set_visible(doshow)
show_bridge = row[5]
uiutil.set_grid_row_visible(bridge_box, show_bridge)
def pretty_network_desc(nettype, source=None, netobj=None):
if nettype == virtinst.VirtualNetworkInterface.TYPE_USER:
return _("Usermode networking")
extra = None
if nettype == virtinst.VirtualNetworkInterface.TYPE_BRIDGE:
ret = _("Bridge")
elif nettype == virtinst.VirtualNetworkInterface.TYPE_VIRTUAL:
ret = _("Virtual network")
if netobj:
extra = ": %s" % netobj.pretty_forward_mode()
else:
ret = nettype.capitalize()
if source:
ret += " '%s'" % source
if extra:
ret += " %s" % extra
return ret
def build_network_list(net_list, bridge_box, source_mode_combo=None,
vport_expander=None):
# [ network type, source name, label, sensitive?, net is active,
# manual bridge, net instance]
net_model = Gtk.ListStore(str, str, str, bool, bool, bool, object)
net_list.set_model(net_model)
net_list.connect("changed", _net_list_changed, bridge_box,
source_mode_combo, vport_expander)
text = Gtk.CellRendererText()
net_list.pack_start(text, True)
net_list.add_attribute(text, 'text', 2)
net_list.add_attribute(text, 'sensitive', 3)
def get_network_selection(net_list, bridge_entry):
row = uiutil.get_list_selection(net_list)
if not row:
return None, None
net_type = row[0]
net_src = row[1]
net_check_bridge = row[5]
if net_check_bridge and bridge_entry:
net_type = virtinst.VirtualNetworkInterface.TYPE_BRIDGE
net_src = bridge_entry.get_text()
return net_type, net_src
def populate_network_list(net_list, conn, show_direct_interfaces=True):
model = net_list.get_model()
model.clear()
vnet_bridges = []
vnet_dict = {}
bridge_dict = {}
iface_dict = {}
def build_row(nettype, name, label, is_sensitive, is_running,
manual_bridge=False, key=None):
return [nettype, name, label,
is_sensitive, is_running, manual_bridge,
key]
def set_active(idx):
net_list.set_active(idx)
def add_dict(indict, model):
keylist = indict.keys()
keylist.sort()
rowlist = [indict[k] for k in keylist]
for row in rowlist:
model.append(row)
# For qemu:///session
if conn.is_qemu_session():
nettype = virtinst.VirtualNetworkInterface.TYPE_USER
r = build_row(nettype, None, pretty_network_desc(nettype), True, True)
model.append(r)
set_active(0)
return
hasNet = False
netIdxLabel = None
# Virtual Networks
for uuid in conn.list_net_uuids():
net = conn.get_net(uuid)
nettype = virtinst.VirtualNetworkInterface.TYPE_VIRTUAL
label = pretty_network_desc(nettype, net.get_name(), net)
if not net.is_active():
label += " (%s)" % _("Inactive")
hasNet = True
# FIXME: Should we use 'default' even if it's inactive?
# FIXME: This preference should be configurable
if net.get_name() == "default":
netIdxLabel = label
vnet_dict[label] = build_row(nettype, net.get_name(), label, True,
net.is_active(), key=net.get_uuid())
# Build a list of vnet bridges, so we know not to list them
# in the physical interface list
vnet_bridge = net.get_bridge_device()
if vnet_bridge:
vnet_bridges.append(vnet_bridge)
if not hasNet:
label = _("No virtual networks available")
vnet_dict[label] = build_row(None, None, label, False, False)
vnet_taps = []
for vm in conn.vms.values():
for nic in vm.get_network_devices(refresh_if_nec=False):
if nic.target_dev and nic.target_dev not in vnet_taps:
vnet_taps.append(nic.target_dev)
skip_ifaces = ["lo"]
# Physical devices
hasShared = False
brIdxLabel = None
for name in conn.list_net_device_paths():
br = conn.get_net_device(name)
bridge_name = br.get_bridge()
nettype = virtinst.VirtualNetworkInterface.TYPE_BRIDGE
if ((bridge_name in vnet_bridges) or
(br.get_name() in vnet_bridges) or
(br.get_name() in vnet_taps) or
(br.get_name() in [v + "-nic" for v in vnet_bridges]) or
(br.get_name() in skip_ifaces)):
# Don't list this, as it is basically duplicating virtual net info
continue
if br.is_shared():
sensitive = True
if br.get_bridge():
hasShared = True
brlabel = "(%s)" % pretty_network_desc(nettype, bridge_name)
else:
bridge_name = name
brlabel = _("(Empty bridge)")
else:
if (show_direct_interfaces and
conn.check_support(
conn.SUPPORT_CONN_DIRECT_INTERFACE)):
sensitive = True
nettype = virtinst.VirtualNetworkInterface.TYPE_DIRECT
bridge_name = name
brlabel = ": %s" % _("macvtap")
else:
sensitive = False
brlabel = "(%s)" % _("Not bridged")
label = _("Host device %s %s") % (br.get_name(), brlabel)
if hasShared and not brIdxLabel:
brIdxLabel = label
row = build_row(nettype, bridge_name, label, sensitive, True,
key=br.get_name())
if sensitive:
bridge_dict[label] = row
else:
iface_dict[label] = row
add_dict(bridge_dict, model)
add_dict(vnet_dict, model)
add_dict(iface_dict, model)
# If there is a bridge device, default to that
# If not, use 'default' network
# If not present, use first list entry
# If list empty, use no network devices
return_warn = False
label = brIdxLabel or netIdxLabel
for idx in range(len(model)):
row = model[idx]
is_inactive = not row[4]
if label:
if row[2] == label:
default = idx
return_warn = is_inactive
break
else:
if row[3] is True:
default = idx
return_warn = is_inactive
break
else:
return_warn = True
row = build_row(None, None, _("No networking"), True, False)
model.insert(0, row)
default = 0
# After all is said and done, add a manual bridge option
manual_row = build_row(None, None, _("Specify shared device name"),
True, False, manual_bridge=True)
model.append(manual_row)
set_active(default)
return return_warn
def validate_network(err, conn, nettype, devname, macaddr, model=None):
net = None
if nettype is None:
return None
# Make sure VirtualNetwork is running
netobj = None
if nettype == virtinst.VirtualNetworkInterface.TYPE_VIRTUAL:
for net in conn.nets.values():
if net.get_name() == devname:
netobj = net
break
if netobj and not netobj.is_active():
res = err.yes_no(_("Virtual Network is not active."),
_("Virtual Network '%s' is not active. "
"Would you like to start the network "
"now?") % devname)
if not res:
return False
# Try to start the network
try:
netobj.start()
netobj.tick()
logging.info("Started network '%s'", devname)
except Exception, e:
return err.show_err(_("Could not start virtual network "
"'%s': %s") % (devname, str(e)))
# Create network device
try:
net = virtinst.VirtualNetworkInterface(conn.get_backend())
net.type = nettype
net.source = devname
net.macaddr = macaddr
net.model = model
if net.model == "spapr-vlan":
net.address.set_addrstr("spapr-vio")
except Exception, e:
return err.val_err(_("Error with network parameters."), e)
# Make sure there is no mac address collision
isfatal, errmsg = net.is_conflict_net(conn.get_backend(), net.macaddr)
if isfatal:
return err.val_err(_("Mac address collision."), errmsg)
elif errmsg is not None:
retv = err.yes_no(_("Mac address collision."),
_("%s Are you sure you want to use this "
"address?") % errmsg)
if not retv:
return False
return net
############################################
# Populate media widget (choosecd, create) #
############################################

View File

@ -122,6 +122,37 @@ def set_row_selection(listwidget, prevkey):
selection.emit("changed")
def set_combo_entry(combo, value):
"""
Search the passed combobox for value, comparing against the
first item in each row. If found, select it. If not found, and
the combobox has a text entry, stick the value in their and
select it.
"""
idx = -1
model_list = [x[0] for x in combo.get_model()]
model_in_list = (value in model_list)
if model_in_list:
idx = model_list.index(value)
combo.set_active(idx)
if idx == -1 and combo.get_has_entry():
combo.get_child().set_text(value or "")
def get_combo_entry(combo):
"""
Helper to get the value specified in a combo box, with or
without and entry
"""
ret = get_list_selection(combo, 0)
if ret:
return ret
if not combo.get_has_entry():
return None
return combo.get_child().get_text().strip()
def child_get_property(parent, child, propname):
"""
Wrapper for child_get_property, which pygobject doesn't properly