From 54581e36a80b10c06c87bd7092059d52f46e76f2 Mon Sep 17 00:00:00 2001 From: Vadim Troshchinskiy Date: Wed, 3 Sep 2025 15:59:33 +0200 Subject: [PATCH] refs #2703: mark and detect broken git clones --- ogclient/lib/python3/GitLib/__init__.py | 66 ++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/ogclient/lib/python3/GitLib/__init__.py b/ogclient/lib/python3/GitLib/__init__.py index 01d371a..ee78d2a 100755 --- a/ogclient/lib/python3/GitLib/__init__.py +++ b/ogclient/lib/python3/GitLib/__init__.py @@ -240,6 +240,23 @@ class RequirementException(Exception): super().__init__(message) self.message = message +class OgGitInternalException(Exception): + """Excepción que indica que hay un problema interno + + Attributes: + message (str): Mensaje de error mostrado al usuario + """ + + def __init__(self, message): + """Inicializar RequirementException. + + Args: + message (str): Mensaje de error mostrado al usuario + """ + super().__init__(message) + self.message = message + + class OpengnsysGitLibrary: """OpenGnsys Git Library""" @@ -697,10 +714,14 @@ class OpengnsysGitLibrary: git_dir = os.path.normpath(os.path.join(path, ".git")) meta_dir = os.path.join(path, ".opengnsys-metadata") + meta_lock = os.path.join(meta_dir, "create_metadata.lock") if not os.path.exists(meta_dir): os.mkdir(meta_dir, mode=0o700) + + Path(meta_lock).touch() + # https://jsonlines.org/ metadata_file = open(os.path.join(meta_dir, "metadata.json.new"), "w", encoding='utf-8') @@ -990,6 +1011,8 @@ class OpengnsysGitLibrary: self._ntfs_secaudit(audit) + Path(meta_lock).unlink() + self.logger.debug("Metadata updated") return return_data @@ -1014,11 +1037,14 @@ class OpengnsysGitLibrary: self.logger.info(f"Restoring metadata in {path}") meta_dir = os.path.join(path, ".opengnsys-metadata") + meta_lock = os.path.join(meta_dir, "restore_metadata.lock") + if not os.path.exists(meta_dir): self.logger.error(f"Metadata directory not found: {meta_dir}") return + Path(meta_lock).touch() if set_device_uuids: # Windows boot manager uses partition UUIDs in at least some cases. One option to make booting work @@ -1235,7 +1261,7 @@ class OpengnsysGitLibrary: - + Path(meta_lock).unlink() self.logger.info("Metadata restoration completed.") def _configure_repo(self, repo): @@ -1549,6 +1575,9 @@ class OpengnsysGitLibrary: if path is None: path = self.fs.ensure_mounted(device) + if self.is_broken(path = path, device = device): + raise OgGitInternalException("Cloned repository is in a broken state, see log.") + self.logger.info("Committing changes from %s to repository", path) repo = git.Repo(path) @@ -1692,7 +1721,42 @@ class OpengnsysGitLibrary: self.logger.warning("Remote can't be accessed, git said: %s", ret.stderr) return False + def is_broken(self, path = None, device = None): + """ + Checks whether a given checked out Git filesystem is in a broken state. + This mainly checks for the presence of lock files that indicate some process didn't run to completion. + + Args: + path (_type_, optional): Path to check. + device (_type_, optional): Device to check. + + Returns: + _Bool_: Whether the check passes + """ + if path is None: + path = self.fs.ensure_mounted(device) + + self.logger.info("Checking whether %s is broken", path) + + meta_dir = os.path.join(path, ".opengnsys-metadata") + if not os.path.exists(meta_dir): + self.logger.error("Metadata directory is missing") + return False + + restore_meta_lock = os.path.join(meta_dir, "restore_metadata.lock") + create_meta_lock = os.path.join(meta_dir, "restore_metadata.lock") + + if os.path.exists(restore_meta_lock): + self.logger.error("Metadata restoration didn't finish") + return False + + if os.path.exists(create_meta_lock): + self.logger.error("Metadata creation didn't finish") + return False + + self.logger.info("Check ok") + return True