[et-mgmt-tools] [PATCH] virt-manager validation and error reporting improvements

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi All,

Attached is a patch that adds validation and error reporting improvements to virt-manager's creation wizard. It removes redundant checking and places the burden solely on virtinst, by plugging the parameters into a virtinst Guest object as it goes to get the error reporting and validation for free. This also simplifies the final setup before beginning the install.

Signed-off-by: Cole Robinson <crobinso@xxxxxxxxxx>

Thanks,
Cole

--
Cole Robinson
crobinso@xxxxxxxxxx
diff -r 27ad8c7fbc3e src/virtManager/create.py
--- a/src/virtManager/create.py	Thu May 24 16:49:13 2007 -0400
+++ b/src/virtManager/create.py	Sun Jun 17 15:47:53 2007 -0400
@@ -102,6 +102,11 @@ class vmmCreate(gobject.GObject):
 
         self.set_initial_state()
 
+        # Guest to fill in with values along the way
+        self._guest = virtinst.Guest(type=self.get_domain_type())
+        self._disk = None
+        self._net = None
+
     def show(self):
         self.topwin.show()
         self.reset_state()
@@ -476,97 +481,28 @@ class vmmCreate(gobject.GObject):
         return 0
 
     def finish(self, ignore=None):
-        # first things first, are we trying to create a fully virt guest?
-        if self.get_config_method() == VM_FULLY_VIRT:
-            guest = virtinst.FullVirtGuest(type=self.get_domain_type(), \
-                                           hypervisorURI=self.connection.get_uri(), \
-                                           arch=self.get_domain_arch())
-            try:
-                guest.cdrom = self.get_config_install_source()
-            except ValueError, e:
-                self._validation_error_box(_("Invalid FV media address"),e.args[0])
-            try:
-                if self.get_config_os_type() is not None and self.get_config_os_type() != "generic":
-                    logging.debug("OS Type: %s" % self.get_config_os_type())
-                    guest.os_type = self.get_config_os_type()
-            except ValueError, e:
-                self._validation_error_box(_("Invalid FV OS Type"),e.args[0])
-            try:
-                if self.get_config_os_variant() is not None and self.get_config_os_type() != "generic":
-                    logging.debug("OS Variant: %s" % self.get_config_os_variant())
-                    guest.os_variant = self.get_config_os_variant()
-            except ValueError, e:
-                self._validation_error_box(_("Invalid FV OS Variant"),e.args[0])
-
-        else:
-            guest = virtinst.ParaVirtGuest(type=self.get_domain_type(), hypervisorURI=self.connection.get_uri())
-            try:
-                guest.location = self.get_config_install_source()
-            except ValueError, e:
-                self._validation_error_box(_("Invalid PV media address"), e.args[0])
-                return
-            ks = self.get_config_kickstart_source()
-            if ks != None and len(ks) != 0:
-                guest.extraargs = "ks=%s" % ks
-
-        # set the name
+        # Validation should have mostly set up out guest. We just need
+        # to take care of a few pieces we didn't touch
+
+        guest = self._guest
+        guest.hypervisorURI = self.connection.get_uri()
+
+        # UUID, append disk and nic
         try:
-            guest.name = self.get_config_name()
+            guest.uuid = virtinst.util.uuidToString(virtinst.util.randomUUID())
+        except ValueError, E:
+            self._validation_error_box(_("UUID Error"), str(e))
+
+        try:
+            guest.disks.append(self._disk)
         except ValueError, e:
-            self._validation_error_box(_("Invalid system name"), e.args[0])
-            return
-
-        # set the memory
+            self._validation_error_box(_("Error Setting up Disk"), str(e))
+        
         try:
