Merge branch 'master' of github.com:archlinux/archinstall into torxed-kernel-params

This commit is contained in:
Anton Hvornum 2021-05-14 18:00:27 +02:00
commit 16441f11cb
37 changed files with 246 additions and 167 deletions

View File

@ -1,3 +1,4 @@
from typing import Optional
import glob, re, os, json, time, hashlib import glob, re, os, json, time, hashlib
import pathlib, traceback, logging import pathlib, traceback, logging
from collections import OrderedDict from collections import OrderedDict
@ -205,7 +206,7 @@ class Partition():
return f'Partition(path={self.path}, size={self.size}, fs={self.filesystem}{mount_repr})' return f'Partition(path={self.path}, size={self.size}, fs={self.filesystem}{mount_repr})'
@property @property
def uuid(self) -> str: def uuid(self) -> Optional[str]:
""" """
Returns the PARTUUID as returned by lsblk. Returns the PARTUUID as returned by lsblk.
This is more reliable than relying on /dev/disk/by-partuuid as This is more reliable than relying on /dev/disk/by-partuuid as
@ -214,7 +215,7 @@ class Partition():
lsblk = b''.join(sys_command(f'lsblk -J -o+PARTUUID {self.path}')) lsblk = b''.join(sys_command(f'lsblk -J -o+PARTUUID {self.path}'))
for partition in json.loads(lsblk.decode('UTF-8'))['blockdevices']: for partition in json.loads(lsblk.decode('UTF-8'))['blockdevices']:
return partition.get('partuuid', None) return partition.get('partuuid', None)
return None
@property @property
def encrypted(self): def encrypted(self):
return self._encrypted return self._encrypted
@ -624,3 +625,11 @@ def get_filesystem_type(path):
return b''.join(handle).strip().decode('UTF-8') return b''.join(handle).strip().decode('UTF-8')
except SysCallError: except SysCallError:
return None return None
def disk_layouts():
try:
handle = sys_command(f"lsblk -f -o+TYPE,SIZE -J")
return json.loads(b''.join(handle).decode('UTF-8'))
except SysCallError as err:
log(f"Could not return disk layouts: {err}")
return None

View File

@ -5,6 +5,7 @@ from subprocess import Popen, STDOUT, PIPE, check_output
from select import epoll, EPOLLIN, EPOLLHUP from select import epoll, EPOLLIN, EPOLLHUP
from .exceptions import * from .exceptions import *
from .output import log from .output import log
from typing import Optional, Union
def gen_uid(entropy_length=256): def gen_uid(entropy_length=256):
return hashlib.sha512(os.urandom(entropy_length)).hexdigest() return hashlib.sha512(os.urandom(entropy_length)).hexdigest()
@ -160,16 +161,15 @@ class sys_command():#Thread):
'exit_code': self.exit_code 'exit_code': self.exit_code
} }
def peak(self, output :str): def peak(self, output : Union[str, bytes]) -> bool:
if type(output) == bytes: if type(output) == bytes:
try: try:
output = output.decode('UTF-8') output = output.decode('UTF-8')
except UnicodeDecodeError: except UnicodeDecodeError:
return None return False
output = output.strip('\r\n ') output = output.strip('\r\n ')
if len(output) <= 0: if len(output) <= 0:
return None return False
if self.peak_output: if self.peak_output:
from .user_interaction import get_terminal_width from .user_interaction import get_terminal_width
@ -191,6 +191,7 @@ class sys_command():#Thread):
# And print the new output we're peaking on: # And print the new output we're peaking on:
sys.stdout.write(output) sys.stdout.write(output)
sys.stdout.flush() sys.stdout.flush()
return True
def run(self): def run(self):
self.status = 'running' self.status = 'running'

View File

@ -3,24 +3,53 @@ from .general import sys_command
from .networking import list_interfaces, enrichIfaceTypes from .networking import list_interfaces, enrichIfaceTypes
from typing import Optional from typing import Optional
__packages__ = ['xf86-video-amdgpu', 'xf86-video-ati', 'xf86-video-intel', 'xf86-video-nouveau', 'xf86-video-fbdev', 'xf86-video-vesa', 'xf86-video-vmware', 'nvidia', 'mesa'] __packages__ = [
"mesa",
"xf86-video-amdgpu",
"xf86-video-ati",
"xf86-video-nouveau",
"xf86-video-vmware",
"libva-mesa-driver",
"libva-intel-driver",
"intel-media-driver",
"vulkan-radeon",
"vulkan-intel",
"nvidia",
]
AVAILABLE_GFX_DRIVERS = { AVAILABLE_GFX_DRIVERS = {
# Sub-dicts are layer-2 options to be selected # Sub-dicts are layer-2 options to be selected
# and lists are a list of packages to be installed # and lists are a list of packages to be installed
'AMD / ATI' : { "All open-source (default)": [
'amd' : ['xf86-video-amdgpu'], "mesa",
'ati' : ['xf86-video-ati'] "xf86-video-amdgpu",
"xf86-video-ati",
"xf86-video-nouveau",
"xf86-video-vmware",
"libva-mesa-driver",
"libva-intel-driver",
"intel-media-driver",
"vulkan-radeon",
"vulkan-intel",
],
"AMD / ATI (open-source)": [
"mesa",
"xf86-video-amdgpu",
"xf86-video-ati",
"libva-mesa-driver",
"vulkan-radeon",
],
"Intel (open-source)": [
"mesa",
"libva-intel-driver",
"intel-media-driver",
"vulkan-intel",
],
"Nvidia": {
"open-source": ["mesa", "xf86-video-nouveau", "libva-mesa-driver"],
"proprietary": ["nvidia"],
}, },
'intel' : ['xf86-video-intel'], "VMware / VirtualBox (open-source)": ["mesa", "xf86-video-vmware"],
'nvidia' : {
'open-source' : ['xf86-video-nouveau'],
'proprietary' : ['nvidia']
},
'mesa' : ['mesa'],
'fbdev' : ['xf86-video-fbdev'],
'vesa' : ['xf86-video-vesa'],
'vmware / virtualbox' : ['xf86-video-vmware']
} }
def hasWifi()->bool: def hasWifi()->bool:
@ -62,6 +91,7 @@ def cpuVendor()-> Optional[str]:
if info.get('field',None): if info.get('field',None):
if info.get('field',None) == "Vendor ID:": if info.get('field',None) == "Vendor ID:":
return info.get('data',None) return info.get('data',None)
return None
def isVM() -> bool: def isVM() -> bool:
try: try:

