Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #2262 and GFX rewrite #2266

Merged
merged 3 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions archinstall/lib/hardware.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,22 @@ def get_ucode(self) -> Optional[Path]:


class GfxPackage(Enum):
Dkms = 'dkms'
IntelMediaDriver = 'intel-media-driver'
LibvaIntelDriver = 'libva-intel-driver'
LibvaMesaDriver = 'libva-mesa-driver'
Mesa = "mesa"
Nvidia = 'nvidia'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this make it so nvidia package is not installed? Which is needed for some platforms? Or we rely solely on the -dkms and add the nvidia hooks to build the driver each kernel upgrade?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I missed something but in the old code Nvidia didn't seem to be installed at all. But please double check that I didn't miss anything

I've actually tried installing nvidia and nvidia-dkms which threw a conflict error

NvidiaDkms = 'nvidia-dkms'
NvidiaOpen = 'nvidia-open'
NvidiaOpenDkms = 'nvidia-open-dkms'
VulkanIntel = 'vulkan-intel'
VulkanRadeon = 'vulkan-radeon'
Xf86VideoAmdgpu = "xf86-video-amdgpu"
Xf86VideoAti = "xf86-video-ati"
Xf86VideoNouveau = 'xf86-video-nouveau'
Xf86VideoVmware = 'xf86-video-vmware'
XorgServer = 'xorg-server'
XorgXinit = 'xorg-xinit'


class GfxDriver(Enum):
Expand All @@ -69,10 +73,12 @@ def is_nvidia(self) -> bool:
case _:
return False

def packages(self) -> List[GfxPackage]:
def gfx_packages(self) -> List[GfxPackage]:
packages = [GfxPackage.XorgServer, GfxPackage.XorgXinit]

