about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Gemfile1
-rw-r--r--Gemfile.lock11
-rw-r--r--app/controllers/admin/dashboard_controller.rb7
-rw-r--r--app/controllers/health_controller.rb7
-rw-r--r--app/javascript/mastodon/features/ui/components/columns_area.js12
-rw-r--r--app/javascript/styles/mastodon/forms.scss42
-rw-r--r--app/lib/admin/system_check.rb21
-rw-r--r--app/lib/admin/system_check/base_check.rb11
-rw-r--r--app/lib/admin/system_check/database_schema_check.rb11
-rw-r--r--app/lib/admin/system_check/message.rb11
-rw-r--r--app/lib/admin/system_check/rules_check.rb13
-rw-r--r--app/lib/admin/system_check/sidekiq_process_check.rb26
-rw-r--r--app/views/admin/dashboard/index.html.haml8
-rwxr-xr-xapp/views/layouts/application.html.haml4
-rw-r--r--app/views/layouts/embedded.html.haml2
-rw-r--r--config/initializers/health_check.rb8
-rw-r--r--config/locales/en.yml9
-rw-r--r--config/routes.rb2
-rw-r--r--lib/mastodon/cli_helper.rb4
-rw-r--r--package.json4
-rw-r--r--yarn.lock24
21 files changed, 191 insertions, 47 deletions
diff --git a/Gemfile b/Gemfile
index 8a77c1bf6..c866625c0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -54,7 +54,6 @@ gem 'fast_blank', '~> 1.0'
 gem 'fastimage'
 gem 'hiredis', '~> 0.6'
 gem 'redis-namespace', '~> 1.8'
-gem 'health_check', git: 'https://github.com/ianheggie/health_check', ref: '0b799ead604f900ed50685e9b2d469cd2befba5b'
 gem 'htmlentities', '~> 4.3'
 gem 'http', '~> 4.4'
 gem 'http_accept_language', '~> 2.1'
diff --git a/Gemfile.lock b/Gemfile.lock
index 9fc70e175..1d6480a7b 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -22,14 +22,6 @@ GIT
       statsd-ruby (~> 1.4, >= 1.4.0)
 
 GIT
-  remote: https://github.com/ianheggie/health_check
-  revision: 0b799ead604f900ed50685e9b2d469cd2befba5b
-  ref: 0b799ead604f900ed50685e9b2d469cd2befba5b
-  specs:
-    health_check (4.0.0.pre)
-      rails (>= 4.0)
-
-GIT
   remote: https://github.com/nsommer/pluck_each
   revision: 73be0947c52fc54bf6d7085378db008358aac5eb
   ref: 73be0947c52fc54bf6d7085378db008358aac5eb
@@ -567,7 +559,7 @@ GEM
     rspec-support (3.10.2)
     rspec_junit_formatter (0.4.1)
       rspec-core (>= 2, < 4, != 2.12.0)
-    rubocop (1.12.0)
+    rubocop (1.12.1)
       parallel (~> 1.10)
       parser (>= 3.0.0.0)
       rainbow (>= 2.2.2, < 4.0)
@@ -756,7 +748,6 @@ DEPENDENCIES
   fog-openstack (~> 0.3)
   fuubar (~> 2.5)
   hamlit-rails (~> 0.2)
-  health_check!
   hiredis (~> 0.6)
   htmlentities (~> 4.3)
   http (~> 4.4)
diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb
index e87dd076f..9e921fb95 100644
--- a/app/controllers/admin/dashboard_controller.rb
+++ b/app/controllers/admin/dashboard_controller.rb
@@ -3,13 +3,8 @@ require 'sidekiq/api'
 
 module Admin
   class DashboardController < BaseController
-    SIDEKIQ_QUEUES = %w(default push mailers pull scheduler).freeze
-
     def index
