Compare commits

...

6 Commits

5 changed files with 198 additions and 111 deletions

View File

@ -2,6 +2,7 @@
import sys
import resource
import logging
import argparse
import NetLib
@ -62,20 +63,26 @@ def main():
print(f"No se pudo aumentar el límite de archivos abiertos: {e}")
parser = argparse.ArgumentParser(
prog = "OpenGnsys Git Image Create",
description = "Creates a git repository from a partition"
)
if len(sys.argv) != 6:
sys.exit(SystemLib.ogRaiseError([], ogGlobals.OG_ERR_FORMAT, "Incorrect number of arguments. Usage: CrearImagenGit.py disk_num partition_num image_name repo tag"))
parser.add_argument("--disk", type=int, metavar="DISK", required=True, help="Disk ID")
parser.add_argument("--partition", type=int, metavar="PART", required=True, help="Disk partition")
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")
# repo - repositorio, ip address. Opcional porque oglive lo recibe como parametro de kernel
# tag - tag a crear automaticamente. Opcional, no necesitamos crear un tag siempre.
parser.add_help = True
args = parser.parse_args()
#disk_num, partition_num, image_name, repo, tag = sys.argv[1:6]
disk_num, partition_num, image_name, repo, tag = sys.argv[1:6]
opengnsys_log_dir = "/opt/opengnsys/log"
ip_address = NetLib.ogGetIpAddress()
logFilePath = f"{opengnsys_log_dir}/{ip_address}.log"
logFilePath = "/var/log/opengnsys.CrearImagenGit.log"
ogLog = OgLogger()
ogLog.setLevel(logging.DEBUG)
@ -95,8 +102,11 @@ def main():
logger.info("Starting CrearImagenGit")
# TODO:
# repo = repositorio, oggit@server.com:/oggit
# image = nombre repo
retval = create_image(disk_num, partition_num, repo, image_name, tag)
retval = create_image(args.disk, args.partition, args.repository, args.image_name, args.tag)

View File

@ -4,7 +4,7 @@ import subprocess
import sys
import time
import resource
import argparse
soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
@ -67,30 +67,69 @@ class OgLogger(logging.StreamHandler):
def commit_image(disk_num, partition_num, image_name, msg):
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()
device = DiskLib.ogDiskToDev(disk_num, partition_num)
og_git.commit(device = device, message = msg)
og_git.push(device = device)
force_push = False
opts = options.split(",")
if "force_push" in opts:
force_push = True
try:
if branch:
if not og_git.create_branch(device = device, name = branch):
sys.exit(SystemLib.ogRaiseError([], ogGlobals.OG_ERR_FORMAT, f"Failed to create branch"))
og_git.commit(device = device, message = msg)
og_git.push(device = device, force = force_push)
except Exception as ex:
sys.exit(SystemLib.ogRaiseError([], ogGlobals.OG_ERR_FORMAT, f"Exception during commit: {ex}"))
return 0
def main():
if len(sys.argv) != 5:
parser = argparse.ArgumentParser(
prog = "OpenGnsys Git Image Modify",
description = "Commits changes to a partition to a git repository"
)
parser.add_argument("--disk", type=int, metavar="DISK", required=True, help="Disk ID")
parser.add_argument("--partition", type=int, metavar="PART", required=True, help="Disk partition")
parser.add_argument("--repository", type=str, metavar="REPO", required=True, help="Address of the Git repository to clone")
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_help = True
args = parser.parse_args()
if len(sys.argv) != 7:
import json
args = json.dumps(sys.argv)
sys.exit(SystemLib.ogRaiseError([], ogGlobals.OG_ERR_FORMAT, f"Incorrect number of arguments. Usage: ModificarImagenGit.py disk_num partition_num image_name repo msg. Received args: {args}"))
sys.exit(SystemLib.ogRaiseError([], ogGlobals.OG_ERR_FORMAT, f"Incorrect number of arguments. Got {len(sys.argv)}. Usage: ModificarImagenGit.py disk_num partition_num repo new_branch options msg. Received args: {args}"))
# repo - repositorio, ip address. Opcional porque oglive lo recibe como parametro de kernel
# tag - tag a crear automaticamente. Opcional, no necesitamos crear un tag siempre.
disk_num, partition_num, image_name, msg = sys.argv[1:5]
disk_num, partition_num, repo, branch, options, msg = sys.argv[1:7]
print(f"Repo : {repo}")
print(f"Branch : {branch}")
print(f"Options: {options}")
print(f"Msg : {msg}")
opengnsys_log_dir = "/opt/opengnsys/log"
ip_address = NetLib.ogGetIpAddress()
@ -114,7 +153,7 @@ def main():
logger.info("Starting ModificarImagenGit")
retval = commit_image(disk_num, partition_num, image_name, msg)
retval = commit_image(disk_num, partition_num, repo, branch, options, msg)
logger.info("ModificarImagenGit done, return code %i", retval)

