예제 #1
0
    def create_image(self):
        """ """
        device = Device(self.device_path)
        disk = Disk(device)

        if device.is_disk():
            mbr = Mbr(self.target_path)
            mbr.save_to_file(self.device_path)
            dlm = DiskLayoutManager(self.target_path)
            dlm.save_to_file(disk)
        
        partition_list = disk.get_valid_partitions()
        
        total_bytes = 0
        for p in partition_list:
            total_bytes += p.filesystem.get_used_size()
       
        total_blocks = long(math.ceil(total_bytes/float(BLOCK_SIZE)))
        self._print_informations(total_bytes)

        information = Information(self.target_path)
        information.set_image_is_disk(device.is_disk())
        information.set_image_name(self.image_name)
        information.set_image_total_bytes(total_bytes)
        information.set_image_compressor_level(self.compressor_level)

        compressor = Compressor(self.compressor_level)
        progress = Progress(total_blocks)
        progress.start()
        for p in partition_list:
            number = p.get_number()
            uuid = p.filesystem.uuid()
            type = p.filesystem.type
            information.add_partition(number, uuid, type)

            p.filesystem.open_to_read()

            file_name = FILE_PATTERN % (self.image_name, number)
            with open(self.target_path + file_name, 'wb') as f:
                # TODO: Work with parallelism
                while True: # Ugly
                    data = p.filesystem.read(BLOCK_SIZE)
                    if not len(data):
                        break
                    cdata = compressor.compact(data)
                    f.write(cdata)
                    progress.increment(1)
            p.filesystem.close()

        swap = disk.get_swap_partition()
        if swap is not None:
            number = swap.get_number()
            uuid = swap.filesystem.uuid()
            type = swap.filesystem.type
            information.add_partition(number, uuid, type)

        information.save()
        progress.stop()
        print "completed."
예제 #2
0
파일: compressed.py 프로젝트: gmoro/carbono
class CompressedReader(GenericReader):

    def __init__(self, path, compressor_level):
        GenericReader.__init__(self, path)
        self.compressor = Compressor(compressor_level)

    def next(self):
        self.open()
        if not self._check_fd():
            header = self._fd.read(self.compressor.get_header_size())
            if not len(header):
                self.close()
                raise StopIteration
            size = self.compressor.read_block_header(header)
            cdata = self._fd.read(size)
            data = self.compressor.extract(cdata)
            return data
예제 #3
0
파일: compressed.py 프로젝트: gmoro/carbono
class CompressedWriter(GenericWriter):

    def __init__(self, path, compressor_level):
        GenericWriter.__init__(self, path)
        self.compressor = Compressor(compressor_level)

    def write(self, data):
        if not self._check_fd():
            data = self.compressor.compact(data)
            self._fd.write(data)
            return len(data)
        return 0
예제 #4
0
class CompressedReader(GenericReader):
    def __init__(self, image_path, pattern, volumes, compressor_level,
                 notify_status):
        GenericReader.__init__(self, image_path, pattern, volumes,
                               notify_status)
        self.compressor = Compressor(compressor_level)

    def read_block(self):
        header_size = self.compressor.get_header_size()
        if not self._check_fd():
            header = self._fd.read(header_size)
            if not len(header):
                self.close()
                if self.current_volume < self.volumes:
                    self.current_volume += 1
                    self.open()
                    data = self.read_block()
                    return data
                else:
                    return None
            size = self.compressor.read_block_header(header)
            data = self._fd.read(size)
            return data
예제 #5
0
class CompressedReader(GenericReader):

    def __init__(self, image_path, pattern, volumes,
                 compressor_level, notify_status):
        GenericReader.__init__(self, image_path, pattern,
                               volumes, notify_status)
        self.compressor = Compressor(compressor_level)

    def read_block(self):
        header_size = self.compressor.get_header_size()
        if not self._check_fd():
            header = self._fd.read(header_size)
            if not len(header):
                self.close()
                if self.current_volume < self.volumes:
                    self.current_volume += 1
                    self.open()
                    data = self.read_block()
                    return data
                else:
                    return None
            size = self.compressor.read_block_header(header)
            data = self._fd.read(size)
            return data
