Browse Source

Maintenance: Introduced Zammad safe mode.

Co-authored-by: Tobias Schäfer <ts@zammad.com>
Co-authored-by: Martin Gruner <mg@zammad.com>
Tobias Schäfer 1 year ago
parent
commit
6ef2f54b41

+ 2 - 1
.gitlab/ci/lint.yml

@@ -9,12 +9,13 @@
     - .template_lint
   services:
     - !reference [.services, postgresql]
-    - !reference [.services, redis]
   before_script:
     - !reference [.scripts, source_rvm]
     - !reference [.scripts, bundle_install]
     - !reference [.scripts, configure_environment]
     - !reference [.scripts, zammad_db_init]
+  variables:
+    ZAMMAD_SAFE_MODE: 1
 
 # Must be a separate job because it uses a custom image.
 'lint: shellcheck':

+ 2 - 1
.gitlab/ci/test/browser_build.yml

@@ -2,7 +2,6 @@ browser:build:
   stage: test
   services:
     - !reference [.services, postgresql]
-    - !reference [.services, redis]
   artifacts:
     expire_in: 1 week
     paths:
@@ -15,8 +14,10 @@ browser:build:
   variables:
     RAILS_ENV: 'production'
     VITE_TEST_MODE: 1
+    ZAMMAD_SAFE_MODE: 1
   script:
     - !reference [.scripts, yarn_install]
     - !reference [.scripts, zammad_db_unseeded]
     - node -v
+    # Don't require Redis.
     - bundle exec rake assets:precompile

+ 1 - 1
.gitlab/configure_environment.rb

@@ -81,7 +81,7 @@ class ConfigureEnvironment
 
   def self.configure_redis
     has_redis = network_host_exists?('redis')
-    needs_redis = ENV['ENABLE_EXPERIMENTAL_MOBILE_FRONTEND'] == 'true'
+    needs_redis = !%w[1 true].include?(ENV['ZAMMAD_SAFE_MODE']) && ENV['ENABLE_EXPERIMENTAL_MOBILE_FRONTEND'] == 'true' # rubocop:disable Rails/NegateInclude
 
     if needs_redis && !has_redis
       raise 'Redis was not found, but is required for ActionCable.'

+ 3 - 0
.overcommit.sh

@@ -2,6 +2,9 @@
 
 set -eux
 
+# Don't require redis.
+export ZAMMAD_SAFE_MODE=1
+
 echo "Checking .pot catalog consistency..."
 rails generate zammad:translation_catalog --check
 

+ 3 - 2
app/graphql/gql/subscriptions/base_subscription.rb

@@ -30,13 +30,14 @@ module Gql::Subscriptions
 
     # Shortcut method to trigger a subscription. Just call:
     #
-    #   Gql::Subscriptions::MyScubscription.trigger(
+    #   Gql::Subscriptions::MySubscription.trigger(
     #     self,                             # object to pass as payload,
     #     arguments: { 'filter' => arg },   # custom arguments
     #   )
     def self.trigger(object, arguments: {}, scope: nil)
 
