[P2604] Fase 15: Optimización IA e integración de herramienta candados. Sincronización de bitácoras y actualización de planes de proyecto.

This commit is contained in:
Ricardo Monla
2026-03-19 09:52:29 -03:00
parent 183dbf6fb6
commit 5aa37e7221
138 changed files with 8777 additions and 464 deletions
+39 -35
View File
@@ -4,13 +4,15 @@ require 'optparse'
require 'fileutils'
require 'date'
require_relative 'backup/configurador'
require_relative '../core/colores'
require_relative '../core/help_formatter'
module ADN
class SubcomandoBackup
def initialize(args, logger)
@args = args
@logger = logger
# Cargar valores predeterminados desde config.yml
defaults = Configurador.obtener('backup.defaults') || {}
@opciones = {
@@ -22,6 +24,12 @@ module ADN
end
def ejecutar
# Handle help flags
if @args.empty? || @args[0] == 'help' || @args[0] == '-h' || @args[0] == '--help'
mostrar_ayuda
return
end
parser = OptionParser.new do |opts|
opts.banner = "Uso: ./adn/tools/run backup <nodo|estados> [OPCIONES]"
opts.separator ""
@@ -107,7 +115,7 @@ module ADN
# Usar popen para leer la salida en tiempo real
@logger.info("Conectando y monitoreando salida de Proxmox...")
clave = (@nodo[:nombre] == 'srv-dasu' ? 'srv-dasu:rmonla' : 'admindasu')
clave = (datos[:host_name] == 'srv-dasu' ? 'srv-dasu:rmonla' : 'admindasu')
IO.popen("ruby #{candados_path} run #{clave} SSHPASS '#{cmd_seguro}' 2>&1") do |pf|
pf.each_line do |line|
# Imprimir flujo para el usuario
@@ -609,46 +617,42 @@ module ADN
@logger.info("Auto-cerrando backup de #{nodo_actual} (Task ID: #{tarea['id']})")
cerrar_entrada_especifica(nodo_actual, hora_inicio_str, exito, tarea['id'], hora_fin)
end
end
end
private
def mostrar_ayuda
ayuda = ADN::HelpFormatter.generar_help(
titulo: "Backup ADN",
descripcion: "Ejecuta un backup remoto o consulta el estado actual.",
uso: "./adn/tools/run backup <nodo|estados> [OPCIONES]",
opciones: [
{ names: ['<nodo>'], desc: "Ejecutar backup del nodo especificado" },
{ names: ['estados'], desc: "Ver estado actual de los backups en Proxmox" },
{ names: ['sanear'], desc: "Limpiar backups antiguos según retención" },
{ names: ['predeterminar'], desc: "Configurar valores por defecto" },
{ names: ['--mode MODO'], desc: "Modo de backup (stop, snapshot, suspend)" },
{ names: ['--storage STORAGE'], desc: "Nombre del storage en Proxmox" },
{ names: ['-h', '--help'], desc: "Mostrar esta ayuda" }
],
ejemplos: [
{ cmd: "./adn/tools/run backup srv-dasu", desc: "Ejecutar backup del nodo srv-dasu" },
{ cmd: "./adn/tools/run backup estados", desc: "Ver estado de backups en Proxmox" },
{ cmd: "./adn/tools/run backup sanear", desc: "Limpiar backups antiguos" }
]
)
puts ayuda
end
end
end
def cerrar_entrada_especifica(nodo, hora_ini, exito, task_id, hora_fin)
fecha = Date.today.iso8601
ruta = File.join(ADN::BITACORAS_DIR, "#{fecha}.md")
return unless File.exist?(ruta)
estado_ico = exito ? '✅' : '⚠️'
desc = exito ? 'Backup completado exitosamente.' : 'Fallo en la ejecución del backup.'
desc = "[task:#{task_id[0..7]}] #{desc}" if task_id
linea_nueva = "| #{hora_ini} | #{hora_fin} | #{desc} | R | #{estado_ico} |"
contenido = File.read(ruta)
# Buscamos la fila específica que coincida con el nodo Y la hora de inicio
# Capturamos el bloque del nodo para evitar errores si otros nodos tienen la misma hora
regex_seccion = /(### #{Regexp.escape(nodo)}.*?)(?=^###\s|<!--|\z)/m
seccion = contenido.match(regex_seccion)&.[](0)
unless seccion
return
end
# Regex para la fila exacta que tenga la hora de inicio Y un reloj ⏳ en la última columna
regex_fila = /\|\s*#{Regexp.escape(hora_ini)}\s*\|\s*\|\s*[^|]*\|\s*[^|]*\|\s*[^|]*⏳[^|]*\|/
if seccion.match?(regex_fila)
@logger.exito("Reconciliado: #{nodo} (#{hora_ini} -> #{hora_fin})")
nueva_seccion = seccion.sub(regex_fila, linea_nueva)
# Si ya no quedan ⏳ en esta sección, actualizamos su icono #### ⏳ -> ✅
# Buscamos cualquier reloj de arena que quede en la sección
unless nueva_seccion.include?('⏳')
nueva_seccion.gsub!(/#### [⏳⏳] - BKP-ADN/, "#### #{estado_ico} - BKP-ADN")
end
nuevo_contenido = contenido.gsub(seccion, nueva_seccion)
File.write(ruta, nuevo_contenido)
end
end
end
end
end
end