Merge pull request #118 from Torxed/torx-fix-profile-issues

Fixed profile issues as well as partition cache issues. Also added some more debug logs for support cases.
This commit is contained in:
Anton Hvornum 2021-03-21 17:52:59 +01:00 committed by GitHub
commit 7c54b4ce72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 8 deletions

View File

@ -129,6 +129,9 @@ class BlockDevice():
return True return True
return False return False
def flush_cache(self):
self.part_cache = OrderedDict()
class Partition(): class Partition():
def __init__(self, path, part_id=None, size=-1, filesystem=None, mountpoint=None, encrypted=False, autodetect_filesystem=True): def __init__(self, path, part_id=None, size=-1, filesystem=None, mountpoint=None, encrypted=False, autodetect_filesystem=True):
if not part_id: if not part_id:
@ -365,7 +368,8 @@ class Filesystem():
if self.blockdevice.keep_partitions is False: if self.blockdevice.keep_partitions is False:
log(f'Wiping {self.blockdevice} by using partition format {self.mode}', level=LOG_LEVELS.Debug) log(f'Wiping {self.blockdevice} by using partition format {self.mode}', level=LOG_LEVELS.Debug)
if self.mode == GPT: if self.mode == GPT:
if sys_command(f'/usr/bin/parted -s {self.blockdevice.device} mklabel gpt',).exit_code == 0: if self.raw_parted(f'{self.blockdevice.device} mklabel gpt').exit_code == 0:
self.blockdevice.flush_cache()
return self return self
else: else:
raise DiskError(f'Problem setting the partition format to GPT:', f'/usr/bin/parted -s {self.blockdevice.device} mklabel gpt') raise DiskError(f'Problem setting the partition format to GPT:', f'/usr/bin/parted -s {self.blockdevice.device} mklabel gpt')
@ -397,7 +401,7 @@ class Filesystem():
def raw_parted(self, string:str): def raw_parted(self, string:str):
x = sys_command(f'/usr/bin/parted -s {string}') x = sys_command(f'/usr/bin/parted -s {string}')
o = b''.join(x) log(f"'parted -s {string}' returned: {b''.join(x)}", level=LOG_LEVELS.Debug)
return x return x
def parted(self, string:str): def parted(self, string:str):

View File

@ -352,6 +352,7 @@ class Installer():
if self.partition.encrypted: if self.partition.encrypted:
log(f"Identifying root partition {self.partition} to boot based on disk UUID, looking for '{os.path.basename(self.partition.real_device)}'.", level=LOG_LEVELS.Debug)
for root, folders, uids in os.walk('/dev/disk/by-uuid'): for root, folders, uids in os.walk('/dev/disk/by-uuid'):
for uid in uids: for uid in uids:
real_path = os.path.realpath(os.path.join(root, uid)) real_path = os.path.realpath(os.path.join(root, uid))
@ -363,6 +364,7 @@ class Installer():
return True return True
break break
else: else:
log(f"Identifying root partition {self.partition} to boot based on partition UUID, looking for '{os.path.basename(self.partition.path)}'.", level=LOG_LEVELS.Debug)
for root, folders, uids in os.walk('/dev/disk/by-partuuid'): for root, folders, uids in os.walk('/dev/disk/by-partuuid'):
for uid in uids: for uid in uids:
real_path = os.path.realpath(os.path.join(root, uid)) real_path = os.path.realpath(os.path.join(root, uid))
@ -373,6 +375,7 @@ class Installer():
self.helper_flags['bootloader'] = bootloader self.helper_flags['bootloader'] = bootloader
return True return True
break 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.") 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: else:
raise RequirementError(f"Unknown (or not yet implemented) bootloader added to add_bootloader(): {bootloader}") raise RequirementError(f"Unknown (or not yet implemented) bootloader added to add_bootloader(): {bootloader}")
@ -381,6 +384,15 @@ 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.
# 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 vriable "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