-      return if Setting.get('import_mode')
+      return if Setting.get('import_mode') || Zammad::SafeMode.enabled?
+      return if ENV['ENABLE_EXPERIMENTAL_MOBILE_FRONTEND'] != 'true'
 
       ::Gql::ZammadSchema.subscriptions.trigger(
         graphql_field_name,

+ 0 - 15
app/graphql/gql/zammad_schema.rb

@@ -103,18 +103,3 @@ class Gql::ZammadSchema < GraphQL::Schema
     raise GraphQL::ExecutionError.new(err.message, extensions: extensions)
   end
 end
-
-# Temporary Hack: only process trigger events if ActionCable is enabled.
-# TODO: Remove when this switch is not needed any more.
-module GraphQL
-  class Subscriptions # rubocop:disable GraphQL/ObjectDescription, GraphQL/MaxComplexitySchema, GraphQL/MaxDepthSchema
-    if !method_defined?(:orig_trigger)
-      alias orig_trigger trigger
-      def trigger(...)
-        return if ENV['ENABLE_EXPERIMENTAL_MOBILE_FRONTEND'] != 'true'
-
-        orig_trigger(...)
-      end
-    end
-  end
-end

+ 6 - 2
config/application.rb

@@ -4,6 +4,7 @@ require_relative 'boot'
 
 require 'rails/all'
 require_relative 'issue_2656_workaround_for_rails_issue_33600'
+require_relative '../lib/zammad/safe_mode'
 
 # Temporary Hack: skip vite build if ENABLE_EXPERIMENTAL_MOBILE_FRONTEND is not set.
 # This must be called before ViteRuby is loaded by Bundler.
@@ -32,6 +33,8 @@ if ArgvHelper.argv.any? { |e| e.start_with? 'assets:' } || Rails.groups.exclude?
   end
 end
 
+Zammad::SafeMode.hint
+
 module Zammad
   class Application < Rails::Application
     # Initialize configuration defaults for originally generated Rails version.
@@ -74,7 +77,7 @@ module Zammad
     config.api_path = '/api/v1'
 
     # define cache store
-    if ENV['MEMCACHE_SERVERS'].present?
+    if ENV['MEMCACHE_SERVERS'].present? && !Zammad::SafeMode.enabled?
       require 'dalli' # Only load this gem when it is really used.
       config.cache_store = [:mem_cache_store, ENV['MEMCACHE_SERVERS'], { expires_in: 7.days }]
     else
@@ -84,7 +87,8 @@ module Zammad
     # define websocket session store
     # The web socket session store will fall back to localhost Redis usage if REDIS_URL is not set.
     # In this case, or if forced via ZAMMAD_WEBSOCKET_SESSION_STORE_FORCE_FS_BACKEND, the FS back end will be used.
-    config.websocket_session_store = ENV['REDIS_URL'].present? && ENV['ZAMMAD_WEBSOCKET_SESSION_STORE_FORCE_FS_BACKEND'].blank? ? :redis : :file
+    legacy_ws_use_redis = ENV['REDIS_URL'].present? && ENV['ZAMMAD_WEBSOCKET_SESSION_STORE_FORCE_FS_BACKEND'].blank? && !Zammad::SafeMode.enabled?
+    config.websocket_session_store = legacy_ws_use_redis ? :redis : :file
 
     # default preferences by permission
     config.preferences_default_by_permission = {

+ 2 - 1
config/initializers/action_cable_preferences.rb

@@ -7,6 +7,7 @@ if ENV['ENABLE_EXPERIMENTAL_MOBILE_FRONTEND'] == 'true'
   # If REDIS_URL is not set, fall back to default port / localhost, to ease configuration
   #   for simple installations.
   redis_url = ENV['REDIS_URL'].presence || 'redis://localhost:6379'
+
   Rails.application.config.action_cable.cable = {
     adapter:        :redis,
     driver:         :hiredis,
@@ -24,7 +25,7 @@ if ENV['ENABLE_EXPERIMENTAL_MOBILE_FRONTEND'] == 'true'
       warn 'Please provide a Redis instance at localhost:6379 or set REDIS_URL to point to a different location.'
     end
     warn e.inspect
-    exit! # rubocop:disable Rails/Exit
+    Zammad::SafeMode.continue_or_exit!
   end
 
   if Rails.env.production?

+ 22 - 0
lib/zammad/safe_mode.rb

@@ -0,0 +1,22 @@
+# Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
+
+module Zammad
+  module SafeMode
+    def self.enabled?
+      %w[1 true].include?(ENV['ZAMMAD_SAFE_MODE']) && !Rails.const_defined?(:Server)
+    end
+
+    def self.continue_or_exit!
+      return if enabled?
+
+      exit! # rubocop:disable Rails/Exit
+    end
+
+    def self.hint
+      return if !enabled?
+
+      warn 'Zammad is running in safe mode. Any third-party services like Redis are ignored.'
+      warn ''
+    end
+  end
+end