-      missing_queues = Sidekiq::ProcessSet.new.reduce(SIDEKIQ_QUEUES) { |queues, process| queues - process['queues'] }
-
-      flash.now[:alert] = I18n.t('admin.dashboard.misconfigured_sidekiq_alert', queues: missing_queues.join(', ')) unless missing_queues.empty?
-
+      @system_checks         = Admin::SystemCheck.perform
       @users_count           = User.count
       @pending_users_count   = User.pending.count
       @registrations_week    = Redis.current.get("activity:accounts:local:#{current_week}") || 0
diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb
new file mode 100644
index 000000000..2a22a0557
--- /dev/null
+++ b/app/controllers/health_controller.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class HealthController < ActionController::Base
+  def show
+    render plain: 'OK'
+  end
+end
diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.js
index 85a92fc3a..270be2851 100644
--- a/app/javascript/mastodon/features/ui/components/columns_area.js
+++ b/app/javascript/mastodon/features/ui/components/columns_area.js
@@ -90,7 +90,11 @@ class ColumnsArea extends ImmutablePureComponent {
     }
 
     if (this.mediaQuery) {
-      this.mediaQuery.addEventListener('change', this.handleLayoutChange);
+      if (this.mediaQuery.addEventListener) {
+        this.mediaQuery.addEventListener('change', this.handleLayoutChange);
+      } else {
+        this.mediaQuery.addListener(this.handleLayoutChange);
+      }
       this.setState({ renderComposePanel: !this.mediaQuery.matches });
     }
 
@@ -125,7 +129,11 @@ class ColumnsArea extends ImmutablePureComponent {
     }
 
     if (this.mediaQuery) {
-      this.mediaQuery.removeEventListener('change', this.handleLayoutChange);
+      if (this.mediaQuery.removeEventListener) {
+        this.mediaQuery.removeEventListener('change', this.handleLayoutChange);
+      } else {
+        this.mediaQuery.removeListener(this.handleLayouteChange);
+      }
     }
   }
 
diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss
index e0604303b..ef4a08c59 100644
--- a/app/javascript/styles/mastodon/forms.scss
+++ b/app/javascript/styles/mastodon/forms.scss
@@ -604,6 +604,12 @@ code {
     color: $valid-value-color;
   }
 
+  &.warning {
+    border: 1px solid rgba($gold-star, 0.5);
+    background: rgba($gold-star, 0.25);
+    color: $gold-star;
+  }
+
   &.alert {
     border: 1px solid rgba($error-value-color, 0.5);
     background: rgba($error-value-color, 0.1);
@@ -625,6 +631,19 @@ code {
     }
   }
 
+  &.warning a {
+    font-weight: 700;
+    color: inherit;
+    text-decoration: underline;
+
+    &:hover,
+    &:focus,
+    &:active {
+      text-decoration: none;
+      color: inherit;
+    }
+  }
+
   p {
     margin-bottom: 15px;
   }
@@ -681,6 +700,29 @@ code {
   }
 }
 
