def create_image(self): """ """ if is_mounted(self.device_path): log.error("The partition {0} is mounted, please umount first, and try again".format(self.device_path)) self.notify_status("mounted_partition_error",{"mounted_partition_error":self.device_path}) raise DeviceIsMounted("Please umount first") self.active = True device = Device(self.device_path) disk = Disk(device) if device.is_disk(): try: mbr = Mbr(self.target_path) mbr.save_to_file(self.device_path) dlm = DiskLayoutManager(self.target_path) dlm.save_to_file(disk) except Exception as e: log.info(e) self.notify_status("write_error", \ {"write_error":self.target_path}) raise ErrorWritingToDevice("Write error in {0}".format(self.target_path)) partition_list = disk.get_valid_partitions(self.raw) if not partition_list: raise ErrorCreatingImage("Partition(s) hasn't a " +\ "valid filesystem") # check partitions filesystem if not self.raw: for part in partition_list: log.info("Checking filesystem of {0}".format(part.get_path())) self.notify_status("checking_filesystem", {"device": part.get_path()}) if not part.filesystem.check(): log.error("{0} Filesystem is not clean".\ format(part.get_path())) raise ErrorCreatingImage("{0} Filesystem is not clean".\ format(part.get_path())) # fill partitions with zeroes if self.raw and self.fill_with_zeros: for part in partition_list: log.info("{0} Filling with zeros".format(part.get_path())) self.notify_status("filling_with_zeros", {"device": part.get_path()}) part.filesystem.fill_with_zeros() # get total size total_bytes = 0 for part in partition_list: total_bytes += part.filesystem.get_used_size() self.total_blocks = long(math.ceil(total_bytes/float(BLOCK_SIZE))) information = Information(self.target_path) information.set_image_is_disk(device.is_disk()) information.set_image_name(self.image_name) information.set_image_compressor_level(self.compressor_level) if device.is_disk(): disk_info = DiskInfo() disk_dict = disk_info.formated_disk(self.device_path) information.set_disk_size(disk_dict["size"]) # TODO: Abstract this whole part, when creating isos, # splitting in files, etc... self.timer.start() remaining_size = self.split_size if self.create_iso: remaining_size -= BASE_SYSTEM_SIZE slices = dict() # Used when creating iso iso_volume = 1 # Used when creating iso for part in partition_list: if not self.active: break log.info("Creating image of {0}".format(part.get_path())) self.notify_status("image_creator", \ {"image_creator ": part.get_path()}) number = part.get_number() uuid = part.filesystem.uuid() label = part.filesystem.read_label() type = part.filesystem.type part.filesystem.open_to_read() #check if partclone is running if type in ("ext2","ext3","ext4"): self.partclone_stderr = part.filesystem.get_error_ext() compact_callback = None if self.compressor_level: compressor = Compressor(self.compressor_level) compact_callback = compressor.compact self.buffer_manager = BufferManagerFactory( part.filesystem.read_block, self.notify_status, compact_callback) self.buffer_manager.start() buffer = self.buffer_manager.output_buffer volumes = 1 while self.active: total_written = 0 # Used to help splitting the file pattern = FILE_PATTERN.format(name=self.image_name, partition=number, volume=volumes) file_path = self.target_path + pattern try: fd = open(file_path, "wb") except Exception as e: log.info(e) self.notify_status("open_file", \ {"open_file":file_path}) raise ImageNotFound("The file wasn't found {0}". \ format(file_path)) next_partition = False while self.active: try: data = buffer.get() except IOError, e: #self.notify_status("read_buffer_error", \ # {"read_buffer_error":str(e)}) if e.errno == errno.EINTR: self.notify_status("read_buffer_error", \ {"read_buffer_error":str(e)}) data = "" self.cancel() raise ErrorReadingFromDevice(e) break if data == EOF: if (self.partclone_stderr != None): self.data_is_eof = True while self.partclone_sucess == False: pass self.partclone_stderr = None self.partclone_sucess = False self.data_is_eof = False next_partition = True if self.create_iso: remaining_size -= total_written if not slices.has_key(iso_volume): slices[iso_volume] = list() slices[iso_volume].append(file_path) break try: fd.write(data) except Exception as e: log.info("{0}".format(e)) self.notify_status("disk_full") self.cancel() raise ErrorWritingToDevice("Error in write file {0}".\ format(file_path)) self.processed_blocks += 1 if self.split_size: bytes_written = len(data) total_written += bytes_written if (total_written + bytes_written) >= remaining_size: volumes += 1 remaining_size = self.split_size if self.create_iso: if not slices.has_key(iso_volume): slices[iso_volume] = list() slices[iso_volume].append(file_path) iso_volume += 1 break try: fd.close() except Exception as e: log.info(e) self.notify_status("write_error",{"write_error":e}) raise ErrorCloseToWrite("Close Error {0}".format(e)) if next_partition: break self.buffer_manager.join() part.filesystem.close() information.add_partition(number, type, volumes, part.filesystem.get_used_size(), uuid, label)