Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/archinstall/lib
diff options
context:
space:
mode:
authorAnton Hvornum <anton.feeds+github@gmail.com>2020-07-22 01:03:14 +0000
committerAnton Hvornum <anton.feeds+github@gmail.com>2020-07-22 01:03:14 +0000
commit0cd088572d4c9a45711eb7a358cb4c2edd98e450 (patch)
tree19d3a2664050dbf35fd2b76b862d94c9f260f412 /archinstall/lib
parentc884a2523746892d15257b68f6f3681119681cf3 (diff)
New feature: application profiles now support .py as well. Also fixed a sys.path issue where an installed version of archinstall would have precedence over the local version when profiles were being executed (because profiles were living in a unknown relative working directory, the caller to those profiles have to make sure .archinstall exists in sys.path before calling said profile)
Diffstat (limited to 'archinstall/lib')
-rw-r--r--archinstall/lib/installer.py10
-rw-r--r--archinstall/lib/profiles.py34
2 files changed, 36 insertions, 8 deletions
diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py
index 90849bf2..9247c635 100644
--- a/archinstall/lib/installer.py
+++ b/archinstall/lib/installer.py
@@ -91,6 +91,12 @@ class Installer():
o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} ln -s /usr/share/zoneinfo/{zone} /etc/localtime'))
return True
+ def run_command(self, cmd):
+ return sys_command(f'/usr/bin/arch-chroot {self.mountpoint} {cmd}')
+
+ def arch_chroot(self, cmd):
+ return self.run_command(cmd)
+
def minimal_installation(self):
self.pacstrap('base base-devel linux linux-firmware btrfs-progs efibootmgr nano'.split(' '))
self.genfstab()
@@ -158,13 +164,13 @@ class Installer():
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_additional_packages(self, *packages):
- self.pacstrap(*packages)
+ return self.pacstrap(*packages)
def install_profile(self, profile):
profile = Profile(self, profile)
log(f'Installing network profile {profile}')
- profile.install()
+ return profile.install()
def user_create(self, user :str, password=None, groups=[]):
log(f'Creating user {user}')
diff --git a/archinstall/lib/profiles.py b/archinstall/lib/profiles.py
index 07bd3fd4..c1e2f8a9 100644
--- a/archinstall/lib/profiles.py
+++ b/archinstall/lib/profiles.py
@@ -40,6 +40,9 @@ class Profile():
@property
def path(self, *args, **kwargs):
+ if os.path.isfile(f'{self.name}'):
+ return os.path.abspath(f'{self.name}')
+
for path in ['./profiles', '/etc/archinstall', '/etc/archinstall/profiles', os.path.abspath(f'{os.path.dirname(__file__)}/../profiles')]: # Step out of /lib
if os.path.isfile(f'{path}/{self.name}.json'):
return os.path.abspath(f'{path}/{self.name}.json')
@@ -86,11 +89,21 @@ class Profile():
raise ProfileError(f'No such profile ({self.name}) was found either locally or in {UPSTREAM_URL}')
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 not archinstall_path in sys.path:
+ sys.path.insert(0, archinstall_path)
+
instructions = self.load_instructions()
if type(instructions) == Imported:
- __builtins__['installation'] = self.installer # 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 lets just make it truly global
+ # 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'Profile {self.name} finished successfully.')
+ log(f'Profile {self.name} finished successfully.', bg='black', fg='green')
else:
if 'args' in instructions:
self.args = instructions['args']
@@ -163,18 +176,27 @@ class Profile():
if type(instructions[title][raw_command]) == bytes and len(instructions['post'][title][raw_command]) and not instructions['post'][title][raw_command] in o:
log(f'{command} failed: {o.decode("UTF-8")}')
log('[W] Post install command failed: {}'.format(o.decode('UTF-8')))
+ return True
class Application(Profile):
+ def __repr__(self, *args, **kwargs):
+ return f'Application({self.name} <"{self.path}">)'
+
@property
def path(self, *args, **kwargs):
- for path in ['./applications', './profiles/applications', '/etc/archinstall/applications', '/etc/archinstall/profiles/applications']:
- if os.path.isfile(f'{path}/{self.name}.json'):
+ if os.path.isfile(f'{self.name}'):
+ return os.path.abspath(f'{self.name}')
+
+ 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.name}.py'):
+ return os.path.abspath(f'{path}/{self.name}.py')
+ elif os.path.isfile(f'{path}/{self.name}.json'):
return os.path.abspath(f'{path}/{self.name}.json')
try:
- if (cache := grab_url_data(f'{UPSTREAM_URL}/{self.name}.json')):
+ if (cache := grab_url_data(f'{UPSTREAM_URL}/applications/{self.name}.py')):
self._cache = cache
- return f'{UPSTREAM_URL}/{self.name}.json'
+ return f'{UPSTREAM_URL}/applications/{self.name}.py'
except urllib.error.HTTPError:
pass
try: