Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PKGBUILD/archinstall-bin/PKGBUILD4
-rw-r--r--PKGBUILD/archinstall/PKGBUILD6
-rw-r--r--PKGBUILD/python-archinstall/PKGBUILD4
-rw-r--r--VERSION2
-rw-r--r--archinstall/__main__.py6
-rw-r--r--archinstall/lib/profiles.py157
-rw-r--r--archinstall/lib/storage.py2
-rw-r--r--docs/conf.py4
-rw-r--r--examples/guided.py6
-rw-r--r--setup.py2
10 files changed, 91 insertions, 102 deletions
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}"
diff --git a/VERSION b/VERSION
index 1dcea3bb..703cec9e 100644
--- a/VERSION
+++ b/VERSION
@@ -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.
diff --git a/setup.py b/setup.py
index b0a08afd..02029a70 100644
--- a/setup.py
+++ b/setup.py
@@ -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')},
)