예제 #6
0
    def restore_image(self):
        """ """
        information = Information(self.image_path)
        information.load()
        image_name = information.get_image_name()
        compressor_level = information.get_image_compressor_level()
        total_bytes = information.get_image_total_bytes()
        total_blocks = long(math.ceil(total_bytes / float(BLOCK_SIZE)))

        compressor = Compressor(compressor_level)

        device = Device(self.target_device)

        if device.is_disk() != \
           information.get_image_is_disk():
            raise ErrorRestoringImage("Invalid target dispositive")

        try:
            disk = Disk(device)
        except _ped.DiskLabelException:
            try:
                device.fix_disk_label()
                disk = Disk(device)
            except:
                raise ErrorRestoringImage("Unrecognized disk label")

        if information.get_image_is_disk():
            mbr = Mbr(self.image_path)
            mbr.restore_from_file(self.target_device)
            dlm = DiskLayoutManager(self.image_path)
            dlm.restore_from_file(disk)

        self._print_informations(total_bytes, image_name)
        progress = Progress(total_blocks)
        progress.start()
        partitions = information.get_partitions()
        for p in partitions:
            if information.get_image_is_disk():
                partition = disk.get_partition_by_number(p.number, p.type)
            else:
                parent_path = get_parent_path(self.target_device)
                parent_device = Device(parent_path)
                parent_disk = Disk(parent_device)
                partition = parent_disk.get_partition_by_path(
                    self.target_device, p.type)

            if partition is None:
                raise ErrorRestoringImage("No valid partitions found")

            if p.uuid is not None:
                partition.filesystem.open_to_write(p.uuid)
            else:
                partition.filesystem.open_to_write()

            if partition.filesystem.is_swap():
                continue

            file_name = FILE_PATTERN % (image_name, p.number)
            with open(self.image_path + file_name, 'rb') as f:
                # TODO: Work with parallelism
                while True:  # Ugly
                    header = f.read(compressor.get_header_size())
                    if not len(header):
                        break
                    size = compressor.read_block_header(header)
                    cdata = f.read(size)
                    data = compressor.extract(cdata)
                    partition.filesystem.write(data)
                    progress.increment(1)
            partition.filesystem.close()

        progress.stop()
        print "completed."
예제 #7
0
파일: compressed.py 프로젝트: gmoro/carbono
 def __init__(self, path, compressor_level):
     GenericReader.__init__(self, path)
     self.compressor = Compressor(compressor_level)
예제 #8
0
    def restore_image(self):
        """ """
        if is_mounted(self.target_device):
            raise DeviceIsMounted("Please umount first")

        self.active = True
        information = Information(self.image_path)
        information.load()
        if self.partitions:
            information.set_partitions(self.partitions)
        image_name = information.get_image_name()
        compressor_level = information.get_image_compressor_level()
        partitions = information.get_partitions()

        # Get total size
        total_bytes = 0
        for part in partitions:
            total_bytes += part.size

        self.total_blocks = long(math.ceil(total_bytes / float(BLOCK_SIZE)))

        device = Device(self.target_device)

        if device.is_disk() != \
           information.get_image_is_disk():
            log.error("Invalid target device %s" % device.path)
            raise ErrorRestoringImage("Invalid target device")

        try:
            disk = Disk(device)
        except _ped.DiskLabelException:
            try:
                device.fix_disk_label()
                disk = Disk(device)
            except:
                log.error("Unrecognized disk label")
                raise ErrorRestoringImage("Unrecognized disk label")

        if information.get_image_is_disk():
            log.info("Restoring MBR and Disk Layout")
            mbr = Mbr(self.image_path)
            mbr.restore_from_file(self.target_device)
            dlm = DiskLayoutManager(self.image_path)
            dlm.restore_from_file(disk, self.expand)

        self.timer.start()
        for part in partitions:
            if not self.active: break

            if information.get_image_is_disk():
                partition = disk.get_partition_by_number(
                    part.number, part.type)
            else:
                parent_path = get_parent_path(self.target_device)
                parent_device = Device(parent_path)
                parent_disk = Disk(parent_device)
                partition = parent_disk.get_partition_by_path(
                    self.target_device, part.type)

            log.info("Restoring partition {0}".format(partition.get_path()))

            if partition is None:
                raise ErrorRestoringImage("No valid partitions found")

            if hasattr(part, "uuid"):
                partition.filesystem.open_to_write(part.uuid)
            else:
                partition.filesystem.open_to_write()

            if hasattr(part, "label"):
                partition.filesystem.write_label(part.label)

            if partition.filesystem.is_swap():
                continue

            pattern = FILE_PATTERN.format(name=image_name,
                                          partition=part.number,
                                          volume="{volume}")
            volumes = 1
            if hasattr(part, "volumes"):
                volumes = part.volumes

            image_reader = ImageReaderFactory(self.image_path, pattern,
                                              volumes, compressor_level,
                                              self.notify_status)

            extract_callback = None
            if compressor_level:
                compressor = Compressor(compressor_level)
                extract_callback = compressor.extract

            self.buffer_manager = BufferManagerFactory(image_reader.read_block,
                                                       extract_callback)

            # open the file after instantiating BufferManager, cause of a
            # problem on multiprocessing module, FD_CLOEXE doesn't work
            # (I don't want to dup the file descriptor).
            image_reader.open()
            self.buffer_manager.start()

            buffer = self.buffer_manager.output_buffer
            while self.active:
                try:
                    data = buffer.get()
                except IOError, e:
                    if e.errno == errno.EINTR:
                        self.cancel()
                        break

                if data == EOF:
                    break

                try:
                    partition.filesystem.write_block(data)
                except ErrorWritingToDevice, e:
                    if not self.canceled:
                        self.stop()
                        raise e

                self.processed_blocks += 1