View File

@ -10,6 +10,10 @@ import DiskLib
from GitLib import OpengnsysGitLibrary, NTFSImplementation, OgProgressPrinterWeb
import argparse
class OgLogger(logging.StreamHandler):
def emit(self, record):
log_types = ["command"]
@ -42,20 +46,25 @@ if __name__ == "__main__":
print(f"No se pudo aumentar el límite de archivos abiertos: {e}")
if len(sys.argv) < 6:
print("Usage: python RestaurarImagenGit.py <disk> <partition> <repo> <ip> <ref> <protocol>")
sys.exit(1)
disk = sys.argv[1]
partition = sys.argv[2]
repo = sys.argv[3]
ipaddr = sys.argv[4]
gitref = sys.argv[5]
proto = sys.argv[6]
parser = argparse.ArgumentParser(
prog = "OpenGnsys Git Image Restore",
description = "Restores an image from Git"
)
opengnsys_log_dir = "/opt/opengnsys/log"
ip_address = NetLib.ogGetIpAddress()
logFilePath = f"{opengnsys_log_dir}/{ip_address}.log"
parser.add_argument("--disk", type=int, metavar="DISK", required=True, help="Disk ID")
parser.add_argument("--partition", type=int, metavar="PART", required=True, help="Disk partition")
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("--branch", type=str, metavar="BRANCH", required=True, help="Branch to check out")
parser.add_argument("--commit", type=str, metavar="COMMIT_ID", required=True, help="Commit to check out")
parser.add_help = True
args = parser.parse_args()
logFilePath = "/var/log/opengnsys.RestaurarImagenGit.log"
ogLog = OgLogger()
ogLog.setLevel(logging.DEBUG)
@ -81,9 +90,9 @@ if __name__ == "__main__":
og_git = OpengnsysGitLibrary(ntfs_implementation = ntfs_impl)
og_git.progress_callback = OgProgressPrinterWeb()
device = DiskLib.ogDiskToDev(disk, partition)
device = DiskLib.ogDiskToDev(args.disk, args.partition)
og_git.cloneRepo(repo, device, device)
og_git.cloneRepo(args.image_name, destination = device, boot_device = device, ref = args.commit, branch = args.branch)
logger.info("RestaurarImagenGit Finished.")

View File

