From 15b6493c089ac82b14a882207377da45572dba17 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 25 Jul 2019 22:11:01 -0300 Subject: [PATCH] poder compilar el sitio con sidekiq --- Capfile | 1 - Gemfile | 1 - Gemfile.lock | 4 - app/controllers/sites_controller.rb | 18 ++--- app/models/site.rb | 60 +------------- app/policies/site_policy.rb | 4 - app/views/sites/index.haml | 9 --- app/workers/deploy_worker.rb | 8 +- bin/jekyll_build_all | 80 ------------------- config/routes.rb | 3 - config/schedule.rb | 8 -- .../20190725185427_create_build_stats.rb | 1 + .../20190726003756_add_status_to_site.rb | 8 ++ db/schema.rb | 3 +- test/controllers/sites_controller_test.rb | 11 +++ 15 files changed, 38 insertions(+), 181 deletions(-) delete mode 100755 bin/jekyll_build_all delete mode 100644 config/schedule.rb create mode 100644 db/migrate/20190726003756_add_status_to_site.rb diff --git a/Capfile b/Capfile index 5abc2d8..1992cec 100644 --- a/Capfile +++ b/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 diff --git a/Gemfile b/Gemfile index 25c7a69..ffd3d77 100644 --- a/Gemfile +++ b/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' diff --git a/Gemfile.lock b/Gemfile.lock index b378733..7250ed9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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 diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb index c5008ab..3b2f672 100644 --- a/app/controllers/sites_controller.rb +++ b/app/controllers/sites_controller.rb @@ -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 diff --git a/app/models/site.rb b/app/models/site.rb index 3235f3a..7b26024 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -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') diff --git a/app/policies/site_policy.rb b/app/policies/site_policy.rb index 702d41c..8e4aceb 100644 --- a/app/policies/site_policy.rb +++ b/app/policies/site_policy.rb @@ -55,10 +55,6 @@ class SitePolicy build? end - def build_log? - build? - end - def reorder_posts? build? end diff --git a/app/views/sites/index.haml b/app/views/sites/index.haml index d082408..464a616 100644 --- a/app/views/sites/index.haml +++ b/app/views/sites/index.haml @@ -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'), diff --git a/app/workers/deploy_worker.rb b/app/workers/deploy_worker.rb index 1b4ef9c..15a3154 100644 --- a/app/workers/deploy_worker.rb +++ b/app/workers/deploy_worker.rb @@ -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 diff --git a/bin/jekyll_build_all b/bin/jekyll_build_all deleted file mode 100755 index daba038..0000000 --- a/bin/jekyll_build_all +++ /dev/null @@ -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 diff --git a/config/routes.rb b/config/routes.rb index 3b70187..7e66c76 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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 diff --git a/config/schedule.rb b/config/schedule.rb deleted file mode 100644 index c17dbfd..0000000 --- a/config/schedule.rb +++ /dev/null @@ -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 diff --git a/db/migrate/20190725185427_create_build_stats.rb b/db/migrate/20190725185427_create_build_stats.rb index 255ea28..1f41e42 100644 --- a/db/migrate/20190725185427_create_build_stats.rb +++ b/db/migrate/20190725185427_create_build_stats.rb @@ -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| diff --git a/db/migrate/20190726003756_add_status_to_site.rb b/db/migrate/20190726003756_add_status_to_site.rb new file mode 100644 index 0000000..3697542 --- /dev/null +++ b/db/migrate/20190726003756_add_status_to_site.rb @@ -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 diff --git a/db/schema.rb b/db/schema.rb index 7e76955..f7c0bd7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -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 diff --git a/test/controllers/sites_controller_test.rb b/test/controllers/sites_controller_test.rb index 72d3ebc..1c5d30e 100644 --- a/test/controllers/sites_controller_test.rb +++ b/test/controllers/sites_controller_test.rb @@ -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