예제 #9
0
 def __init__(self, image_path, pattern, volumes,
              compressor_level, notify_status):
     GenericReader.__init__(self, image_path, pattern,
                            volumes, notify_status)
     self.compressor = Compressor(compressor_level)
예제 #10
0
    def create_image(self):
        """ """
        if is_mounted(self.device_path):
            raise DeviceIsMounted("Please umount first")

        self.active = True
        device = Device(self.device_path)
        disk = Disk(device)

        if device.is_disk():
            mbr = Mbr(self.target_path)
            mbr.save_to_file(self.device_path)
            dlm = DiskLayoutManager(self.target_path)
            dlm.save_to_file(disk)
        
        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)

        # 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()))
            number = part.get_number()
            uuid = part.filesystem.uuid()
            label = part.filesystem.read_label()
            type = part.filesystem.type

            part.filesystem.open_to_read()

            compact_callback = None
            if self.compressor_level:
                compressor = Compressor(self.compressor_level)
                compact_callback = compressor.compact

            self.buffer_manager = BufferManagerFactory(
                                  part.filesystem.read_block,
                                  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
                fd = open(file_path, "wb")

                next_partition = False
                while self.active:
                    try:
                        data = buffer.get()
                    except IOError, e:
                        if e.errno == errno.EINTR:
                            self.cancel()
                            break

                    if data == EOF:
                        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

                    fd.write(data)
                    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

                fd.close()
                if next_partition: break

            self.buffer_manager.join()
            part.filesystem.close()
            information.add_partition(number, type, volumes,
                                      part.filesystem.get_used_size(),
                                      uuid, label)
예제 #11
0
 def __init__(self, image_path, pattern, volumes, compressor_level,
              notify_status):
     GenericReader.__init__(self, image_path, pattern, volumes,
                            notify_status)
     self.compressor = Compressor(compressor_level)
예제 #12
0
    def restore_image(self):
        """ """
        information = Information(self.image_path)
        information.load()
        image_name = information.get_image_name()
        compressor_level = information.get_image_compressor_level()
        total_bytes = information.get_image_total_bytes()
        total_blocks = long(math.ceil(total_bytes/float(BLOCK_SIZE)))

        compressor = Compressor(compressor_level)

        device = Device(self.target_device)

        if device.is_disk() != \
           information.get_image_is_disk():
            raise ErrorRestoringImage("Invalid target dispositive")

        try:
            disk = Disk(device)
        except _ped.DiskLabelException:
            try:
                device.fix_disk_label()
                disk = Disk(device)
            except:
                raise ErrorRestoringImage("Unrecognized disk label")

        if information.get_image_is_disk():
            mbr = Mbr(self.image_path)
            mbr.restore_from_file(self.target_device)
            dlm = DiskLayoutManager(self.image_path)
            dlm.restore_from_file(disk)

        self._print_informations(total_bytes, image_name)
        progress = Progress(total_blocks)
        progress.start()
        partitions = information.get_partitions()
        for p in partitions:
            if information.get_image_is_disk():
                partition = disk.get_partition_by_number(p.number, p.type)
            else:
                parent_path = get_parent_path(self.target_device)
                parent_device = Device(parent_path)
                parent_disk = Disk(parent_device)
                partition = parent_disk.get_partition_by_path(
                                            self.target_device,
                                            p.type)

            if partition is None:
                raise ErrorRestoringImage("No valid partitions found")

            if p.uuid is not None:
                partition.filesystem.open_to_write(p.uuid)
            else:
                partition.filesystem.open_to_write()

            if partition.filesystem.is_swap():
                continue

            file_name = FILE_PATTERN % (image_name, p.number)
            with open(self.image_path + file_name, 'rb') as f:
                # TODO: Work with parallelism
                while True: # Ugly
                    header = f.read(compressor.get_header_size())
                    if not len(header):
                        break
                    size = compressor.read_block_header(header)
                    cdata = f.read(size)
                    data = compressor.extract(cdata)
                    partition.filesystem.write(data)
                    progress.increment(1)
            partition.filesystem.close()

        progress.stop()
        print "completed."