Added colored output. Also tested non-encrypted installations and added ext4 support.
This commit is contained in:
parent
78d4fe4fa1
commit
0bc24699c1
|
|
@ -5,3 +5,6 @@ from .lib.exceptions import *
|
||||||
from .lib.installer import *
|
from .lib.installer import *
|
||||||
from .lib.profiles import *
|
from .lib.profiles import *
|
||||||
from .lib.luks import *
|
from .lib.luks import *
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print('Launching as a module?')
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import glob, re, os, json
|
import glob, re, os, json
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from .exceptions import *
|
from .exceptions import *
|
||||||
from .general import sys_command
|
from .general import *
|
||||||
|
|
||||||
ROOT_DIR_PATTERN = re.compile('^.*?/devices')
|
ROOT_DIR_PATTERN = re.compile('^.*?/devices')
|
||||||
GPT = 0b00000001
|
GPT = 0b00000001
|
||||||
|
|
@ -90,7 +90,7 @@ class Partition():
|
||||||
return f'Partition({self.path}, fs={self.filesystem}, mounted={self.mountpoint})'
|
return f'Partition({self.path}, fs={self.filesystem}, mounted={self.mountpoint})'
|
||||||
|
|
||||||
def format(self, filesystem):
|
def format(self, filesystem):
|
||||||
print(f'Formatting {self} -> {filesystem}')
|
log(f'Formatting {self} -> {filesystem}')
|
||||||
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 not b'UUID' in o:
|
if not b'UUID' in o:
|
||||||
|
|
@ -101,13 +101,17 @@ class Partition():
|
||||||
if (b'mkfs.fat' not in o and b'mkfs.vfat' not in o) or b'command not found' in o:
|
if (b'mkfs.fat' not in o and b'mkfs.vfat' not in o) or b'command not found' in o:
|
||||||
raise DiskError(f'Could not format {self.path} with {filesystem} because: {o}')
|
raise DiskError(f'Could not format {self.path} with {filesystem} because: {o}')
|
||||||
self.filesystem = 'fat32'
|
self.filesystem = 'fat32'
|
||||||
|
elif filesystem == 'ext4':
|
||||||
|
if (handle := sys_command(f'/usr/bin/mkfs.ext4 -F {self.path}')).exit_code != 0:
|
||||||
|
raise DiskError(f'Could not format {self.path} with {filesystem} because: {b"".join(handle)}')
|
||||||
|
self.filesystem = 'fat32'
|
||||||
else:
|
else:
|
||||||
raise DiskError(f'Fileformat {filesystem} is not yet implemented.')
|
raise DiskError(f'Fileformat {filesystem} is not yet implemented.')
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def mount(self, target, fs=None, options=''):
|
def mount(self, target, fs=None, options=''):
|
||||||
if not self.mountpoint:
|
if not self.mountpoint:
|
||||||
print(f'Mounting {self} to {target}')
|
log(f'Mounting {self} to {target}')
|
||||||
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
|
||||||
|
|
@ -166,10 +170,10 @@ class Filesystem():
|
||||||
if prep_mode == 'luks2':
|
if prep_mode == 'luks2':
|
||||||
self.add_partition('primary', start='513MiB', end='100%')
|
self.add_partition('primary', start='513MiB', end='100%')
|
||||||
else:
|
else:
|
||||||
self.add_partition('primary', start='513MiB', end='513MiB', 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):
|
||||||
print(f'Adding partition to {self.blockdevice}')
|
log(f'Adding partition to {self.blockdevice}')
|
||||||
if format:
|
if format:
|
||||||
return self.parted(f'{self.blockdevice.device} mkpart {type} {format} {start} {end}') == 0
|
return self.parted(f'{self.blockdevice.device} mkpart {type} {format} {start} {end}') == 0
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,14 @@
|
||||||
import os, json, hashlib, shlex
|
import os, json, hashlib, shlex, sys
|
||||||
import time, pty
|
import time, pty
|
||||||
from subprocess import Popen, STDOUT, PIPE, check_output
|
from subprocess import Popen, STDOUT, PIPE, check_output
|
||||||
from select import epoll, EPOLLIN, EPOLLHUP
|
from select import epoll, EPOLLIN, EPOLLHUP
|
||||||
|
|
||||||
def log(*args, **kwargs):
|
def log(*args, **kwargs):
|
||||||
print(' '.join([str(x) for x in args]))
|
string = ' '.join([str(x) for x in args])
|
||||||
|
if supports_color():
|
||||||
|
kwargs = {'bg' : 'black', 'fg': 'white', **kwargs}
|
||||||
|
string = stylize_output(string, **kwargs)
|
||||||
|
print(string)
|
||||||
|
|
||||||
def gen_uid(entropy_length=256):
|
def gen_uid(entropy_length=256):
|
||||||
return hashlib.sha512(os.urandom(entropy_length)).hexdigest()
|
return hashlib.sha512(os.urandom(entropy_length)).hexdigest()
|
||||||
|
|
@ -23,6 +27,43 @@ def multisplit(s, splitters):
|
||||||
s = ns
|
s = ns
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
# Heavily influenced by: https://github.com/django/django/blob/ae8338daf34fd746771e0678081999b656177bae/django/utils/termcolors.py#L13
|
||||||
|
# Color options here: https://askubuntu.com/questions/528928/how-to-do-underline-bold-italic-strikethrough-color-background-and-size-i
|
||||||
|
def stylize_output(text :str, *opts, **kwargs):
|
||||||
|
opt_dict = {'bold': '1', 'italic' : '3', 'underscore': '4', 'blink': '5', 'reverse': '7', 'conceal': '8'}
|
||||||
|
color_names = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white')
|
||||||
|
foreground = {color_names[x]: '3%s' % x for x in range(8)}
|
||||||
|
background = {color_names[x]: '4%s' % x for x in range(8)}
|
||||||
|
RESET = '0'
|
||||||
|
|
||||||
|
code_list = []
|
||||||
|
if text == '' and len(opts) == 1 and opts[0] == 'reset':
|
||||||
|
return '\x1b[%sm' % RESET
|
||||||
|
for k, v in kwargs.items():
|
||||||
|
if k == 'fg':
|
||||||
|
code_list.append(foreground[v])
|
||||||
|
elif k == 'bg':
|
||||||
|
code_list.append(background[v])
|
||||||
|
for o in opts:
|
||||||
|
if o in opt_dict:
|
||||||
|
code_list.append(opt_dict[o])
|
||||||
|
if 'noreset' not in opts:
|
||||||
|
text = '%s\x1b[%sm' % (text or '', RESET)
|
||||||
|
return '%s%s' % (('\x1b[%sm' % ';'.join(code_list)), text or '')
|
||||||
|
|
||||||
|
# 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
|
||||||
|
def supports_color():
|
||||||
|
"""
|
||||||
|
Return True if the running system's terminal supports color,
|
||||||
|
and False otherwise.
|
||||||
|
"""
|
||||||
|
supported_platform = sys.platform != 'win32' or 'ANSICON' in os.environ
|
||||||
|
|
||||||
|
# isatty is not always implemented, #6223.
|
||||||
|
is_a_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()
|
||||||
|
return supported_platform and is_a_tty
|
||||||
|
|
||||||
class sys_command():#Thread):
|
class sys_command():#Thread):
|
||||||
"""
|
"""
|
||||||
Stolen from archinstall_gui
|
Stolen from archinstall_gui
|
||||||
|
|
@ -165,14 +206,14 @@ class sys_command():#Thread):
|
||||||
|
|
||||||
if bytes(f']$'.lower(), 'UTF-8') in self.trace_log[0-len(f']$')-5:].lower():
|
if bytes(f']$'.lower(), 'UTF-8') in self.trace_log[0-len(f']$')-5:].lower():
|
||||||
if 'debug' in self.kwargs and self.kwargs['debug']:
|
if 'debug' in self.kwargs and self.kwargs['debug']:
|
||||||
log(f"{self.cmd[0]} has finished.", origin='spawn', level=4)
|
log(f"{self.cmd[0]} has finished.")
|
||||||
alive = False
|
alive = False
|
||||||
break
|
break
|
||||||
|
|
||||||
self.status = 'done'
|
self.status = 'done'
|
||||||
|
|
||||||
if 'debug' in self.kwargs and self.kwargs['debug']:
|
if 'debug' in self.kwargs and self.kwargs['debug']:
|
||||||
log(f"{self.cmd[0]} waiting for exit code.", origin='spawn', level=5)
|
log(f"{self.cmd[0]} waiting for exit code.")
|
||||||
|
|
||||||
if not self.kwargs['emulate']:
|
if not self.kwargs['emulate']:
|
||||||
try:
|
try:
|
||||||
|
|
@ -185,6 +226,9 @@ class sys_command():#Thread):
|
||||||
else:
|
else:
|
||||||
self.exit_code = 0
|
self.exit_code = 0
|
||||||
|
|
||||||
|
if 'debug' in self.kwargs and self.kwargs['debug']:
|
||||||
|
log(f"{self.cmd[0]} got exit code: {self.exit_code}")
|
||||||
|
|
||||||
if 'ignore_errors' in self.kwargs:
|
if 'ignore_errors' in self.kwargs:
|
||||||
self.exit_code = 0
|
self.exit_code = 0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,26 +23,26 @@ class Installer():
|
||||||
# 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]:
|
||||||
raise args[1]
|
raise args[1]
|
||||||
print('Installation completed without any errors.')
|
log('Installation completed without any errors.', bg='black', fg='green')
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def pacstrap(self, *packages):
|
def pacstrap(self, *packages):
|
||||||
if type(packages[0]) in (list, tuple): packages = packages[0]
|
if type(packages[0]) in (list, tuple): packages = packages[0]
|
||||||
print(f'Installing packages: {packages}')
|
log(f'Installing packages: {packages}')
|
||||||
|
|
||||||
if (sync_mirrors := sys_command('/usr/bin/pacman -Syy')).exit_code == 0:
|
if (sync_mirrors := sys_command('/usr/bin/pacman -Syy')).exit_code == 0:
|
||||||
if (pacstrap := sys_command(f'/usr/bin/pacstrap {self.mountpoint} {" ".join(packages)}')).exit_code == 0:
|
if (pacstrap := sys_command(f'/usr/bin/pacstrap {self.mountpoint} {" ".join(packages)}')).exit_code == 0:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
print(f'Could not strap in packages: {pacstrap.exit_code}')
|
log(f'Could not strap in packages: {pacstrap.exit_code}')
|
||||||
else:
|
else:
|
||||||
print(f'Could not sync mirrors: {sync_mirrors.exit_code}')
|
log(f'Could not sync mirrors: {sync_mirrors.exit_code}')
|
||||||
|
|
||||||
def minimal_installation(self):
|
def minimal_installation(self):
|
||||||
return self.pacstrap('base base-devel linux linux-firmware btrfs-progs efibootmgr nano wpa_supplicant dialog'.split(' '))
|
return self.pacstrap('base base-devel linux linux-firmware btrfs-progs efibootmgr nano wpa_supplicant dialog'.split(' '))
|
||||||
|
|
||||||
def add_bootloader(self, partition):
|
def add_bootloader(self, partition):
|
||||||
print(f'Adding bootloader to {partition}')
|
log(f'Adding bootloader to {partition}')
|
||||||
os.makedirs(f'{self.mountpoint}/boot', exist_ok=True)
|
os.makedirs(f'{self.mountpoint}/boot', exist_ok=True)
|
||||||
partition.mount(f'{self.mountpoint}/boot')
|
partition.mount(f'{self.mountpoint}/boot')
|
||||||
o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} bootctl --no-variables --path=/boot install'))
|
o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} bootctl --no-variables --path=/boot install'))
|
||||||
|
|
@ -78,11 +78,11 @@ class Installer():
|
||||||
def install_profile(self, profile):
|
def install_profile(self, profile):
|
||||||
profile = Profile(self, profile)
|
profile = Profile(self, profile)
|
||||||
|
|
||||||
print(f'Installing network profile {profile}')
|
log(f'Installing network profile {profile}')
|
||||||
profile.install()
|
profile.install()
|
||||||
|
|
||||||
def user_create(self, user :str, password=None, groups=[]):
|
def user_create(self, user :str, password=None, groups=[]):
|
||||||
print(f'Creating user {user}')
|
log(f'Creating user {user}')
|
||||||
o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} useradd -m -G wheel {user}'))
|
o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} useradd -m -G wheel {user}'))
|
||||||
if password:
|
if password:
|
||||||
self.user_set_pw(user, password)
|
self.user_set_pw(user, password)
|
||||||
|
|
@ -91,12 +91,13 @@ class Installer():
|
||||||
o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} gpasswd -a {user} {group}'))
|
o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} gpasswd -a {user} {group}'))
|
||||||
|
|
||||||
def user_set_pw(self, user, password):
|
def user_set_pw(self, user, password):
|
||||||
print(f'Setting password for {user}')
|
log(f'Setting password for {user}')
|
||||||
o = b''.join(sys_command(f"/usr/bin/arch-chroot {self.mountpoint} sh -c \"echo '{user}:{password}' | chpasswd\""))
|
o = b''.join(sys_command(f"/usr/bin/arch-chroot {self.mountpoint} sh -c \"echo '{user}:{password}' | chpasswd\""))
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def add_AUR_support(self):
|
def add_AUR_support(self):
|
||||||
print(f'Building and installing yay support into {self.mountpoint}')
|
log(f'Building and installing yay support into {self.mountpoint}')
|
||||||
|
self.add_additional_packages(['git', 'base-devel']) # TODO: Remove if not explicitly added at one point
|
||||||
o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} sh -c "useradd -m -G wheel aibuilder"'))
|
o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} sh -c "useradd -m -G wheel aibuilder"'))
|
||||||
o = b''.join(sys_command(f"/usr/bin/sed -i 's/# %wheel ALL=(ALL) NO/%wheel ALL=(ALL) NO/' {self.mountpoint}/etc/sudoers"))
|
o = b''.join(sys_command(f"/usr/bin/sed -i 's/# %wheel ALL=(ALL) NO/%wheel ALL=(ALL) NO/' {self.mountpoint}/etc/sudoers"))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import os
|
import os
|
||||||
from .exceptions import *
|
from .exceptions import *
|
||||||
from .general import sys_command
|
from .general import *
|
||||||
from .disk import Partition
|
from .disk import Partition
|
||||||
|
|
||||||
class luks2():
|
class luks2():
|
||||||
|
|
@ -22,7 +22,7 @@ class luks2():
|
||||||
return True
|
return True
|
||||||
|
|
||||||
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):
|
||||||
print(f'Encrypting {partition}')
|
log(f'Encrypting {partition}')
|
||||||
if not key_file: key_file = f'/tmp/{os.path.basename(self.partition.path)}.disk_pw' #TODO: Make disk-pw-file randomly unique?
|
if not key_file: key_file = f'/tmp/{os.path.basename(self.partition.path)}.disk_pw' #TODO: Make disk-pw-file randomly unique?
|
||||||
if type(password) != bytes: password = bytes(password, 'UTF-8')
|
if type(password) != bytes: password = bytes(password, 'UTF-8')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,23 +35,23 @@ def get_application_instructions(target):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
instructions = grab_url_data(f'{UPSTREAM_URL}/applications/{target}.json').decode('UTF-8')
|
instructions = grab_url_data(f'{UPSTREAM_URL}/applications/{target}.json').decode('UTF-8')
|
||||||
print('[N] Found application instructions for: {}'.format(target))
|
log('[N] Found application instructions for: {}'.format(target))
|
||||||
except urllib.error.HTTPError:
|
except urllib.error.HTTPError:
|
||||||
print('[N] Could not find remote instructions. yrying local instructions under ./profiles/applications')
|
log('[N] Could not find remote instructions. yrying local instructions under ./profiles/applications')
|
||||||
local_path = './profiles/applications' if os.path.isfile('./archinstall.py') else './archinstall/profiles/applications' # Dangerous assumption
|
local_path = './profiles/applications' if os.path.isfile('./archinstall.py') else './archinstall/profiles/applications' # Dangerous assumption
|
||||||
if os.path.isfile(f'{local_path}/{target}.json'):
|
if os.path.isfile(f'{local_path}/{target}.json'):
|
||||||
with open(f'{local_path}/{target}.json', 'r') as fh:
|
with open(f'{local_path}/{target}.json', 'r') as fh:
|
||||||
instructions = fh.read()
|
instructions = fh.read()
|
||||||
|
|
||||||
print('[N] Found local application instructions for: {}'.format(target))
|
log('[N] Found local application instructions for: {}'.format(target))
|
||||||
else:
|
else:
|
||||||
print('[N] No instructions found for: {}'.format(target))
|
log('[N] No instructions found for: {}'.format(target))
|
||||||
return instructions
|
return instructions
|
||||||
|
|
||||||
try:
|
try:
|
||||||
instructions = json.loads(instructions, object_pairs_hook=oDict)
|
instructions = json.loads(instructions, object_pairs_hook=oDict)
|
||||||
except:
|
except:
|
||||||
print('[E] JSON syntax error in {}'.format('{}/applications/{}.json'.format(args['profiles-path'], target)))
|
log('[E] JSON syntax error in {}'.format('{}/applications/{}.json'.format(args['profiles-path'], target)))
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
@ -108,9 +108,9 @@ class Profile():
|
||||||
for title in instructions:
|
for title in instructions:
|
||||||
log(f'Running post installation step {title}')
|
log(f'Running post installation step {title}')
|
||||||
|
|
||||||
print('[N] Network Deploy: {}'.format(title))
|
log('[N] Network Deploy: {}'.format(title))
|
||||||
if type(instructions[title]) == str:
|
if type(instructions[title]) == str:
|
||||||
print('[N] Loading {} configuration'.format(instructions[title]))
|
log('[N] Loading {} configuration'.format(instructions[title]))
|
||||||
log(f'Loading {instructions[title]} configuration')
|
log(f'Loading {instructions[title]} configuration')
|
||||||
instructions[title] = Application(self.installer, instructions[title], args=self.args)
|
instructions[title] = Application(self.installer, instructions[title], args=self.args)
|
||||||
instructions[title].install()
|
instructions[title].install()
|
||||||
|
|
@ -170,7 +170,7 @@ class Profile():
|
||||||
o = b''.join(sys_command(f'/usr/bin/systemd-nspawn -D {self.installer.mountpoint} --machine temporary {command}'))
|
o = b''.join(sys_command(f'/usr/bin/systemd-nspawn -D {self.installer.mountpoint} --machine temporary {command}'))
|
||||||
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")}')
|
||||||
print('[W] Post install command failed: {}'.format(o.decode('UTF-8')))
|
log('[W] Post install command failed: {}'.format(o.decode('UTF-8')))
|
||||||
|
|
||||||
class Application(Profile):
|
class Application(Profile):
|
||||||
@property
|
@property
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,12 @@ archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', surpress_error
|
||||||
|
|
||||||
# Select a harddrive and a disk password
|
# Select a harddrive and a disk password
|
||||||
harddrive = archinstall.select_disk(archinstall.all_disks())
|
harddrive = archinstall.select_disk(archinstall.all_disks())
|
||||||
disk_password = getpass.getpass(prompt='Disk password (If empty, won\'t use disk encryption): ')
|
while (disk_password := getpass.getpass(prompt='Enter disk encryption password (leave blank for no encryption): ')):
|
||||||
|
disk_password_verification = getpass.getpass(prompt='And one more time for verification: ')
|
||||||
|
if disk_password != disk_password_verification:
|
||||||
|
archinstall.log(' * Passwords did not match * ', bg='black', fg='red')
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
|
||||||
def perform_installation(device, boot_partition):
|
def perform_installation(device, boot_partition):
|
||||||
hostname = input('Desired hostname for the installation: ')
|
hostname = input('Desired hostname for the installation: ')
|
||||||
|
|
@ -15,7 +20,7 @@ def perform_installation(device, boot_partition):
|
||||||
installation.add_bootloader(boot_partition)
|
installation.add_bootloader(boot_partition)
|
||||||
|
|
||||||
packages = input('Additional packages aside from base (space separated): ').split(' ')
|
packages = input('Additional packages aside from base (space separated): ').split(' ')
|
||||||
if len(packages):
|
if len(packages) and packages[0] != '':
|
||||||
installation.add_additional_packages(packages)
|
installation.add_additional_packages(packages)
|
||||||
|
|
||||||
profile = input('Any particular profile you want to install: ')
|
profile = input('Any particular profile you want to install: ')
|
||||||
|
|
@ -28,18 +33,22 @@ def perform_installation(device, boot_partition):
|
||||||
new_user_passwd = getpass.getpass(prompt=f'Password for user {new_user}: ')
|
new_user_passwd = getpass.getpass(prompt=f'Password for user {new_user}: ')
|
||||||
new_user_passwd_verify = getpass.getpass(prompt=f'Enter password again for verification: ')
|
new_user_passwd_verify = getpass.getpass(prompt=f'Enter password again for verification: ')
|
||||||
if new_user_passwd != new_user_passwd_verify:
|
if new_user_passwd != new_user_passwd_verify:
|
||||||
print(' * Passwords did not match * ')
|
archinstall.log(' * Passwords did not match * ', bg='black', fg='red')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
installation.user_create(new_user, new_user_passwd)
|
installation.user_create(new_user, new_user_passwd)
|
||||||
|
|
||||||
root_pw = getpass.getpass(prompt='Enter root password: ')
|
while (root_pw := getpass.getpass(prompt='Enter root password (leave blank for no password): ')):
|
||||||
if len(root_pw.strip()):
|
root_pw_verification = getpass.getpass(prompt='And one more time for verification: ')
|
||||||
|
if root_pw != root_pw_verification:
|
||||||
|
archinstall.log(' * Passwords did not match * ', bg='black', fg='red')
|
||||||
|
continue
|
||||||
installation.user_set_pw('root', root_pw)
|
installation.user_set_pw('root', root_pw)
|
||||||
|
break
|
||||||
|
|
||||||
aur = input('Would you like AUR support? (leave blank for no): ')
|
aur = input('Would you like AUR support? (leave blank for no): ')
|
||||||
if len(aur.strip()):
|
if len(aur.strip()):
|
||||||
print(' - AUR support provided by yay (https://aur.archlinux.org/packages/yay/)')
|
archinstall.log(' - AUR support provided by yay (https://aur.archlinux.org/packages/yay/)', bg='black', fg='white')
|
||||||
installation.add_AUR_support()
|
installation.add_AUR_support()
|
||||||
|
|
||||||
with archinstall.Filesystem(harddrive, archinstall.GPT) as fs:
|
with archinstall.Filesystem(harddrive, archinstall.GPT) as fs:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue