update_torrent_repos #38

Merged
opengnsys merged 10 commits from update_torrent_repos into main 2025-06-26 19:31:03 +02:00
9 changed files with 213 additions and 73 deletions

View File

@ -1,5 +1,20 @@
# Changelog
## [0.9.0] - 2025-06-25
## Added
- Changed old tools for tools non dependant of Pyhton2 in repo
- mktorrent to handle creation of torrent files
- aria2c as torrent client for initial seeding
- opentracker as torrent tracker tool
## [0.8.2] - 2025-06-01
### Changed
- Modified sudoersfile to start torrent
## [0.8.1] - 2025-04-01
### Changed

View File

@ -143,7 +143,7 @@ def search_process(process, string_to_search):
""" Busca procesos que contengan el valor del parámetro "process" y el valor del parámetro "string_to_search" (la ruta de la imagen, normalmente).
Si encuentra alguno retorna "True", y si no encuentra ninguno retorna "False".
"""
journal.send("Running function 'search_process'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
journal.send(f"Running function 'search_process' {process} wit string {string_to_search}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
try:
# Obtenemos todos los procesos que están corriendo, y almacenamos la salida y los errores:
@ -155,11 +155,11 @@ def search_process(process, string_to_search):
# Si hemos encontrado algún proceso que cumpla las condiciones, retornamos "True", y si no retornamos "False":
if process_list != []:
journal.send("Process found", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
journal.send(f"Process found: {process} with string {string_to_search} ", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
journal.send("{'component':'ogRepo', 'severity':'INFO', 'operation':'Run function search_process', 'desc':'Process found'}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api")
return True
else:
journal.send("Process not found", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
journal.send(f"Process not found: {process} with string {string_to_search}", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
journal.send("{'component':'ogRepo', 'severity':'WARNING', 'operation':'Run function search_process', 'desc':'Process not found'}", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api")
return False
# Si se ha producido una excepción, imprimimos el error:
@ -1357,7 +1357,7 @@ def create_torrent_sum():
# ---------------------------------------------------------
# 12 - Endpoint "Enviar paquete Wake On Lan" (SINCRONO):
# 12 - Endoint "Enviar paquete Wake On Lan" (SINCRONO):
@app.route("/ogrepository/v1/wol", methods=['POST'])
def send_wakeonlan():
""" Este endpoint envía un paquete mágico Wake On Lan a la dirección MAC especificada, a través de la IP de broadcast especificadac.
@ -1567,8 +1567,7 @@ def send_p2p():
# Evaluamos los parámetros obtenidos, para construir las llamadas a los scripts, o para devolver un error si no se ha encontrado la imagen:
if param_dict:
cmd_tracker = ['sudo', 'python3', f"{script_path}/runTorrentTracker.py"] # Este script si que requiere ser ejecutado con "sudo"
cmd_seeder = ['sudo', 'python3', f"{script_path}/runTorrentSeeder.py"] # Este script si que requiere ser ejecutado con "sudo"
cmd_seeder = ['python3', f"{script_path}/runTorrentSeeder.py" , param_dict['name']] # Este script si que requiere ser ejecutado con "sudo" , Lanzamos el seeder con el nombre de la imagen como parámetro
base_path = repo_path.rstrip('/') # Le quito la última barra para poder buscar correctamente en los procesos
else:
journal.send("Image not found", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
@ -1578,11 +1577,18 @@ def send_p2p():
"error": "Image not found"
}), 400
# Ejecutamos los scripts "runTorrentSeeder.py" y "runTorrentSeeder.py", que no reciben parámetros.
# NOTA: No almacenamos la salida ni comprobamos los errores, porque los procesos quedarán corriendo hasta que se finalicen manualmente,
# por lo que no podemos comprobar el returncode (luego comprobaremos si los procesos se han iniciado correctamente).
journal.send("Running script 'runTorrentTracker.py'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
subprocess.Popen(cmd_tracker)
# Comprobamos si el tracker esta ejecutandose, si no lo esta devolevemos un error y salimos del endpoint:
tracker_running = search_process('opentracker' , '/etc/opentracker/opentracker.conf') # El tracker se ececuta con "opentracker" y el fichero de configuración "/etc/opentracker/opentracker.conf"
if not tracker_running:
journal.send("Tracker not running", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
journal.send("{'component':'ogRepo', 'severity':'ERROR', 'http_code':'500', 'operation':'Run opentrack', 'desc':'Tracker not running'}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api")
error_message = "Tracker not running. Check if the tracker is installed and configured correctly."
return jsonify({
"success": False,
"error": error_message
}), 500
# Ejecutamos los scripts "runTorrentSeeder.py", que no reciben parámetros.
journal.send("Running script 'runTorrentSeeder.py'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
subprocess.Popen(cmd_seeder)
@ -1590,26 +1596,29 @@ 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)
tracker_running = search_process('bttrack', base_path)
seeder_running = search_process('btlaunchmany', base_path)
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
# Evaluamos las comprobaciones anteriores, para devolver la respuesta que corresponda:
if tracker_running and seeder_running:
journal.send("Scripts 'runTorrentTracker.py' and 'runTorrentSeeder.py' results OK (ReturnCodes: None), and processes running", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
journal.send("{'component':'ogRepo', 'severity':'INFO', 'http_code':'200', 'operation':'Run scripts runTorrentTracker.py and runTorrentSeeder.py', 'desc':'Results OK (ReturnCodes: None), and processes running'}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api")
if seeder_running:
journal.send("'runTorrentSeeder.py' results OK (ReturnCodes: None), and processes running", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
journal.send("{'component':'ogRepo', 'severity':'INFO', 'http_code':'200', 'operation':'Run script runTorrentSeeder.py', 'desc':'Results OK (ReturnCodes: None), and processes running'}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api")
return jsonify({
"success": True,
"output": "Tracker and Seeder serving image correctly"
}), 200
else:
journal.send("Scripts 'runTorrentTracker.py' and 'runTorrentSeeder.py' results KO (Tracker or/and Seeder not runnig)", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
journal.send("{'component':'ogRepo', 'severity':'ERROR', 'http_code':'500', 'operation':'Run scripts runTorrentTracker.py and runTorrentSeeder.py', 'desc':'Results KO (Tracker or/and Seeder not runnig)'}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api")
journal.send("Script 'runTorrentSeeder.py' results KO (Seeder not runnig)", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
journal.send("{'component':'ogRepo', 'severity':'ERROR', 'http_code':'500', 'operation':'Run script runTorrentSeeder.py', 'desc': '" + error_message + "'}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api")
error_message = f"Seeder not running. Check if the image {param_dict['name']}.{param_dict['extension']} exists in the repository."
return jsonify({
"success": False,
"error": "Tracker or Seeder (or both) not running"
"error": error_message
}), 500
# ---------------------------------------------------------

View File

@ -134,8 +134,8 @@ def create_torrent(file_path, torrent_file, datafullsum):
repo_ip = get_IPlocal()
tracker_url = f"http://{repo_ip}:6969/announce"
# Creamos una lista con el comando para crear el torrrent, y lo imprimimos con espacios:
splitted_cmd = f"nice -n 0 ctorrent -t {file_path} -u {tracker_url} -s {torrent_file} -c {datafullsum} -l 4194304".split()
# Creamos una litas para ejecutar el comando mktorrent para crear el archivo torrent
splitted_cmd = f"nice -n 0 mktorrent -a {tracker_url} -c {datafullsum} -o {torrent_file} {file_path}".split()
print(f"Sending command: {' '.join(splitted_cmd)}")
# Ejecutamos el comando en el sistema, e imprimimos el resultado:

View File

@ -106,11 +106,11 @@ def main():
total_disk, used_disk, free_disk, percent_disk = get_disk_info()
# Obtenemos el estado de los servicios listados, que almacenamos en un diccionario:
service_list = ['ssh', 'smbd', 'rsync']
service_list = ['ssh', 'smbd', 'opentracker']
services_status = {service: get_service_status(service) for service in service_list}
# Obtenemos el estado de los procesos listados, que almacenamos en un diccionario:
process_list = ['udp-sender', 'uftp', 'bttrack', 'btlaunchmany.bittornado']
process_list = ['udp-sender', 'uftp', 'aria2c']
process_status = {process: get_process_status(process) for process in process_list}
# Creamos un diccionario con toda la información obtenida:

View File

@ -16,6 +16,8 @@ No recibe ningún parámetro.
import os
import sys
import subprocess
import psutil
import re
from systemd import journal
@ -31,29 +33,73 @@ repo_path = '/opt/opengnsys/ogrepository/images' # En este caso, no lleva barra
# --------------------------------------------------------------------------------------------
def run_bittornado(repo_path):
""" Ejecuta el comando "btlaunchmany.bittornado", con sus parámetros correspondientes.
Además, captura el resultado y los posibles errores, y los imprime.
"""
# Creamos una lista con el comando "btlaunchmany.bittornado" y sus parámetros, y lo imprimimos con espacios:
splitted_cmd = f"btlaunchmany.bittornado {repo_path}".split()
print(f"Sending command: {' '.join(splitted_cmd)}")
journal.send(f"runTorrentSeeder.py: Running command: {' '.join(splitted_cmd)}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# Ejecutamos el comando "btlaunchmany.bittornado" en el sistema, e imprimimos el resultado:
# def run_bittornado(repo_path):
# """ Ejecuta el comando "btlaunchmany.bittornado", con sus parámetros correspondientes.
# Además, captura el resultado y los posibles errores, y los imprime.
# """
# # Creamos una lista con el comando "btlaunchmany.bittornado" y sus parámetros, y lo imprimimos con espacios:
# splitted_cmd = f"btlaunchmany.bittornado {repo_path}".split()
# print(f"Sending command: {' '.join(splitted_cmd)}")
# journal.send(f"runTorrentSeeder.py: Running command: {' '.join(splitted_cmd)}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# # Ejecutamos el comando "btlaunchmany.bittornado" en el sistema, e imprimimos el resultado:
# try:
# result = subprocess.run(splitted_cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# journal.send(f"runTorrentSeeder.py: Command ReturnCode: {result.returncode}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# print(f"Bittornado ReturnCode: {result.returncode}")
# except subprocess.CalledProcessError as error:
# journal.send("runTorrentSeeder.py: Process finalized", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# print(f"Bittornado ReturnCode: {error.returncode}")
# print(f"Bittornado Error Output: {error.stderr.decode()}")
# except Exception as error:
# journal.send(f"runTorrentSeeder.py: Command exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# print(f"Unexpected bittornado error: {error}")
def run_aria2c_seeder(image_name):
"""Lanza aria2c como seeder puro para una imagen concreta ya existente."""
repo_path = '/opt/opengnsys/ogrepository/images'
torrent_file = os.path.join(repo_path, f"{image_name}.img.torrent")
image_file = os.path.join(repo_path, f"{image_name}.img")
# Verificación básica
if not os.path.exists(torrent_file):
print(f"Torrent file not found: {torrent_file}")
journal.send(f"Seeder error: Torrent file not found: {torrent_file}",
PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api")
return
if not os.path.exists(image_file):
print(f"Image file not found: {image_file}")
journal.send(f"Seeder error: Image file not found: {image_file}",
PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api")
return
# Comando aria2c como seeder puro
cmd = [
'aria2c',
'--enable-peer-exchange=true',
'--bt-seed-unverified=true',
'--check-integrity=true',
'--seed-ratio=0.0',
'--dir=' + repo_path,
torrent_file
]
journal.send(f"Launching aria2c seeder for {image_name}",
PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api")
journal.send(f"Command: {' '.join(cmd)}",
PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api")
print("Running command:", ' '.join(cmd))
try:
result = subprocess.run(splitted_cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
journal.send(f"runTorrentSeeder.py: Command ReturnCode: {result.returncode}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
print(f"Bittornado ReturnCode: {result.returncode}")
except subprocess.CalledProcessError as error:
journal.send("runTorrentSeeder.py: Process finalized", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
print(f"Bittornado ReturnCode: {error.returncode}")
print(f"Bittornado Error Output: {error.stderr.decode()}")
except Exception as error:
journal.send(f"runTorrentSeeder.py: Command exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
print(f"Unexpected bittornado error: {error}")
subprocess.run(cmd, check=True)
except subprocess.CalledProcessError as e:
journal.send(f"aria2c seeder failed: {e}",
PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api")
print(f"Seeder process exited with code {e.returncode}")
# --------------------------------------------------------------------------------------------
# MAIN
@ -64,16 +110,40 @@ def main():
"""
"""
# Finalizamos el proceso "btlaunchmany.bittornado" (en caso de que estuviera corriendo):
try:
journal.send("runTorrentSeeder.py: Killing process 'btlaunchmany.bittornado'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
subprocess.run(f"pkill btlaunchmany".split(), check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except Exception as error_description:
journal.send("runTorrentSeeder.py: No 'btlaunchmany.bittornado' process running", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
print(f"No btlaunchmany.bittornado process running? Returned error: {error_description}")
if len(sys.argv) != 2:
print("Usage: runTorrentSeeder.py <image_name>")
journal.send("runTorrentSeeder.py: Invalid number of arguments. Expected 1 argument: <image_name>",
PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
sys.exit(1)
image_name = sys.argv[1]
torrent_file = os.path.join(repo_path, f"{image_name}.img.torrent")
found = False
# Matamos los procesos de aria2c que sirvan la imagen en concreto. Chequeamos todos los procesos
# Ejecutamos el comando "btlaunchmany.bittornado" (para hacer seed de los torrents):
run_bittornado(repo_path)
journal.send(f"runTorrentSeeder.py: looking for aria2c processes for {image_name}.torrent",
PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
for proc in psutil.process_iter(['pid','name','cmdline']):
try:
if proc.info['name'] != 'aria2c':
continue
if any(arg.endswith(torrent_file) for arg in proc.info['cmdline']):
proc.terminate()
found = True
print(f"Killed aria2c process with PID {proc.info['pid']} for {image_name}.torrent")
journal.send(f"runTorrentSeeder.py: Killed aria2c process with PID {proc.info['pid']} for {image_name}.torrent",
PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
except (psutil.NoSuchProcess, psutil.AccessDenied):
continue
if not found:
print(f"No aria2c process found for {image_name}.torrent")
journal.send(f"runTorrentSeeder.py: No aria2c process found for {image_name}.torrent",
PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# Lanzamos aria2c como seeder para la imagen proporcionada
run_aria2c_seeder(image_name)
# --------------------------------------------------------------------------------------------

4
debian/control vendored
View File

@ -8,7 +8,7 @@ Build-Depends: debhelper-compat (= 12)
Package: ogrepository
Architecture: all
Pre-Depends: debian-archive-keyring , debconf (>= 1.5.0),
Depends: ${misc:Depends}, git, python3, python3-pip, python3-flask, python3-paramiko, python3-psutil, python3-flasgger, samba, gunicorn, wakeonlan , lzop , partclone , qemu-utils , udpcast, uftp
Depends: ${misc:Depends}, git, python3, python3-pip, python3-flask, python3-paramiko, python3-psutil, python3-flasgger, samba, gunicorn, wakeonlan , lzop , partclone , qemu-utils , udpcast, uftp, mktorrent, aria2 , opengnsys-opentracker
Description: Ogrepsoitory Package
This package provides Ogrepository service.
X-OG-Release: opengnsys-1.6.0-beta, opengnsys-1.6.1-beta

View File

@ -5,6 +5,25 @@ set -x
. /usr/share/debconf/confmodule
restore_config_if_modified() {
local new="$1"
local backup="$1.bak.upgrade_package"
if [ -f "$backup" ]; then
if ! cmp -s "$new" "$backup"; then
echo ">>> Archivo modificado por el usuario detectado en $new"
echo " - Guardando archivo nuevo como ${new}.new"
mv -f "$new" "${new}.new"
echo " - Restaurando archivo anterior desde backup"
mv -f "$backup" "$new"
else
echo ">>> El archivo $new no ha cambiado desde la última versión, eliminando backup"
rm -f "$backup"
fi
fi
}
# Cargar variables de configuración
db_get opengnsys/ogrepository_ogrepoIp
OGREPO_IP="$RET"
@ -23,17 +42,17 @@ USER="opengnsys"
# Detectar si es una instalación nueva o una actualización
# if [ "$1" = "configure" ] && [ -z "$2" ]; then
# systemd-run --no-block /bin/bash -c "
# sleep 10;
# apt update -y;
# for pkg in bittorrent bittornado ctorrent; do
# if ! dpkg -l | grep -qw \"\$pkg\"; then
# apt install -y \"\$pkg\"
# fi
# done
# "
if [ "$1" = "configure" ] && [ -z "$2" ]; then
systemd-run --no-block /bin/bash -c "
sleep 10;
apt update -y;
for pkg in bittorrent bittornado ctorrent; do
if ! dpkg -l | grep -qw \"\$pkg\"; then
apt install -y \"\$pkg\"
fi
done
"
sed -i "s/%%OGREPOSITORY_USER%%/$SAMBA_USER/g" /etc/systemd/system/ogrepo-api.service
sed -i "s/%%OGREPOSITORY_USER%%/$SAMBA_USER/g" /etc/samba/ogrepo-smb.conf
@ -62,7 +81,7 @@ done
fi
(echo "$SAMBA_PASS"; echo "$SAMBA_PASS") | smbpasswd -a $SAMBA_USER
fi
systemctl enable ogrepo-api
# Configure Repo
cp /opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg.tmpl /opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg
@ -83,6 +102,14 @@ elif [ "$1" = "configure" ] && [ -n "$2" ]; then
cp /opt/opengnsys/ogrepository/etc/opengnsys.pub $OPENGNSYS_HOME/.ssh/id_ed25519.pub
cat $OPENGNSYS_HOME/.ssh/id_ed25519.pub >> $OPENGNSYS_HOME/.ssh/authorized_keys
restore_config_if_modified "/opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg"
restore_config_if_modified "/opt/opengnsys/ogrepository/etc/repoinfo.json"
restore_config_if_modified "/opt/opengnsys/ogrepository/etc/trashinfo.json"
restore_config_if_modified "/etc/samba/smb.conf"
restore_config_if_modified "/etc/samba/ogrepo-smb.conf"
restore_config_if_modified "/etc/sudoers.d/opengnsys-repository"
fi
# Cambiar la propiedad de los archivos al usuario especificado

View File

@ -2,8 +2,18 @@
set -e
KEY_FILE="/usr/share/keyrings/debian-archive-buster-stable.gpg"
REPO_FILE="/etc/apt/sources.list.d/buster.list"
backup_file_if_exists() {
local original="$1"
local backup="$1.bak.upgrade_package"
if [ -e "$original" ]; then
echo " - Guardando backup de $original en $backup"
cp -a "$original" "$backup"
fi
}
# KEY_FILE="/usr/share/keyrings/debian-archive-buster-stable.gpg"
# REPO_FILE="/etc/apt/sources.list.d/buster.list"
# Asegurarse de que el usuario exista
USER="opengnsys"
@ -20,10 +30,17 @@ echo "Añadiendo el repositorio de Debian Buster en $REPO_FILE..."
mkdir -p "$(dirname "$REPO_FILE")"
# Crear el archivo de repositorio si no existe
if [ ! -f "$REPO_FILE" ]; then
echo "deb [signed-by=$KEY_FILE] http://ftp.de.debian.org/debian buster main" > "$REPO_FILE"
else
echo "El repositorio ya está configurado en $REPO_FILE"
fi
# if [ ! -f "$REPO_FILE" ]; then
# echo "deb [signed-by=$KEY_FILE] http://ftp.de.debian.org/debian buster main" > "$REPO_FILE"
# else
# echo "El repositorio ya está configurado en $REPO_FILE"
# fi
backup_file_if_exists "/opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg"
backup_file_if_exists "/opt/opengnsys/ogrepository/etc/repoinfo.json"
backup_file_if_exists "/opt/opengnsys/ogrepository/etc/trashinfo.json"
backup_file_if_exists "/etc/samba/smb.conf"
backup_file_if_exists "/etc/samba/ogrepo-smb.conf"
backup_file_if_exists "/etc/sudoers.d/ogrepository"
exit 0

View File

@ -25,5 +25,7 @@ Cmnd_Alias KILL_BT = \
/usr/bin/pkill -9 bttrack, \
/usr/bin/kill -9 *
Cmnd_Alias PYTHON_OGREPO = /usr/bin/python3 /opt/opengnsys/ogrepository/bin/*
# Permitir al usuario opengnsys ejecutar estos comandos sin contraseña
opengnsys ALL=(root) NOPASSWD: MOUNT_RECOVERY, CHROOT_GRUB, LOOP_KPARTX, KILL_BT
opengnsys ALL=(root) NOPASSWD: MOUNT_RECOVERY, CHROOT_GRUB, LOOP_KPARTX, KILL_BT, PYTHON_OGREPO