Allow user to set mac addresses for new guests and new guest nics. Also fixes some validation bugs. Thanks to Masayuki Sunou <fj1826dm@aa.jp.fujitsu.com>

This commit is contained in:
Hugh O. Brock 2007-05-24 15:51:32 -04:00
parent b20c71f829
commit c3b4a9da71
4 changed files with 354 additions and 10 deletions

View File

@ -71,6 +71,7 @@ class vmmAddHardware(gobject.GObject):
"on_storage_file_address_changed": self.toggle_storage_size,
"on_storage_toggled" : self.change_storage_type,
"on_network_toggled" : self.change_network_type,
"on_mac_address_clicked" : self.change_macaddr_use,
"on_create_help_clicked": self.show_help,
})
@ -138,6 +139,7 @@ class vmmAddHardware(gobject.GObject):
self.change_storage_type()
self.change_network_type()
self.change_macaddr_use()
if os.getuid() == 0:
self.window.get_widget("storage-partition").set_active(True)
else:
@ -212,6 +214,12 @@ class vmmAddHardware(gobject.GObject):
model = dev.get_model()
return ["bridge", model.get_value(dev.get_active_iter(), 0)]
def get_config_macaddr(self):
macaddr = None
if self.window.get_widget("mac-address").get_active():
macaddr = self.window.get_widget("create-mac-address").get_text()
return macaddr
def page_changed(self, notebook, page, page_number):
if page_number == PAGE_DISK:
pass
@ -244,6 +252,11 @@ class vmmAddHardware(gobject.GObject):
self.window.get_widget("summary-net-target").set_text("-")
else:
raise ValueError, "Unknown networking type " + net[0]
macaddr = self.get_config_macaddr()
if macaddr != None:
self.window.get_widget("summary-mac-address").set_text(macaddr)
else:
self.window.get_widget("summary-mac-address").set_text("-")
def close(self, ignore1=None,ignore2=None):
self.topwin.hide()
@ -286,11 +299,12 @@ class vmmAddHardware(gobject.GObject):
def add_network(self):
net = self.get_config_network()
mac = self.get_config_macaddr()
vnic = None
if net[0] == "bridge":
vnic = virtinst.VirtualNetworkInterface(type=net[0], bridge=net[1])
vnic = virtinst.VirtualNetworkInterface(macaddr=mac, type=net[0], bridge=net[1])
elif net[0] == "network":
vnic = virtinst.VirtualNetworkInterface(type=net[0], network=net[1])
vnic = virtinst.VirtualNetworkInterface(macaddr=mac, type=net[0], network=net[1])
else:
raise ValueError, "Unsupported networking type " + net[0]
@ -446,6 +460,12 @@ class vmmAddHardware(gobject.GObject):
self.window.get_widget("net-network").set_sensitive(False)
self.window.get_widget("net-device").set_sensitive(True)
def change_macaddr_use(self, ignore=None):
if self.window.get_widget("mac-address").get_active():
self.window.get_widget("create-mac-address").set_sensitive(True)
else:
self.window.get_widget("create-mac-address").set_sensitive(False)
def validate(self, page_num):
if page_num == PAGE_INTRO:
if self.get_config_hardware_type() == None:
@ -484,6 +504,29 @@ class vmmAddHardware(gobject.GObject):
_("You must select one of the physical devices"))
return False
if self.window.get_widget("mac-address").get_active():
mac= self.window.get_widget("create-mac-address").get_text()
if len(mac) != 17:
self._validation_error_box(_("Invalid MAC address"), \
_("MAC adrress must be 17 characters"))
return False
if re.match("^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$",mac) == None:
self._validation_error_box(_("Invalid MAC address"), \
_("MAC address must be a form such as AA:BB:CC:DD:EE:FF, and MAC adrress may contain numeric and alphabet of A-F(a-f) and ':' characters only"))
return False
hostdevs = virtinst.util.get_host_network_devices()
for hostdev in hostdevs:
if mac.lower() == hostdev[4]:
return self._yes_no_box(_('MAC adress "%s" is already in use by host!' % mac), \
_("Do you really want to use the MAC address ?"))
vms = []
for domains in self.vm.get_connection().vms.values():
vms.append(domains.vm)
vnic = virtinst.VirtualNetworkInterface(macaddr=mac)
if vnic.countMACaddr(vms) > 0:
return self._yes_no_box(_('MAC adress "%s" is already in use by another guest!' % mac), \
_("Do you really want to use the MAC address ?"))
return True
def _validation_error_box(self, text1, text2=None):