-            guest.memory = int(self.get_config_initial_memory())
-        except ValueError:
-            self._validation_error_box(_("Invalid memory setting"), e.args[0])
-            return
-
-        try:
-            guest.maxmemory = int(self.get_config_maximum_memory())
-        except ValueError:
-            self._validation_error_box(_("Invalid memory setting"), e.args[0])
-            return
-
-        # set vcpus
-        guest.vcpus = int(self.get_config_virtual_cpus())
-
-        # disks
-        filesize = None
-        if self.get_config_disk_size() != None:
-            filesize = self.get_config_disk_size() / 1024.0
-        try:
-            d = virtinst.VirtualDisk(self.get_config_disk_image(), filesize, sparse = self.is_sparse_file())
-            if d.type == virtinst.VirtualDisk.TYPE_FILE and \
-                   self.get_config_method() == VM_PARA_VIRT \
-                   and virtinst.util.is_blktap_capable():
-                d.driver_name = virtinst.VirtualDisk.DRIVER_TAP
-            if d.type == virtinst.VirtualDisk.TYPE_FILE and not \
-               self.is_sparse_file():
-                self.non_sparse = True
-            else:
-                self.non_sparse = False
+            guest.nics.append(self._net)
         except ValueError, e:
-            self._validation_error_box(_("Invalid storage address"), e.args[0])
-            return
-        guest.disks.append(d)
-
-        # uuid
-        guest.uuid = virtinst.util.uuidToString(virtinst.util.randomUUID())
-
-        # network
-        net = self.get_config_network()
-        mac = self.get_config_macaddr()
-        if net[0] == "bridge":
-            guest.nics.append(virtinst.VirtualNetworkInterface(macaddr=mac, type=net[0], bridge=net[1]))
-        elif net[0] == "network":
-            guest.nics.append(virtinst.VirtualNetworkInterface(macaddr=mac, type=net[0], network=net[1]))
-        elif net[0] == "user":
-            guest.nics.append(virtinst.VirtualNetworkInterface(macaddr=mac, type=net[0]))
-        else:
-            raise ValueError, "Unsupported networking type " + net[0]
-
+            self._validation_error_box(_("Error Setting up Network"), str(e))
+            
         # set up the graphics to use SDL
         import keytable
         keymap = None
@@ -596,7 +532,7 @@ class vmmCreate(gobject.GObject):
                       "\n  Memory: " + str(guest.memory) + \
                       "\n  Max Memory: " + str(guest.maxmemory) + \
                       "\n  # VCPUs: " + str(guest.vcpus) + \
-                      "\n  Filesize: " + str(filesize) + \
+                      "\n  Filesize: " + str(self._disk.size) + \
                       "\n  Disk image: " + str(self.get_config_disk_image()) +\
                       "\n  Non-sparse file: " + str(self.non_sparse))
 
@@ -786,34 +722,42 @@ class vmmCreate(gobject.GObject):
         startup_mem_adjustment.upper = max_memory
 
     def validate(self, page_num):
+
+        # Setting the values in the Guest/Disk/Network virtinst objects
+        # provides a lot of error checking for free, we just have to catch
+        # the messages
+
         if page_num == PAGE_NAME:
             name = self.window.get_widget("create-vm-name").get_text()
-            if len(name) > 50 or len(name) == 0:
-                self._validation_error_box(_("Invalid System Name"), \
-                                           _("System name must be non-blank and less than 50 characters"))
+            try:
+                self._guest.name = name
+            except ValueError, e:
+                self._validation_error_box(_("Invalid System Name"), str(e))
                 return False
-            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
-
-
+                                           
         elif page_num == PAGE_TYPE:
-            if self.get_config_method() == VM_FULLY_VIRT and self.connection.get_type().startswith("Xen") and not virtinst.util.is_hvm_capable():
-                self._validation_error_box(_("Hardware Support Required"), \
-                                           _("Your hardware does not appear to support full virtualization. Only paravirtualized guests will be available on this hardware."))
-                return False
+
+            # Set up appropriate guest object dependent on selected type
+            tmpguest = self._guest
+            if self.get_config_method() == VM_PARA_VIRT:
+                self._guest = virtinst.ParaVirtGuest(\
+                                        type=self.get_domain_type())
+            else:
+                self._guest = virtinst.FullVirtGuest(\
+                                        type=self.get_domain_type(), \
+                                        arch=self.get_domain_arch())
+            
+            self._guest.name = tmpguest.get_name() # Transfer name over
 
         elif page_num == PAGE_FVINST:
