mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-16 17:46:21 +00:00
Mantener los hostnames anteriores a medida que se cambia de nombre
Para no romper links preexistentes. Lo ideal sería que todos los Deploy se vinculen al directorio principal para no romper links, pero la idea es no romperlos (?)
This commit is contained in:
parent
e6ea1001cd
commit
341a693a35
7 changed files with 111 additions and 16 deletions
|
@ -5,20 +5,27 @@ require 'open3'
|
|||
# Este modelo implementa los distintos tipos de alojamiento que provee
|
||||
# Sutty.
|
||||
#
|
||||
# Cuando cambia el hostname de un Deploy, generamos un
|
||||
# DeployAlternativeDomain en su lugar. Esto permite que no se rompan
|
||||
# links preexistentes y que el nombre no pueda ser tomado por alguien
|
||||
# más.
|
||||
#
|
||||
# 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
|
||||
# Puede tener muchos access logs a través del hostname
|
||||
has_many :access_logs, primary_key: 'hostname', foreign_key: 'host'
|
||||
# Registro de las tareas ejecutadas
|
||||
has_many :build_stats, dependent: :destroy
|
||||
|
||||
# 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
|
||||
# Los hostnames alternativos se crean después de actualizar, cuando ya
|
||||
# se modificó el hostname.
|
||||
around_update :create_alternative_domain!, if: :destination_changed?
|
||||
|
||||
# Siempre tienen que pertenecer a un sitio
|
||||
validates :site, presence: true
|
||||
|
@ -34,6 +41,37 @@ class Deploy < ApplicationRecord
|
|||
where(hostname: hostname).includes(:site).pluck(:name).first
|
||||
end
|
||||
|
||||
# Detecta si el destino existe y si no es un symlink roto.
|
||||
def exist?
|
||||
File.exist? destination
|
||||
end
|
||||
|
||||
# Detecta si el link está roto
|
||||
def broken?
|
||||
File.symlink?(destination) && !File.exist?(File.readlink(destination))
|
||||
end
|
||||
|
||||
# Ubicación del deploy
|
||||
#
|
||||
# @return [String] Una ruta en el sistema de archivos
|
||||
def destination
|
||||
File.join(Rails.root, '_deploy', hostname)
|
||||
end
|
||||
|
||||
# Ubicación anterior del deploy
|
||||
#
|
||||
# @return [String] Una ruta en el sistema de archivos
|
||||
def destination_was
|
||||
return destination unless will_save_change_to_hostname?
|
||||
|
||||
File.join(Rails.root, '_deploy', hostname_was)
|
||||
end
|
||||
|
||||
# Determina si la ubicación cambió
|
||||
def destination_changed?
|
||||
persisted? && will_save_change_to_hostname?
|
||||
end
|
||||
|
||||
# Genera el hostname
|
||||
#
|
||||
# @return [String]
|
||||
|
@ -143,6 +181,20 @@ class Deploy < ApplicationRecord
|
|||
raise NotImplementedError
|
||||
end
|
||||
|
||||
# Cuando el deploy cambia de hostname, generamos un dominio
|
||||
# alternativo para no romper links hacia este sitio.
|
||||
def create_alternative_domain!
|
||||
hw = hostname_was
|
||||
|
||||
# Aplicar la actualización
|
||||
yield
|
||||
|
||||
# Crear el deploy alternativo con el nombre anterior una vez que
|
||||
# lo cambiamos en la base de datos.
|
||||
ad = site.deploys.create(type: 'DeployAlternativeDomain', hostname: hw)
|
||||
ad.deploy if ad.persisted?
|
||||
end
|
||||
|
||||
# Convierte el comando en una versión resumida.
|
||||
#
|
||||
# @param [String]
|
||||
|
|
|
@ -37,6 +37,11 @@ class DeployHiddenService < DeployWww
|
|||
|
||||
private
|
||||
|
||||
# No soportamos cambiar de onion
|
||||
def destination_changed?
|
||||
false
|
||||
end
|
||||
|
||||
def implements_hostname_validation?
|
||||
true
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# Alojamiento local, genera el sitio como si corriéramos `jekyll build`.
|
||||
class DeployLocal < Deploy
|
||||
# Asegurarse que el hostname es el permitido.
|
||||
before_save :reset_hostname!, :default_hostname!
|
||||
before_validation :reset_hostname!, :default_hostname!
|
||||
|
||||
# Realizamos la construcción del sitio usando Jekyll y un entorno
|
||||
# limpio para no pasarle secretos
|
||||
|
@ -30,13 +30,6 @@ class DeployLocal < Deploy
|
|||
end.inject(:+)
|
||||
end
|
||||
|
||||
# La ubicación del sitio luego de generarlo.
|
||||
#
|
||||
# @return [String]
|
||||
def destination
|
||||
File.join(Rails.root, '_deploy', hostname)
|
||||
end
|
||||
|
||||
# El hostname es el nombre del sitio más el dominio principal.
|
||||
#
|
||||
# @return [String]
|
||||
|
|
|
@ -20,11 +20,6 @@ class DeployWww < Deploy
|
|||
File.size destination
|
||||
end
|
||||
|
||||
# @return [String]
|
||||
def destination
|
||||
File.join(Rails.root, '_deploy', hostname)
|
||||
end
|
||||
|
||||
# El hostname por defecto incluye WWW
|
||||
#
|
||||
# @return [String]
|
||||
|
|
|
@ -143,6 +143,10 @@ en:
|
|||
tienda_api_key: Store access key
|
||||
errors:
|
||||
models:
|
||||
deploy:
|
||||
attributes:
|
||||
hostname:
|
||||
destination_exist: 'There already is a file in the destination'
|
||||
site:
|
||||
attributes:
|
||||
name:
|
||||
|
|
|
@ -143,6 +143,10 @@ es:
|
|||
tienda_api_key: Clave de acceso
|
||||
errors:
|
||||
models:
|
||||
deploy:
|
||||
attributes:
|
||||
hostname:
|
||||
destination_exist: 'Ya hay un archivo en esta ubicación'
|
||||
site:
|
||||
attributes:
|
||||
name:
|
||||
|
|
|
@ -22,4 +22,46 @@ class Site::DeploymentTest < ActiveSupport::TestCase
|
|||
assert site_pre.deploys.create(type: 'DeployAlternativeDomain', hostname: "#{dup_name}.#{Site.domain}")
|
||||
assert_not site.update(name: dup_name)
|
||||
end
|
||||
|
||||
test 'al cambiar el nombre se crea un deploy alternativo' do
|
||||
site_name = site.name
|
||||
new_name = SecureRandom.hex
|
||||
original_destination = site.deploy_local.destination
|
||||
urls = [site.url]
|
||||
|
||||
assert site.deploy_local.deploy
|
||||
assert_not site.deploy_local.destination_changed?
|
||||
assert site.update(name: new_name)
|
||||
|
||||
urls << site.url
|
||||
|
||||
assert_equal urls.sort, site.urls.sort
|
||||
assert File.symlink?(original_destination)
|
||||
assert File.exist?(site.deploy_local.destination)
|
||||
assert_equal 2, site.deploys.count
|
||||
end
|
||||
|
||||
test 'al cambiar el nombre se renombra el directorio' do
|
||||
site_name = site.name
|
||||
new_name = "test-#{SecureRandom.hex}"
|
||||
original_destination = site.deploy_local.destination
|
||||
|
||||
assert site.deploy_local.deploy
|
||||
assert_not site.deploy_local.destination_changed?
|
||||
assert site.update(name: new_name)
|
||||
assert site.deploy_local.hostname.start_with?(new_name)
|
||||
assert File.symlink?(original_destination)
|
||||
assert File.exist?(site.deploy_local.destination)
|
||||
end
|
||||
|
||||
test 'al cambiar el nombre varias veces se crean varios links' do
|
||||
assert site.deploy_local.deploy
|
||||
|
||||
q = rand(3..10)
|
||||
q.times do
|
||||
assert site.update(name: "test-#{SecureRandom.hex}")
|
||||
end
|
||||
|
||||
assert_equal q, site.deploys.count
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue