[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:
+39
-35
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user