From 44de5227646c3ae0549e863bb5b2c0a9b0918c94 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 5 Oct 2022 18:44:23 -0300 Subject: [PATCH 01/28] soportar distributed press apiv0 #7839 --- app/models/deploy.rb | 15 ++++++++++ app/models/deploy_distributed_press.rb | 34 +++++++++++++++++++++++ app/models/deploy_local.rb | 38 ++++++++++++++++++-------- 3 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 app/models/deploy_distributed_press.rb diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 3f034ad5..c7e83539 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -75,6 +75,13 @@ class Deploy < ApplicationRecord r&.success? end + # Variables de entorno + # + # @return [Hash] + def local_env + @local_env ||= {} + end + private # @param [String] @@ -82,4 +89,12 @@ class Deploy < ApplicationRecord def readable_cmd(cmd) cmd.split(' -', 2).first.tr(' ', '_') end + + def deploy_local + @deploy_local ||= site.deploys.find_by(type: 'DeployLocal') + end + + def non_local_deploys + @non_local_deploys ||= site.deploys.where.not(type: 'DeployLocal') + end end diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb new file mode 100644 index 00000000..51788865 --- /dev/null +++ b/app/models/deploy_distributed_press.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +# Soportar Distributed Press APIv0 +# +# No se realiza ninguna acción porque el deploy se hace desde el plugin +# local. +class DeployDistributedPress < Deploy + store :values, accessors: %i[api_key hostname], coder: JSON + + def deploy; end + + def limit; end + + def size + deploy_local.size + end + + # TODO: Devolver hyper:// y otras + def url + "ipfs://#{hostname}/" + end + + # Devuelve variables de entorno para enviarle a DeployLocal + # + # @return [Hash] + def local_env + { + 'DISTRIBUTED_PRESS_PROJECT_DOMAIN' => hostname, + 'DISTRIBUTED_PRESS_API_KEY' => api_key + } + end + + def destination; end +end diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 4fa588f5..4b22d728 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -50,21 +50,24 @@ class DeployLocal < Deploy end # Un entorno que solo tiene lo que necesitamos + # + # @return [Hash] def env # XXX: This doesn't support Windows paths :B paths = [File.dirname(`which bundle`), '/usr/bin', '/bin'] - { - 'HOME' => home_dir, - 'PATH' => paths.join(':'), - 'SPREE_API_KEY' => site.tienda_api_key, - 'SPREE_URL' => site.tienda_url, - 'AIRBRAKE_PROJECT_ID' => site.id.to_s, - 'AIRBRAKE_PROJECT_KEY' => site.airbrake_api_key, - 'JEKYLL_ENV' => Rails.env, - 'LANG' => ENV['LANG'], - 'YARN_CACHE_FOLDER' => yarn_cache_dir - } + # Las variables de entorno extra no pueden superponerse al local. + extra_env.merge({ + 'HOME' => home_dir, + 'PATH' => paths.join(':'), + 'SPREE_API_KEY' => site.tienda_api_key, + 'SPREE_URL' => site.tienda_url, + 'AIRBRAKE_PROJECT_ID' => site.id.to_s, + 'AIRBRAKE_PROJECT_KEY' => site.airbrake_api_key, + 'JEKYLL_ENV' => Rails.env, + 'LANG' => ENV['LANG'], + 'YARN_CACHE_FOLDER' => yarn_cache_dir + }) end def yarn_cache_dir @@ -112,4 +115,17 @@ class DeployLocal < Deploy def remove_destination! FileUtils.rm_rf destination end + + # Consigue todas las variables de entorno configuradas por otros + # deploys. + # + # @return [Hash] + def extra_env + @extra_env ||= + non_local_deploys.reduce({}) do |extra_env, deploy| + extra_env.tap do |e| + e.merge! deploy.local_env + end + end + end end From d05b93d85ef3830e51131a6c09f48f47e2fd164b Mon Sep 17 00:00:00 2001 From: f Date: Fri, 18 Nov 2022 15:56:59 -0300 Subject: [PATCH 02/28] feat: poder modificar la url de distributed press --- app/models/deploy_distributed_press.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index 51788865..a24ae62c 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -5,7 +5,7 @@ # No se realiza ninguna acción porque el deploy se hace desde el plugin # local. class DeployDistributedPress < Deploy - store :values, accessors: %i[api_key hostname], coder: JSON + store :values, accessors: %i[api_url api_key hostname], coder: JSON def deploy; end @@ -26,7 +26,8 @@ class DeployDistributedPress < Deploy def local_env { 'DISTRIBUTED_PRESS_PROJECT_DOMAIN' => hostname, - 'DISTRIBUTED_PRESS_API_KEY' => api_key + 'DISTRIBUTED_PRESS_API_KEY' => api_key, + 'DISTRIBUTED_PRESS_API_URL' => api_url } end From 5da4c796e0e9fc3afe0767822e4ed6b78d5feb7c Mon Sep 17 00:00:00 2001 From: Maki Date: Tue, 17 Jan 2023 18:31:54 -0300 Subject: [PATCH 03/28] agrego toggler para distributed press --- app/models/site.rb | 2 +- .../deploys/_deploy_distributed_press.haml | 21 +++++++++++++++++++ config/locales/en.yml | 4 ++++ config/locales/es.yml | 4 ++++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 app/views/deploys/_deploy_distributed_press.haml diff --git a/app/models/site.rb b/app/models/site.rb index 638b3f47..fc012d7d 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -17,7 +17,7 @@ class Site < ApplicationRecord # TODO: Hacer que los diferentes tipos de deploy se auto registren # @see app/services/site_service.rb - DEPLOYS = %i[local private www zip hidden_service].freeze + DEPLOYS = %i[local private www zip hidden_service distributed_press].freeze validates :name, uniqueness: true, hostname: { allow_root_label: true diff --git a/app/views/deploys/_deploy_distributed_press.haml b/app/views/deploys/_deploy_distributed_press.haml new file mode 100644 index 00000000..d7d54db0 --- /dev/null +++ b/app/views/deploys/_deploy_distributed_press.haml @@ -0,0 +1,21 @@ +-# Publicar a la web distribuida + +.row + .col + = deploy.hidden_field :id + = deploy.hidden_field :type + .custom-control.custom-switch + -# + El checkbox invierte la lógica de destrucción porque queremos + crear el deploy si está activado y destruirlo si está + desactivado. + = deploy.check_box :_destroy, + { checked: deploy.object.persisted?, class: 'custom-control-input' }, + '0', '1' + = deploy.label :_destroy, class: 'custom-control-label' do + %h3= t('.title') + = sanitize_markdown t('.help', public_url: deploy.object.site.url), + tags: %w[p strong em a] + + +%hr/ diff --git a/config/locales/en.yml b/config/locales/en.yml index 530a9381..e7fb4f76 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -248,6 +248,10 @@ en: Only accessible through [Tor Browser](https://www.torproject.org/download/) + deploy_distributed_press: + title: 'Publish on Distributed Press' + help: | + ipfs stats: index: title: Statistics diff --git a/config/locales/es.yml b/config/locales/es.yml index eaa23137..18cf5326 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -253,6 +253,10 @@ es: Sólo será accesible a través del [Navegador Tor](https://www.torproject.org/es/download/). + deploy_distributed_press: + title: 'Alojar en la web distribuida' + help: | + Es para que esté en la web distribuida stats: index: title: Estadísticas From 67c0b29029d5f8731f0eb82c6b2c8c7d02e333e7 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 20 Jan 2023 18:22:08 -0300 Subject: [PATCH 04/28] feat: almacenar y renovar tokens de distributed press --- Gemfile | 1 + Gemfile.lock | 40 ++++++++++- Procfile | 1 + .../renew_distributed_press_tokens_job.rb | 17 +++++ app/models/distributed_press_publisher.rb | 68 +++++++++++++++++++ ...5420_create_distributed_press_publisher.rb | 14 ++++ lib/tasks/distributed_press.rake | 10 +++ monit.conf | 5 ++ 8 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 app/jobs/renew_distributed_press_tokens_job.rb create mode 100644 app/models/distributed_press_publisher.rb create mode 100644 db/migrate/20230119165420_create_distributed_press_publisher.rb create mode 100644 lib/tasks/distributed_press.rake diff --git a/Gemfile b/Gemfile index 2b304ee0..f317487b 100644 --- a/Gemfile +++ b/Gemfile @@ -38,6 +38,7 @@ gem 'commonmarker' gem 'devise' gem 'devise-i18n' gem 'devise_invitable' +gem 'distributed-press-api-client', '~> 0.2.0' gem 'email_address', git: 'https://github.com/fauno/email_address', branch: 'i18n' gem 'exception_notification' gem 'fast_blank' diff --git a/Gemfile.lock b/Gemfile.lock index 8df2d77e..cdfe7183 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -124,6 +124,7 @@ GEM xpath (>= 2.0, < 4.0) chartkick (4.1.2) childprocess (4.1.0) + climate_control (1.2.0) coderay (1.1.3) colorator (1.1.0) commonmarker (0.21.2-x86_64-linux-musl) @@ -162,12 +163,45 @@ GEM devise_invitable (2.0.5) actionmailer (>= 5.0) devise (>= 4.6) + distributed-press-api-client (0.2.0) + addressable (~> 2.3, >= 2.3.0) + climate_control + dry-schema + httparty (~> 0.18) + json (~> 2.1, >= 2.1.0) + jwt (~> 2.6.0) dotenv (2.7.6) dotenv-rails (2.7.6) dotenv (= 2.7.6) railties (>= 3.2) down (5.2.4) addressable (~> 2.8) + dry-configurable (1.0.1) + dry-core (~> 1.0, < 2) + zeitwerk (~> 2.6) + dry-core (1.0.0) + concurrent-ruby (~> 1.0) + zeitwerk (~> 2.6) + dry-inflector (1.0.0) + dry-initializer (3.1.1) + dry-logic (1.5.0) + concurrent-ruby (~> 1.0) + dry-core (~> 1.0, < 2) + zeitwerk (~> 2.6) + dry-schema (1.13.0) + concurrent-ruby (~> 1.0) + dry-configurable (~> 1.0, >= 1.0.1) + dry-core (~> 1.0, < 2) + dry-initializer (~> 3.0) + dry-logic (>= 1.5, < 2) + dry-types (>= 1.7, < 2) + zeitwerk (~> 2.6) + dry-types (1.7.0) + concurrent-ruby (~> 1.0) + dry-core (~> 1.0, < 2) + dry-inflector (~> 1.0, < 2) + dry-logic (>= 1.4, < 2) + zeitwerk (~> 2.6) ed25519 (1.2.4-x86_64-linux-musl) editorial-autogestiva-jekyll-theme (0.3.4) jekyll (~> 4) @@ -244,8 +278,8 @@ GEM thor hiredis (0.6.3-x86_64-linux-musl) http_parser.rb (0.8.0-x86_64-linux-musl) - httparty (0.18.1) - mime-types (~> 3.0) + httparty (0.21.0) + mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) i18n (1.8.11) concurrent-ruby (~> 1.0) @@ -320,6 +354,7 @@ GEM jekyll-write-and-commit-changes (0.2.1) jekyll (~> 4) rugged (~> 1) + jwt (2.6.0) kaminari (1.2.1) activesupport (>= 4.1.0) kaminari-actionview (= 1.2.1) @@ -669,6 +704,7 @@ DEPENDENCIES devise devise-i18n devise_invitable + distributed-press-api-client (~> 0.2.0) dotenv-rails down ed25519 diff --git a/Procfile b/Procfile index b308ffd5..1a4580d3 100644 --- a/Procfile +++ b/Procfile @@ -5,3 +5,4 @@ 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_" +distributed_press_renew_tokens: bundle exec rake distributed_press:tokens:renew diff --git a/app/jobs/renew_distributed_press_tokens_job.rb b/app/jobs/renew_distributed_press_tokens_job.rb new file mode 100644 index 00000000..5664d9fa --- /dev/null +++ b/app/jobs/renew_distributed_press_tokens_job.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +# Renueva los tokens de Distributed Press antes que se venzan, +# activando los callbacks que hacen que se refresque el token. +class RenewDistributedPressTokensJob < ApplicationJob + # Renueva todos los tokens a punto de vencer o informa el error sin + # detener la tarea si algo pasa. + def perform + DistributedPressPublisher.with_about_to_expire_tokens.find_each do |publisher| + publisher.touch + rescue DistributedPress::V1::Error => e + data = { instance: publisher.instance, expires_at: publisher.client.token.expires_at } + + ExceptionNotifier.notify_exception(e, data: data) + end + end +end diff --git a/app/models/distributed_press_publisher.rb b/app/models/distributed_press_publisher.rb new file mode 100644 index 00000000..c120811e --- /dev/null +++ b/app/models/distributed_press_publisher.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +require 'distributed_press/v1' + +# Almacena el token de autenticación y la URL, por ahora solo vamos +# a tener uno, pero queda abierta la posibilidad de agregar más. +class DistributedPressPublisher < ApplicationRecord + # Cifrar la información del token en la base de datos + has_encrypted :token + + # La instancia es única + validates_uniqueness_of :instance + + # El token es necesario + validates_presence_of :token + + # Mantener la fecha de vencimiento actualizada + before_save :update_expires_at_from_token!, :update_token_from_client! + + # Devuelve todos los tokens que vencen en una hora + scope :with_about_to_expire_tokens, -> do + where('expires_at > ? and expires_at < ?', Time.now, Time.now + 1.hour) + end + + # Al cambiar el token genera un cliente nuevo + # + # @return [String] + def token=(new_token) + @client = nil + super + end + + # Al cambiar la instancia genera un cliente nuevo + # + # @return [String] + def instance=(new_instance) + @client = nil + super + end + + # Instancia un cliente de Distributed Press a partir del token. Al + # cargar un token a punto de vencer se renueva automáticamente. + # + # @return [DistributedPress::V1::Client] + def client + @client ||= DistributedPress::V1::Client.new(url: instance, token: token) + end + + private + + # Actualiza o desactiva la fecha de vencimiento a partir de la + # información del token. + # + # @return [nil] + def update_expires_at_from_token! + self.expires_at = client.token.forever? ? nil : client.token.expires_at + nil + end + + # Actualiza el token a partir del cliente, que ya actualiza el token + # automáticamente. + # + # @return [nil] + def update_token_from_client! + self.token = client.token.to_s + nil + end +end diff --git a/db/migrate/20230119165420_create_distributed_press_publisher.rb b/db/migrate/20230119165420_create_distributed_press_publisher.rb new file mode 100644 index 00000000..8d8de37a --- /dev/null +++ b/db/migrate/20230119165420_create_distributed_press_publisher.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# Crea la tabla de publishers de Distributed Press que contiene las +# instancias y tokens +class CreateDistributedPressPublisher < ActiveRecord::Migration[6.1] + def change + create_table :distributed_press_publishers do |t| + t.timestamps + t.string :instance, unique: true + t.text :token_ciphertext, null: false + t.datetime :expires_at, null: true + end + end +end diff --git a/lib/tasks/distributed_press.rake b/lib/tasks/distributed_press.rake new file mode 100644 index 00000000..8ba270ec --- /dev/null +++ b/lib/tasks/distributed_press.rake @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +namespace :distributed_press do + namespace :tokens do + desc 'Renew tokens' + task renew: :environment do + RenewDistributedPressTokensJob.perform_now + end + end +end diff --git a/monit.conf b/monit.conf index 96c08d8a..b785964d 100644 --- a/monit.conf +++ b/monit.conf @@ -25,3 +25,8 @@ check program blazer with path "/usr/local/bin/sutty blazer" every 61 cycles if status != 0 then alert + +check program distributed_press_tokens_renew + with path "/usr/bin/foreman run -f /srv/Procfile -d /srv distributed_press_tokens_renew" as uid "rails" gid "www-data" + every "0 3 * * *" + if status != 0 then alert From cbf7b5892746b544668c6043915da783a13b00d0 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 20 Jan 2023 18:28:29 -0300 Subject: [PATCH 05/28] fixup! feat: almacenar y renovar tokens de distributed press --- app/models/distributed_press_publisher.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/distributed_press_publisher.rb b/app/models/distributed_press_publisher.rb index c120811e..610d698d 100644 --- a/app/models/distributed_press_publisher.rb +++ b/app/models/distributed_press_publisher.rb @@ -18,9 +18,9 @@ class DistributedPressPublisher < ApplicationRecord before_save :update_expires_at_from_token!, :update_token_from_client! # Devuelve todos los tokens que vencen en una hora - scope :with_about_to_expire_tokens, -> do + scope :with_about_to_expire_tokens, lambda { where('expires_at > ? and expires_at < ?', Time.now, Time.now + 1.hour) - end + } # Al cambiar el token genera un cliente nuevo # From 932355fa2e331ac7e4bf142e21b1b879aa161a39 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 20 Jan 2023 20:34:27 -0300 Subject: [PATCH 06/28] feat: crear y publicar el sitio en distributed press v1 --- app/models/deploy_distributed_press.rb | 143 ++++++++++++++++++---- app/models/distributed_press_publisher.rb | 5 + 2 files changed, 125 insertions(+), 23 deletions(-) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index a24ae62c..09ba0364 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -1,13 +1,43 @@ # frozen_string_literal: true -# Soportar Distributed Press APIv0 -# -# No se realiza ninguna acción porque el deploy se hace desde el plugin -# local. -class DeployDistributedPress < Deploy - store :values, accessors: %i[api_url api_key hostname], coder: JSON +require 'distributed_press/v1/client/auth' +require 'distributed_press/v1/client/site' - def deploy; end +# Soportar Distributed Press APIv1 +# +# Usa tokens de publicación efímeros para todas las acciones. +# +# Al ser creado, genera el sitio en la instancia de Distributed Press +# configurada y almacena el ID. +# +# Al ser publicado, envía los archivos en un tarball y actualiza la +# información. +class DeployDistributedPress < Deploy + store :values, accessors: %i[hostname remote_site_id remote_info], coder: JSON + + before_create :create_remote_site! + + # Actualiza la información y luego envía los cambios + # + # @param :output [Bool] + # @return [Bool] + def deploy + time_start + + status = false + + site_client.tap do |c| + update remote_info: c.show(publishing_site).to_h + + status = c.publish(publishing_site, deploy_local.destination) + end + + time_stop + + create_stat! status + + status + end def limit; end @@ -15,21 +45,88 @@ class DeployDistributedPress < Deploy deploy_local.size end - # TODO: Devolver hyper:// y otras - def url - "ipfs://#{hostname}/" - end - - # Devuelve variables de entorno para enviarle a DeployLocal - # - # @return [Hash] - def local_env - { - 'DISTRIBUTED_PRESS_PROJECT_DOMAIN' => hostname, - 'DISTRIBUTED_PRESS_API_KEY' => api_key, - 'DISTRIBUTED_PRESS_API_URL' => api_url - } - end - def destination; end + + private + + # El cliente de la API + # + # TODO: cuando soportemos más, tiene que haber una relación entre + # DeployDistributedPress y DistributedPressPublisher. + # + # @return [DistributedPressPublisher] + def publisher + @publisher ||= DistributedPressPublisher.first + end + + # El cliente de autenticación se encarga de intercambiar un token por + # otro + # + # @return [DistributedPress::V1::Client::Auth] + def auth_client + DistributedPress::V1::Client::Auth.new(publisher.client) + end + + # Genera un token con permisos de publicación + # + # @return [DistributedPress::V1::Schemas::NewTokenPayload] + def publishing_token_payload + DistributedPress::V1::Schemas::NewTokenPayload.new.call(capabilities: %w[publisher]) + end + + # Genera un token efímero para publicar el sitio + # + # @return [DistributedPress::V1::Token] + def publishing_token + auth_client.exchange(publishing_token_payload) + end + + # Genera un cliente para publicar el sitio + # + # @return [DistributedPress::V1::Client] + def publishing_client + DistributedPress::V1::Client.new(url: publisher.instance, token: publishing_token) + end + + # El cliente para actualizar el sitio + # + # @return [DistributedPress::V1::Client::Site] + def site_client + DistributedPress::V1::Client::Site.new(publishing_client) + end + + # Genera el esquema de datos para poder publicar el sitio + # + # @return [DistributedPress::V1::Schemas::PublishingSite] + def publishing_site + DistributedPress::V1::Schemas::PublishingSite.new.call(id: remote_site_id) + end + + # Genera el esquema de datos para crear el sitio + # + # @return [DistributedPressPublisher::V1::Schemas::NewSite] + def create_site + DistributedPress::V1::Schemas::NewSite.new.call(domain: hostname, protocols: { http: true, ipfs: true, hyper: true }) + end + + # Crea el sitio en la instancia con el hostname especificado + # + # @return [nil] + def create_remote_site! + created_site = site_client.create(create_site) + + self.remote_site_id = created_site[:id] + self.remote_info = created_site.to_h + + nil + end + + # Registra lo que sucedió + # + # @param status [Bool] + # @return [nil] + def create_stat!(status) + build_stats.create action: publisher.to_s, seconds: time_spent_in_seconds, bytes: size, status: status + nil + end end diff --git a/app/models/distributed_press_publisher.rb b/app/models/distributed_press_publisher.rb index 610d698d..5358e738 100644 --- a/app/models/distributed_press_publisher.rb +++ b/app/models/distributed_press_publisher.rb @@ -46,6 +46,11 @@ class DistributedPressPublisher < ApplicationRecord @client ||= DistributedPress::V1::Client.new(url: instance, token: token) end + # @return [String] + def to_s + "Distributed Press <#{instance}>" + end + private # Actualiza o desactiva la fecha de vencimiento a partir de la From 8006bd03538dee1285ef7746db382958b6cabce7 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 20 Jan 2023 20:35:39 -0300 Subject: [PATCH 07/28] fix: permitir modificar el token estos parches hacian que no se pueda modificar el token --- app/models/distributed_press_publisher.rb | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/app/models/distributed_press_publisher.rb b/app/models/distributed_press_publisher.rb index 5358e738..acfc4226 100644 --- a/app/models/distributed_press_publisher.rb +++ b/app/models/distributed_press_publisher.rb @@ -22,22 +22,6 @@ class DistributedPressPublisher < ApplicationRecord where('expires_at > ? and expires_at < ?', Time.now, Time.now + 1.hour) } - # Al cambiar el token genera un cliente nuevo - # - # @return [String] - def token=(new_token) - @client = nil - super - end - - # Al cambiar la instancia genera un cliente nuevo - # - # @return [String] - def instance=(new_instance) - @client = nil - super - end - # Instancia un cliente de Distributed Press a partir del token. Al # cargar un token a punto de vencer se renueva automáticamente. # From b28d7946460d8bed6400a6f13d6f0911a12a8f53 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 23 Jan 2023 18:39:10 -0300 Subject: [PATCH 08/28] =?UTF-8?q?feat:=20no=20vamos=20a=20expedir=20tokens?= =?UTF-8?q?=20ef=C3=ADmeros=20por=20ahora?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/deploy_distributed_press.rb | 31 +------------------------- 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index 09ba0364..38cb59e3 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -59,40 +59,11 @@ class DeployDistributedPress < Deploy @publisher ||= DistributedPressPublisher.first end - # El cliente de autenticación se encarga de intercambiar un token por - # otro - # - # @return [DistributedPress::V1::Client::Auth] - def auth_client - DistributedPress::V1::Client::Auth.new(publisher.client) - end - - # Genera un token con permisos de publicación - # - # @return [DistributedPress::V1::Schemas::NewTokenPayload] - def publishing_token_payload - DistributedPress::V1::Schemas::NewTokenPayload.new.call(capabilities: %w[publisher]) - end - - # Genera un token efímero para publicar el sitio - # - # @return [DistributedPress::V1::Token] - def publishing_token - auth_client.exchange(publishing_token_payload) - end - - # Genera un cliente para publicar el sitio - # - # @return [DistributedPress::V1::Client] - def publishing_client - DistributedPress::V1::Client.new(url: publisher.instance, token: publishing_token) - end - # El cliente para actualizar el sitio # # @return [DistributedPress::V1::Client::Site] def site_client - DistributedPress::V1::Client::Site.new(publishing_client) + DistributedPress::V1::Client::Site.new(publisher.client) end # Genera el esquema de datos para poder publicar el sitio From ebf1390bdf962c49f2fab7a914a3944060c0c461 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 26 Jan 2023 15:41:54 -0300 Subject: [PATCH 09/28] fix: actualizar api --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index cdfe7183..534ad298 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -163,7 +163,7 @@ GEM devise_invitable (2.0.5) actionmailer (>= 5.0) devise (>= 4.6) - distributed-press-api-client (0.2.0) + distributed-press-api-client (0.2.1) addressable (~> 2.3, >= 2.3.0) climate_control dry-schema From 928bc45920cfbf10a46e088ccbbcece043d24dd5 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 6 Feb 2023 16:09:51 -0300 Subject: [PATCH 10/28] feat: usar pnpm si existe relacionado con sutty/jekyll/sutty-base-jekyll-theme#53 --- Dockerfile | 2 ++ app/models/deploy_local.rb | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/Dockerfile b/Dockerfile index ecf43cbc..b2f96612 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 +RUN apk add npm && npm install -g pnpm && apk del npm + VOLUME "/srv" EXPOSE 3000 diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 4b22d728..51baf492 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -15,6 +15,7 @@ class DeployLocal < Deploy def deploy return false unless mkdir return false unless yarn + return false unless pnpm return false unless bundle jekyll_build @@ -74,6 +75,10 @@ class DeployLocal < Deploy Rails.root.join('_yarn_cache').to_s end + def pnpm_cache_dir + Rails.root.join('_pnpm_cache').to_s + end + def yarn_lock File.join(site.path, 'yarn.lock') end @@ -82,6 +87,14 @@ class DeployLocal < Deploy File.exist? yarn_lock end + def pnpm_lock + File.join(site.path, 'pnpm-lock.yaml') + end + + def pnpm_lock? + File.exist? pnpm_lock + end + def gem run %(gem install bundler --no-document) end @@ -93,6 +106,13 @@ class DeployLocal < Deploy run 'yarn install --production' end + def pnpm + return true unless pnpm_lock? + + run %(pnpm config set store-dir "#{pnpm_cache_dir}") + run 'pnpm install --production' + end + def bundle if Rails.env.production? run %(bundle install --no-cache --path="#{gems_dir}") From a73100a436a283533236989c58f162c0fe8dbd4f Mon Sep 17 00:00:00 2001 From: f Date: Mon, 6 Feb 2023 16:16:27 -0300 Subject: [PATCH 11/28] fix: pnpm se instala localmente --- app/models/deploy_local.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 51baf492..e4845d7c 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -55,7 +55,7 @@ class DeployLocal < Deploy # @return [Hash] def env # XXX: This doesn't support Windows paths :B - paths = [File.dirname(`which bundle`), '/usr/bin', '/bin'] + paths = [File.dirname(`which bundle`), '/usr/local/bin', '/usr/bin', '/bin'] # Las variables de entorno extra no pueden superponerse al local. extra_env.merge({ From 464ff4841b68affaa694ab0e8e348035cf565a38 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 7 Feb 2023 18:15:25 -0300 Subject: [PATCH 12/28] feat: textos para el panel --- config/locales/en.yml | 16 ++++++++++++++-- config/locales/es.yml | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index e7fb4f76..2bbf58ea 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -249,9 +249,21 @@ en: Only accessible through [Tor Browser](https://www.torproject.org/download/) deploy_distributed_press: - title: 'Publish on Distributed Press' + title: 'Publish to the distributed Web' help: | - ipfs + Make your site available through peer-to-peer protocols, + Inter-Planetary File System (IPFS), Hypercore, and via + BitTorrent, so your site is more resilient and can be available + offline, including in community mesh networks. + + **Important:** Only use this option if you would like your data + to be permanently available. If you decide to undo this + selection, a cleared version of the site will be shared in its + place. However, it is possible that nodes on the distributed + storage network may continue retaining copies of the data + indefinitely. + + [Learn more](#) stats: index: title: Statistics diff --git a/config/locales/es.yml b/config/locales/es.yml index 18cf5326..e3b24957 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -254,9 +254,21 @@ es: Sólo será accesible a través del [Navegador Tor](https://www.torproject.org/es/download/). deploy_distributed_press: - title: 'Alojar en la web distribuida' + title: 'Publicar a la Web distribuida' help: | - Es para que esté en la web distribuida + Utiliza protocolos de pares, Inter-Planetary File System (IPFS), + Hypercore y torrents, para que tu sitio sea más resiliente y + esté disponible _offline_, inclusive en redes _mesh_ + comunitarias. + + **Importante:** Sólo usa esta opción si te parece correcto que + tu contenido esté disponible permanentemente. Cuando elijas + des-hacer esta acción, una versión "vacía" del sitio será + compartida en su lugar. Sin embargo, es posible que algunos + nodos en la red de almacenamiento distribuida puedan retener + copias de tu contenido indefinidamente. + + [Saber más](#) stats: index: title: Estadísticas From 9661a34a04396c647f5ad1fe5d6ea75fc3b513ac Mon Sep 17 00:00:00 2001 From: f Date: Wed, 8 Feb 2023 09:38:36 -0300 Subject: [PATCH 13/28] fix: faltaban algunos require --- Gemfile | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index f317487b..694358a6 100644 --- a/Gemfile +++ b/Gemfile @@ -38,7 +38,7 @@ gem 'commonmarker' gem 'devise' gem 'devise-i18n' gem 'devise_invitable' -gem 'distributed-press-api-client', '~> 0.2.0' +gem 'distributed-press-api-client', '~> 0.2.1' gem 'email_address', git: 'https://github.com/fauno/email_address', branch: 'i18n' gem 'exception_notification' gem 'fast_blank' diff --git a/Gemfile.lock b/Gemfile.lock index 534ad298..5c074a7b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -704,7 +704,7 @@ DEPENDENCIES devise devise-i18n devise_invitable - distributed-press-api-client (~> 0.2.0) + distributed-press-api-client (~> 0.2.1) dotenv-rails down ed25519 From 6683f80aba504c2edca9bcb4ca5f3ce4f24eba9c Mon Sep 17 00:00:00 2001 From: f Date: Wed, 8 Feb 2023 11:55:07 -0300 Subject: [PATCH 14/28] fix: no fallar si tarda mucho dp --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 694358a6..7f4cc6ca 100644 --- a/Gemfile +++ b/Gemfile @@ -38,7 +38,7 @@ gem 'commonmarker' gem 'devise' gem 'devise-i18n' gem 'devise_invitable' -gem 'distributed-press-api-client', '~> 0.2.1' +gem 'distributed-press-api-client', '~> 0.2.2' gem 'email_address', git: 'https://github.com/fauno/email_address', branch: 'i18n' gem 'exception_notification' gem 'fast_blank' diff --git a/Gemfile.lock b/Gemfile.lock index 5c074a7b..b5b6fd18 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -163,7 +163,7 @@ GEM devise_invitable (2.0.5) actionmailer (>= 5.0) devise (>= 4.6) - distributed-press-api-client (0.2.1) + distributed-press-api-client (0.2.2) addressable (~> 2.3, >= 2.3.0) climate_control dry-schema @@ -704,7 +704,7 @@ DEPENDENCIES devise devise-i18n devise_invitable - distributed-press-api-client (~> 0.2.1) + distributed-press-api-client (~> 0.2.2) dotenv-rails down ed25519 From ccfd77d9568dce55ea8ce29ea114b2487f7bc0b9 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 8 Feb 2023 17:08:02 -0300 Subject: [PATCH 15/28] =?UTF-8?q?feat:=20guardar=20un=20log=20y=20mostrarl?= =?UTF-8?q?o=20en=20output=20tambi=C3=A9n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/deploy_distributed_press.rb | 24 ++++++++++++++++++----- app/models/distributed_press_publisher.rb | 22 ++++++++++++++++++++- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index 38cb59e3..d805e923 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -22,19 +22,32 @@ class DeployDistributedPress < Deploy # @param :output [Bool] # @return [Bool] def deploy + status = false + log = [] + time_start - status = false - site_client.tap do |c| + stdout = Thread.new(publisher.logger_out) do |io| + until io.eof? + line = io.gets + + puts line if output + log << line + end + end + update remote_info: c.show(publishing_site).to_h status = c.publish(publishing_site, deploy_local.destination) + + publisher.logger.close + stdout.join end time_stop - create_stat! status + create_stat! status, log.join status end @@ -95,9 +108,10 @@ class DeployDistributedPress < Deploy # Registra lo que sucedió # # @param status [Bool] + # @param log [String] # @return [nil] - def create_stat!(status) - build_stats.create action: publisher.to_s, seconds: time_spent_in_seconds, bytes: size, status: status + def create_stat!(status, log) + build_stats.create action: publisher.to_s,log: log, seconds: time_spent_in_seconds, bytes: size, status: status nil end end diff --git a/app/models/distributed_press_publisher.rb b/app/models/distributed_press_publisher.rb index acfc4226..089f63c6 100644 --- a/app/models/distributed_press_publisher.rb +++ b/app/models/distributed_press_publisher.rb @@ -8,6 +8,11 @@ class DistributedPressPublisher < ApplicationRecord # Cifrar la información del token en la base de datos has_encrypted :token + # La salida del log + # + # @return [IO] + attr_reader :logger_out + # La instancia es única validates_uniqueness_of :instance @@ -27,7 +32,7 @@ class DistributedPressPublisher < ApplicationRecord # # @return [DistributedPress::V1::Client] def client - @client ||= DistributedPress::V1::Client.new(url: instance, token: token) + @client ||= DistributedPress::V1::Client.new(url: instance, token: token, logger: logger) end # @return [String] @@ -35,8 +40,23 @@ class DistributedPressPublisher < ApplicationRecord "Distributed Press <#{instance}>" end + # @return [Logger] + def logger + @logger ||= + begin + @logger_out, @logger_in = IO.pipe + ::Logger.new @logger_in, formatter: formatter + end + end + private + def formatter + @formatter ||= lambda do |_, _, _, msg| + "#{msg}\n" + end + end + # Actualiza o desactiva la fecha de vencimiento a partir de la # información del token. # From 89f5ed90ebe60b2b9132c8bdad1e9ee3a310e970 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 8 Feb 2023 17:44:35 -0300 Subject: [PATCH 16/28] =?UTF-8?q?fix:=20link=20a=20saber=20m=C3=A1s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/locales/en.yml | 2 +- config/locales/es.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 2bbf58ea..f37afa7c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -263,7 +263,7 @@ en: storage network may continue retaining copies of the data indefinitely. - [Learn more](#) + [Learn more](https://ffdweb.org/building-distributed-press-a-publishing-tool-for-the-decentralized-web/) stats: index: title: Statistics diff --git a/config/locales/es.yml b/config/locales/es.yml index e3b24957..fef3b6eb 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -268,7 +268,7 @@ es: nodos en la red de almacenamiento distribuida puedan retener copias de tu contenido indefinidamente. - [Saber más](#) + [Saber más (en inglés)](https://ffdweb.org/building-distributed-press-a-publishing-tool-for-the-decentralized-web/) stats: index: title: Estadísticas From 15e6696bcf7b645b59a246c8fcd908db9671ad74 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 8 Feb 2023 18:49:37 -0300 Subject: [PATCH 17/28] feat: un deploy puede tener varias urls --- app/models/deploy_distributed_press.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index d805e923..d3474d50 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -60,6 +60,15 @@ class DeployDistributedPress < Deploy def destination; end + # Devuelve las URLs de todos los protocolos + def urls + remote_info[:links].values.map do |protocol| + [ protocol[:link], protocol[:gateway] ] + end.flatten.compact.select do |link| + link.include? '://' + end + end + private # El cliente de la API From 7ff284d547cd8e0ce8f0f30d4172db182e439430 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 8 Feb 2023 18:52:48 -0300 Subject: [PATCH 18/28] =?UTF-8?q?feat:=20texto=20para=20el=20correo=20de?= =?UTF-8?q?=20notificaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/locales/en.yml | 4 ++++ config/locales/es.yml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index f37afa7c..ac8d7289 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -102,6 +102,10 @@ en: title: Alternative domain name success: Success! error: Error + deploy_distributed_press: + title: Distributed Web + success: Success! + error: Error help: You can contact us by replying to this e-mail maintenance_mailer: notice: diff --git a/config/locales/es.yml b/config/locales/es.yml index fef3b6eb..335fca66 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -102,6 +102,10 @@ es: title: Dominio alternativo success: ¡Éxito! error: Hubo un error + deploy_distributed_press: + title: Web distribuida + success: ¡Éxito! + error: Hubo un error help: Por cualquier duda, responde este correo para contactarte con nosotres. maintenance_mailer: notice: From 3f7b2484d04bee63bff7877f746721703043e217 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 9 Feb 2023 20:01:22 -0300 Subject: [PATCH 19/28] feat: crear temporalmente los dominios en njalla el problema es que no podemos delegar `_dnslink.*.sutty.nl` hacia distributed press, con lo que es necesario crear un subdominio por cada sitio que lo active. --- Gemfile | 1 + Gemfile.lock | 4 ++++ app/models/deploy_distributed_press.rb | 18 ++++++++++++++++++ app/models/distributed_press_publisher.rb | 7 +++++++ 4 files changed, 30 insertions(+) diff --git a/Gemfile b/Gemfile index 7f4cc6ca..8f742348 100644 --- a/Gemfile +++ b/Gemfile @@ -39,6 +39,7 @@ gem 'devise' gem 'devise-i18n' gem 'devise_invitable' gem 'distributed-press-api-client', '~> 0.2.2' +gem 'njalla-api-client' gem 'email_address', git: 'https://github.com/fauno/email_address', branch: 'i18n' gem 'exception_notification' gem 'fast_blank' diff --git a/Gemfile.lock b/Gemfile.lock index b5b6fd18..6469b2db 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -419,6 +419,9 @@ GEM nokogiri (1.12.5-x86_64-linux-musl) mini_portile2 (~> 2.6.1) racc (~> 1.4) + njalla-api-client (0.1.0) + dry-schema + httparty (~> 0.18) orm_adapter (0.5.0) parallel (1.21.0) parser (3.0.2.0) @@ -741,6 +744,7 @@ DEPENDENCIES minima mobility net-ssh + njalla-api-client nokogiri pg pg_search diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index d3474d50..6f2b2c78 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -111,6 +111,12 @@ class DeployDistributedPress < Deploy self.remote_site_id = created_site[:id] self.remote_info = created_site.to_h + # XXX: Esto depende de nuestro DNS actual, cuando lo migremos hay + # que eliminarlo. + self.remote_info['njalla'] = {} + self.remote_info['njalla']['a'] = njalla.add_record(name: site.name, type: 'CNAME', content: "#{Site.domain}.").to_h + self.remote_info['njalla']['ns'] = njalla.add_record(name: "_dnslink.#{site.name}", type: 'NS', content: "#{publisher.hostname}.").to_h + nil end @@ -123,4 +129,16 @@ class DeployDistributedPress < Deploy build_stats.create action: publisher.to_s,log: log, seconds: time_spent_in_seconds, bytes: size, status: status nil end + + # Actualizar registros en Njalla + # + # @return [Njalla::V1::Domain] + def njalla + @njalla ||= + begin + client = Njalla::V1::Client.new(token: ENV['NJALLA_TOKEN']) + + Njalla::V1::Domain.new(domain: Site.domain, client: client) + end + end end diff --git a/app/models/distributed_press_publisher.rb b/app/models/distributed_press_publisher.rb index 089f63c6..6139db93 100644 --- a/app/models/distributed_press_publisher.rb +++ b/app/models/distributed_press_publisher.rb @@ -40,6 +40,13 @@ class DistributedPressPublisher < ApplicationRecord "Distributed Press <#{instance}>" end + # Devuelve el hostname de la instancia + # + # @return [String] + def hostname + @hostname ||= URI.parse(instance).hostname + end + # @return [Logger] def logger @logger ||= From a849eac17962a645a70b8fd5b5546aa8d285a46e Mon Sep 17 00:00:00 2001 From: f Date: Thu, 9 Feb 2023 20:08:56 -0300 Subject: [PATCH 20/28] fix: no crear subdominios para dominios personalizados esto es por retrocompatibilidad para sitios que no usan DeployAlternativeDomain --- app/models/deploy_distributed_press.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index 6f2b2c78..1ae7a2f2 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -113,9 +113,11 @@ class DeployDistributedPress < Deploy # XXX: Esto depende de nuestro DNS actual, cuando lo migremos hay # que eliminarlo. - self.remote_info['njalla'] = {} - self.remote_info['njalla']['a'] = njalla.add_record(name: site.name, type: 'CNAME', content: "#{Site.domain}.").to_h - self.remote_info['njalla']['ns'] = njalla.add_record(name: "_dnslink.#{site.name}", type: 'NS', content: "#{publisher.hostname}.").to_h + unless site.name.end_with? '.' + self.remote_info['njalla'] = {} + self.remote_info['njalla']['a'] = njalla.add_record(name: site.name, type: 'CNAME', content: "#{Site.domain}.").to_h + self.remote_info['njalla']['ns'] = njalla.add_record(name: "_dnslink.#{site.name}", type: 'NS', content: "#{publisher.hostname}.").to_h + end nil end From a3c1d7193f8112006cffa60f830e38d9e8d669f2 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 9 Feb 2023 20:11:17 -0300 Subject: [PATCH 21/28] fix: requires --- app/models/deploy_distributed_press.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index 1ae7a2f2..41054b99 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -require 'distributed_press/v1/client/auth' require 'distributed_press/v1/client/site' +require 'njalla/v1' # Soportar Distributed Press APIv1 # From f2e79a733d26f1cf578d1f49f995aea14376a246 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 17 Mar 2023 17:33:52 -0300 Subject: [PATCH 22/28] fix: no fallar si hay errores remotos closes #10467 closes #10506 closes #10509 --- app/models/deploy_distributed_press.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index 41054b99..09410201 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -118,7 +118,9 @@ class DeployDistributedPress < Deploy self.remote_info['njalla']['a'] = njalla.add_record(name: site.name, type: 'CNAME', content: "#{Site.domain}.").to_h self.remote_info['njalla']['ns'] = njalla.add_record(name: "_dnslink.#{site.name}", type: 'NS', content: "#{publisher.hostname}.").to_h end - + rescue DistributedPress::V1::Error, HTTParty::Error => e + ExceptionNotifier.notify_exception(e, data: { site: site.name }) + ensure nil end From 0c674d6ca12fc0f98645a922e18efd13de85cd09 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 17 Mar 2023 17:37:48 -0300 Subject: [PATCH 23/28] fix: crear el sitio remoto si no se pudo crear antes --- app/models/deploy_distributed_press.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index 09410201..bd80dca4 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -27,6 +27,11 @@ class DeployDistributedPress < Deploy time_start + if remote_site_id.blank? || remote_info['njalla'].blank? + create_remote_site! + save + end + site_client.tap do |c| stdout = Thread.new(publisher.logger_out) do |io| until io.eof? From 698b3a0bf6bbbaf6b84a8c0c961de081e2c1989b Mon Sep 17 00:00:00 2001 From: f Date: Fri, 17 Mar 2023 17:39:41 -0300 Subject: [PATCH 24/28] =?UTF-8?q?feat:=20separar=20la=20creaci=C3=B3n=20de?= =?UTF-8?q?=20DP=20de=20njalla?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/deploy_distributed_press.rb | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index bd80dca4..9afc6a5d 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -15,7 +15,7 @@ require 'njalla/v1' class DeployDistributedPress < Deploy store :values, accessors: %i[hostname remote_site_id remote_info], coder: JSON - before_create :create_remote_site! + before_create :create_remote_site!, :create_njalla_records! # Actualiza la información y luego envía los cambios # @@ -27,10 +27,9 @@ class DeployDistributedPress < Deploy time_start - if remote_site_id.blank? || remote_info['njalla'].blank? - create_remote_site! - save - end + create_remote_site! if remote_site_id.blank? + create_njalla_records! if remote_info['njalla'].blank? + save site_client.tap do |c| stdout = Thread.new(publisher.logger_out) do |io| @@ -115,7 +114,16 @@ class DeployDistributedPress < Deploy self.remote_site_id = created_site[:id] self.remote_info = created_site.to_h + rescue DistributedPress::V1::Error + ExceptionNotifier.notify_exception(e, data: { site: site.name }) + ensure + nil + end + # Crea los registros en Njalla + # + # @return [nil] + def create_njalla_records! # XXX: Esto depende de nuestro DNS actual, cuando lo migremos hay # que eliminarlo. unless site.name.end_with? '.' @@ -123,7 +131,7 @@ class DeployDistributedPress < Deploy self.remote_info['njalla']['a'] = njalla.add_record(name: site.name, type: 'CNAME', content: "#{Site.domain}.").to_h self.remote_info['njalla']['ns'] = njalla.add_record(name: "_dnslink.#{site.name}", type: 'NS', content: "#{publisher.hostname}.").to_h end - rescue DistributedPress::V1::Error, HTTParty::Error => e + rescue HTTParty::Error => e ExceptionNotifier.notify_exception(e, data: { site: site.name }) ensure nil From b297800933ae0556845f1e710ce181a6d4e158cb Mon Sep 17 00:00:00 2001 From: f Date: Fri, 17 Mar 2023 17:44:13 -0300 Subject: [PATCH 25/28] fix: volver a fallar si al hacer deploy todavia estan caidos los servicios --- app/models/deploy_distributed_press.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index 9afc6a5d..e8d8b095 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -31,6 +31,10 @@ class DeployDistributedPress < Deploy create_njalla_records! if remote_info['njalla'].blank? save + if remote_site_id.blank? || remote_info['njalla'].blank? + raise DeployJob::DeployException, '' + end + site_client.tap do |c| stdout = Thread.new(publisher.logger_out) do |io| until io.eof? @@ -133,6 +137,7 @@ class DeployDistributedPress < Deploy end rescue HTTParty::Error => e ExceptionNotifier.notify_exception(e, data: { site: site.name }) + self.remote_info['njalla'] = nil ensure nil end From 16ed7db1d76ff24ee5c8a6d88b6c35788c22441a Mon Sep 17 00:00:00 2001 From: f Date: Mon, 20 Mar 2023 12:13:51 -0300 Subject: [PATCH 26/28] =?UTF-8?q?fix:=20capturar=20la=20excepci=C3=B3n=20#?= =?UTF-8?q?10546?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/deploy_distributed_press.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index e8d8b095..6940a83e 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -118,7 +118,7 @@ class DeployDistributedPress < Deploy self.remote_site_id = created_site[:id] self.remote_info = created_site.to_h - rescue DistributedPress::V1::Error + rescue DistributedPress::V1::Error => e ExceptionNotifier.notify_exception(e, data: { site: site.name }) ensure nil From 34d26a0174b0644d96e430b3bf894c734d366dce Mon Sep 17 00:00:00 2001 From: f Date: Thu, 6 Apr 2023 11:27:28 -0300 Subject: [PATCH 27/28] fix: instalar pnpm 7 porque 8 es incompatible con node 14 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index a6420a35..3da9ffab 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ 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 -RUN apk add npm && npm install -g pnpm && apk del npm +RUN apk add npm && npm install -g pnpm@~7 && apk del npm COPY ./monit.conf /etc/monit.d/sutty.conf From 6cab61891c9c1fd0fb7c3a260febc816d40178ea Mon Sep 17 00:00:00 2001 From: f Date: Thu, 6 Apr 2023 20:30:47 -0300 Subject: [PATCH 28/28] fix: la tarea estaba mal nombrada --- Procfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Procfile b/Procfile index 950168dd..25a1639d 100644 --- a/Procfile +++ b/Procfile @@ -5,6 +5,6 @@ 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_" -distributed_press_renew_tokens: bundle exec rake distributed_press:tokens:renew +distributed_press_tokens_renew: bundle exec rake distributed_press:tokens:renew cleanup: bundle exec rake cleanup:everything stats: bundle exec rake stats:process_all