Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 21 additions & 14 deletions archinstall/lib/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ class ArchConfig:

# Special fields that should be handle with care due to security implications
users: list[User] = field(default_factory=list)
disk_encryption: DiskEncryption | None = None
root_enc_password: Password | None = None

def unsafe_json(self) -> dict[str, Any]:
Expand All @@ -85,8 +84,10 @@ def unsafe_json(self) -> dict[str, Any]:
'root_enc_password': self.root_enc_password.enc_password if self.root_enc_password else None,
}

if self.disk_encryption and self.disk_encryption.encryption_password:
config['encryption_password'] = self.disk_encryption.encryption_password.plaintext
if self.disk_config:
disk_encryption = self.disk_config.disk_encryption
if disk_encryption and disk_encryption.encryption_password:
config['encryption_password'] = disk_encryption.encryption_password.plaintext

return config

Expand All @@ -113,9 +114,6 @@ def safe_json(self) -> dict[str, Any]:
if self.disk_config:
config['disk_config'] = self.disk_config.json()

if self.disk_encryption:
config['disk_encryption'] = self.disk_encryption.json()

if self.profile_config:
config['profile_config'] = self.profile_config.json()

Expand All @@ -137,7 +135,23 @@ def from_config(cls, args_config: dict[str, Any]) -> 'ArchConfig':
arch_config.archinstall_language = translation_handler.get_language_by_name(archinstall_lang)

if disk_config := args_config.get('disk_config', {}):
arch_config.disk_config = DiskLayoutConfiguration.parse_arg(disk_config)
enc_password = args_config.get('encryption_password', '')
password = Password(plaintext=enc_password) if enc_password else None
arch_config.disk_config = DiskLayoutConfiguration.parse_arg(disk_config, password)

# DEPRECATED
# backwards compatibility for main level disk_encryption entry
disk_encryption: DiskEncryption | None = None

if args_config.get('disk_encryption', None) is not None and arch_config.disk_config is not None:
disk_encryption = DiskEncryption.parse_arg(
arch_config.disk_config,
args_config['disk_encryption'],
Password(plaintext=args_config.get('encryption_password', '')),
)

if disk_encryption:
arch_config.disk_config.disk_encryption = disk_encryption

if profile_config := args_config.get('profile_config', None):
arch_config.profile_config = ProfileConfiguration.parse_arg(profile_config)
Expand Down Expand Up @@ -171,13 +185,6 @@ def from_config(cls, args_config: dict[str, Any]) -> 'ArchConfig':
if audio_config := args_config.get('audio_config', None):
arch_config.audio_config = AudioConfiguration.parse_arg(audio_config)

if args_config.get('disk_encryption', None) is not None and arch_config.disk_config is not None:
arch_config.disk_encryption = DiskEncryption.parse_arg(
arch_config.disk_config,
args_config['disk_encryption'],
Password(plaintext=args_config.get('encryption_password', '')),
)

if hostname := args_config.get('hostname', ''):
arch_config.hostname = hostname

Expand Down
54 changes: 54 additions & 0 deletions archinstall/lib/disk/disk_menu.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from dataclasses import dataclass
from typing import override

from archinstall.lib.disk.encryption_menu import DiskEncryptionMenu
from archinstall.lib.models.device_model import (
BtrfsOptions,
DiskEncryption,
DiskLayoutConfiguration,
DiskLayoutType,
EncryptionType,
LvmConfiguration,
SnapshotConfig,
SnapshotType,
Expand All @@ -25,6 +28,7 @@ class DiskMenuConfig:
disk_config: DiskLayoutConfiguration | None
lvm_config: LvmConfiguration | None
btrfs_snapshot_config: SnapshotConfig | None
disk_encryption: DiskEncryption | None


class DiskLayoutConfigurationMenu(AbstractSubMenu[DiskLayoutConfiguration]):
Expand All @@ -34,13 +38,15 @@ def __init__(self, disk_layout_config: DiskLayoutConfiguration | None):
disk_config=None,
lvm_config=None,
btrfs_snapshot_config=None,
disk_encryption=None,
)
else:
snapshot_config = disk_layout_config.btrfs_options.snapshot_config if disk_layout_config.btrfs_options else None

self._disk_menu_config = DiskMenuConfig(
disk_config=disk_layout_config,
lvm_config=disk_layout_config.lvm_config,
disk_encryption=disk_layout_config.disk_encryption,
btrfs_snapshot_config=snapshot_config,
)

Expand Down Expand Up @@ -70,6 +76,13 @@ def _define_menu_options(self) -> list[MenuItem]:
dependencies=[self._check_dep_lvm],
key='lvm_config',
),
MenuItem(
text=tr('Disk encryption'),
action=self._disk_encryption,
preview_action=self._prev_disk_encryption,
dependencies=['disk_config'],
key='disk_encryption',
),
MenuItem(
text='Btrfs snapshots',
action=self._select_btrfs_snapshots,
Expand All @@ -87,6 +100,7 @@ def run(self) -> DiskLayoutConfiguration | None:
if self._disk_menu_config.disk_config:
self._disk_menu_config.disk_config.lvm_config = self._disk_menu_config.lvm_config
self._disk_menu_config.disk_config.btrfs_options = BtrfsOptions(snapshot_config=self._disk_menu_config.btrfs_snapshot_config)
self._disk_menu_config.disk_config.disk_encryption = self._disk_menu_config.disk_encryption
return self._disk_menu_config.disk_config

return None
Expand All @@ -107,11 +121,25 @@ def _check_dep_btrfs(self) -> bool:

return False

def _disk_encryption(self, preset: DiskEncryption | None) -> DiskEncryption | None:
disk_config: DiskLayoutConfiguration | None = self._item_group.find_by_key('disk_config').value

if not disk_config:
# this should not happen as the encryption menu has the disk_config as dependency
raise ValueError('No disk layout specified')

if not DiskEncryption.validate_enc(disk_config):
return None

disk_encryption = DiskEncryptionMenu(disk_config, preset=preset).run()
return disk_encryption

def _select_disk_layout_config(self, preset: DiskLayoutConfiguration | None) -> DiskLayoutConfiguration | None:
disk_config = select_disk_config(preset)

if disk_config != preset:
self._menu_item_group.find_by_key('lvm_config').value = None
self._menu_item_group.find_by_key('disk_encryption').value = None

return disk_config

Expand Down Expand Up @@ -217,3 +245,29 @@ def _prev_btrfs_snapshots(self, item: MenuItem) -> str | None:

snapshot_config: SnapshotConfig = item.value
return tr('Snapshot type: {}').format(snapshot_config.snapshot_type.value)

def _prev_disk_encryption(self, item: MenuItem) -> str | None:
disk_config: DiskLayoutConfiguration | None = self._item_group.find_by_key('disk_config').value
enc_config: DiskEncryption | None = item.value

if disk_config and not DiskEncryption.validate_enc(disk_config):
return tr('LVM disk encryption with more than 2 partitions is currently not supported')

if enc_config:
enc_type = EncryptionType.type_to_text(enc_config.encryption_type)
output = tr('Encryption type') + f': {enc_type}\n'

if enc_config.encryption_password:
output += tr('Password') + f': {enc_config.encryption_password.hidden()}\n'

if enc_config.partitions:
output += f'Partitions: {len(enc_config.partitions)} selected\n'
elif enc_config.lvm_volumes:
output += f'LVM volumes: {len(enc_config.lvm_volumes)} selected\n'

if enc_config.hsm_device:
output += f'HSM: {enc_config.hsm_device.manufacturer}'

return output

return None
8 changes: 2 additions & 6 deletions archinstall/lib/disk/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,9 @@


class FilesystemHandler:
def __init__(
self,
disk_config: DiskLayoutConfiguration,
enc_conf: DiskEncryption | None = None,
):
def __init__(self, disk_config: DiskLayoutConfiguration):
self._disk_config = disk_config
self._enc_config = enc_conf
self._enc_config = disk_config.disk_encryption

def perform_filesystem_operations(self, show_countdown: bool = True) -> None:
if self._disk_config.config_type == DiskLayoutType.Pre_mount:
Expand Down
55 changes: 4 additions & 51 deletions archinstall/lib/global_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
from typing import override

from archinstall.lib.disk.disk_menu import DiskLayoutConfigurationMenu
from archinstall.lib.disk.encryption_menu import DiskEncryptionMenu
from archinstall.lib.models.device_model import DiskEncryption, DiskLayoutConfiguration, DiskLayoutType, EncryptionType, FilesystemType, PartitionModification
from archinstall.lib.models.device_model import DiskLayoutConfiguration, DiskLayoutType, EncryptionType, FilesystemType, PartitionModification
from archinstall.lib.packages import list_available_packages
from archinstall.tui.menu_item import MenuItem, MenuItemGroup

Expand Down Expand Up @@ -79,13 +78,6 @@ def _get_menu_options(self) -> list[MenuItem]:
mandatory=True,
key='disk_config',
),
MenuItem(
text=tr('Disk encryption'),
action=self._disk_encryption,
preview_action=self._prev_disk_encryption,
dependencies=['disk_config'],
key='disk_encryption',
),
MenuItem(
text=tr('Swap'),
value=True,
Expand Down Expand Up @@ -270,19 +262,6 @@ def _update_lang_text(self) -> None:
if o.key is not None:
self._item_group.find_by_key(o.key).text = o.text

def _disk_encryption(self, preset: DiskEncryption | None) -> DiskEncryption | None:
disk_config: DiskLayoutConfiguration | None = self._item_group.find_by_key('disk_config').value

if not disk_config:
# this should not happen as the encryption menu has the disk_config as dependency
raise ValueError('No disk layout specified')

if not DiskEncryption.validate_enc(disk_config):
return None

disk_encryption = DiskEncryptionMenu(disk_config, preset=preset).run()
return disk_encryption

def _locale_selection(self, preset: LocaleConfiguration) -> LocaleConfiguration:
locale_config = LocaleMenu(preset).run()
return locale_config
Expand Down Expand Up @@ -335,6 +314,9 @@ def _prev_disk_config(self, item: MenuItem) -> str | None:
if disk_layout_conf.lvm_config:
output += '{}: {}'.format(tr('LVM configuration type'), disk_layout_conf.lvm_config.config_type.display_msg())

if disk_layout_conf.disk_encryption:
output += tr('Disk encryption') + ': ' + EncryptionType.type_to_text(disk_layout_conf.disk_encryption.encryption_type)

if disk_layout_conf.btrfs_options:
btrfs_options = disk_layout_conf.btrfs_options
if btrfs_options.snapshot_config:
Expand Down Expand Up @@ -391,32 +373,6 @@ def _prev_bootloader(self, item: MenuItem) -> str | None:
return f'{tr("Bootloader")}: {item.value.value}'
return None

def _prev_disk_encryption(self, item: MenuItem) -> str | None:
disk_config: DiskLayoutConfiguration | None = self._item_group.find_by_key('disk_config').value
enc_config: DiskEncryption | None = item.value

if disk_config and not DiskEncryption.validate_enc(disk_config):
return tr('LVM disk encryption with more than 2 partitions is currently not supported')

if enc_config:
enc_type = EncryptionType.type_to_text(enc_config.encryption_type)
output = tr('Encryption type') + f': {enc_type}\n'

if enc_config.encryption_password:
output += tr('Password') + f': {enc_config.encryption_password.hidden()}\n'

if enc_config.partitions:
output += f'Partitions: {len(enc_config.partitions)} selected\n'
elif enc_config.lvm_volumes:
output += f'LVM volumes: {len(enc_config.lvm_volumes)} selected\n'

if enc_config.hsm_device:
output += f'HSM: {enc_config.hsm_device.manufacturer}'

return output

return None

def _validate_bootloader(self) -> str | None:
"""
Checks the selected bootloader is valid for the selected filesystem
Expand Down Expand Up @@ -515,9 +471,6 @@ def _select_disk_config(
) -> DiskLayoutConfiguration | None:
disk_config = DiskLayoutConfigurationMenu(preset).run()

if disk_config != preset:
self._menu_item_group.find_by_key('disk_encryption').value = None

return disk_config

def _select_bootloader(self, preset: Bootloader | None) -> Bootloader | None:
Expand Down
3 changes: 1 addition & 2 deletions archinstall/lib/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ def __init__(
self,
target: Path,
disk_config: DiskLayoutConfiguration,
disk_encryption: DiskEncryption | None = None,
base_packages: list[str] = [],
kernels: list[str] | None = None,
):
Expand All @@ -74,7 +73,7 @@ def __init__(
self.kernels = kernels or ['linux']
self._disk_config = disk_config

self._disk_encryption = disk_encryption or DiskEncryption(EncryptionType.NoEncryption)
self._disk_encryption = disk_config.disk_encryption or DiskEncryption(EncryptionType.NoEncryption)
self.target: Path = target

self.init_time = time.strftime('%Y-%m-%d_%H-%M-%S')
Expand Down
15 changes: 14 additions & 1 deletion archinstall/lib/models/device_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@ class _DiskLayoutConfigurationSerialization(TypedDict):
lvm_config: NotRequired[_LvmConfigurationSerialization]
mountpoint: NotRequired[str]
btrfs_options: NotRequired[_BtrfsOptionsSerialization]
disk_encryption: NotRequired[_DiskEncryptionSerialization]


@dataclass
class DiskLayoutConfiguration:
config_type: DiskLayoutType
device_modifications: list[DeviceModification] = field(default_factory=list)
lvm_config: LvmConfiguration | None = None
disk_encryption: DiskEncryption | None = None
btrfs_options: BtrfsOptions | None = None

# used for pre-mounted config
Expand All @@ -68,13 +70,21 @@ def json(self) -> _DiskLayoutConfigurationSerialization:
if self.lvm_config:
config['lvm_config'] = self.lvm_config.json()

if self.disk_encryption:
config['disk_encryption'] = self.disk_encryption.json()

if self.btrfs_options:
config['btrfs_options'] = self.btrfs_options.json()

return config

@classmethod
def parse_arg(cls, disk_config: _DiskLayoutConfigurationSerialization) -> DiskLayoutConfiguration | None:
def parse_arg(
cls,
disk_config: _DiskLayoutConfigurationSerialization,
enc_password: Password | None = None,
disk_encryption: _DiskEncryptionSerialization | None = None,
) -> DiskLayoutConfiguration | None:
from archinstall.lib.disk.device_handler import device_handler

device_modifications: list[DeviceModification] = []
Expand Down Expand Up @@ -179,6 +189,9 @@ def parse_arg(cls, disk_config: _DiskLayoutConfigurationSerialization) -> DiskLa
if (lvm_arg := disk_config.get('lvm_config', None)) is not None:
config.lvm_config = LvmConfiguration.parse_arg(lvm_arg, config)

if (enc_config := disk_config.get('disk_encryption', None)) is not None:
config.disk_encryption = DiskEncryption.parse_arg(config, enc_config, enc_password)

if config.is_default_btrfs():
if (btrfs_arg := disk_config.get('btrfs_options', None)) is not None:
config.btrfs_options = BtrfsOptions.parse_arg(btrfs_arg)
Expand Down
Loading