def partition(self): """ TODO: before step 3, wipe drive and use the default disklabel for arch skip fixed partitions in all passes (in GLISD maybe?) """ parts_old = {} parts_new = self._install_profile.get_partition_tables() for device in GLIStorageDevice.detect_devices(): parts_old[device] = GLIStorageDevice.Device( device, arch=self._client_configuration.get_architecture_template()) parts_old[device].set_partitions_from_disk() self.notify_frontend("progress", (0, "Examining partitioning data")) total_steps = float(len(parts_new) * 4) # 4 for the number of passes over each device cur_progress = 0 for device in parts_new: # Skip this device in parts_new if device isn't detected on current system if not device in parts_old: self._logger.log( "There is no physical device " + device + " detected to match the entry in the install profile...skipping" ) continue # This just makes things simpler in the code newparts = parts_new[device] oldparts = parts_old[device] # Check to see if the old and new partition table structures are the same...skip if they are if not self._check_table_changed(oldparts, newparts): self._logger.log("Partition table for " + device + " is unchanged...skipping") continue self._logger.log("partition(): Processing " + device + "...") # Commit ritual sepuku if there are any mounted filesystems on this device if GLIUtility.spawn("mount | grep '^" + device + "'", return_output=True)[1].strip(): raise GLIException( "PartitionsMountedError", 'fatal', 'partition', "Cannot partition " + device + " due to filesystems being mounted") # We also can't handle "unknown" partitions for part in newparts: if newparts[part]['type'] == "unknown": raise GLIException( "UnknownPartitionTypeError", 'fatal', 'partition', "Refusing to partition this drive due to the presence of an unknown type of partition" ) # Create pyparted objects for this device parted_dev = parted.PedDevice.get(device) try: parted_disk = parted.PedDisk.new(parted_dev) except: if self._debug: self._logger.log( "partition(): could not load existing disklabel...creating new one" ) parted_disk = parted_dev.disk_new_fresh( parted.disk_type_get( (newparts.get_disklabel() or GLIStorageDevice.archinfo[self._architecture_name]))) # Iterate through new partitions and check for 'origminor' and 'format' == False for part in newparts: tmppart_new = newparts[part] if not tmppart_new['origminor'] or tmppart_new['format']: continue if not tmppart_new['origminor'] in oldparts: raise GLIException( "MissingPartitionsError", 'fatal', 'partition', "Cannot find the existing partition that a new one refers to. This is not a bug. This is in fact your (the user's) fault. You should not reuse the installprofile.xml from a previous install that started the partitioning step." ) tmppart_old = oldparts[tmppart_new['origminor']] if parted_disk.type.check_feature( parted.DISK_TYPE_PARTITION_NAME): tmppart_new['name'] = tmppart_old['name'] tmppart_new['flags'] = tmppart_old['flags'] if tmppart_new['resized']: # Partition is being resized in the new layout self._logger.log( " Partition " + str(part) + " has origminor " + str(tmppart_new['origminor']) + " and it being resized...saving start sector " + str(tmppart_old['start'])) tmppart_new['start'] = tmppart_old['start'] tmppart_new['end'] = 0 else: # Partition is untouched in the new layout self._logger.log(" Partition " + str(part) + " has origminor " + str(tmppart_new['origminor']) + "...saving start sector " + str(tmppart_old['start']) + " and end sector " + str(tmppart_old['end'])) tmppart_new['start'] = tmppart_old['start'] tmppart_new['end'] = tmppart_old['end'] if self._check_table_layout_changed(parts_old[device], parts_new[device]): # First pass to delete old partitions that aren't resized self.notify_frontend( "progress", (cur_progress / total_steps, "Deleting partitioning that aren't being resized for " + device)) cur_progress += 1 self._partition_delete_step(parted_disk, oldparts, newparts) # Second pass to resize old partitions that need to be resized self._logger.log("Partitioning: Second pass...") self.notify_frontend( "progress", (cur_progress / total_steps, "Resizing remaining partitions for " + device)) cur_progress += 1 self._partition_resize_step(parted_disk, device, oldparts, newparts) # Wiping disk and creating blank disklabel try: parted_disk = parted_dev.disk_new_fresh( parted.disk_type_get(newparts.get_disklabel())) parted_disk.commit() except: raise GLIException("DiskLabelCreationError", 'fatal', 'partition', "Could not create a blank disklabel!") # Third pass to create new partition table self._logger.log( "Partitioning: Third pass....creating partitions") self.notify_frontend( "progress", (cur_progress / total_steps, "Recreating partition table for " + device)) cur_progress += 1 self._partition_recreate_step(parted_disk, newparts) else: cur_progress += 3 # Fourth pass to format partitions self._logger.log("Partitioning: formatting partitions") self.notify_frontend("progress", (cur_progress / total_steps, "Formatting partitions for " + device)) cur_progress += 1 self._partition_format_step(parted_disk, device, newparts) # All done for this device self.notify_frontend("progress", (cur_progress / total_steps, "Done with partitioning for " + device)) cur_progress += 1
#!/usr/bin/python import sys sys.path.append("..") import GLIStorageDevice if len(sys.argv) <= 1: print "You must call this script with a device name" sys.exit(1) device = GLIStorageDevice.Device(sys.argv[1]) device.set_partitions_from_disk() print "Device: " + sys.argv[1] print "Disklabel: " + device.get_disklabel() print "Length (MB): " + str(device.get_total_mb()) print "Length (sectors): " + str(device.get_num_sectors()) for partition in device.get_ordered_partition_list(): print str(partition) print repr(device) print str(device[partition]) partition = device[partition] print "--------------------" print "Minor: " + str(partition.get_minor()) print "Type: " + str(partition.get_type()) try: print "Start: " + str(partition.get_start()) print "End: " + str(partition.get_end()) except: pass
def activate(self): self.controller.SHOW_BUTTON_EXIT = True self.controller.SHOW_BUTTON_HELP = True self.controller.SHOW_BUTTON_BACK = False self.controller.SHOW_BUTTON_FORWARD = True self.controller.SHOW_BUTTON_FINISH = False self.devices = self.controller.install_profile.get_partition_tables() if not self.devices: part_load_error = 0 tmp_drives = GLIStorageDevice.detect_devices() tmp_drives.sort() for drive in tmp_drives: try: self.devices[drive] = GLIStorageDevice.Device( drive, arch=self.controller.client_profile. get_architecture_template()) self.devices[drive].set_partitions_from_disk() self.detected_dev_combo.append_text(drive) self.drives.append(drive) except: print _("Exception received while loading partitions") if self.devices.has_key(drive): del self.devices[drive] part_load_error = 1 if part_load_error: msgdlg = gtk.MessageDialog( parent=self.controller.window, type=gtk.MESSAGE_WARNING, buttons=gtk.BUTTONS_OK, message_format= "There was an error loading one or more drives' partition table. Possible causes are running as a normal user or partitions being out of disk order." ) msgdlg.run() msgdlg.destroy() return if not self.drives: tmp_drives = self.devices.keys() tmp_drives.sort() self.drives = tmp_drives for drive in self.drives: self.detected_dev_combo.append_text(drive) if self.devices: self.active_device = self.drives[0] self.detected_dev_combo.set_active(0) self.drive_changed(None) for device in self.devices: for tmppart in self.devices[device].get_partitions(): if tmppart.get_type() == "unknown": msgdlg = gtk.MessageDialog( parent=self.controller.window, type=gtk.MESSAGE_WARNING, buttons=gtk.BUTTONS_OK, message_format= "One of your disks contains a partition of a type that the installer cannot currently handle. If you continue, you risk damaging your partition table. You have been warned!" ) msgdlg.run() msgdlg.destroy() return