diff options
author | Igor <idrozdov@gitlab.com> | 2019-08-05 15:06:02 +0000 |
---|---|---|
committer | Igor <idrozdov@gitlab.com> | 2019-08-05 15:06:02 +0000 |
commit | 7efb062c3c3c7b44113d0dc0fe78fc9b8e95bd7c (patch) | |
tree | a12bde9bbeffcc0c365d3a29339d0389dcefdd8f /config | |
parent | 2bd1320f86b8cfd5d60199c5f7f0caa1cc2aa66b (diff) | |
parent | 3dfc89ade452ad7f0185653b30ed1d4bb2544fb0 (diff) | |
download | gitlab-ce-id-test-codeowners.tar.gz |
Merge branch 'master' into 'id-test-codeowners'id-test-codeowners
# Conflicts:
# .gitlab/CODEOWNERS
Diffstat (limited to 'config')
36 files changed, 306 insertions, 633 deletions
diff --git a/config/application.rb b/config/application.rb index de386506233..92240426b5a 100644 --- a/config/application.rb +++ b/config/application.rb @@ -22,11 +22,6 @@ 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. @@ -168,7 +163,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" @@ -183,9 +177,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/gitlab.yml.example b/config/gitlab.yml.example index 334c241bcaa..39b719a5978 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -400,6 +400,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 +427,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 # ========================== @@ -952,6 +966,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 # ========================== @@ -1158,6 +1182,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..4b21732e179 --- /dev/null +++ b/config/initializers/0_inject_enterprise_edition_module.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module InjectEnterpriseEditionModule + def prepend_if_ee(constant) + prepend(constant.constantize) if Gitlab.ee? + 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 3a121addc98..659801f787d 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -217,6 +217,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 +259,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 +296,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 +479,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 53c3eac3c74..3f2691dde95 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 @@ -23,7 +22,7 @@ Prometheus::Client.configure do |config| 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| diff --git a/config/initializers/active_record_data_types.rb b/config/initializers/active_record_data_types.rb index 151bce4d130..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 = 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::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 = type_map) - 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_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/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/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/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 fbec28186eb..3d84b4e44ce 100644 --- a/config/initializers/lograge.rb +++ b/config/initializers/lograge.rb @@ -34,6 +34,13 @@ unless Sidekiq.server? payload[:gitaly_duration] = Gitlab::GitalyClient.query_time_ms end + rugged_calls = Gitlab::RuggedInstrumentation.query_count + + if rugged_calls > 0 + payload[:rugged_calls] = rugged_calls + payload[:rugged_duration_ms] = Gitlab::RuggedInstrumentation.query_time_ms + end + 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 e6a7d9bef52..00000000000 --- a/config/initializers/mysql_ignore_postgresql_options.rb +++ /dev/null @@ -1,42 +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_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_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..b6c7f1ff4fc 100644 --- a/config/initializers/peek.rb +++ b/config/initializers/peek.rb @@ -1,47 +1,18 @@ -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.into Peek::Views::RedisDetailed +Peek.into Peek::Views::Rugged -PEEK_DB_VIEW.prepend ::Gitlab::PerformanceBar::PeekQueryTracker +# `Peek::Views::GC` is currently disabled in production, as it runs with every request +# even if PerformanceBar is inactive and clears `GC::Profiler` reports we need for metrics. +# Check https://gitlab.com/gitlab-org/gitlab-ce/issues/65455 +Peek.into Peek::Views::GC if Rails.env.development? -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_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/sidekiq.rb b/config/initializers/sidekiq.rb index 166fb9b6916..9f88fb9895b 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -33,6 +33,7 @@ Sidekiq.configure_server do |config| config.redis = queues_config_hash config.server_middleware do |chain| + 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' diff --git a/config/initializers/zz_metrics.rb b/config/initializers/zz_metrics.rb index 5aa6f73c5c5..b005fdf159b 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,42 @@ 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::ApplicationSearch) + instrumentation.instrument_instance_methods(Elastic::IssuesSearch) + instrumentation.instrument_instance_methods(Elastic::MergeRequestsSearch) + instrumentation.instrument_instance_methods(Elastic::MilestonesSearch) + instrumentation.instrument_instance_methods(Elastic::NotesSearch) + 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/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/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..32475ef8380 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,25 +163,25 @@ 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" + 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" + 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)" @@ -191,7 +191,7 @@ panel_groups: 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" @@ -200,7 +200,7 @@ panel_groups: 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 641807203bf..459f2b22bf0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -116,7 +116,7 @@ Rails.application.routes.draw do end end - if ENV['GITLAB_CHAOS_SECRET'] || Rails.env.development? + if ENV['GITLAB_CHAOS_SECRET'] || Rails.env.development? || Rails.env.test? resource :chaos, only: [] do get :leakmem get :cpu_spin 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/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..3113cb172f7 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -339,11 +339,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 @@ -504,6 +500,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', format: false + end end collection do 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..c7586aa1e38 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] diff --git a/config/webpack.config.js b/config/webpack.config.js index cd793743eb7..442b4b4c21e 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,13 @@ module.exports = { } }), + new CopyWebpackPlugin([ + { + from: path.join(ROOT_PATH, 'node_modules/pdfjs-dist/cmaps/'), + to: path.join(ROOT_PATH, 'public/assets/webpack/cmaps/'), + }, + ]), + // compression can require a lot of compute time and is disabled in CI IS_PRODUCTION && !NO_COMPRESSION && new CompressionPlugin(), |