poder compilar el sitio con sidekiq
This commit is contained in:
parent
b149374c41
commit
15b6493c08
15 changed files with 38 additions and 181 deletions
1
Capfile
1
Capfile
|
@ -11,7 +11,6 @@ require 'capistrano/passenger'
|
|||
require 'capistrano/bundler'
|
||||
require 'capistrano/rbenv'
|
||||
require 'capistrano/rails'
|
||||
require 'whenever/capistrano'
|
||||
require 'capistrano/scm/git'
|
||||
install_plugin Capistrano::SCM::Git
|
||||
|
||||
|
|
1
Gemfile
1
Gemfile
|
@ -62,7 +62,6 @@ gem 'rugged'
|
|||
gem 'sidekiq'
|
||||
gem 'terminal-table'
|
||||
gem 'validates_hostname'
|
||||
gem 'whenever', require: false
|
||||
|
||||
group :development, :test do
|
||||
gem 'pry'
|
||||
|
|
|
@ -91,7 +91,6 @@ GEM
|
|||
carrierwave-i18n (0.2.0)
|
||||
childprocess (0.9.0)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
chronic (0.10.2)
|
||||
coderay (1.1.2)
|
||||
colorator (1.1.0)
|
||||
commonmarker (0.18.2)
|
||||
|
@ -401,8 +400,6 @@ GEM
|
|||
websocket-driver (0.7.0)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.3)
|
||||
whenever (0.10.0)
|
||||
chronic (>= 0.6.3)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
|
||||
|
@ -467,7 +464,6 @@ DEPENDENCIES
|
|||
uglifier (>= 1.3.0)
|
||||
validates_hostname
|
||||
web-console (>= 3.3.0)
|
||||
whenever
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.3
|
||||
|
|
|
@ -79,23 +79,15 @@ class SitesController < ApplicationController
|
|||
end
|
||||
|
||||
def enqueue
|
||||
@site = find_site
|
||||
authorize @site
|
||||
@site.enqueue!
|
||||
site = find_site
|
||||
authorize site
|
||||
|
||||
# XXX: Convertir en una máquina de estados?
|
||||
DeployWorker.perform_async site.id if site.enqueue!
|
||||
|
||||
redirect_to sites_path
|
||||
end
|
||||
|
||||
def build_log
|
||||
@site = find_site
|
||||
authorize @site
|
||||
|
||||
# TODO: eliminar ANSI
|
||||
render file: @site.build_log,
|
||||
layout: false,
|
||||
content_type: 'text/plain; charset=utf-8'
|
||||
end
|
||||
|
||||
def reorder_posts
|
||||
@site = find_site
|
||||
authorize @site
|
||||
|
|
|
@ -7,8 +7,8 @@ class Site < ApplicationRecord
|
|||
|
||||
validates :name, uniqueness: true, hostname: true
|
||||
validates :design_id, presence: true
|
||||
|
||||
validate :deploy_local_presence
|
||||
validates_inclusion_of :status, in: %w[waiting enqueued building]
|
||||
|
||||
friendly_id :name, use: %i[finders]
|
||||
|
||||
|
@ -217,65 +217,13 @@ class Site < ApplicationRecord
|
|||
end.flatten.uniq.compact
|
||||
end
|
||||
|
||||
def failed_file
|
||||
File.join(path, '.failed')
|
||||
end
|
||||
|
||||
def failed?
|
||||
File.exist? failed_file
|
||||
end
|
||||
|
||||
def defail
|
||||
FileUtils.rm failed_file if failed?
|
||||
end
|
||||
alias defail! defail
|
||||
|
||||
def build_log
|
||||
File.join(path, 'build.log')
|
||||
end
|
||||
|
||||
def build_log?
|
||||
File.exist? build_log
|
||||
end
|
||||
|
||||
def queue_file
|
||||
File.join(path, '.generate')
|
||||
def enqueue!
|
||||
!enqueued? && update_attribute(:status, 'enqueued')
|
||||
end
|
||||
|
||||
def enqueued?
|
||||
File.exist? queue_file
|
||||
status == 'enqueued'
|
||||
end
|
||||
alias queued? enqueued?
|
||||
|
||||
# El sitio se genera cuando se coloca en una cola de generación, para
|
||||
# que luego lo construya un cronjob
|
||||
def enqueue
|
||||
defail!
|
||||
# TODO: ya van tres métodos donde usamos esta idea, convertir en un
|
||||
# helper o algo
|
||||
File.open(queue_file, File::RDWR | File::CREAT, 0o640) do |f|
|
||||
# Bloquear el archivo para que no sea accedido por otro
|
||||
# proceso u otra editora
|
||||
f.flock(File::LOCK_EX)
|
||||
|
||||
# Empezar por el principio
|
||||
f.rewind
|
||||
|
||||
# Escribir la fecha de creación
|
||||
f.write(Time.now.to_i.to_s)
|
||||
|
||||
# Eliminar el resto
|
||||
f.flush
|
||||
f.truncate(f.pos)
|
||||
end
|
||||
end
|
||||
alias enqueue! enqueue
|
||||
|
||||
# Eliminar de la cola
|
||||
def dequeue
|
||||
FileUtils.rm(queue_file) if enqueued?
|
||||
end
|
||||
alias dequeue! dequeue
|
||||
|
||||
# Verifica si los posts están ordenados
|
||||
def ordered?(collection = 'posts')
|
||||
|
|
|
@ -55,10 +55,6 @@ class SitePolicy
|
|||
build?
|
||||
end
|
||||
|
||||
def build_log?
|
||||
build?
|
||||
end
|
||||
|
||||
def reorder_posts?
|
||||
build?
|
||||
end
|
||||
|
|
|
@ -77,15 +77,6 @@
|
|||
= fa_icon 'building'
|
||||
= t('sites.enqueue')
|
||||
|
||||
- if policy(site).build_log?
|
||||
- if site.failed?
|
||||
%button.btn.btn-danger= t('sites.failed')
|
||||
- if site.build_log?
|
||||
= render 'layouts/btn_with_tooltip',
|
||||
tooltip: t('help.sites.build_log'),
|
||||
text: t('sites.build_log'),
|
||||
type: 'warning',
|
||||
link: site_build_log_path(site)
|
||||
- if policy(site).pull? && site.needs_pull?
|
||||
= render 'layouts/btn_with_tooltip',
|
||||
tooltip: t('help.sites.pull'),
|
||||
|
|
|
@ -6,14 +6,20 @@ class DeployWorker
|
|||
|
||||
def perform(site)
|
||||
site = Site.find(site)
|
||||
site.update_attribute :status, 'building'
|
||||
# Asegurarse que DeployLocal sea el primero!
|
||||
deployed = { deploy_local: deploy_local(site) }
|
||||
|
||||
# No es opcional
|
||||
raise unless deployed[:deploy_local]
|
||||
unless deployed[:deploy_local]
|
||||
site.update_attribute :status, 'waiting'
|
||||
raise
|
||||
end
|
||||
|
||||
deploy_others site, deployed
|
||||
notify_usuaries site, deployed
|
||||
|
||||
site.update_attribute :status, 'waiting'
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
#!/bin/bash
|
||||
# TODO convertir a ruby!
|
||||
set -e
|
||||
|
||||
rails_root="${PWD}"
|
||||
|
||||
# Encontrar todos los sitios únicos con el archivo `.generate`. Esto
|
||||
# significa que la usuaria quiso generar el sitio.
|
||||
find -L ./_sites -mindepth 2 -maxdepth 2 -name .generate \
|
||||
| sed "s/\/\.generate$//" \
|
||||
| while read _path ; do
|
||||
# Como seguimos todos los symlinks y los sitios pueden estar
|
||||
# vinculados entre sí, volvemos a chequear si existe el archivo para
|
||||
# no generarlo dos veces
|
||||
test -f "${_path}/.generate" || continue
|
||||
test -f "${_path}/.generating" && continue
|
||||
|
||||
# Obtenemos las direcciones de correo de las responsables
|
||||
_mail=($(cat "${_path}/.usuarias"))
|
||||
_site="$(echo "${_path}" | xargs basename)"
|
||||
_deploy="${rails_root}/_deploy/${_site}"
|
||||
|
||||
# Entrar al directorio del sitio
|
||||
pushd "${_path}" &>/dev/null
|
||||
|
||||
# Reiniciar el log con la fecha
|
||||
date > build.log
|
||||
|
||||
# Instalar las gemas si no están
|
||||
test -f .bundle/config \
|
||||
|| bundle install --path=/srv/http/gems.kefir.red \
|
||||
>> build.log
|
||||
|
||||
# Actualizar las gemas
|
||||
bundle >> build.log
|
||||
# Instalar los assets
|
||||
test -f yarn.lock \
|
||||
&& yarn >> build.log
|
||||
|
||||
# Crear el sitio con lujo de detalles y guardar un log, pero a la vez
|
||||
# tenerlo en la salida estándar para poder enviar al MAILTO del
|
||||
# cronjob.
|
||||
#
|
||||
# Ya que estamos, eliminamos la ruta donde estamos paradas para no dar
|
||||
# información sobre la servidora.
|
||||
touch .generating
|
||||
# Correr en baja prioridad
|
||||
nice -n 19 \
|
||||
bundle exec \
|
||||
jekyll build --trace --destination "${_deploy}" 2>&1 \
|
||||
| sed -re "s,${_path},,g" \
|
||||
>> "build.log"
|
||||
|
||||
# Acciones posteriores
|
||||
# TODO convertir en un plugin de cada sitio?
|
||||
if test $? -eq 0; then
|
||||
# Si funciona, enviar un mail
|
||||
# TODO enviar un mail más completo y no hardcodear direcciones
|
||||
echo "Everything was good! You can see your changes in https://${_site}" \
|
||||
| mail -b "sysadmin@kefir.red" \
|
||||
-s "${_site}: :)" \
|
||||
${_mail[@]}
|
||||
else
|
||||
echo "There was an error, please check build log at https://sutty.kefir.red/" \
|
||||
| mail -b "sysadmin@kefir.red" \
|
||||
-s "${_site}: :(" \
|
||||
${_mail[@]}
|
||||
date +%s >.failed
|
||||
fi
|
||||
|
||||
# Eliminar el archivo para sacar el sitio de la cola de compilación
|
||||
rm -f .generate .generating
|
||||
# TODO descubrir el grupo según la distro?
|
||||
chgrp -R http "${_deploy}"
|
||||
find "${_deploy}" -type f -print0 | xargs -r -0 chmod 640
|
||||
find "${_deploy}" -type d -print0 | xargs -r -0 chmod 2750
|
||||
|
||||
# Volver al principio para continuar con el siguiente sitio
|
||||
popd &>/dev/null
|
||||
done
|
|
@ -1,6 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# rubocop:disable Metrics/BlockLength
|
||||
Rails.application.routes.draw do
|
||||
devise_for :usuaries
|
||||
|
||||
|
@ -42,8 +41,6 @@ Rails.application.routes.draw do
|
|||
|
||||
# Compilar el sitio
|
||||
post 'enqueue', to: 'sites#enqueue'
|
||||
get 'build_log', to: 'sites#build_log'
|
||||
post 'reorder_posts', to: 'sites#reorder_posts'
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/BlockLength
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
env 'MAILTO', 'sysadmin@kefir.red'
|
||||
job_type :bash, 'cd :path && ./bin/:task'
|
||||
|
||||
every 3.minutes do
|
||||
bash 'jekyll_build_all'
|
||||
end
|
|
@ -1,5 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Crea la tabla de estadísticas de compilación
|
||||
class CreateBuildStats < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :build_stats do |t|
|
||||
|
|
8
db/migrate/20190726003756_add_status_to_site.rb
Normal file
8
db/migrate/20190726003756_add_status_to_site.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# El status de un sitio
|
||||
class AddStatusToSite < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :sites, :status, :string, default: 'waiting'
|
||||
end
|
||||
end
|
|
@ -12,7 +12,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20_190_725_185_427) do
|
||||
ActiveRecord::Schema.define(version: 20_190_726_003_756) do
|
||||
create_table 'build_stats', force: :cascade do |t|
|
||||
t.datetime 'created_at', null: false
|
||||
t.datetime 'updated_at', null: false
|
||||
|
@ -98,6 +98,7 @@ ActiveRecord::Schema.define(version: 20_190_725_185_427) do
|
|||
t.string 'name'
|
||||
t.integer 'design_id'
|
||||
t.integer 'licencia_id'
|
||||
t.string 'status', default: 'waiting'
|
||||
t.index ['design_id'], name: 'index_sites_on_design_id'
|
||||
t.index ['licencia_id'], name: 'index_sites_on_licencia_id'
|
||||
t.index ['name'], name: 'index_sites_on_name', unique: true
|
||||
|
|
|
@ -71,4 +71,15 @@ class SitesControllerTest < ActionDispatch::IntegrationTest
|
|||
}
|
||||
end
|
||||
end
|
||||
|
||||
test 'se pueden encolar' do
|
||||
Sidekiq::Testing.fake!
|
||||
|
||||
post site_enqueue_url(@site), headers: @authorization
|
||||
|
||||
assert DeployWorker.jobs.count.positive?
|
||||
assert @site.reload.enqueued?
|
||||
|
||||
Sidekiq::Testing.inline!
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue