Skip to content

Commit cdb1deb

Browse files
authored
Move disk encryption into disk config menu (#3502)
1 parent 5a54902 commit cdb1deb

11 files changed

Lines changed: 103 additions & 107 deletions

File tree

archinstall/lib/args.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ class ArchConfig:
7676

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

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

88-
if self.disk_encryption and self.disk_encryption.encryption_password:
89-
config['encryption_password'] = self.disk_encryption.encryption_password.plaintext
87+
if self.disk_config:
88+
disk_encryption = self.disk_config.disk_encryption
89+
if disk_encryption and disk_encryption.encryption_password:
90+
config['encryption_password'] = disk_encryption.encryption_password.plaintext
9091

9192
return config
9293

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

116-
if self.disk_encryption:
117-
config['disk_encryption'] = self.disk_encryption.json()
118-
119117
if self.profile_config:
120118
config['profile_config'] = self.profile_config.json()
121119

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

139137
if disk_config := args_config.get('disk_config', {}):
140-
arch_config.disk_config = DiskLayoutConfiguration.parse_arg(disk_config)
138+
enc_password = args_config.get('encryption_password', '')
139+
password = Password(plaintext=enc_password) if enc_password else None
140+
arch_config.disk_config = DiskLayoutConfiguration.parse_arg(disk_config, password)
141+
142+
# DEPRECATED
143+
# backwards compatibility for main level disk_encryption entry
144+
disk_encryption: DiskEncryption | None = None
145+
146+
if args_config.get('disk_encryption', None) is not None and arch_config.disk_config is not None:
147+
disk_encryption = DiskEncryption.parse_arg(
148+
arch_config.disk_config,
149+
args_config['disk_encryption'],
150+
Password(plaintext=args_config.get('encryption_password', '')),
151+
)
152+
153+
if disk_encryption:
154+
arch_config.disk_config.disk_encryption = disk_encryption
141155

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

174-
if args_config.get('disk_encryption', None) is not None and arch_config.disk_config is not None:
175-
arch_config.disk_encryption = DiskEncryption.parse_arg(
176-
arch_config.disk_config,
177-
args_config['disk_encryption'],
178-
Password(plaintext=args_config.get('encryption_password', '')),
179-
)
180-
181188
if hostname := args_config.get('hostname', ''):
182189
arch_config.hostname = hostname
183190

archinstall/lib/disk/disk_menu.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
from dataclasses import dataclass
22
from typing import override
33

4+
from archinstall.lib.disk.encryption_menu import DiskEncryptionMenu
45
from archinstall.lib.models.device_model import (
56
BtrfsOptions,
7+
DiskEncryption,
68
DiskLayoutConfiguration,
79
DiskLayoutType,
10+
EncryptionType,
811
LvmConfiguration,
912
SnapshotConfig,
1013
SnapshotType,
@@ -25,6 +28,7 @@ class DiskMenuConfig:
2528
disk_config: DiskLayoutConfiguration | None
2629
lvm_config: LvmConfiguration | None
2730
btrfs_snapshot_config: SnapshotConfig | None
31+
disk_encryption: DiskEncryption | None
2832

2933

3034
class DiskLayoutConfigurationMenu(AbstractSubMenu[DiskLayoutConfiguration]):
@@ -34,13 +38,15 @@ def __init__(self, disk_layout_config: DiskLayoutConfiguration | None):
3438
disk_config=None,
3539
lvm_config=None,
3640
btrfs_snapshot_config=None,
41+
disk_encryption=None,
3742
)
3843
else:
3944
snapshot_config = disk_layout_config.btrfs_options.snapshot_config if disk_layout_config.btrfs_options else None
4045

4146
self._disk_menu_config = DiskMenuConfig(
4247
disk_config=disk_layout_config,
4348
lvm_config=disk_layout_config.lvm_config,
49+
disk_encryption=disk_layout_config.disk_encryption,
4450
btrfs_snapshot_config=snapshot_config,
4551
)
4652

@@ -70,6 +76,13 @@ def _define_menu_options(self) -> list[MenuItem]:
7076
dependencies=[self._check_dep_lvm],
7177
key='lvm_config',
7278
),
79+
MenuItem(
80+
text=tr('Disk encryption'),
81+
action=self._disk_encryption,
82+
preview_action=self._prev_disk_encryption,
83+
dependencies=['disk_config'],
84+
key='disk_encryption',
85+
),
7386
MenuItem(
7487
text='Btrfs snapshots',
7588
action=self._select_btrfs_snapshots,
@@ -87,6 +100,7 @@ def run(self) -> DiskLayoutConfiguration | None:
87100
if self._disk_menu_config.disk_config:
88101
self._disk_menu_config.disk_config.lvm_config = self._disk_menu_config.lvm_config
89102
self._disk_menu_config.disk_config.btrfs_options = BtrfsOptions(snapshot_config=self._disk_menu_config.btrfs_snapshot_config)
103+
self._disk_menu_config.disk_config.disk_encryption = self._disk_menu_config.disk_encryption
90104
return self._disk_menu_config.disk_config
91105

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

108122
return False
109123

124+
def _disk_encryption(self, preset: DiskEncryption | None) -> DiskEncryption | None:
125+
disk_config: DiskLayoutConfiguration | None = self._item_group.find_by_key('disk_config').value
126+
127+
if not disk_config:
128+
# this should not happen as the encryption menu has the disk_config as dependency
129+
raise ValueError('No disk layout specified')
130+
131+
if not DiskEncryption.validate_enc(disk_config):
132+
return None
133+
134+
disk_encryption = DiskEncryptionMenu(disk_config, preset=preset).run()
135+
return disk_encryption
136+
110137
def _select_disk_layout_config(self, preset: DiskLayoutConfiguration | None) -> DiskLayoutConfiguration | None:
111138
disk_config = select_disk_config(preset)
112139

113140
if disk_config != preset:
114141
self._menu_item_group.find_by_key('lvm_config').value = None
142+
self._menu_item_group.find_by_key('disk_encryption').value = None
115143

116144
return disk_config
117145

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

218246
snapshot_config: SnapshotConfig = item.value
219247
return tr('Snapshot type: {}').format(snapshot_config.snapshot_type.value)
248+
249+
def _prev_disk_encryption(self, item: MenuItem) -> str | None:
250+
disk_config: DiskLayoutConfiguration | None = self._item_group.find_by_key('disk_config').value
251+
enc_config: DiskEncryption | None = item.value
252+
253+
if disk_config and not DiskEncryption.validate_enc(disk_config):
254+
return tr('LVM disk encryption with more than 2 partitions is currently not supported')
255+
256+
if enc_config:
257+
enc_type = EncryptionType.type_to_text(enc_config.encryption_type)
258+
output = tr('Encryption type') + f': {enc_type}\n'
259+
260+
if enc_config.encryption_password:
261+
output += tr('Password') + f': {enc_config.encryption_password.hidden()}\n'
262+
263+
if enc_config.partitions:
264+
output += f'Partitions: {len(enc_config.partitions)} selected\n'
265+
elif enc_config.lvm_volumes:
266+
output += f'LVM volumes: {len(enc_config.lvm_volumes)} selected\n'
267+
268+
if enc_config.hsm_device:
269+
output += f'HSM: {enc_config.hsm_device.manufacturer}'
270+
271+
return output
272+
273+
return None

archinstall/lib/disk/filesystem.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,9 @@
2727

2828

2929
class FilesystemHandler:
30-
def __init__(
31-
self,
32-
disk_config: DiskLayoutConfiguration,
33-
enc_conf: DiskEncryption | None = None,
34-
):
30+
def __init__(self, disk_config: DiskLayoutConfiguration):
3531
self._disk_config = disk_config
36-
self._enc_config = enc_conf
32+
self._enc_config = disk_config.disk_encryption
3733

3834
def perform_filesystem_operations(self, show_countdown: bool = True) -> None:
3935
if self._disk_config.config_type == DiskLayoutType.Pre_mount:

archinstall/lib/global_menu.py

Lines changed: 4 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
from typing import override
44

55
from archinstall.lib.disk.disk_menu import DiskLayoutConfigurationMenu
6-
from archinstall.lib.disk.encryption_menu import DiskEncryptionMenu
7-
from archinstall.lib.models.device_model import DiskEncryption, DiskLayoutConfiguration, DiskLayoutType, EncryptionType, FilesystemType, PartitionModification
6+
from archinstall.lib.models.device_model import DiskLayoutConfiguration, DiskLayoutType, EncryptionType, FilesystemType, PartitionModification
87
from archinstall.lib.packages import list_available_packages
98
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
109

@@ -79,13 +78,6 @@ def _get_menu_options(self) -> list[MenuItem]:
7978
mandatory=True,
8079
key='disk_config',
8180
),
82-
MenuItem(
83-
text=tr('Disk encryption'),
84-
action=self._disk_encryption,
85-
preview_action=self._prev_disk_encryption,
86-
dependencies=['disk_config'],
87-
key='disk_encryption',
88-
),
8981
MenuItem(
9082
text=tr('Swap'),
9183
value=True,
@@ -270,19 +262,6 @@ def _update_lang_text(self) -> None:
270262
if o.key is not None:
271263
self._item_group.find_by_key(o.key).text = o.text
272264

273-
def _disk_encryption(self, preset: DiskEncryption | None) -> DiskEncryption | None:
274-
disk_config: DiskLayoutConfiguration | None = self._item_group.find_by_key('disk_config').value
275-
276-
if not disk_config:
277-
# this should not happen as the encryption menu has the disk_config as dependency
278-
raise ValueError('No disk layout specified')
279-
280-
if not DiskEncryption.validate_enc(disk_config):
281-
return None
282-
283-
disk_encryption = DiskEncryptionMenu(disk_config, preset=preset).run()
284-
return disk_encryption
285-
286265
def _locale_selection(self, preset: LocaleConfiguration) -> LocaleConfiguration:
287266
locale_config = LocaleMenu(preset).run()
288267
return locale_config
@@ -335,6 +314,9 @@ def _prev_disk_config(self, item: MenuItem) -> str | None:
335314
if disk_layout_conf.lvm_config:
336315
output += '{}: {}'.format(tr('LVM configuration type'), disk_layout_conf.lvm_config.config_type.display_msg())
337316

317+
if disk_layout_conf.disk_encryption:
318+
output += tr('Disk encryption') + ': ' + EncryptionType.type_to_text(disk_layout_conf.disk_encryption.encryption_type)
319+
338320
if disk_layout_conf.btrfs_options:
339321
btrfs_options = disk_layout_conf.btrfs_options
340322
if btrfs_options.snapshot_config:
@@ -391,32 +373,6 @@ def _prev_bootloader(self, item: MenuItem) -> str | None:
391373
return f'{tr("Bootloader")}: {item.value.value}'
392374
return None
393375

394-
def _prev_disk_encryption(self, item: MenuItem) -> str | None:
395-
disk_config: DiskLayoutConfiguration | None = self._item_group.find_by_key('disk_config').value
396-
enc_config: DiskEncryption | None = item.value
397-
398-
if disk_config and not DiskEncryption.validate_enc(disk_config):
399-
return tr('LVM disk encryption with more than 2 partitions is currently not supported')
400-
401-
if enc_config:
402-
enc_type = EncryptionType.type_to_text(enc_config.encryption_type)
403-
output = tr('Encryption type') + f': {enc_type}\n'
404-
405-
if enc_config.encryption_password:
406-
output += tr('Password') + f': {enc_config.encryption_password.hidden()}\n'
407-
408-
if enc_config.partitions:
409-
output += f'Partitions: {len(enc_config.partitions)} selected\n'
410-
elif enc_config.lvm_volumes:
411-
output += f'LVM volumes: {len(enc_config.lvm_volumes)} selected\n'
412-
413-
if enc_config.hsm_device:
414-
output += f'HSM: {enc_config.hsm_device.manufacturer}'
415-
416-
return output
417-
418-
return None
419-
420376
def _validate_bootloader(self) -> str | None:
421377
"""
422378
Checks the selected bootloader is valid for the selected filesystem
@@ -515,9 +471,6 @@ def _select_disk_config(
515471
) -> DiskLayoutConfiguration | None:
516472
disk_config = DiskLayoutConfigurationMenu(preset).run()
517473

518-
if disk_config != preset:
519-
self._menu_item_group.find_by_key('disk_encryption').value = None
520-
521474
return disk_config
522475

523476
def _select_bootloader(self, preset: Bootloader | None) -> Bootloader | None:

archinstall/lib/installer.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ def __init__(
6262
self,
6363
target: Path,
6464
disk_config: DiskLayoutConfiguration,
65-
disk_encryption: DiskEncryption | None = None,
6665
base_packages: list[str] = [],
6766
kernels: list[str] | None = None,
6867
):
@@ -74,7 +73,7 @@ def __init__(
7473
self.kernels = kernels or ['linux']
7574
self._disk_config = disk_config
7675

77-
self._disk_encryption = disk_encryption or DiskEncryption(EncryptionType.NoEncryption)
76+
self._disk_encryption = disk_config.disk_encryption or DiskEncryption(EncryptionType.NoEncryption)
7877
self.target: Path = target
7978

8079
self.init_time = time.strftime('%Y-%m-%d_%H-%M-%S')

archinstall/lib/models/device_model.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,15 @@ class _DiskLayoutConfigurationSerialization(TypedDict):
4141
lvm_config: NotRequired[_LvmConfigurationSerialization]
4242
mountpoint: NotRequired[str]
4343
btrfs_options: NotRequired[_BtrfsOptionsSerialization]
44+
disk_encryption: NotRequired[_DiskEncryptionSerialization]
4445

4546

4647
@dataclass
4748
class DiskLayoutConfiguration:
4849
config_type: DiskLayoutType
4950
device_modifications: list[DeviceModification] = field(default_factory=list)
5051
lvm_config: LvmConfiguration | None = None
52+
disk_encryption: DiskEncryption | None = None
5153
btrfs_options: BtrfsOptions | None = None
5254

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

73+
if self.disk_encryption:
74+
config['disk_encryption'] = self.disk_encryption.json()
75+
7176
if self.btrfs_options:
7277
config['btrfs_options'] = self.btrfs_options.json()
7378

7479
return config
7580

7681
@classmethod
77-
def parse_arg(cls, disk_config: _DiskLayoutConfigurationSerialization) -> DiskLayoutConfiguration | None:
82+
def parse_arg(
83+
cls,
84+
disk_config: _DiskLayoutConfigurationSerialization,
85+
enc_password: Password | None = None,
86+
disk_encryption: _DiskEncryptionSerialization | None = None,
87+
) -> DiskLayoutConfiguration | None:
7888
from archinstall.lib.disk.device_handler import device_handler
7989

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

192+
if (enc_config := disk_config.get('disk_encryption', None)) is not None:
193+
config.disk_encryption = DiskEncryption.parse_arg(config, enc_config, enc_password)
194+
182195
if config.is_default_btrfs():
183196
if (btrfs_arg := disk_config.get('btrfs_options', None)) is not None:
184197
config.btrfs_options = BtrfsOptions.parse_arg(btrfs_arg)

0 commit comments

Comments
 (0)