Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/archinstall/default_profiles
diff options
context:
space:
mode:
Diffstat (limited to 'archinstall/default_profiles')
-rw-r--r--archinstall/default_profiles/__init__.py0
-rw-r--r--archinstall/default_profiles/applications/__init__.py0
-rw-r--r--archinstall/default_profiles/applications/pipewire.py40
-rw-r--r--archinstall/default_profiles/custom.py218
-rw-r--r--archinstall/default_profiles/desktop.py87
-rw-r--r--archinstall/default_profiles/desktops/__init__.py0
-rw-r--r--archinstall/default_profiles/desktops/awesome.py63
-rw-r--r--archinstall/default_profiles/desktops/bspwm.py27
-rw-r--r--archinstall/default_profiles/desktops/budgie.py26
-rw-r--r--archinstall/default_profiles/desktops/cinnamon.py27
-rw-r--r--archinstall/default_profiles/desktops/cutefish.py27
-rw-r--r--archinstall/default_profiles/desktops/deepin.py24
-rw-r--r--archinstall/default_profiles/desktops/enlightenment.py23
-rw-r--r--archinstall/default_profiles/desktops/gnome.py23
-rw-r--r--archinstall/default_profiles/desktops/hyprland.py68
-rw-r--r--archinstall/default_profiles/desktops/i3.py29
-rw-r--r--archinstall/default_profiles/desktops/lxqt.py31
-rw-r--r--archinstall/default_profiles/desktops/mate.py23
-rw-r--r--archinstall/default_profiles/desktops/plasma.py27
-rw-r--r--archinstall/default_profiles/desktops/qtile.py23
-rw-r--r--archinstall/default_profiles/desktops/sway.py77
-rw-r--r--archinstall/default_profiles/desktops/xfce4.py26
-rw-r--r--archinstall/default_profiles/minimal.py15
-rw-r--r--archinstall/default_profiles/profile.py205
-rw-r--r--archinstall/default_profiles/server.py56
-rw-r--r--archinstall/default_profiles/servers/__init__.py0
-rw-r--r--archinstall/default_profiles/servers/cockpit.py19
-rw-r--r--archinstall/default_profiles/servers/docker.py33
-rw-r--r--archinstall/default_profiles/servers/httpd.py19
-rw-r--r--archinstall/default_profiles/servers/lighttpd.py19
-rw-r--r--archinstall/default_profiles/servers/mariadb.py25
-rw-r--r--archinstall/default_profiles/servers/nginx.py19
-rw-r--r--archinstall/default_profiles/servers/postgresql.py26
-rw-r--r--archinstall/default_profiles/servers/sshd.py19
-rw-r--r--archinstall/default_profiles/servers/tomcat.py19
-rw-r--r--archinstall/default_profiles/tailored.py21
-rw-r--r--archinstall/default_profiles/xorg.py34
37 files changed, 1418 insertions, 0 deletions
diff --git a/archinstall/default_profiles/__init__.py b/archinstall/default_profiles/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/archinstall/default_profiles/__init__.py
diff --git a/archinstall/default_profiles/applications/__init__.py b/archinstall/default_profiles/applications/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/archinstall/default_profiles/applications/__init__.py
diff --git a/archinstall/default_profiles/applications/pipewire.py b/archinstall/default_profiles/applications/pipewire.py
new file mode 100644
index 00000000..4cb75968
--- /dev/null
+++ b/archinstall/default_profiles/applications/pipewire.py
@@ -0,0 +1,40 @@
+from typing import List, Union, Any, TYPE_CHECKING
+
+import archinstall
+
+from archinstall.default_profiles.profile import Profile, ProfileType
+from archinstall.lib.models import User
+
+if TYPE_CHECKING:
+ from archinstall.lib.installer import Installer
+ _: Any
+
+
+class PipewireProfile(Profile):
+ def __init__(self):
+ super().__init__('Pipewire', ProfileType.Application)
+
+ @property
+ def packages(self) -> List[str]:
+ return [
+ 'pipewire',
+ 'pipewire-alsa',
+ 'pipewire-jack',
+ 'pipewire-pulse',
+ 'gst-plugin-pipewire',
+ 'libpulse',
+ 'wireplumber'
+ ]
+
+ def _enable_pipewire_for_all(self, install_session: 'Installer'):
+ users: Union[User, List[User]] = archinstall.arguments.get('!users', [])
+ if not isinstance(users, list):
+ users = [users]
+
+ for user in users:
+ install_session.arch_chroot('systemctl enable --user pipewire-pulse.service', run_as=user.username)
+
+ def install(self, install_session: 'Installer'):
+ super().install(install_session)
+ install_session.add_additional_packages(self.packages)
+ self._enable_pipewire_for_all(install_session)
diff --git a/archinstall/default_profiles/custom.py b/archinstall/default_profiles/custom.py
new file mode 100644
index 00000000..5f9db620
--- /dev/null
+++ b/archinstall/default_profiles/custom.py
@@ -0,0 +1,218 @@
+# from typing import List, Dict, Optional, TYPE_CHECKING, Any
+#
+# from ..lib import menu
+# from archinstall.lib.output import log, FormattedOutput
+# from archinstall.lib.profile.profiles_handler import profile_handler
+# from archinstall.default_profiles.profile import Profile, ProfileType, SelectResult, ProfileInfo, TProfile
+#
+# if TYPE_CHECKING:
+# from archinstall.lib.installer import Installer
+# _: Any
+#
+#
+# class CustomProfileList(menu.ListManager):
+# def __init__(self, prompt: str, profiles: List[TProfile]):
+# self._actions = [
+# str(_('Add profile')),
+# str(_('Edit profile')),
+# str(_('Delete profile'))
+# ]
+# super().__init__(prompt, profiles, [self._actions[0]], self._actions[1:])
+#
+# def reformat(self, data: List[TProfile]) -> Dict[str, Optional[TProfile]]:
+# table = FormattedOutput.as_table(data)
+# rows = table.split('\n')
+#
+# # these are the header rows of the table and do not map to any profile obviously
+# # we're adding 2 spaces as prefix because the menu selector '> ' will be put before
+# # the selectable rows so the header has to be aligned
+# display_data: Dict[str, Optional[TProfile]] = {f' {rows[0]}': None, f' {rows[1]}': None}
+#
+# for row, profile in zip(rows[2:], data):
+# row = row.replace('|', '\\|')
+# display_data[row] = profile
+#
+# return display_data
+#
+# def selected_action_display(self, profile: TProfile) -> str:
+# return profile.name
+#
+# def handle_action(
+# self,
+# action: str,
+# entry: Optional['CustomTypeProfile'],
+# data: List['CustomTypeProfile']
+# ) -> List['CustomTypeProfile']:
+# if action == self._actions[0]: # add
+# new_profile = self._add_profile()
+# if new_profile is not None:
+# # in case a profile with the same name as an existing profile
+# # was created we'll replace the existing one
+# data = [d for d in data if d.name != new_profile.name]
+# data += [new_profile]
+# elif entry is not None:
+# if action == self._actions[1]: # edit
+# new_profile = self._add_profile(entry)
+# if new_profile is not None:
+# # we'll remove the original profile and add the modified version
+# data = [d for d in data if d.name != entry.name and d.name != new_profile.name]
+# data += [new_profile]
+# elif action == self._actions[2]: # delete
+# data = [d for d in data if d != entry]
+#
+# return data
+#
+# def _is_new_profile_name(self, name: str) -> bool:
+# existing_profile = profile_handler.get_profile_by_name(name)
+# if existing_profile is not None and existing_profile.profile_type != ProfileType.CustomType:
+# return False
+# return True
+#
+# def _add_profile(self, editing: Optional['CustomTypeProfile'] = None) -> Optional['CustomTypeProfile']:
+# name_prompt = '\n\n' + str(_('Profile name: '))
+#
+# while True:
+# profile_name = menu.TextInput(name_prompt, editing.name if editing else '').run().strip()
+#
+# if not profile_name:
+# return None
+#
+# if not self._is_new_profile_name(profile_name):
+# error_prompt = str(_("The profile name you entered is already in use. Try again"))
+# print(error_prompt)
+# else:
+# break
+#
+# packages_prompt = str(_('Packages to be install with this profile (space separated, leave blank to skip): '))
+# edit_packages = ' '.join(editing.packages) if editing else ''
+# packages = menu.TextInput(packages_prompt, edit_packages).run().strip()
+#
+# services_prompt = str(_('Services to be enabled with this profile (space separated, leave blank to skip): '))
+# edit_services = ' '.join(editing.services) if editing else ''
+# services = menu.TextInput(services_prompt, edit_services).run().strip()
+#
+# choice = menu.Menu(
+# str(_('Should this profile be enabled for installation?')),
+# menu.Menu.yes_no(),
+# skip=False,
+# default_option=menu.Menu.no(),
+# clear_screen=False,
+# show_search_hint=False
+# ).run()
+#
+# enable_profile = True if choice.value == menu.Menu.yes() else False
+#
+# profile = CustomTypeProfile(
+# profile_name,
+# enabled=enable_profile,
+# packages=packages.split(' '),
+# services=services.split(' ')
+# )
+#
+# return profile
+#
+#
+# # TODO
+# # Still needs some ironing out
+# class CustomProfile():
+# def __init__(self):
+# super().__init__(
+# 'Custom',
+# ProfileType.Custom,
+# description=str(_('Create your own'))
+# )
+#
+# def json(self) -> Dict[str, Any]:
+# data: Dict[str, Any] = {'main': self.name, 'gfx_driver': self.gfx_driver, 'custom': []}
+#
+# for profile in self._current_selection:
+# data['custom'].append({
+# 'name': profile.name,
+# 'packages': profile.packages,
+# 'services': profile.services,
+# 'enabled': profile.custom_enabled
+# })
+#
+# return data
+#
+# def do_on_select(self) -> SelectResult:
+# custom_profile_list = CustomProfileList('', profile_handler.get_custom_profiles())
+# custom_profiles = custom_profile_list.run()
+#
+# # we'll first remove existing custom default_profiles with
+# # the same name and then add the new ones this
+# # will avoid errors of default_profiles with duplicate naming
+# profile_handler.remove_custom_profiles(custom_profiles)
+# profile_handler.add_custom_profiles(custom_profiles)
+#
+# self.set_current_selection(custom_profiles)
+#
+# if custom_profile_list.is_last_choice_cancel():
+# return SelectResult.SameSelection
+#
+# enabled_profiles = [p for p in self._current_selection if p.custom_enabled]
+# # in case we only created inactive default_profiles we wanna store them but
+# # we want to reset the original setting
+# if not enabled_profiles:
+# return SelectResult.ResetCurrent
+#
+# return SelectResult.NewSelection
+#
+# def post_install(self, install_session: 'Installer'):
+# for profile in self._current_selection:
+# profile.post_install(install_session)
+#
+# def install(self, install_session: 'Installer'):
+# driver_packages = self.gfx_driver_packages()
+# install_session.add_additional_packages(driver_packages)
+#
+# for profile in self._current_selection:
+# if profile.custom_enabled:
+# log(f'Installing custom profile {profile.name}...')
+#
+# install_session.add_additional_packages(profile.packages)
+# install_session.enable_service(profile.services)
+#
+# profile.install(install_session)
+#
+# def info(self) -> Optional[ProfileInfo]:
+# enabled_profiles = [p for p in self._current_selection if p.custom_enabled]
+# if enabled_profiles:
+# details = ', '.join([p.name for p in enabled_profiles])
+# gfx_driver = self.gfx_driver
+# return ProfileInfo(self.name, details, gfx_driver)
+#
+# return None
+#
+# def reset(self):
+# for profile in self._current_selection:
+# profile.set_enabled(False)
+#
+# self.gfx_driver = None
+#
+#
+# class CustomTypeProfile(Profile):
+# def __init__(
+# self,
+# name: str,
+# enabled: bool = False,
+# packages: List[str] = [],
+# services: List[str] = []
+# ):
+# super().__init__(
+# name,
+# ProfileType.CustomType,
+# packages=packages,
+# services=services,
+# support_gfx_driver=True
+# )
+#
+# self.custom_enabled = enabled
+#
+# def json(self) -> Dict[str, Any]:
+# return {
+# 'name': self.name,
+# 'packages': self.packages,
+# 'services': self.services,
+# 'enabled': self.custom_enabled
+# }
diff --git a/archinstall/default_profiles/desktop.py b/archinstall/default_profiles/desktop.py
new file mode 100644
index 00000000..417d86d6
--- /dev/null
+++ b/archinstall/default_profiles/desktop.py
@@ -0,0 +1,87 @@
+from typing import Any, TYPE_CHECKING, List, Optional, Dict
+
+from archinstall.lib import menu
+from archinstall.lib.output import info
+from archinstall.lib.profile.profiles_handler import profile_handler
+from archinstall.default_profiles.profile import Profile, ProfileType, SelectResult, GreeterType
+
+if TYPE_CHECKING:
+ from archinstall.lib.installer import Installer
+ _: Any
+
+
+class DesktopProfile(Profile):
+ def __init__(self, current_selection: List[Profile] = []):
+ super().__init__(
+ 'Desktop',
+ ProfileType.Desktop,
+ description=str(_('Provides a selection of desktop environments and tiling window managers, e.g. GNOME, KDE Plasma, Sway')),
+ current_selection=current_selection,
+ support_greeter=True
+ )
+
+ @property
+ def packages(self) -> List[str]:
+ return [
+ 'nano',
+ 'vim',
+ 'openssh',
+ 'htop',
+ 'wget',
+ 'iwd',
+ 'wireless_tools',
+ 'wpa_supplicant',
+ 'smartmontools',
+ 'xdg-utils'
+ ]
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ combined_greeters: Dict[GreeterType, int] = {}
+ for profile in self.current_selection:
+ if profile.default_greeter_type:
+ combined_greeters.setdefault(profile.default_greeter_type, 0)
+ combined_greeters[profile.default_greeter_type] += 1
+
+ if len(combined_greeters) >= 1:
+ return list(combined_greeters)[0]
+
+ return None
+
+ def _do_on_select_profiles(self):
+ for profile in self.current_selection:
+ profile.do_on_select()
+
+ def do_on_select(self) -> SelectResult:
+ choice = profile_handler.select_profile(
+ profile_handler.get_desktop_profiles(),
+ self._current_selection,
+ title=str(_('Select your desired desktop environment')),
+ multi=True
+ )
+
+ match choice.type_:
+ case menu.MenuSelectionType.Selection:
+ self.set_current_selection(choice.value) # type: ignore
+ self._do_on_select_profiles()
+ return SelectResult.NewSelection
+ case menu.MenuSelectionType.Skip:
+ return SelectResult.SameSelection
+ case menu.MenuSelectionType.Reset:
+ return SelectResult.ResetCurrent
+
+ def post_install(self, install_session: 'Installer'):
+ for profile in self._current_selection:
+ profile.post_install(install_session)
+
+ def install(self, install_session: 'Installer'):
+ # Install common packages for all desktop environments
+ install_session.add_additional_packages(self.packages)
+
+ for profile in self._current_selection:
+ info(f'Installing profile {profile.name}...')
+
+ install_session.add_additional_packages(profile.packages)
+ install_session.enable_service(profile.services)
+
+ profile.install(install_session)
diff --git a/archinstall/default_profiles/desktops/__init__.py b/archinstall/default_profiles/desktops/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/archinstall/default_profiles/desktops/__init__.py
diff --git a/archinstall/default_profiles/desktops/awesome.py b/archinstall/default_profiles/desktops/awesome.py
new file mode 100644
index 00000000..3833ce71
--- /dev/null
+++ b/archinstall/default_profiles/desktops/awesome.py
@@ -0,0 +1,63 @@
+from typing import List, Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import ProfileType
+from archinstall.default_profiles.xorg import XorgProfile
+
+if TYPE_CHECKING:
+ from archinstall.lib.installer import Installer
+ _: Any
+
+
+class AwesomeProfile(XorgProfile):
+ def __init__(self):
+ super().__init__('Awesome', ProfileType.WindowMgr, description='')
+
+ @property
+ def packages(self) -> List[str]:
+ return super().packages + [
+ 'awesome',
+ 'alacritty',
+ 'xorg-xinit',
+ 'xorg-xrandr',
+ 'xterm',
+ 'feh',
+ 'slock',
+ 'terminus-font',
+ 'gnu-free-fonts',
+ 'ttf-liberation',
+ 'xsel',
+ ]
+
+ def install(self, install_session: 'Installer'):
+ super().install(install_session)
+
+ # TODO: Copy a full configuration to ~/.config/awesome/rc.lua instead.
+ with open(f"{install_session.target}/etc/xdg/awesome/rc.lua", 'r') as fh:
+ awesome_lua = fh.read()
+
+ # Replace xterm with alacritty for a smoother experience.
+ awesome_lua = awesome_lua.replace('"xterm"', '"alacritty"')
+
+ with open(f"{install_session.target}/etc/xdg/awesome/rc.lua", 'w') as fh:
+ fh.write(awesome_lua)
+
+ # TODO: Configure the right-click-menu to contain the above packages that were installed. (as a user config)
+
+ # TODO: check if we selected a greeter,
+ # but for now, awesome is intended to run without one.
+ with open(f"{install_session.target}/etc/X11/xinit/xinitrc", 'r') as xinitrc:
+ xinitrc_data = xinitrc.read()
+
+ for line in xinitrc_data.split('\n'):
+ if "twm &" in line:
+ xinitrc_data = xinitrc_data.replace(line, f"# {line}")
+ if "xclock" in line:
+ xinitrc_data = xinitrc_data.replace(line, f"# {line}")
+ if "xterm" in line:
+ xinitrc_data = xinitrc_data.replace(line, f"# {line}")
+
+ xinitrc_data += '\n'
+ xinitrc_data += 'exec awesome\n'
+
+ with open(f"{install_session.target}/etc/X11/xinit/xinitrc", 'w') as xinitrc:
+ xinitrc.write(xinitrc_data) \ No newline at end of file
diff --git a/archinstall/default_profiles/desktops/bspwm.py b/archinstall/default_profiles/desktops/bspwm.py
new file mode 100644
index 00000000..61eeba43
--- /dev/null
+++ b/archinstall/default_profiles/desktops/bspwm.py
@@ -0,0 +1,27 @@
+from typing import List, Optional, Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import ProfileType, GreeterType
+from archinstall.default_profiles.xorg import XorgProfile
+
+if TYPE_CHECKING:
+ _: Any
+
+
+class BspwmProfile(XorgProfile):
+ def __init__(self):
+ super().__init__('Bspwm', ProfileType.WindowMgr, description='')
+
+ @property
+ def packages(self) -> List[str]:
+ # return super().packages + [
+ return [
+ 'bspwm',
+ 'sxhkd',
+ 'dmenu',
+ 'xdo',
+ 'rxvt-unicode'
+ ]
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ return GreeterType.Lightdm
diff --git a/archinstall/default_profiles/desktops/budgie.py b/archinstall/default_profiles/desktops/budgie.py
new file mode 100644
index 00000000..28c05f45
--- /dev/null
+++ b/archinstall/default_profiles/desktops/budgie.py
@@ -0,0 +1,26 @@
+from typing import List, Optional, Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import ProfileType, GreeterType
+from archinstall.default_profiles.xorg import XorgProfile
+
+if TYPE_CHECKING:
+ _: Any
+
+
+class BudgieProfile(XorgProfile):
+ def __init__(self):
+ super().__init__('Budgie', ProfileType.DesktopEnv, description='')
+
+ @property
+ def packages(self) -> List[str]:
+ return [
+ "arc-gtk-theme",
+ "budgie",
+ "mate-terminal",
+ "nemo",
+ "papirus-icon-theme"
+ ]
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ return GreeterType.LightdmSlick
diff --git a/archinstall/default_profiles/desktops/cinnamon.py b/archinstall/default_profiles/desktops/cinnamon.py
new file mode 100644
index 00000000..a819b4d1
--- /dev/null
+++ b/archinstall/default_profiles/desktops/cinnamon.py
@@ -0,0 +1,27 @@
+from typing import Optional, List, Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import ProfileType, GreeterType
+from archinstall.default_profiles.xorg import XorgProfile
+
+if TYPE_CHECKING:
+ _: Any
+
+
+class CinnamonProfile(XorgProfile):
+ def __init__(self):
+ super().__init__('Cinnamon', ProfileType.DesktopEnv, description='')
+
+ @property
+ def packages(self) -> List[str]:
+ return [
+ "cinnamon",
+ "system-config-printer",
+ "gnome-keyring",
+ "gnome-terminal",
+ "blueberry",
+ "metacity"
+ ]
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ return GreeterType.Lightdm
diff --git a/archinstall/default_profiles/desktops/cutefish.py b/archinstall/default_profiles/desktops/cutefish.py
new file mode 100644
index 00000000..c4202920
--- /dev/null
+++ b/archinstall/default_profiles/desktops/cutefish.py
@@ -0,0 +1,27 @@
+from typing import Optional, List, Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import ProfileType, GreeterType
+from archinstall.default_profiles.xorg import XorgProfile
+
+if TYPE_CHECKING:
+ from archinstall.lib.installer import Installer
+ _: Any
+
+
+class CutefishProfile(XorgProfile):
+ def __init__(self):
+ super().__init__('Cutefish', ProfileType.DesktopEnv, description='')
+
+ @property
+ def packages(self) -> List[str]:
+ return [
+ "cutefish",
+ "noto-fonts"
+ ]
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ return GreeterType.Sddm
+
+ def install(self, install_session: 'Installer'):
+ super().install(install_session)
diff --git a/archinstall/default_profiles/desktops/deepin.py b/archinstall/default_profiles/desktops/deepin.py
new file mode 100644
index 00000000..e6a9f6b5
--- /dev/null
+++ b/archinstall/default_profiles/desktops/deepin.py
@@ -0,0 +1,24 @@
+from typing import List, Optional, Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import ProfileType, GreeterType
+from archinstall.default_profiles.xorg import XorgProfile
+
+if TYPE_CHECKING:
+ _: Any
+
+
+class DeepinProfile(XorgProfile):
+ def __init__(self):
+ super().__init__('Deepin', ProfileType.DesktopEnv, description='')
+
+ @property
+ def packages(self) -> List[str]:
+ return [
+ "deepin",
+ "deepin-terminal",
+ "deepin-editor"
+ ]
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ return GreeterType.Lightdm
diff --git a/archinstall/default_profiles/desktops/enlightenment.py b/archinstall/default_profiles/desktops/enlightenment.py
new file mode 100644
index 00000000..7dd7822a
--- /dev/null
+++ b/archinstall/default_profiles/desktops/enlightenment.py
@@ -0,0 +1,23 @@
+from typing import List, Optional, Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import ProfileType, GreeterType
+from archinstall.default_profiles.xorg import XorgProfile
+
+if TYPE_CHECKING:
+ _: Any
+
+
+class EnlighenmentProfile(XorgProfile):
+ def __init__(self):
+ super().__init__('Enlightenment', ProfileType.WindowMgr, description='')
+
+ @property
+ def packages(self) -> List[str]:
+ return [
+ "enlightenment",
+ "terminology"
+ ]
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ return GreeterType.Lightdm
diff --git a/archinstall/default_profiles/desktops/gnome.py b/archinstall/default_profiles/desktops/gnome.py
new file mode 100644
index 00000000..24ade437
--- /dev/null
+++ b/archinstall/default_profiles/desktops/gnome.py
@@ -0,0 +1,23 @@
+from typing import List, Optional, Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import ProfileType, GreeterType
+from archinstall.default_profiles.xorg import XorgProfile
+
+if TYPE_CHECKING:
+ _: Any
+
+
+class GnomeProfile(XorgProfile):
+ def __init__(self):
+ super().__init__('Gnome', ProfileType.DesktopEnv, description='')
+
+ @property
+ def packages(self) -> List[str]:
+ return [
+ 'gnome',
+ 'gnome-tweaks'
+ ]
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ return GreeterType.Gdm
diff --git a/archinstall/default_profiles/desktops/hyprland.py b/archinstall/default_profiles/desktops/hyprland.py
new file mode 100644
index 00000000..0c5452eb
--- /dev/null
+++ b/archinstall/default_profiles/desktops/hyprland.py
@@ -0,0 +1,68 @@
+from enum import Enum
+from typing import List, Optional, TYPE_CHECKING, Any
+
+from archinstall.default_profiles.profile import ProfileType, GreeterType
+from archinstall.default_profiles.xorg import XorgProfile
+from archinstall.lib.menu import Menu
+
+if TYPE_CHECKING:
+ from archinstall.lib.installer import Installer
+ _: Any
+
+
+class SeatAccess(Enum):
+ seatd = 'seatd'
+ polkit = 'polkit'
+
+
+class HyprlandProfile(XorgProfile):
+ def __init__(self):
+ super().__init__('Hyprland', ProfileType.DesktopEnv, description='')
+
+ self.custom_settings = {'seat_access': None}
+
+ @property
+ def packages(self) -> List[str]:
+ return [
+ "hyprland",
+ "dunst",
+ "kitty",
+ "dolphin",
+ "wofi",
+ "xdg-desktop-portal-hyprland",
+ "qt5-wayland",
+ "qt6-wayland",
+ "polkit-kde-agent",
+ "grim",
+ "slurp"
+ ]
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ return GreeterType.Sddm
+
+ @property
+ def services(self) -> List[str]:
+ if pref := self.custom_settings.get('seat_access', None):
+ return [pref]
+ return []
+
+ def _ask_seat_access(self):
+ # need to activate seat service and add to seat group
+ title = str(_('Hyprland needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)'))
+ title += str(_('\n\nChoose an option to give Hyprland access to your hardware'))
+
+ options = [e.value for e in SeatAccess]
+ default = None
+
+ if seat := self.custom_settings.get('seat_access', None):
+ default = seat
+
+ choice = Menu(title, options, skip=False, preset_values=default).run()
+ self.custom_settings['seat_access'] = choice.single_value
+
+ def do_on_select(self):
+ self._ask_seat_access()
+
+ def install(self, install_session: 'Installer'):
+ super().install(install_session)
diff --git a/archinstall/default_profiles/desktops/i3.py b/archinstall/default_profiles/desktops/i3.py
new file mode 100644
index 00000000..9c2994de
--- /dev/null
+++ b/archinstall/default_profiles/desktops/i3.py
@@ -0,0 +1,29 @@
+from typing import Optional, List, Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import ProfileType, GreeterType
+from archinstall.default_profiles.xorg import XorgProfile
+
+if TYPE_CHECKING:
+ _: Any
+
+
+class I3wmProfile(XorgProfile):
+ def __init__(self):
+ super().__init__('i3-wm', ProfileType.WindowMgr, description='')
+
+ @property
+ def packages(self) -> List[str]:
+ return [
+ 'i3-wm',
+ 'i3lock',
+ 'i3status',
+ 'i3blocks',
+ 'xterm',
+ 'lightdm-gtk-greeter',
+ 'lightdm',
+ 'dmenu'
+ ]
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ return GreeterType.Lightdm
diff --git a/archinstall/default_profiles/desktops/lxqt.py b/archinstall/default_profiles/desktops/lxqt.py
new file mode 100644
index 00000000..5d75e08d
--- /dev/null
+++ b/archinstall/default_profiles/desktops/lxqt.py
@@ -0,0 +1,31 @@
+from typing import List, Optional, Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import ProfileType, GreeterType
+from archinstall.default_profiles.xorg import XorgProfile
+
+if TYPE_CHECKING:
+ _: Any
+
+
+class LxqtProfile(XorgProfile):
+ def __init__(self):
+ super().__init__('Lxqt', ProfileType.DesktopEnv, description='')
+
+ # NOTE: SDDM is the only officially supported greeter for LXQt, so unlike other DEs, lightdm is not used here.
+ # LXQt works with lightdm, but since this is not supported, we will not default to this.
+ # https://github.com/lxqt/lxqt/issues/795
+ @property
+ def packages(self) -> List[str]:
+ return [
+ "lxqt",
+ "breeze-icons",
+ "oxygen-icons",
+ "xdg-utils",
+ "ttf-freefont",
+ "leafpad",
+ "slock"
+ ]
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ return GreeterType.Sddm
diff --git a/archinstall/default_profiles/desktops/mate.py b/archinstall/default_profiles/desktops/mate.py
new file mode 100644
index 00000000..d3c4a6e1
--- /dev/null
+++ b/archinstall/default_profiles/desktops/mate.py
@@ -0,0 +1,23 @@
+from typing import List, Optional, Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import ProfileType, GreeterType
+from archinstall.default_profiles.xorg import XorgProfile
+
+if TYPE_CHECKING:
+ _: Any
+
+
+class MateProfile(XorgProfile):
+ def __init__(self):
+ super().__init__('Mate', ProfileType.DesktopEnv, description='')
+
+ @property
+ def packages(self) -> List[str]:
+ return [
+ "mate",
+ "mate-extra"
+ ]
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ return GreeterType.Lightdm
diff --git a/archinstall/default_profiles/desktops/plasma.py b/archinstall/default_profiles/desktops/plasma.py
new file mode 100644
index 00000000..bcc1ea1b
--- /dev/null
+++ b/archinstall/default_profiles/desktops/plasma.py
@@ -0,0 +1,27 @@
+from typing import List, Optional, Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import ProfileType, GreeterType
+from archinstall.default_profiles.xorg import XorgProfile
+
+if TYPE_CHECKING:
+ _: Any
+
+class PlasmaProfile(XorgProfile):
+ def __init__(self):
+ super().__init__('KDE Plasma', ProfileType.DesktopEnv, description='')
+
+ @property
+ def packages(self) -> List[str]:
+ return [
+ "plasma-meta",
+ "konsole",
+ "kwrite",
+ "dolphin",
+ "ark",
+ "plasma-workspace",
+ "egl-wayland"
+ ]
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ return GreeterType.Sddm
diff --git a/archinstall/default_profiles/desktops/qtile.py b/archinstall/default_profiles/desktops/qtile.py
new file mode 100644
index 00000000..96e93b1d
--- /dev/null
+++ b/archinstall/default_profiles/desktops/qtile.py
@@ -0,0 +1,23 @@
+from typing import Optional, List, Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import ProfileType, GreeterType
+from archinstall.default_profiles.xorg import XorgProfile
+
+if TYPE_CHECKING:
+ _: Any
+
+
+class QtileProfile(XorgProfile):
+ def __init__(self):
+ super().__init__('Qtile', ProfileType.WindowMgr, description='')
+
+ @property
+ def packages(self) -> List[str]:
+ return [
+ 'qtile',
+ 'alacritty'
+ ]
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ return GreeterType.Lightdm
diff --git a/archinstall/default_profiles/desktops/sway.py b/archinstall/default_profiles/desktops/sway.py
new file mode 100644
index 00000000..c757797d
--- /dev/null
+++ b/archinstall/default_profiles/desktops/sway.py
@@ -0,0 +1,77 @@
+from enum import Enum
+from typing import List, Optional, TYPE_CHECKING, Any
+
+from archinstall.default_profiles.profile import ProfileType, GreeterType
+from archinstall.default_profiles.xorg import XorgProfile
+from archinstall.lib.menu import Menu
+
+if TYPE_CHECKING:
+ from archinstall.lib.installer import Installer
+ _: Any
+
+
+class SeatAccess(Enum):
+ seatd = 'seatd'
+ polkit = 'polkit'
+
+
+class SwayProfile(XorgProfile):
+ def __init__(self):
+ super().__init__(
+ 'Sway',
+ ProfileType.WindowMgr,
+ description=''
+ )
+
+ self.custom_settings = {'seat_access': None}
+
+ @property
+ def packages(self) -> List[str]:
+ additional = []
+ if seat := self.custom_settings.get('seat_access', None):
+ additional = [seat]
+
+ return [
+ "sway",
+ "swaybg",
+ "swaylock",
+ "swayidle",
+ "waybar",
+ "dmenu",
+ "brightnessctl",
+ "grim",
+ "slurp",
+ "pavucontrol",
+ "foot",
+ "xorg-xwayland"
+ ] + additional
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ return GreeterType.Lightdm
+
+ @property
+ def services(self) -> List[str]:
+ if pref := self.custom_settings.get('seat_access', None):
+ return [pref]
+ return []
+
+ def _ask_seat_access(self):
+ # need to activate seat service and add to seat group
+ title = str(_('Sway needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)'))
+ title += str(_('\n\nChoose an option to give Sway access to your hardware'))
+
+ options = [e.value for e in SeatAccess]
+ default = None
+
+ if seat := self.custom_settings.get('seat_access', None):
+ default = seat
+
+ choice = Menu(title, options, skip=False, preset_values=default).run()
+ self.custom_settings['seat_access'] = choice.single_value
+
+ def do_on_select(self):
+ self._ask_seat_access()
+
+ def install(self, install_session: 'Installer'):
+ super().install(install_session)
diff --git a/archinstall/default_profiles/desktops/xfce4.py b/archinstall/default_profiles/desktops/xfce4.py
new file mode 100644
index 00000000..a7f0a7e6
--- /dev/null
+++ b/archinstall/default_profiles/desktops/xfce4.py
@@ -0,0 +1,26 @@
+from typing import List, Optional, Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import ProfileType, GreeterType
+from archinstall.default_profiles.xorg import XorgProfile
+
+if TYPE_CHECKING:
+ _: Any
+
+
+class Xfce4Profile(XorgProfile):
+ def __init__(self):
+ super().__init__('Xfce4', ProfileType.DesktopEnv, description='')
+
+ @property
+ def packages(self) -> List[str]:
+ return [
+ "xfce4",
+ "xfce4-goodies",
+ "pavucontrol",
+ "gvfs",
+ "xarchiver"
+ ]
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ return GreeterType.Lightdm
diff --git a/archinstall/default_profiles/minimal.py b/archinstall/default_profiles/minimal.py
new file mode 100644
index 00000000..f78708e9
--- /dev/null
+++ b/archinstall/default_profiles/minimal.py
@@ -0,0 +1,15 @@
+from typing import Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import Profile, ProfileType
+
+if TYPE_CHECKING:
+ _: Any
+
+
+class MinimalProfile(Profile):
+ def __init__(self):
+ super().__init__(
+ 'Minimal',
+ ProfileType.Minimal,
+ description=str(_('A very basic installation that allows you to customize Arch Linux as you see fit.'))
+ )
diff --git a/archinstall/default_profiles/profile.py b/archinstall/default_profiles/profile.py
new file mode 100644
index 00000000..4c85b0c7
--- /dev/null
+++ b/archinstall/default_profiles/profile.py
@@ -0,0 +1,205 @@
+from __future__ import annotations
+
+from enum import Enum, auto
+from typing import List, Optional, Any, Dict, TYPE_CHECKING, TypeVar
+
+from archinstall.lib.utils.util import format_cols
+
+if TYPE_CHECKING:
+ from archinstall.lib.installer import Installer
+ _: Any
+
+
+TProfile = TypeVar('TProfile', bound='Profile')
+
+
+class ProfileType(Enum):
+ # top level default_profiles
+ Server = 'Server'
+ Desktop = 'Desktop'
+ Xorg = 'Xorg'
+ Minimal = 'Minimal'
+ Custom = 'Custom'
+ # detailed selection default_profiles
+ ServerType = 'ServerType'
+ WindowMgr = 'Window Manager'
+ DesktopEnv = 'Desktop Environment'
+ CustomType = 'CustomType'
+ # special things
+ Tailored = 'Tailored'
+ Application = 'Application'
+
+
+class GreeterType(Enum):
+ Lightdm = 'lightdm-gtk-greeter'
+ LightdmSlick = 'lightdm-slick-greeter'
+ Sddm = 'sddm'
+ Gdm = 'gdm'
+ Ly = 'ly'
+
+
+class SelectResult(Enum):
+ NewSelection = auto()
+ SameSelection = auto()
+ ResetCurrent = auto()
+
+
+class Profile:
+ def __init__(
+ self,
+ name: str,
+ profile_type: ProfileType,
+ description: str = '',
+ current_selection: List[TProfile] = [],
+ packages: List[str] = [],
+ services: List[str] = [],
+ support_gfx_driver: bool = False,
+ support_greeter: bool = False
+ ):
+ self.name = name
+ self.description = description
+ self.profile_type = profile_type
+ self.custom_settings: Dict[str, Any] = {}
+
+ self._support_gfx_driver = support_gfx_driver
+ self._support_greeter = support_greeter
+
+ # self.gfx_driver: Optional[str] = None
+
+ self._current_selection = current_selection
+ self._packages = packages
+ self._services = services
+
+ # Only used for custom default_profiles
+ self.custom_enabled = False
+
+ @property
+ def current_selection(self) -> List[TProfile]:
+ return self._current_selection
+
+ @property
+ def packages(self) -> List[str]:
+ """
+ Returns a list of packages that should be installed when
+ this profile is among the chosen ones
+ """
+ return self._packages
+
+ @property
+ def services(self) -> List[str]:
+ """
+ Returns a list of services that should be enabled when
+ this profile is among the chosen ones
+ """
+ return self._services
+
+ @property
+ def default_greeter_type(self) -> Optional[GreeterType]:
+ """
+ Setting a default greeter type for a desktop profile
+ """
+ return None
+
+ def install(self, install_session: 'Installer'):
+ """
+ Performs installation steps when this profile was selected
+ """
+
+ def post_install(self, install_session: 'Installer'):
+ """
+ Hook that will be called when the installation process is
+ finished and custom installation steps for specific default_profiles
+ are needed
+ """
+
+ def json(self) -> Dict:
+ """
+ Returns a json representation of the profile
+ """
+ return {}
+
+ def do_on_select(self) -> SelectResult:
+ """
+ Hook that will be called when a profile is selected
+ """
+ return SelectResult.NewSelection
+
+ def set_custom_settings(self, settings: Dict[str, Any]):
+ """
+ Set the custom settings for the profile.
+ This is also called when the settings are parsed from the config
+ and can be overridden to perform further actions based on the profile
+ """
+ self.custom_settings = settings
+
+ def current_selection_names(self) -> List[str]:
+ if self._current_selection:
+ return [s.name for s in self._current_selection]
+ return []
+
+ def reset(self):
+ self.set_current_selection([])
+
+ def set_current_selection(self, current_selection: List[TProfile]):
+ self._current_selection = current_selection
+
+ def is_top_level_profile(self) -> bool:
+ top_levels = [ProfileType.Desktop, ProfileType.Server, ProfileType.Xorg, ProfileType.Minimal, ProfileType.Custom]
+ return self.profile_type in top_levels
+
+ def is_desktop_profile(self) -> bool:
+ return self.profile_type == ProfileType.Desktop
+
+ def is_server_type_profile(self) -> bool:
+ return self.profile_type == ProfileType.ServerType
+
+ def is_desktop_type_profile(self) -> bool:
+ return self.profile_type == ProfileType.DesktopEnv or self.profile_type == ProfileType.WindowMgr
+
+ def is_xorg_type_profile(self) -> bool:
+ return self.profile_type == ProfileType.Xorg
+
+ def is_tailored(self) -> bool:
+ return self.profile_type == ProfileType.Tailored
+
+ def is_custom_type_profile(self) -> bool:
+ return self.profile_type == ProfileType.CustomType
+
+ def is_graphic_driver_supported(self) -> bool:
+ if not self._current_selection:
+ return self._support_gfx_driver
+ else:
+ if any([p._support_gfx_driver for p in self._current_selection]):
+ return True
+ return False
+
+ def is_greeter_supported(self) -> bool:
+ return self._support_greeter
+
+ def preview_text(self) -> Optional[str]:
+ """
+ Override this method to provide a preview text for the profile
+ """
+ return self.packages_text()
+
+ def packages_text(self, include_sub_packages: bool = False) -> Optional[str]:
+ header = str(_('Installed packages'))
+
+ text = ''
+ packages = []
+
+ if self.packages:
+ packages = self.packages
+
+ if include_sub_packages:
+ for p in self.current_selection:
+ if p.packages:
+ packages += p.packages
+
+ text += format_cols(sorted(set(packages)))
+
+ if text:
+ text = f'{header}: \n{text}'
+ return text
+
+ return None
diff --git a/archinstall/default_profiles/server.py b/archinstall/default_profiles/server.py
new file mode 100644
index 00000000..ab758975
--- /dev/null
+++ b/archinstall/default_profiles/server.py
@@ -0,0 +1,56 @@
+from typing import Any, TYPE_CHECKING, List
+
+from archinstall.lib.output import info
+from archinstall.lib.menu import MenuSelectionType
+from archinstall.lib.profile.profiles_handler import profile_handler
+from archinstall.default_profiles.profile import ProfileType, Profile, SelectResult, TProfile
+
+if TYPE_CHECKING:
+ from archinstall.lib.installer import Installer
+ _: Any
+
+
+class ServerProfile(Profile):
+ def __init__(self, current_value: List[TProfile] = []):
+ super().__init__(
+ 'Server',
+ ProfileType.Server,
+ description=str(_('Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb')),
+ current_selection=current_value
+ )
+
+ def do_on_select(self) -> SelectResult:
+ available_servers = profile_handler.get_server_profiles()
+
+ choice = profile_handler.select_profile(
+ available_servers,
+ self._current_selection,
+ title=str(_('Choose which servers to install, if none then a minimal installation will be done')),
+ multi=True
+ )
+
+ match choice.type_:
+ case MenuSelectionType.Selection:
+ self.set_current_selection(choice.value) # type: ignore
+ return SelectResult.NewSelection
+ case MenuSelectionType.Skip:
+ return SelectResult.SameSelection
+ case MenuSelectionType.Reset:
+ return SelectResult.ResetCurrent
+
+ def post_install(self, install_session: 'Installer'):
+ for profile in self._current_selection:
+ profile.post_install(install_session)
+
+ def install(self, install_session: 'Installer'):
+ server_info = self.current_selection_names()
+ details = ', '.join(server_info)
+ info(f'Now installing the selected servers: {details}')
+
+ for server in self._current_selection:
+ info(f'Installing {server.name}...')
+ install_session.add_additional_packages(server.packages)
+ install_session.enable_service(server.services)
+ server.install(install_session)
+
+ info('If your selections included multiple servers with the same port, you may have to reconfigure them.')
diff --git a/archinstall/default_profiles/servers/__init__.py b/archinstall/default_profiles/servers/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/archinstall/default_profiles/servers/__init__.py
diff --git a/archinstall/default_profiles/servers/cockpit.py b/archinstall/default_profiles/servers/cockpit.py
new file mode 100644
index 00000000..8cac0976
--- /dev/null
+++ b/archinstall/default_profiles/servers/cockpit.py
@@ -0,0 +1,19 @@
+from typing import List
+
+from archinstall.default_profiles.profile import Profile, ProfileType
+
+
+class CockpitProfile(Profile):
+ def __init__(self):
+ super().__init__(
+ 'Cockpit',
+ ProfileType.ServerType
+ )
+
+ @property
+ def packages(self) -> List[str]:
+ return ['cockpit', 'udisks2', 'packagekit']
+
+ @property
+ def services(self) -> List[str]:
+ return ['cockpit.socket']
diff --git a/archinstall/default_profiles/servers/docker.py b/archinstall/default_profiles/servers/docker.py
new file mode 100644
index 00000000..f4800916
--- /dev/null
+++ b/archinstall/default_profiles/servers/docker.py
@@ -0,0 +1,33 @@
+from typing import List, Union, TYPE_CHECKING
+
+import archinstall
+
+from archinstall.default_profiles.profile import Profile, ProfileType
+from archinstall.lib.models import User
+
+if TYPE_CHECKING:
+ from archinstall.lib.installer import Installer
+
+
+class DockerProfile(Profile):
+ def __init__(self):
+ super().__init__(
+ 'Docker',
+ ProfileType.ServerType
+ )
+
+ @property
+ def packages(self) -> List[str]:
+ return ['docker']
+
+ @property
+ def services(self) -> List[str]:
+ return ['docker']
+
+ def post_install(self, install_session: 'Installer'):
+ users: Union[User, List[User]] = archinstall.arguments.get('!users', [])
+ if not isinstance(users, list):
+ users = [users]
+
+ for user in users:
+ install_session.arch_chroot(f'usermod -a -G docker {user.username}')
diff --git a/archinstall/default_profiles/servers/httpd.py b/archinstall/default_profiles/servers/httpd.py
new file mode 100644
index 00000000..595ce84f
--- /dev/null
+++ b/archinstall/default_profiles/servers/httpd.py
@@ -0,0 +1,19 @@
+from typing import List
+
+from archinstall.default_profiles.profile import Profile, ProfileType
+
+
+class HttpdProfile(Profile):
+ def __init__(self):
+ super().__init__(
+ 'httpd',
+ ProfileType.ServerType
+ )
+
+ @property
+ def packages(self) -> List[str]:
+ return ['apache']
+
+ @property
+ def services(self) -> List[str]:
+ return ['httpd']
diff --git a/archinstall/default_profiles/servers/lighttpd.py b/archinstall/default_profiles/servers/lighttpd.py
new file mode 100644
index 00000000..00aa5564
--- /dev/null
+++ b/archinstall/default_profiles/servers/lighttpd.py
@@ -0,0 +1,19 @@
+from typing import List
+
+from archinstall.default_profiles.profile import Profile, ProfileType
+
+
+class LighttpdProfile(Profile):
+ def __init__(self):
+ super().__init__(
+ 'Lighttpd',
+ ProfileType.ServerType
+ )
+
+ @property
+ def packages(self) -> List[str]:
+ return ['lighttpd']
+
+ @property
+ def services(self) -> List[str]:
+ return ['lighttpd']
diff --git a/archinstall/default_profiles/servers/mariadb.py b/archinstall/default_profiles/servers/mariadb.py
new file mode 100644
index 00000000..4506f1bc
--- /dev/null
+++ b/archinstall/default_profiles/servers/mariadb.py
@@ -0,0 +1,25 @@
+from typing import List, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import Profile, ProfileType
+
+if TYPE_CHECKING:
+ from archinstall.lib.installer import Installer
+
+
+class MariadbProfile(Profile):
+ def __init__(self):
+ super().__init__(
+ 'Mariadb',
+ ProfileType.ServerType
+ )
+
+ @property
+ def packages(self) -> List[str]:
+ return ['mariadb']
+
+ @property
+ def services(self) -> List[str]:
+ return ['mariadb']
+
+ def post_install(self, install_session: 'Installer'):
+ install_session.arch_chroot('mariadb-install-db --user=mysql --basedir=/usr --datadir=/var/lib/mysql')
diff --git a/archinstall/default_profiles/servers/nginx.py b/archinstall/default_profiles/servers/nginx.py
new file mode 100644
index 00000000..6038616c
--- /dev/null
+++ b/archinstall/default_profiles/servers/nginx.py
@@ -0,0 +1,19 @@
+from typing import List
+
+from archinstall.default_profiles.profile import Profile, ProfileType
+
+
+class NginxProfile(Profile):
+ def __init__(self):
+ super().__init__(
+ 'Nginx',
+ ProfileType.ServerType
+ )
+
+ @property
+ def packages(self) -> List[str]:
+ return ['nginx']
+
+ @property
+ def services(self) -> List[str]:
+ return ['nginx']
diff --git a/archinstall/default_profiles/servers/postgresql.py b/archinstall/default_profiles/servers/postgresql.py
new file mode 100644
index 00000000..dba722ce
--- /dev/null
+++ b/archinstall/default_profiles/servers/postgresql.py
@@ -0,0 +1,26 @@
+from typing import List, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import Profile, ProfileType
+
+if TYPE_CHECKING:
+ from archinstall.lib.installer import Installer
+
+
+class PostgresqlProfile(Profile):
+ def __init__(self):
+ super().__init__(
+ 'Postgresql',
+ ProfileType.ServerType,
+ ''
+ )
+
+ @property
+ def packages(self) -> List[str]:
+ return ['postgresql']
+
+ @property
+ def services(self) -> List[str]:
+ return ['postgresql']
+
+ def post_install(self, install_session: 'Installer'):
+ install_session.arch_chroot("initdb -D /var/lib/postgres/data", run_as='postgres')
diff --git a/archinstall/default_profiles/servers/sshd.py b/archinstall/default_profiles/servers/sshd.py
new file mode 100644
index 00000000..7f855b1a
--- /dev/null
+++ b/archinstall/default_profiles/servers/sshd.py
@@ -0,0 +1,19 @@
+from typing import List
+
+from archinstall.default_profiles.profile import Profile, ProfileType
+
+
+class SshdProfile(Profile):
+ def __init__(self):
+ super().__init__(
+ 'sshd',
+ ProfileType.ServerType
+ )
+
+ @property
+ def packages(self) -> List[str]:
+ return ['openssh']
+
+ @property
+ def services(self) -> List[str]:
+ return ['sshd']
diff --git a/archinstall/default_profiles/servers/tomcat.py b/archinstall/default_profiles/servers/tomcat.py
new file mode 100644
index 00000000..9bd8837b
--- /dev/null
+++ b/archinstall/default_profiles/servers/tomcat.py
@@ -0,0 +1,19 @@
+from typing import List
+
+from archinstall.default_profiles.profile import Profile, ProfileType
+
+
+class TomcatProfile(Profile):
+ def __init__(self):
+ super().__init__(
+ 'Tomcat',
+ ProfileType.ServerType
+ )
+
+ @property
+ def packages(self) -> List[str]:
+ return ['tomcat10']
+
+ @property
+ def services(self) -> List[str]:
+ return ['tomcat10']
diff --git a/archinstall/default_profiles/tailored.py b/archinstall/default_profiles/tailored.py
new file mode 100644
index 00000000..62666249
--- /dev/null
+++ b/archinstall/default_profiles/tailored.py
@@ -0,0 +1,21 @@
+from typing import List, Any, TYPE_CHECKING
+
+from archinstall.default_profiles.profile import ProfileType
+from archinstall.default_profiles.xorg import XorgProfile
+
+if TYPE_CHECKING:
+ from archinstall.lib.installer import Installer
+ _: Any
+
+
+class TailoredProfile(XorgProfile):
+ def __init__(self):
+ super().__init__('52-54-00-12-34-56', ProfileType.Tailored, description='')
+
+ @property
+ def packages(self) -> List[str]:
+ return ['nano', 'wget', 'git']
+
+ def install(self, install_session: 'Installer'):
+ super().install(install_session)
+ # do whatever you like here :)
diff --git a/archinstall/default_profiles/xorg.py b/archinstall/default_profiles/xorg.py
new file mode 100644
index 00000000..88ba55a6
--- /dev/null
+++ b/archinstall/default_profiles/xorg.py
@@ -0,0 +1,34 @@
+from typing import Any, Optional, TYPE_CHECKING, List
+
+from archinstall.default_profiles.profile import Profile, ProfileType
+
+if TYPE_CHECKING:
+ _: Any
+
+
+class XorgProfile(Profile):
+ def __init__(
+ self,
+ name: str = 'Xorg',
+ profile_type: ProfileType = ProfileType.Xorg,
+ description: str = str(_('Installs a minimal system as well as xorg and graphics drivers.')),
+ ):
+ super().__init__(
+ name,
+ profile_type,
+ description=description,
+ support_gfx_driver=True
+ )
+
+ def preview_text(self) -> Optional[str]:
+ text = str(_('Environment type: {}')).format(self.profile_type.value)
+ if packages := self.packages_text():
+ text += f'\n{packages}'
+
+ return text
+
+ @property
+ def packages(self) -> List[str]:
+ return [
+ 'xorg-server'
+ ]