@ -48,6 +48,7 @@ from GitLib.disk import *
from GitLib.ntfs import *
from GitLib.kernel import parse_kernel_cmdline
import CacheLib
#import requests
@ -287,7 +288,8 @@ class OpengnsysGitLibrary:
self.repo_image_path = "oggit"
self.ntfs_implementation = ntfs_implementation
self.cache_dir = self._runBashFunction("ogMountCache", [])
self.cache_dir = CacheLib.ogMountCache()
# Si no hay cache, se va a crear el .git en el FS directamente
if (not self.cache_dir) and require_cache:
@ -349,6 +351,7 @@ class OpengnsysGitLibrary:
self.repo_server = self.kernel_args["ogrepo"]
self.ip_address = self.kernel_args["ip"]
self.initial_branch = "main"
if not self.repo_server:
self.logger.warning("ogrepo kernel argument wasn't passed, or was empty. Defaulting to oglive.")
@ -603,64 +606,6 @@ class OpengnsysGitLibrary:
except OSError as e:
self.logger.warning('Failed to delete %s. Error: %s', file_path, e)
def _runBashFunction(self, function, arguments):
"""
Executes an OpenGnsys bash function with given arguments.
This method creates a temporary bash script that sources all `.lib` files in a specific directory,
writes the specified bash function and its arguments to the script, makes the script executable,
and then runs the script. The output and errors from the script execution are captured and logged.
This is a temporary migration convenience function, it won't be present once the rest of the
code is migrated to Python.
Args:
function (str): The name of the bash function to execute.
arguments (list): A list of arguments to pass to the bash function.
Returns:
str: The standard output from the executed bash function.
Logs:
- Debug information about the bash function and arguments being run.
- The path of the temporary file created.
- The command being executed.
- The standard output and standard error from the script execution.
"""
# Create a temporary file
self.logger.debug(f"Running bash function: {function} {arguments}")
with tempfile.NamedTemporaryFile(mode='w', delete=False) as temp_file:
temp_file.write("#!/bin/bash\n")
temp_file.write("for lib in /opt/opengnsys/client/lib/engine/bin/*.lib ; do\n")
temp_file.write(" source $lib\n")
temp_file.write("done\n")
#temp_file.write("source /opt/oglive/rootfs/opt/opengnsys/lib/engine/bin/Cache.lib")
#temp_file.write("source /opt/oglive/rootfs/opt/opengnsys/lib/engine/bin/Git.lib")
temp_file.write(f"{function} \"$@\"\n")
# Make the temporary file executable
os.chmod(temp_file.name, 0o755)
self.logger.debug(f"File: {temp_file.name}")
# Run the temporary file
command = [temp_file.name] + arguments
self.logger.debug(f"Running: {command} {arguments}")
result = subprocess.run(command, shell=False, capture_output=True, text=True, check=True)
output = result.stdout.strip()
self.logger.debug(f"STDOUT: {output}")
self.logger.debug(f"STDERR: {result.stderr}")
return output
def _getOgRepository(self, name):
return f"{self.repo_user}@{self.repo_server}:{self.repo_image_path}/{name}.git"
@ -1371,7 +1316,7 @@ class OpengnsysGitLibrary:
os.symlink(real_git_dir, git_dir)
with git.Repo.init(path) as repo:
with git.Repo.init(path, initial_branch = self.initial_branch) as repo:
# On NTFS, we have to unmount the filesystem to do secaudit.
# Gitpython objects existing at that time may mean a dangling git process that prevents
# the required unmounting.
@ -1393,7 +1338,7 @@ class OpengnsysGitLibrary:
self.logger.debug("Fetching origin, callback=%s", self.progress_callback)
origin.fetch(progress=self.progress_callback)
repo.heads.master.set_tracking_branch(origin.refs.master)
repo.heads.main.set_tracking_branch(origin.refs.main)
metadata_ret = self._create_metadata(path, initial_creation=True)
@ -1480,7 +1425,7 @@ class OpengnsysGitLibrary:
self.logger.info("initRepo done")
return True
def cloneRepo(self, repo_name, destination, boot_device):
def cloneRepo(self, repo_name, destination, boot_device, ref = None, branch = None):
"""
Clones a repository to a specified destination and sets up the bootloader.
@ -1543,12 +1488,71 @@ class OpengnsysGitLibrary:
self.logger.info("Cloning repository from %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)
if repo_is_efi:
self._efi_install(root_directory=destination_dir)
if 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.logger.debug("Checking out indicated branch %s", branch)
remote_branch_ref = repo.heads[branch]
if branch in repo.heads:
self.logger.debug("Removing existing local branch %s", branch)
repo.delete_head(branch)
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()
else:
self._grub_install(root_directory=destination_dir, boot_device=boot_device)
repo = git.Repo.clone_from(repo_url, destination_dir, multi_options = [f"--separate-git-dir={real_git_dir}"], progress=self.progress_callback)
branches_with_commit = repo.git.branch("-r", "--contains", ref).split("\n")
self.logger.debug("Branches with commit: %s", branches_with_commit)
if len(branches_with_commit) > 0:
remote_branch = branches_with_commit[0].strip()
if "->" in remote_branch:
# Git returned something like:
# origin/HEAD -> origin/main
#
# so take the second part.
remote_branch = remote_branch.split("->")[1].strip()
parts = remote_branch.split("/")
self.logger.info(f"Branch: {remote_branch}, parts: {parts}")
local_branch_name = parts[1]
if local_branch_name in repo.heads:
#self.logger.debug("Removing existing local branch %s", local_branch_name)
#repo.git.reset("--hard")
#repo.delete_head(local_branch_name)
self.logger.debug("Local branch %s exists, checking it out first", local_branch_name)
repo.git.checkout(local_branch_name)
self.logger.debug("Resetting branch %s to ref %s", local_branch_name, ref)
repo.git.reset("--hard", ref)
else:
self.logger.info("Checking out containing remote branch %s, as %s", remote_branch, local_branch_name)
repo.git.checkout("-b", local_branch_name, remote_branch)
try:
self.logger.info("Setting upstream: %s", local_branch_name)
repo.git.branch(f"--set-upstream-to={remote_branch}", local_branch_name)
except Exception as ex:
self.logger.error("Setting upstream failed: %s", ex)
else:
self.logger.info("Checking out REF %s", ref)
repo.git.checkout(ref)
self.fs.mklostandfound(destination_dir)
self._restore_metadata(destination_dir, set_device_uuids=True)
@ -1556,6 +1560,12 @@ class OpengnsysGitLibrary:
if self.fs.filesystem_type(mountpoint = destination_dir) == "ntfs":
self._ntfs_restore_secaudit(destination_dir)
if repo_is_efi:
self._efi_install(root_directory=destination_dir)
else:
self._grub_install(root_directory=destination_dir, boot_device=boot_device)
self.logger.info("Clone completed.")
@ -1615,7 +1625,23 @@ class OpengnsysGitLibrary:
# Restaurar cosas modificadas para git
self._restore_metadata(path, destructive_only=True)
def push(self, path = None, device = None):
def create_branch(self, path = None, device = None, name = ""):
if path is None:
path = self.fs.ensure_mounted(device)
repo = git.Repo(path)
if name in repo.branches:
self.logger.error("Can't create branch, it already exists")
return False
self.logger.info("Creating branch %s", name)
new_branch = repo.create_head(name)
repo.head.reference = new_branch
repo.head.reset(index=True, working_tree=True)
return True
def push(self, path = None, device = None, force = False):
"""
Push local changes to ogrepository
@ -1634,9 +1660,10 @@ class OpengnsysGitLibrary:
return
origin = repo.remotes["origin"]
repo.heads.master.set_tracking_branch(origin.refs.master)
repo.heads.main.set_tracking_branch(origin.refs.main)
origin.push(progress=self.progress_callback)
ret = origin.push(progress=self.progress_callback, force = force)
ret.raise_if_error()
#repo.git.push("--set-upstream", "origin", repo.head.ref, "--force") # force = True)
@ -1792,7 +1819,6 @@ if __name__ == '__main__':
og_git = OpengnsysGitLibrary(ntfs_implementation = ntfs_impl)
# og_git._runBashFunction("ogMountCache", [])
# if args.init_repo:

View File

@ -41,7 +41,7 @@ class FilesystemLibrary:
try:
with open(file, "r", encoding='utf-8') as f:
data = f.read()
except IOError as io_err:
except Exception as io_err:
self.logger.debug("IO Error reading file %s: %s", file, io_err)
return data
@ -51,7 +51,7 @@ class FilesystemLibrary:
try:
data = os.readlink(file)
except IOError as io_err:
except Exception as io_err:
self.logger.debug("IO Error reading link %s: %s", file, io_err)
return data
@ -106,13 +106,16 @@ class FilesystemLibrary:
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}
else:
for fd_file in os.listdir(fd_path):
fd_file_full_path = os.path.join(fd_path, fd_file)
target = self._read_link(fd_file_full_path)
try:
for fd_file in os.listdir(fd_path):
fd_file_full_path = os.path.join(fd_path, fd_file)
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}
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}
except IOError as ioerr:
self.logger.warning("Exception during listdir: %s", ioerr)
return pids_using_path