index : archinstall32 | |
Archlinux32 installer | gitolite user |
summaryrefslogtreecommitdiff |
-rw-r--r-- | PKGBUILD/archinstall-bin/PKGBUILD | 4 | ||||
-rw-r--r-- | PKGBUILD/archinstall/PKGBUILD | 6 | ||||
-rw-r--r-- | PKGBUILD/python-archinstall/PKGBUILD | 4 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | archinstall/__main__.py | 6 | ||||
-rw-r--r-- | archinstall/lib/profiles.py | 157 | ||||
-rw-r--r-- | archinstall/lib/storage.py | 2 | ||||
-rw-r--r-- | docs/conf.py | 4 | ||||
-rw-r--r-- | examples/guided.py | 6 | ||||
-rw-r--r-- | setup.py | 2 |
diff --git a/PKGBUILD/archinstall-bin/PKGBUILD b/PKGBUILD/archinstall-bin/PKGBUILD index 182942f4..00077469 100644 --- a/PKGBUILD/archinstall-bin/PKGBUILD +++ b/PKGBUILD/archinstall-bin/PKGBUILD @@ -1,7 +1,7 @@ # Maintainer: Anton Hvornum anton@hvornum.se # Contributor: Anton Hvornum anton@hvornum.se pkgname="archinstall-bin" -pkgver="2.0.6rc17" +pkgver="2.0.6" pkgdesc="Installs a pre-built binary of ${pkgname}" pkgrel=1 url="https://github.com/Torxed/archinstall" @@ -12,7 +12,7 @@ source=("${pkgname}-v${pkgver}-x86_64.tar.gz::https://github.com/Torxed/archinst #depends=('python>=3.8') makedepends=('python>=3.8' 'nuitka') optdepends=('pyttsx3: Adds text-to-speach support for log/screen output.') -sha256sums=('fb64065af6d26cbe5125452d17887dbb930ff254858ea5dabc9bb543747a6675') +sha256sums=('1a672232194662a90e70b4a5c4a6acfc2c0e027a8fea0699af99110bc17268f5') build() { cd "${pkgname}-${pkgver}" diff --git a/PKGBUILD/archinstall/PKGBUILD b/PKGBUILD/archinstall/PKGBUILD index fd3b1284..34c7703f 100644 --- a/PKGBUILD/archinstall/PKGBUILD +++ b/PKGBUILD/archinstall/PKGBUILD @@ -1,7 +1,7 @@ # Maintainer: Anton Hvornum <anton@hvornum.se> # Contributor: demostanis worlds <demostanis@protonmail.com> pkgname="archinstall" -pkgver="2.0.6rc17" +pkgver="2.0.6" pkgdesc="Installs launcher scripts for archinstall" pkgrel=1 url="https://github.com/Torxed/archinstall" @@ -10,8 +10,8 @@ provides=("${pkgname}") arch=('x86_64') source=("${pkgname}-v${pkgver}-x86_64.tar.gz::https://github.com/Torxed/archinstall/archive/v$pkgver.tar.gz") depends=('python-archinstall') -sha256sums=('fb64065af6d26cbe5125452d17887dbb930ff254858ea5dabc9bb543747a6675') - +sha256sums=('1a672232194662a90e70b4a5c4a6acfc2c0e027a8fea0699af99110bc17268f5') + package() { mkdir -p "${pkgdir}/usr/bin" diff --git a/PKGBUILD/python-archinstall/PKGBUILD b/PKGBUILD/python-archinstall/PKGBUILD index 9fa8a8ad..c0ffd604 100644 --- a/PKGBUILD/python-archinstall/PKGBUILD +++ b/PKGBUILD/python-archinstall/PKGBUILD @@ -2,7 +2,7 @@ # Contributor: demostanis worlds <demostanis@protonmail.com> pkgname="python-archinstall" -pkgver="2.0.6rc17" +pkgver="2.0.6" pkgdesc="Installs ${pkgname} as a python library." pkgrel=1 url="https://github.com/Torxed/archinstall" @@ -13,7 +13,7 @@ arch=('x86_64') depends=('python>=3.8') makedepends=('python-setuptools') optdepends=('pyttsx3: Adds text-to-speech support for log/screen output.') -sha256sums=('fb64065af6d26cbe5125452d17887dbb930ff254858ea5dabc9bb543747a6675') +sha256sums=('1a672232194662a90e70b4a5c4a6acfc2c0e027a8fea0699af99110bc17268f5') build() { cd "archinstall-${pkgver}" @@ -1 +1 @@ -2.0.6rc17
\ No newline at end of file +2.0.6
\ No newline at end of file diff --git a/archinstall/__main__.py b/archinstall/__main__.py index dcf61f58..63c2f715 100644 --- a/archinstall/__main__.py +++ b/archinstall/__main__.py @@ -12,6 +12,9 @@ def run_as_a_module(): This function and the file __main__ acts as a entry point. """ + # Add another path for finding profiles, so that list_profiles() in Script() can find guided.py, unattended.py etc. + archinstall.storage['PROFILE_PATH'].append(os.path.abspath(f'{os.path.dirname(__file__)}/examples')) + if len(sys.argv) == 1: sys.argv.append('guided') @@ -22,6 +25,9 @@ def run_as_a_module(): sys.exit(1) os.chdir(os.path.abspath(os.path.dirname(__file__))) + + # Remove the example directory from the PROFILE_PATH, to avoid guided.py etc shows up in user input questions. + archinstall.storage['PROFILE_PATH'].pop() script.execute() if __name__ == '__main__': diff --git a/archinstall/lib/profiles.py b/archinstall/lib/profiles.py index e83e8346..f9aa206c 100644 --- a/archinstall/lib/profiles.py +++ b/archinstall/lib/profiles.py @@ -15,7 +15,7 @@ def grab_url_data(path): response = urllib.request.urlopen(safe_path, context=ssl_context) return response.read() -def list_profiles(filter_irrelevant_macs=True): +def list_profiles(filter_irrelevant_macs=True, subpath=''): # TODO: Grab from github page as well, not just local static files if filter_irrelevant_macs: local_macs = list_interfaces() @@ -23,7 +23,7 @@ def list_profiles(filter_irrelevant_macs=True): cache = {} # Grab all local profiles found in PROFILE_PATH for PATH_ITEM in storage['PROFILE_PATH']: - for root, folders, files in os.walk(os.path.abspath(os.path.expanduser(PATH_ITEM))): + for root, folders, files in os.walk(os.path.abspath(os.path.expanduser(PATH_ITEM+subpath))): for file in files: if os.path.splitext(file)[1] == '.py': tailored = False @@ -43,7 +43,7 @@ def list_profiles(filter_irrelevant_macs=True): # Grab profiles from upstream URL if storage['PROFILE_DB']: - profiles_url = os.path.join(storage["UPSTREAM_URL"], storage['PROFILE_DB']) + profiles_url = os.path.join(storage["UPSTREAM_URL"]+subpath, storage['PROFILE_DB']) try: profile_list = json.loads(grab_url_data(profiles_url)) except urllib.error.HTTPError as err: @@ -61,33 +61,31 @@ def list_profiles(filter_irrelevant_macs=True): continue tailored = True - cache[profile[:-3]] = {'path' : os.path.join(storage["UPSTREAM_URL"], profile), 'description' : profile_list[profile], 'tailored' : tailored} + cache[profile[:-3]] = {'path' : os.path.join(storage["UPSTREAM_URL"]+subpath, profile), 'description' : profile_list[profile], 'tailored' : tailored} return cache -class Imported(): - def __init__(self, spec, imported): - self.spec = spec - self.imported = imported +class Script(): + def __init__(self, profile, installer=None): + # profile: https://hvornum.se/something.py + # profile: desktop + # profile: /path/to/profile.py + self.profile = profile + self.installer = installer + self.converted_path = None + self.spec = None + self.examples = None + self.namespace = os.path.splitext(os.path.basename(self.path))[0] def __enter__(self, *args, **kwargs): - self.spec.loader.exec_module(self.imported) - return self.imported + self.execute() + return sys.modules[self.namespace] def __exit__(self, *args, **kwargs): # TODO: https://stackoverflow.com/questions/28157929/how-to-safely-handle-an-exception-inside-a-context-manager if len(args) >= 2 and args[1]: raise args[1] - -class Script(): - def __init__(self, profile): - # profile: https://hvornum.se/something.py - # profile: desktop - # profile: /path/to/profile.py - self.profile = profile - self.converted_path = None - def localize_path(self, profile_path): if (url := urllib.parse.urlparse(profile_path)).scheme and url.scheme in ('https', 'http'): if not self.converted_path: @@ -107,101 +105,84 @@ class Script(): # The Profile was not a direct match on a remote URL if not parsed_url.scheme: # Try to locate all local or known URL's - examples = list_profiles() + if not self.examples: + self.examples = list_profiles() - if f"{self.profile}" in examples: - return self.localize_path(examples[self.profile]['path']) + if f"{self.profile}" in self.examples: + return self.localize_path(self.examples[self.profile]['path']) # TODO: Redundant, the below block shouldnt be needed as profiles are stripped of their .py, but just in case for now: - elif f"{self.profile}.py" in examples: - return self.localize_path(examples[f"{self.profile}.py"]['path']) + elif f"{self.profile}.py" in self.examples: + return self.localize_path(self.examples[f"{self.profile}.py"]['path']) # Path was not found in any known examples, check if it's an abolute path if os.path.isfile(self.profile): - return os.path.basename(self.profile) + return self.profile - raise ProfileNotFound(f"File {self.profile} does not exist in {examples}") + raise ProfileNotFound(f"File {self.profile} does not exist in {storage['PROFILE_PATH']}") elif parsed_url.scheme in ('https', 'http'): return self.localize_path(self.profile) else: raise ProfileNotFound(f"Cannot handle scheme {parsed_url.scheme}") + def load_instructions(self, namespace=None): + if namespace: + self.namespace = namespace + + self.spec = importlib.util.spec_from_file_location(self.namespace, self.path) + imported = importlib.util.module_from_spec(self.spec) + sys.modules[self.namespace] = imported + + return self + def execute(self): - spec = importlib.util.spec_from_file_location( - "tempscript", - self.path - ) - imported_path = importlib.util.module_from_spec(spec) - spec.loader.exec_module(imported_path) - sys.modules["tempscript"] = imported_path - -class Profile(): + if not self.namespace in sys.modules or self.spec is None: + 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]) + + return sys.modules[self.namespace] + +class Profile(Script): def __init__(self, installer, path, args={}): - self._path = Script(path) - self.installer = installer + super(Profile, self).__init__(path, installer) self._cache = None - self.args = args def __dump__(self, *args, **kwargs): return {'path' : self.path} def __repr__(self, *args, **kwargs): - return f'Profile({self.path})' - - @property - def path(self, *args, **kwargs): - return self._path.path - - def load_instructions(self, namespace=None): - if (absolute_path := self.path): - if os.path.splitext(absolute_path)[1] == '.py': - if not namespace: - namespace = os.path.splitext(os.path.basename(absolute_path))[0] - spec = importlib.util.spec_from_file_location(namespace, absolute_path) - imported = importlib.util.module_from_spec(spec) - sys.modules[namespace] = imported - return Imported(spec, imported) - else: - raise ProfileError(f'Extension {os.path.splitext(absolute_path)[1]} is not a supported profile model. Only .py is supported.') - - raise ProfileError(f'No such profile ({self.path}) was found either locally or in {storage["UPSTREAM_URL"]}') + return f'Profile({os.path.basename(self.profile)})' def install(self): - # To avoid profiles importing the wrong 'archinstall', - # we need to ensure that this current archinstall is in sys.path - archinstall_path = os.path.abspath(f'{os.path.dirname(__file__)}/../../') - if archinstall_path not in sys.path: - sys.path.insert(0, archinstall_path) - - instructions = self.load_instructions() - if type(instructions) == Imported: - # There's no easy way to give the imported profile the installer instance unless we require the profile-programmer to create a certain function that must be the same for all.. - # Which is a bit inconvenient so we'll make a a truly global installer for now, in the future archinstall main __init__.py should setup the 'installation' variable.. - # but to avoid circular imports and other traps, this works for now. - # TODO: Remove - __builtins__['installation'] = self.installer - with instructions as runtime: - log(f'{self} finished successfully.', bg='black', fg='green', level=LOG_LEVELS.Info, file=storage.get('logfile', None)) - - return True + return self.execute() class Application(Profile): def __repr__(self, *args, **kwargs): - return f'Application({self._path} <"{self.path}">)' + return f'Application({os.path.basename(self.profile)})' @property - def path(self, *args, **kwargs): - if os.path.isfile(f'{self._path}'): - return os.path.abspath(f'{self._path}') + def path(self): + parsed_url = urllib.parse.urlparse(self.profile) - for path in ['./applications', './profiles/applications', '/etc/archinstall/applications', '/etc/archinstall/profiles/applications', os.path.abspath(f'{os.path.dirname(__file__)}/../profiles/applications')]: - if os.path.isfile(f'{path}/{self._path}.py'): - return os.path.abspath(f'{path}/{self._path}.py') + # The Profile was not a direct match on a remote URL + if not parsed_url.scheme: + # Try to locate all local or known URL's + if not self.examples: + self.examples = list_profiles(subpath='/applications') - try: - if (cache := grab_url_data(f'{storage["UPSTREAM_URL"]}/applications/{self._path}.py')): - self._cache = cache - return f'{storage["UPSTREAM_URL"]}/applications/{self._path}.py' - except urllib.error.HTTPError: - pass + if f"{self.profile}" in self.examples: + return self.localize_path(self.examples[self.profile]['path']) + # TODO: Redundant, the below block shouldnt be needed as profiles are stripped of their .py, but just in case for now: + elif f"{self.profile}.py" in self.examples: + return self.localize_path(self.examples[f"{self.profile}.py"]['path']) + + # Path was not found in any known examples, check if it's an abolute path + if os.path.isfile(self.profile): + return os.path.basename(self.profile) - return None
\ No newline at end of file + raise ProfileNotFound(f"Application file {self.profile} does not exist in {storage['PROFILE_PATH']}") + elif parsed_url.scheme in ('https', 'http'): + return self.localize_path(self.profile) + else: + raise ProfileNotFound(f"Application cannot handle scheme {parsed_url.scheme}")
\ No newline at end of file diff --git a/archinstall/lib/storage.py b/archinstall/lib/storage.py index 7c2c2661..3af15153 100644 --- a/archinstall/lib/storage.py +++ b/archinstall/lib/storage.py @@ -12,7 +12,7 @@ storage = { './profiles', '~/.config/archinstall/profiles', os.path.join(os.path.dirname(os.path.abspath(__file__)), 'profiles'), - os.path.abspath(f'{os.path.dirname(__file__)}/../examples') + #os.path.abspath(f'{os.path.dirname(__file__)}/../examples') ], 'UPSTREAM_URL' : 'https://raw.githubusercontent.com/Torxed/archinstall/master/profiles', 'PROFILE_DB' : None # Used in cases when listing profiles is desired, not mandatory for direct profile grabing. diff --git a/docs/conf.py b/docs/conf.py index 02e6cb92..056cf185 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -38,7 +38,7 @@ copyright = '2020, Anton Hvornum' author = 'Anton Hvornum' # The full version, including alpha/beta/rc tags -release = 'v2.0.4' +release = 'v2.0.6' # -- General configuration --------------------------------------------------- @@ -104,7 +104,7 @@ html_show_sourcelink = False #html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'slimhttpdoc' +htmlhelp_basename = 'archinstalldoc' # -- Options for manual page output -------------------------------------------- diff --git a/examples/guided.py b/examples/guided.py index 69162244..3ebdcd14 100644 --- a/examples/guided.py +++ b/examples/guided.py @@ -56,6 +56,8 @@ def perform_installation(device, boot_partition, language, mirrors): if archinstall.storage['_guided']['packages'] and archinstall.storage['_guided']['packages'][0] != '': installation.add_additional_packages(archinstall.storage['_guided']['packages']) + print('Installing:', archinstall.storage['_guided']['profile']['path'].strip()) + time.sleep(10) if 'profile' in archinstall.storage['_guided'] and len(profile := archinstall.storage['_guided']['profile']['path'].strip()): installation.install_profile(profile) @@ -166,8 +168,6 @@ while 1: fg='red' ) continue - - profile = profile[0]._path # Once the prep is done, replace the selected profile with the profile name ("path") given from select_profile() break else: break @@ -226,6 +226,8 @@ archinstall.log("-- Guided template chosen (with below config) --", level=archin archinstall.log(json.dumps(archinstall.storage['_guided'], indent=4, sort_keys=True, cls=archinstall.JSON), level=archinstall.LOG_LEVELS.Info) print() +input('Press Enter to continue.') + """ Issue a final warning before we continue with something un-revertable. We mention the drive one last time, and count from 5 to 0. @@ -23,5 +23,5 @@ setuptools.setup( ], python_requires='>=3.8', setup_requires=['wheel'], - package_data={'archinstall': glob.glob('examples/*.py') + glob.glob('profiles/*.py')}, + package_data={'archinstall': glob.glob('examples/*.py') + glob.glob('profiles/*.py') + glob.glob('profiles/applications/*.py')}, ) |