+
             if self.window.get_widget("media-iso-image").get_active():
+
                 src = self.get_config_install_source()
-                if src == None or len(src) == 0:
-                    self._validation_error_box(_("ISO Path Required"), \
-                                               _("You must specify an ISO location for the guest installation"))
-                    return False
-                elif not(os.path.exists(src)):
-                    self._validation_error_box(_("ISO Path Not Found"), \
-                                               _("You must specify a valid path to the ISO image for guest installation"))
+                try:
+                    self._guest.cdrom = src
+                except ValueError, e:
+                    self._validation_error_box(_("ISO Path Not Found"), str(e))
                     return False
             else:
                 cdlist = self.window.get_widget("cd-path")
@@ -821,33 +765,93 @@ class vmmCreate(gobject.GObject):
                     self._validation_error_box(_("Install media required"), \
                                                _("You must select the CDROM install media for guest installation"))
                     return False
+                src = self.get_config_install_source()
+                try:
+                    self._guest.cdrom = src
+                except ValueError, e:
+                    self._validation_error_box(_("CD-ROM Path Error"), str(e))
+                    return False
+            
+            try:
+                if self.get_config_os_type() is not None \
+                   and self.get_config_os_type() != "generic":
+                    logging.debug("OS Type: %s" % self.get_config_os_type())
+                    guest.os_type = self.get_config_os_type()
+            except ValueError, e:
+                self._validation_error_box(_("Invalid FV OS Type"), str(e))
+
+            try:
+                if self.get_config_os_variant() is not None \
+                   and self.get_config_os_type() != "generic":
+                    logging.debug("OS Variant: %s" % self.get_config_os_variant())
+                    guest.os_variant = self.get_config_os_variant()
+            except ValueError, e:
+                self._validation_error_box(_("Invalid FV OS Variant"), str(e))
+
         elif page_num == PAGE_PVINST:
+
             src = self.get_config_install_source()
-            if src == None or len(src) == 0:
-                self._validation_error_box(_("URL Required"), \
-                                           _("You must specify a URL for the install image for the guest install"))
+            try:
+                self._guest.location = src
+            except ValueError, e:
+                self._validation_error_box(_("Install URL Required"), str(e))
                 return False
 
+            ks = self.get_config_kickstart_source()
+            if ks is not None and len(ks) != 0:
+                if not (ks.startswith("http://";) or ks.startswith("ftp://";) \
+                        or ks.startswith("nfs:")):
+                    self._validation_error_box(_("Kickstart URL Error"), \
+                                               _("Kickstart location must be an NFS, HTTP or FTP source"))
+                    return False
+                else:
+                    self._guest.extraargs = "ks=%s" % (ks,)
+
         elif page_num == PAGE_DISK:
+            
             disk = self.get_config_disk_image()
             if disk == None or len(disk) == 0:
                 self._validation_error_box(_("Storage Address Required"), \
                                            _("You must specify a partition or a file for storage for the guest install"))
                 return False
