From 46fb6bc93b2e403056cc2c80a9e1b8d4d7dfc54d Mon Sep 17 00:00:00 2001 From: Vadim Troshchinskiy Date: Sun, 27 Oct 2024 23:29:56 +0100 Subject: [PATCH] Fix and refactor slightly EFI implementation Allow for system-specific EFI storage --- gitlib/gitlib.py | 85 ++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 35 deletions(-) diff --git a/gitlib/gitlib.py b/gitlib/gitlib.py index 34bfb5e..820efbf 100755 --- a/gitlib/gitlib.py +++ b/gitlib/gitlib.py @@ -601,7 +601,7 @@ class OpengnsysGitLibrary: self.logger.debug(f"stdout: {result.stdout}") self.logger.debug(f"stderr: {result.stderr}") - def _grub_install(self, boot_device, root_directory): + def _grub_install(self, root_directory, boot_device): """ Install GRUB bootloader on the specified boot device. @@ -640,39 +640,51 @@ class OpengnsysGitLibrary: self.logger.debug("UUID is %s", uuid) return uuid - def _efi_install(self, boot_device, root_directory): + def _efi_install(self, root_directory): """ Install EFI data on the specified boot device. Copies EFI data from a metadata directory within the root directory to the specified boot device. It logs the process of installing the EFI data. + Boot device is detected automatically Args: - boot_device (str): The path to the boot device where EFI data will be installed. root_directory (str): The root directory containing the metadata and EFI data. Raises: shutil.Error: If an error occurs during the copying of the EFI data. """ - self.logger.info(f"Installing EFI files in {boot_device}") + boot_device = self._find_boot_device() + boot_mount = self._find_mountpoint(boot_device) + + self.logger.info(f"Installing EFI files in {boot_mount}") meta_dir = os.path.join(root_directory, ".opengnsys-metadata") efi_files_dir = os.path.join(meta_dir, "efi_data") - shutil.copytree(efi_files_dir, boot_device) + + if os.path.exists(efi_files_dir): + self.logger.debug("Copying EFI files") + shutil.copytree(efi_files_dir, boot_mount, dirs_exist_ok=True) + else: + self.logger.error("No general EFI files found") uuid = self._get_system_uuid() - self.logger.debug("Checking if we have system-specific EFI data...") + self.logger.debug("Checking if we have system-specific EFI data for system id %s...", uuid) sys_efi_files_dir = os.path.join(meta_dir, f"efi_data.{uuid}") if os.path.exists(sys_efi_files_dir): self.logger.info("This system has specific EFI data, overriding default...") - shutil.copytree(sys_efi_files_dir, boot_device) + shutil.copytree(sys_efi_files_dir, boot_mount, dirs_exist_ok=True) else: self.logger.debug("No system-specific EFI data.") def _efi_copy(self, root_directory, system_specific = False): meta_dir = os.path.join(root_directory, ".opengnsys-metadata") + boot_device = self._find_boot_device() + boot_mount = self._find_mountpoint(boot_device) + + if not system_specific: self.logger.debug("Copying default EFI data") @@ -680,8 +692,7 @@ class OpengnsysGitLibrary: if os.path.exists(efi_files_dir): shutil.rmtree(efi_files_dir) - boot_device = self._find_boot_device - shutil.copytree(boot_device, efi_files_dir) + shutil.copytree(boot_mount, efi_files_dir) else: uuid = self._get_system_uuid() self.logger.debug("Copying EFI data for system %s", uuid) @@ -693,8 +704,7 @@ class OpengnsysGitLibrary: if os.path.exists(efi_files_dir): shutil.rmtree(efi_files_dir) - boot_device = self._find_boot_device - shutil.copytree(boot_device, efi_files_dir) + shutil.copytree(boot_mount, efi_files_dir) @@ -727,14 +737,21 @@ class OpengnsysGitLibrary: line_num = line_num + 1 for disk in disks: - self.logger.debug("Loading partitions for disk {disk}") - disk_json_data = subprocess.run(["/usr/sbin/sfdisk", "-J", disk], check=True, capture_output=True) - disk_data = json.loads(disk_json_data) + self.logger.debug("Loading partitions for disk %s", disk) + #disk_json_data = subprocess.run(["/usr/sbin/sfdisk", "-J", f"/dev/{disk}"], check=False, capture_output=True) + sfdisk_out = subprocess.run(["/usr/sbin/sfdisk", "-J", f"/dev/{disk}"], check=False, capture_output=True) - for part in disk_data["partitiontable"]["partitions"]: - self.logger.debug("Checking partition {part}") - if part["type"] == "C12A7328-F81F-11D2-BA4B-00A0C93EC93B": - return part["node"] + if sfdisk_out.returncode == 0: + disk_json_data = sfdisk_out.stdout + disk_data = json.loads(disk_json_data) + + for part in disk_data["partitiontable"]["partitions"]: + self.logger.debug("Checking partition %s", part) + if part["type"] == "C12A7328-F81F-11D2-BA4B-00A0C93EC93B": + self.logger.debug("EFI partition found at %s", part["node"]) + return part["node"] + else: + self.logger.debug("sfdisk returned with code %i, error %s", sfdisk_out.returncode, sfdisk_out.stderr) self.logger.warning("Failed to find EFI partition!") @@ -862,7 +879,7 @@ class OpengnsysGitLibrary: return results - def _create_metadata(self, path): + def _create_metadata(self, path, initial_creation=False): """Calculate metadata for a filesystem Here we traverse the entire filesystem to: @@ -890,6 +907,7 @@ class OpengnsysGitLibrary: Args: path (str): Base path of the filesystem + initial_creation (bool): This is being called from the initial repository creation """ self.logger.info(f"Creating metadata for {path}") @@ -916,16 +934,10 @@ class OpengnsysGitLibrary: metadata["efi_boot"] = self._is_efi() if self._is_efi(): - self._efi_copy(path) - #self.logger.debug("Copying EFI data") - #efi_files_dir = os.path.join(meta_dir, "efi_data") - #if os.path.exists(efi_files_dir): - # shutil.rmtree(efi_files_dir) -# boot_device = self._find_boot_device -# shutil.copytree(boot_device, efi_files_dir) - - + # If we're doing the initial repository creation, then we're creating the initial, + # non-system-specific EFI data. + self._efi_copy(root_directory=path, system_specific=not initial_creation) empties_file = open(os.path.join(meta_dir, "empty_directories.jsonl.new"), "w", encoding='utf-8') specials_file = open(os.path.join(meta_dir, "special_files.jsonl.new"), "w", encoding='utf-8') @@ -1494,7 +1506,7 @@ class OpengnsysGitLibrary: repo = git.Repo.init(path) self._configure_repo(repo) self._write_ignore_list(path) - metadata_ret = self._create_metadata(path) + metadata_ret = self._create_metadata(path, initial_creation=True) self.logger.debug(f"Building list of files to add from path {path}") @@ -1641,9 +1653,9 @@ class OpengnsysGitLibrary: repo = git.Repo.clone_from(repo_url, destination_dir, multi_options = [f"--separate-git-dir={real_git_dir}"], progress=OgProgressPrinter(self.logger)) if repo_is_efi: - self._efi_install(boot_device, destination_dir) + self._efi_install(root_directory=destination_dir) else: - self._grub_install(boot_device, destination_dir) + self._grub_install(root_directory=destination_dir, boot_device=boot_device) self._mklostandfound(destination_dir) self._restore_metadata(destination_dir) @@ -1660,7 +1672,7 @@ class OpengnsysGitLibrary: self.logger.info("Committing changes to repository") repo = git.Repo(path) - self._create_metadata(path) + self._create_metadata(path, initial_creation=False) self.logger.info("Adding files") repo.index.add("*") @@ -1786,10 +1798,11 @@ if __name__ == '__main__': parser.add_argument("--fetch", type=str, metavar='DEV', help="Fetch changes from ogrepository") parser.add_argument("--ntfs-type", type=str, metavar="FS", help="Tipo de NTFS, 'kernel' o 'fuse'") - parser.add_argument("--test-metadata", type=str, metavar="DIR", help="Test metadata generation") + parser.add_argument("--test-create-metadata", type=str, metavar="DIR", help="Test metadata generation") parser.add_argument("--test-restore-metadata", type=str, metavar="DIR", help="Test metadata restoration") parser.add_argument("--test-restore-metadata-destructive", type=str, metavar="DIR", help="Test metadata restoration, destructive parts only") parser.add_argument("--test-clone-metadata", type=str, metavar="REPO", help="Test metadata cloning") + parser.add_argument("--test-efi-install", type=str, metavar="DIR", help = "Install EFI") parser.add_argument("-m", "--message", type=str, metavar="MSG", help="Commit message") parser.add_argument("--test-set-ntfsid", type=str, metavar="ID", help="Set NTFS ID") parser.add_argument("--device", type=str, metavar="DEV", help="Device to set the UUID on") @@ -1847,8 +1860,8 @@ if __name__ == '__main__': elif args.pull: with OperationTimer(og_git, "git pull"): og_git.pullRepo(args.pull) - elif args.test_metadata: - og_git._create_metadata(args.test_metadata) # pylint: disable=protected-access + elif args.test_create_metadata: + og_git._create_metadata(args.test_create_metadata, initial_creation=False) # pylint: disable=protected-access elif args.test_restore_metadata: og_git._restore_metadata(args.test_restore_metadata) # pylint: disable=protected-access elif args.test_restore_metadata_destructive: @@ -1858,6 +1871,8 @@ if __name__ == '__main__': elif args.test_set_ntfsid: ntfs = NTFSLibrary(ntfs_impl) ntfs.modify_uuid(args.device, args.test_set_ntfsid) + elif args.test_efi_install: + og_git._efi_install(root_directory=args.test_efi_install) # pylint: disable=protected-access else: print("Debe especificar una acción") #