index : archinstall32 | |
Archlinux32 installer | gitolite user |
summaryrefslogtreecommitdiff |
author | Anton Hvornum <anton@hvornum.se> | 2021-05-15 17:49:58 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-15 17:49:58 +0000 |
commit | a75dd6ea3a4f961ddfeaff6b4378bd4aac5c3b39 (patch) | |
tree | 7db58a8b4e1c640dc16d0060704f3b304a4e325d /archinstall/lib/installer.py | |
parent | 5254ac62200bb279c855d06bea1006b323bfae87 (diff) | |
parent | 5067aaa260d218f7d1d60ada2fe8413e90970060 (diff) |
-rw-r--r-- | archinstall/lib/installer.py | 96 |
diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 68d058f0..eccd2c49 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -1,53 +1,49 @@ -import os, stat, time, shutil, pathlib -import subprocess, logging -from .exceptions import * from .disk import * -from .general import * -from .user_interaction import * -from .profiles import Profile +from .hardware import * from .mirrors import * -from .systemd import Networkd -from .output import log from .storage import storage -from .hardware import * +from .systemd import Networkd +from .user_interaction import * # 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"] + class Installer(): """ `Installer()` is the wrapper for most basic installation steps. It also wraps :py:func:`~archinstall.Installer.pacstrap` among other things. :param partition: Requires a partition as the first argument, this is - so that the installer can mount to `mountpoint` and strap packages there. + so that the installer can mount to `mountpoint` and strap packages there. :type partition: class:`archinstall.Partition` :param boot_partition: There's two reasons for needing a boot partition argument, - The first being so that `mkinitcpio` can place the `vmlinuz` kernel at the right place - during the `pacstrap` or `linux` and the base packages for a minimal installation. - The second being when :py:func:`~archinstall.Installer.add_bootloader` is called, - A `boot_partition` must be known to the installer before this is called. + The first being so that `mkinitcpio` can place the `vmlinuz` kernel at the right place + during the `pacstrap` or `linux` and the base packages for a minimal installation. + The second being when :py:func:`~archinstall.Installer.add_bootloader` is called, + A `boot_partition` must be known to the installer before this is called. :type boot_partition: class:`archinstall.Partition` :param profile: A profile to install, this is optional and can be called later manually. - This just simplifies the process by not having to call :py:func:`~archinstall.Installer.install_profile` later on. + This just simplifies the process by not having to call :py:func:`~archinstall.Installer.install_profile` later on. :type profile: str, optional :param hostname: The given /etc/hostname for the machine. :type hostname: str, optional """ + def __init__(self, target, *, base_packages=__packages__[:3], kernels=['linux']): self.target = target self.init_time = time.strftime('%Y-%m-%d_%H-%M-%S') self.milliseconds = int(str(time.time()).split('.')[1]) self.helper_flags = { - 'base' : False, - 'bootloader' : False + 'base': False, + 'bootloader': False } - + self.base_packages = base_packages.split(' ') if type(base_packages) is str else base_packages for kernel in kernels: self.base_packages.append(kernel) @@ -78,7 +74,7 @@ class Installer(): # TODO: https://stackoverflow.com/questions/28157929/how-to-safely-handle-an-exception-inside-a-context-manager if len(args) >= 2 and args[1]: - #self.log(self.trace_log.decode('UTF-8'), level=logging.DEBUG) + # self.log(self.trace_log.decode('UTF-8'), level=logging.DEBUG) self.log(args[1], level=logging.ERROR, fg='red') self.sync_log_to_install_medium() @@ -100,10 +96,10 @@ class Installer(): self.log('Some required steps were not successfully installed/configured before leaving the installer:', fg='red', level=logging.WARNING) for step in missing_steps: self.log(f' - {step}', fg='red', level=logging.WARNING) - + self.log(f"Detailed error logs can be found at: {storage['LOG_PATH']}", level=logging.WARNING) self.log(f"Submit this zip file as an issue to https://github.com/archlinux/archinstall/issues", level=logging.WARNING) - + self.sync_log_to_install_medium() return False @@ -116,7 +112,7 @@ class Installer(): if not os.path.isdir(f"{self.target}/{os.path.dirname(absolute_logfile)}"): os.makedirs(f"{self.target}/{os.path.dirname(absolute_logfile)}") - + shutil.copy2(absolute_logfile, f"{self.target}/{absolute_logfile}") return True @@ -124,7 +120,7 @@ class Installer(): def mount(self, partition, mountpoint, create_mountpoint=True): if create_mountpoint and not os.path.isdir(f'{self.target}{mountpoint}'): os.makedirs(f'{self.target}{mountpoint}') - + partition.mount(f'{self.target}{mountpoint}') def post_install_check(self, *args, **kwargs): @@ -147,7 +143,7 @@ class Installer(): def genfstab(self, flags='-pU'): self.log(f"Updating {self.target}/etc/fstab", level=logging.INFO) - + fstab = sys_command(f'/usr/bin/genfstab {flags} {self.target}').trace_log with open(f"{self.target}/etc/fstab", 'ab') as fstab_fh: fstab_fh.write(fstab) @@ -173,10 +169,10 @@ class Installer(): def set_timezone(self, zone, *args, **kwargs): if not zone: return True - if not len(zone): return True # Redundant + if not len(zone): return True # Redundant - if (pathlib.Path("/usr")/"share"/"zoneinfo"/zone).exists(): - (pathlib.Path(self.target)/"etc"/"localtime").unlink(missing_ok=True) + if (pathlib.Path("/usr") / "share" / "zoneinfo" / zone).exists(): + (pathlib.Path(self.target) / "etc" / "localtime").unlink(missing_ok=True) sys_command(f'/usr/bin/arch-chroot {self.target} ln -s /usr/share/zoneinfo/{zone} /etc/localtime') return True else: @@ -204,7 +200,7 @@ class Installer(): def arch_chroot(self, cmd, *args, **kwargs): if 'runas' in kwargs: cmd = f"su - {kwargs['runas']} -c \"{cmd}\"" - + return self.run_command(cmd) def drop_to_shell(self): @@ -224,7 +220,7 @@ class Installer(): network["DNS"] = dns conf = Networkd(Match={"Name": nic}, Network=network) - + with open(f"{self.target}/etc/systemd/network/10-{nic}.network", "a") as netconf: netconf.write(str(conf)) @@ -239,6 +235,7 @@ class Installer(): # If we haven't installed the base yet (function called pre-maturely) if self.helper_flags.get('base', False) is False: self.base_packages.append('iwd') + # 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. @@ -268,20 +265,21 @@ class Installer(): if self.helper_flags.get('base', False) is False: def post_install_enable_networkd_resolved(*args, **kwargs): self.enable_service('systemd-networkd', 'systemd-resolved') + self.post_base_install.append(post_install_enable_networkd_resolved) # Otherwise, we can go ahead and enable the services else: self.enable_service('systemd-networkd', 'systemd-resolved') - return True def detect_encryption(self, partition): + part = Partition(partition.parent, None, autodetect_filesystem=True) if partition.encrypted: return partition - elif partition.parent not in partition.path and Partition(partition.parent, None, autodetect_filesystem=True).filesystem == 'crypto_LUKS': - return Partition(partition.parent, None, autodetect_filesystem=True) - + elif partition.parent not in partition.path and part.filesystem == 'crypto_LUKS': + return part + return False def mkinitcpio(self, *flags): @@ -298,11 +296,9 @@ class Installer(): ## TODO: Perhaps this should be living in the function which dictates ## the partitioning. Leaving here for now. - - for partition in self.partitions: if partition.filesystem == 'btrfs': - #if partition.encrypted: + # if partition.encrypted: self.base_packages.append('btrfs-progs') if partition.filesystem == 'xfs': self.base_packages.append('xfsprogs') @@ -320,18 +316,18 @@ class Installer(): if 'encrypt' not in self.HOOKS: self.HOOKS.insert(self.HOOKS.index('filesystems'), 'encrypt') - if not(hasUEFI()): + if not hasUEFI(): self.base_packages.append('grub') - + if not isVM(): vendor = cpuVendor() - if vendor == "AuthenticAMD": + if vendor == "AuthenticAMD": self.base_packages.append("amd-ucode") elif vendor == "GenuineIntel": self.base_packages.append("intel-ucode") else: self.log("Unknown cpu vendor not installing ucode") - + self.pacstrap(self.base_packages) self.helper_flags['base-strapped'] = True @@ -341,9 +337,9 @@ class Installer(): ) # Redundant \n at the start? who knows? ## TODO: Support locale and timezone - #os.remove(f'{self.target}/etc/localtime') - #sys_command(f'/usr/bin/arch-chroot {self.target} ln -s /usr/share/zoneinfo/{localtime} /etc/localtime') - #sys_command('/usr/bin/arch-chroot /mnt hwclock --hctosys --localtime') + # os.remove(f'{self.target}/etc/localtime') + # sys_command(f'/usr/bin/arch-chroot {self.target} ln -s /usr/share/zoneinfo/{localtime} /etc/localtime') + # sys_command('/usr/bin/arch-chroot /mnt hwclock --hctosys --localtime') self.set_hostname('archinstall') self.set_locale('en_US') @@ -365,7 +361,7 @@ class Installer(): boot_partition = None root_partition = None for partition in self.partitions: - if partition.mountpoint == self.target+'/boot': + if partition.mountpoint == self.target + '/boot': boot_partition = partition elif partition.mountpoint == self.target: root_partition = partition @@ -395,7 +391,7 @@ class Installer(): f"default {self.init_time}", f"timeout 5" ] - + with open(f'{self.target}/boot/loader/loader.conf', 'w') as loader: for line in loader_data: if line[:8] == 'default ': @@ -408,7 +404,7 @@ class Installer(): ## For some reason, blkid and /dev/disk/by-uuid are not getting along well. ## And blkid is wrong in terms of LUKS. - #UUID = sys_command('blkid -s PARTUUID -o value {drive}{partition_2}'.format(**args)).decode('UTF-8').strip() + # UUID = sys_command('blkid -s PARTUUID -o value {drive}{partition_2}'.format(**args)).decode('UTF-8').strip() # Setup the loader entry with open(f'{self.target}/boot/loader/entries/{self.init_time}.conf', 'w') as entry: entry.write(f'# Created by: archinstall\n') @@ -417,7 +413,7 @@ class Installer(): entry.write(f'linux /vmlinuz-linux\n') if not isVM(): vendor = cpuVendor() - if vendor == "AuthenticAMD": + if vendor == "AuthenticAMD": entry.write("initrd /amd-ucode.img\n") elif vendor == "GenuineIntel": entry.write("initrd /intel-ucode.img\n") @@ -472,13 +468,13 @@ class Installer(): self.log(f'Installing network profile {profile}', level=logging.INFO) return profile.install() - def enable_sudo(self, entity :str, group=False): + def enable_sudo(self, entity: str, group=False): self.log(f'Enabling sudo permissions for {entity}.', level=logging.INFO) with open(f'{self.target}/etc/sudoers', 'a') as sudoers: sudoers.write(f'{"%" if group else ""}{entity} ALL=(ALL) ALL\n') return True - def user_create(self, user :str, password=None, groups=[], sudo=False): + def user_create(self, user: str, password=None, groups=[], sudo=False): self.log(f'Creating user {user}', level=logging.INFO) o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.target} useradd -m -G wheel {user}')) if password: @@ -500,7 +496,7 @@ 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=logging.INFO) |