Merge branch 'master' into master

This commit is contained in:
Anton Hvornum 2021-09-06 15:01:37 +02:00 committed by GitHub
commit 48fd68124a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 95 additions and 90 deletions

View File

@ -64,7 +64,7 @@ def initialize_arguments():
config[key] = val
config["script"] = args.script
if args.dry_run is not None:
config["dry_run"] = args.dry_run
config["dry-run"] = args.dry_run
return config

View File

@ -347,6 +347,11 @@ class Partition:
raise DiskError(f'Could not format {path} with {filesystem} because: {b"".join(handle)}')
self.filesystem = 'ext4'
elif filesystem == 'ext2':
if (handle := SysCommand(f'/usr/bin/mkfs.ext2 -F {path}')).exit_code != 0:
raise DiskError(f'Could not format {path} with {filesystem} because: {b"".join(handle)}')
self.filesystem = 'ext2'
elif filesystem == 'xfs':
if (handle := SysCommand(f'/usr/bin/mkfs.xfs -f {path}')).exit_code != 0:
raise DiskError(f'Could not format {path} with {filesystem} because: {b"".join(handle)}')
@ -518,12 +523,24 @@ class Filesystem:
self.blockdevice.partition[0].allow_formatting = True
self.blockdevice.partition[1].allow_formatting = True
else:
# we don't need a seprate boot partition it would be a waste of space
self.add_partition('primary', start='1MB', end='100%')
self.blockdevice.partition[0].filesystem = root_filesystem_type
log(f"Set the root partition {self.blockdevice.partition[0]} to use filesystem {root_filesystem_type}.", level=logging.DEBUG)
self.blockdevice.partition[0].target_mountpoint = '/'
if not self.parted_mklabel(self.blockdevice.device, "msdos"):
raise KeyError(f"Could not create a MSDOS label on {self}")
self.add_partition('primary', start='1MiB', end='513MiB', partition_format='ext4')
self.set(0, 'boot on')
self.add_partition('primary', start='513MiB', end='100%')
self.blockdevice.partition[0].filesystem = 'ext4' # TODO: Up for debate weither or not this should be user-supplied: https://github.com/archlinux/archinstall/pull/595/files
self.blockdevice.partition[1].filesystem = root_filesystem_type
log(f"Set the boot partition {self.blockdevice.partition[0]} to use filesystem {'ext4'}.", level=logging.DEBUG)
log(f"Set the root partition {self.blockdevice.partition[1]} to use filesystem {root_filesystem_type}.", level=logging.DEBUG)
self.blockdevice.partition[0].target_mountpoint = '/boot'
self.blockdevice.partition[1].target_mountpoint = '/'
self.blockdevice.partition[0].allow_formatting = True
self.blockdevice.partition[1].allow_formatting = True
def add_partition(self, partition_type, start, end, partition_format=None):
log(f'Adding partition to {self.blockdevice}', level=logging.INFO)
@ -539,11 +556,9 @@ class Filesystem:
if partitioning:
start_wait = time.time()
while previous_partitions == self.blockdevice.partitions:
time.sleep(0.025) # Let the new partition come up in the kernel
if time.time() - start_wait > 10:
raise DiskError(f"New partition never showed up after adding new partition on {self} (timeout 10 seconds).")
time.sleep(0.025) # Let the new partition come up in the kernel
if time.time() - start_wait > 20:
raise DiskError(f"New partition never showed up after adding new partition on {self} (timeout 10 seconds).")
return True
def set_name(self, partition: int, name: str):

View File

@ -98,10 +98,7 @@ class JsonEncoder:
elif isinstance(obj, (datetime, date)):
return obj.isoformat()
elif isinstance(obj, (list, set, tuple)):
r = []
for item in obj:
r.append(json.loads(json.dumps(item, cls=JSON)))
return r
return [json.loads(json.dumps(item, cls=JSON)) for item in obj]
else:
return obj

View File

@ -131,7 +131,10 @@ def product_name() -> Optional[str]:
def mem_info():
# This implementation is from https://stackoverflow.com/a/28161352
return dict((i.split()[0].rstrip(':'), int(i.split()[1])) for i in open('/proc/meminfo').readlines())
return {
i.split()[0].rstrip(':'): int(i.split()[1])
for i in open('/proc/meminfo').readlines()
}
def mem_available() -> Optional[str]:

View File

