index : archinstall32 | |
Archlinux32 installer | gitolite user |
summaryrefslogtreecommitdiff |
-rw-r--r-- | archinstall/__init__.py | 4 | ||||
-rw-r--r-- | archinstall/lib/general.py | 10 | ||||
-rw-r--r-- | archinstall/lib/installer.py | 14 | ||||
-rw-r--r-- | archinstall/lib/locale_helpers.py | 3 | ||||
-rw-r--r-- | archinstall/lib/mirrors.py | 9 | ||||
-rw-r--r-- | archinstall/lib/services.py | 2 | ||||
-rw-r--r-- | archinstall/lib/user_interaction.py | 8 | ||||
-rw-r--r-- | examples/guided.py | 39 | ||||
-rw-r--r-- | profiles/awesome.py | 4 |
diff --git a/archinstall/__init__.py b/archinstall/__init__.py index afea843b..d98b6daa 100644 --- a/archinstall/__init__.py +++ b/archinstall/__init__.py @@ -16,10 +16,6 @@ from .lib.hardware import * __version__ = "2.1.3" -if hasUEFI() is False: - log("Archinstall currently only support UEFI booted machines. MBR & GRUB is coming in version 2.2.0!", fg="red", level=LOG_LEVELS.Error) - exit(1) - ## Basic version of arg.parse() supporting: ## --key=value ## --boolean diff --git a/archinstall/lib/general.py b/archinstall/lib/general.py index f2a714e7..6e3b66f1 100644 --- a/archinstall/lib/general.py +++ b/archinstall/lib/general.py @@ -76,7 +76,7 @@ class sys_command():#Thread): """ Stolen from archinstall_gui """ - def __init__(self, cmd, callback=None, start_callback=None, *args, **kwargs): + def __init__(self, cmd, callback=None, start_callback=None, environment_vars={}, *args, **kwargs): kwargs.setdefault("worker_id", gen_uid()) kwargs.setdefault("emulate", False) kwargs.setdefault("suppress_errors", False) @@ -93,6 +93,7 @@ class sys_command():#Thread): raise ValueError(f'Incorrect string to split: {cmd}\n{e}') self.args = args self.kwargs = kwargs + self.environment_vars = environment_vars self.kwargs.setdefault("worker", None) self.callback = callback @@ -159,7 +160,7 @@ class sys_command():#Thread): # Replace child process with our main process if not self.kwargs['emulate']: try: - os.execv(self.cmd[0], self.cmd) + os.execve(self.cmd[0], self.cmd, {**os.environ, **self.environment_vars}) except FileNotFoundError: self.status = 'done' self.log(f"{self.cmd[0]} does not exist.", level=LOG_LEVELS.Debug) @@ -262,6 +263,11 @@ class sys_command():#Thread): with open(f'{self.cwd}/trace.log', 'wb') as fh: fh.write(self.trace_log) + try: + os.close(child_fd) + except: + pass + def prerequisite_check(): if not os.path.isdir("/sys/firmware/efi"): diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 4ff9e80a..758033a7 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -1,4 +1,4 @@ -import os, stat, time, shutil, pathlib +import os, stat, time, shutil, pathlib, subprocess from .exceptions import * from .disk import * @@ -81,6 +81,7 @@ class Installer(): if not (missing_steps := self.post_install_check()): self.log('Installation completed without any errors. You may now reboot.', bg='black', fg='green', level=LOG_LEVELS.Info) self.sync_log_to_install_medium() + return True else: self.log('Some required steps were not successfully installed/configured before leaving the installer:', bg='black', fg='red', level=LOG_LEVELS.Warning) @@ -190,6 +191,9 @@ class Installer(): def arch_chroot(self, cmd, *args, **kwargs): return self.run_command(cmd) + def drop_to_shell(self): + subprocess.check_call(f"/usr/bin/arch-chroot {self.target}", shell=True) + def configure_nic(self, nic, dhcp=True, ip=None, gateway=None, dns=None, *args, **kwargs): if dhcp: conf = Networkd(Match={"Name": nic}, Network={"DHCP": "yes"}) @@ -443,10 +447,18 @@ class Installer(): o = b''.join(sys_command(f"/usr/bin/arch-chroot {self.target} sh -c \"echo '{user}:{password}' | chpasswd\"")) pass + + def user_set_shell(self, user, shell): + self.log(f'Setting shell for {user} to {shell}', level=LOG_LEVELS.Info) + + o = b''.join(sys_command(f"/usr/bin/arch-chroot {self.target} sh -c \"chsh -s {shell} {user}\"")) + pass def set_keyboard_language(self, language): if len(language.strip()): with open(f'{self.target}/etc/vconsole.conf', 'w') as vconsole: vconsole.write(f'KEYMAP={language}\n') vconsole.write(f'FONT=lat9w-16\n') + else: + self.log(f'Keyboard language was not changed from default (no language specified).', fg="yellow", level=LOG_LEVELS.Info) return True diff --git a/archinstall/lib/locale_helpers.py b/archinstall/lib/locale_helpers.py index 523a23d5..82964dc9 100644 --- a/archinstall/lib/locale_helpers.py +++ b/archinstall/lib/locale_helpers.py @@ -1,3 +1,4 @@ +import subprocess import os from .exceptions import * @@ -26,4 +27,4 @@ def search_keyboard_layout(filter, layout='qwerty'): yield language def set_keyboard_language(locale): - return os.system(f'loadkeys {locale}') == 0 + return subprocess.call(['loadkeys',locale]) == 0 diff --git a/archinstall/lib/mirrors.py b/archinstall/lib/mirrors.py index d7d35782..04f47c0d 100644 --- a/archinstall/lib/mirrors.py +++ b/archinstall/lib/mirrors.py @@ -74,10 +74,15 @@ def re_rank_mirrors(top=10, *positionals, **kwargs): def list_mirrors(): url = f"https://archlinux.org/mirrorlist/?protocol=https&ip_version=4&ip_version=6&use_mirror_status=on" - - response = urllib.request.urlopen(url) regions = {} + try: + response = urllib.request.urlopen(url) + except urllib.error.URLError as err: + log(f'Could not fetch an active mirror-list: {err}', level=LOG_LEVELS.Warning, fg="yellow") + return regions + + region = 'Unknown region' for line in response.readlines(): if len(line.strip()) == 0: diff --git a/archinstall/lib/services.py b/archinstall/lib/services.py index 8fcdd296..bb6f64f2 100644 --- a/archinstall/lib/services.py +++ b/archinstall/lib/services.py @@ -7,6 +7,6 @@ def service_state(service_name: str): if os.path.splitext(service_name)[1] != '.service': service_name += '.service' # Just to be safe - state = b''.join(sys_command(f'systemctl show -p SubState --value {service_name}')) + state = b''.join(sys_command(f'systemctl show --no-pager -p SubState --value {service_name}', environment_vars={'SYSTEMD_COLORS' : '0'})) return state.strip().decode('UTF-8') diff --git a/archinstall/lib/user_interaction.py b/archinstall/lib/user_interaction.py index 16627794..99cf6274 100644 --- a/archinstall/lib/user_interaction.py +++ b/archinstall/lib/user_interaction.py @@ -130,7 +130,9 @@ def ask_for_additional_users(prompt='Any additional users to install (leave blan return users, super_users def ask_for_a_timezone(): - timezone = input('Enter a valid timezone (Example: Europe/Stockholm): ').strip() + timezone = input('Enter a valid timezone (examples: Europe/Stockholm, US/Eastern) or press enter to use UTC: ').strip() + if timezone == '': + timezone = 'UTC' if (pathlib.Path("/usr")/"share"/"zoneinfo"/timezone).exists(): return timezone else: @@ -184,7 +186,7 @@ def ask_to_configure_network(): elif nic: return nic - return None + return {} def ask_for_disk_layout(): options = { @@ -400,4 +402,4 @@ def select_mirror_regions(mirrors, show_top_mirrors=True): return selected_mirrors - raise RequirementError("Selecting mirror region require a least one region to be given as an option.") + return None diff --git a/examples/guided.py b/examples/guided.py index beb577c8..d47a949c 100644 --- a/examples/guided.py +++ b/examples/guided.py @@ -3,6 +3,10 @@ import archinstall from archinstall.lib.hardware import hasUEFI from archinstall.lib.profiles import Profile +if hasUEFI() is False: + log("ArchInstall currently only supports machines booted with UEFI. MBR & GRUB support is coming in version 2.2.0!", fg="red", level=archinstall.LOG_LEVELS.Error) + exit(1) + def ask_user_questions(): """ First, we'll ask the user for a bunch of user input. @@ -171,7 +175,7 @@ def ask_user_questions(): else: # packages installed by a profile may depend on audio and something may get installed anyways, not much we can do about that. # we will not try to remove packages post-installation to not have audio, as that may cause multiple issues - archinstall.arguments['audio'] = 'none' + archinstall.arguments['audio'] = None # Additional packages (with some light weight error handling for invalid package names) if not archinstall.arguments.get('packages', None): @@ -273,38 +277,47 @@ def perform_installation(mountpoint): # Certain services might be running that affects the system during installation. # Currently, only one such service is "reflector.service" which updates /etc/pacman.d/mirrorlist # We need to wait for it before we continue since we opted in to use a custom mirror/region. - installation.log(f'Waiting for automatic mirror selection has completed before using custom mirrors.') - while 'dead' not in (status := archinstall.service_state('reflector')): + installation.log(f'Waiting for automatic mirror selection (reflector) to complete.', level=archinstall.LOG_LEVELS.Info) + while archinstall.service_state('reflector') not in ('dead', 'failed'): time.sleep(1) - archinstall.use_mirrors(archinstall.arguments['mirror-region']) # Set the mirrors for the live medium + # Set mirrors used by pacstrap (outside of installation) + if archinstall.arguments.get('mirror-region', None): + archinstall.use_mirrors(archinstall.arguments['mirror-region']) # Set the mirrors for the live medium + if installation.minimal_installation(): installation.set_hostname(archinstall.arguments['hostname']) - installation.set_mirrors(archinstall.arguments['mirror-region']) # Set the mirrors in the installation medium + + # Configure the selected mirrors in the installation + if archinstall.arguments.get('mirror-region', None): + installation.set_mirrors(archinstall.arguments['mirror-region']) # Set the mirrors in the installation medium + installation.set_keyboard_language(archinstall.arguments['keyboard-language']) installation.add_bootloader() # If user selected to copy the current ISO network configuration # Perform a copy of the config - if archinstall.arguments.get('nic', None) == 'Copy ISO network configuration to installation': + if archinstall.arguments.get('nic', {}) == 'Copy ISO network configuration to installation': installation.copy_ISO_network_config(enable_services=True) # Sources the ISO network configuration to the install medium. - elif archinstall.arguments.get('nic',{}).get('NetworkManager',False): + elif archinstall.arguments.get('nic', {}).get('NetworkManager',False): installation.add_additional_packages("networkmanager") installation.enable_service('NetworkManager.service') # Otherwise, if a interface was selected, configure that interface - elif archinstall.arguments.get('nic', None): + elif archinstall.arguments.get('nic', {}): installation.configure_nic(**archinstall.arguments.get('nic', {})) installation.enable_service('systemd-networkd') installation.enable_service('systemd-resolved') if archinstall.arguments.get('audio', None) != None: - installation.log(f"The {archinstall.arguments.get('audio', None)} audio server will be used.", level=archinstall.LOG_LEVELS.Info) + installation.log(f"This audio server will be used: {archinstall.arguments.get('audio', None)}", level=archinstall.LOG_LEVELS.Info) if archinstall.arguments.get('audio', None) == 'pipewire': print('Installing pipewire ...') installation.add_additional_packages(["pipewire", "pipewire-alsa", "pipewire-jack", "pipewire-media-session", "pipewire-pulse", "gst-plugin-pipewire", "libpulse"]) elif archinstall.arguments.get('audio', None) == 'pulseaudio': print('Installing pulseaudio ...') installation.add_additional_packages("pulseaudio") + else: + installation.log("No audio server will be installed.", level=archinstall.LOG_LEVELS.Info) if archinstall.arguments.get('packages', None) and archinstall.arguments.get('packages', None)[0] != '': installation.add_additional_packages(archinstall.arguments.get('packages', None)) @@ -324,6 +337,14 @@ def perform_installation(mountpoint): if (root_pw := archinstall.arguments.get('!root-password', None)) and len(root_pw): installation.user_set_pw('root', root_pw) + installation.log("For post-installation tips, see https://wiki.archlinux.org/index.php/Installation_guide#Post-installation", fg="yellow") + choice = input("Would you like to chroot into the newly created installation and perform post-installation configuration? [Y/n] ") + if choice.lower() in ("y", ""): + try: + installation.drop_to_shell() + except: + pass ask_user_questions() perform_installation_steps() + diff --git a/profiles/awesome.py b/profiles/awesome.py index 0b00a424..cbd52a3c 100644 --- a/profiles/awesome.py +++ b/profiles/awesome.py @@ -39,13 +39,13 @@ if __name__ == 'awesome': alacritty.install() # TODO: Copy a full configuration to ~/.config/awesome/rc.lua instead. - with open(f'{installation.mountpoint}/etc/xdg/awesome/rc.lua', 'r') as fh: + with open(f'{installation.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'{installation.mountpoint}/etc/xdg/awesome/rc.lua', 'w') as fh: + with open(f'{installation.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) |