5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-12-01 08:56:21 +00:00
panel/app/models/deploy_rsync.rb

109 lines
2.5 KiB
Ruby
Raw Permalink Normal View History

2022-04-06 19:39:56 +00:00
# frozen_string_literal: true
# Sincroniza sitios a servidores remotos usando Rsync. El servidor
# remoto tiene que tener rsync instalado.
class DeployRsync < Deploy
2023-03-18 19:48:32 +00:00
store :values, accessors: %i[hostname destination host_keys], coder: JSON
2022-04-06 19:39:56 +00:00
DEPENDENCIES = %i[deploy_local deploy_zip]
2023-03-23 22:11:33 +00:00
def deploy(output: false)
ssh? && rsync(output: output)
2022-04-06 19:39:56 +00:00
end
# El espacio remoto es el mismo que el local
2022-04-06 19:39:56 +00:00
#
# @return [Integer]
def size
deploy_local.size
2022-04-06 19:39:56 +00:00
end
2022-04-06 21:26:41 +00:00
# Devolver el destino o lanzar un error si no está configurado
def destination
values[:destination].tap do |d|
raise(ArgumentError, 'destination no está configurado') if d.blank?
end
end
2023-03-18 19:48:32 +00:00
# @return [String]
def url
"https://#{hostname}/"
end
2022-04-06 19:39:56 +00:00
private
# Verificar la conexión SSH implementando Trust On First Use
#
# TODO: Medir el tiempo que tarda en iniciarse la conexión
#
# @return [Boolean]
def ssh?
2023-04-21 18:48:09 +00:00
return true if destination.start_with? 'rsync://'
2022-04-06 19:39:56 +00:00
user, host = user_host
ssh_available = false
Net::SSH.start(host, user, verify_host_key: tofu, timeout: 5) do |ssh|
2022-04-06 19:39:56 +00:00
if values[:host_keys].blank?
# Guardar las llaves que se encontraron en la primera conexión
values[:host_keys] = ssh.transport.host_keys.map do |host_key|
"#{host_key.ssh_type} #{host_key.fingerprint}"
end
ssh_available = save
else
ssh_available = true
end
end
ssh_available
rescue Exception => e
ExceptionNotifier.notify_exception(e, data: { site: site.id, hostname: host, user: user })
false
end
2022-04-06 20:23:42 +00:00
def env
{
'HOME' => home_dir,
'PATH' => '/usr/bin',
'LANG' => ENV['LANG']
}
end
2022-04-06 19:39:56 +00:00
# Confiar en la primera llave que encontremos, fallar si cambian
#
# @return [Symbol]
def tofu
values[:host_keys].present? ? :always : :accept_new
end
# Devuelve el par user host
#
# @return [Array]
def user_host
destination.split(':', 2).first.split('@', 2).tap do |d|
next unless d.size == 1
d.insert(0, nil)
end
end
2022-04-06 21:27:52 +00:00
# Sincroniza hacia el directorio remoto
2022-04-06 19:39:56 +00:00
#
# @return [Boolean]
def rsync(output: false)
2023-03-18 17:45:35 +00:00
run %(rsync -aviH --delete-after --timeout=5 #{Shellwords.escape source}/ #{Shellwords.escape destination}/), output: output
2022-04-06 19:39:56 +00:00
end
# El origen es el destino de la compilación
#
# @return [String]
def source
deploy_local.destination
end
def deploy_local
@deploy_local ||= site.deploys.find_by(type: 'DeployLocal')
2022-04-06 19:39:56 +00:00
end
end