-
-            if not self.window.get_widget("storage-partition").get_active():
-                if os.path.isdir(disk):
-                    self._validation_error_box(_("Storage Address Is Directory"), \
-                                               _("You chose 'Simple File' storage for your storage method, but chose a directory instead of a file. Please enter a new filename or choose an existing file."))
-                    return False
-
-            d = virtinst.VirtualDisk(self.get_config_disk_image(), self.get_config_disk_size(), sparse = self.is_sparse_file())
-            if d.is_conflict_disk(self.connection.vmm) is True:
-               res = self._yes_no_box(_('Disk "%s" is already in use by another guest!' % disk), \
-                                               _("Do you really want to use the disk ?"))
+            
+            # Attempt to set disk
+            filesize = None
+            if self.get_config_disk_size() != None:
+                filesize = self.get_config_disk_size() / 1024.0
+            try:
+                if self.window.get_widget("storage-partition").get_active():
+                    type = virtinst.VirtualDisk.TYPE_BLOCK
+                else:
+                    type = virtinst.VirtualDisk.TYPE_FILE
+
+                self._disk = virtinst.VirtualDisk(\
+                                        self.get_config_disk_image(), \
+                                        filesize, \
+                                        sparse = self.is_sparse_file(), \
+                                        type=type)
+
+                if self._disk.type == virtinst.VirtualDisk.TYPE_FILE and \
+                   self.get_config_method() == VM_PARA_VIRT and \
+                   virtinst.util.is_blktap_capable():
+                    self._disk.driver_name = virtinst.VirtualDisk.DRIVER_TAP
+
+                if self._disk.type == virtinst.VirtualDisk.TYPE_FILE and not \
+                   self.is_sparse_file():
+                    self.non_sparse = True
+                else:
+                    self.non_sparse = False
+            except ValueError, e:
+                self._validation_error_box(_("Invalid Storage Address"), \
+                                            str(e))
+                return False
+
+            if self._disk.is_conflict_disk(self.connection.vmm) is True:
+               res = self._yes_no_box(_('Disk "%s" is already in use by another guest!' % disk), _("Do you really want to use the disk ?"))
                return res
 
         elif page_num == PAGE_NETWORK:
+
             if self.window.get_widget("net-type-network").get_active():
                 if self.window.get_widget("net-network").get_active() == -1:
                     self._validation_error_box(_("Virtual Network Required"),
@@ -859,28 +863,72 @@ class vmmCreate(gobject.GObject):
                                                _("You must select one of the physical devices"))
                     return False
 
+            net = self.get_config_network()
+
             if self.window.get_widget("mac-address").get_active():
                 mac = self.window.get_widget("create-mac-address").get_text()
-                if len(mac) != 17:
+                if mac is None or len(mac) == 0:
                     self._validation_error_box(_("Invalid MAC address"), \
-                                               _("MAC adrress must be 17 characters"))
+                                               _("No MAC Address was entered. Please enter a valid MAC address."))
                     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"))
+                try:
+                    self._guest.mac = mac
+                except ValueError, e:
+                    self._validation_error_box(_("Invalid Mac Address"), \
+                                                str(e))
                     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 ?"))
+                        return self._yes_no_box(_('MAC adress "%s" is already in use by host!' % mac), _("Do you really want to use the MAC address ?"))
+            else:
+                mac = None
+            try:    
+                if net[0] == "bridge":
+                    self._net = virtinst.VirtualNetworkInterface(macaddr=mac, \
+                                                                 type=net[0], \
+                                                                 bridge=net[1])
+                elif net[0] == "network":
+                    self._net = virtinst.VirtualNetworkInterface(macaddr=mac, \
+                                                                 type=net[0], \
+                                                                 network=net[1])
+                elif net[0] == "user":
+                    self._net = virtinst.VirtualNetworkInterface(macaddr=mac, \
+                                                                 type=net[0])
+            except ValueError, e:
+                self._validation_error_box(_("Network Parameter Error"), \
+                                            str(e))
+                return False
+
+            vms = []
+            for domains in self.connection.vms.values():
+                vms.append(domains.vm)
+            if self._net.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 ?"))
+
+        elif page_num == PAGE_CPUMEM:
+
+            # Set vcpus
+            try:
+                self._guest.vcpus = int(self.get_config_virtual_cpus())
+            except ValueError, e: 
+                self._validation_error_box(_("VCPU Count Error"), \
+                                            str(e))
+
+            # Set Memory
+            try:
+                self._guest.memory = int(self.get_config_initial_memory())
+            except ValueError, e: 
+                self._validation_error_box(_("Memory Amount Error"), \
+                                            str(e))
+
+            # Set Max Memory
+            try:
+                self._guest.maxmemory = int(self.get_config_maximum_memory())
+            except ValueError, e: 
+                self._validation_error_box(_("Max Memory Amount Error"), \
+                                            str(e))
 
         # do this always, since there's no "leaving a notebook page" event.
         self.window.get_widget("create-back").set_sensitive(True)

[Index of Archives]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux