5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-06-02 13:44:15 +00:00
panel/app/jobs/deploy_job.rb

135 lines
3.6 KiB
Ruby
Raw Permalink Normal View History

2019-07-26 00:36:33 +00:00
# frozen_string_literal: true
# Realiza el deploy de un sitio
2019-09-16 16:44:29 +00:00
class DeployJob < ApplicationJob
class DeployException < StandardError; end
class DeployTimedOutException < DeployException; end
class DeployAlreadyRunningException < DeployException; end
discard_on ActiveRecord::RecordNotFound
# Lanzar lo antes posible
self.priority = 10
2024-04-09 17:16:27 +00:00
retry_on DeployAlreadyRunningException, wait: 1.minute
discard_on DeployTimedOutException
# rubocop:disable Metrics/MethodLength
def perform(site, notify: true, time: Time.now, output: false)
@site = site
2019-09-18 19:28:30 +00:00
ActiveRecord::Base.connection_pool.with_connection do
# Si ya hay una tarea corriendo, aplazar esta. Si estuvo
# esperando más de 10 minutos, recuperar el estado anterior.
#
# Como el trabajo actual se aplaza al siguiente, arrastrar la
# hora original para poder ir haciendo timeouts.
if site.building?
notify = false
2024-05-02 18:57:49 +00:00
raise DeployAlreadyRunningException unless 10.minutes.ago >= time
raise DeployTimedOutException,
"#{site.name} la tarea estuvo más de 10 minutos esperando, volviendo al estado original"
end
2023-03-18 16:42:47 +00:00
@deployed = {}
site.update status: 'building'
site.deployment_list.each do |d|
2023-03-18 16:42:47 +00:00
begin
raise DeployException, 'Una dependencia falló' if failed_dependencies? d
2019-07-26 00:36:33 +00:00
status = d.deploy(output: output)
2023-03-18 20:00:29 +00:00
seconds = d.build_stats.last.try(:seconds) || 0
size = d.size
2023-08-31 17:52:49 +00:00
urls = d.urls.map do |url|
URI.parse url
rescue URI::Error
nil
end.compact
2024-05-02 18:57:49 +00:00
raise DeployException, 'Falló la compilación' if d == site.deployment_list.last && !status
2023-03-18 16:42:47 +00:00
rescue StandardError => e
status = false
seconds ||= 0
size ||= 0
# XXX: Hace que se vea la tabla
urls ||= [nil]
2023-03-18 16:42:47 +00:00
notify_exception e, d
end
2019-07-26 00:36:33 +00:00
2023-03-18 16:42:47 +00:00
@deployed[d.type.underscore.to_sym] = {
status: status,
seconds: seconds,
size: size,
2023-08-31 17:58:16 +00:00
urls: urls
2023-03-18 16:42:47 +00:00
}
end
return unless output
2024-05-02 18:57:49 +00:00
puts(Terminal::Table.new do |t|
t << (%w[type] + @deployed.values.first.keys)
t.add_separator
@deployed.each do |type, row|
t << ([type.to_s] + row.values)
end
end)
ensure
if site.present?
site.update status: 'waiting'
notify_usuaries if notify
puts "\a" if output
end
2019-09-18 19:28:30 +00:00
end
2019-07-26 00:36:33 +00:00
end
# rubocop:enable Metrics/MethodLength
2019-07-26 00:36:33 +00:00
private
2023-03-18 16:42:47 +00:00
# Detecta si un método de publicación tiene dependencias fallidas
#
# @param :deploy [Deploy]
# @return [Boolean]
def failed_dependencies?(deploy)
failed_dependencies(deploy).present?
end
# Obtiene las dependencias fallidas de un deploy
#
# @param :deploy [Deploy]
# @return [Array]
def failed_dependencies(deploy)
deploy.class::DEPENDENCIES & (@deployed.reject do |_, v|
v[:status]
end.keys)
end
# @param :exception [StandardError]
# @param :deploy [Deploy]
def notify_exception(exception, deploy = nil)
data = {
site: site.name,
deploy: deploy&.type,
2023-03-18 16:42:47 +00:00
log: deploy&.build_stats&.last&.log,
failed_dependencies: (failed_dependencies(deploy) if deploy)
}
ExceptionNotifier.notify_exception(exception, data: data)
end
def notify_usuaries
usuarie_ids = site.roles.where(rol: 'usuarie', temporal: false).pluck(:usuarie_id)
Usuarie.where(id: usuarie_ids).find_each do |usuarie|
DeployMailer.with(usuarie: usuarie, site: site)
.deployed(@deployed)
2019-07-26 00:36:33 +00:00
.deliver_now
end
end
end