Ticket #738, ticket #739: git sync and backup

ticket-769
Vadim vtroshchinskiy 2024-09-16 15:51:23 +02:00
parent 24071465e2
commit 8674c36223
2 changed files with 77 additions and 3 deletions

View File

@ -3,13 +3,54 @@ import os.path
import os import os
import git import git
import shutil import shutil
import subprocess
import uuid
from opengnsys_git_installer import OpengnsysGitInstaller from opengnsys_git_installer import OpengnsysGitInstaller
from flask import request from flask import Flask, request
from flask_executor import Executor
import subprocess
from flask import stream_with_context, Response
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__)
executor = Executor(app)
tasks = {}
def do_repo_backup(repo, params):
user = params["ssh_user"]
server = params["ssh_server"]
filename = params["filename"]
os.chdir(repositories_base_path)
os.chdir(f"{repo}.git")
subprocess.run(f"git archive --format=tar HEAD | ssh {user}@{server} -T \"cat > {filename}\"", shell=True, check=True)
#sleep(10)
def do_repo_sync(repo, params):
gitrepo = git.Repo(f"{repositories_base_path}/{repo}.git")
# Recreate the remote every time, it might change
if "backup" in gitrepo.remotes:
gitrepo.delete_remote("backup")
backup_repo = gitrepo.create_remote("backup", params["remote_repository"])
pushrets = backup_repo.push("*:*")
results = []
# This gets returned to the API
for ret in pushrets:
results = results + [ {"local_ref" : ret.local_ref.name, "remote_ref" : ret.remote_ref.name, "summary" : ret.summary }]
return results
# Define a route for the root URL # Define a route for the root URL
@app.route('/') @app.route('/')
@ -63,11 +104,19 @@ def sync_repo(repo):
data = request.json data = request.json
if data is None:
return jsonify({"error" : "Parameters missing"}), 400
dest_repo = data["remote_repository"] dest_repo = data["remote_repository"]
future = executor.submit(do_repo_sync, repo, data)
task_id = str(uuid.uuid4())
tasks[task_id] = future
return jsonify({"status": "started", "task_id" : task_id}), 200
return jsonify({"status": "Started synchronization", "repository" : repo, "destination_repository" : dest_repo}), 200 # return jsonify({"status": "Started synchronization", "repository" : repo, "destination_repository" : dest_repo}), 200
@app.route('/repositories/<repo>/backup', methods=['POST']) @app.route('/repositories/<repo>/backup', methods=['POST'])
@ -79,11 +128,35 @@ def backup_repo(repo):
data = request.json data = request.json
if data is None:
return jsonify({"error" : "Parameters missing"}), 400
dest_server = data["ssh_server"] dest_server = data["ssh_server"]
dest_user = data["ssh_user"] dest_user = data["ssh_user"]
dest_file = data["filename"] dest_file = data["filename"]
return jsonify({"status": "Started backup", "repository" : repo, "ssh_server" : dest_server, "ssh_user" : dest_user, "filename" : dest_file}), 200
future = executor.submit(do_repo_backup, repo, data)
task_id = str(uuid.uuid4())
tasks[task_id] = future
return jsonify({"status": "started", "task_id" : task_id}), 200
#return jsonify({"status": "Started backup", "repository" : repo, "ssh_server" : dest_server, "ssh_user" : dest_user, "filename" : dest_file}), 200
@app.route('/tasks/<task_id>/status')
def tasks_status(task_id):
if not task_id in tasks:
return jsonify({"error": "Task not found"}), 404
future = tasks[task_id]
if future.done():
result = future.result()
return jsonify({"status" : "completed", "result" : result}), 200
else:
return jsonify({"status" : "in progress"}), 202
@app.route('/repositories/<repo>', methods=['DELETE']) @app.route('/repositories/<repo>', methods=['DELETE'])

View File

@ -2,6 +2,7 @@ click==8.0.4
colorterm==0.3 colorterm==0.3
dataclasses==0.8 dataclasses==0.8
Flask==2.0.3 Flask==2.0.3
Flask-Executor==1.0.0
gitdb==4.0.9 gitdb==4.0.9
GitPython==3.1.20 GitPython==3.1.20
importlib-metadata==4.8.3 importlib-metadata==4.8.3