Migración dtic-DASUTEN a estándar A04: - A04_dtic-DASUTEN.md: Manifiesto creado - A04.P001 a A04.P005: Planes renombrados de P2601.* - _hist/_hist_P2601_dasuten.md: Legacy archivado Migración dtic-BKPs a estándar A03: - A03_dtic-BKPs.md: Manifiesto creado - A03.P001, A03.P002: Planes migrados - docs/ambito/dtic-BKPs/: Nueva estructura Herramientas ADN nuevas: - adn/tools/bkps/: BKPs migrado a tools ADN - adn/tools/cli/dron.rb: Vigía de tareas largas - adn/tools/cli/copiloto.rb: Asistente CLI - adn/tools/cli/novato.rb: CLI de aprendizaje Limpieza: - dtic-BKPs/ → _hist/dtic-BKPs/ (legacy archivado) - adn/tools/cli/backup.rb → _hist/ (migrado a bkps.rb) Otros: - nodos/pcv-dasu1.md, srvv-data.md, srvv-nginx-rm.md: Actualizados - adn/tools/core/conciliador.rb: Mejoras - adn/tools/w-zombi/data/cmd.json: Actualizado Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
89 lines
2.9 KiB
Ruby
89 lines
2.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# ==========================================================
|
|
# adn/tools/bkps/lib/proc_xen.rb — Procesador XEN (.xva)
|
|
# Migrado desde dtic-BKPs v6.0 → ADN::BKPs
|
|
# ==========================================================
|
|
|
|
require 'shellwords'
|
|
require 'open3'
|
|
require 'fileutils'
|
|
|
|
module ADN
|
|
module BKPs
|
|
module Procesador
|
|
class Xen
|
|
def initialize(log)
|
|
@log = log
|
|
@pv = system('which pv > /dev/null 2>&1')
|
|
end
|
|
|
|
def ejecutar(tarea)
|
|
@log.info("--- #{tarea[:texto]} ---")
|
|
@log.info("#{tarea[:id]}: Origen: #{tarea[:origen]}")
|
|
|
|
archivos = Dir.glob(File.join(tarea[:origen], '*.xva'))
|
|
if archivos.empty?
|
|
@log.info("#{tarea[:id]}: Sin archivos .xva en origen.")
|
|
return true
|
|
end
|
|
|
|
@log.info("Encontrados #{archivos.length} archivo(s) .xva.")
|
|
procesados = 0
|
|
|
|
archivos.each do |ruta_xva|
|
|
nombre_xva = File.basename(ruta_xva)
|
|
nombre_vm = nombre_xva.split('_').first
|
|
dir_dest = File.join(tarea[:destino], nombre_vm)
|
|
FileUtils.mkdir_p(dir_dest)
|
|
|
|
nombre_sin_ext = File.basename(nombre_xva, '.xva')
|
|
ruta_tar = File.join(dir_dest, "#{nombre_sin_ext}.tar.gz")
|
|
|
|
if File.exist?(ruta_tar)
|
|
if tarea[:sobrescribir]
|
|
@log.info("#{File.basename(ruta_tar)} existe. Sobrescribiendo.")
|
|
else
|
|
@log.info("#{File.basename(ruta_tar)} existe. Saltando.")
|
|
next
|
|
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
|
|
end
|
|
|
|
@log.info("✔ #{procesados} archivos .xva procesados.")
|
|
true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|