diff --git a/usr/lib/akshara/classes/rootfs.py b/usr/lib/akshara/classes/rootfs.py index 1f3cc69..7720f74 100644 --- a/usr/lib/akshara/classes/rootfs.py +++ b/usr/lib/akshara/classes/rootfs.py @@ -29,6 +29,33 @@ class RootFS: """ return os.path.exists(os.path.join(self.rootfs_path, path)) + def exec_chroot(self, cmd, **kwargs) -> subprocess.CompletedProcess: + """Runs command within rootfs using chroot. + + Args: + cmd: List comprising command and arguments. + **kwargs: Keyword arguments list for subprocess.run(). + """ + + for dir in ("sys, proc", "dev"): + subprocess.run( + ["mount", "--bind", f"/{dir}", os.path.join(self.rootfs_path, dir)] + ) + + completedProcess = subprocess.run( + [ + "chroot", + self.rootfs_path, + ] + + list(cmd), + **kwargs, + ) + + for dir in ("sys, proc", "dev"): + subprocess.run(["umount", os.path.join(self.rootfs_path, dir)]) + + return completedProcess + def exec(self, cmd, **kwargs) -> subprocess.CompletedProcess: """Runs command within rootfs. diff --git a/usr/lib/akshara/utils/update.py b/usr/lib/akshara/utils/update.py index 9a69692..50722f3 100644 --- a/usr/lib/akshara/utils/update.py +++ b/usr/lib/akshara/utils/update.py @@ -18,6 +18,8 @@ def update_cleanup() -> None: for path in ( "/etc/grub.d", "/etc/default/grub", + "/var/cache/akshara/rootfs/dev", + "/var/cache/akshara/rootfs/proc", "/var/cache/akshara/rootfs/var/cache/blendOS", ): subprocess.run( @@ -140,31 +142,10 @@ def merge_var(new_rootfs: RootFS, overrides_keep_new: dict) -> None: ) -def is_bind_mnt(src, mountpoint) -> bool: - """Checks if /boot presently has /.tmp.boot bind-mounted to it. - - Args: - src: Source directory of bind-mount. - mountpoint: Mountpoint for bind-mount. - """ - with open("/proc/self/mountinfo") as mountinfo_file: - for line in mountinfo_file: - parts = line.strip().split() - if parts[3] != "/" and parts[3] == src and parts[4] == mountpoint: - return True - return False - - def handle_boot(new_rootfs, boot_config) -> None: """Handles /boot partition.""" - if os.path.isdir("/.tmp.boot"): - if is_bind_mnt("/.tmp.boot", "/boot"): - subprocess.run(["umount", "-l", "/boot"]) - subprocess.run(["rm", "-rf", "/.tmp.boot"]) - subprocess.run(["cp", "-ax", os.path.join(str(new_rootfs), "boot"), "/.tmp.boot"]) - subprocess.run(["mount", "--bind", "/.tmp.boot", "/boot"]) if boot_config["type"] == "bios": if boot_config["loader"] == "grub": @@ -173,6 +154,7 @@ def handle_boot(new_rootfs, boot_config) -> None: [ "grub-install", f"--directory={os.path.join(str(new_rootfs), 'usr/lib/grub/i386-pc')}", + "--boot-directory=/.tmp.boot", "--target=i386-pc", boot_config["device"], ] @@ -180,7 +162,6 @@ def handle_boot(new_rootfs, boot_config) -> None: != 0 ): output.error("aborting update...") - subprocess.run(["umount", "-l", "/boot"]) subprocess.run(["rm", "-rf", "/.tmp.boot"]) output.error("failed to install GRUB") exit(1) @@ -196,7 +177,8 @@ def handle_boot(new_rootfs, boot_config) -> None: [ "grub-install", f"--directory={os.path.join(str(new_rootfs), 'usr/lib/grub/x86_64-efi')}", - "--efi-directory=/boot", + "--efi-directory=/.tmp.boot", + "--boot-directory=/.tmp.boot", "--target=x86_64-efi", "--removable", "--bootloader-id=blendOS", @@ -205,12 +187,10 @@ def handle_boot(new_rootfs, boot_config) -> None: != 0 ): output.error("aborting update...") - subprocess.run(["umount", "-l", "/boot"]) subprocess.run(["rm", "-rf", "/.tmp.boot"]) output.error("failed to install GRUB") exit(1) else: - subprocess.run(["umount", "-l", "/boot"]) subprocess.run(["rm", "-rf", "/.tmp.boot"]) output.error("unsupported bootloader for BIOS configuration") exit(1) @@ -221,15 +201,14 @@ def handle_boot(new_rootfs, boot_config) -> None: exit(1) if boot_config["loader"] == "grub": - new_rootfs.exec(["grub-mkconfig", "-o", "/grub.cfg"]) - subprocess.run(["cp", f"{new_rootfs}/grub.cfg", "/boot/grub/grub.cfg"]) - - subprocess.run(["umount", "-l", "/boot"]) + new_rootfs.exec_chroot(["grub-mkconfig", "-o", "/grub.cfg"]) + subprocess.run(["cp", f"{new_rootfs}/grub.cfg", "/.tmp.boot/grub/grub.cfg"]) # Replace /boot with /.tmp.boot # FIXME: should be atomic for tmp_boot, dirs, files in os.walk("/.tmp.boot"): boot = tmp_boot.replace("/tmp.boot", "/boot", 1) + subprocess.run(["mkdir", "-p", boot]) for path in dirs + files: subprocess.run(["rm", "-rf", "--", os.path.join(boot, path)]) subprocess.run(