Skip to content

Commit 37b3985

Browse files
authored
Move audio configuration to application config (#3612)
1 parent 63848f6 commit 37b3985

18 files changed

Lines changed: 241 additions & 190 deletions

File tree

archinstall/applications/audio.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
from typing import TYPE_CHECKING
2+
3+
from archinstall.lib.hardware import SysInfo
4+
from archinstall.lib.models.application import Audio, AudioConfiguration
5+
from archinstall.lib.models.users import User
6+
from archinstall.lib.output import debug
7+
8+
if TYPE_CHECKING:
9+
from archinstall.lib.installer import Installer
10+
11+
12+
class AudioApp:
13+
@property
14+
def pulseaudio_packages(self) -> list[str]:
15+
return [
16+
'pulseaudio',
17+
]
18+
19+
@property
20+
def pipewire_packages(self) -> list[str]:
21+
return [
22+
'pipewire',
23+
'pipewire-alsa',
24+
'pipewire-jack',
25+
'pipewire-pulse',
26+
'gst-plugin-pipewire',
27+
'libpulse',
28+
'wireplumber',
29+
]
30+
31+
def _enable_pipewire(
32+
self,
33+
install_session: 'Installer',
34+
users: list['User'] | None = None,
35+
) -> None:
36+
if users is None:
37+
return
38+
39+
for user in users:
40+
# Create the full path for enabling the pipewire systemd items
41+
service_dir = install_session.target / 'home' / user.username / '.config' / 'systemd' / 'user' / 'default.target.wants'
42+
service_dir.mkdir(parents=True, exist_ok=True)
43+
44+
# Set ownership of the entire user catalogue
45+
install_session.arch_chroot(f'chown -R {user.username}:{user.username} /home/{user.username}')
46+
47+
# symlink in the correct pipewire systemd items
48+
install_session.arch_chroot(
49+
f'ln -sf /usr/lib/systemd/user/pipewire-pulse.service /home/{user.username}/.config/systemd/user/default.target.wants/pipewire-pulse.service',
50+
run_as=user.username,
51+
)
52+
install_session.arch_chroot(
53+
f'ln -sf /usr/lib/systemd/user/pipewire-pulse.socket /home/{user.username}/.config/systemd/user/default.target.wants/pipewire-pulse.socket',
54+
run_as=user.username,
55+
)
56+
57+
def install(
58+
self,
59+
install_session: 'Installer',
60+
audio_config: AudioConfiguration,
61+
users: list[User] | None = None,
62+
) -> None:
63+
debug(f'Installing audio server: {audio_config.audio.value}')
64+
65+
if audio_config.audio == Audio.NO_AUDIO:
66+
debug('No audio server selected, skipping installation.')
67+
return
68+
69+
if SysInfo.requires_sof_fw():
70+
install_session.add_additional_packages('sof-firmware')
71+
72+
if SysInfo.requires_alsa_fw():
73+
install_session.add_additional_packages('alsa-firmware')
74+
75+
match audio_config.audio:
76+
case Audio.PIPEWIRE:
77+
install_session.add_additional_packages(self.pipewire_packages)
78+
self._enable_pipewire(install_session, users)
79+
case Audio.PULSEAUDIO:
80+
install_session.add_additional_packages(self.pulseaudio_packages)

archinstall/applications/bluetooth.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from archinstall.lib.installer import Installer
77

88

9-
class Bluetooth:
9+
class BluetoothApp:
1010
@property
1111
def packages(self) -> list[str]:
1212
return [

archinstall/default_profiles/applications/__init__.py

Whitespace-only changes.

archinstall/default_profiles/applications/pipewire.py

Lines changed: 0 additions & 57 deletions
This file was deleted.
Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from typing import TYPE_CHECKING
22

3-
from archinstall.applications.bluetooth import Bluetooth
3+
from archinstall.applications.audio import AudioApp
4+
from archinstall.applications.bluetooth import BluetoothApp
45
from archinstall.lib.models.application import ApplicationConfiguration
6+
from archinstall.lib.models.users import User
57

68
if TYPE_CHECKING:
79
from archinstall.lib.installer import Installer
@@ -11,13 +13,16 @@ class ApplicationHandler:
1113
def __init__(self) -> None:
1214
pass
1315

14-
def install_applications(
15-
self,
16-
install_session: 'Installer',
17-
app_config: ApplicationConfiguration,
18-
) -> None:
16+
def install_applications(self, install_session: 'Installer', app_config: ApplicationConfiguration, users: list['User'] | None = None) -> None:
1917
if app_config.bluetooth_config:
20-
Bluetooth().install(install_session)
18+
BluetoothApp().install(install_session)
19+
20+
if app_config.audio_config:
21+
AudioApp().install(
22+
install_session,
23+
app_config.audio_config,
24+
users,
25+
)
2126

2227

2328
application_handler = ApplicationHandler()

archinstall/lib/applications/application_menu.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from typing import override
22

33
from archinstall.lib.menu.abstract_menu import AbstractSubMenu
4-
from archinstall.lib.models.application import ApplicationConfiguration, BluetoothConfiguration
4+
from archinstall.lib.models.application import ApplicationConfiguration, Audio, AudioConfiguration, BluetoothConfiguration
55
from archinstall.lib.translationhandler import tr
66
from archinstall.tui.curses_menu import SelectMenu
77
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
8-
from archinstall.tui.types import Alignment, Orientation
8+
from archinstall.tui.result import ResultType
9+
from archinstall.tui.types import Alignment, FrameProperties, Orientation
910

1011

1112
class ApplicationMenu(AbstractSubMenu[ApplicationConfiguration]):
@@ -41,6 +42,12 @@ def _define_menu_options(self) -> list[MenuItem]:
4142
preview_action=self._prev_bluetooth,
4243
key='bluetooth_config',
4344
),
45+
MenuItem(
46+
text=tr('Audio'),
47+
action=select_audio,
48+
preview_action=self._prev_audio,
49+
key='audio_config',
50+
),
4451
]
4552

