diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index b4bb0097..b241f25c 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -6,7 +6,9 @@ class DeployJob < ApplicationJob class DeployTimedOutException < DeployException; end # rubocop:disable Metrics/MethodLength - def perform(site, notify = true, time = Time.now) + def perform(site, notify: true, time: Time.now, output: false) + @output = output + ActiveRecord::Base.connection_pool.with_connection do @site = Site.find(site) @@ -22,7 +24,7 @@ class DeployJob < ApplicationJob "#{@site.name} la tarea estuvo más de 10 minutos esperando, volviendo al estado original" end - DeployJob.perform_in(60, site, notify, time) + DeployJob.perform_in(60, site, notify: notify, time: time, output: output) return end @@ -75,13 +77,13 @@ class DeployJob < ApplicationJob end def deploy_locally - deploy_local.deploy + deploy_local.deploy(output: @output) end def deploy_others @site.deploys.where.not(type: 'DeployLocal').find_each do |d| begin - status = d.deploy + status = d.deploy(output: @output) seconds = d.build_stats.last.try(:seconds) rescue StandardError => e status = false diff --git a/app/models/deploy.rb b/app/models/deploy.rb index b7c1d2c7..79da67ca 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -11,7 +11,7 @@ class Deploy < ApplicationRecord belongs_to :site has_many :build_stats, dependent: :destroy - def deploy + def deploy(**) raise NotImplementedError end @@ -55,20 +55,26 @@ class Deploy < ApplicationRecord # # @param [String] # @return [Boolean] - def run(cmd) + def run(cmd, output: false) r = nil lines = [] time_start Dir.chdir(site.path) do Open3.popen2e(env, cmd, unsetenv_others: true) do |_, o, t| - r = t.value - # XXX: Tenemos que leer línea por línea porque en salidas largas - # se cuelga la IO # TODO: Enviar a un websocket para ver el proceso en vivo? - o.each do |line| - lines << line + Thread.new do + o.each do |line| + lines << line + + puts line if output + end + rescue IOError => e + lines << e.message + puts e.message if output end + + r = t.value end end time_stop diff --git a/app/models/deploy_alternative_domain.rb b/app/models/deploy_alternative_domain.rb index d245ac21..5ad381d5 100644 --- a/app/models/deploy_alternative_domain.rb +++ b/app/models/deploy_alternative_domain.rb @@ -5,7 +5,7 @@ class DeployAlternativeDomain < Deploy store :values, accessors: %i[hostname], coder: JSON # Generar un link simbólico del sitio principal al alternativo - def deploy + def deploy(**) File.symlink?(destination) || File.symlink(site.hostname, destination).zero? end diff --git a/app/models/deploy_hidden_service.rb b/app/models/deploy_hidden_service.rb index 8df46c2e..dc9549f5 100644 --- a/app/models/deploy_hidden_service.rb +++ b/app/models/deploy_hidden_service.rb @@ -2,7 +2,7 @@ # Genera una versión onion class DeployHiddenService < DeployWww - def deploy + def deploy(**) return true if fqdn.blank? super diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 7b41ce35..1964fd28 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -12,12 +12,12 @@ class DeployLocal < Deploy # # Pasamos variables de entorno mínimas para no filtrar secretos de # Sutty - def deploy + def deploy(output: false) return false unless mkdir - return false unless yarn - return false unless bundle + return false unless yarn(output: output) + return false unless bundle(output: output) - jekyll_build + jekyll_build(output: output) end # Sólo permitimos un deploy local @@ -96,23 +96,23 @@ class DeployLocal < Deploy File.exist? yarn_lock end - def gem - run %(gem install bundler --no-document) + def gem(output: false) + run %(gem install bundler --no-document), output: output end # Corre yarn dentro del repositorio - def yarn + def yarn(output: false) return true unless yarn_lock? - run 'yarn install --production' + run 'yarn install --production', output: output end - def bundle + def bundle(output: false) run %(bundle install --no-cache --path="#{gems_dir}") end - def jekyll_build - run %(bundle exec jekyll build --trace --profile --destination "#{escaped_destination}") + def jekyll_build(output: false) + run %(bundle exec jekyll build --trace --profile --destination "#{escaped_destination}"), output: output end # no debería haber espacios ni caracteres especiales, pero por si diff --git a/app/models/deploy_localized_domain.rb b/app/models/deploy_localized_domain.rb index 6e89c794..59e17dcd 100644 --- a/app/models/deploy_localized_domain.rb +++ b/app/models/deploy_localized_domain.rb @@ -5,7 +5,7 @@ class DeployLocalizedDomain < DeployAlternativeDomain store :values, accessors: %i[hostname locale], coder: JSON # Generar un link simbólico del sitio principal al alternativo - def deploy + def deploy(**) File.symlink?(destination) || File.symlink(File.join(site.hostname, locale), destination).zero? end diff --git a/app/models/deploy_private.rb b/app/models/deploy_private.rb index 0d79811d..d3bfb50d 100644 --- a/app/models/deploy_private.rb +++ b/app/models/deploy_private.rb @@ -7,8 +7,8 @@ # jekyll-private-data class DeployPrivate < DeployLocal # No es necesario volver a instalar dependencias - def deploy - jekyll_build + def deploy(output: false) + jekyll_build(output: output) end # Hacer el deploy a un directorio privado diff --git a/app/models/deploy_reindex.rb b/app/models/deploy_reindex.rb index d6b2be65..f3eb3d23 100644 --- a/app/models/deploy_reindex.rb +++ b/app/models/deploy_reindex.rb @@ -2,7 +2,7 @@ # Reindexa los artículos al terminar la compilación class DeployReindex < Deploy - def deploy + def deploy(**) time_start site.reset diff --git a/app/models/deploy_rsync.rb b/app/models/deploy_rsync.rb index 996f8cdd..a658de6b 100644 --- a/app/models/deploy_rsync.rb +++ b/app/models/deploy_rsync.rb @@ -5,8 +5,8 @@ class DeployRsync < Deploy store :values, accessors: %i[destination host_keys], coder: JSON - def deploy - ssh? && rsync + def deploy(output: false) + ssh? && rsync(output: output) end # El espacio remoto es el mismo que el local @@ -83,8 +83,8 @@ class DeployRsync < Deploy # Sincroniza hacia el directorio remoto # # @return [Boolean] - def rsync - run %(rsync -aviH --timeout=5 #{Shellwords.escape source}/ #{Shellwords.escape destination}/) + def rsync(output: output) + run %(rsync -aviH --timeout=5 #{Shellwords.escape source}/ #{Shellwords.escape destination}/), output: output end # El origen es el destino de la compilación diff --git a/app/models/deploy_www.rb b/app/models/deploy_www.rb index 3c9feb3b..dff769a6 100644 --- a/app/models/deploy_www.rb +++ b/app/models/deploy_www.rb @@ -6,7 +6,7 @@ class DeployWww < Deploy before_destroy :remove_destination! - def deploy + def deploy(**) File.symlink?(destination) || File.symlink(site.hostname, destination).zero? end diff --git a/app/models/deploy_zip.rb b/app/models/deploy_zip.rb index 0a66b602..f1c94083 100644 --- a/app/models/deploy_zip.rb +++ b/app/models/deploy_zip.rb @@ -12,7 +12,7 @@ class DeployZip < Deploy # y generar un zip accesible públicamente. # # rubocop:disable Metrics/MethodLength - def deploy + def deploy(**) FileUtils.rm_f path time_start