5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-05-19 10:30:49 +00:00
panel/app/models/deploy_distributed_press.rb
fauno bf0a0494cd Merge branch 'issue-14540' into 'rails'
feat: soportar varias instancias de distributed press #14540

See merge request sutty/sutty!224
2024-05-02 19:10:17 +00:00

164 lines
3.9 KiB
Ruby

# frozen_string_literal: true
require 'distributed_press/v1/client/site'
# Soportar Distributed Press APIv1
#
# Usa tokens de publicación efímeros para todas las acciones.
#
# Al ser creado, genera el sitio en la instancia de Distributed Press
# configurada y almacena el ID.
#
# Al ser publicado, envía los archivos en un tarball y actualiza la
# información.
class DeployDistributedPress < Deploy
store :values, accessors: %i[hostname remote_site_id remote_info distributed_press_publisher_id], coder: JSON
before_create :create_remote_site!
before_destroy :delete_remote_site!
DEPENDENCIES = %i[deploy_local]
# Actualiza la información y luego envía los cambios
#
# @param :output [Bool]
# @return [Bool]
def deploy
status = false
log = []
time_start
create_remote_site! if remote_site_id.blank?
save
if remote_site_id.blank?
raise DeployJob::DeployException, 'El sitio no se creó en Distributed Press'
end
site_client.tap do |c|
stdout = Thread.new(publisher.logger_out) do |io|
until io.eof?
line = io.gets
puts line if output
log << line
end
end
begin
status = c.publish(publishing_site, deploy_local.destination)
rescue DistributedPress::V1::Error => e
ExceptionNotifier.notify_exception(e, data: { site: site.name })
status = false
end
if status
self.remote_info[:distributed_press] = c.show(publishing_site).to_h
save
end
publisher.logger.close
stdout.join
end
time_stop
create_stat! status, log.join
status
end
def limit; end
def size
deploy_local.size
end
def destination; end
# Devuelve las URLs de todos los protocolos
def urls
gateway_urls
end
private
# @return [Array]
def gateway_urls
remote_info.dig(:distributed_press, :links)&.values&.map do |protocol|
[protocol[:link]]
end&.flatten&.compact&.select do |link|
link.include? '://'
end || []
end
# El cliente de la API
#
# @return [DistributedPressPublisher]
def publisher
@publisher ||=
if distributed_press_publisher_id
DistributedPressPublisher.find(distributed_press_publisher_id)
else
DistributedPressPublisher.find_by_default(true)
end
end
# El cliente para actualizar el sitio
#
# @return [DistributedPress::V1::Client::Site]
def site_client
DistributedPress::V1::Client::Site.new(publisher.client)
end
# Genera el esquema de datos para poder publicar el sitio
#
# @return [DistributedPress::V1::Schemas::PublishingSite]
def publishing_site
DistributedPress::V1::Schemas::PublishingSite.new.call(id: remote_site_id)
end
# Genera el esquema de datos para crear el sitio
#
# @return [DistributedPressPublisher::V1::Schemas::NewSite]
def create_site
DistributedPress::V1::Schemas::NewSite.new.call(domain: hostname, protocols: { http: true, ipfs: true, hyper: true })
end
# Crea el sitio en la instancia con el hostname especificado
#
# @return [nil]
def create_remote_site!
self.hostname ||= site.hostname
created_site = site_client.create(create_site)
self.remote_site_id = created_site[:id]
self.remote_info ||= {}
self.remote_info[:distributed_press] = created_site.to_h
nil
rescue DistributedPress::V1::Error => e
ExceptionNotifier.notify_exception(e, data: { site: site.name })
nil
end
# Registra lo que sucedió
#
# @param status [Bool]
# @param log [String]
# @return [nil]
def create_stat!(status, log)
build_stats.create action: publisher.to_s,log: log, seconds: time_spent_in_seconds, bytes: size, status: status
nil
end
def delete_remote_site!
site_client.delete(publishing_site)
nil
rescue DistributedPress::V1::Error => e
ExceptionNotifier.notify_exception(e, data: { site: site.name })
nil
end
end