Skip to content

Commit

Permalink
disk: rework manual partitioning (#3071)
Browse files Browse the repository at this point in the history
* disk: rework manual partitioning

* disk: fix end alignment

* disk: validate config

* test: fix disk config partition overlap
  • Loading branch information
codefiles authored Jan 7, 2025
1 parent 25b7bbb commit 9163e8c
Show file tree
Hide file tree
Showing 5 changed files with 336 additions and 222 deletions.
6 changes: 5 additions & 1 deletion archinstall/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,11 @@ def post_process_arguments(args: dict[str, Any]) -> None:
path = args['plugin']
load_plugin(path)

load_config()
try:
load_config()
except ValueError as err:
warn(str(err))
exit(1)


define_arguments()
Expand Down
53 changes: 52 additions & 1 deletion archinstall/lib/disk/device_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from ..exceptions import DiskError, SysCallError
from ..general import SysCommand
from ..hardware import SysInfo
from ..output import debug
from ..storage import storage

Expand Down Expand Up @@ -148,6 +149,41 @@ def parse_arg(cls, disk_config: _DiskLayoutConfigurationSerialization) -> DiskLa
device_modification.partitions = device_partitions
device_modifications.append(device_modification)

using_gpt = SysInfo.has_uefi()

for dev_mod in device_modifications:
partitions = sorted(dev_mod.partitions, key=lambda p: p.start)

for i, current_partition in enumerate(partitions[1:], start=1):
previous_partition = partitions[i - 1]
if (
current_partition.status == ModificationStatus.Create
and current_partition.start < previous_partition.end
):
raise ValueError('Partitions overlap')

partitions = [
part_mod for part_mod in dev_mod.partitions
if part_mod.status == ModificationStatus.Create
]

if not partitions:
continue

for part in partitions:
if (
part.start != part.start.align()
or part.length != part.length.align()
):
raise ValueError('Partition is misaligned')

total_size = dev_mod.device.device_info.total_size

if using_gpt and partitions[-1].end > total_size.gpt_end():
raise ValueError('Partition overlaps backup GPT header')
elif partitions[-1].end > total_size.align():
raise ValueError('Partition too large for device')

# Parse LVM configuration from settings
if (lvm_arg := disk_config.get('lvm_config', None)) is not None:
config.lvm_config = LvmConfiguration.parse_arg(lvm_arg, config)
Expand Down Expand Up @@ -355,6 +391,14 @@ def format_highest(self, include_unit: bool = True, units: Units = Units.BINARY)
else:
return self.si_unit_highest(include_unit)

def align(self) -> Size:
align_norm = Size(1, Unit.MiB, self.sector_size)._normalize()
src_norm = self._normalize()
return self - Size(abs(src_norm % align_norm), Unit.B, self.sector_size)

def gpt_end(self) -> Size:
return self - Size(33, Unit.sectors, self.sector_size)

def _normalize(self) -> int:
"""
will normalize the value of the unit to Byte
Expand Down Expand Up @@ -907,11 +951,18 @@ def is_home(self) -> bool:
def is_modify(self) -> bool:
return self.status == ModificationStatus.Modify

def is_delete(self) -> bool:
return self.status == ModificationStatus.Delete

def exists(self) -> bool:
return self.status == ModificationStatus.Exist

def is_exists_or_modify(self) -> bool:
return self.status in [ModificationStatus.Exist, ModificationStatus.Modify]
return self.status in [
ModificationStatus.Exist,
ModificationStatus.Delete,
ModificationStatus.Modify
]

def is_create_or_modify(self) -> bool:
return self.status in [ModificationStatus.Create, ModificationStatus.Modify]
Expand Down
Loading

0 comments on commit 9163e8c

Please sign in to comment.