Lvm2/LUKS fixes/Mirror Logic (#4047)
* Lvm hotfix attempt * Use --force and --yes flags * Changed mirror behavior and more lvm testing * Handle properly LvmOnLuks to only export in one fo the scenarios * Idek * Remove dead block * Use -f flag and wipefs to remove any existing headers avoid "has signatures" * oops * Revert mirror change
This commit is contained in:
parent
ac984b7622
commit
747385a883
|
|
@ -464,8 +464,22 @@ class DeviceHandler:
|
||||||
SysCommand(cmd)
|
SysCommand(cmd)
|
||||||
|
|
||||||
def lvm_import_vg(self, vg: LvmVolumeGroup) -> None:
|
def lvm_import_vg(self, vg: LvmVolumeGroup) -> None:
|
||||||
cmd = f'vgimport {vg.name}'
|
# Check if the VG is actually exported before trying to import it
|
||||||
|
check_cmd = f'vgs --noheadings -o vg_exported {vg.name}'
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = SysCommand(check_cmd)
|
||||||
|
is_exported = result.decode().strip() == 'exported'
|
||||||
|
except SysCallError:
|
||||||
|
# VG might not exist yet, skip import
|
||||||
|
debug(f'Volume group {vg.name} not found, skipping import')
|
||||||
|
return
|
||||||
|
|
||||||
|
if not is_exported:
|
||||||
|
debug(f'Volume group {vg.name} is already active (not exported), skipping import')
|
||||||
|
return
|
||||||
|
|
||||||
|
cmd = f'vgimport {vg.name}'
|
||||||
debug(f'vgimport: {cmd}')
|
debug(f'vgimport: {cmd}')
|
||||||
SysCommand(cmd)
|
SysCommand(cmd)
|
||||||
|
|
||||||
|
|
@ -477,33 +491,22 @@ class DeviceHandler:
|
||||||
SysCommand(cmd)
|
SysCommand(cmd)
|
||||||
|
|
||||||
def lvm_pv_create(self, pvs: Iterable[Path]) -> None:
|
def lvm_pv_create(self, pvs: Iterable[Path]) -> None:
|
||||||
cmd = 'pvcreate ' + ' '.join([str(pv) for pv in pvs])
|
pvs_str = ' '.join([str(pv) for pv in pvs])
|
||||||
|
# Signatures are already wiped by wipefs, -f is just for safety
|
||||||
|
cmd = f'pvcreate -f --yes {pvs_str}'
|
||||||
|
# note flags used in scripting
|
||||||
debug(f'Creating LVM PVS: {cmd}')
|
debug(f'Creating LVM PVS: {cmd}')
|
||||||
|
SysCommand(cmd)
|
||||||
worker = SysCommandWorker(cmd)
|
|
||||||
worker.poll()
|
|
||||||
worker.write(b'y\n', line_ending=False)
|
|
||||||
|
|
||||||
# Wait for the command to complete
|
|
||||||
while worker.is_alive():
|
|
||||||
worker.poll()
|
|
||||||
|
|
||||||
# Sync with udev to ensure the PVs are visible
|
# Sync with udev to ensure the PVs are visible
|
||||||
self.udev_sync()
|
self.udev_sync()
|
||||||
|
|
||||||
def lvm_vg_create(self, pvs: Iterable[Path], vg_name: str) -> None:
|
def lvm_vg_create(self, pvs: Iterable[Path], vg_name: str) -> None:
|
||||||
pvs_str = ' '.join([str(pv) for pv in pvs])
|
pvs_str = ' '.join([str(pv) for pv in pvs])
|
||||||
cmd = f'vgcreate --yes {vg_name} {pvs_str}'
|
cmd = f'vgcreate --yes --force {vg_name} {pvs_str}'
|
||||||
|
|
||||||
debug(f'Creating LVM group: {cmd}')
|
debug(f'Creating LVM group: {cmd}')
|
||||||
|
SysCommand(cmd)
|
||||||
worker = SysCommandWorker(cmd)
|
|
||||||
worker.poll()
|
|
||||||
worker.write(b'y\n', line_ending=False)
|
|
||||||
|
|
||||||
# Wait for the command to complete
|
|
||||||
while worker.is_alive():
|
|
||||||
worker.poll()
|
|
||||||
|
|
||||||
# Sync with udev to ensure the VG is visible
|
# Sync with udev to ensure the VG is visible
|
||||||
self.udev_sync()
|
self.udev_sync()
|
||||||
|
|
@ -750,6 +753,17 @@ class DeviceHandler:
|
||||||
|
|
||||||
disk.commit()
|
disk.commit()
|
||||||
|
|
||||||
|
# Wipe filesystem/LVM signatures from newly created partitions
|
||||||
|
# to prevent "signature detected" errors
|
||||||
|
for part_mod in filtered_part:
|
||||||
|
if part_mod.dev_path:
|
||||||
|
debug(f'Wiping signatures from: {part_mod.dev_path}')
|
||||||
|
SysCommand(f'wipefs --all {part_mod.dev_path}')
|
||||||
|
|
||||||
|
# Sync with udev after wiping signatures
|
||||||
|
if filtered_part:
|
||||||
|
self.udev_sync()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def swapon(path: Path) -> None:
|
def swapon(path: Path) -> None:
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -145,28 +145,19 @@ class FilesystemHandler:
|
||||||
self._setup_lvm(lvm_config, enc_mods)
|
self._setup_lvm(lvm_config, enc_mods)
|
||||||
self._format_lvm_vols(lvm_config)
|
self._format_lvm_vols(lvm_config)
|
||||||
|
|
||||||
# export the lvm group safely otherwise the Luks cannot be closed
|
# Don't close LVM or LUKS during setup - keep everything active
|
||||||
self._safely_close_lvm(lvm_config)
|
# The installation phase will handle unlocking and mounting
|
||||||
|
# Closing causes "parent leaked" and lvchange errors
|
||||||
for luks in enc_mods.values():
|
|
||||||
luks.lock()
|
|
||||||
elif enc_config.encryption_type == EncryptionType.LuksOnLvm:
|
elif enc_config.encryption_type == EncryptionType.LuksOnLvm:
|
||||||
self._setup_lvm(lvm_config)
|
self._setup_lvm(lvm_config)
|
||||||
enc_vols = self._encrypt_lvm_vols(lvm_config, enc_config, False)
|
enc_vols = self._encrypt_lvm_vols(lvm_config, enc_config, False)
|
||||||
self._format_lvm_vols(lvm_config, enc_vols)
|
self._format_lvm_vols(lvm_config, enc_vols)
|
||||||
|
|
||||||
|
# Lock LUKS devices but keep LVM active
|
||||||
|
# LVM volumes must remain active for later re-unlock during installation
|
||||||
for luks in enc_vols.values():
|
for luks in enc_vols.values():
|
||||||
luks.lock()
|
luks.lock()
|
||||||
|
|
||||||
self._safely_close_lvm(lvm_config)
|
|
||||||
|
|
||||||
def _safely_close_lvm(self, lvm_config: LvmConfiguration) -> None:
|
|
||||||
for vg in lvm_config.vol_groups:
|
|
||||||
for vol in vg.volumes:
|
|
||||||
device_handler.lvm_vol_change(vol, False)
|
|
||||||
|
|
||||||
device_handler.lvm_export_vg(vg)
|
|
||||||
|
|
||||||
def _setup_lvm(
|
def _setup_lvm(
|
||||||
self,
|
self,
|
||||||
lvm_config: LvmConfiguration,
|
lvm_config: LvmConfiguration,
|
||||||
|
|
|
||||||
|
|
@ -248,6 +248,7 @@ class Installer:
|
||||||
|
|
||||||
match self._disk_encryption.encryption_type:
|
match self._disk_encryption.encryption_type:
|
||||||
case EncryptionType.NoEncryption:
|
case EncryptionType.NoEncryption:
|
||||||
|
self._import_lvm()
|
||||||
self._mount_lvm_layout()
|
self._mount_lvm_layout()
|
||||||
case EncryptionType.Luks:
|
case EncryptionType.Luks:
|
||||||
luks_handlers = self._prepare_luks_partitions(self._disk_encryption.partitions)
|
luks_handlers = self._prepare_luks_partitions(self._disk_encryption.partitions)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue