def __init__(self, size, filesystem, format_command, mountopts): """ :param Bytes size: Size of the partition :param str filesystem: Filesystem the partition should be formatted with :param list format_command: Optional format command, valid variables are fs, device_path and size """ self.size = size self.filesystem = filesystem self.format_command = format_command # List of mount options self.mountopts = mountopts # Initialize the start & end padding to 0 sectors, may be changed later self.pad_start = Sectors(0, size.sector_size) self.pad_end = Sectors(0, size.sector_size) # Path to the partition self.device_path = None # Dictionary with mount points as keys and Mount objects as values self.mounts = {} # Create the configuration for our state machine cfg = { 'initial': 'nonexistent', 'events': self.events, 'callbacks': {} } super(AbstractPartition, self).__init__(cfg)
def get_start(self): """Gets the starting byte of this partition :return: The starting byte of this partition :rtype: Sectors """ from bootstrapvz.common.sectors import Sectors return Sectors(0, self.size.sector_size)
def get_start(self): """Gets the starting byte of this partition :return: The starting byte of this partition :rtype: Sectors """ if self.previous is None: return Sectors(0, self.size.sector_size) return self.previous.get_end()
def __init__(self, data, sector_size, bootloader): """ :param dict data: volume.partitions part of the manifest :param int sector_size: Sectorsize of the volume :param str bootloader: Name of the bootloader we will use for bootstrapping """ from bootstrapvz.common.sectors import Sectors # In the NoPartitions partitions map we only have a single 'partition' self.root = SinglePartition(Sectors(data['root']['size'], sector_size), data['root']['filesystem'], data['root'].get('format_command', None)) self.partitions = [self.root]
def test_isub(): s = Sectors('2GiB', std_secsz) s -= Sectors('1GiB', std_secsz) eq_(Sectors('1GiB', std_secsz), s)
def test_convert_int(): secsize = 512 eq_(pow(1024, 3) / secsize, int(Sectors('1GiB', secsize)))
def __init__(self, data, sector_size, bootloader): """ :param dict data: volume.partitions part of the manifest :param int sector_size: Sectorsize of the volume :param str bootloader: Name of the bootloader we will use for bootstrapping """ from bootstrapvz.common.sectors import Sectors # List of partitions self.partitions = [] # Returns the last partition unless there is none def last_partition(): return self.partitions[-1] if len(self.partitions) > 0 else None # The boot and swap partitions are optional if 'boot' in data: self.boot = MSDOSPartition( Sectors(data['boot']['size'], sector_size), data['boot']['filesystem'], data['boot'].get('format_command', None), data['boot'].get('mountopts', None), 'boot', last_partition()) self.partitions.append(self.boot) # Offset all partitions by 1 sector. # parted in jessie has changed and no longer allows # partitions to be right next to each other. partition_gap = Sectors(1, sector_size) if 'swap' in data: self.swap = MSDOSSwapPartition( Sectors(data['swap']['size'], sector_size), last_partition()) if self.swap.previous is not None: # No need to pad if this is the first partition self.swap.pad_start += partition_gap self.swap.size -= partition_gap self.partitions.append(self.swap) self.root = MSDOSPartition(Sectors(data['root']['size'], sector_size), data['root']['filesystem'], data['root'].get('format_command', None), data['root'].get('mountopts', None), 'root', last_partition()) if self.root.previous is not None: self.root.pad_start += partition_gap self.root.size -= partition_gap self.partitions.append(self.root) # Raise exception while trying to create additional partitions # as its hard to calculate the actual size of the extended partition ATM # And anyhow - we should go with GPT... for partition in data: if partition not in ["boot", "swap", "root", "type"]: raise PartitionError( "If you want to have additional partitions please use GPT partition scheme" ) # Mark boot as the boot partition, or root, if boot does not exist getattr(self, 'boot', self.root).flags.append('boot') # If we are using the grub bootloader, we will need to add a 2 MB offset # at the beginning of the partitionmap and steal it from the first partition. # The MBR offset is included in the grub offset, so if we don't use grub # we should reduce the size of the first partition and move it by only 512 bytes. if bootloader == 'grub': mbr_offset = Sectors('2MiB', sector_size) else: mbr_offset = Sectors('512B', sector_size) self.partitions[0].pad_start += mbr_offset self.partitions[0].size -= mbr_offset # Leave the last sector unformatted # parted in jessie thinks that a partition 10 sectors in size # goes from sector 0 to sector 9 (instead of 0 to 10) self.partitions[-1].pad_end += 1 self.partitions[-1].size -= 1 super(MSDOSPartitionMap, self).__init__(bootloader)
def __init__(self, data, sector_size, bootloader): """ :param dict data: volume.partitions part of the manifest :param int sector_size: Sectorsize of the volume :param str bootloader: Name of the bootloader we will use for bootstrapping """ from bootstrapvz.common.sectors import Sectors # List of partitions self.partitions = [] # Returns the last partition unless there is none def last_partition(): return self.partitions[-1] if len(self.partitions) > 0 else None if bootloader == 'grub': # If we are using the grub bootloader we need to create an unformatted partition # at the beginning of the map. Its size is 1007kb, which seems to be chosen so that # primary gpt + grub = 1024KiB # The 1 MiB will be subtracted later on, once we know what the subsequent partition is from ..partitions.unformatted import UnformattedPartition self.grub_boot = UnformattedPartition(Sectors('1MiB', sector_size), last_partition()) self.partitions.append(self.grub_boot) # Offset all partitions by 1 sector. # parted in jessie has changed and no longer allows # partitions to be right next to each other. partition_gap = Sectors(1, sector_size) # The boot and swap partitions are optional if 'boot' in data: self.boot = GPTPartition( Sectors(data['boot']['size'], sector_size), data['boot']['filesystem'], data['boot'].get('format_command', None), 'boot', last_partition()) if self.boot.previous is not None: # No need to pad if this is the first partition self.boot.pad_start += partition_gap self.boot.size -= partition_gap self.partitions.append(self.boot) if 'swap' in data: self.swap = GPTSwapPartition( Sectors(data['swap']['size'], sector_size), last_partition()) if self.swap.previous is not None: self.swap.pad_start += partition_gap self.swap.size -= partition_gap self.partitions.append(self.swap) self.root = GPTPartition(Sectors(data['root']['size'], sector_size), data['root']['filesystem'], data['root'].get('format_command', None), 'root', last_partition()) if self.root.previous is not None: self.root.pad_start += partition_gap self.root.size -= partition_gap self.partitions.append(self.root) if hasattr(self, 'grub_boot'): # Mark the grub partition as a bios_grub partition self.grub_boot.flags.append('bios_grub') # Subtract the grub partition size from the subsequent partition self.partitions[1].size -= self.grub_boot.size else: # Not using grub, mark the boot partition or root as bootable getattr(self, 'boot', self.root).flags.append('legacy_boot') # The first and last 34 sectors are reserved for the primary/secondary GPT primary_gpt_size = Sectors(34, sector_size) self.partitions[0].pad_start += primary_gpt_size self.partitions[0].size -= primary_gpt_size secondary_gpt_size = Sectors(34, sector_size) self.partitions[-1].pad_end += secondary_gpt_size self.partitions[-1].size -= secondary_gpt_size super(GPTPartitionMap, self).__init__(bootloader)
def test_idiv(): s = Sectors('2GiB', std_secsz) s /= 2 eq_(Sectors('1GiB', std_secsz), s)
def test_div(): eq_(Sectors('1GiB', std_secsz), Sectors('2GiB', std_secsz) / 2)
def test_imul(): s = Sectors('1GiB', std_secsz) s *= 2 eq_(Sectors('2GiB', std_secsz), s)
def test_ge(): assert Sectors('2MiB', std_secsz) >= Sectors('1MiB', std_secsz) assert Sectors('2MiB', std_secsz) >= Sectors('2MiB', std_secsz)
def test_gt(): assert Sectors('2MiB', std_secsz) > Sectors('1MiB', std_secsz)
def test_neq(): assert Sectors('15MiB', std_secsz) != Sectors('1MiB', std_secsz)
def test_eq(): eq_(Sectors('1MiB', std_secsz), Sectors('1MiB', std_secsz))
def test_le(): assert Sectors('1MiB', std_secsz) <= Sectors('2MiB', std_secsz) assert Sectors('1MiB', std_secsz) <= Sectors('1MiB', std_secsz)
def test_lt(): assert Sectors('1MiB', std_secsz) < Sectors('2MiB', std_secsz)
def test_mul(): eq_(Sectors('2GiB', std_secsz), Sectors('1GiB', std_secsz) * 2)
def test_mul_bytes(): Sectors('1GiB', std_secsz) * Sectors('1GiB', std_secsz)
def test_eq_unit(): eq_(Sectors('1024MiB', std_secsz), Sectors('1GiB', std_secsz))
def test_init_with_int(): secsize = 4096 eq_(Sectors('1MiB', secsize), Sectors(256, secsize))
def test_add(): eq_(Sectors('2GiB', std_secsz), Sectors('1GiB', std_secsz) + Sectors('1GiB', std_secsz))
def test_div_bytes(): eq_(2, Sectors('2GiB', std_secsz) / Sectors('1GiB', std_secsz))
def test_add_with_diff_secsize(): Sectors('1GiB', Bytes(512)) + Sectors('1GiB', Bytes(4096))
def test_imod(): s = Sectors('1GiB', std_secsz) s %= Sectors('768MiB', std_secsz) eq_(Sectors('256MiB', std_secsz), s)
def test_iadd(): s = Sectors('1GiB', std_secsz) s += Sectors('1GiB', std_secsz) eq_(Sectors('2GiB', std_secsz), s)
def test_mod_int(): Sectors('1GiB', std_secsz) % 768
def test_sub_int(): secsize = Bytes('4KiB') eq_(Sectors('1MiB', secsize), Sectors('1028KiB', secsize) - 1)
def test_sub(): eq_(Sectors('1GiB', std_secsz), Sectors('2GiB', std_secsz) - Sectors('1GiB', std_secsz))
def test_imod_int(): s = Sectors('1GiB', std_secsz) s %= 5