View File

@ -92,6 +92,7 @@ class vmmCreate(gobject.GObject):
"on_storage_file_address_changed": self.toggle_storage_size,
"on_storage_toggled" : self.change_storage_type,
"on_network_toggled" : self.change_network_type,
"on_mac_address_clicked" : self.change_macaddr_use,
"on_media_toggled" : self.change_media_type,
"on_os_type_changed" : self.change_os_type,
"on_cpu_architecture_changed": self.change_cpu_arch,
@ -238,6 +239,7 @@ class vmmCreate(gobject.GObject):
self.change_media_type()
self.change_storage_type()
self.change_network_type()
self.change_macaddr_use()
self.window.get_widget("create-vm-name").set_text("")
self.window.get_widget("media-iso-image").set_active(True)
self.window.get_widget("fv-iso-location").set_text("")
@ -362,6 +364,12 @@ class vmmCreate(gobject.GObject):
model = dev.get_model()
return ["bridge", model.get_value(dev.get_active_iter(), 0)]
def get_config_macaddr(self):
macaddr = None
if self.window.get_widget("mac-address").get_active():
macaddr = self.window.get_widget("create-mac-address").get_text()
return macaddr
def get_config_maximum_memory(self):
return self.window.get_widget("create-memory-max").get_value()
@ -449,6 +457,12 @@ class vmmCreate(gobject.GObject):
self.window.get_widget("summary-net-target").set_text("-")
else:
raise ValueError, "Unknown networking type " + net[0]
macaddr = self.get_config_macaddr()
if macaddr != None:
self.window.get_widget("summary-mac-address").set_text(macaddr)
else:
self.window.get_widget("summary-mac-address").set_text("-")
self.window.get_widget("create-forward").hide()
self.window.get_widget("create-finish").show()
@ -543,12 +557,13 @@ class vmmCreate(gobject.GObject):
# network
net = self.get_config_network()
mac = self.get_config_macaddr()
if net[0] == "bridge":
guest.nics.append(virtinst.VirtualNetworkInterface(type=net[0], bridge=net[1]))
guest.nics.append(virtinst.VirtualNetworkInterface(macaddr=mac, type=net[0], bridge=net[1]))
elif net[0] == "network":
guest.nics.append(virtinst.VirtualNetworkInterface(type=net[0], network=net[1]))
guest.nics.append(virtinst.VirtualNetworkInterface(macaddr=mac, type=net[0], network=net[1]))
elif net[0] == "user":
guest.nics.append(virtinst.VirtualNetworkInterface(type=net[0]))
guest.nics.append(virtinst.VirtualNetworkInterface(macaddr=mac, type=net[0]))
else:
raise ValueError, "Unsupported networking type " + net[0]
@ -757,6 +772,12 @@ class vmmCreate(gobject.GObject):
self.window.get_widget("net-network").set_sensitive(False)
self.window.get_widget("net-device").set_sensitive(True)
def change_macaddr_use(self, ignore=None):
if self.window.get_widget("mac-address").get_active():
self.window.get_widget("create-mac-address").set_sensitive(True)
else:
self.window.get_widget("create-mac-address").set_sensitive(False)
def set_max_memory(self, src):
max_memory = src.get_adjustment().value
startup_mem_adjustment = self.window.get_widget("create-memory-startup").get_adjustment()
@ -771,7 +792,7 @@ class vmmCreate(gobject.GObject):
self._validation_error_box(_("Invalid System Name"), \
_("System name must be non-blank and less than 50 characters"))
return False
if re.match("^[a-zA-Z0-9_]*$", name) == None:
if re.match("^[a-zA-Z0-9_-]*$", name) == None:
self._validation_error_box(_("Invalid System Name"), \
_("System name may contain alphanumeric and '_' characters only"))
return False
@ -838,6 +859,28 @@ class vmmCreate(gobject.GObject):
_("You must select one of the physical devices"))
return False
if self.window.get_widget("mac-address").get_active():
mac = self.window.get_widget("create-mac-address").get_text()
if len(mac) != 17:
self._validation_error_box(_("Invalid MAC address"), \
_("MAC adrress must be 17 characters"))
return False
if re.match("^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$",mac) == None:
self._validation_error_box(_("Invalid MAC address"), \
_("MAC address must be a form such as AA:BB:CC:DD:EE:FF, and MAC adrress may contain numeric and alphabet of A-F(a-f) and ':' characters only"))
return False
hostdevs = virtinst.util.get_host_network_devices()
for hostdev in hostdevs:
if mac.lower() == hostdev[4]:
return self._yes_no_box(_('MAC adress "%s" is already in use by host!' % mac), \
_("Do you really want to use the MAC address ?"))
vms = []
for domains in self.connection.vms.values():
vms.append(domains.vm)
vnic = virtinst.VirtualNetworkInterface(macaddr=mac)
if vnic.countMACaddr(vms) > 0:
return self._yes_no_box(_('MAC adress "%s" is already in use by another guest!' % mac), \
_("Do you really want to use the MAC address ?"))
# do this always, since there's no "leaving a notebook page" event.
self.window.get_widget("create-back").set_sensitive(True)

