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)
This commit is contained in:
parent
c884a25237
commit
0cd088572d
|
|
@ -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'))
|
o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} ln -s /usr/share/zoneinfo/{zone} /etc/localtime'))
|
||||||
return True
|
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):
|
def minimal_installation(self):
|
||||||
self.pacstrap('base base-devel linux linux-firmware btrfs-progs efibootmgr nano'.split(' '))
|
self.pacstrap('base base-devel linux linux-firmware btrfs-progs efibootmgr nano'.split(' '))
|
||||||
self.genfstab()
|
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.')
|
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):
|
def add_additional_packages(self, *packages):
|
||||||
self.pacstrap(*packages)
|
return self.pacstrap(*packages)
|
||||||
|
|
||||||
def install_profile(self, profile):
|
def install_profile(self, profile):
|
||||||
profile = Profile(self, profile)
|
profile = Profile(self, profile)
|
||||||
|
|
||||||
log(f'Installing network profile {profile}')
|
log(f'Installing network profile {profile}')
|
||||||
profile.install()
|
return profile.install()
|
||||||
|
|
||||||
def user_create(self, user :str, password=None, groups=[]):
|
def user_create(self, user :str, password=None, groups=[]):
|
||||||
log(f'Creating user {user}')
|
log(f'Creating user {user}')
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,9 @@ class Profile():
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def path(self, *args, **kwargs):
|
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
|
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'):
|
if os.path.isfile(f'{path}/{self.name}.json'):
|
||||||
return os.path.abspath(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}')
|
raise ProfileError(f'No such profile ({self.name}) was found either locally or in {UPSTREAM_URL}')
|
||||||
|
|
||||||
def install(self):
|
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()
|
instructions = self.load_instructions()
|
||||||
if type(instructions) == Imported:
|
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:
|
with instructions as runtime:
|
||||||
log(f'Profile {self.name} finished successfully.')
|
log(f'Profile {self.name} finished successfully.', bg='black', fg='green')
|
||||||
else:
|
else:
|
||||||
if 'args' in instructions:
|
if 'args' in instructions:
|
||||||
self.args = instructions['args']
|
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:
|
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(f'{command} failed: {o.decode("UTF-8")}')
|
||||||
log('[W] Post install command failed: {}'.format(o.decode('UTF-8')))
|
log('[W] Post install command failed: {}'.format(o.decode('UTF-8')))
|
||||||
|
return True
|
||||||
|
|
||||||
class Application(Profile):
|
class Application(Profile):
|
||||||
|
def __repr__(self, *args, **kwargs):
|
||||||
|
return f'Application({self.name} <"{self.path}">)'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def path(self, *args, **kwargs):
|
def path(self, *args, **kwargs):
|
||||||
for path in ['./applications', './profiles/applications', '/etc/archinstall/applications', '/etc/archinstall/profiles/applications']:
|
if os.path.isfile(f'{self.name}'):
|
||||||
if os.path.isfile(f'{path}/{self.name}.json'):
|
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')
|
return os.path.abspath(f'{path}/{self.name}.json')
|
||||||
|
|
||||||
try:
|
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
|
self._cache = cache
|
||||||
return f'{UPSTREAM_URL}/{self.name}.json'
|
return f'{UPSTREAM_URL}/applications/{self.name}.py'
|
||||||
except urllib.error.HTTPError:
|
except urllib.error.HTTPError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
import archinstall
|
||||||
|
|
||||||
|
installation.add_additional_packages("awesome xorg-server xorg-xrandr xorg-xinit xterm feh slock xscreensaver terminus-font-otb gnu-free-fonts ttf-liberation xsel")
|
||||||
|
|
||||||
|
with open(f'{installation.mountpoint}/etc/X11/xinit/xinitrc', 'r') as xinitrc:
|
||||||
|
xinitrc_data = xinitrc.read()
|
||||||
|
|
||||||
|
xinitrc_data = xinitrc_data.replace('twm &', '# twm &').replace('\nxclock ', '\n# xclock').replace('exec xterm', '# exec xterm')
|
||||||
|
xinitrc_data += '\nxscreensaver -no-splash &\n'
|
||||||
|
xinitrc_data += 'exec awesome\n'
|
||||||
|
with open(f'{installation.mountpoint}/etc/X11/xinit/xinitrc', 'w') as xinitrc:
|
||||||
|
xinitrc.write(xinitrc_data)
|
||||||
|
|
||||||
|
with open(f'{installation.mountpoint}/etc/xdg/awesome/rc.lua', 'r') as awesome_rc_lua:
|
||||||
|
awesome = awesome_rc_lua.read()
|
||||||
|
|
||||||
|
awesome = awesome.replace('xterm', 'xterm -ls -xrm "XTerm*selectToClipboard: true"')
|
||||||
|
awesome = awesome.replace('{ "open terminal", terminal, ','{ "Chromium", "chromium" },\n "open terminal", terminal, ')
|
||||||
|
awesome = awesome.replace('{ "open terminal", terminal, ', '{ "File handler", "nemo" },\n "open terminal", terminal, ')
|
||||||
|
awesome = awesome.replace('\nglobalkeys = gears.table.join(', 'globalkeys = gears.table.join(\n awful.key({ modkey, }, \"l\", function() awful.spawn(\"xscreensaver-command -lock &\") end),\n')
|
||||||
|
# "awk -i inplace -v RS='' '{gsub(/awful.key\\({ modkey,.*?}, \"Tab\",.*?\"client\"}\\),/, \"awful.key({ modkey, }, \"Tab\",\n function ()\n awful.client.focus.byidx(-1)\n if client.focus then\n client.focus:raise()\n end\n end),\n awful.key({ modkey, \"Shift\" }, \"Tab\",\n function ()\n awful.client.focus.byidx(1)\n if client.focus then\n client.focus.raise()\n end\n end),\"); print}' {installation.mountpoint}/etc/xdg/awesome/rc.lua" : {"no-chroot" : true},
|
||||||
|
|
||||||
|
with open(f'{installation.mountpoint}/etc/xdg/awesome/rc.lua', 'w') as awesome_rc_lua:
|
||||||
|
awesome_rc_lua.write(awesome)
|
||||||
|
|
||||||
|
installation.arch_chroot('gsettings set org.nemo.desktop show-desktop-icons false')
|
||||||
|
installation.arch_chroot('xdg-mime default nemo.desktop inode/directory application/x-gnome-saved-search')
|
||||||
|
|
@ -7,14 +7,12 @@ arguments = {
|
||||||
"filebrowser" : "nemo gpicview-gtk3",
|
"filebrowser" : "nemo gpicview-gtk3",
|
||||||
"webbrowser" : "chromium",
|
"webbrowser" : "chromium",
|
||||||
"window_manager" : "awesome",
|
"window_manager" : "awesome",
|
||||||
"window_manager_dependencies" : "xorg-server xorg-xrandr xorg-xinit xterm",
|
|
||||||
"window_manager_utilities" : "feh slock xscreensaver terminus-font-otb gnu-free-fonts ttf-liberation xsel",
|
|
||||||
"virtulization" : "qemu ovmf",
|
"virtulization" : "qemu ovmf",
|
||||||
"utils" : "openssh sshfs git htop pkgfile scrot dhclient wget smbclient cifs-utils libu2f-host",
|
"utils" : "openssh sshfs git htop pkgfile scrot dhclient wget smbclient cifs-utils libu2f-host",
|
||||||
"audio" : "pulseaudio pulseaudio-alsa pavucontrol"
|
"audio" : "pulseaudio pulseaudio-alsa pavucontrol"
|
||||||
}
|
}
|
||||||
|
|
||||||
installation.add_additional_packages("{_webbrowser} {_utils} {_mediaplayer} {_window_manager} {_window_manager_dependencies} {_window_manager_utilities} {_virtulization} {_filebrowser} {_editor}".format(**arguments))
|
installation.add_additional_packages("{webbrowser} {utils} {mediaplayer} {window_manager} {virtulization} {filebrowser} {editor}".format(**arguments))
|
||||||
|
|
||||||
with open(f'{installation.mountpoint}/etc/X11/xinit/xinitrc', 'a') as X11:
|
with open(f'{installation.mountpoint}/etc/X11/xinit/xinitrc', 'a') as X11:
|
||||||
X11.write('setxkbmap se\n')
|
X11.write('setxkbmap se\n')
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue