Skip to content

Commit

Permalink
fix[close #376]: Removes call to lsblk for disk that doesn't exist
Browse files Browse the repository at this point in the history
* accounts for empty drive

* cleanup: Formatting

---------

Co-authored-by: Mateus Melchiades <[email protected]>
  • Loading branch information
taukakao and matbme authored Apr 14, 2024
1 parent 09cc910 commit 713a8bb
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 78 deletions.
42 changes: 19 additions & 23 deletions vanilla_installer/core/disks.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
import os
import subprocess
import json


class Diskutils:
@staticmethod
Expand All @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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()
)
Expand All @@ -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()
)
Expand All @@ -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()
)
Expand All @@ -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()
)
Expand Down Expand Up @@ -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()
Expand Down
90 changes: 35 additions & 55 deletions vanilla_installer/utils/processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand Down Expand Up @@ -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 = []
Expand Down Expand Up @@ -278,22 +281,16 @@ 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,
"make-thin-pool",
["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"]])

Expand All @@ -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]):
Expand All @@ -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 = []
Expand All @@ -341,24 +334,23 @@ 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).
# But we still need to format partitions.
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"
Expand All @@ -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:
Expand Down Expand Up @@ -415,24 +401,21 @@ 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":
setup_partition("vos-var", encrypt, password)
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]:
Expand Down Expand Up @@ -481,21 +464,26 @@ 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:
part_info = Processor.__gen_manual_partition_steps(
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:
Expand All @@ -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 ""
Expand All @@ -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}",
],
)
Expand All @@ -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 ''}",
],
Expand Down Expand Up @@ -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:
Expand All @@ -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(
Expand Down

0 comments on commit 713a8bb

Please sign in to comment.