I simplified the countdown, by moving it into it's own function instead of wrapped inside guided.. This can now be used by others for a simple countdown. I also re-worked the minimal.py example to work with the new internal partitioning logic API as well as support some flags from archinstall.arguments to minimize user input requirements to just one single question. This one question will most likely go away too, but stays for simplicity right now.

This commit is contained in:
Anton Hvornum 2021-04-08 21:14:19 +02:00
parent ae2da06075
commit b5245b31fe
No known key found for this signature in database
GPG Key ID: F1234C5BA67C59DF
3 changed files with 98 additions and 74 deletions

View File

@ -1,4 +1,5 @@
import getpass, pathlib, os, shutil, re
import sys, time, signal
from .exceptions import *
from .profiles import Profile
from .locale_helpers import search_keyboard_layout
@ -19,14 +20,49 @@ def get_longest_option(options):
return max([len(x) for x in options])
def check_for_correct_username(username):
if re.match(r'^[a-z_][a-z0-9_-]*\$?$', username) and len(username) <= 32:
return True
log(
if re.match(r'^[a-z_][a-z0-9_-]*\$?$', username) and len(username) <= 32:
return True
log(
"The username you entered is invalid. Try again",
level=LOG_LEVELS.Warning,
fg='red'
)
return False
return False
def do_countdown():
SIG_TRIGGER = False
def kill_handler(sig, frame):
print()
exit(0)
def sig_handler(sig, frame):
global SIG_TRIGGER
SIG_TRIGGER = True
signal.signal(signal.SIGINT, kill_handler)
original_sigint_handler = signal.getsignal(signal.SIGINT)
signal.signal(signal.SIGINT, sig_handler)
for i in range(5, 0, -1):
print(f"{i}", end='')
for x in range(4):
sys.stdout.flush()
time.sleep(0.25)
print(".", end='')
if SIG_TRIGGER:
abort = input('\nDo you really want to abort (y/n)? ')
if abort.strip() != 'n':
exit(0)
if SIG_TRIGGER is False:
sys.stdin.read()
SIG_TRIGGER = False
signal.signal(signal.SIGINT, sig_handler)
print()
signal.signal(signal.SIGINT, original_sigint_handler)
return True
def get_password(prompt="Enter a password: "):
while (passwd := getpass.getpass(prompt)):

View File

@ -1,30 +1,8 @@
import getpass, time, json, sys, signal, os
import getpass, time, json, os
import archinstall
from archinstall.lib.hardware import hasUEFI
from archinstall.lib.profiles import Profile
"""
This signal-handler chain (and global variable)
is used to trigger the "Are you sure you want to abort?" question further down.
It might look a bit odd, but have a look at the line: "if SIG_TRIGGER:"
"""
SIG_TRIGGER = False
def kill_handler(sig, frame):
print()
exit(0)
def sig_handler(sig, frame):
global SIG_TRIGGER
SIG_TRIGGER = True
signal.signal(signal.SIGINT, kill_handler)
original_sigint_handler = signal.getsignal(signal.SIGINT)
signal.signal(signal.SIGINT, sig_handler)
if archinstall.arguments.get('help'):
print("See `man archinstall` for help.")
exit(0)
def ask_user_questions():
"""
First, we'll ask the user for a bunch of user input.
@ -206,8 +184,6 @@ def ask_user_questions():
def perform_installation_steps():
global SIG_TRIGGER
print()
print('This is your chosen configuration:')
archinstall.log("-- Guided template chosen (with below config) --", level=archinstall.LOG_LEVELS.Debug)
@ -222,29 +198,7 @@ def perform_installation_steps():
"""
print(f" ! Formatting {archinstall.arguments['harddrive']} in ", end='')
for i in range(5, 0, -1):
print(f"{i}", end='')
for x in range(4):
sys.stdout.flush()
time.sleep(0.25)
print(".", end='')
if SIG_TRIGGER:
abort = input('\nDo you really want to abort (y/n)? ')
if abort.strip() != 'n':
exit(0)
if SIG_TRIGGER is False:
sys.stdin.read()
SIG_TRIGGER = False
signal.signal(signal.SIGINT, sig_handler)
# Put back the default/original signal handler now that we're done catching
# and interrupting SIGINT with "Do you really want to abort".
print()
signal.signal(signal.SIGINT, original_sigint_handler)
archinstall.do_countdown()
"""
Setup the blockdevice, filesystem (and optionally encryption).

View File

@ -1,30 +1,64 @@
import archinstall, getpass
# Unmount and close previous runs
archinstall.sys_command(f'umount -R /mnt', suppress_errors=True)
archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', suppress_errors=True)
# Select a harddrive and a disk password
harddrive = archinstall.select_disk(archinstall.all_disks())
disk_password = getpass.getpass(prompt='Disk password (won\'t echo): ')
archinstall.log(f"Minimal only supports:")
archinstall.log(f" * Being installed to a single disk")
with archinstall.Filesystem(harddrive, archinstall.GPT) as fs:
# Use the entire disk instead of setting up partitions on your own
fs.use_entire_disk('luks2')
if archinstall.arguments.get('help', None):
archinstall.log(f" - Optional disk encryption via --!encryption-password=<password>")
archinstall.log(f" - Optional filesystem type via --filesystem=<fs type>")
archinstall.log(f" - Optional systemd network via --network")
if harddrive.partition[1].size == '512M':
raise OSError('Trying to encrypt the boot partition for petes sake..')
harddrive.partition[0].format('fat32')
archinstall.arguments['harddrive'] = archinstall.select_disk(archinstall.all_disks())
archinstall.arguments['harddrive'].keep_partitions = False
with archinstall.luks2(harddrive.partition[1], 'luksloop', disk_password) as unlocked_device:
unlocked_device.format('btrfs')
with archinstall.Installer(unlocked_device, boot_partition=harddrive.partition[0], hostname='testmachine') as installation:
if installation.minimal_installation():
installation.add_bootloader()
def install_on(root, boot):
# We kick off the installer by telling it where the root and boot lives
with archinstall.Installer(root, boot_partition=boot, hostname='minimal-arch') as installation:
# Strap in the base system, add a boot loader and configure
# some other minor details as specified by this profile and user.
if installation.minimal_installation():
installation.add_bootloader()
installation.add_additional_packages(['nano', 'wget', 'git'])
installation.install_profile('minimal')
# Optionally enable networking:
if archinstall.arguments.get('network', None):
installation.copy_ISO_network_config(enable_services=True)
installation.user_create('devel', 'devel')
installation.user_set_pw('root', 'toor')
installation.add_additional_packages(['nano', 'wget', 'git'])
installation.install_profile('minimal')
installation.user_create('devel', 'devel')
installation.user_set_pw('root', 'airoot')
# Once this is done, we output some useful information to the user
# And the installation is complete.
archinstall.log(f"There are two new accounts in your installation after reboot:")
archinstall.log(f" * root (password: airoot)")
archinstall.log(f" * devel (password: devel)")
print(f" ! Formatting {archinstall.arguments['harddrive']} in ", end='')
archinstall.do_countdown()
# First, we configure the basic filesystem layout
with archinstall.Filesystem(archinstall.arguments['harddrive'], archinstall.GPT) as fs:
# We use the entire disk instead of setting up partitions on your own
if archinstall.arguments['harddrive'].keep_partitions is False:
fs.use_entire_disk(root_filesystem_type=archinstall.arguments.get('filesystem', 'btrfs'))
boot = fs.find_partition('/boot')
root = fs.find_partition('/')
boot.format('vfat')
# We encrypt the root partition if we got a password to do so with,
# Otherwise we just skip straight to formatting and installation
if archinstall.arguments.get('!encryption-password', None):
root.encrypt()
with archinstall.luks2(root, 'luksloop', archinstall.arguments.get('!encryption-password', None)) as unlocked_root:
unlocked_root.format(root.filesystem)
install_on(unlocked_root)
else:
root.format(root.filesystem)
install_on(root)