@ -1,7 +1,7 @@
import os, urllib.request, urllib.parse, ssl, json, re import os, urllib.request, urllib.parse, ssl, json, re
import importlib.util, sys, glob, hashlib import importlib.util, sys, glob, hashlib
from collections import OrderedDict from collections import OrderedDict
from .general import multisplit, sys_command, log from .general import multisplit, sys_command
from .exceptions import * from .exceptions import *
from .networking import * from .networking import *
from .output import log, LOG_LEVELS from .output import log, LOG_LEVELS
@ -76,6 +76,8 @@ class Script():
self.spec = None self.spec = None
self.examples = None self.examples = None
self.namespace = os.path.splitext(os.path.basename(self.path))[0] self.namespace = os.path.splitext(os.path.basename(self.path))[0]
self.original_namespace = self.namespace
log(f"Script {self} has been loaded with namespace '{self.namespace}'", level=LOG_LEVELS.Debug)
def __enter__(self, *args, **kwargs): def __enter__(self, *args, **kwargs):
self.execute() self.execute()
@ -131,14 +133,13 @@ class Script():
self.spec = importlib.util.spec_from_file_location(self.namespace, self.path) self.spec = importlib.util.spec_from_file_location(self.namespace, self.path)
imported = importlib.util.module_from_spec(self.spec) imported = importlib.util.module_from_spec(self.spec)
sys.modules[self.namespace] = imported sys.modules[self.namespace] = imported
return self return self
def execute(self): def execute(self):
if not self.namespace in sys.modules or self.spec is None: if not self.namespace in sys.modules or self.spec is None:
self.load_instructions() self.load_instructions()
__builtins__['installation'] = self.installer # TODO: Replace this with a import archinstall.session instead
self.spec.loader.exec_module(sys.modules[self.namespace]) self.spec.loader.exec_module(sys.modules[self.namespace])
return sys.modules[self.namespace] return sys.modules[self.namespace]
@ -146,7 +147,6 @@ class Script():
class Profile(Script): class Profile(Script):
def __init__(self, installer, path, args={}): def __init__(self, installer, path, args={}):
super(Profile, self).__init__(path, installer) super(Profile, self).__init__(path, installer)
self._cache = None
def __dump__(self, *args, **kwargs): def __dump__(self, *args, **kwargs):
return {'path' : self.path} return {'path' : self.path}
@ -155,6 +155,10 @@ class Profile(Script):
return f'Profile({os.path.basename(self.profile)})' return f'Profile({os.path.basename(self.profile)})'
def install(self): def install(self):
# Before installing, revert any temporary changes to the namespace.
# This ensures that the namespace during installation is the original initation namespace.
# (For instance awesome instead of aweosme.py or app-awesome.py)
self.namespace = self.original_namespace
return self.execute() return self.execute()
def has_prep_function(self): def has_prep_function(self):
@ -202,4 +206,11 @@ class Application(Profile):
elif parsed_url.scheme in ('https', 'http'): elif parsed_url.scheme in ('https', 'http'):
return self.localize_path(self.profile) return self.localize_path(self.profile)
else: else:
raise ProfileNotFound(f"Application cannot handle scheme {parsed_url.scheme}") raise ProfileNotFound(f"Application cannot handle scheme {parsed_url.scheme}")
def install(self):
# Before installing, revert any temporary changes to the namespace.
# This ensures that the namespace during installation is the original initation namespace.
# (For instance awesome instead of aweosme.py or app-awesome.py)
self.namespace = self.original_namespace
return self.execute()

View File

@ -32,7 +32,7 @@ if __name__ == 'awesome':
editor = "nano" editor = "nano"
filebrowser = "nemo gpicview-gtk3" filebrowser = "nemo gpicview-gtk3"
webbrowser = "chromium" # TODO: Ask the user to select one instead webbrowser = "chromium" # TODO: Ask the user to select one instead
utils = "openssh sshfs git htop pkgfile scrot dhclient wget libu2f-host" utils = "openssh sshfs htop scrot wget"
installation.add_additional_packages(f"{webbrowser} {utils} {filebrowser} {editor}") installation.add_additional_packages(f"{webbrowser} {utils} {filebrowser} {editor}")