Make pylint happy

ticket-698
Vadim vtroshchinskiy 2024-10-10 10:46:51 +02:00
parent dea57835f3
commit 9af377f9fa
2 changed files with 110 additions and 34 deletions

View File

@ -1,18 +1,63 @@
from flask import Flask, jsonify #!/usr/bin/env python3
"""
This module provides a Flask-based API for managing Git repositories in the OpenGnsys system.
It includes endpoints for creating, deleting, synchronizing, backing up, and performing garbage
collection on Git repositories. The API also provides endpoints for retrieving repository
information such as the list of repositories and branches, as well as checking the status of
asynchronous tasks.
Classes:
None
Functions:
do_repo_backup(repo, params)
do_repo_sync(repo, params)
do_repo_gc(repo)
home()
get_repositories()
create_repo(repo)
sync_repo(repo)
backup_repository(repo)
gc_repo(repo)
tasks_status(task_id)
delete_repo(repo)
get_repository_branches(repo)
health_check()
Constants:
REPOSITORIES_BASE_PATH (str): The base path where Git repositories are stored.
Global Variables:
app (Flask): The Flask application instance.
executor (Executor): The Flask-Executor instance for managing asynchronous tasks.
tasks (dict): A dictionary to store the status of asynchronous tasks.
"""
# pylint: disable=locally-disabled, line-too-long
import os.path import os.path
import os import os
import git
import shutil import shutil
import subprocess
import uuid import uuid
import git
from opengnsys_git_installer import OpengnsysGitInstaller from opengnsys_git_installer import OpengnsysGitInstaller
from flask import Flask, request from flask import Flask, request, jsonify # stream_with_context, Response,
from flask_executor import Executor from flask_executor import Executor
import subprocess
from flask import stream_with_context, Response
import paramiko import paramiko
repositories_base_path = "/opt/opengnsys/images" REPOSITORIES_BASE_PATH = "/opt/opengnsys/images"
# Create an instance of the Flask class # Create an instance of the Flask class
app = Flask(__name__) app = Flask(__name__)
@ -25,8 +70,22 @@ tasks = {}
def do_repo_backup(repo, params): def do_repo_backup(repo, params):
"""
Creates a backup of the specified Git repository and uploads it to a remote server via SFTP.
gitrepo = git.Repo(f"{repositories_base_path}/{repo}.git") Args:
repo (str): The name of the repository to back up.
params (dict): A dictionary containing the following keys:
- ssh_server (str): The SSH server address.
- ssh_port (int): The SSH server port.
- ssh_user (str): The SSH username.
- filename (str): The remote filename where the backup will be stored.
Returns:
bool: True if the backup was successful.
"""
gitrepo = git.Repo(f"{REPOSITORIES_BASE_PATH}/{repo}.git")
ssh = paramiko.SSHClient() ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
@ -42,24 +101,46 @@ def do_repo_backup(repo, params):
return True return True
def do_repo_sync(repo, params): def do_repo_sync(repo, params):
gitrepo = git.Repo(f"{repositories_base_path}/{repo}.git") """
Synchronizes a local Git repository with a remote repository.
Args:
repo (str): The name of the local repository to synchronize.
params (dict): A dictionary containing the remote repository URL with the key "remote_repository".
Returns:
list: A list of dictionaries, each containing:
- "local_ref" (str): The name of the local reference.
- "remote_ref" (str): The name of the remote reference.
- "summary" (str): A summary of the push operation for the reference.
"""
gitrepo = git.Repo(f"{REPOSITORIES_BASE_PATH}/{repo}.git")
# Recreate the remote every time, it might change # Recreate the remote every time, it might change
if "backup" in gitrepo.remotes: if "backup" in gitrepo.remotes:
gitrepo.delete_remote("backup") gitrepo.delete_remote("backup")
backup_repo = gitrepo.create_remote("backup", params["remote_repository"]) backup_repo = gitrepo.create_remote("backup", params["remote_repository"])
pushrets = backup_repo.push("*:*") pushed_references = backup_repo.push("*:*")
results = [] results = []
# This gets returned to the API # This gets returned to the API
for ret in pushrets: for ref in pushed_references:
results = results + [ {"local_ref" : ret.local_ref.name, "remote_ref" : ret.remote_ref.name, "summary" : ret.summary }] results = results + [ {"local_ref" : ref.local_ref.name, "remote_ref" : ref.remote_ref.name, "summary" : ref.summary }]
return results return results
def do_repo_gc(repo): def do_repo_gc(repo):
gitrepo = git.Repo(f"{repositories_base_path}/{repo}.git") """
Perform garbage collection on the specified Git repository.
Args:
repo (str): The name of the repository to perform garbage collection on.
Returns:
bool: True if the garbage collection command was executed successfully.
"""
gitrepo = git.Repo(f"{REPOSITORIES_BASE_PATH}/{repo}.git")
gitrepo.git.gc() gitrepo.git.gc()
return True return True
@ -99,11 +180,11 @@ def get_repositories():
} }
""" """
if not os.path.isdir(repositories_base_path): if not os.path.isdir(REPOSITORIES_BASE_PATH):
return jsonify({"error": "Repository storage not found, git functionality may not be installed."}), 500 return jsonify({"error": "Repository storage not found, git functionality may not be installed."}), 500
repos = [] repos = []
for entry in os.scandir(repositories_base_path): for entry in os.scandir(REPOSITORIES_BASE_PATH):
if entry.is_dir(follow_symlinks=False) and os.path.isfile(os.path.join(entry.path, "HEAD")): if entry.is_dir(follow_symlinks=False) and os.path.isfile(os.path.join(entry.path, "HEAD")):
name = entry.name name = entry.name
if name.endswith(".git"): if name.endswith(".git"):
@ -131,13 +212,13 @@ def create_repo(repo):
- 200: If the repository already exists. - 200: If the repository already exists.
- 201: If the repository is successfully created. - 201: If the repository is successfully created.
""" """
repo_path = os.path.join(repositories_base_path, repo + ".git") repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git")
if os.path.isdir(repo_path): if os.path.isdir(repo_path):
return jsonify({"status": "Repository already exists"}), 200 return jsonify({"status": "Repository already exists"}), 200
installer = OpengnsysGitInstaller() installer = OpengnsysGitInstaller()
installer._init_git_repo(repo + ".git") installer.init_git_repo(repo + ".git")
return jsonify({"status": "Repository created"}), 201 return jsonify({"status": "Repository created"}), 201
@ -160,7 +241,7 @@ def sync_repo(repo):
- 400: If the request payload is missing or invalid. - 400: If the request payload is missing or invalid.
- 404: If the specified repository is not found. - 404: If the specified repository is not found.
""" """
repo_path = os.path.join(repositories_base_path, repo + ".git") repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git")
if not os.path.isdir(repo_path): if not os.path.isdir(repo_path):
return jsonify({"error": "Repository not found"}), 404 return jsonify({"error": "Repository not found"}), 404
@ -170,9 +251,6 @@ def sync_repo(repo):
if data is None: if data is None:
return jsonify({"error" : "Parameters missing"}), 400 return jsonify({"error" : "Parameters missing"}), 400
dest_repo = data["remote_repository"]
future = executor.submit(do_repo_sync, repo, data) future = executor.submit(do_repo_sync, repo, data)
task_id = str(uuid.uuid4()) task_id = str(uuid.uuid4())
tasks[task_id] = future tasks[task_id] = future
@ -180,7 +258,7 @@ def sync_repo(repo):
@app.route('/repositories/<repo>/backup', methods=['POST']) @app.route('/repositories/<repo>/backup', methods=['POST'])
def backup_repo(repo): def backup_repository(repo):
""" """
Backup a specified repository. Backup a specified repository.
@ -203,7 +281,7 @@ def backup_repo(repo):
- The backup operation is performed asynchronously using a thread pool executor. - The backup operation is performed asynchronously using a thread pool executor.
- The task ID of the backup operation is generated using UUID and stored in a global tasks dictionary. - The task ID of the backup operation is generated using UUID and stored in a global tasks dictionary.
""" """
repo_path = os.path.join(repositories_base_path, repo + ".git") repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git")
if not os.path.isdir(repo_path): if not os.path.isdir(repo_path):
return jsonify({"error": "Repository not found"}), 404 return jsonify({"error": "Repository not found"}), 404
@ -240,7 +318,7 @@ def gc_repo(repo):
a unique task ID if the repository is found, or an error a unique task ID if the repository is found, or an error
message if the repository is not found. message if the repository is not found.
""" """
repo_path = os.path.join(repositories_base_path, repo + ".git") repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git")
if not os.path.isdir(repo_path): if not os.path.isdir(repo_path):
return jsonify({"error": "Repository not found"}), 404 return jsonify({"error": "Repository not found"}), 404
@ -295,7 +373,7 @@ def delete_repo(repo):
Returns: Returns:
Response: A JSON response with a status message and the appropriate HTTP status code. Response: A JSON response with a status message and the appropriate HTTP status code.
""" """
repo_path = os.path.join(repositories_base_path, repo + ".git") repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git")
if not os.path.isdir(repo_path): if not os.path.isdir(repo_path):
return jsonify({"error": "Repository not found"}), 404 return jsonify({"error": "Repository not found"}), 404
@ -319,14 +397,14 @@ def get_repository_branches(repo):
- 200: A JSON object with a "branches" key containing a list of branch names. - 200: A JSON object with a "branches" key containing a list of branch names.
- 404: A JSON object with an "error" key containing the message "Repository not found" if the repository does not exist. - 404: A JSON object with an "error" key containing the message "Repository not found" if the repository does not exist.
""" """
repo_path = os.path.join(repositories_base_path, repo + ".git") repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git")
if not os.path.isdir(repo_path): if not os.path.isdir(repo_path):
return jsonify({"error": "Repository not found"}), 404 return jsonify({"error": "Repository not found"}), 404
gitRepo = git.Repo(repo_path) git_repo = git.Repo(repo_path)
branches = [] branches = []
for branch in gitRepo.branches: for branch in git_repo.branches:
branches = branches + [branch.name] branches = branches + [branch.name]
@ -357,5 +435,3 @@ def health_check():
# Run the Flask app # Run the Flask app
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0') app.run(debug=True, host='0.0.0.0')

