From 6a125d5bd2e5e0c27dc1feb3598e2e60a0526dd8 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Sat, 18 Sep 2021 11:22:18 +0200 Subject: Adding in options for BTRFS subvolumes --- examples/guided.py | 1 + 1 file changed, 1 insertion(+) (limited to 'examples') diff --git a/examples/guided.py b/examples/guided.py index b7c75b30..afe648e7 100644 --- a/examples/guided.py +++ b/examples/guided.py @@ -116,6 +116,7 @@ def ask_user_questions(): if archinstall.arguments.get('harddrives', None) is not None and archinstall.storage.get('disk_layouts', None) is None: archinstall.storage['disk_layouts'] = archinstall.select_disk_layout(archinstall.arguments['harddrives']) + archinstall.disk_layout_filesystem_checks(archinstall.storage['disk_layouts']) # Get disk encryption password (or skip if blank) if archinstall.arguments['harddrives'] and archinstall.arguments.get('!encryption-password', None) is None: -- cgit v1.2.3-70-g09d2 From ed823be3bae2151a73ba9817a32c226ac5a3c1c0 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Sat, 18 Sep 2021 15:52:29 +0200 Subject: Refactoring and cleaning up a bit I'm making sure that the JSON structure of the user config can get a say in how the subvolumes should be used later on. As well as splitting up where the logic should be to make it easier to maintain. --- archinstall/lib/disk.py | 35 +++++++++++++++++++++-------------- archinstall/lib/disk2/btrfs.py | 11 +++-------- examples/guided.py | 1 - 3 files changed, 24 insertions(+), 23 deletions(-) (limited to 'examples') diff --git a/archinstall/lib/disk.py b/archinstall/lib/disk.py index be5b9edb..740fd4ce 100644 --- a/archinstall/lib/disk.py +++ b/archinstall/lib/disk.py @@ -111,19 +111,6 @@ def select_disk_larger_than_or_close_to(devices, gigabytes, filter_out=None): return min(copy_devices, key=(lambda device : abs(device.size - gigabytes))) -def disk_layout_filesystem_checks(layout): - # This can probably be compressed into a any() - options = {} - for block_device in layout: - for partition in block_device.get('partitions', []): - if partition.get('filesystem', {}).get('format', False) == 'btrfs': - if not partition['filesystem'].get('subvolume', None): - if not options.get('btrfs-subvolumes', None) is None: - options['btrfs-subvolumes'] = input('Would you like to use BTRFS subvolumes? (Y/n)').strip().lower() in ('', 'y', 'yes') - - if options['btrfs-subvolumes']: - btrfs.create_subvolume(partition) - def suggest_single_disk_layout(block_device, default_filesystem=None): if not default_filesystem: from .user_interaction import ask_for_main_filesystem_format @@ -164,7 +151,23 @@ def suggest_single_disk_layout(block_device, default_filesystem=None): } }) - if block_device.size >= MIN_SIZE_TO_ALLOW_HOME_PART: + if default_filesystem == 'btrfs' and input('Would you like to use BTRFS subvolumes? (Y/n)').strip().lower() in ('', 'y', 'yes'): + # https://btrfs.wiki.kernel.org/index.php/FAQ + # https://unix.stackexchange.com/questions/246976/btrfs-subvolume-uuid-clash + # https://github.com/classy-giraffe/easy-arch/blob/main/easy-arch.sh + layout[block_device.path]['partitions'][1]['btrfs'] = { + "subvolumes" : { + '@home' : '/home', + '@log' : '/var/log', + '@pkgs' : '/var/cache/pacman/pkg', + '@.snapshots' : '/.snapshots' + } + } + + elif block_device.size >= MIN_SIZE_TO_ALLOW_HOME_PART: + # If we don't want to use subvolumes, + # But we want to be able to re-use data between re-installs.. + # A second partition for /home would be nice if we have the space for it layout[block_device.path]['partitions'].append({ # Home "type" : "primary", @@ -186,6 +189,10 @@ def suggest_multi_disk_layout(block_devices, default_filesystem=None): from .user_interaction import ask_for_main_filesystem_format default_filesystem = ask_for_main_filesystem_format() + # Not really a rock solid foundation of information to stand on, but it's a start: + # https://www.reddit.com/r/btrfs/comments/m287gp/partition_strategy_for_two_physical_disks/ + # https://www.reddit.com/r/btrfs/comments/9us4hr/what_is_your_btrfs_partitionsubvolumes_scheme/ + MIN_SIZE_TO_ALLOW_HOME_PART = 40 # Gb ARCH_LINUX_INSTALLED_SIZE = 20 # Gb, rough estimate taking in to account user desktops etc. TODO: Catch user packages to detect size? diff --git a/archinstall/lib/disk2/btrfs.py b/archinstall/lib/disk2/btrfs.py index 549d23c1..d6758b3f 100644 --- a/archinstall/lib/disk2/btrfs.py +++ b/archinstall/lib/disk2/btrfs.py @@ -1,9 +1,4 @@ -def create_subvolume(partition): - if partition['mountpoint'] == '/': - partition['filesystem']['subvolume'] = '@' - elif partition['mountpoint'] == '/home': - partition['filesystem']['subvolume'] = '@home' +from ..general import SysCommand - # @.snapshots /.snapshots - # @log /var/log - # @pkg /var/cache/pacman/pkg \ No newline at end of file +def create_subvolume(installation): + SysCommand(f"btrfs subvolume create {installation.target}/@") \ No newline at end of file diff --git a/examples/guided.py b/examples/guided.py index afe648e7..b7c75b30 100644 --- a/examples/guided.py +++ b/examples/guided.py @@ -116,7 +116,6 @@ def ask_user_questions(): if archinstall.arguments.get('harddrives', None) is not None and archinstall.storage.get('disk_layouts', None) is None: archinstall.storage['disk_layouts'] = archinstall.select_disk_layout(archinstall.arguments['harddrives']) - archinstall.disk_layout_filesystem_checks(archinstall.storage['disk_layouts']) # Get disk encryption password (or skip if blank) if archinstall.arguments['harddrives'] and archinstall.arguments.get('!encryption-password', None) is None: -- cgit v1.2.3-70-g09d2 From 7149b76f3bd3163938fe7413546e5f678f98851f Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Fri, 22 Oct 2021 21:54:16 +0200 Subject: Forgot some imports that didn't show up on a static run without going through a few of the menu's --- archinstall/lib/disk/__init__.py | 2 +- archinstall/lib/disk/blockdevice.py | 3 +++ archinstall/lib/disk/filesystem.py | 6 +++++- archinstall/lib/disk/helpers.py | 2 ++ archinstall/lib/disk/partition.py | 4 ++++ archinstall/lib/disk/user_guides.py | 4 ++-- examples/guided.py | 6 +++--- 7 files changed, 20 insertions(+), 7 deletions(-) (limited to 'examples') diff --git a/archinstall/lib/disk/__init__.py b/archinstall/lib/disk/__init__.py index 8237f774..352d04b9 100644 --- a/archinstall/lib/disk/__init__.py +++ b/archinstall/lib/disk/__init__.py @@ -1,7 +1,7 @@ from .btrfs import * from .helpers import * from .blockdevice import BlockDevice -from .filesystem import Filesystem +from .filesystem import Filesystem, MBR, GPT from .partition import * from .user_guides import * from .validators import * \ No newline at end of file diff --git a/archinstall/lib/disk/blockdevice.py b/archinstall/lib/disk/blockdevice.py index daa65323..57cbcfa6 100644 --- a/archinstall/lib/disk/blockdevice.py +++ b/archinstall/lib/disk/blockdevice.py @@ -1,3 +1,4 @@ +import os import json import logging from ..output import log @@ -94,6 +95,7 @@ class BlockDevice: @property def partitions(self): + from .filesystem import Partition SysCommand(['partprobe', self.path]) result = SysCommand(['/usr/bin/lsblk', '-J', self.path]) @@ -123,6 +125,7 @@ class BlockDevice: @property def partition_table_type(self): + from .filesystem import GPT return GPT @property diff --git a/archinstall/lib/disk/filesystem.py b/archinstall/lib/disk/filesystem.py index b53d8451..28846764 100644 --- a/archinstall/lib/disk/filesystem.py +++ b/archinstall/lib/disk/filesystem.py @@ -1,7 +1,11 @@ import time +import logging +import json from .partition import Partition from .blockdevice import BlockDevice +from ..general import SysCommand from ..output import log +from ..storage import storage GPT = 0b00000001 MBR = 0b00000010 @@ -58,7 +62,7 @@ class Filesystem: return index def load_layout(self, layout :dict): - from .luks import luks2 + from ..luks import luks2 # If the layout tells us to wipe the drive, we do so if layout.get('wipe', False): diff --git a/archinstall/lib/disk/helpers.py b/archinstall/lib/disk/helpers.py index 8b372f73..65abdea2 100644 --- a/archinstall/lib/disk/helpers.py +++ b/archinstall/lib/disk/helpers.py @@ -132,6 +132,8 @@ def get_mount_info(path) -> dict: def get_partitions_in_use(mountpoint) -> list: + from .partition import Partition + try: output = SysCommand(f"/usr/bin/findmnt --json -R {mountpoint}").decode('UTF-8') except SysCallError: diff --git a/archinstall/lib/disk/partition.py b/archinstall/lib/disk/partition.py index 30151583..3bb2982b 100644 --- a/archinstall/lib/disk/partition.py +++ b/archinstall/lib/disk/partition.py @@ -2,9 +2,13 @@ import glob import pathlib import time import logging +import json +import os from typing import Optional from .blockdevice import BlockDevice +from .helpers import get_mount_info, get_filesystem_type from ..output import log +from ..general import SysCommand class Partition: def __init__(self, path: str, block_device: BlockDevice, part_id=None, size=-1, filesystem=None, mountpoint=None, encrypted=False, autodetect_filesystem=True): diff --git a/archinstall/lib/disk/user_guides.py b/archinstall/lib/disk/user_guides.py index 0a975149..79b9d48f 100644 --- a/archinstall/lib/disk/user_guides.py +++ b/archinstall/lib/disk/user_guides.py @@ -3,7 +3,7 @@ from ..output import log def suggest_single_disk_layout(block_device, default_filesystem=None): if not default_filesystem: - from .user_interaction import ask_for_main_filesystem_format + from ..user_interaction import ask_for_main_filesystem_format default_filesystem = ask_for_main_filesystem_format() MIN_SIZE_TO_ALLOW_HOME_PART = 40 # Gb @@ -76,7 +76,7 @@ def suggest_single_disk_layout(block_device, default_filesystem=None): def suggest_multi_disk_layout(block_devices, default_filesystem=None): if not default_filesystem: - from .user_interaction import ask_for_main_filesystem_format + from ..user_interaction import ask_for_main_filesystem_format default_filesystem = ask_for_main_filesystem_format() # Not really a rock solid foundation of information to stand on, but it's a start: diff --git a/examples/guided.py b/examples/guided.py index b7c75b30..2efb4972 100644 --- a/examples/guided.py +++ b/examples/guided.py @@ -140,7 +140,7 @@ def ask_user_questions(): # Ask for a root password (optional, but triggers requirement for super-user if skipped) if not archinstall.arguments.get('!root-password', None): - archinstall.arguments['!root-password'] = archinstall.get_password(prompt='Enter root password (Recommendation: leave blank to leave root disabled): ') + archinstall.arguments['!root-password'] = archinstall.get_password(prompt='Enter root password (leave blank to disable disabled & create superuser): ') # Ask for additional users (super-user if root pw was not set) @@ -245,9 +245,9 @@ def perform_filesystem_operations(): Setup the blockdevice, filesystem (and optionally encryption). Once that's done, we'll hand over to perform_installation() """ - mode = archinstall.GPT + mode = archinstall.disk.GPT if has_uefi() is False: - mode = archinstall.MBR + mode = archinstall.disk.MBR for drive in archinstall.arguments['harddrives']: with archinstall.Filesystem(drive, mode) as fs: -- cgit v1.2.3-70-g09d2 From 05a8739231412ca1ce866e8f8b1636b3e7b94ebe Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Sat, 30 Oct 2021 12:02:00 +0200 Subject: Wrong exposed variable corrected. --- examples/guided.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'examples') diff --git a/examples/guided.py b/examples/guided.py index 2efb4972..f8791c9b 100644 --- a/examples/guided.py +++ b/examples/guided.py @@ -245,9 +245,9 @@ def perform_filesystem_operations(): Setup the blockdevice, filesystem (and optionally encryption). Once that's done, we'll hand over to perform_installation() """ - mode = archinstall.disk.GPT + mode = archinstall.GPT if has_uefi() is False: - mode = archinstall.disk.MBR + mode = archinstall.MBR for drive in archinstall.arguments['harddrives']: with archinstall.Filesystem(drive, mode) as fs: -- cgit v1.2.3-70-g09d2