Compare commits
5 Commits
sudoers-og
...
main
Author | SHA1 | Date |
---|---|---|
|
b2066d3e5d | |
|
eace7142ae | |
|
8bd472fd6b | |
|
c9c8952741 | |
|
e0b9a036ca |
29
CHANGELOG.md
29
CHANGELOG.md
|
@ -1,15 +1,28 @@
|
|||
# Changelog
|
||||
|
||||
## [0.10.3] - 2025-09-22
|
||||
### Changed
|
||||
- Actualiza sudoers para permitir ejecutar cpio sin contraseña
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.10.4] - 2025-09-30
|
||||
|
||||
### Fixed
|
||||
|
||||
- Set safe.directory just once
|
||||
|
||||
## [0.10.3] - 2025-09-18
|
||||
|
||||
### Changed
|
||||
|
||||
- Create tags via a query to the forgejo API
|
||||
|
||||
## [0.10.2] - 2025-09-01
|
||||
|
||||
## Fixed
|
||||
### Fixed
|
||||
|
||||
- Corregida la logica en el endpoint create torrent sum
|
||||
- Mejoras en los mensajes de logs
|
||||
- Corregida la logica en el endpoint create torrent sum
|
||||
- Mejoras en los mensajes de logs
|
||||
- Mejoras en la validación de los archivos info e info.checked
|
||||
|
||||
## [0.10.1] - 2025-08-25
|
||||
|
@ -25,13 +38,13 @@
|
|||
|
||||
- OgGit functionality (#2371, #2363, #2363, #2317)
|
||||
|
||||
### Removed
|
||||
### Removed
|
||||
|
||||
- Removed unused BitTorrent-related packages and logic
|
||||
|
||||
## [0.9.0] - 2025-06-25
|
||||
|
||||
## Added
|
||||
### Added
|
||||
|
||||
- Changed old tools for tools non dependant of Pyhton2 in repo
|
||||
- mktorrent to handle creation of torrent files
|
||||
|
|
106
api/repo_api.py
106
api/repo_api.py
|
@ -14,15 +14,13 @@ Librerías Python requeridas: - flask (se puede instalar con "sudo apt install p
|
|||
- flasgger (se puede instalar con "sudo apt install python3-flasgger")
|
||||
"""
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# IMPORTS
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
from flask import Flask, jsonify, request
|
||||
import os
|
||||
import subprocess
|
||||
import json
|
||||
from time import sleep
|
||||
import time
|
||||
import sys
|
||||
import git
|
||||
import paramiko
|
||||
import logging
|
||||
import threading
|
||||
|
@ -34,13 +32,8 @@ from systemd import journal
|
|||
# Imports para Swagger:
|
||||
from flasgger import Swagger
|
||||
import yaml
|
||||
import time
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# VARIABLES
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
repo_path = '/opt/opengnsys/ogrepository/images/' # No borrar la barra final
|
||||
vm_path = '/opt/opengnsys/ogrepository/images_virtual/' # No borrar la barra final
|
||||
script_path = '/opt/opengnsys/ogrepository/bin'
|
||||
|
@ -48,21 +41,10 @@ repo_file = '/opt/opengnsys/ogrepository/etc/repoinfo.json'
|
|||
trash_file = '/opt/opengnsys/ogrepository/etc/trashinfo.json'
|
||||
config_file = '/opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg'
|
||||
|
||||
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# GIT
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
REPOSITORIES_BASE_PATH = "/opt/opengnsys/ogrepository/oggit/git/"
|
||||
OGGIT_USER = "oggit"
|
||||
OGGIT_FORGEJO_PORT = 3100
|
||||
|
||||
import sys
|
||||
import git
|
||||
import paramiko
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# FUNCTIONS
|
||||
|
@ -273,7 +255,7 @@ def check_lock_local(image_file_path, job_id):
|
|||
journal.send("Running function 'check_lock_local'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
||||
|
||||
# Esperamos 30 segundos, para dar tiempo a que se cree el archivo ".lock":
|
||||
sleep(30)
|
||||
time.sleep(30)
|
||||
|
||||
# Creamos un bucle infinito:
|
||||
while True:
|
||||
|
@ -310,7 +292,7 @@ def check_lock_local(image_file_path, job_id):
|
|||
journal.send("Task in process (.lock file exists)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
||||
|
||||
# Esperamos 1 minuto para volver a realizar la comprobación:
|
||||
sleep(60)
|
||||
time.sleep(60)
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
@ -335,7 +317,7 @@ def check_remote_backup(image_name, remote_ip, remote_user, remote_path, job_id)
|
|||
sftp_client = ssh_client.open_sftp()
|
||||
|
||||
# Esperamos 30 segundos antes de empezar a realizar la comprobación:
|
||||
sleep(30)
|
||||
time.sleep(30)
|
||||
|
||||
# Creamos una lista con las extensiones de los archivos asociados a la imagen (incluyendo ninguna extensión, que corresponde a la propia imagen):
|
||||
extensions = ['', '.size', '.sum', '.full.sum', '.info']
|
||||
|
@ -424,7 +406,7 @@ def check_remote_backup(image_name, remote_ip, remote_user, remote_path, job_id)
|
|||
journal.send("Task in process (backup incomplete)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
||||
|
||||
# Esperamos 1 minuto para volver a realizar la comprobación:
|
||||
sleep(60)
|
||||
time.sleep(60)
|
||||
|
||||
# Ya fuera del bucle, cerramos el cliente SSH y el cliente SFTP:
|
||||
ssh_client.close()
|
||||
|
@ -490,7 +472,7 @@ def check_aux_files(image_file_path, job_id):
|
|||
recall_ogcore(data)
|
||||
break
|
||||
# Esperamos 10 segundos para volver a realizar la comprobación:
|
||||
sleep(10)
|
||||
time.sleep(10)
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
@ -506,7 +488,7 @@ def check_virtual_image_conversion(image_name, job_id):
|
|||
journal.send("Running function 'check_virtual_image_conversion'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
||||
|
||||
# Esperamos 30 segundos, para dar tiempo a que se cree algún archivo:
|
||||
sleep(30)
|
||||
time.sleep(30)
|
||||
|
||||
# Construimos la ruta de la imagen (una vez convertida):
|
||||
image_file_path = f"{repo_path}{image_name}.img"
|
||||
|
@ -547,7 +529,7 @@ def check_virtual_image_conversion(image_name, job_id):
|
|||
journal.send("Task in process (Conversion not finalized)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
||||
|
||||
# Esperamos 1 minuto para volver a realizar la comprobación:
|
||||
sleep(60)
|
||||
time.sleep(60)
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
@ -562,7 +544,7 @@ def check_virtual_image_reconversion(image_name, vm_extension, job_id):
|
|||
journal.send("Running function 'check_virtual_image_reconversion'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
||||
|
||||
# Esperamos 30 segundos, para dar tiempo a que se cree algún archivo:
|
||||
sleep(30)
|
||||
time.sleep(30)
|
||||
|
||||
# Construimos la ruta de la imagen virtual (una vez exportada), y la ruta de exportación:
|
||||
virtual_image_file_path = f"{vm_path}export/{image_name}.{vm_extension}"
|
||||
|
@ -604,7 +586,7 @@ def check_virtual_image_reconversion(image_name, vm_extension, job_id):
|
|||
journal.send("Task in process (Conversion not finalized)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
||||
|
||||
# Esperamos 1 minuto para volver a realizar la comprobación:
|
||||
sleep(60)
|
||||
time.sleep(60)
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
@ -1504,7 +1486,7 @@ def send_udpcast():
|
|||
result = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='UTF8')
|
||||
|
||||
# Comprobamos si está corriendo el proceso correspondiente de "udp-sender" (esperando 5 segundos para darle tiempo a iniciarse):
|
||||
sleep(5)
|
||||
time.sleep(5)
|
||||
process_running = search_process('udp-sender', f"{param_dict['name']}.{param_dict['extension']}")
|
||||
|
||||
# Evaluamos el resultado de la ejecución, y devolvemos una respuesta:
|
||||
|
@ -1577,7 +1559,7 @@ def send_uftp():
|
|||
result = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='UTF8')
|
||||
|
||||
# Comprobamos si está corriendo el proceso correspondiente de "uftp" (esperando 5 segundos para darle tiempo a iniciarse):
|
||||
sleep(5)
|
||||
time.sleep(5)
|
||||
process_running = search_process('uftp', f"{param_dict['name']}.{param_dict['extension']}")
|
||||
|
||||
# Evaluamos el resultado de la ejecución, y devolvemos una respuesta:
|
||||
|
@ -1659,7 +1641,7 @@ def send_p2p():
|
|||
|
||||
# Comprobamos si el tracker y el seeder están corriendo, y si apuntan al directorio que le hemos pasado
|
||||
# (esperamos 10 segundos antes de hacerlo, porque los procesos no se inician inmediatamente):
|
||||
sleep(10)
|
||||
time.sleep(10)
|
||||
seeder_running = search_process('aria2c', f"{param_dict['name']}.img.torrent") # El seeder se ejecuta con "aria2c" y el nombre de la imagen como parámetro
|
||||
|
||||
|
||||
|
@ -2267,6 +2249,11 @@ def rename_image():
|
|||
#
|
||||
# -----------------------------------------------------------
|
||||
|
||||
def repo_set_safe_directory (repo, path):
|
||||
try:
|
||||
repo.git.config ('--get', 'safe-directory')
|
||||
except:
|
||||
repo.git.config ('--global', '--add', 'safe.directory', path)
|
||||
|
||||
def git_forgejo_post_command(url, json_data):
|
||||
token = ""
|
||||
|
@ -2301,6 +2288,12 @@ def git_forgejo_create_repo(repo):
|
|||
"private" : False
|
||||
})
|
||||
|
||||
def git_forgejo_create_tag(repo,tag,msg,target):
|
||||
return git_forgejo_post_command(f"/api/v1/repos/oggit/{repo}/tags", {
|
||||
"message": msg,
|
||||
"tag_name": tag,
|
||||
"target": target
|
||||
})
|
||||
|
||||
def git_forgejo_add_sshkey(pubkey, description = ""):
|
||||
return git_forgejo_post_command("/api/v1/user/keys",
|
||||
|
@ -2315,7 +2308,7 @@ def git_compact_repository_task(repo, job_id):
|
|||
|
||||
git_repo_path = os.path.join(REPOSITORIES_BASE_PATH, OGGIT_USER, repo + ".git")
|
||||
git_repo = git.Repo(git_repo_path)
|
||||
git_repo.git.config('--global', '--add', 'safe.directory', git_repo_path)
|
||||
repo_set_safe_directory (git_repo, git_repo_path)
|
||||
|
||||
git_repo.git.gc()
|
||||
|
||||
|
@ -2332,7 +2325,7 @@ def git_sync_repository_task(repo, remote_repository, job_id):
|
|||
|
||||
git_repo_path = os.path.join(REPOSITORIES_BASE_PATH, OGGIT_USER, repo + ".git")
|
||||
git_repo = git.Repo(git_repo_path)
|
||||
git_repo.git.config('--global', '--add', 'safe.directory', git_repo_path)
|
||||
repo_set_safe_directory (git_repo, git_repo_path)
|
||||
|
||||
# Recreate the remote every time, it might change
|
||||
if "backup" in git_repo.remotes:
|
||||
|
@ -2360,7 +2353,7 @@ def git_backup_repository_task(repo, params, job_id):
|
|||
|
||||
git_repo_path = os.path.join(REPOSITORIES_BASE_PATH, OGGIT_USER, repo + ".git")
|
||||
git_repo = git.Repo(git_repo_path)
|
||||
git_repo.git.config('--global', '--add', 'safe.directory', git_repo_path)
|
||||
repo_set_safe_directory (git_repo, git_repo_path)
|
||||
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
|
@ -2575,7 +2568,7 @@ def git_get_branches(repo):
|
|||
return jsonify({"error": "Repository not found"}), 404
|
||||
|
||||
git_repo = git.Repo(repo_path)
|
||||
git_repo.git.config('--global', '--add', 'safe.directory', repo_path)
|
||||
repo_set_safe_directory (git_repo, repo_path)
|
||||
|
||||
branches = []
|
||||
for branch in git_repo.branches:
|
||||
|
@ -2611,7 +2604,7 @@ def git_get_commits(repo, branch):
|
|||
|
||||
|
||||
git_repo = git.Repo(repo_path)
|
||||
git_repo.git.config('--global', '--add', 'safe.directory', repo_path)
|
||||
repo_set_safe_directory (git_repo, repo_path)
|
||||
|
||||
|
||||
if not branch in git_repo.branches:
|
||||
|
@ -2701,7 +2694,7 @@ def git_create_branch(repo):
|
|||
return jsonify({"error": "Repository not found"}), 404
|
||||
|
||||
git_repo = git.Repo(repo_path)
|
||||
git_repo.git.config('--global', '--add', 'safe.directory', repo_path)
|
||||
repo_set_safe_directory (git_repo, repo_path)
|
||||
|
||||
data = request.json
|
||||
if data is None:
|
||||
|
@ -2746,7 +2739,7 @@ def git_delete_branch(repo, branch):
|
|||
return {"error": "Repository not found"}, 404
|
||||
|
||||
git_repo = git.Repo(repo_path)
|
||||
git_repo.git.config('--global', '--add', 'safe.directory', repo_path)
|
||||
repo_set_safe_directory (git_repo, repo_path)
|
||||
|
||||
|
||||
if not branch in git_repo.branches:
|
||||
|
@ -2778,7 +2771,7 @@ def git_list_tags(repo):
|
|||
return jsonify({"error": "Repository not found"}), 404
|
||||
|
||||
git_repo = git.Repo(repo_path)
|
||||
git_repo.git.config('--global', '--add', 'safe.directory', repo_path)
|
||||
repo_set_safe_directory (git_repo, repo_path)
|
||||
|
||||
|
||||
tags = []
|
||||
|
@ -2818,14 +2811,6 @@ def git_create_tag(repo):
|
|||
- 409: A JSON object with an "error" key containing the message "Tag already exists"
|
||||
"""
|
||||
|
||||
repo_path = os.path.join(REPOSITORIES_BASE_PATH, OGGIT_USER, repo + ".git")
|
||||
if not os.path.isdir(repo_path):
|
||||
journal.send(f"Can't create tag. Repository storage at {REPOSITORIES_BASE_PATH} not found", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
||||
return jsonify({"error": "Repository not found"}), 404
|
||||
|
||||
git_repo = git.Repo(repo_path)
|
||||
git_repo.git.config('--global', '--add', 'safe.directory', repo_path)
|
||||
|
||||
data = request.json
|
||||
if data is None:
|
||||
journal.send(f"Can't create tag. JSON post data missing", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
||||
|
@ -2845,21 +2830,16 @@ def git_create_tag(repo):
|
|||
if "message" in data:
|
||||
commit_message = data["message"]
|
||||
|
||||
if tag in git_repo.tags:
|
||||
journal.send(f"Can't create tag. Already found in repository {repo}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
||||
return jsonify({"error": "Tag already exists"}), 409
|
||||
|
||||
try:
|
||||
git_repo.create_tag(tag, ref = data["commit"], message = commit_message)
|
||||
except git.exc.GitCommandError as ge:
|
||||
if "not a valid tag name" in ge.stderr:
|
||||
journal.send(f"Tag name {tag} is invalid", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
||||
return jsonify({"error" : "Invalid tag name"}), 400
|
||||
else:
|
||||
journal.send(f"Git error {ge}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
||||
return jsonify({"error" : "Error when performing git command"}), 500
|
||||
|
||||
res = git_forgejo_create_tag(repo,tag,commit_message,data["commit"])
|
||||
except Exception as e:
|
||||
journal.send (str(e), PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
||||
return jsonify({"error" : f"git_forgejo_create_tag failed: {e}"}), 500
|
||||
|
||||
if 200 != res[0]:
|
||||
j = json.loads(res[1])
|
||||
journal.send (j["message"], PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
||||
return jsonify({"error" : j["message"]}), 409
|
||||
|
||||
journal.send(f"Tag {tag} created in repo {repo}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
||||
return jsonify({"status": "created"}), 200
|
||||
|
@ -2883,7 +2863,7 @@ def git_delete_tag(repo, tag):
|
|||
return {"error": "Repository not found"}, 404
|
||||
|
||||
git_repo = git.Repo(repo_path)
|
||||
git_repo.git.config('--global', '--add', 'safe.directory', repo_path)
|
||||
repo_set_safe_directory (git_repo, repo_path)
|
||||
|
||||
|
||||
if not tag in git_repo.tags:
|
||||
|
|
Loading…
Reference in New Issue