@ -409,7 +409,7 @@ class Installer:
return True
def add_bootloader(self, bootloader='systemd-bootctl'):
def add_bootloader(self, _device, bootloader='systemd-bootctl'):
for plugin in plugins.values():
if hasattr(plugin, 'on_add_bootloader'):
# Allow plugins to override the boot-loader handling.
@ -500,7 +500,16 @@ class Installer:
self.helper_flags['bootloader'] = bootloader
elif bootloader == "grub-install":
self.pacstrap('grub')
self.pacstrap('grub') # no need?
if real_device := self.detect_encryption(root_partition):
_file = "/etc/default/grub"
root_uuid = SysCommand(f"blkid -s UUID -o value {real_device.path}").decode().rstrip()
add_to_CMDLINE_LINUX = f"sed -i 's/GRUB_CMDLINE_LINUX=\"\"/GRUB_CMDLINE_LINUX=\"cryptdevice=UUID={root_uuid}:cryptlvm\"/'"
enable_CRYPTODISK = "sed -i 's/#GRUB_ENABLE_CRYPTODISK=y/GRUB_ENABLE_CRYPTODISK=y/'"
SysCommand(f"/usr/bin/arch-chroot {self.target} {add_to_CMDLINE_LINUX} {_file}")
SysCommand(f"/usr/bin/arch-chroot {self.target} {enable_CRYPTODISK} {_file}")
if has_uefi():
self.pacstrap('efibootmgr')
@ -509,10 +518,7 @@ class Installer:
self.helper_flags['bootloader'] = True
return True
else:
root_device = subprocess.check_output(f'basename "$(readlink -f /sys/class/block/{root_partition.path.replace("/dev/", "")}/..)"', shell=True).decode().strip()
if root_device == "block":
root_device = f"{root_partition.path}"
o = b''.join(SysCommand(f'/usr/bin/arch-chroot {self.target} grub-install --target=i386-pc /dev/{root_device}'))
o = b''.join(SysCommand(f'/usr/bin/arch-chroot {self.target} grub-install --target=i386-pc --recheck {_device.path}'))
SysCommand('/usr/bin/arch-chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg')
self.helper_flags['bootloader'] = True
else:

View File

