Merge pull request 'git-fast-updates' (#115) from git-fast-updates into main
ogclient/pipeline/head This commit looks good Details

Reviewed-on: #115
pull/117/head
Vadim vtroshchinskiy 2025-09-09 22:03:16 +02:00
commit 80635240dd
3 changed files with 101 additions and 39 deletions

View File

@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.4.5] - 2025-09-09
## Change
- Oggit fast restore
## [1.4.4] - 2025-09-09
## Change

View File

@ -4,6 +4,8 @@ import resource
import logging
import subprocess
sys.path.insert(0, "/opt/opengnsys/lib/python3-test")
import NetLib
import ogGlobals
import SystemLib

View File

@ -1479,7 +1479,7 @@ class OpengnsysGitLibrary:
self.logger.info("initRepo done")
return True
def cloneRepo(self, repo_name, destination, boot_device, ref = None, branch = None):
def cloneRepo(self, repo_name, destination, boot_device, ref = None, branch = None, delete_existing_repo = False, format_existing = False):
"""
Clones a repository to a specified destination and sets up the bootloader.
@ -1487,6 +1487,9 @@ class OpengnsysGitLibrary:
repo_name (str): The name of the repository to clone.
destination (str): The destination directory where the repository will be cloned.
boot_device (str): The boot device to install the bootloader.
delete_existing_repo (bool): Whether to delete an existing repository and re-create from scratch,
even if the repo is the one we need.
format_existing (bool): Whether to format the filesystem even if we don't need to.
Raises:
RequirementException: If the repository metadata is incorrect or if the repository's
@ -1496,18 +1499,38 @@ class OpengnsysGitLibrary:
Info: Logs the start of the cloning process.
Debug: Logs the repository URL, EFI compatibility of the repository and the system.
"""
self.logger.info(f"Cloning repo: {repo_name} => {destination}")
self.logger.info(f"Cloning repo : {repo_name} => {destination}")
repo_url = self._getOgRepository(repo_name)
real_git_dir = os.path.join(self.cache_dir, f"git-{repo_name}")
if os.path.exists(real_git_dir):
self.logger.debug(f"Removing existing repository {real_git_dir}")
shutil.rmtree(real_git_dir)
repo = None
self.logger.debug(f"URL: {repo_url}")
if os.path.exists(real_git_dir):
if delete_existing_repo:
self.logger.info("There is an existing repository, but a full reset will be done")
repo = None
else:
self.logger.info("Verifying existing repository at %s", real_git_dir)
repo = git.Repo.init(real_git_dir, bare=True)
if "origin" in repo.remotes:
if repo_url in repo.remotes.origin.urls:
self.logger.info("Remote URL of existing repository matches")
else:
self.logger.info("Existing repo points to a different URL, will delete.")
repo = None
else:
self.logger.info("Existing repo has no origin remote, will delete.")
repo = None
if repo is None:
self.logger.debug(f"Removing existing repository %s", real_git_dir)
os._exit(10)
shutil.rmtree(real_git_dir)
all_metadata = self._get_repo_metadata(repo_name)
metadata = all_metadata["metadata.json"]
fs_data = all_metadata["filesystems.json"]
@ -1528,50 +1551,80 @@ class OpengnsysGitLibrary:
if repo_is_efi != efi:
raise RequirementException("Repositorio usa sistema de arranque incompatible con sistema actual")
self.fs.unmount(device = destination)
if repo is None or format_existing:
self.logger.info("Creating a new filesystem at %s")
self.fs.unmount(device = destination)
filesystem_map = {"/" : destination}
filesystem_map = {"/" : destination}
self._create_filesystems(fs_data, filesystem_map)
self._create_filesystems(fs_data, filesystem_map)
destination_dir = "/mnt/repo-" + repo_name
destination_dir = "/mnt/repo-" + repo_name
self.fs.mount(destination, destination_dir)
self.fs.mount(destination, destination_dir)
self._delete_contents(destination_dir)
self.logger.info("Cloning repository from %s", repo_url)
if branch:
# We've got a nearby branch, start from that
self.logger.debug("Cloning repo %s, branch %s", repo_url, branch)
repo = git.Repo.clone_from(repo_url, destination_dir, branch = branch, multi_options = [f"--separate-git-dir={real_git_dir}"], progress=self.progress_callback)
self._delete_contents(destination_dir)
else:
# Start from main instead
self.logger.debug("Cloning repo %s", repo_url)
repo = git.Repo.clone_from(repo_url, destination_dir, multi_options = [f"--separate-git-dir={real_git_dir}"], progress=self.progress_callback)
destination_dir = "/mnt/repo-" + repo_name
self.logger.info("Mounting existing filesystem %s at %s", destination, destination_dir)
self.fs.unmount(device = destination)
self.fs.mount(destination, destination_dir)
# Change from bare repo to our checked out repo
self.logger.info("Opening repo from %s now", destination_dir)
git_dotdir = os.path.join(destination, ".git")
if os.path.exists(git_dotdir):
self.logger.debug("Replacing .git directory, gitpython doesn't like the file method")
os.unlink(git_dotdir)
os.symlink(src = real_git_dir, dst = git_dotdir)
self.logger.info("Re-opening git repo at %s", destination_dir)
repo = git.Repo(destination_dir)
self.logger.info("Forcing git repo to non-bare status")
repo.config_writer().set_value("core", "bare", "false").release()
self.logger.info("Re-opening git repo again after non-bare adjustment at %s", destination_dir)
repo = git.Repo(destination_dir)
self.logger.info("New repo is %s", repo)
self.logger.debug("Checking out indicated branch %s", branch)
remote_branch_ref = repo.heads[branch]
if branch in repo.heads:
self.logger.debug("Local branch %s exists, checking it out first", branch)
repo.git.checkout(branch)
if repo is None:
self.logger.info("Cloning repository from %s", repo_url)
self.logger.debug("Resetting branch %s to ref %s", branch, ref)
repo.git.reset("--hard", ref)
if branch:
# We've got a nearby branch, start from that
self.logger.debug("Cloning repo %s, branch %s", repo_url, branch)
repo = git.Repo.clone_from(repo_url, destination_dir, branch = branch, multi_options = [f"--separate-git-dir={real_git_dir}"], progress=self.progress_callback)
else:
if ref:
self.logger.debug("Local branch adjusted to ref %s", ref)
local_ref = repo.create_head(branch, ref)
else:
self.logger.debug("Local branch is set to remote branch %s", remote_branch_ref)
local_ref = repo.create_head(branch, remote_branch_ref)
local_ref.set_tracking_branch(remote_branch_ref)
# Start from main instead
self.logger.debug("Cloning repo %s", repo_url)
repo = git.Repo.clone_from(repo_url, destination_dir, multi_options = [f"--separate-git-dir={real_git_dir}"], progress=self.progress_callback)
else:
self.logger.info("Fetching updates from remote in %s", repo)
for remote in repo.remotes:
remote.fetch()
self.logger.debug("Checking out indicated branch %s", branch)
remote_branch_ref = repo.heads[branch]
if branch in repo.heads:
self.logger.debug("Local branch %s exists, checking it out first", branch)
repo.git.checkout(branch)
self.logger.debug("Resetting branch %s to ref %s", branch, ref)
repo.git.reset("--hard", ref)
else:
if ref:
self.logger.debug("Local branch adjusted to ref %s", ref)
local_ref = repo.create_head(branch, ref)
else:
self.logger.debug("Local branch is set to remote branch %s", remote_branch_ref)
local_ref = repo.create_head(branch, remote_branch_ref)
local_ref.set_tracking_branch(remote_branch_ref)
self.logger.debug("Checking out local branch %s", branch)
local_ref.checkout()