Improvements for logging and error handling

ogrepository-integration
Vadim vtroshchinskiy 2025-01-29 09:45:26 +01:00
parent 14cd2d4363
commit 73118501b3
1 changed files with 66 additions and 2 deletions

View File

@ -59,6 +59,16 @@ from flask_executor import Executor
from flask_restx import Api, Resource, fields
#from flasgger import Swagger
import paramiko
import logging
from systemd.journal import JournalHandler
debug_enabled = False
log = logging.getLogger('gitapi')
log.addHandler(JournalHandler())
log.setLevel(logging.INFO)
log.info("Started")
REPOSITORIES_BASE_PATH = "/opt/opengnsys/ogrepository/oggit/git/oggit/"
@ -158,6 +168,35 @@ def do_repo_gc(repo):
return True
@app.errorhandler(Exception)
def handle_exception(e):
"""Return JSON for errors"""
# start with the correct headers and status code from the error
response = e.get_response()
errid = uuid.uuid4()
if debug_enabled:
response = {
"errcode": e.code,
"errname": e.name,
"description": e.description,
}
else:
response = {
"errcode" : 500,
"errname" : "Internal error",
"description": f"Please see the log for error {errid}",
"error_id" : errid
}
log.error("Error ID %s: code %i, name %s, description %s", errid, e.code, e.name, e.description, extra = { "error_id" : errid, "errcode" : e.code, "errname" : e.name, "description" : e.description })
# response.content_type = "application/json"
return response
# Define a route for the root URL
@api.route('/')
class GitLib(Resource):
@ -170,6 +209,8 @@ class GitLib(Resource):
Returns:
Response: A Flask JSON response containing a welcome message.
"""
log.info("Root URL accessed")
return {
"message": "OpenGnsys Git API"
}
@ -197,6 +238,7 @@ class GitRepositories(Resource):
"""
if not os.path.isdir(REPOSITORIES_BASE_PATH):
log.error("Can't list repositories. Repository storage at %s not found", REPOSITORIES_BASE_PATH, extra = {"path" : REPOSITORIES_BASE_PATH})
return {"error": "Repository storage not found, git functionality may not be installed."}, 500
repos = []
@ -208,6 +250,7 @@ class GitRepositories(Resource):
repos = repos + [name]
log.info("Returning %i repositories", len(repos))
return {
"repositories": repos
}
@ -236,6 +279,7 @@ class GitRepositories(Resource):
repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git")
if os.path.isdir(repo_path):
log.error("Can't create repository %s, already exists at %s", repo, repo_path, extra = {"repository" : repo, "path" : repo_path})
return {"status": "Repository already exists"}, 200
@ -244,7 +288,7 @@ class GitRepositories(Resource):
#installer.init_git_repo(repo + ".git")
log.info("Repository %s created", repo, extra = {"repository" : repo})
return {"status": "Repository created"}, 201
@ -268,6 +312,7 @@ class GitRepoSync(Resource):
"""
repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git")
if not os.path.isdir(repo_path):
log.error("Can't sync repository %s, not found. Looked in %s", repo, repo_path, extra = {"repository" : repo, "path" : repo_path })
return {"error": "Repository not found"}, 404
@ -276,9 +321,15 @@ class GitRepoSync(Resource):
if data is None:
return {"error" : "Parameters missing"}, 400
if not "remote_repository" in data:
return {"error" : "Parameter 'remote_repository' missing"}, 400
future = executor.submit(do_repo_sync, repo, data)
task_id = str(uuid.uuid4())
tasks[task_id] = future
log.info("Starting synchronization of repository %s, task %s", repo, task_id, extra = {"repository" : repo, "task_id" : task_id})
return {"status": "started", "task_id" : task_id}, 200
@ -310,6 +361,7 @@ class GitRepoBackup(Resource):
"""
repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git")
if not os.path.isdir(repo_path):
log.error("Can't backup repository %s, not found. Looked in %s", repo, repo_path, extra = {"repository" : repo, "path" : repo_path })
return {"error": "Repository not found"}, 404
@ -326,6 +378,7 @@ class GitRepoBackup(Resource):
task_id = str(uuid.uuid4())
tasks[task_id] = future
log.info("Starting backup of repository %s, task %s", repo, task_id, extra = {"repository" : repo, "task_id" : task_id})
return {"status": "started", "task_id" : task_id}, 200
@git_ns.route('/repositories/<repo>/compact', methods=['POST'])
@ -348,12 +401,14 @@ class GitRepoCompact(Resource):
"""
repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git")
if not os.path.isdir(repo_path):
log.error("Can't compact repository %s, not found. Looked in %s", repo, repo_path, extra = {"repository" : repo, "path" : repo_path })
return {"error": "Repository not found"}, 404
future = executor.submit(do_repo_gc, repo)
task_id = str(uuid.uuid4())
tasks[task_id] = future
log.info("Starting compaction of repository %s, task %s", repo, task_id, extra = {"repository" : repo, "task_id" : task_id})
return {"status": "started", "task_id" : task_id}, 200
@ -373,14 +428,17 @@ class GitTaskStatus(Resource):
- If the task is still in progress, returns a 202 status indicating the task is in progress.
"""
if not task_id in tasks:
log.error("Task %s was not found", task_id, extra = {"task_id" : task_id})
return {"error": "Task not found"}, 404
future = tasks[task_id]
if future.done():
result = future.result()
log.info("Returning completion of task %s", task_id, extra = {"task_id" : task_id})
return {"status" : "completed", "result" : result}, 200
else:
log.info("Task %s is still in progress", task_id, extra = {"task_id" : task_id})
return {"status" : "in progress"}, 202
@ -405,10 +463,12 @@ class GitRepo(Resource):
"""
repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git")
if not os.path.isdir(repo_path):
log.error("Can't delete repository %s, not found. Looked in %s", repo, repo_path, extra = {"repository" : repo, "path" : repo_path })
return {"error": "Repository not found"}, 404
shutil.rmtree(repo_path)
log.info("Deleted repository %s", repo, extra = {"repository" : repo})
return {"status": "Repository deleted"}, 200
@ -430,6 +490,7 @@ class GitRepoBranches(Resource):
"""
repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git")
if not os.path.isdir(repo_path):
log.error("Can't get branches of repository repository %s, not found. Looked in %s", repo, repo_path, extra = {"repository" : repo, "path" : repo_path })
return {"error": "Repository not found"}, 404
git_repo = git.Repo(repo_path)
@ -438,7 +499,7 @@ class GitRepoBranches(Resource):
for branch in git_repo.branches:
branches = branches + [branch.name]
log.info("Returning %i branches", len(branches))
return {
"branches": branches
}
@ -460,6 +521,7 @@ class GitHealth(Resource):
active and functional.
"""
log.info("Health check endpoint called")
return {
"status": "OK"
}
@ -476,6 +538,8 @@ class GitStatus(Resource):
Response: A JSON response with status information
"""
log.info("Status endpoint called")
return {
"uptime" : time.time() - start_time,
"active_tasks" : len(tasks)