mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-22 09:50:37 +00:00
Remove the PartitionGap class, it's way too much of a hassle to work with
Instead pad_start and pad_end have been introduced
This commit is contained in:
parent
05006f2d83
commit
a62ce1705a
11 changed files with 53 additions and 105 deletions
|
@ -1,6 +1,5 @@
|
|||
from abc import ABCMeta
|
||||
from abc import abstractmethod
|
||||
from ..partitions.gap import PartitionGap
|
||||
from bootstrapvz.common.tools import log_check_call
|
||||
from bootstrapvz.common.fsm_proxy import FSMProxy
|
||||
from ..exceptions import PartitionError
|
||||
|
@ -76,8 +75,6 @@ class AbstractPartitionMap(FSMProxy):
|
|||
.format(device_path=volume.device_path))
|
||||
log_check_call(['kpartx', '-as', volume.device_path])
|
||||
|
||||
mappable_partitions = filter(lambda p: not isinstance(p, PartitionGap), self.partitions)
|
||||
|
||||
import os.path
|
||||
# Run through the kpartx output and map the paths to the partitions
|
||||
for mapping in mappings:
|
||||
|
@ -86,12 +83,10 @@ class AbstractPartitionMap(FSMProxy):
|
|||
raise PartitionError('Unable to parse kpartx output: ' + mapping)
|
||||
partition_path = os.path.join('/dev/mapper', match.group('name'))
|
||||
p_idx = int(match.group('p_idx')) - 1
|
||||
mappable_partitions[p_idx].map(partition_path)
|
||||
self.partitions[p_idx].map(partition_path)
|
||||
|
||||
# Check if any partition was not mapped
|
||||
for idx, partition in enumerate(self.partitions):
|
||||
if isinstance(partition, PartitionGap):
|
||||
continue
|
||||
if partition.fsm.current not in ['mapped', 'formatted']:
|
||||
raise PartitionError('kpartx did not map partition #' + str(partition.get_index()))
|
||||
|
||||
|
@ -117,8 +112,6 @@ class AbstractPartitionMap(FSMProxy):
|
|||
volume = event.volume
|
||||
# Run through all partitions before unmapping and make sure they can all be unmapped
|
||||
for partition in self.partitions:
|
||||
if isinstance(partition, PartitionGap):
|
||||
continue
|
||||
if partition.fsm.cannot('unmap'):
|
||||
msg = 'The partition {partition} prevents the unmap procedure'.format(partition=partition)
|
||||
raise PartitionError(msg)
|
||||
|
@ -126,6 +119,4 @@ class AbstractPartitionMap(FSMProxy):
|
|||
log_check_call(['kpartx', '-ds', volume.device_path])
|
||||
# Call unmap on all partitions
|
||||
for partition in self.partitions:
|
||||
if isinstance(partition, PartitionGap):
|
||||
continue
|
||||
partition.unmap()
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from abstract import AbstractPartitionMap
|
||||
from ..partitions.gpt import GPTPartition
|
||||
from ..partitions.gpt_swap import GPTSwapPartition
|
||||
from ..partitions.gap import PartitionGap
|
||||
from bootstrapvz.common.tools import log_check_call
|
||||
|
||||
|
||||
|
@ -24,57 +23,60 @@ class GPTPartitionMap(AbstractPartitionMap):
|
|||
def last_partition():
|
||||
return self.partitions[-1] if len(self.partitions) > 0 else None
|
||||
|
||||
# The first 34 sectors are reserved for the primary GPT
|
||||
primary_gpt = PartitionGap(Sectors(34, sector_size), last_partition())
|
||||
self.partitions.append(primary_gpt)
|
||||
|
||||
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
|
||||
# gpt_primary + grub = 1024KiB
|
||||
# So lets just specify grub size as 1MiB - 34 sectors
|
||||
# primary gpt + grub = 1024KiB
|
||||
# The 34 sectors for the primary gpt will be subtracted later on
|
||||
from ..partitions.unformatted import UnformattedPartition
|
||||
grub_size = Sectors('1MiB', sector_size) - primary_gpt.size
|
||||
self.grub_boot = UnformattedPartition(grub_size, last_partition())
|
||||
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
|
||||
# gpt 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())
|
||||
# Offset all partitions by 1 sector.
|
||||
# parted in jessie has changed and no longer allows partitions to be right next to each other.
|
||||
self.boot.offset = Sectors(1, sector_size)
|
||||
self.boot.size -= self.boot.offset
|
||||
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())
|
||||
self.swap.offset = Sectors(1, sector_size)
|
||||
self.swap.size -= self.swap.offset
|
||||
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())
|
||||
self.root.offset = Sectors(1, sector_size)
|
||||
self.root.size -= self.root.offset
|
||||
if self.root.previous is not None:
|
||||
self.root.pad_start += partition_gap
|
||||
self.root.size -= partition_gap
|
||||
self.partitions.append(self.root)
|
||||
|
||||
# The last 34 sectors are reserved for the secondary GPT
|
||||
secondary_gpt = PartitionGap(Sectors(34, sector_size), last_partition())
|
||||
self.partitions.append(secondary_gpt)
|
||||
# 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
|
||||
|
||||
# reduce the size of the root partition so that the overall volume size is not exceeded
|
||||
self.root.size -= primary_gpt.size + secondary_gpt.size
|
||||
if hasattr(self, 'grub_boot'):
|
||||
self.root.size -= self.grub_boot.size
|
||||
secondary_gpt_size = Sectors(34, sector_size)
|
||||
self.partitions[-1].pad_end += secondary_gpt_size
|
||||
self.partitions[-1].size -= secondary_gpt_size
|
||||
|
||||
# Set the boot flag on the right partition
|
||||
if hasattr(self, 'grub_boot'):
|
||||
# Mark the partition as a bios_grub partition
|
||||
# Mark the grub partition as a bios_grub partition
|
||||
self.grub_boot.flags.append('bios_grub')
|
||||
else:
|
||||
# Mark the boot partition, or root, if boot does not exist
|
||||
# Not using grub, mark the boot partition or root as bootable
|
||||
getattr(self, 'boot', self.root).flags.append('legacy_boot')
|
||||
|
||||
super(GPTPartitionMap, self).__init__(bootloader)
|
||||
|
@ -89,6 +91,4 @@ class GPTPartitionMap(AbstractPartitionMap):
|
|||
'--', 'mklabel', 'gpt'])
|
||||
# Create the partitions
|
||||
for partition in self.partitions:
|
||||
if isinstance(partition, PartitionGap):
|
||||
continue
|
||||
partition.create(volume)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from abstract import AbstractPartitionMap
|
||||
from ..partitions.msdos import MSDOSPartition
|
||||
from ..partitions.msdos_swap import MSDOSSwapPartition
|
||||
from ..partitions.gap import PartitionGap
|
||||
from bootstrapvz.common.tools import log_check_call
|
||||
|
||||
|
||||
|
@ -31,9 +30,11 @@ class MSDOSPartitionMap(AbstractPartitionMap):
|
|||
data['boot']['filesystem'], data['boot'].get('format_command', None),
|
||||
last_partition())
|
||||
self.partitions.append(self.boot)
|
||||
|
||||
if 'swap' in data:
|
||||
self.swap = MSDOSSwapPartition(Sectors(data['swap']['size'], sector_size), last_partition())
|
||||
self.partitions.append(self.swap)
|
||||
|
||||
self.root = MSDOSPartition(Sectors(data['root']['size'], sector_size),
|
||||
data['root']['filesystem'], data['root'].get('format_command', None),
|
||||
last_partition())
|
||||
|
@ -47,16 +48,18 @@ class MSDOSPartitionMap(AbstractPartitionMap):
|
|||
# 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':
|
||||
offset = Sectors('2MiB', sector_size)
|
||||
mbr_offset = Sectors('2MiB', sector_size)
|
||||
else:
|
||||
offset = Sectors('512B', sector_size)
|
||||
mbr_offset = Sectors('512B', sector_size)
|
||||
|
||||
self.partitions[0].offset += offset
|
||||
self.partitions[0].size -= offset
|
||||
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
|
||||
self.partitions.append(PartitionGap(Sectors(1, sector_size), last_partition()))
|
||||
|
||||
super(MSDOSPartitionMap, self).__init__(bootloader)
|
||||
|
||||
|
@ -68,6 +71,4 @@ class MSDOSPartitionMap(AbstractPartitionMap):
|
|||
'--', 'mklabel', 'msdos'])
|
||||
# Create the partitions
|
||||
for partition in self.partitions:
|
||||
if isinstance(partition, PartitionGap):
|
||||
continue
|
||||
partition.create(volume)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from abc import ABCMeta
|
||||
from abc import abstractmethod
|
||||
from bootstrapvz.common.sectors import Sectors
|
||||
from bootstrapvz.common.tools import log_check_call
|
||||
from bootstrapvz.common.fsm_proxy import FSMProxy
|
||||
|
||||
|
@ -27,6 +28,9 @@ class AbstractPartition(FSMProxy):
|
|||
self.size = size
|
||||
self.filesystem = filesystem
|
||||
self.format_command = format_command
|
||||
# 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
|
||||
|
@ -55,7 +59,7 @@ class AbstractPartition(FSMProxy):
|
|||
:return: The end of the partition
|
||||
:rtype: Sectors
|
||||
"""
|
||||
return self.get_start() + self.size
|
||||
return self.get_start() + self.pad_start + self.size + self.pad_end
|
||||
|
||||
def _before_format(self, e):
|
||||
"""Formats the partition
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from abstract import AbstractPartition
|
||||
from bootstrapvz.common.sectors import Sectors
|
||||
|
||||
|
||||
class BasePartition(AbstractPartition):
|
||||
|
@ -25,12 +26,9 @@ class BasePartition(AbstractPartition):
|
|||
:param list format_command: Optional format command, valid variables are fs, device_path and size
|
||||
:param BasePartition previous: The partition that preceeds this one
|
||||
"""
|
||||
# By saving the previous partition we have
|
||||
# a linked list that partitions can go backwards in to find the first partition.
|
||||
# By saving the previous partition we have a linked list
|
||||
# that partitions can go backwards in to find the first partition.
|
||||
self.previous = previous
|
||||
from bootstrapvz.common.sectors import Sectors
|
||||
# Initialize the offset to 0 sectors, may be changed later
|
||||
self.offset = Sectors(0, size.sector_size)
|
||||
# List of flags that parted should put on the partition
|
||||
self.flags = []
|
||||
super(BasePartition, self).__init__(size, filesystem, format_command)
|
||||
|
@ -62,11 +60,9 @@ class BasePartition(AbstractPartition):
|
|||
:rtype: Sectors
|
||||
"""
|
||||
if self.previous is None:
|
||||
# If there is no previous partition, this partition begins at the offset
|
||||
return self.offset
|
||||
return Sectors(0, self.size.sector_size)
|
||||
else:
|
||||
# Get the end of the previous partition and add the offset of this partition
|
||||
return self.previous.get_end() + self.offset
|
||||
return self.previous.get_end()
|
||||
|
||||
def map(self, device_path):
|
||||
"""Maps the partition to a device_path
|
||||
|
@ -81,8 +77,8 @@ class BasePartition(AbstractPartition):
|
|||
from bootstrapvz.common.tools import log_check_call
|
||||
# The create command is failry simple, start and end are just Bytes objects coerced into strings
|
||||
create_command = ('mkpart primary {start} {end}'
|
||||
.format(start=str(self.get_start()),
|
||||
end=str(self.get_end())))
|
||||
.format(start=str(self.get_start() + self.pad_start),
|
||||
end=str(self.get_end() - self.pad_end)))
|
||||
# Create the partition
|
||||
log_check_call(['parted', '--script', '--align', 'none', e.volume.device_path,
|
||||
'--', create_command])
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
from base import BasePartition
|
||||
|
||||
|
||||
class PartitionGap(BasePartition):
|
||||
"""Represents a non-existent partition
|
||||
A gap in the partitionmap
|
||||
"""
|
||||
|
||||
# The states for our state machine. It can neither be create nor mapped.
|
||||
events = []
|
||||
|
||||
def __init__(self, size, previous):
|
||||
"""
|
||||
:param Bytes size: Size of the partition
|
||||
:param BasePartition previous: The partition that preceeds this one
|
||||
"""
|
||||
super(PartitionGap, self).__init__(size, None, None, previous)
|
||||
|
||||
def get_index(self):
|
||||
"""Gets the index of this partition in the partition map
|
||||
Note that PartitionGap.get_index() simply returns the index of the
|
||||
previous partition, since a gap does not count towards
|
||||
the number of partitions.
|
||||
If there is no previous partition 0 will be returned
|
||||
(although partitions really are 1 indexed)
|
||||
|
||||
:return: The index of the partition in the partition map
|
||||
:rtype: int
|
||||
"""
|
||||
if self.previous is None:
|
||||
return 0
|
||||
else:
|
||||
# Recursive call to the previous partition, walking up the chain...
|
||||
return self.previous.get_index()
|
|
@ -12,5 +12,4 @@ class SinglePartition(AbstractPartition):
|
|||
:rtype: Sectors
|
||||
"""
|
||||
from bootstrapvz.common.sectors import Sectors
|
||||
# On an unpartitioned volume there is no offset and no previous partition
|
||||
return Sectors(0, self.size.sector_size)
|
||||
|
|
|
@ -25,9 +25,8 @@ class Format(Task):
|
|||
@classmethod
|
||||
def run(cls, info):
|
||||
from bootstrapvz.base.fs.partitions.unformatted import UnformattedPartition
|
||||
from bootstrapvz.base.fs.partitions.gap import PartitionGap
|
||||
for partition in info.volume.partition_map.partitions:
|
||||
if isinstance(partition, (UnformattedPartition, PartitionGap)):
|
||||
if isinstance(partition, UnformattedPartition):
|
||||
continue
|
||||
partition.format()
|
||||
|
||||
|
@ -40,11 +39,10 @@ class TuneVolumeFS(Task):
|
|||
@classmethod
|
||||
def run(cls, info):
|
||||
from bootstrapvz.base.fs.partitions.unformatted import UnformattedPartition
|
||||
from bootstrapvz.base.fs.partitions.gap import PartitionGap
|
||||
import re
|
||||
# Disable the time based filesystem check
|
||||
for partition in info.volume.partition_map.partitions:
|
||||
if isinstance(partition, (UnformattedPartition, PartitionGap)):
|
||||
if isinstance(partition, UnformattedPartition):
|
||||
continue
|
||||
if re.match('^ext[2-4]$', partition.filesystem) is not None:
|
||||
log_check_call(['tune2fs', '-i', '0', partition.device_path])
|
||||
|
|
|
@ -68,10 +68,7 @@ class InstallGrub_1_99(Task):
|
|||
with open(device_map_path, 'w') as device_map:
|
||||
device_map.write('(hd0) {device_path}\n'.format(device_path=device_path))
|
||||
if not isinstance(p_map, partitionmaps.none.NoPartitions):
|
||||
from bootstrapvz.base.fs.partitions.gap import PartitionGap
|
||||
for idx, partition in enumerate(info.volume.partition_map.partitions):
|
||||
if isinstance(partition, PartitionGap):
|
||||
continue
|
||||
device_map.write('(hd0,{prefix}{idx}) {device_path}\n'
|
||||
.format(device_path=partition.device_path,
|
||||
prefix=partition_prefix,
|
||||
|
|
|
@ -84,12 +84,9 @@ def set_fs_states(volume):
|
|||
if not isinstance(p_map, NoPartitions):
|
||||
p_map.fsm.current = 'unmapped'
|
||||
|
||||
from bootstrapvz.base.fs.partitions.gap import PartitionGap
|
||||
from bootstrapvz.base.fs.partitions.unformatted import UnformattedPartition
|
||||
from bootstrapvz.base.fs.partitions.single import SinglePartition
|
||||
for partition in p_map.partitions:
|
||||
if isinstance(partition, PartitionGap):
|
||||
continue
|
||||
if isinstance(partition, UnformattedPartition):
|
||||
partition.fsm.current = 'unmapped'
|
||||
continue
|
||||
|
|
|
@ -20,7 +20,6 @@ supported_classes = ['bootstrapvz.base.manifest.Manifest',
|
|||
'bootstrapvz.base.fs.partitions.msdos_swap.MSDOSSwapPartition',
|
||||
'bootstrapvz.base.fs.partitions.single.SinglePartition',
|
||||
'bootstrapvz.base.fs.partitions.unformatted.UnformattedPartition',
|
||||
'bootstrapvz.base.fs.partitions.gap.PartitionGap',
|
||||
'bootstrapvz.common.bytes.Bytes',
|
||||
'bootstrapvz.common.sectors.Sectors',
|
||||
]
|
||||
|
|
Loading…
Add table
Reference in a new issue