+.flash-message-stack {
+  margin-bottom: 30px;
+
+  .flash-message {
+    border-radius: 0;
+    margin-bottom: 0;
+    border-top-width: 0;
+
+    &:first-child {
+      border-radius: 4px 4px 0 0;
+      border-top-width: 1px;
+    }
+
+    &:last-child {
+      border-radius: 0 0 4px 4px;
+
+      &:first-child {
+        border-radius: 4px;
+      }
+    }
+  }
+}
+
 .form-footer {
   margin-top: 30px;
   text-align: center;
diff --git a/app/lib/admin/system_check.rb b/app/lib/admin/system_check.rb
new file mode 100644
index 000000000..afb20cb47
--- /dev/null
+++ b/app/lib/admin/system_check.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class Admin::SystemCheck
+  ACTIVE_CHECKS = [
+    Admin::SystemCheck::DatabaseSchemaCheck,
+    Admin::SystemCheck::SidekiqProcessCheck,
+    Admin::SystemCheck::RulesCheck,
+  ].freeze
+
+  def self.perform
+    ACTIVE_CHECKS.each_with_object([]) do |klass, arr|
+      check = klass.new
+
+      if check.pass?
+        arr
+      else
+        arr << check.message
+      end
+    end
+  end
+end
diff --git a/app/lib/admin/system_check/base_check.rb b/app/lib/admin/system_check/base_check.rb
new file mode 100644
index 000000000..fcad8daca
--- /dev/null
+++ b/app/lib/admin/system_check/base_check.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class Admin::SystemCheck::BaseCheck
+  def pass?
+    raise NotImplementedError
+  end
+
+  def message
+    raise NotImplementedError
+  end
+end
diff --git a/app/lib/admin/system_check/database_schema_check.rb b/app/lib/admin/system_check/database_schema_check.rb
new file mode 100644
index 000000000..b93d1954e
--- /dev/null
+++ b/app/lib/admin/system_check/database_schema_check.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class Admin::SystemCheck::DatabaseSchemaCheck < Admin::SystemCheck::BaseCheck
+  def pass?
+    !ActiveRecord::Base.connection.migration_context.needs_migration?
+  end
+
+  def message
+    Admin::SystemCheck::Message.new(:database_schema_check)
+  end
+end
diff --git a/app/lib/admin/system_check/message.rb b/app/lib/admin/system_check/message.rb
new file mode 100644
index 000000000..bfcad3bf3
--- /dev/null
+++ b/app/lib/admin/system_check/message.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class Admin::SystemCheck::Message
+  attr_reader :key, :value, :action
+
+  def initialize(key, value = nil, action = nil)
+    @key    = key
+    @value  = value
+    @action = action
+  end
+end
diff --git a/app/lib/admin/system_check/rules_check.rb b/app/lib/admin/system_check/rules_check.rb
new file mode 100644
index 000000000..1fbdf955d
--- /dev/null
+++ b/app/lib/admin/system_check/rules_check.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class Admin::SystemCheck::RulesCheck < Admin::SystemCheck::BaseCheck
+  include RoutingHelper
+
+  def pass?
+    Rule.kept.exists?
+  end
+
+  def message
+    Admin::SystemCheck::Message.new(:rules_check, nil, admin_rules_path)
+  end
+end
diff --git a/app/lib/admin/system_check/sidekiq_process_check.rb b/app/lib/admin/system_check/sidekiq_process_check.rb
new file mode 100644
index 000000000..c44d86c44
--- /dev/null
+++ b/app/lib/admin/system_check/sidekiq_process_check.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class Admin::SystemCheck::SidekiqProcessCheck < Admin::SystemCheck::BaseCheck
+  SIDEKIQ_QUEUES = %w(
+    default
+    push
+    mailers
+    pull
+    scheduler
+    ingress
+  ).freeze
+
+  def pass?
+    missing_queues.empty?
+  end
+
+  def message
+    Admin::SystemCheck::Message.new(:sidekiq_process_check, missing_queues.join(', '))
+  end
+
+  private
+
+  def missing_queues
+    @missing_queues ||= Sidekiq::ProcessSet.new.reduce(SIDEKIQ_QUEUES) { |queues, process| queues - process['queues'] }
+  end
+end
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index 249e12563..f2f0c813d 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -1,6 +1,14 @@
 - content_for :page_title do
   = t('admin.dashboard.title')
 
+- unless @system_checks.empty?
+  .flash-message-stack
+    - @system_checks.each do |message|
+      .flash-message.warning
+        = t("admin.system_checks.#{message.key}.message_html", message.value ? { value: content_tag(:strong, message.value) } : {})
+        - if message.action
+          = link_to t("admin.system_checks.#{message.key}.action"), message.action
+
 .dashboard__counters
   %div
     = link_to admin_accounts_url(local: 1, recent: 1) do
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 3daaf93a9..09826afb3 100755
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -45,5 +45,5 @@
     = content_for?(:content) ? yield(:content) : yield
 
     .logo-resources
-      = render file: Rails.root.join('app', 'javascript', 'images', 'logo_transparent.svg')
-      = render file: Rails.root.join('app', 'javascript', 'images', 'logo_full.svg')
+      = raw render file: Rails.root.join('app', 'javascript', 'images', 'logo_transparent.svg')
+      = raw render file: Rails.root.join('app', 'javascript', 'images', 'logo_full.svg')
diff --git a/app/views/layouts/embedded.html.haml b/app/views/layouts/embedded.html.haml
index 431bd260c..2a2996d28 100644
--- a/app/views/layouts/embedded.html.haml
+++ b/app/views/layouts/embedded.html.haml
@@ -25,4 +25,4 @@
     = yield
 
     .logo-resources
-      = render file: Rails.root.join('app', 'javascript', 'images', 'logo_transparent.svg')
+      = raw render file: Rails.root.join('app', 'javascript', 'images', 'logo_transparent.svg')
diff --git a/config/initializers/health_check.rb b/config/initializers/health_check.rb
deleted file mode 100644
index 6f1e78fed..000000000
--- a/config/initializers/health_check.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-HealthCheck.setup do |config|
-  config.uri = 'health'
-
-  config.standard_checks = %w(database migrations cache)
-  config.full_checks = %w(database migrations cache)
-  
-  config.include_error_in_response_body = false
-end
diff --git a/config/locales/en.yml b/config/locales/en.yml
index b907d3882..182a8e985 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -367,7 +367,6 @@ en:
       feature_timeline_preview: Timeline preview
       features: Features
       hidden_service: Federation with hidden services
-      misconfigured_sidekiq_alert: 'No Sidekiq process seems to be handling the following queues: %{queues}. Please review your Sidekiq configuration.'
       open_reports: open reports
       pending_tags: hashtags waiting for review
       pending_users: users waiting for review
@@ -661,6 +660,14 @@ en:
       no_status_selected: No statuses were changed as none were selected
       title: Account statuses
       with_media: With media
+    system_checks:
+      database_schema_check:
+        message_html: There are pending database migrations. Please run them to ensure the application behaves as expected
+      rules_check:
+        action: Manage server rules
+        message_html: You haven't defined any server rules.
+      sidekiq_process_check:
+        message_html: No Sidekiq process running for the %{value} queue(s). Please review your Sidekiq configuration
     tags:
       accounts_today: Unique uses today
       accounts_week: Unique uses this week
diff --git a/config/routes.rb b/config/routes.rb
index 6814dc61e..8ec67113b 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -10,7 +10,7 @@ Rails.application.routes.draw do
 
   mount LetterOpenerWeb::Engine, at: 'letter_opener' if Rails.env.development?
 
-  health_check_routes
+  get 'health', to: 'health#show'
 
   authenticate :user, lambda { |u| u.admin? } do
     mount Sidekiq::Web, at: 'sidekiq', as: :sidekiq
diff --git a/lib/mastodon/cli_helper.rb b/lib/mastodon/cli_helper.rb
index ed22f44b2..aaee1fa91 100644
--- a/lib/mastodon/cli_helper.rb
+++ b/lib/mastodon/cli_helper.rb
@@ -25,7 +25,9 @@ module Mastodon
         exit(1)
       end
 
-      ActiveRecord::Base.configurations[Rails.env]['pool'] = options[:concurrency] + 1
+      db_config = ActiveRecord::Base.configurations[Rails.env].dup
+      db_config['pool'] = options[:concurrency] + 1
+      ActiveRecord::Base.establish_connection(db_config)
 
       progress  = create_progress_bar(scope.count)
       pool      = Concurrent::FixedThreadPool.new(options[:concurrency])
diff --git a/package.json b/package.json
index 7337760bf..c5855f6af 100644
--- a/package.json
+++ b/package.json
@@ -167,7 +167,7 @@
     "twitter-text": "3.1.0",
     "uuid": "^8.3.1",
     "webpack": "^4.46.0",
-    "webpack-assets-manifest": "^4.0.1",
+    "webpack-assets-manifest": "^4.0.2",
     "webpack-bundle-analyzer": "^4.4.0",
     "webpack-cli": "^3.3.12",
     "webpack-merge": "^5.7.3",
@@ -176,7 +176,7 @@
   },
   "devDependencies": {
     "@testing-library/jest-dom": "^5.11.10",
-    "@testing-library/react": "^11.2.5",
+    "@testing-library/react": "^11.2.6",
     "babel-eslint": "^10.1.0",
     "babel-jest": "^26.6.3",
     "eslint": "^7.23.0",
diff --git a/yarn.lock b/yarn.lock
index 4d8a1a4a6..d0aa62307 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1405,10 +1405,10 @@
     lodash "^4.17.15"
     redent "^3.0.0"
 
-"@testing-library/react@^11.2.5":
-  version "11.2.5"
-  resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-11.2.5.tgz#ae1c36a66c7790ddb6662c416c27863d87818eb9"
-  integrity sha512-yEx7oIa/UWLe2F2dqK0FtMF9sJWNXD+2PPtp39BvE0Kh9MJ9Kl0HrZAgEuhUJR+Lx8Di6Xz+rKwSdEPY2UV8ZQ==
+"@testing-library/react@^11.2.6":
+  version "11.2.6"
+  resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-11.2.6.tgz#586a23adc63615985d85be0c903f374dab19200b"
+  integrity sha512-TXMCg0jT8xmuU8BkKMtp8l7Z50Ykew5WNX8UoIKTaLFwKkP2+1YDhOLA2Ga3wY4x29jyntk7EWfum0kjlYiSjQ==
   dependencies:
     "@babel/runtime" "^7.12.5"
     "@testing-library/dom" "^7.28.1"
@@ -3696,7 +3696,7 @@ deep-is@^0.1.3, deep-is@~0.1.3:
   resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
   integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
 
-deepmerge@^4.2.2:
+deepmerge@^4.0, deepmerge@^4.2.2:
   version "4.2.2"
   resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
   integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
@@ -6894,7 +6894,7 @@ locate-path@^5.0.0:
   dependencies:
     p-locate "^4.1.0"
 
-lockfile@^1.0.4:
+lockfile@^1.0:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.4.tgz#07f819d25ae48f87e538e6578b6964a4981a5609"
   integrity sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==
@@ -11213,14 +11213,14 @@ webidl-conversions@^6.1.0:
   resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
   integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
 
-webpack-assets-manifest@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/webpack-assets-manifest/-/webpack-assets-manifest-4.0.1.tgz#918989c51a7800be6683aaa27b9f36bcc7a9afdc"
-  integrity sha512-NS7Bx2C3JsEj6a0MB/PPmPOD/BzDYjB3PaKcI7/r2fKXq0PuZ4YtcbZ5Og+q4gkmetGX9v21vejeAlbru/Fvhw==
+webpack-assets-manifest@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/webpack-assets-manifest/-/webpack-assets-manifest-4.0.2.tgz#ead6e6dbdcd1c2af45d11a382246fcc79a286372"
+  integrity sha512-bBb9PvEGDOCFvW5/t6Yp9MEE0fymNJ0OvEud9nPvQegDbQEUZ/2WTeHnNoALwWMu1x3JHPyqHVYh8SwtYZ/dww==
   dependencies:
     chalk "^4.0"
-    deepmerge "^4.2.2"
-    lockfile "^1.0.4"
+    deepmerge "^4.0"
+    lockfile "^1.0"
     lodash.escaperegexp "^4.0"
     lodash.get "^4.0"
     lodash.has "^4.0"