match self:
case GfxDriver.AllOpenSource:
return [
packages += [
GfxPackage.Mesa,
GfxPackage.Xf86VideoAmdgpu,
GfxPackage.Xf86VideoAti,
Expand All @@ -85,38 +91,44 @@ def packages(self) -> List[GfxPackage]:
GfxPackage.VulkanIntel
]
case GfxDriver.AmdOpenSource:
return [
packages += [
GfxPackage.Mesa,
GfxPackage.Xf86VideoAmdgpu,
GfxPackage.Xf86VideoAti,
GfxPackage.LibvaMesaDriver,
GfxPackage.VulkanRadeon
]
case GfxDriver.IntelOpenSource:
return [
packages += [
GfxPackage.Mesa,
GfxPackage.LibvaIntelDriver,
GfxPackage.IntelMediaDriver,
GfxPackage.VulkanIntel
]
case GfxDriver.NvidiaOpenKernel:
return [GfxPackage.NvidiaOpen]
packages += [
GfxPackage.NvidiaOpen,
GfxPackage.Dkms,
GfxPackage.NvidiaOpenDkms
]
case GfxDriver.NvidiaOpenSource:
return [
packages += [
GfxPackage.Mesa,
GfxPackage.Xf86VideoNouveau,
GfxPackage.LibvaMesaDriver
]
case GfxDriver.NvidiaProprietary:
return [
GfxPackage.Nvidia
packages += [
GfxPackage.NvidiaDkms,
GfxPackage.Dkms,
]
case GfxDriver.VMOpenSource:
return [
packages += [
GfxPackage.Mesa,
GfxPackage.Xf86VideoVmware
]

return packages

class _SysInfo:
def __init__(self):
Expand Down
58 changes: 36 additions & 22 deletions archinstall/lib/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
if TYPE_CHECKING:
_: Any


# Any package that the Installer() is responsible for (optional and the default ones)
__packages__ = ["base", "base-devel", "linux-firmware", "linux", "linux-lts", "linux-zen", "linux-hardened"]

Expand Down Expand Up @@ -77,7 +76,7 @@ def __init__(
storage['session'] = self
storage['installation_session'] = self

self.modules: List[str] = []
self._modules: List[str] = []
self._binaries: List[str] = []
self._files: List[str] = []

Expand All @@ -104,7 +103,8 @@ def __exit__(self, exc_type, exc_val, exc_tb):

# We avoid printing /mnt/<log path> because that might confuse people if they note it down
# and then reboot, and a identical log file will be found in the ISO medium anyway.
print(_("[!] A log file has been created here: {}").format(os.path.join(storage['LOG_PATH'], storage['LOG_FILE'])))
print(_("[!] A log file has been created here: {}").format(
os.path.join(storage['LOG_PATH'], storage['LOG_FILE'])))
print(_(" Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues"))
raise exc_val

Expand All @@ -124,6 +124,14 @@ def __exit__(self, exc_type, exc_val, exc_tb):
self.sync_log_to_install_medium()
return False

def remove_mod(self, mod: str):
if mod in self._modules:
self._modules.remove(mod)

def append_mod(self, mod: str):
if mod not in self._modules:
self._modules.append(mod)

def _verify_service_stop(self):
"""
Certain services might be running that affects the system during installation.
Expand All @@ -139,14 +147,16 @@ def _verify_service_stop(self):
while True:
if not _notified and time.time() - _started_wait > 5:
_notified = True
warn(_("Time syncronization not completing, while you wait - check the docs for workarounds: https://archinstall.readthedocs.io/"))

warn(
_("Time syncronization not completing, while you wait - check the docs for workarounds: https://archinstall.readthedocs.io/"))

time_val = SysCommand('timedatectl show --property=NTPSynchronized --value').decode()
if time_val and time_val.strip() == 'yes':
break
time.sleep(1)
else:
info(_('Skipping waiting for automatic time sync (this can cause issues if time is out of sync during installation)'))
info(
_('Skipping waiting for automatic time sync (this can cause issues if time is out of sync during installation)'))

info('Waiting for automatic mirror selection (reflector) to complete.')
while self._service_state('reflector') not in ('dead', 'failed', 'exited'):
Expand Down Expand Up @@ -211,7 +221,8 @@ def mount_ordered_layout(self):
# partition is not encrypted
self._mount_partition(part_mod)

def _prepare_luks_partitions(self, partitions: List[disk.PartitionModification]) -> Dict[disk.PartitionModification, Luks2]:
def _prepare_luks_partitions(self, partitions: List[disk.PartitionModification]) -> Dict[
disk.PartitionModification, Luks2]:
return {
part_mod: disk.device_handler.unlock_luks2_dev(
part_mod.dev_path,
Expand Down Expand Up @@ -304,7 +315,7 @@ def add_swapfile(self, size='4G', enable_resume=True, file='/swapfile'):
self._kernel_params.append(f'resume=UUID={resume_uuid}')
self._kernel_params.append(f'resume_offset={resume_offset}')

def post_install_check(self, *args :str, **kwargs :str) -> List[str]:
def post_install_check(self, *args: str, **kwargs: str) -> List[str]:
return [step for step, flag in self.helper_flags.items() if flag is False]

def set_mirrors(self, mirror_config: MirrorConfiguration):
Expand All @@ -319,14 +330,15 @@ def set_mirrors(self, mirror_config: MirrorConfiguration):
if mirror_config.custom_mirrors:
add_custom_mirrors(mirror_config.custom_mirrors)

def genfstab(self, flags :str = '-pU'):
def genfstab(self, flags: str = '-pU'):
fstab_path = self.target / "etc" / "fstab"
info(f"Updating {fstab_path}")

try:
gen_fstab = SysCommand(f'/usr/bin/genfstab {flags} {self.target}').decode()
except SysCallError as err:
raise RequirementError(f'Could not generate fstab, strapping in packages most likely failed (disk out of space?)\n Error: {err}')
raise RequirementError(
f'Could not generate fstab, strapping in packages most likely failed (disk out of space?)\n Error: {err}')

with open(fstab_path, 'a') as fp:
fp.write(gen_fstab)
Expand Down Expand Up @@ -366,14 +378,15 @@ def genfstab(self, flags :str = '-pU'):
# We then locate the correct subvolume and check if it's compressed,
# and skip entries where compression is already defined
# We then sneak in the compress=zstd option if it doesn't already exist:
if sub_vol.compress and str(sub_vol.mountpoint) == Path(mountpoint[0].strip()) and ',compress=zstd,' not in line:
if sub_vol.compress and str(sub_vol.mountpoint) == Path(
mountpoint[0].strip()) and ',compress=zstd,' not in line:
fstab[index] = line.replace(subvoldef[0], f',compress=zstd{subvoldef[0]}')
break

with fstab_path.open('w') as fp:
fp.writelines(fstab)

def set_hostname(self, hostname: str, *args :str, **kwargs :str) -> None:
def set_hostname(self, hostname: str, *args: str, **kwargs: str) -> None:
with open(f'{self.target}/etc/hostname', 'w') as fh:
fh.write(hostname + '\n')

Expand Down Expand Up @@ -424,7 +437,7 @@ def set_locale(self, locale_config: LocaleConfiguration) -> bool:
(self.target / 'etc/locale.conf').write_text(f'LANG={lang_value}\n')
return True

def set_timezone(self, zone :str, *args :str, **kwargs :str) -> bool:
def set_timezone(self, zone: str, *args: str, **kwargs: str) -> bool:
if not zone:
return True
if not len(zone):
Expand Down Expand Up @@ -474,10 +487,10 @@ def enable_service(self, services: Union[str, List[str]]) -> None:
if hasattr(plugin, 'on_service'):
plugin.on_service(service)

def run_command(self, cmd :str, *args :str, **kwargs :str) -> SysCommand:
def run_command(self, cmd: str, *args: str, **kwargs: str) -> SysCommand:
return SysCommand(f'/usr/bin/arch-chroot {self.target} {cmd}')

def arch_chroot(self, cmd :str, run_as :Optional[str] = None) -> SysCommand:
def arch_chroot(self, cmd: str, run_as: Optional[str] = None) -> SysCommand:
if run_as:
cmd = f"su - {run_as} -c {shlex.quote(cmd)}"

Expand All @@ -502,7 +515,7 @@ def configure_nic(self, nic: Nic):
with open(f"{self.target}/etc/systemd/network/10-{nic.iface}.network", "a") as netconf:
netconf.write(str(conf))

def copy_iso_network_config(self, enable_services :bool = False) -> bool:
def copy_iso_network_config(self, enable_services: bool = False) -> bool:
# Copy (if any) iwd password and config files
if os.path.isdir('/var/lib/iwd/'):
if psk_files := glob.glob('/var/lib/iwd/*.psk'):
Expand All @@ -517,7 +530,7 @@ def copy_iso_network_config(self, enable_services :bool = False) -> bool:
# This function will be called after minimal_installation()
# as a hook for post-installs. This hook is only needed if
# base is not installed yet.
def post_install_enable_iwd_service(*args :str, **kwargs :str):
def post_install_enable_iwd_service(*args: str, **kwargs: str):
self.enable_service('iwd')

self.post_base_install.append(post_install_enable_iwd_service)
Expand All @@ -542,7 +555,7 @@ def post_install_enable_iwd_service(*args :str, **kwargs :str):
# If we haven't installed the base yet (function called pre-maturely)
if self.helper_flags.get('base', False) is False:

def post_install_enable_networkd_resolved(*args :str, **kwargs :str):
def post_install_enable_networkd_resolved(*args: str, **kwargs: str):
self.enable_service(['systemd-networkd', 'systemd-resolved'])

self.post_base_install.append(post_install_enable_networkd_resolved)
Expand All @@ -560,7 +573,7 @@ def mkinitcpio(self, flags: List[str]) -> bool:
return True

with open(f'{self.target}/etc/mkinitcpio.conf', 'w') as mkinit:
mkinit.write(f"MODULES=({' '.join(self.modules)})\n")
mkinit.write(f"MODULES=({' '.join(self._modules)})\n")
mkinit.write(f"BINARIES=({' '.join(self._binaries)})\n")
mkinit.write(f"FILES=({' '.join(self._files)})\n")

Expand Down Expand Up @@ -603,7 +616,7 @@ def minimal_installation(
if (pkg := part.fs_type.installation_pkg) is not None:
self.base_packages.append(pkg)
if (module := part.fs_type.installation_module) is not None:
self.modules.append(module)
self._modules.append(module)
if (binary := part.fs_type.installation_binary) is not None:
self._binaries.append(binary)

Expand Down Expand Up @@ -694,7 +707,7 @@ def minimal_installation(
if hasattr(plugin, 'on_install'):
plugin.on_install(self)

def setup_swap(self, kind :str = 'zram'):
def setup_swap(self, kind: str = 'zram'):
if kind == 'zram':
info(f"Setting up swap on zram")
self.pacman.strap('zram-generator')
Expand Down Expand Up @@ -1272,7 +1285,8 @@ def create_users(self, users: Union[User, List[User]]):
for user in users:
self.user_create(user.username, user.password, user.groups, user.sudo)

def user_create(self, user :str, password :Optional[str] = None, groups :Optional[List[str]] = None, sudo :bool = False) -> None:
def user_create(self, user: str, password: Optional[str] = None, groups: Optional[List[str]] = None,
sudo: bool = False) -> None:
if groups is None:
groups = []

Expand Down
52 changes: 19 additions & 33 deletions archinstall/lib/profile/profiles_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@

from archinstall.default_profiles.profile import Profile, TProfile, GreeterType
from .profile_model import ProfileConfiguration
from ..hardware import GfxDriver, GfxPackage
from ..hardware import GfxDriver
from ..menu import MenuSelectionType, Menu, MenuSelection
from ..networking import list_interfaces, fetch_data_from_url
from ..output import error, debug, info, warn
from ..output import error, debug, info
from ..storage import storage

if TYPE_CHECKING:
Expand Down Expand Up @@ -206,38 +206,24 @@ def install_greeter(self, install_session: 'Installer', greeter: GreeterType):
with open(path, 'w') as file:
file.write(filedata)

def install_gfx_driver(self, install_session: 'Installer', driver: Optional[GfxDriver]):
try:
def install_gfx_driver(self, install_session: 'Installer', driver: GfxDriver):
debug(f'Installing GFX driver: {driver.value}')

if driver in [GfxDriver.NvidiaOpenKernel, GfxDriver.NvidiaProprietary]:
headers = [f'{kernel}-headers' for kernel in install_session.kernels]
# Fixes https://github.com/archlinux/archinstall/issues/585
install_session.add_additional_packages(headers)
elif driver in [GfxDriver.AllOpenSource, GfxDriver.AmdOpenSource]:
# The order of these two are important if amdgpu is installed #808
install_session.remove_mod('amdgpu')
install_session.remove_mod('radeon')

install_session.append_mod('amdgpu')
install_session.append_mod('radeon')

if driver is not None:
driver_pkgs = driver.packages()
pkg_names = [p.value for p in driver_pkgs]

for driver_pkg in {GfxPackage.Nvidia, GfxPackage.NvidiaOpen} & set(driver_pkgs):
for kernel in {"linux-lts", "linux-zen"} & set(install_session.kernels):
# Fixes https://github.com/archlinux/archinstall/issues/585
install_session.add_additional_packages(f"{kernel}-headers")

# I've had kernel regen fail if it wasn't installed before nvidia-dkms
install_session.add_additional_packages(['dkms', 'xorg-server', 'xorg-xinit', f'{driver_pkg.value}-dkms'])
# Return after first driver match, since it is impossible to use both simultaneously.
return

if 'amdgpu' in driver_pkgs:
# The order of these two are important if amdgpu is installed #808
if 'amdgpu' in install_session.modules:
install_session.modules.remove('amdgpu')
install_session.modules.append('amdgpu')

if 'radeon' in install_session.modules:
install_session.modules.remove('radeon')
install_session.modules.append('radeon')

install_session.add_additional_packages(pkg_names)
except Exception as err:
warn(f"Could not handle nvidia and linuz-zen specific situations during xorg installation: {err}")
# Prep didn't run, so there's no driver to install
install_session.add_additional_packages(['xorg-server', 'xorg-xinit'])
driver_pkgs = driver.gfx_packages()
pkg_names = [p.value for p in driver_pkgs]
install_session.add_additional_packages(pkg_names)

def install_profile_config(self, install_session: 'Installer', profile_config: ProfileConfiguration):
profile = profile_config.profile
Expand Down
Loading