diff options
Diffstat (limited to 'config')
62 files changed, 600 insertions, 891 deletions
diff --git a/config/application.rb b/config/application.rb index edf8b3e87f9..294ed470298 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,8 +1,14 @@ -require File.expand_path('boot', __dir__) +require_relative 'boot' -require 'rails/all' +# Based on https://github.com/rails/rails/blob/v5.2.3/railties/lib/rails/all.rb +# Only load the railties we need instead of loading everything +require 'active_record/railtie' +require 'action_controller/railtie' +require 'action_view/railtie' +require 'action_mailer/railtie' +require 'rails/test_unit/railtie' -Bundler.require(:default, Rails.env) +Bundler.require(*Rails.groups) module Gitlab class Application < Rails::Application @@ -16,15 +22,12 @@ module Gitlab require_dependency Rails.root.join('lib/gitlab/middleware/read_only') require_dependency Rails.root.join('lib/gitlab/middleware/basic_health_check') - # This needs to be loaded before DB connection is made - # to make sure that all connections have NO_ZERO_DATE - # setting disabled - require_dependency Rails.root.join('lib/mysql_zero_date') - # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. + config.active_record.sqlite3.represent_boolean_as_integer = true + # Sidekiq uses eager loading, but directories not in the standard Rails # directories must be added to the eager load paths: # https://github.com/mperham/sidekiq/wiki/FAQ#why-doesnt-sidekiq-autoload-my-rails-application-code @@ -38,11 +41,6 @@ module Gitlab #{config.root}/app/models/hooks #{config.root}/app/models/members #{config.root}/app/models/project_services - #{config.root}/app/workers/concerns - #{config.root}/app/policies/concerns - #{config.root}/app/services/concerns - #{config.root}/app/serializers/concerns - #{config.root}/app/finders/concerns #{config.root}/app/graphql/resolvers/concerns #{config.root}/app/graphql/mutations/concerns]) @@ -86,13 +84,6 @@ module Gitlab # Configure the default encoding used in templates for Ruby 1.9. config.encoding = "utf-8" - # ActionCable mount point. - # The default Rails' mount point is `/cable` which may conflict with existing - # namespaces/users. - # https://github.com/rails/rails/blob/5-0-stable/actioncable/lib/action_cable.rb#L38 - # Please change this value when configuring ActionCable for real usage. - config.action_cable.mount_path = "/-/cable" - # Configure sensitive parameters which will be filtered from the log file. # # Parameters filtered: @@ -109,10 +100,23 @@ module Gitlab # - Sentry DSN (:sentry_dsn) # - File content from Web Editor (:content) # - Jira shared secret (:sharedSecret) + # - Titles, bodies, and descriptions for notes, issues, etc. # - # NOTE: It is **IMPORTANT** to also update gitlab-workhorse's filter when adding parameters here to not - # introduce another security vulnerability: https://gitlab.com/gitlab-org/gitlab-workhorse/issues/182 - config.filter_parameters += [/token$/, /password/, /secret/, /key$/, /^note$/, /^text$/] + # NOTE: It is **IMPORTANT** to also update labkit's filter when + # adding parameters here to not introduce another security + # vulnerability: + # https://gitlab.com/gitlab-org/labkit/blob/master/mask/matchers.go + config.filter_parameters += [ + /token$/, + /password/, + /secret/, + /key$/, + /^body$/, + /^description$/, + /^note$/, + /^text$/, + /^title$/ + ] config.filter_parameters += %i( certificate encrypted_key @@ -167,7 +171,6 @@ module Gitlab # Import gitlab-svgs directly from vendored directory config.assets.paths << "#{config.root}/node_modules/@gitlab/svgs/dist" - config.assets.paths << "#{config.root}/node_modules" config.assets.precompile << "icons.svg" config.assets.precompile << "icons.json" config.assets.precompile << "illustrations/*.svg" @@ -182,9 +185,19 @@ module Gitlab config.assets.precompile << "pages/jira_connect.css" end + # Import path for EE specific SCSS entry point + # In CE it will import a noop file, in EE a functioning file + # Order is important, so that the ee file takes precedence: + config.assets.paths << "#{config.root}/ee/app/assets/stylesheets/_ee" + config.assets.paths << "#{config.root}/app/assets/stylesheets/_ee" + config.assets.paths << "#{config.root}/vendor/assets/javascripts/" config.assets.precompile << "snowplow/sp.js" + # This path must come last to avoid confusing sprockets + # See https://gitlab.com/gitlab-org/gitlab-ce/issues/64091#note_194512508 + config.assets.paths << "#{config.root}/node_modules" + # Compile non-JS/CSS assets in the ee/app/assets folder by default # Mimic sprockets-rails default: https://github.com/rails/sprockets-rails/blob/v3.2.1/lib/sprockets/railtie.rb#L84-L87 LOOSE_EE_APP_ASSETS = lambda do |logical_path, filename| diff --git a/config/boot.rb b/config/boot.rb index b76b26a5e75..da4e6b7290c 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -2,8 +2,4 @@ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) # Set up gems listed in the Gemfile. require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) -begin - require 'bootsnap/setup' unless ENV['DISABLE_BOOTSNAP'] -rescue LoadError - # bootsnap is an optional dependency, so if we don't have it, it's fine -end +require 'bootsnap/setup' if ENV['RAILS_ENV'] != 'production' || %w(1 yes true).include?(ENV['ENABLE_BOOTSNAP']) diff --git a/config/database.yml.mysql b/config/database.yml.mysql deleted file mode 100644 index 98c2abe9f5e..00000000000 --- a/config/database.yml.mysql +++ /dev/null @@ -1,60 +0,0 @@ -# -# PRODUCTION -# -production: - adapter: mysql2 - encoding: utf8 - collation: utf8_general_ci - reconnect: false - database: gitlabhq_production - pool: 10 - username: git - password: "secure password" - host: localhost - # socket: /tmp/mysql.sock - -# -# Development specific -# -development: - adapter: mysql2 - encoding: utf8 - collation: utf8_general_ci - reconnect: false - database: gitlabhq_development - pool: 5 - username: root - password: "secure password" - host: localhost - # socket: /tmp/mysql.sock - -# -# Staging specific -# -staging: - adapter: mysql2 - encoding: utf8 - collation: utf8_general_ci - reconnect: false - database: gitlabhq_staging - pool: 10 - username: git - password: "secure password" - host: localhost - # socket: /tmp/mysql.sock - -# Warning: The database defined as "test" will be erased and -# re-generated from your development database when you run "rake". -# Do not set this db to the same as development or production. -test: &test - adapter: mysql2 - encoding: utf8mb4 - collation: utf8mb4_general_ci - reconnect: false - database: gitlabhq_test - pool: 5 - username: root - password: - host: localhost - # socket: /tmp/mysql.sock - prepared_statements: false diff --git a/config/environments/development.rb b/config/environments/development.rb index ac9b02b08d5..3881f1be152 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -7,6 +7,7 @@ Rails.application.configure do config.cache_classes = false # Show full error reports and disable caching + config.active_record.verbose_query_logs = true config.consider_all_requests_local = true config.action_controller.perform_caching = false diff --git a/config/environments/test.rb b/config/environments/test.rb index e7166882eea..153d16e4e55 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -23,6 +23,7 @@ Rails.application.configure do config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' } # Show full error reports and disable caching + config.active_record.verbose_query_logs = true config.consider_all_requests_local = true config.action_controller.perform_caching = false @@ -40,7 +41,7 @@ Rails.application.configure do # Print deprecation notices to the stderr config.active_support.deprecation = :stderr - config.eager_load = false + config.eager_load = true config.cache_store = :null_store diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 334c241bcaa..20b1020e025 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -47,6 +47,29 @@ production: &base # # relative_url_root: /gitlab + # Content Security Policy + # See https://guides.rubyonrails.org/security.html#content-security-policy + content_security_policy: + enabled: true + report_only: false + directives: + base_uri: + child_src: + connect_src: "'self' http://localhost:* ws://localhost:* wss://localhost:*" + default_src: "'self'" + font_src: + form_action: + frame_ancestors: "'self'" + frame_src: "'self' https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://content.googleapis.com https://content-compute.googleapis.com https://content-cloudbilling.googleapis.com https://content-cloudresourcemanager.googleapis.com" + img_src: "* data: blob:" + manifest_src: + media_src: + object_src: "'none'" + script_src: "'self' 'unsafe-eval' http://localhost:* https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://www.gstatic.com/recaptcha/ https://apis.google.com" + style_src: "'self' 'unsafe-inline'" + worker_src: "'self' blob:" + report_uri: + # Trusted Proxies # Customize if you have GitLab behind a reverse proxy which is running on a different machine. # Add the IP address for your reverse proxy to the list, otherwise users will appear signed in from that address. @@ -72,6 +95,15 @@ production: &base email_display_name: GitLab email_reply_to: noreply@example.com email_subject_suffix: '' + email_smime: + # Uncomment and set to true if you need to enable email S/MIME signing (default: false) + # enabled: false + # S/MIME private key file in PEM format, unencrypted + # Default is '.gitlab_smime_key' relative to Rails.root (i.e. root of the GitLab app). + # key_file: /home/git/gitlab/.gitlab_smime_key + # S/MIME public certificate key in PEM format, will be attached to signed messages + # Default is '.gitlab_smime_cert' relative to Rails.root (i.e. root of the GitLab app). + # cert_file: /home/git/gitlab/.gitlab_smime_cert # Email server smtp settings are in config/initializers/smtp_settings.rb.sample @@ -400,6 +432,15 @@ production: &base # path: shared/registry # issuer: gitlab-issuer + # Add notification settings if you plan to use Geo Replication for the registry + # notifications: + # - name: geo_event + # url: https://example.com/api/v4/container_registry_event/events + # timeout: 2s + # threshold: 5 + # backoff: 1s + # headers: + # Authorization: secret_phrase ## Error Reporting and Logging with Sentry sentry: @@ -418,6 +459,11 @@ production: &base # If it is blank, it defaults to external_url. node_name: '' + registry_replication: + # enabled: true + # primary_api_url: http://localhost:5000/ # internal address to the primary registry, will be used by GitLab to directly communicate with primary registry API + + # # 2. GitLab CI settings # ========================== @@ -734,6 +780,14 @@ production: &base # (default: []) external_providers: [] + # CAUTION! + # This allows users to login with the specified providers without two factor. Define the allowed providers + # using an array, e.g. ["twitter", 'google_oauth2'], or as true/false to allow all providers or none. + # This option should only be configured for providers which already have two factor. + # This configration dose not apply to SAML. + # (default: false) + allow_bypass_two_factor: ["twitter", 'google_oauth2'] + ## Auth providers # Uncomment the following lines and fill in the data of the auth provider you want to use # If your favorite auth provider is not listed you can use others: @@ -952,6 +1006,16 @@ production: &base # address: localhost # port: 3807 + ## Prometheus settings + # Do not modify these settings here. They should be modified in /etc/gitlab/gitlab.rb + # if you installed GitLab via Omnibus. + # If you installed from source, you need to install and configure Prometheus + # yourself, and then update the values here. + # https://docs.gitlab.com/ee/administration/monitoring/prometheus/ + prometheus: + # enable: true + # listen_address: 'localhost:9090' + # # 5. Extra customization # ========================== @@ -1043,6 +1107,27 @@ test: host: localhost port: 80 + content_security_policy: + enabled: true + report_only: false + directives: + base_uri: + child_src: + connect_src: + default_src: "'self'" + font_src: + form_action: + frame_ancestors: "'self'" + frame_src: "'self' https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://content.googleapis.com https://content-compute.googleapis.com https://content-cloudbilling.googleapis.com https://content-cloudresourcemanager.googleapis.com" + img_src: "* data: blob:" + manifest_src: + media_src: + object_src: "'none'" + script_src: "'self' 'unsafe-eval' http://localhost:* https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://www.gstatic.com/recaptcha/ https://apis.google.com" + style_src: "'self' 'unsafe-inline'" + worker_src: "'self' blob:" + report_uri: + # When you run tests we clone and set up gitlab-shell # In order to set it up correctly you need to specify # your system username you use to run GitLab @@ -1158,6 +1243,9 @@ test: user_filter: '' group_base: 'ou=groups,dc=example,dc=com' admin_group: '' + prometheus: + enable: true + listen_address: 'localhost:9090' staging: <<: *base diff --git a/config/initializers/0_inflections.rb b/config/initializers/0_inflections.rb index 4d1f4917275..d317825c1b8 100644 --- a/config/initializers/0_inflections.rb +++ b/config/initializers/0_inflections.rb @@ -19,6 +19,7 @@ ActiveSupport::Inflector.inflections do |inflect| project_registry file_registry job_artifact_registry + container_repository_registry vulnerability_feedback vulnerabilities_feedback group_view diff --git a/config/initializers/0_inject_enterprise_edition_module.rb b/config/initializers/0_inject_enterprise_edition_module.rb new file mode 100644 index 00000000000..b3ebb44ef25 --- /dev/null +++ b/config/initializers/0_inject_enterprise_edition_module.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'active_support/inflector' + +module InjectEnterpriseEditionModule + def prepend_if_ee(constant, with_descendants: false) + return unless Gitlab.ee? + + ee_module = constant.constantize + prepend(ee_module) + + if with_descendants + descendants.each { |descendant| descendant.prepend(ee_module) } + end + end + + def extend_if_ee(constant) + extend(constant.constantize) if Gitlab.ee? + end + + def include_if_ee(constant) + include(constant.constantize) if Gitlab.ee? + end +end + +Module.prepend(InjectEnterpriseEditionModule) diff --git a/config/initializers/0_license.rb b/config/initializers/0_license.rb index f750022dfdf..19c71c34904 100644 --- a/config/initializers/0_license.rb +++ b/config/initializers/0_license.rb @@ -10,7 +10,7 @@ Gitlab.ee do end # Needed to run migration - if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.data_source_exists?('licenses') + if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.table_exists?('licenses') message = LicenseHelper.license_message(signed_in: true, is_admin: true, in_html: false) if ::License.block_changes? && message.present? warn "WARNING: #{message}" diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 0b8a6607250..81433b620bc 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -1,5 +1,6 @@ require_relative '../settings' require_relative '../object_store_settings' +require_relative '../smime_signature_settings' # Default settings Settings['ldap'] ||= Settingslogic.new({}) @@ -55,7 +56,7 @@ if Settings.ldap['enabled'] || Rails.env.test? server['tls_options'] ||= {} if server['ssl_version'] || server['ca_file'] - Rails.logger.warn 'DEPRECATED: LDAP options `ssl_version` and `ca_file` should be nested within `tls_options`' + Rails.logger.warn 'DEPRECATED: LDAP options `ssl_version` and `ca_file` should be nested within `tls_options`' # rubocop:disable Gitlab/RailsLogger end if server['ssl_version'] @@ -83,6 +84,7 @@ Settings['omniauth'] ||= Settingslogic.new({}) Settings.omniauth['enabled'] = true if Settings.omniauth['enabled'].nil? Settings.omniauth['auto_sign_in_with_provider'] = false if Settings.omniauth['auto_sign_in_with_provider'].nil? Settings.omniauth['allow_single_sign_on'] = false if Settings.omniauth['allow_single_sign_on'].nil? +Settings.omniauth['allow_bypass_two_factor'] = false if Settings.omniauth['allow_bypass_two_factor'].nil? Settings.omniauth['external_providers'] = [] if Settings.omniauth['external_providers'].nil? Settings.omniauth['block_auto_created_users'] = true if Settings.omniauth['block_auto_created_users'].nil? Settings.omniauth['auto_link_ldap_user'] = false if Settings.omniauth['auto_link_ldap_user'].nil? @@ -171,6 +173,7 @@ Settings.gitlab['email_from'] ||= ENV['GITLAB_EMAIL_FROM'] || "gitlab@#{Settings Settings.gitlab['email_display_name'] ||= ENV['GITLAB_EMAIL_DISPLAY_NAME'] || 'GitLab' Settings.gitlab['email_reply_to'] ||= ENV['GITLAB_EMAIL_REPLY_TO'] || "noreply@#{Settings.gitlab.host}" Settings.gitlab['email_subject_suffix'] ||= ENV['GITLAB_EMAIL_SUBJECT_SUFFIX'] || "" +Settings.gitlab['email_smime'] = SmimeSignatureSettings.parse(Settings.gitlab['email_smime']) Settings.gitlab['base_url'] ||= Settings.__send__(:build_base_gitlab_url) Settings.gitlab['url'] ||= Settings.__send__(:build_gitlab_url) Settings.gitlab['user'] ||= 'git' @@ -200,6 +203,7 @@ Settings.gitlab.default_projects_features['visibility_level'] = Settings.__sen Settings.gitlab['domain_whitelist'] ||= [] Settings.gitlab['import_sources'] ||= Gitlab::ImportSources.values Settings.gitlab['trusted_proxies'] ||= [] +Settings.gitlab['content_security_policy'] ||= Gitlab::ContentSecurityPolicy::ConfigLoader.default_settings_hash Settings.gitlab['no_todos_messages'] ||= YAML.load_file(Rails.root.join('config', 'no_todos_messages.yml')) Settings.gitlab['impersonation_enabled'] ||= true if Settings.gitlab['impersonation_enabled'].nil? Settings.gitlab['usage_ping_enabled'] = true if Settings.gitlab['usage_ping_enabled'].nil? @@ -217,6 +221,7 @@ Gitlab.ee do Settings['elasticsearch'] ||= Settingslogic.new({}) Settings.elasticsearch['enabled'] = false if Settings.elasticsearch['enabled'].nil? Settings.elasticsearch['url'] = ENV['ELASTIC_URL'] || "http://localhost:9200" + Settings.elasticsearch['indexer_path'] ||= Gitlab::Utils.which('gitlab-elasticsearch-indexer') end # @@ -258,6 +263,7 @@ Settings.registry['key'] ||= nil Settings.registry['issuer'] ||= nil Settings.registry['host_port'] ||= [Settings.registry['host'], Settings.registry['port']].compact.join(':') Settings.registry['path'] = Settings.absolute(Settings.registry['path'] || File.join(Settings.shared['path'], 'registry')) +Settings.registry['notifications'] ||= [] # # Error Reporting and Logging with Sentry @@ -294,6 +300,12 @@ Gitlab.ee do Settings['geo'] ||= Settingslogic.new({}) # For backwards compatibility, default to gitlab_url and if so, ensure it ends with "/" Settings.geo['node_name'] = Settings.geo['node_name'].presence || Settings.gitlab['url'].chomp('/').concat('/') + + # + # Registry replication + # + Settings.geo['registry_replication'] ||= Settingslogic.new({}) + Settings.geo.registry_replication['enabled'] ||= false end # @@ -471,6 +483,9 @@ Gitlab.ee do Settings.cron_jobs['geo_repository_verification_secondary_scheduler_worker'] ||= Settingslogic.new({}) Settings.cron_jobs['geo_repository_verification_secondary_scheduler_worker']['cron'] ||= '*/1 * * * *' Settings.cron_jobs['geo_repository_verification_secondary_scheduler_worker']['job_class'] ||= 'Geo::RepositoryVerification::Secondary::SchedulerWorker' + Settings.cron_jobs['geo_container_repository_sync_worker'] ||= Settingslogic.new({}) + Settings.cron_jobs['geo_container_repository_sync_worker']['cron'] ||= '*/1 * * * *' + Settings.cron_jobs['geo_container_repository_sync_worker']['job_class'] ||= 'Geo::ContainerRepositorySyncDispatchWorker' Settings.cron_jobs['historical_data_worker'] ||= Settingslogic.new({}) Settings.cron_jobs['historical_data_worker']['cron'] ||= '0 12 * * *' Settings.cron_jobs['historical_data_worker']['job_class'] = 'HistoricalDataWorker' diff --git a/config/initializers/7_prometheus_metrics.rb b/config/initializers/7_prometheus_metrics.rb index 741c8ef1ca0..143b34b5368 100644 --- a/config/initializers/7_prometheus_metrics.rb +++ b/config/initializers/7_prometheus_metrics.rb @@ -1,5 +1,4 @@ require 'prometheus/client' -require 'prometheus/client/support/unicorn' # Keep separate directories for separate processes def prometheus_default_multiproc_dir @@ -17,13 +16,13 @@ def prometheus_default_multiproc_dir end Prometheus::Client.configure do |config| - config.logger = Rails.logger + config.logger = Rails.logger # rubocop:disable Gitlab/RailsLogger config.initial_mmap_file_size = 4 * 1024 config.multiprocess_files_dir = ENV['prometheus_multiproc_dir'] || prometheus_default_multiproc_dir - config.pid_provider = Prometheus::Client::Support::Unicorn.method(:worker_pid_provider) + config.pid_provider = Prometheus::PidProvider.method(:worker_id) end Gitlab::Application.configure do |config| @@ -33,6 +32,9 @@ end Sidekiq.configure_server do |config| config.on(:startup) do + # webserver metrics are cleaned up in config.ru: `warmup` block + Prometheus::CleanupMultiprocDirService.new.execute + Gitlab::Metrics::SidekiqMetricsExporter.instance.start end end @@ -52,22 +54,3 @@ if !Rails.env.test? && Gitlab::Metrics.prometheus_metrics_enabled? end end end - -def cleanup_prometheus_multiproc_dir - # The following is necessary to ensure stale Prometheus metrics don't - # accumulate over time. It needs to be done in this hook as opposed to - # inside an init script to ensure metrics files aren't deleted after new - # unicorn workers start after a SIGUSR2 is received. - if dir = ::Prometheus::Client.configuration.multiprocess_files_dir - old_metrics = Dir[File.join(dir, '*.db')] - FileUtils.rm_rf(old_metrics) - end -end - -Gitlab::Cluster::LifecycleEvents.on_master_start do - cleanup_prometheus_multiproc_dir -end - -Gitlab::Cluster::LifecycleEvents.on_master_restart do - cleanup_prometheus_multiproc_dir -end diff --git a/config/initializers/8_devise.rb b/config/initializers/8_devise.rb index 3dd12c7e64d..8ef9ff6b7fc 100644 --- a/config/initializers/8_devise.rb +++ b/config/initializers/8_devise.rb @@ -81,7 +81,7 @@ Devise.setup do |config| # You can use this to let your user access some features of your application # without confirming the account, but blocking it after a certain period # (ie 2 days). - # config.allow_unconfirmed_access_for = 2.days + config.allow_unconfirmed_access_for = 30.days # Defines which key will be used when confirming an account # config.confirmation_keys = [ :email ] diff --git a/config/initializers/action_mailer_hooks.rb b/config/initializers/action_mailer_hooks.rb index f1b3c1f8ae8..02ca6ef13bf 100644 --- a/config/initializers/action_mailer_hooks.rb +++ b/config/initializers/action_mailer_hooks.rb @@ -10,3 +10,8 @@ ActionMailer::Base.register_interceptors( ) ActionMailer::Base.register_observer(::Gitlab::Email::Hook::DeliveryMetricsObserver) + +if Gitlab.config.gitlab.email_enabled && Gitlab.config.gitlab.email_smime.enabled + ActionMailer::Base.register_interceptor(::Gitlab::Email::Hook::SmimeSignatureInterceptor) + Gitlab::AppLogger.debug "S/MIME signing of outgoing emails enabled" +end diff --git a/config/initializers/active_record_data_types.rb b/config/initializers/active_record_data_types.rb index e95157bfde5..846f28e6f66 100644 --- a/config/initializers/active_record_data_types.rb +++ b/config/initializers/active_record_data_types.rb @@ -1,83 +1,45 @@ # ActiveRecord custom data type for storing datetimes with timezone information. # See https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/11229 -if Gitlab::Database.postgresql? - require 'active_record/connection_adapters/postgresql_adapter' +require 'active_record/connection_adapters/postgresql_adapter' - module ActiveRecord::ConnectionAdapters::PostgreSQL::OID - # Add the class `DateTimeWithTimeZone` so we can map `timestamptz` to it. - class DateTimeWithTimeZone < DateTime - def type - :datetime_with_timezone - end +module ActiveRecord::ConnectionAdapters::PostgreSQL::OID + # Add the class `DateTimeWithTimeZone` so we can map `timestamptz` to it. + class DateTimeWithTimeZone < DateTime + def type + :datetime_with_timezone end end +end - module RegisterDateTimeWithTimeZone - # Run original `initialize_type_map` and then register `timestamptz` as a - # `DateTimeWithTimeZone`. - # - # Apparently it does not matter that the original `initialize_type_map` - # aliases `timestamptz` to `timestamp`. - # - # When schema dumping, `timestamptz` columns will be output as - # `t.datetime_with_timezone`. - def initialize_type_map(mapping) - super mapping - - mapping.register_type 'timestamptz' do |_, _, sql_type| - precision = extract_precision(sql_type) - ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID::DateTimeWithTimeZone.new(precision: precision) - end - end - end - - class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter - prepend RegisterDateTimeWithTimeZone - - # Add column type `datetime_with_timezone` so we can do this in - # migrations: - # - # add_column(:users, :datetime_with_timezone) - # - NATIVE_DATABASE_TYPES[:datetime_with_timezone] = { name: 'timestamptz' } - end -elsif Gitlab::Database.mysql? - require 'active_record/connection_adapters/mysql2_adapter' - - module RegisterDateTimeWithTimeZone - # Run original `initialize_type_map` and then register `timestamp` as a - # `MysqlDateTimeWithTimeZone`. - # - # When schema dumping, `timestamp` columns will be output as - # `t.datetime_with_timezone`. - def initialize_type_map(mapping) - super mapping - - mapping.register_type(/timestamp/i) do |sql_type| - precision = extract_precision(sql_type) - ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::MysqlDateTimeWithTimeZone.new(precision: precision) - end +module RegisterDateTimeWithTimeZone + # Run original `initialize_type_map` and then register `timestamptz` as a + # `DateTimeWithTimeZone`. + # + # Apparently it does not matter that the original `initialize_type_map` + # aliases `timestamptz` to `timestamp`. + # + # When schema dumping, `timestamptz` columns will be output as + # `t.datetime_with_timezone`. + def initialize_type_map(mapping = type_map) + super mapping + + mapping.register_type 'timestamptz' do |_, _, sql_type| + precision = extract_precision(sql_type) + ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID::DateTimeWithTimeZone.new(precision: precision) end end +end - class ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter - prepend RegisterDateTimeWithTimeZone - - # Add the class `DateTimeWithTimeZone` so we can map `timestamp` to it. - class MysqlDateTimeWithTimeZone < ActiveRecord::Type::DateTime - def type - :datetime_with_timezone - end - end +class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter + prepend RegisterDateTimeWithTimeZone - # Add column type `datetime_with_timezone` so we can do this in - # migrations: - # - # add_column(:users, :datetime_with_timezone) - # - NATIVE_DATABASE_TYPES[:datetime_with_timezone] = { name: 'timestamp' } - end + # Add column type `datetime_with_timezone` so we can do this in + # migrations: + # + # add_column(:users, :datetime_with_timezone) + # + NATIVE_DATABASE_TYPES[:datetime_with_timezone] = { name: 'timestamptz' } end # Ensure `datetime_with_timezone` columns are correctly written to schema.rb diff --git a/config/initializers/active_record_lifecycle.rb b/config/initializers/active_record_lifecycle.rb index 7fa37121efc..61f1d299960 100644 --- a/config/initializers/active_record_lifecycle.rb +++ b/config/initializers/active_record_lifecycle.rb @@ -7,7 +7,7 @@ if defined?(ActiveRecord::Base) && !Sidekiq.server? ActiveSupport.on_load(:active_record) do ActiveRecord::Base.establish_connection - Rails.logger.debug("ActiveRecord connection established") + Rails.logger.debug("ActiveRecord connection established") # rubocop:disable Gitlab/RailsLogger end end end @@ -18,6 +18,6 @@ if defined?(ActiveRecord::Base) # as there's no need for the master process to hold a connection ActiveRecord::Base.connection.disconnect! - Rails.logger.debug("ActiveRecord connection disconnected") + Rails.logger.debug("ActiveRecord connection disconnected") # rubocop:disable Gitlab/RailsLogger end end diff --git a/config/initializers/active_record_migration.rb b/config/initializers/active_record_migration.rb deleted file mode 100644 index 04c06be7834..00000000000 --- a/config/initializers/active_record_migration.rb +++ /dev/null @@ -1,10 +0,0 @@ -require 'active_record/migration' - -module ActiveRecord - class Migration - # data_source_exists? is not available in 4.2.10, table_exists deprecated in 5.0 - def table_exists?(table_name) - ActiveRecord::Base.connection.data_source_exists?(table_name) - end - end -end diff --git a/config/initializers/active_record_mysql_timestamp.rb b/config/initializers/active_record_mysql_timestamp.rb deleted file mode 100644 index af74c4ff6fb..00000000000 --- a/config/initializers/active_record_mysql_timestamp.rb +++ /dev/null @@ -1,30 +0,0 @@ -# Make sure that MySQL won't try to use CURRENT_TIMESTAMP when the timestamp -# column is NOT NULL. See https://gitlab.com/gitlab-org/gitlab-ce/issues/36405 -# And also: https://bugs.mysql.com/bug.php?id=75098 -# This patch was based on: -# https://github.com/rails/rails/blob/15ef55efb591e5379486ccf53dd3e13f416564f6/activerecord/lib/active_record/connection_adapters/mysql/schema_creation.rb#L34-L36 - -if Gitlab::Database.mysql? - require 'active_record/connection_adapters/abstract/schema_creation' - - module MySQLTimestampFix - def add_column_options!(sql, options) - # By default, TIMESTAMP columns are NOT NULL, cannot contain NULL values, - # and assigning NULL assigns the current timestamp. To permit a TIMESTAMP - # column to contain NULL, explicitly declare it with the NULL attribute. - # See http://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html - if sql.end_with?('timestamp') && !options[:primary_key] - if options[:null] != false - sql << ' NULL' - elsif options[:column].default.nil? - sql << ' DEFAULT 0' - end - end - - super - end - end - - ActiveRecord::ConnectionAdapters::AbstractAdapter::SchemaCreation - .prepend(MySQLTimestampFix) -end diff --git a/config/initializers/active_record_preloader.rb b/config/initializers/active_record_preloader.rb index 3b16014f302..a293909149e 100644 --- a/config/initializers/active_record_preloader.rb +++ b/config/initializers/active_record_preloader.rb @@ -1,9 +1,22 @@ module ActiveRecord module Associations class Preloader + class NullPreloader + def self.new(klass, owners, reflection, preload_scope) + self + end + + def self.run(preloader) + end + + def self.preloaded_records + [] + end + end + module NoCommitPreloader - def preloader_for(reflection, owners, rhs_klass) - return NullPreloader if rhs_klass == ::Commit + def preloader_for(reflection, owners) + return NullPreloader if owners.first.association(reflection.name).klass == ::Commit super end diff --git a/config/initializers/active_record_query_cache.rb b/config/initializers/active_record_query_cache.rb new file mode 100644 index 00000000000..61505a1edd3 --- /dev/null +++ b/config/initializers/active_record_query_cache.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +ActiveRecord::ConnectionAdapters::ConnectionPool.prepend Gitlab::Patch::ActiveRecordQueryCache diff --git a/config/initializers/active_record_verbose_query_logs.rb b/config/initializers/active_record_verbose_query_logs.rb deleted file mode 100644 index 1c5fbc8e830..00000000000 --- a/config/initializers/active_record_verbose_query_logs.rb +++ /dev/null @@ -1,56 +0,0 @@ -# frozen_string_literal: true - -# This is backport of https://github.com/rails/rails/pull/26815/files -# Enabled by default for every non-production environment - -module ActiveRecord - class LogSubscriber - module VerboseQueryLogs - def debug(progname = nil, &block) - return unless super - - log_query_source - end - - def log_query_source - source_line, line_number = extract_callstack(caller_locations) - - if source_line - if defined?(::Rails.root) - app_root = "#{::Rails.root}/".freeze - source_line = source_line.sub(app_root, "") - end - - logger.debug(" ↳ #{source_line}:#{line_number}") - end - end - - def extract_callstack(callstack) - line = callstack.find do |frame| - frame.absolute_path && !ignored_callstack(frame.absolute_path) - end - - offending_line = line || callstack.first - [ - offending_line.path, - offending_line.lineno, - offending_line.label - ] - end - - LOG_SUBSCRIBER_FILE = ActiveRecord::LogSubscriber.method(:logger).source_location.first - RAILS_GEM_ROOT = File.expand_path("../../../..", LOG_SUBSCRIBER_FILE) + "/" - APP_CONFIG_ROOT = File.expand_path("..", __dir__) + "/" - - def ignored_callstack(path) - path.start_with?(APP_CONFIG_ROOT, RAILS_GEM_ROOT, RbConfig::CONFIG["rubylibdir"]) - end - end - - if Rails.version.start_with?("5.2") - raise "Remove this monkey patch: #{__FILE__}" - else - prepend(VerboseQueryLogs) unless Rails.env.production? - end - end -end diff --git a/config/initializers/ar_mysql_jsonb_support.rb b/config/initializers/ar_mysql_jsonb_support.rb deleted file mode 100644 index 63a0b05119a..00000000000 --- a/config/initializers/ar_mysql_jsonb_support.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -require 'active_record/connection_adapters/abstract_mysql_adapter' -require 'active_record/connection_adapters/mysql/schema_definitions' - -# MySQL (5.6) and MariaDB (10.1) are currently supported versions within GitLab, -# Since they do not support native `json` datatype we force to emulate it as `text` - -if Gitlab::Database.mysql? - module ActiveRecord - module ConnectionAdapters - class AbstractMysqlAdapter - JSON_DATASIZE = 1.megabyte - - NATIVE_DATABASE_TYPES.merge!( - json: { name: "text", limit: JSON_DATASIZE }, - jsonb: { name: "text", limit: JSON_DATASIZE } - ) - end - - module MySQL - module ColumnMethods - # We add `jsonb` helper, as `json` is already defined for `MySQL` since Rails 5 - def jsonb(*args, **options) - args.each { |name| column(name, :json, options) } - end - end - end - end - end -end diff --git a/config/initializers/ar_native_database_types.rb b/config/initializers/ar_native_database_types.rb deleted file mode 100644 index 6d397661f75..00000000000 --- a/config/initializers/ar_native_database_types.rb +++ /dev/null @@ -1,12 +0,0 @@ -require 'active_record/connection_adapters/abstract_mysql_adapter' - -module ActiveRecord - module ConnectionAdapters - class AbstractMysqlAdapter - NATIVE_DATABASE_TYPES.merge!( - bigserial: { name: 'bigint(20) auto_increment PRIMARY KEY' }, - serial: { name: 'int auto_increment PRIMARY KEY' } - ) - end - end -end diff --git a/config/initializers/ar_speed_up_migration_checking.rb b/config/initializers/ar_speed_up_migration_checking.rb index f98b246db0b..c4ffcc54cb2 100644 --- a/config/initializers/ar_speed_up_migration_checking.rb +++ b/config/initializers/ar_speed_up_migration_checking.rb @@ -2,17 +2,14 @@ if Rails.env.test? require 'active_record/migration' module ActiveRecord - class Migrator - class << self - alias_method :migrations_unmemoized, :migrations + class MigrationContext + alias_method :migrations_unmemoized, :migrations - # This method is called a large number of times per rspec example, and - # it reads + parses `db/migrate/*` each time. Memoizing it can save 0.5 - # seconds per spec. - def migrations(paths) - @migrations ||= {} - (@migrations[paths] ||= migrations_unmemoized(paths)).dup - end + # This method is called a large number of times per rspec example, and + # it reads + parses `db/migrate/*` each time. Memoizing it can save 0.5 + # seconds per spec. + def migrations + @migrations ||= migrations_unmemoized end end end diff --git a/config/initializers/config_initializers_active_record_locking.rb b/config/initializers/config_initializers_active_record_locking.rb index 608d63223a3..915247826e9 100644 --- a/config/initializers/config_initializers_active_record_locking.rb +++ b/config/initializers/config_initializers_active_record_locking.rb @@ -22,10 +22,11 @@ module ActiveRecord # Patched because when `lock_version` is read as `0`, it may actually be `NULL` in the DB. possible_previous_lock_value = previous_lock_value.to_i == 0 ? [nil, 0] : previous_lock_value - affected_rows = self.class.unscoped._update_record( - arel_attributes_with_values(attribute_names), - self.class.primary_key => id_in_database, - locking_column => possible_previous_lock_value + affected_rows = self.class.unscoped.where( + locking_column => possible_previous_lock_value, + self.class.primary_key => id_in_database + ).update_all( + attributes_with_values_for_update(attribute_names) ) if affected_rows != 1 diff --git a/config/initializers/connection_fix.rb b/config/initializers/connection_fix.rb deleted file mode 100644 index d0b1444f607..00000000000 --- a/config/initializers/connection_fix.rb +++ /dev/null @@ -1,32 +0,0 @@ -# from http://gist.github.com/238999 -# -# If your workers are inactive for a long period of time, they'll lose -# their MySQL connection. -# -# This hack ensures we re-connect whenever a connection is -# lost. Because, really. why not? -# -# Stick this in RAILS_ROOT/config/initializers/connection_fix.rb (or somewhere similar) -# -# From: -# http://coderrr.wordpress.com/2009/01/08/activerecord-threading-issues-and-resolutions/ - -if defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter) - module ActiveRecord::ConnectionAdapters - class Mysql2Adapter - alias_method :execute_without_retry, :execute - - def execute(*args) - execute_without_retry(*args) - rescue ActiveRecord::StatementInvalid => e - if e.message =~ /server has gone away/i - warn "Lost connection to MySQL server during query" - reconnect! - retry - else - raise e - end - end - end - end -end diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb new file mode 100644 index 00000000000..608d0401a96 --- /dev/null +++ b/config/initializers/content_security_policy.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +csp_settings = Settings.gitlab.content_security_policy + +if csp_settings['enabled'] + # See https://guides.rubyonrails.org/security.html#content-security-policy + Rails.application.config.content_security_policy do |policy| + directives = csp_settings.fetch('directives', {}) + loader = ::Gitlab::ContentSecurityPolicy::ConfigLoader.new(directives) + loader.load(policy) + end + + Rails.application.config.content_security_policy_report_only = csp_settings['report_only'] + Rails.application.config.content_security_policy_nonce_generator = ->(request) { SecureRandom.base64(16) } +end diff --git a/config/initializers/deprecations.rb b/config/initializers/deprecations.rb index 14616e726d9..0d096e34eb7 100644 --- a/config/initializers/deprecations.rb +++ b/config/initializers/deprecations.rb @@ -2,7 +2,7 @@ if Rails.env.development? || ENV['GITLAB_LEGACY_PATH_LOG_MESSAGE'] deprecator = ActiveSupport::Deprecation.new('11.0', 'GitLab') deprecator.behavior = -> (message, callstack) { - Rails.logger.warn("#{message}: #{callstack[1..20].join}") + Rails.logger.warn("#{message}: #{callstack[1..20].join}") # rubocop:disable Gitlab/RailsLogger } ActiveSupport::Deprecation.deprecate_methods(Gitlab::GitalyClient::StorageSettings, :legacy_disk_path, deprecator: deprecator) diff --git a/config/initializers/elastic_client_setup.rb b/config/initializers/elastic_client_setup.rb index 2ecb7956007..a1abb29838b 100644 --- a/config/initializers/elastic_client_setup.rb +++ b/config/initializers/elastic_client_setup.rb @@ -5,46 +5,42 @@ require 'gitlab/current_settings' Gitlab.ee do + require 'elasticsearch/model' + + ### Modified from elasticsearch-model/lib/elasticsearch/model.rb + + [ + Elasticsearch::Model::Client::ClassMethods, + Elasticsearch::Model::Naming::ClassMethods, + Elasticsearch::Model::Indexing::ClassMethods, + Elasticsearch::Model::Searching::ClassMethods + ].each do |mod| + Elasticsearch::Model::Proxy::ClassMethodsProxy.include mod + end + + [ + Elasticsearch::Model::Client::InstanceMethods, + Elasticsearch::Model::Naming::InstanceMethods, + Elasticsearch::Model::Indexing::InstanceMethods, + Elasticsearch::Model::Serializing::InstanceMethods + ].each do |mod| + Elasticsearch::Model::Proxy::InstanceMethodsProxy.include mod + end + + Elasticsearch::Model::Proxy::InstanceMethodsProxy.class_eval <<-CODE, __FILE__, __LINE__ + 1 + def as_indexed_json(options={}) + target.respond_to?(:as_indexed_json) ? target.__send__(:as_indexed_json, options) : super + end + CODE + + ### Monkey patches + Elasticsearch::Model::Response::Records.prepend GemExtensions::Elasticsearch::Model::Response::Records Elasticsearch::Model::Adapter::Multiple::Records.prepend GemExtensions::Elasticsearch::Model::Adapter::Multiple::Records Elasticsearch::Model::Indexing::InstanceMethods.prepend GemExtensions::Elasticsearch::Model::Indexing::InstanceMethods - - module Elasticsearch - module Model - module Client - # This mutex is only used to synchronize *creation* of a new client, so - # all including classes can share the same client instance - CLIENT_MUTEX = Mutex.new - - cattr_accessor :cached_client - cattr_accessor :cached_config - - module ClassMethods - # Override the default ::Elasticsearch::Model::Client implementation to - # return a client configured from application settings. All including - # classes will use the same instance, which is refreshed automatically - # if the settings change. - # - # _client is present to match the arity of the overridden method, where - # it is also not used. - # - # @return [Elasticsearch::Transport::Client] - def client(_client = nil) - store = ::Elasticsearch::Model::Client - - store::CLIENT_MUTEX.synchronize do - config = Gitlab::CurrentSettings.elasticsearch_config - - if store.cached_client.nil? || config != store.cached_config - store.cached_client = ::Gitlab::Elastic::Client.build(config) - store.cached_config = config - end - end - - store.cached_client - end - end - end - end - end + Elasticsearch::Model::Adapter::ActiveRecord::Importing.prepend GemExtensions::Elasticsearch::Model::Adapter::ActiveRecord::Importing + Elasticsearch::Model::Client::InstanceMethods.prepend GemExtensions::Elasticsearch::Model::Client + Elasticsearch::Model::Client::ClassMethods.prepend GemExtensions::Elasticsearch::Model::Client + Elasticsearch::Model::ClassMethods.prepend GemExtensions::Elasticsearch::Model::Client + Elasticsearch::Model.singleton_class.prepend GemExtensions::Elasticsearch::Model::Client end diff --git a/config/initializers/httpclient_patch.rb b/config/initializers/httpclient_patch.rb new file mode 100644 index 00000000000..22cc5605d9b --- /dev/null +++ b/config/initializers/httpclient_patch.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# By default, httpclient (and hence anything that uses rack-oauth2) +# ignores the system-wide SSL certificate configuration in favor of its +# own cacert.pem. This makes it impossible to use custom certificates +# without patching that file. Until +# https://github.com/nahi/httpclient/pull/386 is merged, we work around +# this limitation by forcing the HTTPClient SSL store to use the default +# system configuration. +module HTTPClient::SSLConfigDefaultPaths + def initialize(client) + super + + set_default_paths + end +end + +HTTPClient::SSLConfig.prepend HTTPClient::SSLConfigDefaultPaths diff --git a/config/initializers/invisible_captcha.rb b/config/initializers/invisible_captcha.rb new file mode 100644 index 00000000000..5177c730596 --- /dev/null +++ b/config/initializers/invisible_captcha.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +InvisibleCaptcha.setup do |config| + config.honeypots = %w(firstname lastname) + config.timestamp_enabled = true + config.timestamp_threshold = 4 +end diff --git a/config/initializers/load_balancing.rb b/config/initializers/load_balancing.rb index 029c0ff4277..a49bcbe1f96 100644 --- a/config/initializers/load_balancing.rb +++ b/config/initializers/load_balancing.rb @@ -3,7 +3,7 @@ # We need to run this initializer after migrations are done so it doesn't fail on CI Gitlab.ee do - if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.data_source_exists?('licenses') + if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.table_exists?('licenses') if Gitlab::Database::LoadBalancing.enable? Gitlab::Database.disable_prepared_statements diff --git a/config/initializers/lograge.rb b/config/initializers/lograge.rb index 1ad93e14f7e..346725e4080 100644 --- a/config/initializers/lograge.rb +++ b/config/initializers/lograge.rb @@ -18,7 +18,7 @@ unless Sidekiq.server? .map { |k, v| { key: k, value: v } } payload = { - time: event.time.utc.iso8601(3), + time: Time.now.utc.iso8601(3), params: params, remote_ip: event.payload[:remote_ip], user_id: event.payload[:user_id], @@ -27,12 +27,7 @@ unless Sidekiq.server? queue_duration: event.payload[:queue_duration] } - gitaly_calls = Gitlab::GitalyClient.get_request_count - - if gitaly_calls > 0 - payload[:gitaly_calls] = gitaly_calls - payload[:gitaly_duration] = Gitlab::GitalyClient.query_time_ms - end + ::Gitlab::InstrumentationHelper.add_instrumentation_data(payload) payload[:response] = event.payload[:response] if event.payload[:response] payload[Labkit::Correlation::CorrelationId::LOG_KEY] = Labkit::Correlation::CorrelationId.current_id diff --git a/config/initializers/mysql_ignore_postgresql_options.rb b/config/initializers/mysql_ignore_postgresql_options.rb deleted file mode 100644 index 9a569be7674..00000000000 --- a/config/initializers/mysql_ignore_postgresql_options.rb +++ /dev/null @@ -1,49 +0,0 @@ -# This patches ActiveRecord so indexes created using the MySQL adapter ignore -# any PostgreSQL specific options (e.g. `using: :gin`). -# -# These patches do the following for MySQL: -# -# 1. Indexes created using the :opclasses option are ignored (as they serve no -# purpose on MySQL). -# 2. When creating an index with `using: :gin` the `using` option is discarded -# as :gin is not a valid value for MySQL. -# 3. The `:opclasses` option is stripped from add_index_options in case it's -# used anywhere other than in the add_index methods. - -if defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter) - module ActiveRecord - module ConnectionAdapters - class Mysql2Adapter < AbstractMysqlAdapter - alias_method :__gitlab_add_index, :add_index - alias_method :__gitlab_add_index_sql, :add_index_sql - alias_method :__gitlab_add_index_options, :add_index_options - - def add_index(table_name, column_name, options = {}) - unless options[:opclasses] - __gitlab_add_index(table_name, column_name, options) - end - end - - def add_index_sql(table_name, column_name, options = {}) - unless options[:opclasses] - __gitlab_add_index_sql(table_name, column_name, options) - end - end - - def add_index_options(table_name, column_name, options = {}) - if options[:using] && options[:using] == :gin - options = options.dup - options.delete(:using) - end - - if options[:opclasses] - options = options.dup - options.delete(:opclasses) - end - - __gitlab_add_index_options(table_name, column_name, options) - end - end - end - end -end diff --git a/config/initializers/mysql_set_length_for_binary_indexes.rb b/config/initializers/mysql_set_length_for_binary_indexes.rb deleted file mode 100644 index 552f3a20a95..00000000000 --- a/config/initializers/mysql_set_length_for_binary_indexes.rb +++ /dev/null @@ -1,30 +0,0 @@ -# This patches ActiveRecord so indexes for binary columns created using the -# MySQL adapter apply a length of 20. Otherwise MySQL can't create an index on -# binary columns. - -module MysqlSetLengthForBinaryIndexAndIgnorePostgresOptionsForSchema - # This method is used in Rails 5 schema loading as t.index - def index(column_names, options = {}) - # Ignore indexes that use opclasses, - # also see config/initializers/mysql_ignore_postgresql_options.rb - if options[:opclasses] - warn "WARNING: index on columns #{column_names} uses unsupported option, skipping." - return - end - - options[:length] ||= {} - Array(column_names).each do |column_name| - column = columns.find { |c| c.name == column_name } - - if column&.type == :binary - options[:length][column_name] = 20 - end - end - - super(column_names, options) - end -end - -if defined?(ActiveRecord::ConnectionAdapters::MySQL::TableDefinition) - ActiveRecord::ConnectionAdapters::MySQL::TableDefinition.send(:prepend, MysqlSetLengthForBinaryIndexAndIgnorePostgresOptionsForSchema) -end diff --git a/config/initializers/octokit.rb b/config/initializers/octokit.rb new file mode 100644 index 00000000000..b3749258ec5 --- /dev/null +++ b/config/initializers/octokit.rb @@ -0,0 +1 @@ +Octokit.middleware.insert_after Octokit::Middleware::FollowRedirects, Gitlab::Octokit::Middleware diff --git a/config/initializers/peek.rb b/config/initializers/peek.rb index d492b60705d..f9055285e5c 100644 --- a/config/initializers/peek.rb +++ b/config/initializers/peek.rb @@ -1,47 +1,13 @@ -Rails.application.config.peek.adapter = :redis, { client: ::Redis.new(Gitlab::Redis::Cache.params) } - -Peek.into Peek::Views::Host +require 'peek/adapters/redis' -if Gitlab::Database.mysql? - require 'peek-mysql2' - PEEK_DB_CLIENT = ::Mysql2::Client - PEEK_DB_VIEW = Peek::Views::Mysql2 -elsif Gitlab::Database.postgresql? - require 'peek-pg' - PEEK_DB_CLIENT = ::PG::Connection - PEEK_DB_VIEW = Peek::Views::PG +Peek::Adapters::Redis.prepend ::Gitlab::PerformanceBar::RedisAdapterWhenPeekEnabled - # Remove once we have https://github.com/peek/peek-pg/pull/10 - module ::Peek::PGInstrumented - def exec_params(*args) - start = Time.now - super(*args) - ensure - duration = (Time.now - start) - PEEK_DB_CLIENT.query_time.update { |value| value + duration } - PEEK_DB_CLIENT.query_count.update { |value| value + 1 } - end - end -else - raise "Unsupported database adapter for peek!" -end +Rails.application.config.peek.adapter = :redis, { client: ::Redis.new(Gitlab::Redis::Cache.params) } -Peek.into PEEK_DB_VIEW +Peek.into Peek::Views::Host +Peek.into Peek::Views::ActiveRecord Peek.into Peek::Views::Gitaly -Peek.into Peek::Views::Rblineprof -Peek.into Peek::Views::Redis -Peek.into Peek::Views::GC -Peek.into Peek::Views::Tracing if Labkit::Tracing.tracing_url_enabled? - -# rubocop:disable Naming/ClassAndModuleCamelCase -class PEEK_DB_CLIENT - class << self - attr_accessor :query_details - end - self.query_details = Concurrent::Array.new -end - -PEEK_DB_VIEW.prepend ::Gitlab::PerformanceBar::PeekQueryTracker +Peek.into Peek::Views::RedisDetailed +Peek.into Peek::Views::Rugged -require 'peek/adapters/redis' -Peek::Adapters::Redis.prepend ::Gitlab::PerformanceBar::RedisAdapterWhenPeekEnabled +Peek.into Peek::Views::Tracing if Labkit::Tracing.tracing_url_enabled? diff --git a/config/initializers/postgresql_cte.rb b/config/initializers/postgresql_cte.rb index 56689bc8e74..68d53c4edbf 100644 --- a/config/initializers/postgresql_cte.rb +++ b/config/initializers/postgresql_cte.rb @@ -94,8 +94,8 @@ module ActiveRecord end end - def build_arel - arel = super() + def build_arel(aliases) + arel = super build_with(arel) if @values[:with] diff --git a/config/initializers/postgresql_opclasses_support.rb b/config/initializers/postgresql_opclasses_support.rb deleted file mode 100644 index 7e912180820..00000000000 --- a/config/initializers/postgresql_opclasses_support.rb +++ /dev/null @@ -1,211 +0,0 @@ -# rubocop:disable all - -# These changes add support for PostgreSQL operator classes when creating -# indexes and dumping/loading schemas. Taken from Rails pull request -# https://github.com/rails/rails/pull/19090. -# -# License: -# -# Copyright (c) 2004-2016 David Heinemeier Hansson -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -require 'date' -require 'set' -require 'bigdecimal' -require 'bigdecimal/util' - -# As the Struct definition is changed in this PR/patch we have to first remove -# the existing one. -ActiveRecord::ConnectionAdapters.send(:remove_const, :IndexDefinition) - -module ActiveRecord - module ConnectionAdapters #:nodoc: - # Abstract representation of an index definition on a table. Instances of - # this type are typically created and returned by methods in database - # adapters. e.g. ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#indexes - attrs = [:table, :name, :unique, :columns, :lengths, :orders, :where, :type, :using, :comment, :opclasses] - - class IndexDefinition < Struct.new(*attrs) #:nodoc: - end - end -end - - -module ActiveRecord - module ConnectionAdapters # :nodoc: - module SchemaStatements - def add_index_options(table_name, column_name, options = {}) #:nodoc: - column_names = Array(column_name) - index_name = index_name(table_name, column: column_names) - - options.assert_valid_keys(:unique, :order, :name, :where, :length, :internal, :using, :algorithm, :type, :opclasses) - - index_type = options[:unique] ? "UNIQUE" : "" - index_type = options[:type].to_s if options.key?(:type) - index_name = options[:name].to_s if options.key?(:name) - max_index_length = options.fetch(:internal, false) ? index_name_length : allowed_index_name_length - - if options.key?(:algorithm) - algorithm = index_algorithms.fetch(options[:algorithm]) { - raise ArgumentError.new("Algorithm must be one of the following: #{index_algorithms.keys.map(&:inspect).join(', ')}") - } - end - - using = "USING #{options[:using]}" if options[:using].present? - - if supports_partial_index? - index_options = options[:where] ? " WHERE #{options[:where]}" : "" - end - - if index_name.length > max_index_length - raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{max_index_length} characters" - end - if data_source_exists?(table_name) && index_name_exists?(table_name, index_name) - raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists" - end - index_columns = quoted_columns_for_index(column_names, options).join(", ") - - [index_name, index_type, index_columns, index_options, algorithm, using] - end - end - end -end - -module ActiveRecord - module ConnectionAdapters - module PostgreSQL - module SchemaStatements - # Returns an array of indexes for the given table. - def indexes(table_name, name = nil) - result = query(<<-SQL, 'SCHEMA') - SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid - FROM pg_class t - INNER JOIN pg_index d ON t.oid = d.indrelid - INNER JOIN pg_class i ON d.indexrelid = i.oid - WHERE i.relkind = 'i' - AND d.indisprimary = 'f' - AND t.relname = '#{table_name}' - AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false)) ) - ORDER BY i.relname - SQL - - result.map do |row| - index_name = row[0] - unique = row[1] - indkey = row[2].split(" ").map(&:to_i) - inddef = row[3] - oid = row[4] - - columns = Hash[query(<<-SQL, "SCHEMA")] - SELECT a.attnum, a.attname - FROM pg_attribute a - WHERE a.attrelid = #{oid} - AND a.attnum IN (#{indkey.join(",")}) - SQL - - column_names = columns.values_at(*indkey).compact - - unless column_names.empty? - # add info on sort order for columns (only desc order is explicitly specified, asc is the default) - desc_order_columns = inddef.scan(/(\w+) DESC/).flatten - orders = desc_order_columns.any? ? Hash[desc_order_columns.map {|order_column| [order_column, :desc]}] : {} - where = inddef.scan(/WHERE (.+)$/).flatten[0] - using = inddef.scan(/USING (.+?) /).flatten[0].to_sym - opclasses = Hash[inddef.scan(/\((.+?)\)(?:$| WHERE )/).flatten[0].split(',').map do |column_and_opclass| - column, opclass = column_and_opclass.split(' ').map(&:strip) - end.reject do |column, opclass| - ['desc', 'asc'].include?(opclass&.downcase) - end.map do |column, opclass| - [column, opclass] if opclass - end.compact] - - index_attrs = [table_name, index_name, unique, column_names, [], orders, where, nil, using, nil, opclasses] - - IndexDefinition.new(*index_attrs) - end - end.compact - end - - def add_index(table_name, column_name, options = {}) #:nodoc: - index_name, index_type, index_columns_and_opclasses, index_options, index_algorithm, index_using = add_index_options(table_name, column_name, options) - execute "CREATE #{index_type} INDEX #{index_algorithm} #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} #{index_using} (#{index_columns_and_opclasses})#{index_options}" - end - - protected - - def quoted_columns_for_index(column_names, options = {}) - column_opclasses = options[:opclasses] || {} - column_names.map {|name| "#{quote_column_name(name)} #{column_opclasses[name]}"} - - quoted_columns = Hash[column_names.map { |name| [name.to_sym, "#{quote_column_name(name)} #{column_opclasses[name]}"] }] - add_options_for_index_columns(quoted_columns, options).values - end - end - end - end -end - -module ActiveRecord - class SchemaDumper - private - - def indexes(table, stream) - if (indexes = @connection.indexes(table)).any? - add_index_statements = indexes.map do |index| - table_name = remove_prefix_and_suffix(index.table).inspect - " add_index #{([table_name]+index_parts(index)).join(', ')}" - end - - stream.puts add_index_statements.sort.join("\n") - stream.puts - end - end - - def indexes_in_create(table, stream) - if (indexes = @connection.indexes(table)).any? - index_statements = indexes.map do |index| - " t.index #{index_parts(index).join(', ')}" - end - stream.puts index_statements.sort.join("\n") - end - end - - def index_parts(index) - index_parts = [ - index.columns.inspect, - "name: #{index.name.inspect}", - ] - index_parts << "unique: true" if index.unique - index_parts << "length: { #{format_options(index.lengths)} }" if index.lengths.present? - index_parts << "order: { #{format_options(index.orders)} }" if index.orders.present? - index_parts << "where: #{index.where.inspect}" if index.where - index_parts << "using: #{index.using.inspect}" if index.using - index_parts << "type: #{index.type.inspect}" if index.type - index_parts << "opclasses: #{index.opclasses.inspect}" if index.opclasses.present? - index_parts << "comment: #{index.comment.inspect}" if index.comment - index_parts - end - - def format_options(options) - options.map { |key, value| "#{key}: #{value.inspect}" }.join(", ") - end - end -end diff --git a/config/initializers/rack_attack_logging.rb b/config/initializers/rack_attack_logging.rb index 7eb34bd69e5..b43fff24bb0 100644 --- a/config/initializers/rack_attack_logging.rb +++ b/config/initializers/rack_attack_logging.rb @@ -7,9 +7,9 @@ ActiveSupport::Notifications.subscribe('rack.attack') do |name, start, finish, r rack_attack_info = { message: 'Rack_Attack', env: req.env['rack.attack.match_type'], - ip: req.ip, + remote_ip: req.ip, request_method: req.request_method, - fullpath: req.fullpath + path: req.fullpath } if %w(throttle_authenticated_api throttle_authenticated_web).include? req.env['rack.attack.matched'] diff --git a/config/initializers/rack_timeout.rb b/config/initializers/rack_timeout.rb index 58f46b55725..246cf3482a4 100644 --- a/config/initializers/rack_timeout.rb +++ b/config/initializers/rack_timeout.rb @@ -14,8 +14,8 @@ if defined?(::Puma) && !Rails.env.test? Gitlab::Application.configure do |config| config.middleware.insert_before(Rack::Runtime, Rack::Timeout, - service_timeout: 60, - wait_timeout: 90) + service_timeout: ENV.fetch('GITLAB_RAILS_RACK_TIMEOUT', 60).to_i, + wait_timeout: ENV.fetch('GITLAB_RAILS_WAIT_TIMEOUT', 90).to_i) end observer = Gitlab::Cluster::RackTimeoutObserver.new diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index f9ef5d66bfa..9f3e104bc2b 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -28,16 +28,20 @@ if Rails.env.development? end enable_json_logs = Gitlab.config.sidekiq.log_format == 'json' +enable_sidekiq_monitor = ENV.fetch("SIDEKIQ_MONITOR_WORKER", 0).to_i.nonzero? Sidekiq.configure_server do |config| config.redis = queues_config_hash config.server_middleware do |chain| + chain.add Gitlab::SidekiqMiddleware::Monitor if enable_sidekiq_monitor + chain.add Gitlab::SidekiqMiddleware::Metrics if Settings.monitoring.sidekiq_exporter chain.add Gitlab::SidekiqMiddleware::ArgumentsLogger if ENV['SIDEKIQ_LOG_ARGUMENTS'] && !enable_json_logs chain.add Gitlab::SidekiqMiddleware::MemoryKiller if ENV['SIDEKIQ_MEMORY_KILLER_MAX_RSS'] chain.add Gitlab::SidekiqMiddleware::RequestStoreMiddleware unless ENV['SIDEKIQ_REQUEST_STORE'] == '0' chain.add Gitlab::SidekiqMiddleware::BatchLoader chain.add Gitlab::SidekiqMiddleware::CorrelationLogger + chain.add Gitlab::SidekiqMiddleware::InstrumentationLogger chain.add Gitlab::SidekiqStatus::ServerMiddleware end @@ -55,6 +59,8 @@ Sidekiq.configure_server do |config| # Clear any connections that might have been obtained before starting # Sidekiq (e.g. in an initializer). ActiveRecord::Base.clear_all_connections! + + Gitlab::SidekiqMonitor.instance.start if enable_sidekiq_monitor end if enable_reliable_fetch? @@ -72,7 +78,7 @@ Sidekiq.configure_server do |config| cron_jobs[k]['class'] = cron_jobs[k].delete('job_class') else cron_jobs.delete(k) - Rails.logger.error("Invalid cron_jobs config key: '#{k}'. Check your gitlab config file.") + Rails.logger.error("Invalid cron_jobs config key: '#{k}'. Check your gitlab config file.") # rubocop:disable Gitlab/RailsLogger end end Sidekiq::Cron::Job.load_from_hash! cron_jobs @@ -83,7 +89,7 @@ Sidekiq.configure_server do |config| Rails.application.config.database_configuration[Rails.env] db_config['pool'] = Sidekiq.options[:concurrency] ActiveRecord::Base.establish_connection(db_config) - Rails.logger.debug("Connection Pool size for Sidekiq Server is now: #{ActiveRecord::Base.connection.pool.instance_variable_get('@size')}") + Rails.logger.debug("Connection Pool size for Sidekiq Server is now: #{ActiveRecord::Base.connection.pool.instance_variable_get('@size')}") # rubocop:disable Gitlab/RailsLogger Gitlab.ee do Gitlab::Mirror.configure_cron_job! @@ -94,7 +100,7 @@ Sidekiq.configure_server do |config| Rails.configuration.geo_database['pool'] = Sidekiq.options[:concurrency] Geo::TrackingBase.establish_connection(Rails.configuration.geo_database) - Rails.logger.debug("Connection Pool size for Sidekiq Server is now: #{Geo::TrackingBase.connection_pool.size} (Geo tracking database)") + Rails.logger.debug("Connection Pool size for Sidekiq Server is now: #{Geo::TrackingBase.connection_pool.size} (Geo tracking database)") # rubocop:disable Gitlab/RailsLogger end end diff --git a/config/initializers/tracing.rb b/config/initializers/tracing.rb index 3c8779f238f..5b55a06692e 100644 --- a/config/initializers/tracing.rb +++ b/config/initializers/tracing.rb @@ -21,9 +21,13 @@ if Labkit::Tracing.enabled? end end + # Instrument Redis + Labkit::Tracing::Redis.instrument + # Instrument Rails Labkit::Tracing::Rails::ActiveRecordSubscriber.instrument Labkit::Tracing::Rails::ActionViewSubscriber.instrument + Labkit::Tracing::Rails::ActiveSupportSubscriber.instrument # In multi-processed clustered architectures (puma, unicorn) don't # start tracing until the worker processes are spawned. This works diff --git a/config/initializers/zz_metrics.rb b/config/initializers/zz_metrics.rb index 5aa6f73c5c5..af4aec7b355 100644 --- a/config/initializers/zz_metrics.rb +++ b/config/initializers/zz_metrics.rb @@ -6,6 +6,7 @@ # that we can stub it for testing, as it is only called when metrics are # enabled. # +# rubocop:disable Metrics/AbcSize def instrument_classes(instrumentation) instrumentation.instrument_instance_methods(Gitlab::Shell) @@ -53,7 +54,7 @@ def instrument_classes(instrumentation) instrumentation.instrument_methods(Banzai::Querying) instrumentation.instrument_instance_methods(Banzai::ObjectRenderer) - instrumentation.instrument_instance_methods(Banzai::Redactor) + instrumentation.instrument_instance_methods(Banzai::ReferenceRedactor) [Issuable, Mentionable, Participable].each do |klass| instrumentation.instrument_instance_methods(klass) @@ -86,12 +87,38 @@ def instrument_classes(instrumentation) instrumentation.instrument_methods(Gitlab::Highlight) instrumentation.instrument_instance_methods(Gitlab::Highlight) + Gitlab.ee do + instrumentation.instrument_methods(Elasticsearch::Git::Repository) + instrumentation.instrument_instance_methods(Elasticsearch::Git::Repository) + + instrumentation.instrument_instance_methods(Search::GlobalService) + instrumentation.instrument_instance_methods(Search::ProjectService) + + instrumentation.instrument_instance_methods(Gitlab::Elastic::SearchResults) + instrumentation.instrument_instance_methods(Gitlab::Elastic::ProjectSearchResults) + instrumentation.instrument_instance_methods(Gitlab::Elastic::Indexer) + instrumentation.instrument_instance_methods(Gitlab::Elastic::SnippetSearchResults) + instrumentation.instrument_methods(Gitlab::Elastic::Helper) + + instrumentation.instrument_instance_methods(Elastic::ApplicationVersionedSearch) + instrumentation.instrument_instance_methods(Elastic::ProjectsSearch) + instrumentation.instrument_instance_methods(Elastic::RepositoriesSearch) + instrumentation.instrument_instance_methods(Elastic::SnippetsSearch) + instrumentation.instrument_instance_methods(Elastic::WikiRepositoriesSearch) + + instrumentation.instrument_instance_methods(Gitlab::BitbucketImport::Importer) + instrumentation.instrument_instance_methods(Bitbucket::Connection) + + instrumentation.instrument_instance_methods(Geo::RepositorySyncWorker) + end + # This is a Rails scope so we have to instrument it manually. instrumentation.instrument_method(Project, :visible_to_user) # Needed for https://gitlab.com/gitlab-org/gitlab-ce/issues/30224#note_32306159 instrumentation.instrument_instance_method(MergeRequestDiff, :load_commits) end +# rubocop:enable Metrics/AbcSize # With prometheus enabled by default this breaks all specs # that stubs methods using `any_instance_of` for the models reloaded here. diff --git a/config/karma.config.js b/config/karma.config.js index 2a5bf3581e0..97794225a3f 100644 --- a/config/karma.config.js +++ b/config/karma.config.js @@ -107,7 +107,8 @@ if (specFilters.length) { module.exports = function(config) { process.env.TZ = 'Etc/UTC'; - const fixturesPath = `${IS_EE ? 'ee/' : ''}spec/javascripts/fixtures`; + const fixturesPath = `tmp/tests/frontend/fixtures${IS_EE ? '-ee' : ''}`; + const staticFixturesPath = 'spec/frontend/fixtures/static'; const karmaConfig = { basePath: ROOT_PATH, @@ -131,8 +132,13 @@ module.exports = function(config) { frameworks: ['jasmine'], files: [ { pattern: 'spec/javascripts/test_bundle.js', watched: false }, - { pattern: `${fixturesPath}/**/*@(.json|.html|.png|.bmpr|.pdf)`, included: false }, + { pattern: `${fixturesPath}/**/*`, included: false }, + { pattern: `${staticFixturesPath}/**/*`, included: false }, ], + proxies: { + '/fixtures/': `/base/${fixturesPath}/`, + '/fixtures/static/': `/base/${staticFixturesPath}/`, + }, preprocessors: { 'spec/javascripts/**/*.js': ['webpack', 'sourcemap'], 'ee/spec/javascripts/**/*.js': ['webpack', 'sourcemap'], diff --git a/config/knative/api_resources.yml b/config/knative/api_resources.yml new file mode 100644 index 00000000000..43427b730db --- /dev/null +++ b/config/knative/api_resources.yml @@ -0,0 +1,64 @@ +--- + +- meshpolicies.authentication.istio.io +- policies.authentication.istio.io +- adapters.config.istio.io +- apikeys.config.istio.io +- attributemanifests.config.istio.io +- authorizations.config.istio.io +- bypasses.config.istio.io +- podautoscalers.autoscaling.internal.knative.dev +- builds.build.knative.dev +- buildtemplates.build.knative.dev +- clusterbuildtemplates.build.knative.dev +- images.caching.internal.knative.dev +- certificates.networking.internal.knative.dev +- clusteringresses.networking.internal.knative.dev +- serverlessservices.networking.internal.knative.dev +- configurations.serving.knative.dev +- revisions.serving.knative.dev +- routes.serving.knative.dev +- services.serving.knative.dev +- checknothings.config.istio.io +- circonuses.config.istio.io +- deniers.config.istio.io +- edges.config.istio.io +- fluentds.config.istio.io +- handlers.config.istio.io +- httpapispecbindings.config.istio.io +- httpapispecs.config.istio.io +- instances.config.istio.io +- kubernetesenvs.config.istio.io +- kuberneteses.config.istio.io +- listcheckers.config.istio.io +- listentries.config.istio.io +- logentries.config.istio.io +- memquotas.config.istio.io +- metrics.config.istio.io +- noops.config.istio.io +- opas.config.istio.io +- prometheuses.config.istio.io +- quotas.config.istio.io +- quotaspecbindings.config.istio.io +- quotaspecs.config.istio.io +- rbacs.config.istio.io +- redisquotas.config.istio.io +- reportnothings.config.istio.io +- rules.config.istio.io +- servicecontrolreports.config.istio.io +- servicecontrols.config.istio.io +- signalfxs.config.istio.io +- solarwindses.config.istio.io +- stackdrivers.config.istio.io +- statsds.config.istio.io +- stdios.config.istio.io +- templates.config.istio.io +- tracespans.config.istio.io +- destinationrules.networking.istio.io +- envoyfilters.networking.istio.io +- gateways.networking.istio.io +- serviceentries.networking.istio.io +- virtualservices.networking.istio.io +- rbacconfigs.rbac.istio.io +- servicerolebindings.rbac.istio.io +- serviceroles.rbac.istio.io
\ No newline at end of file diff --git a/config/locales/doorkeeper.en.yml b/config/locales/doorkeeper.en.yml index a8234263275..258d8a99986 100644 --- a/config/locales/doorkeeper.en.yml +++ b/config/locales/doorkeeper.en.yml @@ -69,7 +69,7 @@ en: email: Allows read-only access to the user's primary email address using OpenID Connect scope_desc: api: - Grants complete read/write access to the API, including all groups and projects. + Grants complete read/write access to the API, including all groups and projects, the container registry, and the package registry. read_user: Grants read-only access to the authenticated user's profile through the /user API endpoint, which includes username, public email, and full name. Also grants access to read-only API endpoints under /users. read_repository: diff --git a/config/locales/en.yml b/config/locales/en.yml index a3dceb2fb62..a60f86e1d80 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -16,12 +16,6 @@ en: api_url: "Sentry API URL" project/metrics_setting: external_dashboard_url: "External dashboard URL" - errors: - messages: - label_already_exists_at_group_level: "already exists at group level for %{group}. Please choose another one." - wrong_size: "is the wrong size (should be %{file_size})" - size_too_small: "is too small (should be at least %{file_size})" - size_too_big: "is too big (should be at most %{file_size})" views: pagination: previous: "Prev" diff --git a/config/locales/invisible_captcha.en.yml b/config/locales/invisible_captcha.en.yml new file mode 100644 index 00000000000..5978549c0c3 --- /dev/null +++ b/config/locales/invisible_captcha.en.yml @@ -0,0 +1,4 @@ +en: + invisible_captcha: + sentence_for_humans: If you are human, please ignore this field. + timestamp_error_message: That was a bit too quick! Please resubmit. diff --git a/config/prometheus/cluster_metrics.yml b/config/prometheus/cluster_metrics.yml index 3df76b0974f..f2a41e4c337 100644 --- a/config/prometheus/cluster_metrics.yml +++ b/config/prometheus/cluster_metrics.yml @@ -2,12 +2,12 @@ priority: 1 metrics: - title: "CPU Usage" - y_label: "CPU" + y_label: "CPU (cores)" required_metrics: ['container_cpu_usage_seconds_total'] weight: 1 queries: - query_range: 'avg(sum(rate(container_cpu_usage_seconds_total{id="/"}[15m])) by (job)) without (job)' - label: Usage + label: Usage (cores) unit: "cores" appearance: line: @@ -15,7 +15,7 @@ area: opacity: 0 - query_range: 'sum(kube_pod_container_resource_requests_cpu_cores{kubernetes_namespace="gitlab-managed-apps"})' - label: Requested + label: Requested (cores) unit: "cores" appearance: line: @@ -23,7 +23,7 @@ area: opacity: 0 - query_range: 'sum(kube_node_status_capacity_cpu_cores{kubernetes_namespace="gitlab-managed-apps"})' - label: Capacity + label: Capacity (cores) unit: "cores" appearance: line: @@ -32,12 +32,12 @@ area: opacity: 0 - title: "Memory usage" - y_label: "Memory" + y_label: "Memory (GiB)" required_metrics: ['container_memory_usage_bytes'] weight: 1 queries: - query_range: 'avg(sum(container_memory_usage_bytes{id="/"}) by (job)) without (job) / 2^30' - label: Usage + label: Usage (GiB) unit: "GiB" appearance: line: @@ -45,7 +45,7 @@ area: opacity: 0 - query_range: 'sum(kube_pod_container_resource_requests_memory_bytes{kubernetes_namespace="gitlab-managed-apps"})/2^30' - label: Requested + label: Requested (GiB) unit: "GiB" appearance: line: @@ -53,7 +53,7 @@ area: opacity: 0 - query_range: 'sum(kube_node_status_capacity_memory_bytes{kubernetes_namespace="gitlab-managed-apps"})/2^30' - label: Capacity + label: Capacity (GiB) unit: "GiB" appearance: line: diff --git a/config/prometheus/common_metrics.yml b/config/prometheus/common_metrics.yml index f9ce5a6f365..08504d6f7d5 100644 --- a/config/prometheus/common_metrics.yml +++ b/config/prometheus/common_metrics.yml @@ -21,16 +21,16 @@ panel_groups: metrics: - id: response_metrics_nginx_ingress_latency_pod_average query_range: 'avg(nginx_upstream_response_msecs_avg{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"})' - label: Pod average + label: Pod average (ms) unit: ms - title: "HTTP Error Rate" type: "area-chart" - y_label: "HTTP Errors" + y_label: "HTTP Errors (%)" weight: 1 metrics: - id: response_metrics_nginx_ingress_http_error_rate query_range: 'sum(rate(nginx_upstream_responses_total{status_code="5xx", upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[2m])) / sum(rate(nginx_upstream_responses_total{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[2m])) * 100' - label: 5xx Errors + label: 5xx Errors (%) unit: "%" # NGINX Ingress metrics for post-0.16.0 versions - group: Response metrics (NGINX Ingress) @@ -52,16 +52,16 @@ panel_groups: metrics: - id: response_metrics_nginx_ingress_16_latency_pod_average query_range: 'sum(rate(nginx_ingress_controller_ingress_upstream_latency_seconds_sum{namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) / sum(rate(nginx_ingress_controller_ingress_upstream_latency_seconds_count{namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) * 1000' - label: Pod average + label: Pod average (ms) unit: ms - title: "HTTP Error Rate" type: "area-chart" - y_label: "HTTP Errors" + y_label: "HTTP Errors (%)" weight: 1 metrics: - id: response_metrics_nginx_ingress_16_http_error_rate query_range: 'sum(rate(nginx_ingress_controller_requests{status=~"5.*",namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) / sum(rate(nginx_ingress_controller_requests{namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) * 100' - label: 5xx Errors + label: 5xx Errors (%) unit: "%" - group: Response metrics (HA Proxy) priority: 10 @@ -82,7 +82,7 @@ panel_groups: metrics: - id: response_metrics_ha_proxy_http_error_rate query_range: 'sum(rate(haproxy_frontend_http_responses_total{code="5xx",%{environment_filter}}[2m])) / sum(rate(haproxy_frontend_http_responses_total{%{environment_filter}}[2m]))' - label: HTTP Errors + label: HTTP Errors (%) unit: "%" - group: Response metrics (AWS ELB) priority: 10 @@ -94,7 +94,7 @@ panel_groups: metrics: - id: response_metrics_aws_elb_throughput_requests query_range: 'sum(aws_elb_request_count_sum{%{environment_filter}}) / 60' - label: Total + label: Total (req/sec) unit: req / sec - title: "Latency" type: "area-chart" @@ -103,7 +103,7 @@ panel_groups: metrics: - id: response_metrics_aws_elb_latency_average query_range: 'avg(aws_elb_latency_average{%{environment_filter}}) * 1000' - label: Average + label: Average (ms) unit: ms - title: "HTTP Error Rate" type: "area-chart" @@ -112,7 +112,7 @@ panel_groups: metrics: - id: response_metrics_aws_elb_http_error_rate query_range: 'sum(aws_elb_httpcode_backend_5_xx_sum{%{environment_filter}}) / sum(aws_elb_request_count_sum{%{environment_filter}})' - label: HTTP Errors + label: HTTP Errors (%) unit: "%" - group: Response metrics (NGINX) priority: 10 @@ -133,9 +133,9 @@ panel_groups: metrics: - id: response_metrics_nginx_latency query_range: 'avg(nginx_server_requestMsec{%{environment_filter}})' - label: Upstream + label: Upstream (ms) unit: ms - - title: "HTTP Error Rate" + - title: "HTTP Error Rate (Errors / Sec)" type: "area-chart" y_label: "HTTP 500 Errors / Sec" weight: 1 @@ -149,12 +149,12 @@ panel_groups: panels: - title: "Memory Usage (Total)" type: "area-chart" - y_label: "Total Memory Used" + y_label: "Total Memory Used (GB)" weight: 4 metrics: - id: system_metrics_kubernetes_container_memory_total query_range: 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) /1024/1024/1024' - label: Total + label: Total (GB) unit: GB - title: "Core Usage (Total)" type: "area-chart" @@ -163,44 +163,44 @@ panel_groups: metrics: - id: system_metrics_kubernetes_container_cores_total query_range: 'avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job)' - label: Total + label: Total (cores) unit: "cores" - title: "Memory Usage (Pod average)" - type: "area-chart" - y_label: "Memory Used per Pod" + type: "line-chart" + y_label: "Memory Used per Pod (MB)" weight: 2 metrics: - id: system_metrics_kubernetes_container_memory_average query_range: 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024' - label: Pod average + label: Pod average (MB) unit: MB - title: "Canary: Memory Usage (Pod Average)" - type: "area-chart" - y_label: "Memory Used per Pod" + type: "line-chart" + y_label: "Memory Used per Pod (MB)" weight: 2 metrics: - id: system_metrics_kubernetes_container_memory_average_canary query_range: 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024' - label: Pod average + label: Pod average (MB) unit: MB track: canary - title: "Core Usage (Pod Average)" - type: "area-chart" + type: "line-chart" y_label: "Cores per Pod" weight: 1 metrics: - id: system_metrics_kubernetes_container_core_usage query_range: 'avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job) / count(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}[15m])) by (pod_name))' - label: Pod average + label: Pod average (cores) unit: "cores" - title: "Canary: Core Usage (Pod Average)" - type: "area-chart" + type: "line-chart" y_label: "Cores per Pod" weight: 1 metrics: - id: system_metrics_kubernetes_container_core_usage_canary query_range: 'avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job) / count(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}[15m])) by (pod_name))' - label: Pod average + label: Pod average (cores) unit: "cores" track: canary - title: "Knative function invocations" diff --git a/config/routes.rb b/config/routes.rb index a42fc037227..d633228a495 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -58,6 +58,7 @@ Rails.application.routes.draw do # Search get 'search' => 'search#show' get 'search/autocomplete' => 'search#autocomplete', as: :search_autocomplete + get 'search/count' => 'search#count', as: :search_count # JSON Web Token get 'jwt/auth' => 'jwt#auth' @@ -82,7 +83,11 @@ Rails.application.routes.draw do resources :issues, only: [:index, :create, :update] end - resources :issues, module: :boards, only: [:index, :update] + resources :issues, module: :boards, only: [:index, :update] do + collection do + put :bulk_move, format: :json + end + end Gitlab.ee do resources :users, module: :boards, only: [:index] @@ -104,13 +109,23 @@ Rails.application.routes.draw do Gitlab.ee do draw :smartcard draw :jira_connect + draw :username + end + + Gitlab.ee do + constraints(::Constraints::FeatureConstrainer.new(:analytics)) do + draw :analytics + end end - if ENV['GITLAB_ENABLE_CHAOS_ENDPOINTS'] - get '/chaos/leakmem' => 'chaos#leakmem' - get '/chaos/cpuspin' => 'chaos#cpuspin' - get '/chaos/sleep' => 'chaos#sleep' - get '/chaos/kill' => 'chaos#kill' + if ENV['GITLAB_CHAOS_SECRET'] || Rails.env.development? || Rails.env.test? + resource :chaos, only: [] do + get :leakmem + get :cpu_spin + get :db_spin + get :sleep + get :kill + end end end diff --git a/config/routes/admin.rb b/config/routes/admin.rb index f609739d9fd..6f9a5552564 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -73,7 +73,7 @@ namespace :admin do resource :background_jobs, controller: 'background_jobs', only: [:show] resource :system_info, controller: 'system_info', only: [:show] - resources :requests_profiles, only: [:index, :show], param: :name, constraints: { name: /.+\.html/ } + resources :requests_profiles, only: [:index, :show], param: :name, constraints: { name: /.+\.(html|txt)/ } resources :projects, only: [:index] diff --git a/config/routes/api.rb b/config/routes/api.rb index c6c17b5708e..d55bbdf6776 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -1,5 +1,5 @@ post '/api/graphql', to: 'graphql#execute' mount GraphiQL::Rails::Engine, at: '/-/graphql-explorer', graphql_path: '/api/graphql' -::API::API.logger Rails.logger +::API::API.logger Rails.logger # rubocop:disable Gitlab/RailsLogger mount ::API::API => '/' diff --git a/config/routes/git_http.rb b/config/routes/git_http.rb index a959d40881b..aac6d418a92 100644 --- a/config/routes/git_http.rb +++ b/config/routes/git_http.rb @@ -34,6 +34,18 @@ scope(path: '*namespace_id/:project_id', end end + # Redirect /group/project.wiki.git to the project wiki + scope(format: true, constraints: { project_id: Gitlab::PathRegex.project_wiki_git_route_regex, format: :git }) do + wiki_redirect = redirect do |params, request| + project_id = params[:project_id].delete_suffix('.wiki') + path = [params[:namespace_id], project_id, 'wikis'].join('/') + path << "?#{request.query_string}" unless request.query_string.blank? + path + end + + get '/', to: wiki_redirect + end + # Redirect /group/project/info/refs to /group/project.git/info/refs scope(constraints: { project_id: Gitlab::PathRegex.project_route_regex }) do # Allow /info/refs, /info/refs?service=git-upload-pack, and diff --git a/config/routes/project.rb b/config/routes/project.rb index c202463dadb..29e462f904d 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -170,7 +170,9 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do get :recent end end + resources :releases, only: [:index] + resources :starrers, only: [:index] resources :forks, only: [:index, :new, :create] resources :group_links, only: [:index, :create, :update, :destroy], constraints: { id: /\d+/ } @@ -265,6 +267,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do get :pipelines get :diffs, to: 'merge_requests/diffs#show' get :widget, to: 'merge_requests/content#widget' + get :cached_widget, to: 'merge_requests/content#cached_widget' end get :diff_for_path, controller: 'merge_requests/diffs' @@ -339,11 +342,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do resource :variables, only: [:show, :update] - resources :triggers, only: [:index, :create, :edit, :update, :destroy] do - member do - post :take_ownership - end - end + resources :triggers, only: [:index, :create, :edit, :update, :destroy] resource :mirror, only: [:show, :update] do member do @@ -360,6 +359,9 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do collection do resource :pipelines_settings, path: 'settings', only: [:show, :update] get :charts + scope '(*ref)', constraints: { ref: Gitlab::PathRegex.git_reference_regex } do + get :latest, action: :show, defaults: { latest: true } + end end member do @@ -478,7 +480,11 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do # in JSON format, or a request for tag named `latest.json`. scope format: false do resources :tags, only: [:index, :destroy], - constraints: { id: Gitlab::Regex.container_registry_tag_regex } + constraints: { id: Gitlab::Regex.container_registry_tag_regex } do + collection do + delete :bulk_destroy + end + end end end end @@ -504,6 +510,10 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do get :realtime_changes post :create_merge_request get :discussions, format: :json + + Gitlab.ee do + get 'designs(/*vueroute)', to: 'issues#show', as: :designs, format: false + end end collection do diff --git a/config/routes/user.rb b/config/routes/user.rb index 80f266aa8f9..d4616c8080d 100644 --- a/config/routes/user.rb +++ b/config/routes/user.rb @@ -43,13 +43,6 @@ scope '-/users', module: :users do end end -scope '-/users', module: :users do - resources :terms, only: [:index] do - post :accept, on: :member - post :decline, on: :member - end -end - scope(constraints: { username: Gitlab::PathRegex.root_namespace_route_regex }) do scope(path: 'users/:username', as: :user, @@ -59,6 +52,7 @@ scope(constraints: { username: Gitlab::PathRegex.root_namespace_route_regex }) d get :groups get :projects get :contributed, as: :contributed_projects + get :starred, as: :starred_projects get :snippets get :exists get :activity diff --git a/config/routes/wiki.rb b/config/routes/wiki.rb index 2ca52e55fca..d439c99270e 100644 --- a/config/routes/wiki.rb +++ b/config/routes/wiki.rb @@ -2,6 +2,7 @@ scope(controller: :wikis) do scope(path: 'wikis', as: :wikis) do get :git_access get :pages + get :new get '/', to: redirect('%{namespace_id}/%{project_id}/wikis/home') post '/', to: 'wikis#create' end diff --git a/config/settings.rb b/config/settings.rb index da459afcce2..8756c120645 100644 --- a/config/settings.rb +++ b/config/settings.rb @@ -1,4 +1,5 @@ require 'settingslogic' +require 'digest/md5' # We can not use `Rails.root` here, as this file might be loaded without the # full Rails environment being loaded. We can not use `require_relative` either, @@ -170,14 +171,17 @@ class Settings < Settingslogic URI.parse(url_without_path).host end - # Runs every minute in a random ten-minute period on Sundays, to balance the - # load on the server receiving these pings. The usage ping is safe to run - # multiple times because of a 24 hour exclusive lock. + # Runs at a random time of day on a consistent day of the week based on + # the instance UUID. This is to balance the load on the service receiving + # these pings. The sidekiq job handles temporary http failures. def cron_for_usage_ping hour = rand(24) - minute = rand(6) + minute = rand(60) + # Set a default UUID for the case when the UUID hasn't been initialized. + uuid = Gitlab::CurrentSettings.uuid || 'uuid-not-set' + day_of_week = Digest::MD5.hexdigest(uuid).to_i(16) % 7 - "#{minute}0-#{minute}9 #{hour} * * 0" + "#{minute} #{hour} * * #{day_of_week}" end end end diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml index 80791795390..ea165508d29 100644 --- a/config/sidekiq_queues.yml +++ b/config/sidekiq_queues.yml @@ -95,6 +95,7 @@ - [update_project_statistics, 1] - [phabricator_import_import_tasks, 1] - [update_namespace_statistics, 1] + - [chaos, 2] # EE-specific queues - [ldap_group_sync, 2] @@ -112,3 +113,4 @@ - [elastic_namespace_indexer, 1] - [export_csv, 1] - [incident_management, 2] + - [jira_connect, 1] diff --git a/config/smime_signature_settings.rb b/config/smime_signature_settings.rb new file mode 100644 index 00000000000..3d19db84c19 --- /dev/null +++ b/config/smime_signature_settings.rb @@ -0,0 +1,11 @@ +# Set default values for email_smime settings +class SmimeSignatureSettings + def self.parse(email_smime) + email_smime ||= Settingslogic.new({}) + email_smime['enabled'] = false unless email_smime['enabled'] + email_smime['key_file'] ||= Rails.root.join('.gitlab_smime_key') + email_smime['cert_file'] ||= Rails.root.join('.gitlab_smime_cert') + + email_smime + end +end diff --git a/config/webpack.config.js b/config/webpack.config.js index a81590e8b8e..969a84e85dd 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -6,6 +6,7 @@ const StatsWriterPlugin = require('webpack-stats-plugin').StatsWriterPlugin; const CompressionPlugin = require('compression-webpack-plugin'); const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; +const CopyWebpackPlugin = require('copy-webpack-plugin'); const ROOT_PATH = path.resolve(__dirname, '..'); const CACHE_PATH = process.env.WEBPACK_CACHE_PATH || path.join(ROOT_PATH, 'tmp/cache'); @@ -89,6 +90,12 @@ const alias = { // the following resolves files which are different between CE and EE ee_else_ce: path.join(ROOT_PATH, 'app/assets/javascripts'), + + // override loader path for icons.svg so we do not duplicate this asset + '@gitlab/svgs/dist/icons.svg': path.join( + ROOT_PATH, + 'app/assets/javascripts/lib/utils/icons_path.js', + ), }; if (IS_EE) { @@ -157,7 +164,15 @@ module.exports = { loader: 'graphql-tag/loader', }, { + test: /icons\.svg$/, + loader: 'file-loader', + options: { + name: '[name].[hash:8].[ext]', + }, + }, + { test: /\.svg$/, + exclude: /icons\.svg$/, loader: 'raw-loader', }, { @@ -278,6 +293,20 @@ module.exports = { } }), + new CopyWebpackPlugin([ + { + from: path.join(ROOT_PATH, 'node_modules/pdfjs-dist/cmaps/'), + to: path.join(ROOT_PATH, 'public/assets/webpack/cmaps/'), + }, + { + from: path.join( + ROOT_PATH, + 'node_modules/@gitlab/visual-review-tools/dist/visual_review_toolbar.js', + ), + to: path.join(ROOT_PATH, 'public/assets/webpack'), + }, + ]), + // compression can require a lot of compute time and is disabled in CI IS_PRODUCTION && !NO_COMPRESSION && new CompressionPlugin(), @@ -344,6 +373,8 @@ module.exports = { devtool: NO_SOURCEMAPS ? false : devtool, - // sqljs requires fs - node: { fs: 'empty' }, + node: { + fs: 'empty', // sqljs requires fs + setImmediate: false, + }, }; diff --git a/config/webpack.config.review_toolbar.js b/config/webpack.config.review_toolbar.js deleted file mode 100644 index baaba7ed387..00000000000 --- a/config/webpack.config.review_toolbar.js +++ /dev/null @@ -1,58 +0,0 @@ -const path = require('path'); -const CompressionPlugin = require('compression-webpack-plugin'); - -const ROOT_PATH = path.resolve(__dirname, '..'); -const CACHE_PATH = process.env.WEBPACK_CACHE_PATH || path.join(ROOT_PATH, 'tmp/cache'); -const NO_SOURCEMAPS = process.env.NO_SOURCEMAPS; -const IS_PRODUCTION = process.env.NODE_ENV === 'production'; - -const devtool = IS_PRODUCTION ? 'source-map' : 'cheap-module-eval-source-map'; - -const alias = { - vendor: path.join(ROOT_PATH, 'vendor/assets/javascripts'), - spec: path.join(ROOT_PATH, 'spec/javascripts'), -}; - -module.exports = { - mode: IS_PRODUCTION ? 'production' : 'development', - - context: path.join(ROOT_PATH, 'app/assets/javascripts'), - - name: 'visual_review_toolbar', - - entry: './visual_review_toolbar', - - output: { - path: path.join(ROOT_PATH, 'public/assets/webpack'), - filename: 'visual_review_toolbar.js', - library: 'VisualReviewToolbar', - libraryTarget: 'var', - }, - - resolve: { - alias, - }, - - module: { - rules: [ - { - test: /\.js$/, - loader: 'babel-loader', - options: { - cacheDirectory: path.join(CACHE_PATH, 'babel-loader'), - }, - }, - { - test: /\.css$/, - use: ['style-loader', 'css-loader'], - }, - ], - }, - - plugins: [ - // compression can require a lot of compute time and is disabled in CI - new CompressionPlugin(), - ].filter(Boolean), - - devtool: NO_SOURCEMAPS ? false : devtool, -}; |