docs: armonización masiva de bitácoras, categorización de nodos y diagnóstico srv-dasu
This commit is contained in:
Executable
+170
@@ -0,0 +1,170 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
# ==========================================================
|
||||
# dtic-BKPs — Procesador de Backups Automatizado v6.0
|
||||
# ----------------------------------------------------------
|
||||
# Refactorización de dtic-BKPs v5.5.1
|
||||
# AUTOR: Ricardo MONLA (rmonla@)
|
||||
# ==========================================================
|
||||
#
|
||||
# Uso:
|
||||
# ruby dtic-BKPs.rb # Menú interactivo (auto-screen)
|
||||
# ruby dtic-BKPs.rb T1 # Ejecutar tarea 1 directamente
|
||||
# ruby dtic-BKPs.rb C1 # Ejecutar comando 1 directamente
|
||||
# ruby dtic-BKPs.rb list # Listar tareas y comandos
|
||||
# ruby dtic-BKPs.rb --help # Ayuda
|
||||
|
||||
require 'shellwords'
|
||||
|
||||
# ─── Rutas ───────────────────────────────────────────────────
|
||||
APP_DIR = File.dirname(File.expand_path(__FILE__))
|
||||
LIB_DIR = File.join(APP_DIR, 'lib')
|
||||
|
||||
require_relative 'lib/logger'
|
||||
require_relative 'lib/config'
|
||||
require_relative 'lib/proc_proxmox'
|
||||
require_relative 'lib/proc_xen'
|
||||
require_relative 'lib/sync_rclone'
|
||||
require_relative 'lib/menu'
|
||||
|
||||
include DTICBKPs
|
||||
|
||||
# ─── Dispatcher ──────────────────────────────────────────────
|
||||
class Dispatcher
|
||||
TIPOS = {
|
||||
'proxmox' => -> (log) { Procesador::Proxmox.new(log) },
|
||||
'xva' => -> (log) { Procesador::Xen.new(log) },
|
||||
'rclone' => -> (log) { Procesador::Rclone.new(log) },
|
||||
}.freeze
|
||||
|
||||
def initialize(config, log)
|
||||
@config = config
|
||||
@log = log
|
||||
end
|
||||
|
||||
def ejecutar_tarea(tarea)
|
||||
tipo = tarea[:tipo].to_s
|
||||
factory = TIPOS[tipo]
|
||||
unless factory
|
||||
@log.error("Tipo desconocido: #{tipo}")
|
||||
return
|
||||
end
|
||||
procesador = factory.call(@log)
|
||||
procesador.ejecutar(tarea)
|
||||
end
|
||||
|
||||
def ejecutar_comando(comando)
|
||||
@log.titulo(comando[:texto])
|
||||
tareas_ids = comando[:tareas] || []
|
||||
tareas_ids.each_with_index do |id, i|
|
||||
tarea = @config.find_tarea(id)
|
||||
if tarea
|
||||
@log.paso("Paso #{i + 1}/#{tareas_ids.length}: #{tarea[:texto]}")
|
||||
ejecutar_tarea(tarea)
|
||||
else
|
||||
@log.error("Tarea '#{id}' no encontrada en comando '#{comando[:id]}'.")
|
||||
end
|
||||
end
|
||||
@log.ok("Comando '#{comando[:texto]}' completado.")
|
||||
end
|
||||
end
|
||||
|
||||
# ─── Auto-Screen Wrapper ─────────────────────────────────────
|
||||
def auto_screen!
|
||||
return if ENV['TERM']&.start_with?('screen') || ENV['STY']
|
||||
puts "\n#{C::CYAN}ℹ Relanzando en sesión screen para permitir desatención...#{C::RESET}"
|
||||
|
||||
cmd = ([$PROGRAM_NAME] + ARGV).map { |a| Shellwords.escape(a) }.join(' ')
|
||||
nombre = "dticbkps_#{Time.now.strftime('%H%M%S')}"
|
||||
|
||||
puts "Para reconectarte: #{C::YELLOW}screen -r #{nombre}#{C::RESET}"
|
||||
sleep 1
|
||||
|
||||
system('screen', '-dmS', nombre, 'bash', '-c', "#{cmd}; echo ''; read -p 'Enter para cerrar...'")
|
||||
exit 0
|
||||
end
|
||||
|
||||
# ─── Ctrl+C Handler ──────────────────────────────────────────
|
||||
Signal.trap('INT') do
|
||||
puts "\n#{C::RED}Ctrl+C — Saliendo...#{C::RESET}"
|
||||
exit 130
|
||||
end
|
||||
|
||||
# ─── Ayuda ───────────────────────────────────────────────────
|
||||
def mostrar_ayuda(config)
|
||||
puts <<~HELP
|
||||
#{C::BOLD}#{C::CYAN}dtic-BKPs — Procesador de Backups v6.0#{C::RESET}
|
||||
|
||||
#{C::YELLOW}Uso:#{C::RESET}
|
||||
ruby dtic-BKPs.rb Menú interactivo
|
||||
ruby dtic-BKPs.rb T<N> Ejecutar tarea N
|
||||
ruby dtic-BKPs.rb C<N> Ejecutar comando N
|
||||
ruby dtic-BKPs.rb list Listar tareas/comandos
|
||||
ruby dtic-BKPs.rb --help Esta ayuda
|
||||
|
||||
#{C::YELLOW}Tareas configuradas:#{C::RESET}
|
||||
HELP
|
||||
|
||||
config.tareas.each_with_index do |t, i|
|
||||
puts " #{C::GREEN}T#{i+1}#{C::RESET} #{t[:texto]} #{C::DIM}(#{t[:tipo]})#{C::RESET}"
|
||||
end
|
||||
|
||||
puts "\n #{C::YELLOW}Comandos configurados:#{C::RESET}"
|
||||
config.comandos.each_with_index do |c, i|
|
||||
puts " #{C::GREEN}C#{i+1}#{C::RESET} #{c[:texto]}"
|
||||
end
|
||||
end
|
||||
|
||||
def cmd_list(config)
|
||||
puts "#{C::BOLD}Tareas:#{C::RESET}"
|
||||
config.tareas.each_with_index do |t, i|
|
||||
puts " T#{i+1} #{t[:id]} #{t[:texto]} [#{t[:tipo]}] #{t[:origen]} → #{t[:destino]}"
|
||||
end
|
||||
puts "\n#{C::BOLD}Comandos:#{C::RESET}"
|
||||
config.comandos.each_with_index do |c, i|
|
||||
puts " C#{i+1} #{c[:id]} #{c[:texto]} → #{c[:tareas]&.join(', ')}"
|
||||
end
|
||||
end
|
||||
|
||||
# ─── Main ────────────────────────────────────────────────────
|
||||
|
||||
config_path = File.join(APP_DIR, 'dtic-BKPs.yml')
|
||||
log = AppLogger.new(File.join(APP_DIR, 'logs'))
|
||||
config = Config.new(config_path)
|
||||
dispatcher = Dispatcher.new(config, log)
|
||||
|
||||
arg = ARGV[0]&.strip
|
||||
|
||||
case arg
|
||||
when nil
|
||||
# Menú interactivo con auto-screen
|
||||
auto_screen!
|
||||
log.info("===== dtic-BKPs v6.0 iniciado (Screen) =====")
|
||||
Menu.new(config, dispatcher, log).ejecutar
|
||||
|
||||
when '--help', '-h', 'help'
|
||||
mostrar_ayuda(config)
|
||||
|
||||
when 'list'
|
||||
cmd_list(config)
|
||||
|
||||
when /^[TC]\d+$/i
|
||||
# Ejecución directa desde CLI
|
||||
tipo = arg[0].upcase
|
||||
idx = arg[1..].to_i - 1
|
||||
|
||||
if tipo == 'T' && config.tareas[idx]
|
||||
dispatcher.ejecutar_tarea(config.tareas[idx])
|
||||
elsif tipo == 'C' && config.comandos[idx]
|
||||
dispatcher.ejecutar_comando(config.comandos[idx])
|
||||
else
|
||||
puts "#{ERR} Opción no válida: #{arg}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
else
|
||||
puts "#{ERR} Comando desconocido: #{arg}"
|
||||
mostrar_ayuda(config)
|
||||
exit 1
|
||||
end
|
||||
Reference in New Issue
Block a user