View File

@ -439,7 +439,7 @@ class Installer():
self.pacstrap('grub') self.pacstrap('grub')
if hasUEFI(): if hasUEFI():
self.pacstrap('efibootmgr')` self.pacstrap('efibootmgr')
o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.target} grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB')) o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.target} grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB'))
sys_command('/usr/bin/arch-chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg') sys_command('/usr/bin/arch-chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg')
return True return True
@ -458,14 +458,7 @@ class Installer():
return self.pacstrap(*packages) return self.pacstrap(*packages)
def install_profile(self, profile): def install_profile(self, profile):
# TODO: Replace this with a import archinstall.session instead in the profiles. storage['installation_session'] = self
# The tricky thing with doing the import archinstall.session instead is that
# profiles might be run from a different chroot, and there's no way we can
# guarantee file-path safety when accessing the installer object that way.
# Doing the __builtins__ replacement, ensures that the global variable "installation"
# is always kept up to date. It's considered a nasty hack - but it's a safe way
# of ensuring 100% accuracy of archinstall session variables.
__builtins__['installation'] = self
if type(profile) == str: if type(profile) == str:
profile = Profile(self, profile) profile = Profile(self, profile)

View File

@ -19,7 +19,7 @@ class journald(dict):
@abc.abstractmethod @abc.abstractmethod
def log(message, level=logging.DEBUG): def log(message, level=logging.DEBUG):
try: try:
import systemd.journal import systemd.journal # type: ignore
except ModuleNotFoundError: except ModuleNotFoundError:
return False return False

View File

@ -1,3 +1,4 @@
from typing import Optional
import os, urllib.request, urllib.parse, ssl, json, re import os, urllib.request, urllib.parse, ssl, json, re
import importlib.util, sys, glob, hashlib, logging import importlib.util, sys, glob, hashlib, logging
from collections import OrderedDict from collections import OrderedDict
@ -35,7 +36,7 @@ def list_profiles(filter_irrelevant_macs=True, subpath='', filter_top_level_prof
description = '' description = ''
with open(os.path.join(root, file), 'r') as fh: with open(os.path.join(root, file), 'r') as fh:
first_line = fh.readline() first_line = fh.readline()
if first_line[0] == '#': if len(first_line) and first_line[0] == '#':
description = first_line[1:].strip() description = first_line[1:].strip()
cache[file[:-3]] = {'path' : os.path.join(root, file), 'description' : description, 'tailored' : tailored} cache[file[:-3]] = {'path' : os.path.join(root, file), 'description' : description, 'tailored' : tailored}
@ -49,7 +50,7 @@ def list_profiles(filter_irrelevant_macs=True, subpath='', filter_top_level_prof
except urllib.error.HTTPError as err: except urllib.error.HTTPError as err:
print(f'Error: Listing profiles on URL "{profiles_url}" resulted in:', err) print(f'Error: Listing profiles on URL "{profiles_url}" resulted in:', err)
return cache return cache
except: except json.decoder.JSONDecodeError as err:
print(f'Error: Could not decode "{profiles_url}" result as JSON:', err) print(f'Error: Could not decode "{profiles_url}" result as JSON:', err)
return cache return cache
@ -215,7 +216,7 @@ class Profile(Script):
return True return True
@property @property
def packages(self) -> list: def packages(self) -> Optional[list]:
""" """
Returns a list of packages baked into the profile definition. Returns a list of packages baked into the profile definition.
If no package definition has been done, .packages() will return None. If no package definition has been done, .packages() will return None.

View File

@ -83,16 +83,18 @@ def get_password(prompt="Enter a password: "):
def print_large_list(options, padding=5, margin_bottom=0, separator=': '): def print_large_list(options, padding=5, margin_bottom=0, separator=': '):
highest_index_number_length = len(str(len(options))) highest_index_number_length = len(str(len(options)))
longest_line = highest_index_number_length + len(separator) + get_longest_option(options) + padding longest_line = highest_index_number_length + len(separator) + get_longest_option(options) + padding
spaces_without_option = longest_line - (len(separator) + highest_index_number_length)
max_num_of_columns = get_terminal_width() // longest_line max_num_of_columns = get_terminal_width() // longest_line
max_options_in_cells = max_num_of_columns * (get_terminal_height()-margin_bottom) max_options_in_cells = max_num_of_columns * (get_terminal_height()-margin_bottom)
if (len(options) > max_options_in_cells): if (len(options) > max_options_in_cells):
for index, option in enumerate(options): for index, option in enumerate(options):
print(f"{index}: {option}") print(f"{index}: {option}")
return 1, index
else: else:
for row in range(0, (get_terminal_height()-margin_bottom)): for row in range(0, (get_terminal_height()-margin_bottom)):
for column in range(row, len(options), (get_terminal_height()-margin_bottom)): for column in range(row, len(options), (get_terminal_height()-margin_bottom)):
spaces = " "*(longest_line - len(options[column])) spaces = " "*(spaces_without_option - len(options[column]))
print(f"{str(column): >{highest_index_number_length}}{separator}{options[column]}", end = spaces) print(f"{str(column): >{highest_index_number_length}}{separator}{options[column]}", end = spaces)
print() print()
@ -100,6 +102,18 @@ def print_large_list(options, padding=5, margin_bottom=0, separator=': '):
def generic_multi_select(options, text="Select one or more of the options above (leave blank to continue): ", sort=True, default=None, allow_empty=False): def generic_multi_select(options, text="Select one or more of the options above (leave blank to continue): ", sort=True, default=None, allow_empty=False):
# Checking if the options are different from `list` or `dict` or if they are empty
if type(options) not in [list, dict]:
log(f" * Generic multi-select doesn't support ({type(options)}) as type of options * ", fg='red')
log(" * If problem persists, please create an issue on https://github.com/archlinux/archinstall/issues * ", fg='yellow')
raise RequirementError("generic_multi_select() requires list or dictionary as options.")
if not options:
log(f" * Generic multi-select didn't find any options to choose from * ", fg='red')
log(" * If problem persists, please create an issue on https://github.com/archlinux/archinstall/issues * ", fg='yellow')
raise RequirementError('generic_multi_select() requires at least one option to proceed.')
# After passing the checks, function continues to work
if type(options) == dict:
options = list(options.values())
if sort: if sort:
options = sorted(options) options = sorted(options)
@ -108,7 +122,7 @@ def generic_multi_select(options, text="Select one or more of the options above
selected_options = [] selected_options = []
while True: while True:
if len(selected_options) <= 0 and default and default in options: if not selected_options and default in options:
selected_options.append(default) selected_options.append(default)
printed_options = [] printed_options = []
@ -119,32 +133,42 @@ def generic_multi_select(options, text="Select one or more of the options above
printed_options.append(f'{option}') printed_options.append(f'{option}')
section.clear(0, get_terminal_height()-section._cursor_y-1) section.clear(0, get_terminal_height()-section._cursor_y-1)
x, y = print_large_list(printed_options, margin_bottom=2) print_large_list(printed_options, margin_bottom=2)
section._cursor_y = len(printed_options) section._cursor_y = len(printed_options)
section._cursor_x = 0 section._cursor_x = 0
section.write_line(text) section.write_line(text)
section.input_pos = section._cursor_x section.input_pos = section._cursor_x
selected_option = section.get_keyboard_input(end=None) selected_option = section.get_keyboard_input(end=None)
# This string check is necessary to correct work with it
if selected_option is None: # Without this, Python will raise AttributeError because of stripping `None`
if len(selected_options) <= 0 and default: # It also allows to remove empty spaces if the user accidentally entered them.
selected_options = [default] if isinstance(selected_option, str):
selected_option = selected_option.strip()
if len(selected_options) or allow_empty is True: try:
break if not selected_option:
if not selected_options and default:
selected_options = [default]
elif selected_options or allow_empty:
break
else:
raise RequirementError('Please select at least one option to continue')
elif selected_option.isnumeric():
if (selected_option := int(selected_option)) >= len(options):
raise RequirementError(f'Selected option "{selected_option}" is out of range')
selected_option = options[selected_option]
if selected_option in selected_options:
selected_options.remove(selected_option)
else:
selected_options.append(selected_option)
elif selected_option in options:
if selected_option in selected_options:
selected_options.remove(selected_option)
else:
selected_options.append(selected_option)
else: else:
log('* Need to select at least one option!', fg='red') raise RequirementError(f'Selected option "{selected_option}" does not exist in available options')
continue except RequirementError as e:
log(f" * {e} * ", fg='red')
elif selected_option.isdigit():
if (selected_option := int(selected_option)) >= len(options):
log('* Option is out of range, please select another one!', fg='red')
continue
selected_option = options[selected_option]
if selected_option in selected_options:
selected_options.remove(selected_option)
else:
selected_options.append(selected_option)
return selected_options return selected_options
@ -263,14 +287,14 @@ class MiniCurses():
if response: if response:
return response return response
def ask_for_superuser_account(prompt='Username for required super-user with sudo privileges: ', forced=False): def ask_for_superuser_account(prompt='Username for required superuser with sudo privileges: ', forced=False):
while 1: while 1:
new_user = input(prompt).strip(' ') new_user = input(prompt).strip(' ')
if not new_user and forced: if not new_user and forced:
# TODO: make this text more generic? # TODO: make this text more generic?
# It's only used to create the first sudo user when root is disabled in guided.py # It's only used to create the first sudo user when root is disabled in guided.py
log(' * Since root is disabled, you need to create a least one (super) user!', fg='red') log(' * Since root is disabled, you need to create a least one superuser!', fg='red')
continue continue
elif not new_user and not forced: elif not new_user and not forced:
raise UserError("No superuser was created.") raise UserError("No superuser was created.")
@ -282,7 +306,7 @@ def ask_for_superuser_account(prompt='Username for required super-user with sudo
def ask_for_additional_users(prompt='Any additional users to install (leave blank for no users): '): def ask_for_additional_users(prompt='Any additional users to install (leave blank for no users): '):
users = {} users = {}
super_users = {} superusers = {}
while 1: while 1:
new_user = input(prompt).strip(' ') new_user = input(prompt).strip(' ')
@ -292,12 +316,12 @@ def ask_for_additional_users(prompt='Any additional users to install (leave blan
continue continue
password = get_password(prompt=f'Password for user {new_user}: ') password = get_password(prompt=f'Password for user {new_user}: ')
if input("Should this user be a sudo (super) user (y/N): ").strip(' ').lower() in ('y', 'yes'): if input("Should this user be a superuser (sudoer) [y/N]: ").strip(' ').lower() in ('y', 'yes'):
super_users[new_user] = {"!password" : password} superusers[new_user] = {"!password" : password}
else: else:
users[new_user] = {"!password" : password} users[new_user] = {"!password" : password}
return users, super_users return users, superusers
def ask_for_a_timezone(): def ask_for_a_timezone():
while True: while True:
@ -435,20 +459,24 @@ def generic_select(options, input_text="Select one of the above by index or abso
this function returns an item from list, a string, or None this function returns an item from list, a string, or None
""" """
# Checking if options are different from `list` or `dict` # Checking if the options are different from `list` or `dict` or if they are empty
if type(options) not in [list, dict]: if type(options) not in [list, dict]:
log(f" * Generic select doesn't support ({type(options)}) as type of options * ", fg='red') log(f" * Generic select doesn't support ({type(options)}) as type of options * ", fg='red')
log(" * If problem persists, please create an issue on https://github.com/archlinux/archinstall/issues * ", fg='yellow') log(" * If problem persists, please create an issue on https://github.com/archlinux/archinstall/issues * ", fg='yellow')
raise RequirementError("generic_select() requires list or dictionary as options.") raise RequirementError("generic_select() requires list or dictionary as options.")
# To allow only `list` and `dict`, converting values of options here. if not options:
# Therefore, now we can only provide the dictionary itself
if type(options) == dict: options = list(options.values())
if sort: options = sorted(options) # As we pass only list and dict (converted to list), we can skip converting to list
if len(options) == 0:
log(f" * Generic select didn't find any options to choose from * ", fg='red') log(f" * Generic select didn't find any options to choose from * ", fg='red')
log(" * If problem persists, please create an issue on https://github.com/archlinux/archinstall/issues * ", fg='yellow') log(" * If problem persists, please create an issue on https://github.com/archlinux/archinstall/issues * ", fg='yellow')
raise RequirementError('generic_select() requires at least one option to proceed.') raise RequirementError('generic_select() requires at least one option to proceed.')
# After passing the checks, function continues to work
if type(options) == dict:
# To allow only `list` and `dict`, converting values of options here.
# Therefore, now we can only provide the dictionary itself
options = list(options.values())
if sort:
# As we pass only list and dict (converted to list), we can skip converting to list
options = sorted(options)
# Added ability to disable the output of options items, # Added ability to disable the output of options items,
# if another function displays something different from this # if another function displays something different from this
@ -460,8 +488,8 @@ def generic_select(options, input_text="Select one of the above by index or abso
# Now the try...except block handles validation for invalid input from the user # Now the try...except block handles validation for invalid input from the user
while True: while True:
try: try:
selected_option = input(input_text) selected_option = input(input_text).strip()
if len(selected_option.strip()) == 0: if not selected_option:
# `allow_empty_input` parameter handles return of None on empty input, if necessary # `allow_empty_input` parameter handles return of None on empty input, if necessary
# Otherwise raise `RequirementError` # Otherwise raise `RequirementError`
if allow_empty_input: if allow_empty_input:
@ -469,8 +497,7 @@ def generic_select(options, input_text="Select one of the above by index or abso
raise RequirementError('Please select an option to continue') raise RequirementError('Please select an option to continue')
# Replaced `isdigit` with` isnumeric` to discard all negative numbers # Replaced `isdigit` with` isnumeric` to discard all negative numbers
elif selected_option.isnumeric(): elif selected_option.isnumeric():
selected_option = int(selected_option) if (selected_option := int(selected_option)) >= len(options):
if selected_option >= len(options):
raise RequirementError(f'Selected option "{selected_option}" is out of range') raise RequirementError(f'Selected option "{selected_option}" is out of range')
selected_option = options[selected_option] selected_option = options[selected_option]
break break
@ -480,7 +507,6 @@ def generic_select(options, input_text="Select one of the above by index or abso
raise RequirementError(f'Selected option "{selected_option}" does not exist in available options') raise RequirementError(f'Selected option "{selected_option}" does not exist in available options')
except RequirementError as err: except RequirementError as err:
log(f" * {err} * ", fg='red') log(f" * {err} * ", fg='red')
continue
return selected_option return selected_option
@ -649,6 +675,7 @@ def select_driver(options=AVAILABLE_GFX_DRIVERS):
""" """
drivers = sorted(list(options)) drivers = sorted(list(options))
default_option = options["All open-source (default)"]
if drivers: if drivers:
lspci = sys_command(f'/usr/bin/lspci') lspci = sys_command(f'/usr/bin/lspci')
@ -660,6 +687,10 @@ def select_driver(options=AVAILABLE_GFX_DRIVERS):
print(' ** AMD card detected, suggested driver: AMD / ATI **') print(' ** AMD card detected, suggested driver: AMD / ATI **')
initial_option = generic_select(drivers, input_text="Select your graphics card driver: ") initial_option = generic_select(drivers, input_text="Select your graphics card driver: ")
if not initial_option:
return default_option
selected_driver = options[initial_option] selected_driver = options[initial_option]
if type(selected_driver) == dict: if type(selected_driver) == dict:
@ -691,6 +722,6 @@ def select_kernel(options):
kernels = sorted(list(options)) kernels = sorted(list(options))
if kernels: if kernels:
return generic_multi_select(kernels, f"Choose which kernel to use (leave blank for default: {DEFAULT_KERNEL}): ", default=DEFAULT_KERNEL) return generic_multi_select(kernels, f"Choose which kernels to use (leave blank for default: {DEFAULT_KERNEL}): ", default=DEFAULT_KERNEL, sort=False)
raise RequirementError("Selecting kernels require a least one kernel to be given as an option.") raise RequirementError("Selecting kernels require a least one kernel to be given as an option.")

0
examples/__init__.py Normal file
View File

View File

@ -7,6 +7,9 @@ if archinstall.arguments.get('help'):
print("See `man archinstall` for help.") print("See `man archinstall` for help.")
exit(0) exit(0)
# For support reasons, we'll log the disk layout pre installation to match against post-installation layout
archinstall.log(f"Disk states before installing: {archinstall.disk_layouts()}", level=archinstall.LOG_LEVELS.Debug)
def ask_user_questions(): def ask_user_questions():
""" """
First, we'll ask the user for a bunch of user input. First, we'll ask the user for a bunch of user input.
@ -385,5 +388,8 @@ def perform_installation(mountpoint):
except: except:
pass pass
# For support reasons, we'll log the disk layout post installation (crash or no crash)
archinstall.log(f"Disk states after installing: {archinstall.disk_layouts()}", level=archinstall.LOG_LEVELS.Debug)
ask_user_questions() ask_user_questions()
perform_installation_steps() perform_installation_steps()

View File

@ -5,7 +5,7 @@ import urllib.request
__packages__ = ['nano', 'wget', 'git'] __packages__ = ['nano', 'wget', 'git']
if __name__ == '52-54-00-12-34-56': if __name__ == '52-54-00-12-34-56':
awesome = archinstall.Application(installation, 'postgresql') awesome = archinstall.Application(archinstall.storage['installation_session'], 'postgresql')
awesome.install() awesome.install()
""" """

0
profiles/__init__.py Normal file
View File

View File

View File

@ -2,11 +2,11 @@ import archinstall
__packages__ = ["awesome", "xorg-xrandr", "xterm", "feh", "slock", "terminus-font", "gnu-free-fonts", "ttf-liberation", "xsel"] __packages__ = ["awesome", "xorg-xrandr", "xterm", "feh", "slock", "terminus-font", "gnu-free-fonts", "ttf-liberation", "xsel"]
installation.install_profile('xorg') archinstall.storage['installation_session'].install_profile('xorg')
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
with open(f'{installation.target}/etc/X11/xinit/xinitrc', 'r') as xinitrc: with open(f"{archinstall.storage['installation_session'].target}/etc/X11/xinit/xinitrc", 'r') as xinitrc:
xinitrc_data = xinitrc.read() xinitrc_data = xinitrc.read()
for line in xinitrc_data.split('\n'): for line in xinitrc_data.split('\n'):
@ -20,5 +20,5 @@ for line in xinitrc_data.split('\n'):
xinitrc_data += '\n' xinitrc_data += '\n'
xinitrc_data += 'exec awesome\n' xinitrc_data += 'exec awesome\n'
with open(f'{installation.target}/etc/X11/xinit/xinitrc', 'w') as xinitrc: with open(f"{archinstall.storage['installation_session'].target}/etc/X11/xinit/xinitrc", 'w') as xinitrc:
xinitrc.write(xinitrc_data) xinitrc.write(xinitrc_data)

View File

@ -4,6 +4,6 @@ import archinstall
# which packages will be installed by this profile # which packages will be installed by this profile
__packages__ = ["cockpit", "udisks2", "packagekit"] __packages__ = ["cockpit", "udisks2", "packagekit"]
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
installation.enable_service('cockpit.socket') archinstall.storage['installation_session'].enable_service('cockpit.socket')

View File

@ -4,6 +4,6 @@ import archinstall
# which packages will be installed by this profile # which packages will be installed by this profile
__packages__ = ["docker"] __packages__ = ["docker"]
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
installation.enable_service('docker') archinstall.storage['installation_session'].enable_service('docker')

View File

@ -4,6 +4,6 @@ import archinstall
# which packages will be installed by this profile # which packages will be installed by this profile
__packages__ = ["apache"] __packages__ = ["apache"]
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
installation.enable_service('httpd') archinstall.storage['installation_session'].enable_service('httpd')

View File

@ -4,6 +4,6 @@ import archinstall
# which packages will be installed by this profile # which packages will be installed by this profile
__packages__ = ["lighttpd"] __packages__ = ["lighttpd"]
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
installation.enable_service('lighttpd') archinstall.storage['installation_session'].enable_service('lighttpd')

View File

@ -4,8 +4,8 @@ import archinstall
# which packages will be installed by this profile # which packages will be installed by this profile
__packages__ = ["mariadb"] __packages__ = ["mariadb"]
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
installation.arch_chroot("mariadb-install-db --user=mysql --basedir=/usr --datadir=/var/lib/mysql") archinstall.storage['installation_session'].arch_chroot("mariadb-install-db --user=mysql --basedir=/usr --datadir=/var/lib/mysql")
installation.enable_service('mariadb') archinstall.storage['installation_session'].enable_service('mariadb')

View File

@ -4,6 +4,6 @@ import archinstall
# which packages will be installed by this profile # which packages will be installed by this profile
__packages__ = ["nginx"] __packages__ = ["nginx"]
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
installation.enable_service('nginx') archinstall.storage['installation_session'].enable_service('nginx')

View File

@ -4,8 +4,8 @@ import archinstall
# which packages will be installed by this profile # which packages will be installed by this profile
__packages__ = ["postgresql"] __packages__ = ["postgresql"]
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
installation.arch_chroot("initdb -D /var/lib/postgres/data", runas='postgres') archinstall.storage['installation_session'].arch_chroot("initdb -D /var/lib/postgres/data", runas='postgres')
installation.enable_service('postgresql') archinstall.storage['installation_session'].enable_service('postgresql')

View File

@ -4,6 +4,6 @@ import archinstall
# which packages will be installed by this profile # which packages will be installed by this profile
__packages__ = ["openssh"] __packages__ = ["openssh"]
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
installation.enable_service('sshd') archinstall.storage['installation_session'].enable_service('sshd')

View File

@ -7,6 +7,6 @@ import archinstall
# which packages will be installed by this profile # which packages will be installed by this profile
__packages__ = ["tomcat10"] __packages__ = ["tomcat10"]
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
installation.enable_service('tomcat10') archinstall.storage['installation_session'].enable_service('tomcat10')

View File

@ -30,23 +30,23 @@ def _prep_function(*args, **kwargs):
# or through conventional import awesome # or through conventional import awesome
if __name__ == 'awesome': if __name__ == 'awesome':
# Install the application awesome from the template under /applications/ # Install the application awesome from the template under /applications/
awesome = archinstall.Application(installation, 'awesome') awesome = archinstall.Application(archinstall.storage['installation_session'], 'awesome')
awesome.install() awesome.install()
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
# TODO: Copy a full configuration to ~/.config/awesome/rc.lua instead. # TODO: Copy a full configuration to ~/.config/awesome/rc.lua instead.
with open(f'{installation.target}/etc/xdg/awesome/rc.lua', 'r') as fh: with open(f"{archinstall.storage['installation_session'].target}/etc/xdg/awesome/rc.lua", 'r') as fh:
awesome_lua = fh.read() awesome_lua = fh.read()
## Replace xterm with alacritty for a smoother experience. ## Replace xterm with alacritty for a smoother experience.
awesome_lua = awesome_lua.replace('"xterm"', '"alacritty"') awesome_lua = awesome_lua.replace('"xterm"', '"alacritty"')
with open(f'{installation.target}/etc/xdg/awesome/rc.lua', 'w') as fh: with open(f"{archinstall.storage['installation_session'].target}/etc/xdg/awesome/rc.lua", 'w') as fh:
fh.write(awesome_lua) fh.write(awesome_lua)
## TODO: Configure the right-click-menu to contain the above packages that were installed. (as a user config) ## TODO: Configure the right-click-menu to contain the above packages that were installed. (as a user config)
## Remove some interfering nemo settings ## Remove some interfering nemo settings
installation.arch_chroot("gsettings set org.nemo.desktop show-desktop-icons false") archinstall.storage['installation_session'].arch_chroot("gsettings set org.nemo.desktop show-desktop-icons false")
installation.arch_chroot("xdg-mime default nemo.desktop inode/directory application/x-gnome-saved-search") archinstall.storage['installation_session'].arch_chroot("xdg-mime default nemo.desktop inode/directory application/x-gnome-saved-search")

View File

@ -28,9 +28,9 @@ def _prep_function(*args, **kwargs):
# or through conventional import budgie # or through conventional import budgie
if __name__ == 'budgie': if __name__ == 'budgie':
# Install dependency profiles # Install dependency profiles
installation.install_profile('xorg') archinstall.storage['installation_session'].install_profile('xorg')
# Install the Budgie packages # Install the Budgie packages
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
installation.enable_service('lightdm') # Light Display Manager archinstall.storage['installation_session'].enable_service('lightdm') # Light Display Manager

View File

@ -27,9 +27,9 @@ def _prep_function(*args, **kwargs):
# or through conventional import cinnamon # or through conventional import cinnamon
if __name__ == 'cinnamon': if __name__ == 'cinnamon':
# Install dependency profiles # Install dependency profiles
installation.install_profile('xorg') archinstall.storage['installation_session'].install_profile('xorg')
# Install the Cinnamon packages # Install the Cinnamon packages
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
installation.enable_service('lightdm') # Light Display Manager archinstall.storage['installation_session'].enable_service('lightdm') # Light Display Manager

View File

@ -28,10 +28,10 @@ def _prep_function(*args, **kwargs):
# or through conventional import deepin # or through conventional import deepin
if __name__ == 'deepin': if __name__ == 'deepin':
# Install dependency profiles # Install dependency profiles
installation.install_profile('xorg') archinstall.storage['installation_session'].install_profile('xorg')
# Install the Deepin packages # Install the Deepin packages
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
# Enable autostart of Deepin for all users # Enable autostart of Deepin for all users
installation.enable_service('lightdm') archinstall.storage['installation_session'].enable_service('lightdm')

View File

@ -48,9 +48,7 @@ if __name__ == 'desktop':
""" """
# Install common packages for all desktop environments # Install common packages for all desktop environments
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
# TODO: Remove magic variable 'installation' and place it archinstall.storage['installation_session'].install_profile(archinstall.storage['_desktop_profile'])
# in archinstall.storage or archinstall.session/archinstall.installation
installation.install_profile(archinstall.storage['_desktop_profile'])

View File

@ -29,11 +29,11 @@ def _prep_function(*args, **kwargs):
# or through conventional import gnome # or through conventional import gnome
if __name__ == 'gnome': if __name__ == 'gnome':
# Install dependency profiles # Install dependency profiles
installation.install_profile('xorg') archinstall.storage['installation_session'].install_profile('xorg')
# Install the GNOME packages # Install the GNOME packages
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
installation.enable_service('gdm') # Gnome Display Manager archinstall.storage['installation_session'].enable_service('gdm') # Gnome Display Manager
# We could also start it via xinitrc since we do have Xorg, # We could also start it via xinitrc since we do have Xorg,
# but for gnome that's deprecated and wayland is preferred. # but for gnome that's deprecated and wayland is preferred.

View File

@ -6,7 +6,7 @@ is_top_level_profile = False
# New way of defining packages for a profile, which is iterable and can be used out side # New way of defining packages for a profile, which is iterable and can be used out side
# of the profile to get a list of "what packages will be installed". # of the profile to get a list of "what packages will be installed".
__packages__ = ['i3lock', 'i3status', 'i3blocks', 'xterm', 'lightdm-gtk-greeter', 'lightdm'] __packages__ = ['i3lock', 'i3status', 'i3blocks', 'xterm', 'lightdm-gtk-greeter', 'lightdm', 'dmenu']
def _prep_function(*args, **kwargs): def _prep_function(*args, **kwargs):
""" """
@ -48,16 +48,16 @@ if __name__ == 'i3':
""" """
# Install common packages for all i3 configurations # Install common packages for all i3 configurations
installation.add_additional_packages(__packages__[:4]) archinstall.storage['installation_session'].add_additional_packages(__packages__[:4])
# Install dependency profiles # Install dependency profiles
installation.install_profile('xorg') archinstall.storage['installation_session'].install_profile('xorg')
# gaps is installed by deafult so we are overriding it here with lightdm # gaps is installed by deafult so we are overriding it here with lightdm
installation.add_additional_packages(__packages__[4:]) archinstall.storage['installation_session'].add_additional_packages(__packages__[4:])
# Auto start lightdm for all users # Auto start lightdm for all users
installation.enable_service('lightdm') archinstall.storage['installation_session'].enable_service('lightdm')
# install the i3 group now # install the i3 group now
installation.add_additional_packages(archinstall.storage['_i3_configuration']) archinstall.storage['installation_session'].add_additional_packages(archinstall.storage['_i3_configuration'])

View File

@ -37,10 +37,10 @@ def _post_install(*args, **kwargs):
# or through conventional import kde # or through conventional import kde
if __name__ == 'kde': if __name__ == 'kde':
# Install dependency profiles # Install dependency profiles
installation.install_profile('xorg') archinstall.storage['installation_session'].install_profile('xorg')
# Install the KDE packages # Install the KDE packages
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
# Enable autostart of KDE for all users # Enable autostart of KDE for all users
installation.enable_service('sddm') archinstall.storage['installation_session'].enable_service('sddm')

View File

@ -28,9 +28,9 @@ def _prep_function(*args, **kwargs):
# or through conventional import lxqt # or through conventional import lxqt
if __name__ == 'lxqt': if __name__ == 'lxqt':
# Install dependency profiles # Install dependency profiles
installation.install_profile('xorg') archinstall.storage['installation_session'].install_profile('xorg')
# Install the LXQt packages # Install the LXQt packages
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
installation.enable_service('sddm') # SDDM Display Manager archinstall.storage['installation_session'].enable_service('sddm') # SDDM Display Manager

View File

@ -27,9 +27,9 @@ def _prep_function(*args, **kwargs):
# or through conventional import mate # or through conventional import mate
if __name__ == 'mate': if __name__ == 'mate':
# Install dependency profiles # Install dependency profiles
installation.install_profile('xorg') archinstall.storage['installation_session'].install_profile('xorg')
# Install the MATE packages # Install the MATE packages
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
installation.enable_service('lightdm') # Light Display Manager archinstall.storage['installation_session'].enable_service('lightdm') # Light Display Manager

View File

@ -24,7 +24,7 @@ if __name__ == 'server':
archinstall.log(archinstall.storage['_selected_servers'], level=logging.DEBUG) archinstall.log(archinstall.storage['_selected_servers'], level=logging.DEBUG)
for server in archinstall.storage['_selected_servers']: for server in archinstall.storage['_selected_servers']:
archinstall.log(f'Installing {server} ...', level=logging.INFO) archinstall.log(f'Installing {server} ...', level=logging.INFO)
app = archinstall.Application(installation, server) app = archinstall.Application(archinstall.storage['installation_session'], server)
app.install() app.install()
archinstall.log('If your selections included multiple servers with the same port, you may have to reconfigure them.', fg="yellow", level=logging.INFO) archinstall.log('If your selections included multiple servers with the same port, you may have to reconfigure them.', fg="yellow", level=logging.INFO)

View File

@ -4,7 +4,19 @@ import archinstall
is_top_level_profile = False is_top_level_profile = False
__packages__ = ["sway", "swaylock", "swayidle", "waybar", "dmenu", "light", "grim", "slurp", "pavucontrol", "alacritty"] __packages__ = [
"sway",
"swaylock",
"swayidle",
"waybar",
"dmenu",
"light",
"grim",
"slurp",
"pavucontrol",
"alacritty",
]
def _prep_function(*args, **kwargs): def _prep_function(*args, **kwargs):
""" """
@ -13,18 +25,26 @@ def _prep_function(*args, **kwargs):
other code in this stage. So it's a safe way to ask the user other code in this stage. So it's a safe way to ask the user
for more input before any other installer steps start. for more input before any other installer steps start.
""" """
if "nvidia" in _gfx_driver_packages: __builtins__["_gfx_driver_packages"] = archinstall.select_driver()
choice = input("The proprietary Nvidia driver is not supported by Sway. It is likely that you will run into issues. Continue anyways? [y/N] ")
if choice.lower() in ("n", ""):
raise archinstall.lib.exceptions.HardwareIncompatibilityError("Sway does not support the proprietary nvidia drivers.")
__builtins__['_gfx_driver_packages'] = archinstall.select_driver()
return True return True
# Ensures that this code only gets executed if executed # Ensures that this code only gets executed if executed
# through importlib.util.spec_from_file_location("sway", "/somewhere/sway.py") # through importlib.util.spec_from_file_location("sway", "/somewhere/sway.py")
# or through conventional import sway # or through conventional import sway
if __name__ == 'sway': if __name__ == "sway":
if "nvidia" in _gfx_driver_packages:
choice = input(
"The proprietary Nvidia driver is not supported by Sway. It is likely that you will run into issues. Continue anyways? [y/N] "
)
if choice.lower() in ("n", ""):
raise archinstall.lib.exceptions.HardwareIncompatibilityError(
"Sway does not support the proprietary nvidia drivers."
)
# Install the Sway packages # Install the Sway packages
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
# Install the graphics driver packages
archinstall.storage['installation_session'].add_additional_packages(_gfx_driver_packages)

View File

@ -28,9 +28,9 @@ def _prep_function(*args, **kwargs):
# or through conventional import xfce4 # or through conventional import xfce4
if __name__ == 'xfce4': if __name__ == 'xfce4':
# Install dependency profiles # Install dependency profiles
installation.install_profile('xorg') archinstall.storage['installation_session'].install_profile('xorg')
# Install the XFCE4 packages # Install the XFCE4 packages
installation.add_additional_packages(__packages__) archinstall.storage['installation_session'].add_additional_packages(__packages__)
installation.enable_service('lightdm') # Light Display Manager archinstall.storage['installation_session'].enable_service('lightdm') # Light Display Manager

View File

@ -28,22 +28,12 @@ def _prep_function(*args, **kwargs):
if __name__ == 'xorg': if __name__ == 'xorg':
try: try:
if "nvidia" in _gfx_driver_packages: if "nvidia" in _gfx_driver_packages:
if "linux-zen" in installation.base_packages or "linux-lts" in installation.base_packages: if "linux-zen" in archinstall.storage['installation_session'].base_packages or "linux-lts" in archinstall.storage['installation_session'].base_packages:
installation.add_additional_packages("dkms")#I've had kernel regen fail if it wasn't installed before nvidia-dkms archinstall.storage['installation_session'].add_additional_packages("dkms")#I've had kernel regen fail if it wasn't installed before nvidia-dkms
installation.add_additional_packages("xorg-server xorg-xinit nvidia-dkms") archinstall.storage['installation_session'].add_additional_packages("xorg-server xorg-xinit nvidia-dkms")
else: else:
installation.add_additional_packages(f"xorg-server xorg-xinit {' '.join(_gfx_driver_packages)}") archinstall.storage['installation_session'].add_additional_packages(f"xorg-server xorg-xinit {' '.join(_gfx_driver_packages)}")
else: else:
installation.add_additional_packages(f"xorg-server xorg-xinit {' '.join(_gfx_driver_packages)}") archinstall.storage['installation_session'].add_additional_packages(f"xorg-server xorg-xinit {' '.join(_gfx_driver_packages)}")
except: except:
installation.add_additional_packages(f"xorg-server xorg-xinit") # Prep didn't run, so there's no driver to install archinstall.storage['installation_session'].add_additional_packages(f"xorg-server xorg-xinit") # Prep didn't run, so there's no driver to install
# with open(f'{installation.mountpoint}/etc/X11/xinit/xinitrc', 'a') as X11:
# X11.write('setxkbmap se\n')
# with open(f'{installation.mountpoint}/etc/vconsole.conf', 'a') as vconsole:
# vconsole.write('KEYMAP={keyboard_layout}\n'.format(**arguments))
# vconsole.write('FONT=lat9w-16\n')
# awesome = archinstall.Application(installation, 'awesome')
# awesome.install()

View File

@ -1,2 +1,2 @@
import setuptools import setuptools # type: ignore
setuptools.setup() setuptools.setup()