Merge pull request #95 from Torxed/improved-logging
Tested and verified on a installation. Log file ends up and on errors there's a message printing guiding users to look for it and report issues :)
This commit is contained in:
commit
6cac9b8610
|
|
@ -119,7 +119,7 @@ class Partition():
|
||||||
return f'Partition(path={self.path}, fs={self.filesystem}, mounted={self.mountpoint})'
|
return f'Partition(path={self.path}, fs={self.filesystem}, mounted={self.mountpoint})'
|
||||||
|
|
||||||
def format(self, filesystem):
|
def format(self, filesystem):
|
||||||
log(f'Formatting {self} -> {filesystem}', level=LOG_LEVELS.Info, file=storage.get('logfile', None))
|
log(f'Formatting {self} -> {filesystem}', level=LOG_LEVELS.Info)
|
||||||
if filesystem == 'btrfs':
|
if filesystem == 'btrfs':
|
||||||
o = b''.join(sys_command(f'/usr/bin/mkfs.btrfs -f {self.path}'))
|
o = b''.join(sys_command(f'/usr/bin/mkfs.btrfs -f {self.path}'))
|
||||||
if b'UUID' not in o:
|
if b'UUID' not in o:
|
||||||
|
|
@ -162,7 +162,7 @@ class Partition():
|
||||||
|
|
||||||
def mount(self, target, fs=None, options=''):
|
def mount(self, target, fs=None, options=''):
|
||||||
if not self.mountpoint:
|
if not self.mountpoint:
|
||||||
log(f'Mounting {self} to {target}', level=LOG_LEVELS.Info, file=storage.get('logfile', None))
|
log(f'Mounting {self} to {target}', level=LOG_LEVELS.Info)
|
||||||
if not fs:
|
if not fs:
|
||||||
if not self.filesystem: raise DiskError(f'Need to format (or define) the filesystem on {self} before mounting.')
|
if not self.filesystem: raise DiskError(f'Need to format (or define) the filesystem on {self} before mounting.')
|
||||||
fs = self.filesystem
|
fs = self.filesystem
|
||||||
|
|
@ -227,7 +227,7 @@ class Filesystem():
|
||||||
self.add_partition('primary', start='513MiB', end='100%', format='ext4')
|
self.add_partition('primary', start='513MiB', end='100%', format='ext4')
|
||||||
|
|
||||||
def add_partition(self, type, start, end, format=None):
|
def add_partition(self, type, start, end, format=None):
|
||||||
log(f'Adding partition to {self.blockdevice}', level=LOG_LEVELS.Info, file=storage.get('logfile', None))
|
log(f'Adding partition to {self.blockdevice}', level=LOG_LEVELS.Info)
|
||||||
|
|
||||||
previous_partitions = self.blockdevice.partitions
|
previous_partitions = self.blockdevice.partitions
|
||||||
if format:
|
if format:
|
||||||
|
|
|
||||||
|
|
@ -245,9 +245,9 @@ class sys_command():#Thread):
|
||||||
self.exit_code = 0
|
self.exit_code = 0
|
||||||
|
|
||||||
if self.exit_code != 0 and not self.kwargs['suppress_errors']:
|
if self.exit_code != 0 and not self.kwargs['suppress_errors']:
|
||||||
self.log(f"'{self.raw_cmd}' did not exit gracefully, exit code {self.exit_code}.", level=LOG_LEVELS.Error)
|
#self.log(self.trace_log.decode('UTF-8'), level=LOG_LEVELS.Debug)
|
||||||
self.log(self.trace_log.decode('UTF-8'), level=LOG_LEVELS.Debug)
|
#self.log(f"'{self.raw_cmd}' did not exit gracefully, exit code {self.exit_code}.", level=LOG_LEVELS.Error)
|
||||||
raise SysCallError(f"'{self.raw_cmd}' did not exit gracefully, exit code {self.exit_code}.\n{self.trace_log.decode('UTF-8')}")
|
raise SysCallError(f"{self.trace_log.decode('UTF-8')}\n'{self.raw_cmd}' did not exit gracefully (trace log above), exit code: {self.exit_code}")
|
||||||
|
|
||||||
self.ended = time.time()
|
self.ended = time.time()
|
||||||
with open(f'{self.cwd}/trace.log', 'wb') as fh:
|
with open(f'{self.cwd}/trace.log', 'wb') as fh:
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,18 @@ class Installer():
|
||||||
:type hostname: str, optional
|
:type hostname: str, optional
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, partition, boot_partition, *, base_packages='base base-devel linux linux-firmware efibootmgr nano', profile=None, mountpoint='/mnt', hostname='ArchInstalled'):
|
def __init__(self, partition, boot_partition, *, base_packages='base base-devel linux linux-firmware efibootmgr nano', profile=None, mountpoint='/mnt', hostname='ArchInstalled', logdir=None, logfile=None):
|
||||||
self.profile = profile
|
self.profile = profile
|
||||||
self.hostname = hostname
|
self.hostname = hostname
|
||||||
self.mountpoint = mountpoint
|
self.mountpoint = mountpoint
|
||||||
self.init_time = time.strftime('%Y-%m-%d_%H-%M-%S')
|
self.init_time = time.strftime('%Y-%m-%d_%H-%M-%S')
|
||||||
self.milliseconds = int(str(time.time()).split('.')[1])
|
self.milliseconds = int(str(time.time()).split('.')[1])
|
||||||
|
|
||||||
|
if logdir:
|
||||||
|
storage['LOG_PATH'] = logdir
|
||||||
|
if logfile:
|
||||||
|
storage['LOG_FILE'] = logfile
|
||||||
|
|
||||||
self.helper_flags = {
|
self.helper_flags = {
|
||||||
'bootloader' : False,
|
'bootloader' : False,
|
||||||
'base' : False,
|
'base' : False,
|
||||||
|
|
@ -54,18 +59,12 @@ class Installer():
|
||||||
self.partition = partition
|
self.partition = partition
|
||||||
self.boot_partition = boot_partition
|
self.boot_partition = boot_partition
|
||||||
|
|
||||||
def log(self, *args, level=LOG_LEVELS.Debug, file=None, **kwargs):
|
def log(self, *args, level=LOG_LEVELS.Debug, **kwargs):
|
||||||
if not file:
|
"""
|
||||||
if 'logfile' not in storage:
|
installer.log() wraps output.log() mainly to set a default log-level for this install session.
|
||||||
log_root = os.path.join(os.path.expanduser('~/'), '.cache/archinstall')
|
Any manual override can be done per log() call.
|
||||||
if not os.path.isdir(log_root):
|
"""
|
||||||
os.makedirs(log_root)
|
log(*args, level=level, **kwargs)
|
||||||
|
|
||||||
storage['logfile'] = f"{log_root}/install-session_{self.init_time}.{self.milliseconds}.log"
|
|
||||||
|
|
||||||
file = storage['logfile']
|
|
||||||
|
|
||||||
log(*args, level=level, file=file, **kwargs)
|
|
||||||
|
|
||||||
def __enter__(self, *args, **kwargs):
|
def __enter__(self, *args, **kwargs):
|
||||||
self.partition.mount(self.mountpoint)
|
self.partition.mount(self.mountpoint)
|
||||||
|
|
@ -76,13 +75,24 @@ class Installer():
|
||||||
def __exit__(self, *args, **kwargs):
|
def __exit__(self, *args, **kwargs):
|
||||||
# b''.join(sys_command(f'sync')) # No need to, since the underlaying fs() object will call sync.
|
# b''.join(sys_command(f'sync')) # No need to, since the underlaying fs() object will call sync.
|
||||||
# TODO: https://stackoverflow.com/questions/28157929/how-to-safely-handle-an-exception-inside-a-context-manager
|
# TODO: https://stackoverflow.com/questions/28157929/how-to-safely-handle-an-exception-inside-a-context-manager
|
||||||
|
|
||||||
if len(args) >= 2 and args[1]:
|
if len(args) >= 2 and args[1]:
|
||||||
|
#self.log(self.trace_log.decode('UTF-8'), level=LOG_LEVELS.Debug)
|
||||||
|
self.log(args[1], level=LOG_LEVELS.Error)
|
||||||
|
|
||||||
|
self.sync_log_to_install_medium()
|
||||||
|
|
||||||
|
# We avoid printing /mnt/<log path> because that might confuse people if they note it down
|
||||||
|
# and then reboot, and a identical log file will be found in the ISO medium anyway.
|
||||||
|
print(f"[!] A log file has been created here: {os.path.join(storage['LOG_PATH'], storage['LOG_FILE'])}")
|
||||||
|
print(f" Please submit this issue (and file) to https://github.com/Torxed/archinstall/issues")
|
||||||
raise args[1]
|
raise args[1]
|
||||||
|
|
||||||
self.genfstab()
|
self.genfstab()
|
||||||
|
|
||||||
if not (missing_steps := self.post_install_check()):
|
if not (missing_steps := self.post_install_check()):
|
||||||
self.log('Installation completed without any errors. You may now reboot.', bg='black', fg='green', level=LOG_LEVELS.Info)
|
self.log('Installation completed without any errors. You may now reboot.', bg='black', fg='green', level=LOG_LEVELS.Info)
|
||||||
|
self.sync_log_to_install_medium()
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
self.log('Some required steps were not successfully installed/configured before leaving the installer:', bg='black', fg='red', level=LOG_LEVELS.Warning)
|
self.log('Some required steps were not successfully installed/configured before leaving the installer:', bg='black', fg='red', level=LOG_LEVELS.Warning)
|
||||||
|
|
@ -90,8 +100,23 @@ class Installer():
|
||||||
self.log(f' - {step}', bg='black', fg='red', level=LOG_LEVELS.Warning)
|
self.log(f' - {step}', bg='black', fg='red', level=LOG_LEVELS.Warning)
|
||||||
self.log(f"Detailed error logs can be found at: {log_path}", level=LOG_LEVELS.Warning)
|
self.log(f"Detailed error logs can be found at: {log_path}", level=LOG_LEVELS.Warning)
|
||||||
self.log(f"Submit this zip file as an issue to https://github.com/Torxed/archinstall/issues", level=LOG_LEVELS.Warning)
|
self.log(f"Submit this zip file as an issue to https://github.com/Torxed/archinstall/issues", level=LOG_LEVELS.Warning)
|
||||||
|
self.sync_log_to_install_medium()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def sync_log_to_install_medium(self):
|
||||||
|
# Copy over the install log (if there is one) to the install medium if
|
||||||
|
# at least the base has been strapped in, otherwise we won't have a filesystem/structure to copy to.
|
||||||
|
if self.helper_flags.get('base-strapped', False) is True:
|
||||||
|
if (filename := storage.get('LOG_FILE', None)):
|
||||||
|
absolute_logfile = os.path.join(storage.get('LOG_PATH', './'), filename)
|
||||||
|
|
||||||
|
if not os.path.isdir(f"{self.mountpoint}/{os.path.dirname(absolute_logfile)}"):
|
||||||
|
os.makedirs(f"{self.mountpoint}/{os.path.dirname(absolute_logfile)}")
|
||||||
|
|
||||||
|
shutil.copy2(absolute_logfile, f"{self.mountpoint}/{absolute_logfile}")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def mount(self, partition, mountpoint, create_mountpoint=True):
|
def mount(self, partition, mountpoint, create_mountpoint=True):
|
||||||
if create_mountpoint and not os.path.isdir(f'{self.mountpoint}{mountpoint}'):
|
if create_mountpoint and not os.path.isdir(f'{self.mountpoint}{mountpoint}'):
|
||||||
os.makedirs(f'{self.mountpoint}{mountpoint}')
|
os.makedirs(f'{self.mountpoint}{mountpoint}')
|
||||||
|
|
@ -235,6 +260,7 @@ class Installer():
|
||||||
if self.partition.filesystem == 'xfs':
|
if self.partition.filesystem == 'xfs':
|
||||||
self.base_packages.append('xfsprogs')
|
self.base_packages.append('xfsprogs')
|
||||||
self.pacstrap(self.base_packages)
|
self.pacstrap(self.base_packages)
|
||||||
|
self.helper_flags['base-strapped'] = True
|
||||||
#self.genfstab()
|
#self.genfstab()
|
||||||
|
|
||||||
with open(f"{self.mountpoint}/etc/fstab", "a") as fstab:
|
with open(f"{self.mountpoint}/etc/fstab", "a") as fstab:
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ class luks2():
|
||||||
def encrypt(self, partition, password, key_size=512, hash_type='sha512', iter_time=10000, key_file=None):
|
def encrypt(self, partition, password, key_size=512, hash_type='sha512', iter_time=10000, key_file=None):
|
||||||
# TODO: We should be able to integrate this into the main log some how.
|
# TODO: We should be able to integrate this into the main log some how.
|
||||||
# Perhaps post-mortem?
|
# Perhaps post-mortem?
|
||||||
log(f'Encrypting {partition}', level=LOG_LEVELS.Info, file=storage.get('logfile', None))
|
log(f'Encrypting {partition} (This might take a while)', level=LOG_LEVELS.Info)
|
||||||
|
|
||||||
if not key_file:
|
if not key_file:
|
||||||
key_file = f"/tmp/{os.path.basename(self.partition.path)}.disk_pw" # TODO: Make disk-pw-file randomly unique?
|
key_file = f"/tmp/{os.path.basename(self.partition.path)}.disk_pw" # TODO: Make disk-pw-file randomly unique?
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ def insert_mirrors(mirrors, *args, **kwargs):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def use_mirrors(regions :dict, destination='/etc/pacman.d/mirrorlist'):
|
def use_mirrors(regions :dict, destination='/etc/pacman.d/mirrorlist'):
|
||||||
log(f'A new package mirror-list has been created: {destination}', level=LOG_LEVELS.Info, file=storage.get('logfile', None))
|
log(f'A new package mirror-list has been created: {destination}', level=LOG_LEVELS.Info)
|
||||||
for region, mirrors in regions.items():
|
for region, mirrors in regions.items():
|
||||||
with open(destination, 'w') as mirrorlist:
|
with open(destination, 'w') as mirrorlist:
|
||||||
for mirror in mirrors:
|
for mirror in mirrors:
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import abc
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
from .storage import storage
|
from .storage import storage
|
||||||
|
|
||||||
class LOG_LEVELS:
|
class LOG_LEVELS:
|
||||||
|
|
@ -36,6 +37,11 @@ class journald(dict):
|
||||||
# Fallback logger
|
# Fallback logger
|
||||||
log_adapter.debug(message)
|
log_adapter.debug(message)
|
||||||
|
|
||||||
|
# TODO: Replace log() for session based logging.
|
||||||
|
class SessionLogging():
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
# Found first reference here: https://stackoverflow.com/questions/7445658/how-to-detect-if-the-console-does-support-ansi-escape-codes-in-python
|
# Found first reference here: https://stackoverflow.com/questions/7445658/how-to-detect-if-the-console-does-support-ansi-escape-codes-in-python
|
||||||
# And re-used this: https://github.com/django/django/blob/master/django/core/management/color.py#L12
|
# And re-used this: https://github.com/django/django/blob/master/django/core/management/color.py#L12
|
||||||
def supports_color():
|
def supports_color():
|
||||||
|
|
@ -76,30 +82,28 @@ def stylize_output(text :str, *opts, **kwargs):
|
||||||
def log(*args, **kwargs):
|
def log(*args, **kwargs):
|
||||||
string = orig_string = ' '.join([str(x) for x in args])
|
string = orig_string = ' '.join([str(x) for x in args])
|
||||||
|
|
||||||
|
# Attempt to colorize the output if supported
|
||||||
|
# Insert default colors and override with **kwargs
|
||||||
if supports_color():
|
if supports_color():
|
||||||
kwargs = {'bg' : 'black', 'fg': 'white', **kwargs}
|
kwargs = {'bg' : 'black', 'fg': 'white', **kwargs}
|
||||||
string = stylize_output(string, **kwargs)
|
string = stylize_output(string, **kwargs)
|
||||||
|
|
||||||
if (logfile := storage.get('logfile', None)) and 'file' not in kwargs:
|
# If a logfile is defined in storage,
|
||||||
kwargs['file'] = logfile
|
# we use that one to output everything
|
||||||
|
if (filename := storage.get('LOG_FILE', None)):
|
||||||
|
absolute_logfile = os.path.join(storage.get('LOG_PATH', './'), filename)
|
||||||
|
if not os.path.isfile(absolute_logfile):
|
||||||
|
os.makedirs(os.path.dirname(absolute_logfile))
|
||||||
|
Path(absolute_logfile).touch() # Overkill?
|
||||||
|
|
||||||
# Log to a file output unless specifically told to suppress this feature.
|
with open(absolute_logfile, 'a') as log_file:
|
||||||
# (level has no effect on the log file, everything will be written there)
|
log_file.write(f"{orig_string}\n")
|
||||||
if 'file' in kwargs and ('suppress' not in kwargs or kwargs['suppress'] == False):
|
|
||||||
if type(kwargs['file']) is str:
|
|
||||||
with open(kwargs['file'], 'a') as log_file:
|
|
||||||
log_file.write(f"{orig_string}\n")
|
|
||||||
elif kwargs['file']:
|
|
||||||
kwargs['file'].write(f"{orig_string}\n")
|
|
||||||
|
|
||||||
# If we assigned a level, try to log it to systemd's journald.
|
# If we assigned a level, try to log it to systemd's journald.
|
||||||
# Unless the level is higher than we've decided to output interactively.
|
# Unless the level is higher than we've decided to output interactively.
|
||||||
# (Remember, log files still get *ALL* the output despite level restrictions)
|
# (Remember, log files still get *ALL* the output despite level restrictions)
|
||||||
if 'level' in kwargs:
|
if 'level' in kwargs:
|
||||||
if 'LOG_LEVEL' not in storage:
|
if kwargs['level'] > storage.get('LOG_LEVEL', LOG_LEVELS.Info):
|
||||||
storage['LOG_LEVEL'] = LOG_LEVELS.Info
|
|
||||||
|
|
||||||
if kwargs['level'] > storage['LOG_LEVEL']:
|
|
||||||
# Level on log message was Debug, but output level is set to Info.
|
# Level on log message was Debug, but output level is set to Info.
|
||||||
# In that case, we'll drop it.
|
# In that case, we'll drop it.
|
||||||
return None
|
return None
|
||||||
|
|
@ -110,5 +114,7 @@ def log(*args, **kwargs):
|
||||||
pass # Ignore writing to journald
|
pass # Ignore writing to journald
|
||||||
|
|
||||||
# Finally, print the log unless we skipped it based on level.
|
# Finally, print the log unless we skipped it based on level.
|
||||||
# And we print the string which may or may not contain color formatting.
|
# We use sys.stdout.write()+flush() instead of print() to try and
|
||||||
print(string)
|
# fix issue #94
|
||||||
|
sys.stdout.write(f"{string}\n")
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
@ -15,5 +15,7 @@ storage = {
|
||||||
#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',
|
'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.
|
'PROFILE_DB' : None, # Used in cases when listing profiles is desired, not mandatory for direct profile grabing.
|
||||||
|
'LOG_PATH' : '/var/log/archinstall',
|
||||||
|
'LOG_FILE' : 'install.log'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,10 @@
|
||||||
import getpass, time, json, sys, signal, os
|
import getpass, time, json, sys, signal, os
|
||||||
import archinstall
|
import archinstall
|
||||||
|
|
||||||
# Setup a global log file.
|
# Create a storage structure for all our information.
|
||||||
# Archinstall will honor storage['logfile'] in most of it's functions log handle.
|
# We'll print this right before the user gets informed about the formatting timer.
|
||||||
log_root = os.path.join(os.path.expanduser('~/'), '.cache/archinstall')
|
archinstall.storage['_guided'] = {}
|
||||||
if not os.path.isdir(log_root):
|
archinstall.storage['_guided_hidden'] = {} # This will simply be hidden from printouts and things.
|
||||||
os.makedirs(log_root)
|
|
||||||
|
|
||||||
init_time = time.strftime('%Y-%m-%d_%H-%M-%S')
|
|
||||||
milliseconds = int(str(time.time()).split('.')[1])
|
|
||||||
archinstall.storage['logfile'] = f"{log_root}/install-session_{init_time}.{milliseconds}.log"
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This signal-handler chain (and global variable)
|
This signal-handler chain (and global variable)
|
||||||
|
|
@ -84,6 +79,7 @@ def perform_installation(device, boot_partition, language, mirrors):
|
||||||
archinstall.sys_command(f'umount -R /mnt', suppress_errors=True)
|
archinstall.sys_command(f'umount -R /mnt', suppress_errors=True)
|
||||||
archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', suppress_errors=True)
|
archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', suppress_errors=True)
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
First, we'll ask the user for a bunch of user input.
|
First, we'll ask the user for a bunch of user input.
|
||||||
Not until we're satisfied with what we want to install
|
Not until we're satisfied with what we want to install
|
||||||
|
|
@ -92,11 +88,7 @@ archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', suppress_error
|
||||||
|
|
||||||
if len(keyboard_language := archinstall.select_language(archinstall.list_keyboard_languages()).strip()):
|
if len(keyboard_language := archinstall.select_language(archinstall.list_keyboard_languages()).strip()):
|
||||||
archinstall.set_keyboard_language(keyboard_language)
|
archinstall.set_keyboard_language(keyboard_language)
|
||||||
|
archinstall.storage['_guided']['keyboard_layout'] = keyboard_language
|
||||||
# Create a storage structure for all our information.
|
|
||||||
# We'll print this right before the user gets informed about the formatting timer.
|
|
||||||
archinstall.storage['_guided'] = {}
|
|
||||||
archinstall.storage['_guided_hidden'] = {} # This will simply be hidden from printouts and things.
|
|
||||||
|
|
||||||
# Set which region to download packages from during the installation
|
# Set which region to download packages from during the installation
|
||||||
mirror_regions = archinstall.select_mirror_regions(archinstall.list_mirrors())
|
mirror_regions = archinstall.select_mirror_regions(archinstall.list_mirrors())
|
||||||
|
|
@ -109,6 +101,7 @@ while (disk_password := getpass.getpass(prompt='Enter disk encryption password (
|
||||||
if disk_password != disk_password_verification:
|
if disk_password != disk_password_verification:
|
||||||
archinstall.log(' * Passwords did not match * ', bg='black', fg='red')
|
archinstall.log(' * Passwords did not match * ', bg='black', fg='red')
|
||||||
continue
|
continue
|
||||||
|
archinstall.storage['_guided']['disk_encryption'] = True
|
||||||
break
|
break
|
||||||
archinstall.storage['_guided']['harddrive'] = harddrive
|
archinstall.storage['_guided']['harddrive'] = harddrive
|
||||||
|
|
||||||
|
|
@ -125,7 +118,10 @@ while (root_pw := getpass.getpass(prompt='Enter root password (leave blank to le
|
||||||
archinstall.log(' * Passwords did not match * ', bg='black', fg='red')
|
archinstall.log(' * Passwords did not match * ', bg='black', fg='red')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# Storing things in _guided_hidden helps us avoid printing it
|
||||||
|
# when echoing user configuration: archinstall.storage['_guided']
|
||||||
archinstall.storage['_guided_hidden']['root_pw'] = root_pw
|
archinstall.storage['_guided_hidden']['root_pw'] = root_pw
|
||||||
|
archinstall.storage['_guided']['root_unlocked'] = True
|
||||||
break
|
break
|
||||||
|
|
||||||
# Ask for additional users (super-user if root pw was not set)
|
# Ask for additional users (super-user if root pw was not set)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import archinstall
|
||||||
installation.install_profile('xorg')
|
installation.install_profile('xorg')
|
||||||
|
|
||||||
installation.add_additional_packages(
|
installation.add_additional_packages(
|
||||||
"awesome xorg-xrandr xterm feh slock terminus-font-otb gnu-free-fonts ttf-liberation xsel"
|
"awesome xorg-xrandr xterm feh slock terminus-font gnu-free-fonts ttf-liberation xsel"
|
||||||
)
|
)
|
||||||
|
|
||||||
with open(f'{installation.mountpoint}/etc/X11/xinit/xinitrc', 'r') as xinitrc:
|
with open(f'{installation.mountpoint}/etc/X11/xinit/xinitrc', 'r') as xinitrc:
|
||||||
|
|
|
||||||
|
|
@ -31,25 +31,24 @@ if __name__ == 'awesome':
|
||||||
# Then setup and configure the desktop environment: awesome
|
# Then setup and configure the desktop environment: awesome
|
||||||
editor = "nano"
|
editor = "nano"
|
||||||
filebrowser = "nemo gpicview-gtk3"
|
filebrowser = "nemo gpicview-gtk3"
|
||||||
webbrowser = "chromium"
|
webbrowser = "chromium" # TODO: Ask the user to select one instead
|
||||||
virtulization = "qemu ovmf"
|
utils = "openssh sshfs git htop pkgfile scrot dhclient wget libu2f-host"
|
||||||
utils = "openssh sshfs git htop pkgfile scrot dhclient wget smbclient cifs-utils libu2f-host"
|
|
||||||
|
|
||||||
|
|
||||||
installation.add_additional_packages(f"{webbrowser} {utils} {virtulization} {filebrowser} {editor}")
|
installation.add_additional_packages(f"{webbrowser} {utils} {filebrowser} {editor}")
|
||||||
|
|
||||||
alacritty = archinstall.Application(installation, 'alacritty')
|
alacritty = archinstall.Application(installation, 'alacritty')
|
||||||
alacritty.install()
|
alacritty.install()
|
||||||
|
|
||||||
# TODO: Copy a full configuration to ~/.config/awesome/rc.lua instead.
|
# TODO: Copy a full configuration to ~/.config/awesome/rc.lua instead.
|
||||||
with open(f'{installation.mountpoint}/etc/xdg/awesome/rc.lua', 'r') as awesome_rc_lua:
|
with open(f'{installation.mountpoint}/etc/xdg/awesome/rc.lua', 'r') as fh:
|
||||||
awesome_lua = awesome_rc_lua.read()
|
awesome_lua = fh.read()
|
||||||
|
|
||||||
## Replace xterm with alacritty for a smoother experience.
|
## Replace xterm with alacritty for a smoother experience.
|
||||||
awesome_lua = awesome_rc_lua.replace('"xterm"', '"alacritty"')
|
awesome_lua = awesome_lua.replace('"xterm"', '"alacritty"')
|
||||||
|
|
||||||
with open(f'{installation.mountpoint}/etc/xdg/awesome/rc.lua', 'w') as awesome_rc_lua:
|
with open(f'{installation.mountpoint}/etc/xdg/awesome/rc.lua', 'w') as fh:
|
||||||
awesome_rc_lua.write(awesome_lua)
|
fh.write(awesome_lua)
|
||||||
|
|
||||||
## TODO: Configure the right-click-menu to contain the above packages that were installed. (as a user config)
|
## TODO: Configure the right-click-menu to contain the above packages that were installed. (as a user config)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue