Files
dtic-DIIAA/adn/tools/cli/dasuten_orquestador.rb
Ricardo Monla 892019fa22 [A04.P005] DASUTEN: Pipeline refactorizado + Documentación + Informes
Refactorización del pipeline de backups DASUTEN:

1. Flujo simplificado (un solo destino):
   - Backup directo a X:\ (share srv-ns8)
   - Eliminado paso intermedio E:\BK_SQL\sysdasuten\
   - Reducido de 3 ubicaciones a 2 (X: → /var/tmp/)

2. Módulo común DasuExecutor (lib/dasu_executor.rb):
   - Centraliza ejecución PowerShell en dasu-sql4
   - Centraliza verificación de archivos en fenix
   - Elimina código repetido en 6 drones (-52% líneas)

3. Drones refactorizados:
   - dasuten_exportar_srvv-fenix.rb (FULL → X:)
   - dasuten_exportar_diferencial_srvv-fenix.rb (DIF → X:)
   - dasuten_transferir_srvv-fenix-srv-ns8.rb (simplificado)
   - dasuten_restaurar_dasu-sql4.rb (usa DasuExecutor)
   - dasuten_restaurar_diferencial_dasu-sql4.rb (usa DasuExecutor)
   - dasuten_download_drive-dasu-sql4.rb (usa DasuExecutor)
   - dasuten_verificar-integridad_dasu-sql4.rb (usa DasuExecutor)

4. Integración BKPs mantenida:
   - T8-T15: Tareas individuales
   - C7: dasuten_full (pipeline semanal)
   - C8: dasuten_diferencial (pipeline diario)

5. Documentación actualizada:
   - A04.P006_Backups-DASUTEN.md: flujo simplificado + módulo común
   - Lecciones aprendidas agregadas

6. Nuevos archivos:
   - Informes técnicos DASUTEN (docs/informes/2026-04_DASUTEN-migracion/)
   - A01.P011/P012: Documentación de drones y pipeline
   - proc_linux.rb, ops.rb: Utilitarios del ecosistema

7. Scripts legacy (para referencia):
   - orquestador_pipeline.rb, orquestador_pipeline_diferencial.rb
   - dasuten_upload_srv-ns8-drive.rb
2026-04-14 20:06:06 -03:00

138 lines
4.9 KiB
Ruby
Executable File

#!/usr/bin/env ruby
# frozen_string_literal: true
# ==========================================================
# adn/tools/cli/dasuten_orquestador.rb — Orquestador Fase 8b
# ==========================================================
# Flujo completo: srvv-fenix → Google Drive → dasu-sql4
# Uso: ruby adn/tools/cli/dasuten_orquestador.rb [upload|download|restore]
# ==========================================================
require 'optparse'
require_relative 'dron/dispatcher'
PROJECT_ROOT = File.expand_path('../..', __dir__)
CLI_DIR = File.join(PROJECT_ROOT, 'adn', 'tools', 'cli')
ADN_RUN = File.join(PROJECT_ROOT, 'adn', 'tools', 'run')
opciones = {
paso: 'all',
dry_run: false,
nodo: nil
}
OptionParser.new do |opts|
opts.banner = "Uso: #{ADN_RUN} dasuten_orquestador [opciones]"
opts.on("--paso PASO", %w[upload download restore all], "Ejecutar solo este paso (upload|download|restore|all)") { |p| opciones[:paso] = p }
opts.on("--nodo NOMBRE", "Nodo para bitácora del dron") { |n| opciones[:nodo] = n }
opts.on("--dry-run", "Simulación sin ejecutar") { opciones[:dry_run] = true }
end.parse!(ARGV)
puts "\n#{'='*60}"
puts "🛸 ORQUESTADOR DASUTEN — Fase 8b (Refresco BD vía Google Drive)"
puts '='*60
puts " Paso seleccionado: #{opciones[:paso]}"
puts " Dry-run: #{opciones[:dry_run]}"
puts " Nodo: #{opciones[:nodo] || 'auto-detect'}"
puts '='*60
def lanzar_dron(cmd, nota, nodo: nil)
puts "\n🛸 Lanzando dron: #{nota}"
puts " Comando: #{cmd}"
args = ["lanzar", "--nota", nota]
args << "--nodo" << nodo if nodo
args << "--" << cmd
# Ejecutar dron directamente
require_relative 'dron/ejecutor'
resultado = Dron::Ejecutor.lanzar(
cmd: cmd,
nota: nota,
nodo: nodo,
timeout: 1800 # 30 minutos max
)
resultado
end
caso = opciones[:paso]
# ──────────────────────────────────────────────────────────────
# PASO 1: UPLOAD desde srvv-fenix a Google Drive
# ──────────────────────────────────────────────────────────────
if caso == 'all' || caso == 'upload'
puts "\n" + "─"*60
puts "📤 PASO 1: Upload desde srvv-fenix → Google Drive"
puts "─"*60
cmd_upload = "ruby #{CLI_DIR}/dasuten_backup_upload.rb"
if opciones[:dry_run]
puts "[DRY-RUN] Ejecutaría: #{cmd_upload}"
else
resultado = lanzar_dron(cmd_upload, "📤 Upload backup DASUTEN a Drive", nodo: 'srvv-fenix')
if resultado[:exit_code] != 0
puts "\n❌ Upload fallido. Deteniendo orquestación."
exit 1
end
end
end
# ──────────────────────────────────────────────────────────────
# PASO 2: DOWNLOAD desde Google Drive a dasu-sql4
# ──────────────────────────────────────────────────────────────
if caso == 'all' || caso == 'download'
puts "\n" + "─"*60
puts "📥 PASO 2: Download desde Google Drive → dasu-sql4"
puts "─"*60
cmd_download = "ruby #{CLI_DIR}/dasuten_backup_download.rb"
if opciones[:dry_run]
puts "[DRY-RUN] Ejecutaría: #{cmd_download}"
else
resultado = lanzar_dron(cmd_download, "📥 Download backup DASUTEN desde Drive", nodo: 'dasu-sql4')
if resultado[:exit_code] != 0
puts "\n❌ Download fallido. Deteniendo orquestación."
exit 1
end
end
end
# ──────────────────────────────────────────────────────────────
# PASO 3: RESTORE en dasu-sql4
# ──────────────────────────────────────────────────────────────
if caso == 'all' || caso == 'restore'
puts "\n" + "─"*60
puts "💾 PASO 3: Restore + DBCC CHECKDB en dasu-sql4"
puts "─"*60
cmd_restore = <<~SQL.gsub("\n", ' ').strip
powershell -Command "
$query = @'
RESTORE DATABASE sysdasuten FROM DISK = 'F:\\BACKUP\\sysdasuten_compressed_ADN.bak'
WITH REPLACE,
MOVE 'sysdasuten' TO 'F:\\DATA\\sysdasuten.mdf',
MOVE 'sysdasuten_log' TO 'F:\\LOG\\sysdasuten_log.ldf';
DBCC CHECKDB('sysdasuten');
'@
sqlcmd -S localhost -Q $query
"
SQL
if opciones[:dry_run]
puts "[DRY-RUN] Ejecutaría: #{cmd_restore}"
else
resultado = lanzar_dron(cmd_restore, "💾 Restore + CHECKDB DASUTEN", nodo: 'dasu-sql4')
if resultado[:exit_code] != 0
puts "\n❌ Restore fallido. Verificar logs."
exit 1
end
end
end
puts "\n" + "═"*60
puts "✅ Orquestación completada exitosamente!"
puts "═"*60