Merge pull request 'Fixes for issues detected in testing' (#110) from fixes into main
ogclient/pipeline/head This commit looks good Details

Reviewed-on: #110
pull/112/head
Vadim vtroshchinskiy 2025-09-03 16:01:01 +02:00
commit b0ce2f9b4d
5 changed files with 94 additions and 14 deletions

View File

@ -35,17 +35,18 @@ class OgLogger(logging.StreamHandler):
def create_image(disk_num, partition_num, repo, image_name):
def create_image(disk_num, partition_num, repo, image_name, commit_message):
ntfs_impl = NTFSImplementation.NTFS3G
og_git = OpengnsysGitLibrary(ntfs_implementation = ntfs_impl)
og_git.progress_callback = OgProgressPrinterWeb()
og_git.repo_server = repo
device = DiskLib.ogDiskToDev(disk_num, partition_num)
if device is None:
sys.exit(SystemLib.ogRaiseError([], ogGlobals.OG_ERR_FORMAT, f"Failed to translate disk {disk_num} partition {partition_num} to a device"))
if og_git.initRepo(device, image_name):
if og_git.initRepo(device, image_name, message = commit_message):
return 0
else:
return 1
@ -73,7 +74,7 @@ def main():
parser.add_argument("--repository", type=str, metavar="REPO", required=True, help="Address of the Git repository to clone")
parser.add_argument("--image-name", type=str, metavar="REPO", required=True, help="Name of the new image at the repository")
parser.add_argument("--tag", type=str, metavar="TAG", required=False, help="Tag to automatically create")
parser.add_argument("--message", type=str, metavar="MSG", required=False, help="Commit message")
parser.add_argument("--message", type=str, metavar="MSG", required=False, default="", help="Commit message")
parser.add_help = True
@ -106,7 +107,7 @@ def main():
# repo = repositorio, oggit@server.com:/oggit
# image = nombre repo
retval = create_image(args.disk, args.partition, args.repository, args.image_name)
retval = create_image(args.disk, args.partition, args.repository, args.image_name, args.message)

View File

@ -72,6 +72,7 @@ def commit_image(disk_num, partition_num, repository, branch, options, msg):
ntfs_impl = NTFSImplementation.NTFS3G
og_git = OpengnsysGitLibrary(ntfs_implementation = ntfs_impl)
og_git.progress_callback = OgProgressPrinterWeb()
og_git.repo_server = repository
device = DiskLib.ogDiskToDev(disk_num, partition_num)
if device is None:
@ -110,7 +111,7 @@ def main():
parser.add_argument("--branch", type=str, metavar="BRANCH", required=False, help="Branch to automatically create")
parser.add_argument("--options", type=str, metavar="OPTS", required=False, help="Options to branch creation (forcepush)")
parser.add_argument("--message", type=str, metavar="MSG", required=False, help="Commit message")
parser.add_argument("--message", type=str, metavar="MSG", required=False, default="", help="Commit message")
parser.add_help = True

View File

@ -94,6 +94,9 @@ if __name__ == "__main__":
if device is None:
sys.exit(SystemLib.ogRaiseError([], ogGlobals.OG_ERR_FORMAT, f"Failed to translate disk {args.disk} partition {args.partition} to a device"))
if args.repository:
og_git.repo_server = args.repository
og_git.cloneRepo(args.image_name, destination = device, boot_device = device, ref = args.commit, branch = args.branch)
logger.info("RestaurarImagenGit Finished.")

View File

@ -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):
@ -1254,7 +1280,7 @@ class OpengnsysGitLibrary:
repo.config_writer().add_value("push", "followTags", "true").release()
def initRepo(self, device, repo_name):
def initRepo(self, device, repo_name, message = None):
"""
Initialize a Git repository on a specified device.
@ -1396,7 +1422,11 @@ class OpengnsysGitLibrary:
self.logger.info("Committing")
repo.index.commit("Initialize repository")
if message:
repo.index.commit(message)
else:
repo.index.commit("Initialize repository")
# Restaurar cosas modificadas para git
self._restore_metadata(path, destructive_only=True, set_device_uuids=False)
@ -1545,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)
@ -1688,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

View File

@ -89,6 +89,8 @@ class FilesystemLibrary:
if not pid_dir.isdigit():
continue # Not a pid directory
pid_num = int(pid_dir)
pid_dir_path = os.path.join(proc_path, pid_dir)
fd_path = os.path.join(pid_dir_path, "fd")
@ -100,11 +102,11 @@ class FilesystemLibrary:
if command_name.startswith(path):
self.logger.debug("PID %s (%s) is running from within %s: %s", pid_dir, command_name, path, command_name)
pids_using_path[pid_dir] = { "cmd" : command_name, "args" : cmdline}
self.logger.debug("PID %i (%s) is running from within %s: %s", pid_num, command_name, path, command_name)
pids_using_path[pid_num] = { "cmd" : command_name, "args" : cmdline}
elif working_dir.startswith(path):
self.logger.debug("PID %s (%s) is has a working directory within %s: %s", pid_dir, command_name, path, working_dir)
pids_using_path[pid_dir] = { "cmd" : command_name, "args" : cmdline}
self.logger.debug("PID %i (%s) is has a working directory within %s: %s", pid_num, command_name, path, working_dir)
pids_using_path[pid_num] = { "cmd" : command_name, "args" : cmdline}
else:
try:
for fd_file in os.listdir(fd_path):
@ -112,8 +114,8 @@ class FilesystemLibrary:
target = self._read_link(fd_file_full_path)
if target.startswith(path):
self.logger.debug("PID %s (%s) is has an open file within %s: %s", pid_dir, command_name, path, target)
pids_using_path[pid_dir] = { "cmd" : command_name, "args" : cmdline}
self.logger.debug("PID %i (%s) is has an open file within %s: %s", pid_num, command_name, path, target)
pids_using_path[pid_num] = { "cmd" : command_name, "args" : cmdline}
except IOError as ioerr:
self.logger.warning("Exception during listdir: %s", ioerr)
@ -140,6 +142,11 @@ class FilesystemLibrary:
lsof_data = self.lsof(path)
for pid, pid_data in lsof_data.items():
if pid == os.getpid():
self.logger.error("We're trying to terminate our own process!")
self.logger.error("This script is probably being run from within a mounted filesystem we need unmounted.")
self.logger.error("Our working directory is %s", os.getcwd())
self.logger.error("We need %s to be unmounted", path)
try:
if use_sigkill: