diff --git a/.dockerignore b/.dockerignore index afe4e8d7..7b84d429 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,3 +2,4 @@ * # Solo agregar lo que usamos en COPY # !./archivo +!./monit.conf diff --git a/Dockerfile b/Dockerfile index ecf43cbc..342c2750 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,8 @@ RUN apk add --no-cache libxslt libxml2 postgresql-libs libssh2 \ RUN gem install --no-document --no-user-install foreman RUN wget https://github.com/jgm/pandoc/releases/download/${PANDOC_VERSION}/pandoc-${PANDOC_VERSION}-linux-amd64.tar.gz -O - | tar --strip-components 1 -xvzf - pandoc-${PANDOC_VERSION}/bin/pandoc && mv /bin/pandoc /usr/bin/pandoc +COPY ./monit.conf /etc/monit.d/sutty.conf + VOLUME "/srv" EXPOSE 3000 diff --git a/Procfile b/Procfile index 8f6c7741..45fe1df7 100644 --- a/Procfile +++ b/Procfile @@ -1,8 +1,2 @@ -migrate: bundle exec rake db:prepare db:seed -sutty: bundle exec puma config.ru -blazer_5m: bundle exec rake blazer:run_checks SCHEDULE="5 minutes" -blazer_1h: bundle exec rake blazer:run_checks SCHEDULE="1 hour" -blazer_1d: bundle exec rake blazer:run_checks SCHEDULE="1 day" -blazer: bundle exec rake blazer:send_failing_checks -prometheus: bundle exec prometheus_exporter -b 0.0.0.0 --prefix "sutty_" +cleanup: bundle exec rake cleanup:everything stats: bundle exec rake stats:process_all diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 3f034ad5..42bfd345 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -23,6 +23,9 @@ class Deploy < ApplicationRecord raise NotImplementedError end + # Realizar tareas de limpieza. + def cleanup!; end + def time_start @start = Time.now end diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 66a8345a..0aa00742 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -45,6 +45,17 @@ class DeployLocal < Deploy File.join(Rails.root, '_deploy', site.hostname) end + # Libera espacio eliminando archivos temporales + # + # @return [nil] + def cleanup! + FileUtils.rm_rf(gems_dir) + FileUtils.rm_rf(yarn_cache_dir) + FileUtils.rm_rf(File.join(site.path, 'node_modules')) + FileUtils.rm_rf(File.join(site.path, '.sass-cache')) + FileUtils.rm_rf(File.join(site.path, '.jekyll-cache')) + end + private def mkdir diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 74db2549..f63288d4 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -147,6 +147,23 @@ class Site rugged.index.remove(relativize(file)) end + # Garbage collection + # + # @return [Boolean] + def gc + env = { 'PATH' => '/usr/bin', 'LANG' => ENV['LANG'], 'HOME' => path } + cmd = 'git gc' + + r = nil + Dir.chdir(path) do + Open3.popen2e(env, cmd, unsetenv_others: true) do |_, _, t| + r = t.value + end + end + + r&.success? + end + private # Si Sutty tiene una llave privada de tipo ED25519, devuelve las diff --git a/app/services/cleanup_service.rb b/app/services/cleanup_service.rb new file mode 100644 index 00000000..ad87cf9a --- /dev/null +++ b/app/services/cleanup_service.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +# Realiza tareas de limpieza en todos los sitios, para optimizar y +# liberar espacio. +class CleanupService + # Días de antigüedad de los sitios + attr_reader :before + + # @param :before [ActiveSupport::TimeWithZone] Cuánto tiempo lleva sin usarse un sitio. + def initialize(before: 30.days.ago) + @before = before + end + + # Limpieza general + # + # @return [nil] + def cleanup_everything! + cleanup_older_sites! + cleanup_newer_sites! + end + + # Encuentra todos los sitios sin actualizar y realiza limpieza. + # + # @return [nil] + def cleanup_older_sites! + Site.where('updated_at < ?', before).find_each do |site| + next unless File.directory? site.path + + site.deploys.find_each(&:cleanup!) + + site.repository.gc + site.touch + end + end + + # Tareas para los sitios en uso + # + # @return [nil] + def cleanup_newer_sites! + Site.where('updated_at >= ?', before).find_each do |site| + next unless File.directory? site.path + + site.repository.gc + site.touch + end + end +end diff --git a/lib/tasks/cleanup.rake b/lib/tasks/cleanup.rake new file mode 100644 index 00000000..e14693bc --- /dev/null +++ b/lib/tasks/cleanup.rake @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +namespace :cleanup do + desc 'Cleanup sites' + task everything: :environment do + before = ENV.fetch('BEFORE', '30').to_i.days.ago + service = CleanupService.new(before: before) + + service.cleanup_everything! + end +end diff --git a/monit.conf b/monit.conf index 83d17449..39f45d6d 100644 --- a/monit.conf +++ b/monit.conf @@ -1,29 +1,7 @@ -check process sutty with pidfile /srv/tmp/puma.pid - start program = "/usr/local/bin/sutty start" - stop program = "/usr/local/bin/sutty stop" - -check process prometheus with pidfile /tmp/prometheus.pid - start program = "/usr/local/bin/sutty prometheus start" - stop program = "/usr/local/bin/sutty prometheus start" - -check program blazer_5m - with path "/usr/local/bin/sutty blazer 5m" - every 5 cycles - if status != 0 then alert - -check program blazer_1h - with path "/usr/local/bin/sutty blazer 1h" - every 60 cycles - if status != 0 then alert - -check program blazer_1d - with path "/usr/local/bin/sutty blazer 1d" - every 1440 cycles - if status != 0 then alert - -check program blazer - with path "/usr/local/bin/sutty blazer" - every 61 cycles +# Limpiar mensualmente +check program cleanup + with path "/usr/bin/foreman run -f /srv/Procfile -d /srv cleanup" as uid "rails" gid "www-data" + every "0 3 1 * *" if status != 0 then alert check program access_logs