View File

@ -157,7 +157,7 @@ class OpengnsysGitInstaller:
if self.temp_dir: if self.temp_dir:
shutil.rmtree(self.temp_dir, ignore_errors=True) shutil.rmtree(self.temp_dir, ignore_errors=True)
def _init_git_repo(self, reponame): def init_git_repo(self, reponame):
"""Inicializa un repositorio Git""" """Inicializa un repositorio Git"""
# Creamos repositorio # Creamos repositorio
ogdir_images = os.path.join(self.base_path, "images") ogdir_images = os.path.join(self.base_path, "images")
@ -330,9 +330,9 @@ class OpengnsysGitInstaller:
os.system(f"usermod -s {SHELL} opengnsys") os.system(f"usermod -s {SHELL} opengnsys")
# Creamos repositorios # Creamos repositorios
self._init_git_repo('windows.git') self.init_git_repo('windows.git')
self._init_git_repo('linux.git') self.init_git_repo('linux.git')
self._init_git_repo('mac.git') self.init_git_repo('mac.git')
# Damos permiso al usuario opengnsys # Damos permiso al usuario opengnsys
for DIR in ["base.git", "linux.git", "windows.git"]: #, "LinAcl", "WinAcl"]: for DIR in ["base.git", "linux.git", "windows.git"]: #, "LinAcl", "WinAcl"]: