Ticket #808: Initial implementation
parent
9af377f9fa
commit
22173d67bb
|
@ -52,22 +52,34 @@ import os
|
|||
import shutil
|
||||
import uuid
|
||||
import git
|
||||
import time
|
||||
from opengnsys_git_installer import OpengnsysGitInstaller
|
||||
from flask import Flask, request, jsonify # stream_with_context, Response,
|
||||
from flask_executor import Executor
|
||||
from flask_restx import Api, Resource, fields
|
||||
#from flasgger import Swagger
|
||||
import paramiko
|
||||
|
||||
REPOSITORIES_BASE_PATH = "/opt/opengnsys/images"
|
||||
|
||||
start_time = time.time()
|
||||
tasks = {}
|
||||
|
||||
|
||||
# Create an instance of the Flask class
|
||||
app = Flask(__name__)
|
||||
api = Api(app,
|
||||
version='0.50',
|
||||
title = "OpenGnsys Git API",
|
||||
description = "API for managing disk images stored in Git",
|
||||
doc = "/swagger/")
|
||||
|
||||
git_ns = api.namespace(name = "oggit", description = "Git operations", path = "/oggit/v1")
|
||||
|
||||
executor = Executor(app)
|
||||
|
||||
|
||||
|
||||
tasks = {}
|
||||
|
||||
|
||||
|
||||
def do_repo_backup(repo, params):
|
||||
"""
|
||||
|
@ -147,20 +159,24 @@ def do_repo_gc(repo):
|
|||
|
||||
|
||||
# Define a route for the root URL
|
||||
@app.route('/')
|
||||
def home():
|
||||
@api.route('/')
|
||||
class GitLib(Resource):
|
||||
|
||||
@api.doc('home')
|
||||
def get(self):
|
||||
"""
|
||||
Home route that returns a JSON response with a welcome message for the OpenGnsys Git API.
|
||||
|
||||
Returns:
|
||||
Response: A Flask JSON response containing a welcome message.
|
||||
"""
|
||||
return jsonify({
|
||||
return {
|
||||
"message": "OpenGnsys Git API"
|
||||
})
|
||||
}
|
||||
|
||||
@app.route('/repositories')
|
||||
def get_repositories():
|
||||
@git_ns.route('/oggit/v1/repositories')
|
||||
class GitRepositories(Resource):
|
||||
def get(self):
|
||||
"""
|
||||
Retrieve a list of Git repositories.
|
||||
|
||||
|
@ -196,8 +212,7 @@ def get_repositories():
|
|||
"repositories": repos
|
||||
})
|
||||
|
||||
@app.route('/repositories/<repo>', methods=['PUT'])
|
||||
def create_repo(repo):
|
||||
def post(self):
|
||||
"""
|
||||
Create a new Git repository.
|
||||
|
||||
|
@ -212,6 +227,13 @@ def create_repo(repo):
|
|||
- 200: If the repository already exists.
|
||||
- 201: If the repository is successfully created.
|
||||
"""
|
||||
data = request.json
|
||||
|
||||
if data is None:
|
||||
return jsonify({"error" : "Parameters missing"}), 400
|
||||
|
||||
repo = data["name"]
|
||||
|
||||
repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git")
|
||||
if os.path.isdir(repo_path):
|
||||
return jsonify({"status": "Repository already exists"}), 200
|
||||
|
@ -224,8 +246,9 @@ def create_repo(repo):
|
|||
return jsonify({"status": "Repository created"}), 201
|
||||
|
||||
|
||||
@app.route('/repositories/<repo>/sync', methods=['POST'])
|
||||
def sync_repo(repo):
|
||||
@git_ns.route('/oggit/v1/repositories/<repo>/sync')
|
||||
class GitRepoSync(Resource):
|
||||
def post(self, repo):
|
||||
"""
|
||||
Synchronize a repository with a remote repository.
|
||||
|
||||
|
@ -257,8 +280,10 @@ def sync_repo(repo):
|
|||
return jsonify({"status": "started", "task_id" : task_id}), 200
|
||||
|
||||
|
||||
@app.route('/repositories/<repo>/backup', methods=['POST'])
|
||||
def backup_repository(repo):
|
||||
|
||||
@git_ns.route('/oggit/v1/repositories/<repo>/backup')
|
||||
class GitRepoBackup(Resource):
|
||||
def backup_repository(self, repo):
|
||||
"""
|
||||
Backup a specified repository.
|
||||
|
||||
|
@ -301,8 +326,9 @@ def backup_repository(repo):
|
|||
|
||||
return jsonify({"status": "started", "task_id" : task_id}), 200
|
||||
|
||||
@app.route('/repositories/<repo>/gc', methods=['POST'])
|
||||
def gc_repo(repo):
|
||||
@git_ns.route('/oggit/v1/repositories/<repo>/compact', methods=['POST'])
|
||||
class GitRepoCompact(Resource):
|
||||
def post(self, repo):
|
||||
"""
|
||||
Initiates a garbage collection (GC) process for a specified Git repository.
|
||||
|
||||
|
@ -329,8 +355,9 @@ def gc_repo(repo):
|
|||
return jsonify({"status": "started", "task_id" : task_id}), 200
|
||||
|
||||
|
||||
@app.route('/tasks/<task_id>/status')
|
||||
def tasks_status(task_id):
|
||||
@git_ns.route('/oggit/v1/tasks/<task_id>/status')
|
||||
class GitTaskStatus(Resource):
|
||||
def get(self, task_id):
|
||||
"""
|
||||
Endpoint to check the status of a specific task.
|
||||
|
||||
|
@ -356,8 +383,9 @@ def tasks_status(task_id):
|
|||
|
||||
|
||||
|
||||
@app.route('/repositories/<repo>', methods=['DELETE'])
|
||||
def delete_repo(repo):
|
||||
@git_ns.route('/oggit/v1/repositories/<repo>', methods=['DELETE'])
|
||||
class GitRepo(Resource):
|
||||
def delete(self, repo):
|
||||
"""
|
||||
Deletes a Git repository.
|
||||
|
||||
|
@ -384,8 +412,9 @@ def delete_repo(repo):
|
|||
|
||||
|
||||
|
||||
@app.route('/repositories/<repo>/branches')
|
||||
def get_repository_branches(repo):
|
||||
@git_ns.route('/oggit/v1/repositories/<repo>/branches')
|
||||
class GitRepoBranches(Resource):
|
||||
def get(self, repo):
|
||||
"""
|
||||
Retrieve the list of branches for a given repository.
|
||||
|
||||
|
@ -415,8 +444,9 @@ def get_repository_branches(repo):
|
|||
|
||||
|
||||
|
||||
@app.route('/health')
|
||||
def health_check():
|
||||
@git_ns.route('/health')
|
||||
class GitHealth(Resource):
|
||||
def get(self):
|
||||
"""
|
||||
Health check endpoint.
|
||||
|
||||
|
@ -428,10 +458,33 @@ def health_check():
|
|||
active and functional.
|
||||
|
||||
"""
|
||||
return jsonify({
|
||||
return {
|
||||
"status": "OK"
|
||||
})
|
||||
}
|
||||
|
||||
@git_ns.route('/status')
|
||||
class GitStatus(Resource):
|
||||
def get(self):
|
||||
"""
|
||||
Status check endpoint.
|
||||
|
||||
This endpoint returns a JSON response indicating the status of the application.
|
||||
|
||||
Returns:
|
||||
Response: A JSON response with status information
|
||||
|
||||
"""
|
||||
return {
|
||||
"uptime" : time.time() - start_time,
|
||||
"active_tasks" : len(tasks)
|
||||
}
|
||||
|
||||
|
||||
api.add_namespace(git_ns)
|
||||
|
||||
|
||||
|
||||
# Run the Flask app
|
||||
if __name__ == '__main__':
|
||||
print(f"Map: {app.url_map}")
|
||||
app.run(debug=True, host='0.0.0.0')
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
aniso8601==9.0.1
|
||||
attrs==24.2.0
|
||||
bcrypt==4.2.0
|
||||
blinker==1.8.2
|
||||
cffi==1.17.1
|
||||
click==8.1.7
|
||||
cryptography==43.0.1
|
||||
dataclasses==0.6
|
||||
flasgger==0.9.7.1
|
||||
Flask==3.0.3
|
||||
Flask-Executor==1.0.0
|
||||
flask-restx==1.3.0
|
||||
gitdb==4.0.11
|
||||
GitPython==3.1.43
|
||||
importlib_resources==6.4.5
|
||||
itsdangerous==2.2.0
|
||||
Jinja2==3.1.4
|
||||
jsonschema==4.23.0
|
||||
jsonschema-specifications==2024.10.1
|
||||
libarchive-c==5.1
|
||||
MarkupSafe==3.0.1
|
||||
mistune==3.0.2
|
||||
packaging==24.1
|
||||
paramiko==3.5.0
|
||||
pycparser==2.22
|
||||
PyNaCl==1.5.0
|
||||
pytz==2024.2
|
||||
PyYAML==6.0.2
|
||||
referencing==0.35.1
|
||||
rpds-py==0.20.0
|
||||
six==1.16.0
|
||||
smmap==5.0.1
|
||||
termcolor==2.5.0
|
||||
Werkzeug==3.0.4
|
Loading…
Reference in New Issue