@ -59,9 +59,7 @@ def filter_mirrors_by_region(regions, destination='/etc/pacman.d/mirrorlist', so
:param regions: A series of country codes separated by `,`. For instance `SE,US` for sweden and United States.
:type regions: str
"""
region_list = []
for region in regions.split(','):
region_list.append(f'country={region}')
region_list = [f'country={region}' for region in regions.split(',')]
response = urllib.request.urlopen(urllib.request.Request(f"https://archlinux.org/mirrorlist/?{'&'.join(region_list)}&protocol=https&protocol=http&ip_version=4&ip_version=6&use_mirror_status=on'", headers={'User-Agent': 'ArchInstall'}))
new_list = response.read().replace(b"#Server", b"Server")

View File

@ -46,10 +46,7 @@ def find_packages(*names):
The function itself is rather slow, so consider not sending to
many packages to the search query.
"""
result = {}
for package in names:
result[package] = find_package(package)
return result
return {package: find_package(package) for package in names}
def validate_package_list(packages: list):
@ -57,11 +54,11 @@ def validate_package_list(packages: list):
Validates a list of given packages.
Raises `RequirementError` if one or more packages are not found.
"""
invalid_packages = []
for package in packages:
if not find_package(package)['results'] and not find_group(package):
invalid_packages.append(package)
invalid_packages = [
package
for package in packages
if not find_package(package)['results'] and not find_group(package)
]
if invalid_packages:
raise RequirementError(f"Invalid package names: {invalid_packages}")

View File

@ -710,7 +710,8 @@ def select_driver(options=AVAILABLE_GFX_DRIVERS):
if has_nvidia_graphics():
print('For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.')
arguments['gfx_driver'] = generic_select(drivers, input_text="Select a graphics driver or leave blank to install all open-source drivers: ")
if not arguments.get('gfx_driver', None):
arguments['gfx_driver'] = generic_select(drivers, input_text="Select a graphics driver or leave blank to install all open-source drivers: ")
if arguments.get('gfx_driver', None) is None:
arguments['gfx_driver'] = "All open-source (default)"

View File

@ -7,9 +7,7 @@ sys.path.insert(0, os.path.abspath('..'))
def process_docstring(app, what, name, obj, options, lines):
spaces_pat = re.compile(r"( {8})")
ll = []
for line in lines:
ll.append(spaces_pat.sub(" ", line))
ll = [spaces_pat.sub(" ", line) for line in lines]
lines[:] = ll

View File

@ -26,7 +26,33 @@ archinstall.log(f"Graphics devices detected: {archinstall.graphics_devices().key
# For support reasons, we'll log the disk layout pre installation to match against post-installation layout
archinstall.log(f"Disk states before installing: {archinstall.disk_layouts()}", level=logging.DEBUG)
def load_config():
if archinstall.arguments.get('harddrive', None) is not None:
archinstall.arguments['harddrive'] = archinstall.BlockDevice(path=archinstall.arguments['harddrive']['path'])
# Temporarily disabling keep_partitions if config file is loaded
archinstall.arguments['harddrive'].keep_partitions = False
# Temporary workaround to make Desktop Environments work
if archinstall.arguments.get('profile', None) is not None:
if type(archinstall.arguments.get('profile', None)) is dict:
archinstall.arguments['profile'] = archinstall.Profile(None, archinstall.arguments.get('profile', None)['path'])
else:
archinstall.arguments['profile'] = archinstall.Profile(None, archinstall.arguments.get('profile', None))
archinstall.storage['_desktop_profile'] = archinstall.arguments.get('desktop-environment', None)
if archinstall.arguments.get('mirror-region', None) is not None:
if type(archinstall.arguments.get('mirror-region', None)) is dict:
archinstall.arguments['mirror-region'] = archinstall.arguments.get('mirror-region', None)
else:
selected_region = archinstall.arguments.get('mirror-region', None)
archinstall.arguments['mirror-region'] = {selected_region: archinstall.list_mirrors()[selected_region]}
if archinstall.arguments.get('sys-language', None) is not None:
archinstall.arguments['sys-language'] = archinstall.arguments.get('sys-language', 'en_US')
if archinstall.arguments.get('sys-encoding', None) is not None:
archinstall.arguments['sys-encoding'] = archinstall.arguments.get('sys-encoding', 'utf-8')
if archinstall.arguments.get('gfx_driver', None) is not None:
archinstall.storage['gfx_driver_packages'] = AVAILABLE_GFX_DRIVERS.get(archinstall.arguments.get('gfx_driver', None), None)
if archinstall.arguments.get('servers', None) is not None:
archinstall.storage['_selected_servers'] = archinstall.arguments.get('servers', None)
def ask_user_questions():
"""
First, we'll ask the user for a bunch of user input.
@ -54,9 +80,6 @@ def ask_user_questions():
break
except archinstall.RequirementError as e:
archinstall.log(e, fg="red")
else:
selected_region = archinstall.arguments['mirror-region']
archinstall.arguments['mirror-region'] = {selected_region: archinstall.list_mirrors()[selected_region]}
if not archinstall.arguments.get('sys-language', None) and archinstall.arguments.get('advanced', False):
archinstall.arguments['sys-language'] = input("Enter a valid locale (language) for your OS, (Default: en_US): ").strip()
@ -69,9 +92,7 @@ def ask_user_questions():
archinstall.arguments['sys-encoding'] = 'utf-8'
# Ask which harddrive/block-device we will install to
if archinstall.arguments.get('harddrive', None):
archinstall.arguments['harddrive'] = archinstall.BlockDevice(archinstall.arguments['harddrive'])
else:
if not archinstall.arguments.get('harddrive', None):
archinstall.arguments['harddrive'] = archinstall.select_disk(archinstall.all_disks())
if archinstall.arguments['harddrive'] is None:
archinstall.arguments['target-mount'] = archinstall.storage.get('MOUNT_POINT', '/mnt')
@ -188,20 +209,15 @@ def ask_user_questions():
archinstall.arguments['!root-password'] = archinstall.get_password(prompt='Enter root password (Recommendation: leave blank to leave root disabled): ')
# Ask for additional users (super-user if root pw was not set)
archinstall.arguments['users'] = {}
archinstall.arguments['superusers'] = {}
if not archinstall.arguments.get('!root-password', None):
if not archinstall.arguments.get('!root-password', None) and not archinstall.arguments.get('superusers', None):
archinstall.arguments['superusers'] = archinstall.ask_for_superuser_account('Create a required super-user with sudo privileges: ', forced=True)
users, superusers = archinstall.ask_for_additional_users('Enter a username to create a additional user (leave blank to skip & continue): ')
archinstall.arguments['users'] = users
archinstall.arguments['superusers'] = {**archinstall.arguments['superusers'], **superusers}
users, superusers = archinstall.ask_for_additional_users('Enter a username to create a additional user (leave blank to skip & continue): ')
archinstall.arguments['users'] = users
archinstall.arguments['superusers'] = {**archinstall.arguments['superusers'], **superusers}
# Ask for archinstall-specific profiles (such as desktop environments etc)
if not archinstall.arguments.get('profile', None):
archinstall.arguments['profile'] = archinstall.select_profile()
else:
archinstall.arguments['profile'] = Profile(installer=None, path=archinstall.arguments['profile'])
# Check the potentially selected profiles preparations to get early checks if some additional questions are needed.
if archinstall.arguments['profile'] and archinstall.arguments['profile'].has_prep_function():
@ -266,7 +282,7 @@ def perform_installation_steps():
config_file.write(user_configuration)
print()
if archinstall.arguments.get('dry_run'):
if archinstall.arguments.get('dry-run'):
exit(0)
if not archinstall.arguments.get('silent'):
@ -322,8 +338,7 @@ def perform_installation_steps():
else:
fs.find_partition('/').mount(archinstall.storage.get('MOUNT_POINT', '/mnt'))
if has_uefi():
fs.find_partition('/boot').mount(archinstall.storage.get('MOUNT_POINT', '/mnt') + '/boot')
fs.find_partition('/boot').mount(archinstall.storage.get('MOUNT_POINT', '/mnt') + '/boot')
perform_installation(archinstall.storage.get('MOUNT_POINT', '/mnt'))
@ -352,7 +367,7 @@ def perform_installation(mountpoint):
installation.set_mirrors(archinstall.arguments['mirror-region']) # Set the mirrors in the installation medium
if archinstall.arguments["bootloader"] == "grub-install" and has_uefi():
installation.add_additional_packages("grub")
installation.add_bootloader(archinstall.arguments["bootloader"])
installation.add_bootloader(archinstall.arguments["harddrive"], archinstall.arguments["bootloader"])
# If user selected to copy the current ISO network configuration
# Perform a copy of the config
@ -437,33 +452,8 @@ if not check_mirror_reachable():
archinstall.log(f"Arch Linux mirrors are not reachable. Please check your internet connection and the log file '{log_file}'.", level=logging.INFO, fg="red")
exit(1)
load_config()
if not archinstall.arguments.get('silent'):
ask_user_questions()
else:
# Workarounds if config is loaded from a file
# The harddrive section should be moved to perform_installation_steps, where it's actually being performed
# Blockdevice object should be created in perform_installation_steps
# This needs to be done until then
archinstall.arguments['harddrive'] = archinstall.BlockDevice(path=archinstall.arguments['harddrive']['path'])
# Temporarily disabling keep_partitions if config file is loaded
archinstall.arguments['harddrive'].keep_partitions = False
# Temporary workaround to make Desktop Environments work
if archinstall.arguments.get('profile', None) is not None:
if type(archinstall.arguments.get('profile', None)) is dict:
archinstall.arguments['profile'] = archinstall.Profile(None, archinstall.arguments.get('profile', None)['path'])
else:
archinstall.arguments['profile'] = archinstall.Profile(None, archinstall.arguments.get('profile', None))
else:
archinstall.arguments['profile'] = None
if archinstall.arguments.get('mirror-region', None) is not None:
if type(archinstall.arguments.get('mirror-region', None)) is dict:
archinstall.arguments['mirror-region'] = archinstall.arguments.get('mirror-region', None)
else:
selected_region = archinstall.arguments.get('mirror-region', None)
archinstall.arguments['mirror-region'] = {selected_region: archinstall.list_mirrors()[selected_region]}
archinstall.arguments['sys-language'] = archinstall.arguments.get('sys-language', 'en_US')
archinstall.arguments['sys-encoding'] = archinstall.arguments.get('sys-encoding', 'utf-8')
if archinstall.arguments.get('gfx_driver', None) is not None:
archinstall.storage['gfx_driver_packages'] = AVAILABLE_GFX_DRIVERS.get(archinstall.arguments.get('gfx_driver', None), None)
perform_installation_steps()

View File

@ -50,12 +50,11 @@ def _prep_function(*args, **kwargs):
# Temporarily store the selected desktop profile
# in a session-safe location, since this module will get reloaded
# the next time it gets executed.
if '_desktop_profile' not in archinstall.storage.keys():
if not archinstall.storage.get('_desktop_profile', None):
archinstall.storage['_desktop_profile'] = desktop
if not archinstall.arguments.get('desktop-environment', None):
archinstall.arguments['desktop-environment'] = desktop
profile = archinstall.Profile(None, desktop)
# Set the resolved profile path to the actual desktop environment
archinstall.arguments['profile'] = profile
# Loading the instructions with a custom namespace, ensures that a __name__ comparison is never triggered.
with profile.load_instructions(namespace=f"{desktop}.py") as imported:
if hasattr(imported, '_prep_function'):

View File

@ -26,8 +26,9 @@ def _prep_function(*args, **kwargs):
Magic function called by the importing installer
before continuing any further.
"""
selected_servers = archinstall.generic_multi_select(available_servers, "Choose which servers to install and enable (leave blank for a minimal installation): ")
archinstall.storage['_selected_servers'] = selected_servers
if not archinstall.storage.get('_selected_servers', None):
selected_servers = archinstall.generic_multi_select(available_servers, "Choose which servers to install and enable (leave blank for a minimal installation): ")
archinstall.storage['_selected_servers'] = selected_servers
return True