4653
def _prev_bluetooth(self, item: MenuItem) -> str | None:
@@ -52,6 +59,12 @@ def _prev_bluetooth(self, item: MenuItem) -> str | None:
5259
return output
5360
return None
5461

62+
def _prev_audio(self, item: MenuItem) -> str | None:
63+
if item.value is not None:
64+
config: AudioConfiguration = item.value
65+
return f'{tr("Audio")}: {config.audio.value}'
66+
return None
67+
5568

5669
def select_bluetooth(preset: BluetoothConfiguration | None) -> BluetoothConfiguration | None:
5770
group = MenuItemGroup.yes_no()
@@ -74,3 +87,26 @@ def select_bluetooth(preset: BluetoothConfiguration | None) -> BluetoothConfigur
7487
enabled = result.item() == MenuItem.yes()
7588

7689
return BluetoothConfiguration(enabled)
90+
91+
92+
def select_audio(preset: AudioConfiguration | None = None) -> AudioConfiguration | None:
93+
items = [MenuItem(a.value, value=a) for a in Audio]
94+
group = MenuItemGroup(items)
95+
96+
if preset:
97+
group.set_focus_by_value(preset.audio)
98+
99+
result = SelectMenu[Audio](
100+
group,
101+
allow_skip=True,
102+
alignment=Alignment.CENTER,
103+
frame=FrameProperties.min(tr('Audio')),
104+
).run()
105+
106+
match result.type_:
107+
case ResultType.Skip:
108+
return preset
109+
case ResultType.Selection:
110+
return AudioConfiguration(audio=result.get_value())
111+
case ResultType.Reset:
112+
raise ValueError('Unhandled result type')

archinstall/lib/args.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
from archinstall.lib.crypt import decrypt
1616
from archinstall.lib.models.application import ApplicationConfiguration
17-
from archinstall.lib.models.audio_configuration import AudioConfiguration
1817
from archinstall.lib.models.bootloader import Bootloader
1918
from archinstall.lib.models.device_model import DiskEncryption, DiskLayoutConfiguration
2019
from archinstall.lib.models.locale import LocaleConfiguration
@@ -63,8 +62,7 @@ class ArchConfig:
6362
network_config: NetworkConfiguration | None = None
6463
bootloader: Bootloader = field(default=Bootloader.get_default())
6564
uki: bool = False
66-
audio_config: AudioConfiguration | None = None
67-
application_config: ApplicationConfiguration | None = None
65+
app_config: ApplicationConfiguration | None = None
6866
hostname: str = 'archlinux'
6967
kernels: list[str] = field(default_factory=lambda: ['linux'])
7068
ntp: bool = True
@@ -106,8 +104,7 @@ def safe_json(self) -> dict[str, Any]:
106104
'services': self.services,
107105
'custom_commands': self.custom_commands,
108106
'bootloader': self.bootloader.json(),
109-
'audio_config': self.audio_config.json() if self.audio_config else None,
110-
'app_config': self.application_config.json() if self.application_config else None,
107+
'app_config': self.app_config.json() if self.app_config else None,
111108
}
112109

