index : archinstall32 | |
Archlinux32 installer | gitolite user |
summaryrefslogtreecommitdiff |
-rw-r--r-- | archinstall/lib/installer.py | 132 |
diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 99d8f2b9..775de50a 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -1,4 +1,4 @@ -import os, stat +import os, stat, time from .exceptions import * from .disk import * @@ -6,6 +6,8 @@ from .general import * from .user_interaction import * from .profiles import Profile from .mirrors import * +from .output import log, LOG_LEVELS +from .storage import storage class Installer(): """ @@ -35,6 +37,8 @@ class Installer(): self.profile = profile self.hostname = hostname self.mountpoint = mountpoint + self.init_time = time.strftime('%Y-%m-%d_%H-%M-%S') + self.milliseconds = int(str(time.time()).split('.')[1]) self.helper_flags = { 'bootloader' : False, @@ -43,10 +47,24 @@ class Installer(): } self.base_packages = base_packages.split(' ') + storage['session'] = self self.partition = partition self.boot_partition = boot_partition + def log(self, *args, level=LOG_LEVELS.Debug, file=None, **kwargs): + if not file: + if 'logfile' not in storage: + log_root = os.path.join(os.path.expanduser('~/'), '.cache/archinstall') + if not os.path.isdir(log_root): + os.makedirs(log_root) + + storage['logfile'] = f"{log_root}/install-session_{self.init_time}.{self.milliseconds}.log" + + file = storage['logfile'] + + log(*args, level=level, file=file, **kwargs) + def __enter__(self, *args, **kwargs): self.partition.mount(self.mountpoint) os.makedirs(f'{self.mountpoint}/boot', exist_ok=True) @@ -60,12 +78,14 @@ class Installer(): raise args[1] if not (missing_steps := self.post_install_check()): - log('Installation completed without any errors. You may now reboot.', bg='black', fg='green') + self.log('Installation completed without any errors. You may now reboot.', bg='black', fg='green', level=LOG_LEVELS.Info) return True else: - log('Some required steps were not successfully installed/configured before leaving the installer:', bg='black', fg='red') + self.log('Some required steps were not successfully installed/configured before leaving the installer:', bg='black', fg='red', level=LOG_LEVELS.Warning) for step in missing_steps: - log(f' - {step}', bg='black', fg='red') + self.log(f' - {step}', bg='black', fg='red', level=LOG_LEVELS.Warning) + self.log(f"Detailed error logs can be found at: {log_path}", level=LOG_LEVELS.Warning) + self.log(f"Submit this zip file as an issue to https://github.com/Torxed/archinstall/issues", level=LOG_LEVELS.Warning) return False def post_install_check(self, *args, **kwargs): @@ -73,15 +93,15 @@ class Installer(): def pacstrap(self, *packages, **kwargs): if type(packages[0]) in (list, tuple): packages = packages[0] - log(f'Installing packages: {packages}') + self.log(f'Installing packages: {packages}', level=LOG_LEVELS.Info) if (sync_mirrors := sys_command('/usr/bin/pacman -Syy')).exit_code == 0: if (pacstrap := sys_command(f'/usr/bin/pacstrap {self.mountpoint} {" ".join(packages)}', **kwargs)).exit_code == 0: return True else: - log(f'Could not strap in packages: {pacstrap.exit_code}') + self.log(f'Could not strap in packages: {pacstrap.exit_code}', level=LOG_LEVELS.Info) else: - log(f'Could not sync mirrors: {sync_mirrors.exit_code}') + self.log(f'Could not sync mirrors: {sync_mirrors.exit_code}', level=LOG_LEVELS.Info) def set_mirrors(self, mirrors): return use_mirrors(mirrors, destination=f'{self.mountpoint}/etc/pacman.d/mirrorlist') @@ -114,13 +134,13 @@ class Installer(): return True def activate_ntp(self): - log(f'Installing and activating NTP.') + self.log(f'Installing and activating NTP.', level=LOG_LEVELS.Info) if self.pacstrap('ntp'): if self.enable_service('ntpd'): return True def enable_service(self, service): - log(f'Enabling service {service}') + self.log(f'Enabling service {service}', level=LOG_LEVELS.Info) return self.arch_chroot(f'systemctl enable {service}').exit_code == 0 def run_command(self, cmd, *args, **kwargs): @@ -168,47 +188,51 @@ class Installer(): self.helper_flags['base'] = True return True - def add_bootloader(self): - log(f'Adding bootloader to {self.boot_partition}') - o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} bootctl --no-variables --path=/boot install')) - with open(f'{self.mountpoint}/boot/loader/loader.conf', 'w') as loader: - loader.write('default arch\n') - loader.write('timeout 5\n') - - ## 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() - with open(f'{self.mountpoint}/boot/loader/entries/arch.conf', 'w') as entry: - entry.write('title Arch Linux\n') - entry.write('linux /vmlinuz-linux\n') - entry.write('initrd /initramfs-linux.img\n') - ## blkid doesn't trigger on loopback devices really well, - ## so we'll use the old manual method until we get that sorted out. - - - if self.partition.encrypted: - for root, folders, uids in os.walk('/dev/disk/by-uuid'): - for uid in uids: - real_path = os.path.realpath(os.path.join(root, uid)) - if not os.path.basename(real_path) == os.path.basename(self.partition.real_device): continue - - entry.write(f'options cryptdevice=UUID={uid}:luksdev root=/dev/mapper/luksdev rw intel_pstate=no_hwp\n') - - self.helper_flags['bootloader'] = True - return True - break - else: - for root, folders, uids in os.walk('/dev/disk/by-partuuid'): - for uid in uids: - real_path = os.path.realpath(os.path.join(root, uid)) - if not os.path.basename(real_path) == os.path.basename(self.partition.path): continue - - entry.write(f'options root=PARTUUID={uid} rw intel_pstate=no_hwp\n') - - self.helper_flags['bootloader'] = True - return True - break - raise RequirementError(f'Could not identify the UUID of {self.partition}, there for {self.mountpoint}/boot/loader/entries/arch.conf will be broken until fixed.') + def add_bootloader(self, bootloader='systemd-bootctl'): + self.log(f'Adding bootloader {bootloader} to {self.boot_partition}', level=LOG_LEVELS.Info) + + if bootloader == 'systemd-bootctl': + o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} bootctl --no-variables --path=/boot install')) + with open(f'{self.mountpoint}/boot/loader/loader.conf', 'w') as loader: + loader.write('default arch\n') + loader.write('timeout 5\n') + + ## 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() + with open(f'{self.mountpoint}/boot/loader/entries/arch.conf', 'w') as entry: + entry.write('title Arch Linux\n') + entry.write('linux /vmlinuz-linux\n') + entry.write('initrd /initramfs-linux.img\n') + ## blkid doesn't trigger on loopback devices really well, + ## so we'll use the old manual method until we get that sorted out. + + + if self.partition.encrypted: + for root, folders, uids in os.walk('/dev/disk/by-uuid'): + for uid in uids: + real_path = os.path.realpath(os.path.join(root, uid)) + if not os.path.basename(real_path) == os.path.basename(self.partition.real_device): continue + + entry.write(f'options cryptdevice=UUID={uid}:luksdev root=/dev/mapper/luksdev rw intel_pstate=no_hwp\n') + + self.helper_flags['bootloader'] = bootloader + return True + break + else: + for root, folders, uids in os.walk('/dev/disk/by-partuuid'): + for uid in uids: + real_path = os.path.realpath(os.path.join(root, uid)) + if not os.path.basename(real_path) == os.path.basename(self.partition.path): continue + + entry.write(f'options root=PARTUUID={uid} rw intel_pstate=no_hwp\n') + + self.helper_flags['bootloader'] = bootloader + return True + break + raise RequirementError(f"Could not identify the UUID of {self.partition}, there for {self.mountpoint}/boot/loader/entries/arch.conf will be broken until fixed.") + else: + raise RequirementError(f"Unknown (or not yet implemented) bootloader added to add_bootloader(): {bootloader}") def add_additional_packages(self, *packages): return self.pacstrap(*packages) @@ -216,17 +240,17 @@ class Installer(): def install_profile(self, profile): profile = Profile(self, profile) - log(f'Installing network profile {profile}') + self.log(f'Installing network profile {profile}', level=LOG_LEVELS.Info) return profile.install() def enable_sudo(self, entity :str, group=False): - log(f'Enabling sudo permissions for {entity}.') + self.log(f'Enabling sudo permissions for {entity}.', level=LOG_LEVELS.Info) with open(f'{self.mountpoint}/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): - log(f'Creating user {user}') + self.log(f'Creating user {user}', level=LOG_LEVELS.Info) o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} useradd -m -G wheel {user}')) if password: self.user_set_pw(user, password) @@ -239,7 +263,7 @@ class Installer(): self.helper_flags['user'] = True def user_set_pw(self, user, password): - log(f'Setting password for {user}') + self.log(f'Setting password for {user}', level=LOG_LEVELS.Info) if user == 'root': # This means the root account isn't locked/disabled with * in /etc/passwd |