Merge branch 'master' of github.com:archlinux/archinstall into torxed-rework-partitioning
This commit is contained in:
commit
71b6efab69
|
|
@ -61,6 +61,10 @@ def initialize_arguments():
|
|||
|
||||
|
||||
arguments = initialize_arguments()
|
||||
storage['arguments'] = arguments
|
||||
if arguments.get('debug'):
|
||||
log(f"Warning: --debug mode will write certain credentials to {storage['LOG_PATH']}/{storage['LOG_FILE']}!", fg="red", level=logging.WARNING)
|
||||
|
||||
from .lib.plugins import plugins, load_plugin # This initiates the plugin loading ceremony
|
||||
|
||||
if arguments.get('plugin', None):
|
||||
|
|
|
|||
|
|
@ -353,7 +353,8 @@ class Partition:
|
|||
return None
|
||||
|
||||
def has_content(self):
|
||||
if not get_filesystem_type(self.path):
|
||||
fs_type = get_filesystem_type(self.path)
|
||||
if not fs_type or "swap" in fs_type:
|
||||
return False
|
||||
|
||||
temporary_mountpoint = '/tmp/' + hashlib.md5(bytes(f"{time.time()}", 'UTF-8') + os.urandom(12)).hexdigest()
|
||||
|
|
@ -555,7 +556,7 @@ class Filesystem:
|
|||
if SysCommand(f'/usr/bin/parted -s {self.blockdevice.device} mklabel msdos').exit_code == 0:
|
||||
return self
|
||||
else:
|
||||
raise DiskError('Problem setting the partition format to GPT:', f'/usr/bin/parted -s {self.blockdevice.device} mklabel msdos')
|
||||
raise DiskError('Problem setting the partition format to MBR:', f'/usr/bin/parted -s {self.blockdevice.device} mklabel msdos')
|
||||
else:
|
||||
raise DiskError(f'Unknown mode selected to format in: {self.mode}')
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from typing import Union
|
|||
|
||||
from .exceptions import *
|
||||
from .output import log
|
||||
|
||||
from .storage import storage
|
||||
|
||||
def gen_uid(entropy_length=256):
|
||||
return hashlib.sha512(os.urandom(entropy_length)).hexdigest()
|
||||
|
|
@ -265,6 +265,8 @@ class SysCommandWorker:
|
|||
if not self.pid:
|
||||
try:
|
||||
os.execve(self.cmd[0], self.cmd, {**os.environ, **self.environment_vars})
|
||||
if storage['arguments'].get('debug'):
|
||||
log(f"Executing: {self.cmd}", level=logging.DEBUG)
|
||||
except FileNotFoundError:
|
||||
log(f"{self.cmd[0]} does not exist.", level=logging.ERROR, fg="red")
|
||||
self.exit_code = 1
|
||||
|
|
|
|||
|
|
@ -79,22 +79,22 @@ def has_uefi() -> bool:
|
|||
def graphics_devices() -> dict:
|
||||
cards = {}
|
||||
for line in SysCommand("lspci"):
|
||||
if b' VGA ' in line:
|
||||
if b' VGA ' in line or b' 3D ' in line:
|
||||
_, identifier = line.split(b': ', 1)
|
||||
cards[identifier.strip().lower().decode('UTF-8')] = line
|
||||
cards[identifier.strip().decode('UTF-8')] = line
|
||||
return cards
|
||||
|
||||
|
||||
def has_nvidia_graphics() -> bool:
|
||||
return any('nvidia' in x for x in graphics_devices())
|
||||
return any('nvidia' in x.lower() for x in graphics_devices())
|
||||
|
||||
|
||||
def has_amd_graphics() -> bool:
|
||||
return any('amd' in x for x in graphics_devices())
|
||||
return any('amd' in x.lower() for x in graphics_devices())
|
||||
|
||||
|
||||
def has_intel_graphics() -> bool:
|
||||
return any('intel' in x for x in graphics_devices())
|
||||
return any('intel' in x.lower() for x in graphics_devices())
|
||||
|
||||
|
||||
def cpu_vendor() -> Optional[str]:
|
||||
|
|
@ -107,6 +107,47 @@ def cpu_vendor() -> Optional[str]:
|
|||
return None
|
||||
|
||||
|
||||
def cpu_model() -> Optional[str]:
|
||||
cpu_info_raw = SysCommand("lscpu -J")
|
||||
cpu_info = json.loads(b"".join(cpu_info_raw).decode('UTF-8'))['lscpu']
|
||||
|
||||
for info in cpu_info:
|
||||
if info.get('field', None) == "Model name:":
|
||||
return info.get('data', None)
|
||||
return None
|
||||
|
||||
|
||||
def sys_vendor() -> Optional[str]:
|
||||
with open(f"/sys/devices/virtual/dmi/id/sys_vendor") as vendor:
|
||||
return vendor.read().strip()
|
||||
|
||||
|
||||
def product_name() -> Optional[str]:
|
||||
with open(f"/sys/devices/virtual/dmi/id/product_name") as product:
|
||||
return product.read().strip()
|
||||
|
||||
|
||||
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())
|
||||
|
||||
|
||||
def mem_available() -> Optional[str]:
|
||||
return mem_info()['MemAvailable']
|
||||
|
||||
|
||||
def mem_free() -> Optional[str]:
|
||||
return mem_info()['MemFree']
|
||||
|
||||
|
||||
def mem_total() -> Optional[str]:
|
||||
return mem_info()['MemTotal']
|
||||
|
||||
|
||||
def virtualization() -> Optional[str]:
|
||||
return str(SysCommand("systemd-detect-virt")).strip('\r\n')
|
||||
|
||||
|
||||
def is_vm() -> bool:
|
||||
try:
|
||||
# systemd-detect-virt issues a non-zero exit code if it is not on a virtual machine
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ from .disk import *
|
|||
from .hardware import *
|
||||
from .locale_helpers import verify_keyboard_layout, verify_x11_keyboard_layout
|
||||
from .mirrors import *
|
||||
from .storage import storage
|
||||
from .plugins import plugins
|
||||
from .storage import storage
|
||||
from .user_interaction import *
|
||||
|
||||
# Any package that the Installer() is responsible for (optional and the default ones)
|
||||
|
|
@ -40,6 +40,7 @@ class Installer:
|
|||
base_packages = __packages__[:3]
|
||||
if kernels is None:
|
||||
kernels = ['linux']
|
||||
self.kernels = kernels
|
||||
self.target = target
|
||||
self.init_time = time.strftime('%Y-%m-%d_%H-%M-%S')
|
||||
self.milliseconds = int(str(time.time()).split('.')[1])
|
||||
|
|
@ -440,6 +441,10 @@ class Installer:
|
|||
# Fallback, try creating the boot loader without touching the EFI variables
|
||||
SysCommand(f'/usr/bin/arch-chroot {self.target} bootctl --no-variables --path=/boot install')
|
||||
|
||||
# Ensure that the /boot/loader directory exists before we try to create files in it
|
||||
if not os.path.exists(f'{self.target}/boot/loader'):
|
||||
os.makedirs(f'{self.target}/boot/loader')
|
||||
|
||||
# Modify or create a loader.conf
|
||||
if os.path.isfile(f'{self.target}/boot/loader/loader.conf'):
|
||||
with open(f'{self.target}/boot/loader/loader.conf', 'r') as loader:
|
||||
|
|
@ -453,45 +458,46 @@ class Installer:
|
|||
with open(f'{self.target}/boot/loader/loader.conf', 'w') as loader:
|
||||
for line in loader_data:
|
||||
if line[:8] == 'default ':
|
||||
loader.write(f'default {self.init_time}\n')
|
||||
loader.write(f'default {self.init_time}_{self.kernels[0]}\n')
|
||||
elif line[:8] == '#timeout' and 'timeout 5' not in loader_data:
|
||||
# We add in the default timeout to support dual-boot
|
||||
loader.write(f"{line[1:]}\n")
|
||||
else:
|
||||
loader.write(f"{line}\n")
|
||||
|
||||
# For some reason, blkid and /dev/disk/by-uuid are not getting along well.
|
||||
# And blkid is wrong in terms of LUKS.
|
||||
# UUID = sys_command('blkid -s PARTUUID -o value {drive}{partition_2}'.format(**args)).decode('UTF-8').strip()
|
||||
# Setup the loader entry
|
||||
with open(f'{self.target}/boot/loader/entries/{self.init_time}.conf', 'w') as entry:
|
||||
entry.write('# Created by: archinstall\n')
|
||||
entry.write(f'# Created on: {self.init_time}\n')
|
||||
entry.write('title Arch Linux\n')
|
||||
entry.write('linux /vmlinuz-linux\n')
|
||||
if not is_vm():
|
||||
vendor = cpu_vendor()
|
||||
if vendor == "AuthenticAMD":
|
||||
entry.write("initrd /amd-ucode.img\n")
|
||||
elif vendor == "GenuineIntel":
|
||||
entry.write("initrd /intel-ucode.img\n")
|
||||
# Ensure that the /boot/loader/entries directory exists before we try to create files in it
|
||||
if not os.path.exists(f'{self.target}/boot/loader/entries'):
|
||||
os.makedirs(f'{self.target}/boot/loader/entries')
|
||||
|
||||
for kernel in self.kernels:
|
||||
# Setup the loader entry
|
||||
with open(f'{self.target}/boot/loader/entries/{self.init_time}_{kernel}.conf', 'w') as entry:
|
||||
entry.write('# Created by: archinstall\n')
|
||||
entry.write(f'# Created on: {self.init_time}\n')
|
||||
entry.write('title Arch Linux\n')
|
||||
entry.write(f"linux /vmlinuz-{kernel}\n")
|
||||
if not is_vm():
|
||||
vendor = cpu_vendor()
|
||||
if vendor == "AuthenticAMD":
|
||||
entry.write("initrd /amd-ucode.img\n")
|
||||
elif vendor == "GenuineIntel":
|
||||
entry.write("initrd /intel-ucode.img\n")
|
||||
else:
|
||||
self.log("unknow cpu vendor, not adding ucode to systemd-boot config")
|
||||
entry.write(f"initrd /initramfs-{kernel}.img\n")
|
||||
# blkid doesn't trigger on loopback devices really well,
|
||||
# so we'll use the old manual method until we get that sorted out.
|
||||
|
||||
if real_device := self.detect_encryption(root_partition):
|
||||
# TODO: We need to detect if the encrypted device is a whole disk encryption,
|
||||
# or simply a partition encryption. Right now we assume it's a partition (and we always have)
|
||||
log(f"Identifying root partition by PART-UUID on {real_device}: '{real_device.uuid}'.", level=logging.DEBUG)
|
||||
entry.write(f'options cryptdevice=PARTUUID={real_device.uuid}:luksdev root=/dev/mapper/luksdev rw intel_pstate=no_hwp {" ".join(self.KERNEL_PARAMS)}\n')
|
||||
else:
|
||||
self.log("unknow cpu vendor, not adding ucode to systemd-boot config")
|
||||
entry.write('initrd /initramfs-linux.img\n')
|
||||
# blkid doesn't trigger on loopback devices really well,
|
||||
# so we'll use the old manual method until we get that sorted out.
|
||||
log(f"Identifying root partition by PART-UUID on {root_partition}, looking for '{root_partition.uuid}'.", level=logging.DEBUG)
|
||||
entry.write(f'options root=PARTUUID={root_partition.uuid} rw intel_pstate=no_hwp {" ".join(self.KERNEL_PARAMS)}\n')
|
||||
|
||||
if real_device := self.detect_encryption(root_partition):
|
||||
# TODO: We need to detect if the encrypted device is a whole disk encryption,
|
||||
# or simply a partition encryption. Right now we assume it's a partition (and we always have)
|
||||
log(f"Identifying root partition by PART-UUID on {real_device}: '{real_device.uuid}'.", level=logging.DEBUG)
|
||||
entry.write(f'options cryptdevice=PARTUUID={real_device.uuid}:luksdev root=/dev/mapper/luksdev rw intel_pstate=no_hwp {" ".join(self.KERNEL_PARAMS)}\n')
|
||||
else:
|
||||
log(f"Identifying root partition by PART-UUID on {root_partition}, looking for '{root_partition.uuid}'.", level=logging.DEBUG)
|
||||
entry.write(f'options root=PARTUUID={root_partition.uuid} rw intel_pstate=no_hwp {" ".join(self.KERNEL_PARAMS)}\n')
|
||||
|
||||
self.helper_flags['bootloader'] = bootloader
|
||||
return True
|
||||
self.helper_flags['bootloader'] = bootloader
|
||||
|
||||
elif bootloader == "grub-install":
|
||||
self.pacstrap('grub')
|
||||
|
|
@ -509,10 +515,11 @@ class Installer:
|
|||
o = b''.join(SysCommand(f'/usr/bin/arch-chroot {self.target} grub-install --target=i386-pc /dev/{root_device}'))
|
||||
SysCommand('/usr/bin/arch-chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg')
|
||||
self.helper_flags['bootloader'] = True
|
||||
return True
|
||||
else:
|
||||
raise RequirementError(f"Unknown (or not yet implemented) bootloader requested: {bootloader}")
|
||||
|
||||
return True
|
||||
|
||||
def add_additional_packages(self, *packages):
|
||||
return self.pacstrap(*packages)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ plugins = {}
|
|||
# 1: List archinstall.plugin definitions
|
||||
# 2: Load the plugin entrypoint
|
||||
# 3: Initiate the plugin and store it as .name in plugins
|
||||
for plugin_definition in metadata.entry_points()['archinstall.plugin']:
|
||||
for plugin_definition in metadata.entry_points().get('archinstall.plugin', []):
|
||||
plugin_entrypoint = plugin_definition.load()
|
||||
try:
|
||||
plugins[plugin_definition.name] = plugin_entrypoint()
|
||||
|
|
|
|||
|
|
@ -228,6 +228,18 @@ class Profile(Script):
|
|||
# since developers like less code - omitting it should assume they want to present it.
|
||||
return True
|
||||
|
||||
def get_profile_description(self):
|
||||
with open(self.path, 'r') as source:
|
||||
source_data = source.read()
|
||||
|
||||
if '__description__' in source_data:
|
||||
with self.load_instructions(namespace=f"{self.namespace}.py") as imported:
|
||||
if hasattr(imported, '__description__'):
|
||||
return imported.__description__
|
||||
|
||||
# Default to this string if the profile does not have a description.
|
||||
return "This profile does not have the __description__ attribute set."
|
||||
|
||||
@property
|
||||
def packages(self) -> Optional[list]:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -855,11 +855,11 @@ def select_profile():
|
|||
|
||||
if len(shown_profiles) >= 1:
|
||||
for index, profile in enumerate(shown_profiles):
|
||||
print(f"{index}: {profile}")
|
||||
description = Profile(None, profile).get_profile_description()
|
||||
print(f"{index}: {profile}: {description}")
|
||||
|
||||
print(' -- The above list is a set of pre-programmed profiles. --')
|
||||
print(' -- They might make it easier to install things like desktop environments. --')
|
||||
print(' -- The desktop profile will let you select a DE/WM profile, e.g gnome, kde, sway --')
|
||||
print(' -- (Leave blank and hit enter to skip this step and continue) --')
|
||||
|
||||
selected_profile = generic_select(actual_profiles_raw, 'Enter a pre-programmed profile name if you want to install one: ', options_output=False)
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
Binary file not shown.
|
|
@ -8,7 +8,7 @@
|
|||
],
|
||||
"!encryption-password": "supersecret",
|
||||
"filesystem": "btrfs",
|
||||
"gfx_driver": "VMware / VirtualBox (open-source)",
|
||||
"gfx_driver": "All open-source (default)",
|
||||
"harddrive": {
|
||||
"path": "/dev/nvme0n1"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import time
|
|||
|
||||
import archinstall
|
||||
from archinstall.lib.general import run_custom_user_commands
|
||||
from archinstall.lib.hardware import has_uefi, AVAILABLE_GFX_DRIVERS
|
||||
from archinstall.lib.hardware import *
|
||||
from archinstall.lib.networking import check_mirror_reachable
|
||||
from archinstall.lib.profiles import Profile
|
||||
|
||||
|
|
@ -16,6 +16,13 @@ if os.getuid() != 0:
|
|||
print("Archinstall requires root privileges to run. See --help for more.")
|
||||
exit(1)
|
||||
|
||||
# Log various information about hardware before starting the installation. This might assist in troubleshooting
|
||||
archinstall.log(f"Hardware model detected: {archinstall.sys_vendor()} {archinstall.product_name()}; UEFI mode: {archinstall.has_uefi()}", level=logging.DEBUG)
|
||||
archinstall.log(f"Processor model detected: {archinstall.cpu_model()}", level=logging.DEBUG)
|
||||
archinstall.log(f"Memory statistics: {archinstall.mem_available()} available out of {archinstall.mem_total()} total installed", level=logging.DEBUG)
|
||||
archinstall.log(f"Virtualization detected: {archinstall.virtualization()}; is VM: {archinstall.is_vm()}", level=logging.DEBUG)
|
||||
archinstall.log(f"Graphics devices detected: {archinstall.graphics_devices().keys()}", level=logging.DEBUG)
|
||||
|
||||
# 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)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue