Refactorizar Deploy

* Validar los hostnames
* Generar los hostnames por defecto
* Cada Deploy sabe su propia URL
This commit is contained in:
f 2021-08-01 21:50:44 -03:00
parent 7cfd55e126
commit e1664d0c12
2 changed files with 110 additions and 48 deletions

View file

@ -1,44 +1,85 @@
# frozen_string_literal: true
require 'open3'
# Este modelo implementa los distintos tipos de alojamiento que provee
# Sutty.
#
# Los datos se guardan en la tabla `deploys`. Para guardar los
# atributos, cada modelo tiene que definir su propio `store
# :attributes`.
# TODO: Cambiar el nombre a algo que no sea industrial/militar.
class Deploy < ApplicationRecord
# Un sitio puede tener muchas formas de publicarse.
belongs_to :site
# Siempre generar el hostname
after_initialize :default_hostname!
# Eliminar los archivos generados por el deploy.
before_destroy :remove_destination!
# Registro de las tareas ejecutadas
has_many :build_stats, dependent: :destroy
# Siempre tienen que pertenecer a un sitio
validates :site, presence: true
# El hostname tiene que ser único en toda la plataforma
validates :hostname, uniqueness: true
# Cada deploy puede implementar su propia validación
validates :hostname, hostname: true, unless: :implements_hostname_validation?
# Genera el hostname
#
# @return [String]
def default_hostname
raise NotImplementedError
end
# Devolver la URL
#
# @return [String]
def url
"https://#{hostname}"
end
# Ejecutar la tarea
#
# @return [Boolean]
def deploy
raise NotImplementedError
end
def limit
raise NotImplementedError
end
# El espacio ocupado por este deploy.
#
# @return [Integer]
def size
raise NotImplementedError
end
# Empezar a contar el tiempo
#
# @return [Time]
def time_start
@start = Time.now
end
# Detener el contador
#
# @return [Time]
def time_stop
@stop = Time.now
end
# Obtener la demora de la tarea
#
# @return [Float]
def time_spent_in_seconds
(@stop - @start).round(3)
end
def home_dir
site.path
end
# El directorio donde se almacenan las gemas.
#
# TODO: En un momento podíamos tenerlas todas compartidas y ahorrar
# espacio, pero bundler empezó a mezclar cosas.
#
# @return [String]
def gems_dir
@gems_dir ||= Rails.root.join('_storage', 'gems', site.name)
end
@ -77,9 +118,33 @@ class Deploy < ApplicationRecord
private
# Genera el hostname
#
# @return [Boolean]
def default_hostname!
self.hostname = default_hostname
true
end
# Elimina los archivos generados por el deploy
#
# @return [Boolean]
def remove_destination!
raise NotImplementedError
end
# Convierte el comando en una versión resumida.
#
# @param [String]
# @return [String]
def readable_cmd(cmd)
cmd.split(' -', 2).first.tr(' ', '_')
end
# Cada deploy puede decidir su propia validación
#
# @return [Boolean]
def implements_hostname_validation?
false
end
end

View file

@ -85,47 +85,44 @@ class Site < ApplicationRecord
@repository ||= Site::Repository.new path
end
def hostname
sub = name || I18n.t('deploys.deploy_local.ejemplo')
if sub.ends_with? '.'
sub.gsub(/\.\Z/, '')
else
"#{sub}.#{Site.domain}"
end
# El primer deploy del sitio
#
# @return [DeployLocal]
def deploy_local
@deploy_local ||= deploys.order(created_at: :asc).find_by(type: 'DeployLocal')
end
# Devuelve la URL siempre actualizada a través del hostname
# Todas las URLs posibles para este sitio, ordenados según fecha de
# creación.
#
# @param slash Boolean Agregar / al final o no
# @return String La URL con o sin / al final
def url(slash: true)
"https://#{hostname}#{slash ? '/' : ''}"
end
# Obtiene los dominios alternativos
#
# @return Array
def alternative_hostnames
deploys.where(type: 'DeployAlternativeDomain').map(&:hostname).map do |h|
h.end_with?('.') ? h[0..-2] : "#{h}.#{Site.domain}"
end
end
# Obtiene todas las URLs alternativas para este sitio
#
# @return Array
def alternative_urls(slash: true)
alternative_hostnames.map do |h|
"https://#{h}#{slash ? '/' : ''}"
end
end
# Todas las URLs posibles para este sitio
#
# @return Array
# @param :slash [Boolean] Con o sin / al final, por defecto con
# @return [Array]
def urls(slash: true)
alternative_urls(slash: slash) << url(slash: slash)
deploys.order(created_at: :asc).map(&:url).map do |url|
slash ? "#{url}/" : url
end
end
# Todos los hostnames, ordenados según fecha de creación.
#
# @return [Array]
def hostnames
deploys.order(created_at: :asc).pluck(:hostname)
end
# Obtiene la URL principal
#
# @param :slash [Boolean]
# @return [String]
def url(slash: true)
deploy_local.url.tap do |url|
"#{url}/" if slash
end
end
# TODO: Usar DeployCanonical
def hostname
deploy_local.hostname
end
def invitade?(usuarie)