113110
if self.locale_config:
@@ -184,11 +181,12 @@ def from_config(cls, args_config: dict[str, Any]) -> 'ArchConfig':
184181
if args_config.get('uki') and not arch_config.bootloader.has_uki_support():
185182
arch_config.uki = False
186183

187-
if audio_config := args_config.get('audio_config', None):
188-
arch_config.audio_config = AudioConfiguration.parse_arg(audio_config)
184+
# deprecated: backwards compatibility
185+
audio_config_args = args_config.get('audio_config', None)
186+
app_config_args = args_config.get('app_config', None)
189187

190-
if app_config := args_config.get('app_config', None):
191-
arch_config.application_config = ApplicationConfiguration.parse_arg(app_config)
188+
if audio_config_args is not None or app_config_args is not None:
189+
arch_config.app_config = ApplicationConfiguration.parse_arg(app_config_args, audio_config_args)
192190

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

archinstall/lib/global_menu.py

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
add_number_of_parallel_downloads,
1717
ask_additional_packages_to_install,
1818
ask_for_a_timezone,
19-
ask_for_audio_selection,
2019
ask_hostname,
2120
ask_ntp,
2221
)
@@ -26,7 +25,6 @@
2625
from .locale.locale_menu import LocaleMenu
2726
from .menu.abstract_menu import CONFIG_KEY, AbstractMenu
2827
from .mirrors import MirrorMenu
29-
from .models.audio_configuration import AudioConfiguration
3028
from .models.bootloader import Bootloader
3129
from .models.locale import LocaleConfiguration
3230
from .models.mirrors import MirrorConfiguration
@@ -128,12 +126,6 @@ def _get_menu_options(self) -> list[MenuItem]:
128126
preview_action=self._prev_profile,
129127
key='profile_config',
130128
),
131-
MenuItem(
132-
text=tr('Audio'),
133-
action=ask_for_audio_selection,
134-
preview_action=self._prev_audio,
135-
key='audio_config',
136-
),
137129
MenuItem(
138130
text=tr('Applications'),
139131
action=self._select_applications,
@@ -311,7 +303,13 @@ def _prev_applications(self, item: MenuItem) -> str | None:
311303

312304
if app_config.bluetooth_config:
313305
output += f'{tr("Bluetooth")}: '
314-
output += tr('Enabled') if app_config.bluetooth_config.enabled else tr('Disabled') + '\n'
306+
output += tr('Enabled') if app_config.bluetooth_config.enabled else tr('Disabled')
307+
output += '\n'
308+
309+
if app_config.audio_config:
310+
audio_config = app_config.audio_config
311+
output += f'{tr("Audio")}: {audio_config.audio.value}'
312+
output += '\n'
315313

316314
return output
317315

@@ -378,12 +376,6 @@ def _prev_root_pwd(self, item: MenuItem) -> str | None:
378376
return f'{tr("Root password")}: {password.hidden()}'
379377
return None
380378

381-
def _prev_audio(self, item: MenuItem) -> str | None:
382-
if item.value is not None:
383-
config: AudioConfiguration = item.value
384-
return f'{tr("Audio")}: {config.audio.value}'
385-
return None
386-
387379
def _prev_parallel_dw(self, item: MenuItem) -> str | None:
388380
if item.value is not None:
389381
return f'{tr("Parallel Downloads")}: {item.value}'

archinstall/lib/interactions/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
add_number_of_parallel_downloads,
1111
ask_additional_packages_to_install,
1212
ask_for_a_timezone,
13-
ask_for_audio_selection,
1413
ask_hostname,
1514
ask_ntp,
1615
select_archinstall_language,
@@ -26,7 +25,6 @@
2625
'ask_additional_packages_to_install',
2726
'ask_for_a_timezone',
2827
'ask_for_additional_users',
29-
'ask_for_audio_selection',
3028
'ask_for_bootloader',
3129
'ask_for_swap',
3230
'ask_for_uki',

0 commit comments

Comments
 (0)