🐝 Fase 2: Orquestador 1-dron-por-archivo (bkps orquestar)
- proc_xen.rb: listar() scanner + ejecutar_uno() atómico - bkps.rb: --archivo flag + subcomando orquestar - Patrón: scan → lanza drones secuenciales → 1 VM por dron - Filosofía: Menos es Más
This commit is contained in:
@@ -3,6 +3,11 @@
|
||||
# ==========================================================
|
||||
# adn/tools/bkps/lib/proc_xen.rb — Procesador XEN (.xva)
|
||||
# Migrado desde dtic-BKPs v6.0 → ADN::BKPs
|
||||
#
|
||||
# Fase 2: Soporta orquestación 1-dron-por-archivo
|
||||
# listar(tarea) → lista archivos pendientes
|
||||
# ejecutar_uno(tarea, arch) → comprime UN solo archivo
|
||||
# ejecutar(tarea) → comprime TODOS (legacy)
|
||||
# ==========================================================
|
||||
|
||||
require 'shellwords'
|
||||
@@ -18,6 +23,51 @@ module ADN
|
||||
@pv = system('which pv > /dev/null 2>&1')
|
||||
end
|
||||
|
||||
# Scanner: devuelve lista de archivos .xva pendientes de procesar
|
||||
def listar(tarea)
|
||||
archivos = Dir.glob(File.join(tarea[:origen], '*.xva'))
|
||||
archivos.map do |ruta_xva|
|
||||
nombre_xva = File.basename(ruta_xva)
|
||||
nombre_vm = nombre_xva.split('_').first
|
||||
dir_dest = File.join(tarea[:destino], nombre_vm)
|
||||
nombre_sin_ext = File.basename(nombre_xva, '.xva')
|
||||
ruta_tar = File.join(dir_dest, "#{nombre_sin_ext}.tar.gz")
|
||||
|
||||
{
|
||||
archivo: nombre_xva,
|
||||
ruta: ruta_xva,
|
||||
vm: nombre_vm,
|
||||
destino: ruta_tar,
|
||||
tamaño: File.size(ruta_xva),
|
||||
pendiente: !File.exist?(ruta_tar) || tarea[:sobrescribir]
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
# Atómico: comprime UN solo archivo .xva
|
||||
def ejecutar_uno(tarea, nombre_archivo)
|
||||
ruta_xva = File.join(tarea[:origen], nombre_archivo)
|
||||
unless File.exist?(ruta_xva)
|
||||
@log.error("Archivo no encontrado: #{nombre_archivo}")
|
||||
return false
|
||||
end
|
||||
|
||||
nombre_vm = nombre_archivo.split('_').first
|
||||
dir_dest = File.join(tarea[:destino], nombre_vm)
|
||||
FileUtils.mkdir_p(dir_dest)
|
||||
|
||||
nombre_sin_ext = File.basename(nombre_archivo, '.xva')
|
||||
ruta_tar = File.join(dir_dest, "#{nombre_sin_ext}.tar.gz")
|
||||
|
||||
if File.exist?(ruta_tar) && !tarea[:sobrescribir]
|
||||
@log.info("#{File.basename(ruta_tar)} existe. Saltando.")
|
||||
return true
|
||||
end
|
||||
|
||||
comprimir(tarea, ruta_xva, nombre_archivo, ruta_tar)
|
||||
end
|
||||
|
||||
# Legacy: procesa TODOS los archivos (compatibilidad con sistema previo)
|
||||
def ejecutar(tarea)
|
||||
@log.info("--- #{tarea[:texto]} ---")
|
||||
@log.info("#{tarea[:id]}: Origen: #{tarea[:origen]}")
|
||||
@@ -49,39 +99,44 @@ module ADN
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
@log.info("Comprimiendo #{nombre_xva}")
|
||||
|
||||
if @pv
|
||||
cmd_tar = ['tar', '-czf', '-', '-C', tarea[:origen], nombre_xva]
|
||||
cmd_pv = ['pv', '-s', File.size(ruta_xva).to_s]
|
||||
File.open(ruta_tar, 'wb') do |f|
|
||||
Open3.pipeline(cmd_tar, cmd_pv, out: f).each_with_index do |s, i|
|
||||
raise "Falló #{%w[tar pv][i]} (#{s.exitstatus})" unless s.success?
|
||||
end
|
||||
end
|
||||
else
|
||||
cmd = "tar -czf #{Shellwords.escape(ruta_tar)} -C #{Shellwords.escape(tarea[:origen])} #{Shellwords.escape(nombre_xva)}"
|
||||
system(cmd) or raise "tar falló (#{$?.exitstatus})"
|
||||
end
|
||||
|
||||
@log.info("✔ Compresión OK: #{File.basename(ruta_tar)}")
|
||||
|
||||
if tarea[:eliminar_origen]
|
||||
FileUtils.rm_f(ruta_xva)
|
||||
@log.info("XVA original eliminado.")
|
||||
end
|
||||
|
||||
procesados += 1
|
||||
rescue => e
|
||||
@log.error("#{tarea[:id]}: Error comprimiendo #{nombre_xva}: #{e.message}")
|
||||
FileUtils.rm_f(ruta_tar)
|
||||
end
|
||||
procesados += 1 if comprimir(tarea, ruta_xva, nombre_xva, ruta_tar)
|
||||
end
|
||||
|
||||
@log.info("✔ #{procesados} archivos .xva procesados.")
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def comprimir(tarea, ruta_xva, nombre_xva, ruta_tar)
|
||||
@log.info("Comprimiendo #{nombre_xva}")
|
||||
|
||||
if @pv
|
||||
cmd_tar = ['tar', '-czf', '-', '-C', tarea[:origen], nombre_xva]
|
||||
cmd_pv = ['pv', '-s', File.size(ruta_xva).to_s]
|
||||
File.open(ruta_tar, 'wb') do |f|
|
||||
Open3.pipeline(cmd_tar, cmd_pv, out: f).each_with_index do |s, i|
|
||||
raise "Falló #{%w[tar pv][i]} (#{s.exitstatus})" unless s.success?
|
||||
end
|
||||
end
|
||||
else
|
||||
cmd = "tar -czf #{Shellwords.escape(ruta_tar)} -C #{Shellwords.escape(tarea[:origen])} #{Shellwords.escape(nombre_xva)}"
|
||||
system(cmd) or raise "tar falló (#{$?.exitstatus})"
|
||||
end
|
||||
|
||||
@log.info("✔ Compresión OK: #{File.basename(ruta_tar)}")
|
||||
|
||||
if tarea[:eliminar_origen]
|
||||
FileUtils.rm_f(ruta_xva)
|
||||
@log.info("XVA original eliminado.")
|
||||
end
|
||||
|
||||
true
|
||||
rescue => e
|
||||
@log.error("#{tarea[:id]}: Error comprimiendo #{nombre_xva}: #{e.message}")
|
||||
FileUtils.rm_f(ruta_tar)
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user