View File

@ -992,7 +992,7 @@
<child>
<widget class="GtkTable" id="table31">
<property name="visible">True</property>
<property name="n_rows">6</property>
<property name="n_rows">8</property>
<property name="n_columns">2</property>
<property name="homogeneous">False</property>
<property name="row_spacing">6</property>
@ -1319,6 +1319,79 @@
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="mac-address">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Set _fixed MAC address for this NIC?</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
<signal name="clicked" handler="on_mac_address_clicked" last_modification_time="Wed, 16 May 2007 02:31:50 GMT"/>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">2</property>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label386">
<property name="visible">True</property>
<property name="label" translatable="yes">_MAC address:</property>
<property name="use_underline">True</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">create-mac-address</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">7</property>
<property name="bottom_attach">8</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="create-mac-address">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">17</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">•</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">7</property>
<property name="bottom_attach">8</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
</child>
</widget>
@ -1597,7 +1670,7 @@
<widget class="GtkTable" id="summary-network">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="n_rows">4</property>
<property name="n_columns">3</property>
<property name="homogeneous">False</property>
<property name="row_spacing">3</property>
@ -1742,6 +1815,62 @@
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label387">
<property name="visible">True</property>
<property name="label" translatable="yes">MAC address:</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<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">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary-mac-address">
<property name="visible">True</property>
<property name="label" translatable="yes">-</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>

View File

@ -3118,7 +3118,7 @@ mipsel</property>
<child>
<widget class="GtkTable" id="table31">
<property name="visible">True</property>
<property name="n_rows">6</property>
<property name="n_rows">8</property>
<property name="n_columns">2</property>
<property name="homogeneous">False</property>
<property name="row_spacing">6</property>
@ -3445,6 +3445,79 @@ mipsel</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label385">
<property name="visible">True</property>
<property name="label" translatable="yes">_MAC address:</property>
<property name="use_underline">True</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">create-mac-address</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">7</property>
<property name="bottom_attach">8</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="mac-address">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Set _fixed MAC address for your virtual system?</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
<signal name="clicked" handler="on_mac_address_clicked" last_modification_time="Tue, 15 May 2007 02:05:47 GMT"/>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">2</property>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="create-mac-address">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">17</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">•</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">7</property>
<property name="bottom_attach">8</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
</child>
</widget>
@ -4225,7 +4298,7 @@ mipsel</property>
<widget class="GtkTable" id="table29">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="n_rows">16</property>
<property name="n_rows">17</property>
<property name="n_columns">3</property>
<property name="homogeneous">False</property>
<property name="row_spacing">3</property>
@ -5038,6 +5111,62 @@ mipsel</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label386">
<property name="visible">True</property>
<property name="label" translatable="yes">MAC address:</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">16</property>
<property name="bottom_attach">17</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary-mac-address">
<property name="visible">True</property>
<property name="label" translatable="yes">-</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">16</property>
<property name="bottom_attach">17</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
</child>
</widget>