diff --git a/vanilla_installer/core/disks.py b/vanilla_installer/core/disks.py index 5fc70125..bc354a1f 100644 --- a/vanilla_installer/core/disks.py +++ b/vanilla_installer/core/disks.py @@ -1,6 +1,7 @@ +import json import os import subprocess -import json + class Diskutils: @staticmethod @@ -13,29 +14,29 @@ def pretty_size(size: int) -> str: return f"{round(size / 1024, 2)} KB" else: return f"{size} B" - + @staticmethod - def separate_device_and_partn(part_dev: str) -> tuple[str, str|None]: + def separate_device_and_partn(part_dev: str) -> tuple[str, str | None]: info_json = subprocess.check_output( "lsblk --json -o NAME,PKNAME,PARTN " + part_dev, shell=True ).decode("utf-8") info_multiple = json.loads(info_json)["blockdevices"] - + if len(info_multiple) > 1: - raise ValueError(f'{part_dev} returned more than one device') + raise ValueError(f"{part_dev} returned more than one device") info = info_multiple[0] - - if info["partn"] == None: + + if info["partn"] is None: # part_dev is actually a device, not a partition return "/dev/" + info["name"], None - + return "/dev/" + info["pkname"], str(info["partn"]) @staticmethod def fetch_lvm_pvs() -> list[list[str]]: - output_json = subprocess.check_output( - "sudo pvs --reportformat=json", shell=True - ).decode("utf-8") + output_json = subprocess.check_output("sudo pvs --reportformat=json", shell=True).decode( + "utf-8" + ) output_pvs = json.loads(output_json)["report"][0]["pv"] pv_with_vgs = [] for pv_output in output_pvs: @@ -44,6 +45,7 @@ def fetch_lvm_pvs() -> list[list[str]]: pv_with_vgs.append([pv_name, vg_name]) return pv_with_vgs + class Disk: def __init__(self, disk: str): self.__disk = disk @@ -101,6 +103,7 @@ def pretty_size(self): else: return f"{size} B" + class Partition: def __init__(self, disk: str, partition: str): self.__disk = disk @@ -114,9 +117,7 @@ def __init__(self, disk: str, partition: str): def __get_mountpoint(self): try: return ( - subprocess.check_output( - f"findmnt -n -o TARGET {self.partition}", shell=True - ) + subprocess.check_output(f"findmnt -n -o TARGET {self.partition}", shell=True) .decode("utf-8") .strip() ) @@ -129,9 +130,7 @@ def __get_size(self): def __get_fs_type(self): try: return ( - subprocess.check_output( - f"lsblk -d -n -o FSTYPE {self.partition}", shell=True - ) + subprocess.check_output(f"lsblk -d -n -o FSTYPE {self.partition}", shell=True) .decode("utf-8") .strip() ) @@ -141,9 +140,7 @@ def __get_fs_type(self): def __get_uuid(self): try: return ( - subprocess.check_output( - f"lsblk -d -n -o UUID {self.partition}", shell=True - ) + subprocess.check_output(f"lsblk -d -n -o UUID {self.partition}", shell=True) .decode("utf-8") .strip() ) @@ -153,9 +150,7 @@ def __get_uuid(self): def __get_label(self): try: return ( - subprocess.check_output( - f"findmnt -n -o LABEL {self.partition}", shell=True - ) + subprocess.check_output(f"findmnt -n -o LABEL {self.partition}", shell=True) .decode("utf-8") .strip() ) @@ -210,6 +205,7 @@ def __eq__(self, other): return False return self.uuid == other.uuid and self.fs_type == other.fs_type + class DisksManager: def __init__(self): self.__disks = self.__get_disks() diff --git a/vanilla_installer/utils/processor.py b/vanilla_installer/utils/processor.py index f84431d0..0119f2f5 100644 --- a/vanilla_installer/utils/processor.py +++ b/vanilla_installer/utils/processor.py @@ -22,8 +22,8 @@ from datetime import datetime from typing import Any, Union -from vanilla_installer.core.system import Systeminfo from vanilla_installer.core.disks import Diskutils +from vanilla_installer.core.system import Systeminfo logger = logging.getLogger("Installer::Processor") @@ -242,8 +242,11 @@ def merge_postinstall_steps(self): class Processor: @staticmethod def __gen_auto_partition_steps( - disk: str, encrypt: bool, root_size: int, - existing_pvs: list[str] | None, existing_vgs: list[str] | None, + disk: str, + encrypt: bool, + root_size: int, + existing_pvs: list[str] | None, + existing_vgs: list[str] | None, password: str | None = None, ): setup_steps = [] @@ -278,9 +281,7 @@ def __gen_auto_partition_steps( # LVM root thin pool setup_steps.append([disk, "lvcreate", ["root", "vos-root", "linear", 19456]]) - setup_steps.append( - [disk, "lvcreate", ["root-meta", "vos-root", "linear", 1024]] - ) + setup_steps.append([disk, "lvcreate", ["root-meta", "vos-root", "linear", 1024]]) setup_steps.append( [ disk, @@ -288,12 +289,8 @@ def __gen_auto_partition_steps( ["vos-root/root", "vos-root/root-meta"], ] ) - setup_steps.append( - [disk, "lvcreate-thin", ["root-a", "vos-root", 19456, "root"]] - ) - setup_steps.append( - [disk, "lvcreate-thin", ["root-b", "vos-root", 19456, "root"]] - ) + setup_steps.append([disk, "lvcreate-thin", ["root-a", "vos-root", 19456, "root"]]) + setup_steps.append([disk, "lvcreate-thin", ["root-b", "vos-root", 19456, "root"]]) setup_steps.append([disk, "lvm-format", ["vos-root/root-a", "btrfs", "vos-a"]]) setup_steps.append([disk, "lvm-format", ["vos-root/root-b", "btrfs", "vos-b"]]) @@ -302,9 +299,7 @@ def __gen_auto_partition_steps( lvm_var_args = ["vos-var/var", "btrfs", "vos-var"] if encrypt: lvm_var_args.insert(2, password) - setup_steps.append( - [disk, "lvm-luks-format" if encrypt else "lvm-format", lvm_var_args] - ) + setup_steps.append([disk, "lvm-luks-format" if encrypt else "lvm-format", lvm_var_args]) # Mountpoints if not re.match(r"[0-9]", disk[-1]): @@ -321,12 +316,10 @@ def __gen_auto_partition_steps( mountpoints.append(["/dev/vos-root/root-b", "/"]) mountpoints.append(["/dev/vos-var/var", "/var"]) - return setup_steps, mountpoints, post_install_steps + return setup_steps, mountpoints, post_install_steps, disk @staticmethod - def __gen_manual_partition_steps( - disk_final: dict, encrypt: bool, password: str | None = None - ): + def __gen_manual_partition_steps(disk_final: dict, encrypt: bool, password: str | None = None): setup_steps = [] mountpoints = [] post_install_steps = [] @@ -341,14 +334,15 @@ def __gen_manual_partition_steps( continue disk, _ = Diskutils.separate_device_and_partn(pv) pvs_to_remove.append([pv, disk]) - if vg is not None and vg not in vgs_to_remove: + if vg is not None and vg not in vgs_to_remove: vgs_to_remove.append([vg, disk]) for vg, disk in vgs_to_remove: - setup_steps.append([disk, "vgremove", [vg]]) + setup_steps.append([disk, "vgremove", [vg]]) for pv, disk in pvs_to_remove: setup_steps.append([disk, "pvremove", [pv]]) + boot_disk = None # Since manual partitioning uses GParted to handle partitions (for now), # we don't need to create any partitions or label disks (for now). @@ -356,9 +350,7 @@ def __gen_manual_partition_steps( for part, values in disk_final.items(): part_disk, part_number = Diskutils.separate_device_and_partn(part) - def setup_partition( - part_name: str, encrypt: bool = False, password: str = None - ): + def setup_partition(part_name: str, encrypt: bool = False, password: str = None): format_args = [part_number, values["fs"]] if encrypt: operation = "luks-format" @@ -372,15 +364,9 @@ def setup_partition( if values["mp"] == "/": setup_steps.append([part_disk, "pvcreate", [part]]) - setup_steps.append( - [part_disk, "vgcreate", ["vos-root", [part]]] - ) - setup_steps.append( - [part_disk, "lvcreate", ["init", "vos-root", "linear", 512]] - ) - setup_steps.append( - [part_disk, "lvm-format", ["vos-root/init", "ext4", "vos-init"]] - ) + setup_steps.append([part_disk, "vgcreate", ["vos-root", [part]]]) + setup_steps.append([part_disk, "lvcreate", ["init", "vos-root", "linear", 512]]) + setup_steps.append([part_disk, "lvm-format", ["vos-root/init", "ext4", "vos-init"]]) # LVM root thin pool # Total pool size is the disk size, subtracted by: @@ -415,16 +401,13 @@ def setup_partition( ["root-b", "vos-root", thin_size, "root"], ] ) - setup_steps.append( - [part_disk, "lvm-format", ["vos-root/root-a", "btrfs", "vos-a"]] - ) - setup_steps.append( - [part_disk, "lvm-format", ["vos-root/root-b", "btrfs", "vos-b"]] - ) + setup_steps.append([part_disk, "lvm-format", ["vos-root/root-a", "btrfs", "vos-a"]]) + setup_steps.append([part_disk, "lvm-format", ["vos-root/root-b", "btrfs", "vos-b"]]) mountpoints.append(["/dev/vos-root/root-a", "/"]) mountpoints.append(["/dev/vos-root/root-b", "/"]) elif values["mp"] == "/boot": setup_partition("vos-boot") + boot_disk = part_disk elif values["mp"] == "/boot/efi": setup_partition("vos-efi") elif values["mp"] == "/var": @@ -432,7 +415,7 @@ def setup_partition( elif values["mp"] == "swap": post_install_steps.append(["swapon", [part], True]) - return setup_steps, mountpoints, post_install_steps + return setup_steps, mountpoints, post_install_steps, boot_disk @staticmethod def __find_partitions(recipe: AlbiusRecipe) -> tuple[str, str, str, str, str]: @@ -481,13 +464,18 @@ def gen_install_recipe(log_path, finals, sys_recipe): encrypt = final["encryption"]["use_encryption"] password = final["encryption"]["encryption_key"] if encrypt else None + boot_disk = None + # Setup disks and mountpoints for final in finals: if "disk" in final.keys(): if "auto" in final["disk"].keys(): part_info = Processor.__gen_auto_partition_steps( - final["disk"]["auto"]["disk"], encrypt, root_size, - final["disk"]["auto"]["pvs_to_remove"], final["disk"]["auto"]["vgs_to_remove"], + final["disk"]["auto"]["disk"], + encrypt, + root_size, + final["disk"]["auto"]["pvs_to_remove"], + final["disk"]["auto"]["vgs_to_remove"], password, ) else: @@ -495,7 +483,7 @@ def gen_install_recipe(log_path, finals, sys_recipe): final["disk"], encrypt, password ) - setup_steps, mountpoints, post_install_steps = part_info + setup_steps, mountpoints, post_install_steps, boot_disk = part_info for step in setup_steps: recipe.add_setup_step(*step) for mount in mountpoints: @@ -520,7 +508,6 @@ def gen_install_recipe(log_path, finals, sys_recipe): root_b_part, var_part, ) = Processor.__find_partitions(recipe) - boot_disk, _ = Diskutils.separate_device_and_partn(boot_part) # Create SystemD units to setup mountpoints extra_target = "cryptsetup" if encrypt else "" @@ -540,7 +527,7 @@ def gen_install_recipe(log_path, finals, sys_recipe): "shell", [ f"cp /tmp/{filename_escaped} /mnt/a/etc/systemd/system/{filename_escaped}", - f"mkdir -p /mnt/a/etc/systemd/system/local-fs.target.wants", + "mkdir -p /mnt/a/etc/systemd/system/local-fs.target.wants", f"ln -s ../{filename_escaped} /mnt/a/etc/systemd/system/local-fs.target.wants/{filename_escaped}", ], ) @@ -565,10 +552,7 @@ def gen_install_recipe(log_path, finals, sys_recipe): *[f"mkdir -p /mnt/a/{path}" for path in _BASE_DIRS], *[f"ln -rs /mnt/a/.system/{path} /mnt/a/" for path in _REL_LINKS], *[f"rm -rf /mnt/a/.system/{path}" for path in _REL_SYSTEM_LINKS], - *[ - f"ln -rs /mnt/a/{path} /mnt/a/.system/" - for path in _REL_SYSTEM_LINKS - ], + *[f"ln -rs /mnt/a/{path} /mnt/a/.system/" for path in _REL_SYSTEM_LINKS], f"mount {var_label} /mnt/a/var", f"mount {boot_part} /mnt/a/boot{f' && mount {efi_part} /mnt/a/boot/efi' if efi_part else ''}", ], @@ -633,9 +617,7 @@ def gen_install_recipe(log_path, finals, sys_recipe): ) # Run `grub-mkconfig` to generate files for the boot partition - recipe.add_postinstall_step( - "grub-mkconfig", ["/boot/grub/grub.cfg"], chroot=True - ) + recipe.add_postinstall_step("grub-mkconfig", ["/boot/grub/grub.cfg"], chroot=True) # Replace main GRUB entry in the boot partition with open("/tmp/boot-grub.cfg", "w") as file: @@ -650,9 +632,7 @@ def gen_install_recipe(log_path, finals, sys_recipe): ) # Run `grub-mkconfig` inside the root partition - recipe.add_postinstall_step( - "grub-mkconfig", ["/boot/grub/grub.cfg"], chroot=True - ) + recipe.add_postinstall_step("grub-mkconfig", ["/boot/grub/grub.cfg"], chroot=True) # Copy init files to init LV recipe.add_postinstall_step(