Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
7134e029c5
commit
c575d3cfde
|
|
@ -62,38 +62,36 @@ Geo secondary sites have a [Geo tracking database](https://gitlab.com/gitlab-org
|
|||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
unless table_exists?(:cool_widget_registry)
|
||||
ActiveRecord::Base.transaction do
|
||||
create_table :cool_widget_registry, id: :bigserial, force: :cascade do |t|
|
||||
t.bigint :cool_widget_id, null: false
|
||||
t.datetime_with_timezone :created_at, null: false
|
||||
t.datetime_with_timezone :last_synced_at
|
||||
t.datetime_with_timezone :retry_at
|
||||
t.datetime_with_timezone :verified_at
|
||||
t.datetime_with_timezone :verification_started_at
|
||||
t.datetime_with_timezone :verification_retry_at
|
||||
t.integer :state, default: 0, null: false, limit: 2
|
||||
t.integer :verification_state, default: 0, null: false, limit: 2
|
||||
t.integer :retry_count, default: 0, limit: 2, null: false
|
||||
t.integer :verification_retry_count, default: 0, limit: 2, null: false
|
||||
t.boolean :checksum_mismatch, default: false, null: false
|
||||
t.boolean :force_to_redownload, default: false, null: false
|
||||
t.boolean :missing_on_primary, default: false, null: false
|
||||
t.binary :verification_checksum
|
||||
t.binary :verification_checksum_mismatched
|
||||
t.string :verification_failure, limit: 255 # rubocop:disable Migration/PreventStrings see https://gitlab.com/gitlab-org/gitlab/-/issues/323806
|
||||
t.string :last_sync_failure, limit: 255 # rubocop:disable Migration/PreventStrings see https://gitlab.com/gitlab-org/gitlab/-/issues/323806
|
||||
ActiveRecord::Base.transaction do
|
||||
create_table :cool_widget_registry, id: :bigserial, force: :cascade do |t|
|
||||
t.bigint :cool_widget_id, null: false
|
||||
t.datetime_with_timezone :created_at, null: false
|
||||
t.datetime_with_timezone :last_synced_at
|
||||
t.datetime_with_timezone :retry_at
|
||||
t.datetime_with_timezone :verified_at
|
||||
t.datetime_with_timezone :verification_started_at
|
||||
t.datetime_with_timezone :verification_retry_at
|
||||
t.integer :state, default: 0, null: false, limit: 2
|
||||
t.integer :verification_state, default: 0, null: false, limit: 2
|
||||
t.integer :retry_count, default: 0, limit: 2, null: false
|
||||
t.integer :verification_retry_count, default: 0, limit: 2, null: false
|
||||
t.boolean :checksum_mismatch, default: false, null: false
|
||||
t.boolean :force_to_redownload, default: false, null: false
|
||||
t.boolean :missing_on_primary, default: false, null: false
|
||||
t.binary :verification_checksum
|
||||
t.binary :verification_checksum_mismatched
|
||||
t.string :verification_failure, limit: 255 # rubocop:disable Migration/PreventStrings see https://gitlab.com/gitlab-org/gitlab/-/issues/323806
|
||||
t.string :last_sync_failure, limit: 255 # rubocop:disable Migration/PreventStrings see https://gitlab.com/gitlab-org/gitlab/-/issues/323806
|
||||
|
||||
t.index :cool_widget_id, name: :index_cool_widget_registry_on_cool_widget_id, unique: true
|
||||
t.index :retry_at
|
||||
t.index :state
|
||||
# To optimize performance of CoolWidgetRegistry.verification_failed_batch
|
||||
t.index :verification_retry_at, name: :cool_widget_registry_failed_verification, order: "NULLS FIRST", where: "((state = 2) AND (verification_state = 3))"
|
||||
# To optimize performance of CoolWidgetRegistry.needs_verification_count
|
||||
t.index :verification_state, name: :cool_widget_registry_needs_verification, where: "((state = 2) AND (verification_state = ANY (ARRAY[0, 3])))"
|
||||
# To optimize performance of CoolWidgetRegistry.verification_pending_batch
|
||||
t.index :verified_at, name: :cool_widget_registry_pending_verification, order: "NULLS FIRST", where: "((state = 2) AND (verification_state = 0))"
|
||||
end
|
||||
t.index :cool_widget_id, name: :index_cool_widget_registry_on_cool_widget_id, unique: true
|
||||
t.index :retry_at
|
||||
t.index :state
|
||||
# To optimize performance of CoolWidgetRegistry.verification_failed_batch
|
||||
t.index :verification_retry_at, name: :cool_widget_registry_failed_verification, order: "NULLS FIRST", where: "((state = 2) AND (verification_state = 3))"
|
||||
# To optimize performance of CoolWidgetRegistry.needs_verification_count
|
||||
t.index :verification_state, name: :cool_widget_registry_needs_verification, where: "((state = 2) AND (verification_state = ANY (ARRAY[0, 3])))"
|
||||
# To optimize performance of CoolWidgetRegistry.verification_pending_batch
|
||||
t.index :verified_at, name: :cool_widget_registry_pending_verification, order: "NULLS FIRST", where: "((state = 2) AND (verification_state = 0))"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -537,9 +535,11 @@ If you did not add verification state fields to a separate table, `cool_widget_s
|
|||
|
||||
Otherwise, you can follow [the example of Merge Request Diffs](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63309).
|
||||
|
||||
- [ ] Add a `Geo::CoolWidgetState` model in `ee/app/models/ee/geo/cool_widget_state.rb`:
|
||||
- [ ] Add a `Geo::CoolWidgetState` model in `ee/app/models/geo/cool_widget_state.rb`:
|
||||
|
||||
``` ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Geo
|
||||
class CoolWidgetState < ApplicationRecord
|
||||
self.primary_key = :cool_widget_id
|
||||
|
|
@ -745,7 +745,7 @@ The GraphQL API is used by `Admin > Geo > Replication Details` views, and is dir
|
|||
graphql_name 'CoolWidgetRegistry'
|
||||
description 'Represents the Geo replication and verification state of a cool_widget'
|
||||
|
||||
field :cool_widget_id, GraphQL::ID_TYPE, null: false, description: 'ID of the Cool Widget'
|
||||
field :cool_widget_id, GraphQL::Types::ID, null: false, description: 'ID of the Cool Widget.'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2305,7 +2305,6 @@ Gitlab/NamespacedClass:
|
|||
- 'ee/app/workers/sync_security_reports_to_report_approval_rules_worker.rb'
|
||||
- 'ee/app/workers/update_all_mirrors_worker.rb'
|
||||
- 'ee/app/workers/update_max_seats_used_for_gitlab_com_subscriptions_worker.rb'
|
||||
- 'ee/lib/generators/rails/geo_migration_generator.rb'
|
||||
- 'ee/lib/gitlab/path_locks_finder.rb'
|
||||
- 'ee/spec/support/elastic_query_name_inspector.rb'
|
||||
- 'ee/spec/support/ssh_keygen.rb'
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import getPipelineDetails from 'shared_queries/pipelines/get_pipeline_details.qu
|
|||
import getUserCallouts from '~/graphql_shared/queries/get_user_callouts.query.graphql';
|
||||
import { __ } from '~/locale';
|
||||
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
|
||||
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import { DEFAULT, DRAW_FAILURE, LOAD_FAILURE } from '../../constants';
|
||||
import DismissPipelineGraphCallout from '../../graphql/mutations/dismiss_pipeline_notification.graphql';
|
||||
import getPipelineQuery from '../../graphql/queries/get_pipeline_header_data.query.graphql';
|
||||
|
|
@ -32,7 +31,6 @@ export default {
|
|||
LocalStorageSync,
|
||||
PipelineGraph,
|
||||
},
|
||||
mixins: [glFeatureFlagMixin()],
|
||||
inject: {
|
||||
graphqlResourceEtag: {
|
||||
default: '',
|
||||
|
|
@ -200,7 +198,7 @@ export default {
|
|||
return this.$apollo.queries.pipeline.loading && !this.pipeline;
|
||||
},
|
||||
showGraphViewSelector() {
|
||||
return Boolean(this.glFeatures.pipelineGraphLayersView && this.pipeline?.usesNeeds);
|
||||
return this.pipeline?.usesNeeds;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ const addMulti = (mainPipelineProjectPath, linkedPipeline) => {
|
|||
};
|
||||
|
||||
const calculatePipelineLayersInfo = (pipeline, componentName, metricsPath) => {
|
||||
const shouldCollectMetrics = Boolean(metricsPath.length);
|
||||
const shouldCollectMetrics = Boolean(metricsPath);
|
||||
|
||||
if (shouldCollectMetrics) {
|
||||
beginPerfMeasure();
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ export default {
|
|||
<div v-for="(field, key, index) in filteredModalData" :key="index" class="row gl-mt-3 gl-mb-3">
|
||||
<strong class="col-sm-3 text-right"> {{ field.text }}: </strong>
|
||||
|
||||
<div class="col-sm-9 text-secondary">
|
||||
<div class="col-sm-9">
|
||||
<code-block v-if="field.type === $options.fieldTypes.codeBlock" :code="field.value" />
|
||||
|
||||
<gl-link
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ class Projects::PipelinesController < Projects::ApplicationController
|
|||
before_action :authorize_create_pipeline!, only: [:new, :create, :config_variables]
|
||||
before_action :authorize_update_pipeline!, only: [:retry, :cancel]
|
||||
before_action do
|
||||
push_frontend_feature_flag(:pipeline_graph_layers_view, project, type: :development, default_enabled: :yaml)
|
||||
push_frontend_feature_flag(:graphql_pipeline_details, project, type: :development, default_enabled: :yaml)
|
||||
push_frontend_feature_flag(:graphql_pipeline_details_users, current_user, type: :development, default_enabled: :yaml)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -49,8 +49,12 @@ class ReleaseHighlight
|
|||
end
|
||||
|
||||
def self.file_paths
|
||||
@file_paths ||= Rails.cache.fetch(self.cache_key('file_paths'), expires_in: CACHE_DURATION) do
|
||||
Dir.glob(FILES_PATH).sort.reverse
|
||||
@file_paths ||= self.relative_file_paths.map { |path| path.prepend(Rails.root.to_s) }
|
||||
end
|
||||
|
||||
def self.relative_file_paths
|
||||
Rails.cache.fetch(self.cache_key('file_paths'), expires_in: CACHE_DURATION) do
|
||||
Dir.glob(FILES_PATH).sort.reverse.map { |path| path.delete_prefix(Rails.root.to_s) }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ module Gitlab
|
|||
require_dependency Rails.root.join('lib/gitlab/middleware/rack_multipart_tempfile_factory')
|
||||
require_dependency Rails.root.join('lib/gitlab/runtime')
|
||||
|
||||
config.autoloader = :classic
|
||||
config.autoloader = :zeitwerk
|
||||
|
||||
# Settings in config/environments/* take precedence over those specified here.
|
||||
# Application configuration should go into files in config/initializers
|
||||
|
|
@ -86,7 +86,11 @@ module Gitlab
|
|||
# Rake tasks ignore the eager loading settings, so we need to set the
|
||||
# autoload paths explicitly
|
||||
config.autoload_paths = config.eager_load_paths.dup
|
||||
|
||||
# These are only used in Rake tasks so we don't need to add these to eager_load_paths
|
||||
config.autoload_paths.push("#{config.root}/lib/generators")
|
||||
Gitlab.ee { config.autoload_paths.push("#{config.root}/ee/lib/generators") }
|
||||
Gitlab.jh { config.autoload_paths.push("#{config.root}/jh/lib/generators") }
|
||||
|
||||
# Only load the plugins named here, in the order given (default is alphabetical).
|
||||
# :all can be used as a placeholder for all plugins not explicitly named.
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: pipeline_graph_layers_view
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56865
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/328538
|
||||
milestone: '13.11'
|
||||
type: development
|
||||
group: group::pipeline authoring
|
||||
default_enabled: true
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_dependency 'gitlab'
|
||||
|
|
@ -5,15 +5,11 @@ Rails.autoloaders.each do |autoloader|
|
|||
# that do not define Ruby classes / modules
|
||||
autoloader.ignore(Rails.root.join('lib/support'))
|
||||
|
||||
# Ignore generators since these are loaded manually by Rails
|
||||
# https://github.com/rails/rails/blob/v6.1.3.2/railties/lib/rails/command/behavior.rb#L56-L65
|
||||
autoloader.ignore(Rails.root.join('lib/generators'))
|
||||
autoloader.ignore(Rails.root.join('ee/lib/generators')) if Gitlab.ee?
|
||||
|
||||
# Mailer previews are also loaded manually by Rails
|
||||
# Mailer previews are loaded manually by Rails
|
||||
# https://github.com/rails/rails/blob/v6.1.3.2/actionmailer/lib/action_mailer/preview.rb#L121-L125
|
||||
autoloader.ignore(Rails.root.join('app/mailers/previews'))
|
||||
autoloader.ignore(Rails.root.join('ee/app/mailers/previews')) if Gitlab.ee?
|
||||
autoloader.ignore(Rails.root.join('jh/app/mailers/previews')) if Gitlab.jh?
|
||||
|
||||
autoloader.inflector.inflect(
|
||||
'api' => 'API',
|
||||
|
|
|
|||
|
|
@ -389,7 +389,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
|
|||
namespace :design_management do
|
||||
namespace :designs, path: 'designs/:design_id(/:sha)', constraints: -> (params) { params[:sha].nil? || Gitlab::Git.commit_id?(params[:sha]) } do
|
||||
resource :raw_image, only: :show
|
||||
resources :resized_image, only: :show, constraints: -> (params) { DesignManagement::DESIGN_IMAGE_SIZES.include?(params[:id]) }
|
||||
resources :resized_image, only: :show, constraints: -> (params) { ::DesignManagement::DESIGN_IMAGE_SIZES.include?(params[:id]) }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,6 @@
|
|||
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,
|
||||
# as Rails uses `load` for `require_dependency` (used when loading the Rails
|
||||
# environment). This could then lead to this file being loaded twice.
|
||||
require_dependency File.expand_path('../lib/gitlab', __dir__)
|
||||
|
||||
class Settings < Settingslogic
|
||||
source ENV.fetch('GITLAB_CONFIG') { Pathname.new(File.expand_path('..', __dir__)).join('config/gitlab.yml') }
|
||||
namespace ENV.fetch('GITLAB_ENV') { Rails.env }
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ architected
|
|||
architecting
|
||||
archiver
|
||||
Arel
|
||||
arity
|
||||
Artifactory
|
||||
Asana
|
||||
Asciidoctor
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ sudo gitlab-ctl \
|
|||
--backup-timeout=21600
|
||||
```
|
||||
|
||||
This will give the initial replication up to six hours to complete, rather than
|
||||
This gives the initial replication up to six hours to complete, rather than
|
||||
the default thirty minutes. Adjust as required for your installation.
|
||||
|
||||
### Message: "PANIC: could not write to file `pg_xlog/xlogtemp.123`: No space left on device"
|
||||
|
|
@ -335,7 +335,7 @@ log data to build up in `pg_xlog`. Removing the unused slots can reduce the amou
|
|||
```
|
||||
|
||||
NOTE:
|
||||
Using `gitlab-rails dbconsole` will not work, because managing replication slots requires superuser permissions.
|
||||
Using `gitlab-rails dbconsole` does not work, because managing replication slots requires superuser permissions.
|
||||
|
||||
1. View your replication slots with:
|
||||
|
||||
|
|
@ -358,13 +358,12 @@ Slots where `active` is `f` are not active.
|
|||
|
||||
### Message: "ERROR: canceling statement due to conflict with recovery"
|
||||
|
||||
This error may rarely occur under normal usage, and the system is resilient
|
||||
This error occurs infrequently under normal usage, and the system is resilient
|
||||
enough to recover.
|
||||
|
||||
However, under certain conditions, some database queries on secondaries may run
|
||||
excessively long, which increases the frequency of this error. At some point,
|
||||
some of these queries will never be able to complete due to being canceled
|
||||
every time.
|
||||
excessively long, which increases the frequency of this error. This can lead to a situation
|
||||
where some queries never complete due to being canceled on every replication.
|
||||
|
||||
These long-running queries are
|
||||
[planned to be removed in the future](https://gitlab.com/gitlab-org/gitlab/-/issues/34269),
|
||||
|
|
@ -505,7 +504,7 @@ Then reconfigure GitLab:
|
|||
sudo gitlab-ctl reconfigure
|
||||
```
|
||||
|
||||
This will increase the timeout to four hours (14400 seconds). Choose a time
|
||||
This increases the timeout to four hours (14400 seconds). Choose a time
|
||||
long enough to accommodate a full clone of your largest repositories.
|
||||
|
||||
### New LFS objects are never replicated
|
||||
|
|
@ -564,9 +563,8 @@ to start again from scratch, there are a few steps that can help you:
|
|||
1. _(Optional)_ Rename other data folders and create new ones
|
||||
|
||||
WARNING:
|
||||
You may still have files on the **secondary** node that have been removed from **primary** node but
|
||||
removal have not been reflected. If you skip this step, they will never be removed
|
||||
from this Geo node.
|
||||
You may still have files on the **secondary** node that have been removed from the **primary** node, but this
|
||||
removal has not been reflected. If you skip this step, these files are not removed at all from the Geo node.
|
||||
|
||||
Any uploaded content like file attachments, avatars or LFS objects are stored in a
|
||||
subfolder in one of the two paths below:
|
||||
|
|
@ -661,12 +659,12 @@ Counts:
|
|||
|
||||
#### If you are promoting a Geo secondary site running on a single server
|
||||
|
||||
`gitlab-ctl promotion-preflight-checks` will fail due to the existence of
|
||||
`gitlab-ctl promotion-preflight-checks` fails due to the existence of
|
||||
`failed` rows in the `geo_design_registry` table. Use the
|
||||
[previous snippet](#design-repository-failures-on-mirrored-projects-and-project-imports) to
|
||||
determine the actual replication status of Design repositories.
|
||||
|
||||
`gitlab-ctl promote-to-primary-node` will fail since it runs preflight checks.
|
||||
`gitlab-ctl promote-to-primary-node` fails since it runs preflight checks.
|
||||
If the [previous snippet](#design-repository-failures-on-mirrored-projects-and-project-imports)
|
||||
shows that all designs are synced, then you can use the
|
||||
`--skip-preflight-checks` option or the `--force` option to move forward with
|
||||
|
|
@ -674,7 +672,7 @@ promotion.
|
|||
|
||||
#### If you are promoting a Geo secondary site running on multiple servers
|
||||
|
||||
`gitlab-ctl promotion-preflight-checks` will fail due to the existence of
|
||||
`gitlab-ctl promotion-preflight-checks` fails due to the existence of
|
||||
`failed` rows in the `geo_design_registry` table. Use the
|
||||
[previous snippet](#design-repository-failures-on-mirrored-projects-and-project-imports) to
|
||||
determine the actual replication status of Design repositories.
|
||||
|
|
@ -766,7 +764,7 @@ When
|
|||
you need to run the `gitlab-pg-ctl` command to promote the PostgreSQL
|
||||
read-replica database.
|
||||
|
||||
In GitLab 12.8 and earlier, this command will fail with the message:
|
||||
In GitLab 12.8 and earlier, this command fails with the message:
|
||||
|
||||
```plaintext
|
||||
sudo: gitlab-pg-ctl: command not found
|
||||
|
|
@ -825,7 +823,7 @@ If you notice for some reason there are more artifacts on the Geo
|
|||
secondary node than on the Geo primary node, you can use the Rake task
|
||||
to [cleanup orphan artifact files](../../../raketasks/cleanup.md#remove-orphan-artifact-files).
|
||||
|
||||
On a Geo **secondary** node, this command will also clean up all Geo
|
||||
On a Geo **secondary** node, this command also cleans up all Geo
|
||||
registry record related to the orphan files on disk.
|
||||
|
||||
## Fixing sign in errors
|
||||
|
|
|
|||
|
|
@ -824,6 +824,13 @@ notifications:
|
|||
|
||||
## Run the Cleanup policy now
|
||||
|
||||
WARNING:
|
||||
If you're using a distributed architecture and Sidekiq is running on a different node, the cleanup
|
||||
policies don't work. To fix this, you must configure the `gitlab.rb` file on the Sidekiq nodes to
|
||||
point to the correct registry URL and copy the `registry.key` file to each Sidekiq node. For more
|
||||
information, see the [Sidekiq configuration](../sidekiq.md)
|
||||
page.
|
||||
|
||||
To reduce the amount of [Container Registry disk space used by a given project](../troubleshooting/gitlab_rails_cheat_sheet.md#registry-disk-space-usage-by-project),
|
||||
administrators can clean up image tags
|
||||
and [run garbage collection](#container-registry-garbage-collection).
|
||||
|
|
|
|||
|
|
@ -94,6 +94,16 @@ you want using steps 1 and 2 from the GitLab downloads page.
|
|||
gitlab_exporter['enable'] = false
|
||||
```
|
||||
|
||||
1. If you're using the Container Registry and it's running on a different node than Sidekiq, then
|
||||
configure the registry URL:
|
||||
|
||||
```ruby
|
||||
registry_external_url 'https://registry.example.com'
|
||||
gitlab_rails['registry_api_url'] = "https://registry.example.com"
|
||||
```
|
||||
|
||||
You must also copy the `registry.key` file to each Sidekiq node.
|
||||
|
||||
1. Run `gitlab-ctl reconfigure`.
|
||||
|
||||
You will need to restart the Sidekiq nodes after an update has occurred and database
|
||||
|
|
@ -180,6 +190,10 @@ node_exporter['listen_address'] = '10.10.1.48:9100'
|
|||
|
||||
# Rails Status for prometheus
|
||||
gitlab_rails['monitoring_whitelist'] = ['10.10.1.42', '127.0.0.1']
|
||||
|
||||
# Container Registry URL for cleanup jobs
|
||||
registry_external_url 'https://registry.example.com'
|
||||
gitlab_rails['registry_api_url'] = "https://registry.example.com"
|
||||
```
|
||||
|
||||
## Further reading
|
||||
|
|
|
|||
|
|
@ -363,9 +363,7 @@ you visualize the entire pipeline, including all cross-project inter-dependencie
|
|||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/298973) in GitLab 13.12.
|
||||
> - [Deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
|
||||
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/328538) in GitLab 13.12.
|
||||
> - Enabled on GitLab.com.
|
||||
> - Recommended for production use.
|
||||
> - To disable in GitLab self-managed instances, ask a GitLab administrator to [disable it](#enable-or-disable-job-dependency-view). **(FREE SELF)**
|
||||
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/328538) in GitLab 14.2.
|
||||
|
||||
This in-development feature might not be available for your use. There can be
|
||||
[risks when enabling features still in development](../../administration/feature_flags.md#risks-when-enabling-features-still-in-development).
|
||||
|
|
@ -391,24 +389,6 @@ To see the full `needs` dependency tree for a job, hover over it:
|
|||
|
||||

|
||||
|
||||
#### Enable or disable job dependency view **(FREE SELF)**
|
||||
|
||||
The job dependency view is deployed behind a feature flag that is **enabled by default**.
|
||||
[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
|
||||
can disable it.
|
||||
|
||||
To enable it:
|
||||
|
||||
```ruby
|
||||
Feature.enable(:pipeline_graph_layers_view)
|
||||
```
|
||||
|
||||
To disable it:
|
||||
|
||||
```ruby
|
||||
Feature.disable(:pipeline_graph_layers_view)
|
||||
```
|
||||
|
||||
### Pipeline mini graphs
|
||||
|
||||
Pipeline mini graphs take less space and can tell you at a
|
||||
|
|
|
|||
|
|
@ -41,13 +41,13 @@ The following is an example of a merge request with an environment set dynamical
|
|||
In this example, a branch was:
|
||||
|
||||
- Successfully built.
|
||||
- Deployed under a dynamic environment that can be reached by clicking on the **View app** button.
|
||||
- Deployed under a dynamic environment that can be reached by selecting **View app**.
|
||||
|
||||
After adding Review Apps to your workflow, you follow the branched Git flow. That is:
|
||||
|
||||
1. Push a branch and let the runner deploy the Review App based on the `script` definition of the dynamic environment job.
|
||||
1. Wait for the runner to build and deploy your web application.
|
||||
1. Click on the link provided in the merge request related to the branch to see the changes live.
|
||||
1. To view the changes live, select the link in the merge request related to the branch.
|
||||
|
||||
## Configuring Review Apps
|
||||
|
||||
|
|
@ -66,21 +66,26 @@ The process of configuring Review Apps is as follows:
|
|||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118844) in GitLab 12.8.
|
||||
|
||||
When configuring Review Apps for a project, you need to add a new job to `.gitlab-ci.yml`,
|
||||
as mentioned above. To facilitate this and if you are using Kubernetes, you can click
|
||||
the **Enable Review Apps** button and GitLab prompts you with a template code block that
|
||||
you can copy and paste into `.gitlab-ci.yml` as a starting point. To do so:
|
||||
When configuring Review Apps for a project, you add a new job to the `.gitlab-ci.yml` file,
|
||||
as mentioned above. To facilitate this, and if you are using Kubernetes, you can select
|
||||
**Enable Review Apps** and GitLab prompts you with a template code block that
|
||||
you can copy and paste into `.gitlab-ci.yml` as a starting point.
|
||||
|
||||
1. Go to the project your want to create a Review App job for.
|
||||
1. From the left nav, go to **Deployments > Environments**.
|
||||
1. Click on the **Enable Review Apps** button. It is available to you
|
||||
if you have Developer or higher [permissions](../../user/permissions.md) to that project.
|
||||
Prerequisite:
|
||||
|
||||
- You need at least the Developer [role](../../user/permissions.md) for the project.
|
||||
|
||||
To use the Review Apps template:
|
||||
|
||||
1. On the top bar, select **Menu > Projects** and find the project you want to create a Review App job for.
|
||||
1. On the left sidebar, select **Deployments > Environments**.
|
||||
1. Select **Enable Review Apps**.
|
||||
1. Copy the provided code snippet and paste it into your
|
||||
`.gitlab-ci.yml` file:
|
||||
|
||||

|
||||
|
||||
1. Feel free to tune this template to your own needs.
|
||||
You can edit this template as needed.
|
||||
|
||||
## Review Apps auto-stop
|
||||
|
||||
|
|
@ -168,9 +173,9 @@ and results in a public path of `index.html`, instead of
|
|||
|
||||
After you have the route mapping set up, it takes effect in the following locations:
|
||||
|
||||
- In the merge request widget. The:
|
||||
- **View app** button takes you to the environment URL set in `.gitlab-ci.yml`.
|
||||
- Dropdown lists the first 5 matched items from the route map, but you can filter them if more
|
||||
- In the merge request widget:
|
||||
- The **View app** button takes you to the environment URL set in the `.gitlab-ci.yml` file.
|
||||
- The list shows the first 5 matched items from the route map, but you can filter them if more
|
||||
than 5 are available.
|
||||
|
||||

|
||||
|
|
@ -202,14 +207,14 @@ Review App, the Visual Reviews feedback form is overlaid on the right side of ev
|
|||
|
||||
To use the feedback form to make a comment in the merge request:
|
||||
|
||||
1. Click the **Review** tab on the right side of a page.
|
||||
1. On the right side of a page, select the **Review** tab.
|
||||
1. Make a comment on the visual review. You can make use of all the
|
||||
[Markdown annotations](../../user/markdown.md) that are also available in
|
||||
merge request comments.
|
||||
1. Enter your personal information:
|
||||
- If [`data-require-auth`](#authentication-for-visual-reviews) is `true`, you must enter your [personal access token](../../user/profile/personal_access_tokens.md).
|
||||
- Otherwise, enter your name, and optionally your email.
|
||||
1. Click **Send feedback**.
|
||||
1. Select **Send feedback**.
|
||||
|
||||
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
|
||||
To see Visual reviews in action, see the [Visual Reviews Walk through](https://youtu.be/1_tvWTlPfM4).
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ as such the docs for CE and EE are now identical. For historical reasons and
|
|||
in order not to break any existing links throughout the internet, we still
|
||||
maintain the CE docs (`https://docs.gitlab.com/ce/`), although it is hidden
|
||||
from the website, and is now a symlink to the EE docs. When
|
||||
[Pages supports redirects](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/24),
|
||||
[Support wildcard redirects](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/500) is resolved,
|
||||
we can remove this completely.
|
||||
|
||||
## Assets
|
||||
|
|
|
|||
|
|
@ -127,7 +127,90 @@ reversible_migration do |migration|
|
|||
end
|
||||
```
|
||||
|
||||
### Example database migration test
|
||||
### Custom matchers for post-deployment migrations
|
||||
|
||||
We have some custom matchers in
|
||||
[`spec/support/matchers/background_migrations_matchers.rb`](https://gitlab.com/gitlab-org/gitlab/blob/v14.1.0-ee/spec/support/matchers/background_migrations_matchers.rb)
|
||||
to verify background migrations were correctly scheduled from a post-deployment migration, and
|
||||
receive the correct number of arguments.
|
||||
|
||||
All of them use the internal matcher `be_background_migration_with_arguments`, which verifies that
|
||||
the `#perform` method on your migration class doesn't crash when receiving the provided arguments.
|
||||
|
||||
#### `be_scheduled_migration`
|
||||
|
||||
Verifies that a Sidekiq job was queued with the expected class and arguments.
|
||||
|
||||
This matcher usually makes sense if you're queueing jobs manually, rather than going through our helpers.
|
||||
|
||||
```ruby
|
||||
# Migration
|
||||
BackgroundMigrationWorker.perform_async('MigrationClass', args)
|
||||
|
||||
# Spec
|
||||
expect('MigrationClass').to be_scheduled_migration(*args)
|
||||
```
|
||||
|
||||
#### `be_scheduled_migration_with_multiple_args`
|
||||
|
||||
Verifies that a Sidekiq job was queued with the expected class and arguments.
|
||||
|
||||
This works the same as `be_scheduled_migration`, except that the order is ignored when comparing
|
||||
array arguments.
|
||||
|
||||
```ruby
|
||||
# Migration
|
||||
BackgroundMigrationWorker.perform_async('MigrationClass', ['foo', [3, 2, 1]])
|
||||
|
||||
# Spec
|
||||
expect('MigrationClass').to be_scheduled_migration_with_multiple_args('foo', [1, 2, 3])
|
||||
```
|
||||
|
||||
#### `be_scheduled_delayed_migration`
|
||||
|
||||
Verifies that a Sidekiq job was queued with the expected delay, class, and arguments.
|
||||
|
||||
This can also be used with `queue_background_migration_jobs_by_range_at_intervals` and related helpers.
|
||||
|
||||
```ruby
|
||||
# Migration
|
||||
BackgroundMigrationWorker.perform_in(delay, 'MigrationClass', args)
|
||||
|
||||
# Spec
|
||||
expect('MigrationClass').to be_scheduled_delayed_migration(delay, *args)
|
||||
```
|
||||
|
||||
#### `have_scheduled_batched_migration`
|
||||
|
||||
Verifies that a `BatchedMigration` record was created with the expected class and arguments.
|
||||
|
||||
The `*args` are additional arguments passed to the `MigrationClass`, while `**kwargs` are any other
|
||||
attributes to be verified on the `BatchedMigration` record (Example: `interval: 2.minutes`).
|
||||
|
||||
```ruby
|
||||
# Migration
|
||||
queue_batched_background_migration(
|
||||
'MigrationClass',
|
||||
table_name,
|
||||
column_name,
|
||||
*args,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
# Spec
|
||||
expect('MigrationClass').to have_scheduled_batched_migration(
|
||||
table_name: table_name,
|
||||
column_name: column_name,
|
||||
job_arguments: args,
|
||||
**kwargs
|
||||
)
|
||||
```
|
||||
|
||||
### Examples of migration tests
|
||||
|
||||
Migration tests depend on what the migration does exactly, the most common types are data migrations and scheduling background migrations.
|
||||
|
||||
#### Example of a data migration test
|
||||
|
||||
This spec tests the
|
||||
[`db/post_migrate/20170526185842_migrate_pipeline_stages.rb`](https://gitlab.com/gitlab-org/gitlab-foss/blob/v11.6.5/db/post_migrate/20170526185842_migrate_pipeline_stages.rb)
|
||||
|
|
@ -181,6 +264,59 @@ RSpec.describe MigratePipelineStages do
|
|||
end
|
||||
```
|
||||
|
||||
#### Example of a background migration scheduling test
|
||||
|
||||
To test these you usually have to:
|
||||
|
||||
- Create some records.
|
||||
- Run the migration.
|
||||
- Verify that the expected jobs were scheduled, with the correct set
|
||||
of records, the correct batch size, interval, etc.
|
||||
|
||||
The behavior of the background migration itself needs to be verified in a [separate
|
||||
test for the background migration class](#example-background-migration-test).
|
||||
|
||||
This spec tests the
|
||||
[`db/post_migrate/20210701111909_backfill_issues_upvotes_count.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/v14.1.0-ee/db/post_migrate/20210701111909_backfill_issues_upvotes_count.rb)
|
||||
post-deployment migration. You can find the complete spec in
|
||||
[`spec/migrations/backfill_issues_upvotes_count_spec.rb`](https://gitlab.com/gitlab-org/gitlab/blob/v14.1.0-ee/spec/spec/migrations/backfill_issues_upvotes_count_spec.rb).
|
||||
|
||||
```ruby
|
||||
require 'spec_helper'
|
||||
require_migration!
|
||||
|
||||
RSpec.describe BackfillIssuesUpvotesCount do
|
||||
let(:migration) { described_class.new }
|
||||
let(:issues) { table(:issues) }
|
||||
let(:award_emoji) { table(:award_emoji) }
|
||||
|
||||
let!(:issue1) { issues.create! }
|
||||
let!(:issue2) { issues.create! }
|
||||
let!(:issue3) { issues.create! }
|
||||
let!(:issue4) { issues.create! }
|
||||
let!(:issue4_without_thumbsup) { issues.create! }
|
||||
|
||||
let!(:award_emoji1) { award_emoji.create!( name: 'thumbsup', awardable_type: 'Issue', awardable_id: issue1.id) }
|
||||
let!(:award_emoji2) { award_emoji.create!( name: 'thumbsup', awardable_type: 'Issue', awardable_id: issue2.id) }
|
||||
let!(:award_emoji3) { award_emoji.create!( name: 'thumbsup', awardable_type: 'Issue', awardable_id: issue3.id) }
|
||||
let!(:award_emoji4) { award_emoji.create!( name: 'thumbsup', awardable_type: 'Issue', awardable_id: issue4.id) }
|
||||
|
||||
it 'correctly schedules background migrations', :aggregate_failures do
|
||||
stub_const("#{described_class.name}::BATCH_SIZE", 2)
|
||||
|
||||
Sidekiq::Testing.fake! do
|
||||
freeze_time do
|
||||
migrate!
|
||||
|
||||
expect(described_class::MIGRATION).to be_scheduled_migration(issue1.id, issue2.id)
|
||||
expect(described_class::MIGRATION).to be_scheduled_migration(issue3.id, issue4.id)
|
||||
expect(BackgroundMigrationWorker.jobs.size).to eq(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## Testing a non-`ActiveRecord::Migration` class
|
||||
|
||||
To test a non-`ActiveRecord::Migration` test (a background migration),
|
||||
|
|
|
|||
|
|
@ -383,6 +383,7 @@ applications.
|
|||
| `AUTO_DEVOPS_CHART_REPOSITORY_NAME` | From GitLab 11.11, used to set the name of the Helm repository. Defaults to `gitlab`. |
|
||||
| `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME` | From GitLab 11.11, used to set a username to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD`. |
|
||||
| `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD` | From GitLab 11.11, used to set a password to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME`. |
|
||||
| `AUTO_DEVOPS_CHART_REPOSITORY_PASS_CREDENTIALS` | From GitLab 14.2, set to a non-empty value to enable forwarding of the Helm repository credentials to the chart server when the chart artifacts are on a different host than repository. |
|
||||
| `AUTO_DEVOPS_DEPLOY_DEBUG` | From GitLab 13.1, if this variable is present, Helm outputs debug logs. |
|
||||
| `AUTO_DEVOPS_ALLOW_TO_FORCE_DEPLOY_V<N>` | From [auto-deploy-image](https://gitlab.com/gitlab-org/cluster-integration/auto-deploy-image) v1.0.0, if this variable is present, a new major version of chart is forcibly deployed. For more information, see [Ignore warnings and continue deploying](upgrading_auto_deploy_dependencies.md#ignore-warnings-and-continue-deploying). |
|
||||
| `BUILDPACK_URL` | Buildpack's full URL. [Must point to a URL supported by Pack or Herokuish](#custom-buildpacks). |
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ is locked.
|
|||
|
||||
## Activate GitLab EE with an Activation Code **(PREMIUM SELF)**
|
||||
|
||||
As of GitLab Enterprise Edition 14.0, you need an activation code to activate your instance. You can obtain an activation code by [purchasing a license](https://about.gitlab.com/pricing/) or by signing up for a [free trial](https://about.gitlab.com/free-trial/). This activation code is a 24-character alphanumeric string you receive in a confirmation email. You can also sign in to the [Customers Portal](https://customers.gitlab.com/customers/sign_in) to copy the activation code to your clipboard.
|
||||
As of GitLab Enterprise Edition 14.1, you need an activation code to activate your instance. You can obtain an activation code by [purchasing a license](https://about.gitlab.com/pricing/) or by signing up for a [free trial](https://about.gitlab.com/free-trial/). This activation code is a 24-character alphanumeric string you receive in a confirmation email. You can also sign in to the [Customers Portal](https://customers.gitlab.com/customers/sign_in) to copy the activation code to your clipboard.
|
||||
|
||||
To begin the activation process with your activation code:
|
||||
|
||||
|
|
@ -155,4 +155,8 @@ and how to add additional seats can be found in the
|
|||
|
||||
### There is a connectivity issue
|
||||
|
||||
In GitLab 14.0 and later, to activate your subscription, your GitLab instance must be connected to the internet. If you have questions or need assistance activating your instance please [contact GitLab Support](https://about.gitlab.com/support/#contact-support).
|
||||
In GitLab 14.1 and later, to activate your subscription, your GitLab instance must be connected to the internet.
|
||||
|
||||
If you have an offline or airgapped environment, you can [upload a license file](license.md#activate-gitlab-ee-with-a-license-file) instead.
|
||||
|
||||
If you have questions or need assistance activating your instance, please [contact GitLab Support](https://about.gitlab.com/support/#contact-support).
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ upstream image from a registry, acting as a pull-through cache.
|
|||
|
||||
## Prerequisites
|
||||
|
||||
The Dependency Proxy must be [enabled by an administrator](../../../administration/packages/dependency_proxy.md).
|
||||
- The Dependency Proxy is enabled by default but can be [turned off by an administrator](../../../administration/packages/dependency_proxy.md).
|
||||
|
||||
### Supported images and packages
|
||||
|
||||
|
|
@ -33,11 +33,6 @@ The following images and packages are supported.
|
|||
For a list of planned additions, view the
|
||||
[direction page](https://about.gitlab.com/direction/package/#dependency-proxy).
|
||||
|
||||
## Enable the Dependency Proxy
|
||||
|
||||
The Dependency Proxy is disabled by default.
|
||||
[Learn how an administrator can enable it](../../../administration/packages/dependency_proxy.md).
|
||||
|
||||
## View the Dependency Proxy
|
||||
|
||||
To view the Dependency Proxy:
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ module GemExtensions
|
|||
@relation_delegate_cache2 = {} # rubocop:disable Gitlab/ModuleWithInstanceVariables
|
||||
|
||||
[
|
||||
DisableJoins::Relation
|
||||
::GemExtensions::ActiveRecord::DisableJoins::Relation
|
||||
].each do |klass|
|
||||
delegate = Class.new(klass) do
|
||||
include ::ActiveRecord::Delegation::ClassSpecificRelation
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ module Gitlab
|
|||
|
||||
ALLOWED_OPERATIONS = %w(count distinct_count).freeze
|
||||
|
||||
source_root File.expand_path('templates', __dir__)
|
||||
source_root File.expand_path('usage_metric/templates', __dir__)
|
||||
|
||||
class_option :ee, type: :boolean, optional: true, default: false, desc: 'Indicates if instrumentation is for EE'
|
||||
class_option :type, type: :string, desc: "Metric type, must be one of: #{ALLOWED_SUPERCLASSES.keys.join(', ')}"
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'rails/generators'
|
||||
|
||||
module Rails
|
||||
module PostDeploymentMigration
|
||||
class PostDeploymentMigrationGenerator < Rails::Generators::NamedBase
|
||||
def create_migration_file
|
||||
timestamp = Time.now.utc.strftime('%Y%m%d%H%M%S')
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
.dast-auto-deploy:
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v2.6.0"
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v2.12.0"
|
||||
|
||||
dast_environment_deploy:
|
||||
extends: .dast-auto-deploy
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
.auto-deploy:
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v2.6.0"
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v2.12.0"
|
||||
dependencies: []
|
||||
|
||||
review:
|
||||
|
|
|
|||
|
|
@ -29,11 +29,11 @@ module Gitlab
|
|||
@host = host
|
||||
@port = port
|
||||
@load_balancer = load_balancer
|
||||
@pool = load_balancer.create_replica_connection_pool(LoadBalancing.pool_size, host, port)
|
||||
@pool = load_balancer.create_replica_connection_pool(::Gitlab::Database::LoadBalancing.pool_size, host, port)
|
||||
@online = true
|
||||
@last_checked_at = Time.zone.now
|
||||
|
||||
interval = LoadBalancing.replica_check_interval
|
||||
interval = ::Gitlab::Database::LoadBalancing.replica_check_interval
|
||||
@intervals = (interval..(interval * 2)).step(0.5).to_a
|
||||
end
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def offline!
|
||||
LoadBalancing::Logger.warn(
|
||||
::Gitlab::Database::LoadBalancing::Logger.warn(
|
||||
event: :host_offline,
|
||||
message: 'Marking host as offline',
|
||||
db_host: @host,
|
||||
|
|
@ -72,14 +72,14 @@ module Gitlab
|
|||
refresh_status
|
||||
|
||||
if @online
|
||||
LoadBalancing::Logger.info(
|
||||
::Gitlab::Database::LoadBalancing::Logger.info(
|
||||
event: :host_online,
|
||||
message: 'Host is online after replica status check',
|
||||
db_host: @host,
|
||||
db_port: @port
|
||||
)
|
||||
else
|
||||
LoadBalancing::Logger.warn(
|
||||
::Gitlab::Database::LoadBalancing::Logger.warn(
|
||||
event: :host_offline,
|
||||
message: 'Host is offline after replica status check',
|
||||
db_host: @host,
|
||||
|
|
@ -108,7 +108,7 @@ module Gitlab
|
|||
|
||||
def replication_lag_below_threshold?
|
||||
if (lag_time = replication_lag_time)
|
||||
lag_time <= LoadBalancing.max_replication_lag_time
|
||||
lag_time <= ::Gitlab::Database::LoadBalancing.max_replication_lag_time
|
||||
else
|
||||
false
|
||||
end
|
||||
|
|
@ -125,7 +125,7 @@ module Gitlab
|
|||
# only do this if we haven't replicated in a while so we only need
|
||||
# to connect to the primary when truly necessary.
|
||||
if (lag_size = replication_lag_size)
|
||||
lag_size <= LoadBalancing.max_replication_difference
|
||||
lag_size <= ::Gitlab::Database::LoadBalancing.max_replication_difference
|
||||
else
|
||||
false
|
||||
end
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ module Gitlab
|
|||
# namespace - The namespace to use for sticking.
|
||||
# id - The identifier to use for sticking.
|
||||
def self.stick_or_unstick(env, namespace, id)
|
||||
return unless LoadBalancing.enable?
|
||||
return unless ::Gitlab::Database::LoadBalancing.enable?
|
||||
|
||||
Sticking.unstick_or_continue_sticking(namespace, id)
|
||||
::Gitlab::Database::LoadBalancing::Sticking.unstick_or_continue_sticking(namespace, id)
|
||||
|
||||
env[STICK_OBJECT] ||= Set.new
|
||||
env[STICK_OBJECT] << [namespace, id]
|
||||
|
|
@ -56,7 +56,7 @@ module Gitlab
|
|||
namespaces_and_ids = sticking_namespaces_and_ids(env)
|
||||
|
||||
namespaces_and_ids.each do |namespace, id|
|
||||
Sticking.unstick_or_continue_sticking(namespace, id)
|
||||
::Gitlab::Database::LoadBalancing::Sticking.unstick_or_continue_sticking(namespace, id)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -65,17 +65,17 @@ module Gitlab
|
|||
namespaces_and_ids = sticking_namespaces_and_ids(env)
|
||||
|
||||
namespaces_and_ids.each do |namespace, id|
|
||||
Sticking.stick_if_necessary(namespace, id)
|
||||
::Gitlab::Database::LoadBalancing::Sticking.stick_if_necessary(namespace, id)
|
||||
end
|
||||
end
|
||||
|
||||
def clear
|
||||
load_balancer.release_host
|
||||
Session.clear_session
|
||||
::Gitlab::Database::LoadBalancing::Session.clear_session
|
||||
end
|
||||
|
||||
def load_balancer
|
||||
LoadBalancing.proxy.load_balancer
|
||||
::Gitlab::Database::LoadBalancing.proxy.load_balancer
|
||||
end
|
||||
|
||||
# Determines the sticking namespace and identifier based on the Rack
|
||||
|
|
|
|||
|
|
@ -63,31 +63,36 @@ module Gitlab
|
|||
end
|
||||
|
||||
def start
|
||||
# We run service discovery once in the current thread so that the application's main thread
|
||||
# does not race this thread to use the results of initial service discovery.
|
||||
next_sleep_duration = perform_service_discovery
|
||||
|
||||
Thread.new do
|
||||
loop do
|
||||
interval =
|
||||
begin
|
||||
refresh_if_necessary
|
||||
rescue StandardError => error
|
||||
# Any exceptions that might occur should be reported to
|
||||
# Sentry, instead of silently terminating this thread.
|
||||
Gitlab::ErrorTracking.track_exception(error)
|
||||
|
||||
Gitlab::AppLogger.error(
|
||||
"Service discovery encountered an error: #{error.message}"
|
||||
)
|
||||
|
||||
self.interval
|
||||
end
|
||||
|
||||
# We slightly randomize the sleep() interval. This should reduce
|
||||
# the likelihood of _all_ processes refreshing at the same time,
|
||||
# possibly putting unnecessary pressure on the DNS server.
|
||||
sleep(interval + rand(MAX_SLEEP_ADJUSTMENT))
|
||||
sleep(next_sleep_duration + rand(MAX_SLEEP_ADJUSTMENT))
|
||||
|
||||
next_sleep_duration = perform_service_discovery
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def perform_service_discovery
|
||||
refresh_if_necessary
|
||||
rescue StandardError => error
|
||||
# Any exceptions that might occur should be reported to
|
||||
# Sentry, instead of silently terminating this thread.
|
||||
Gitlab::ErrorTracking.track_exception(error)
|
||||
|
||||
Gitlab::AppLogger.error(
|
||||
"Service discovery encountered an error: #{error.message}"
|
||||
)
|
||||
|
||||
interval
|
||||
end
|
||||
|
||||
# Refreshes the hosts, but only if the DNS record returned a new list of
|
||||
# addresses.
|
||||
#
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def design?
|
||||
klass == DesignManagement::Design
|
||||
klass == ::DesignManagement::Design
|
||||
end
|
||||
|
||||
def diff_commit_user?
|
||||
|
|
|
|||
|
|
@ -66,28 +66,28 @@ module Gitlab
|
|||
def call(env)
|
||||
method = env['REQUEST_METHOD'].downcase
|
||||
method = 'INVALID' unless HTTP_METHODS.key?(method)
|
||||
started = Gitlab::Metrics::System.monotonic_time
|
||||
started = ::Gitlab::Metrics::System.monotonic_time
|
||||
health_endpoint = health_endpoint?(env['PATH_INFO'])
|
||||
status = 'undefined'
|
||||
|
||||
begin
|
||||
status, headers, body = @app.call(env)
|
||||
|
||||
elapsed = Gitlab::Metrics::System.monotonic_time - started
|
||||
elapsed = ::Gitlab::Metrics::System.monotonic_time - started
|
||||
|
||||
if !health_endpoint && Gitlab::Metrics.record_duration_for_status?(status)
|
||||
RequestsRackMiddleware.http_request_duration_seconds.observe({ method: method }, elapsed)
|
||||
if !health_endpoint && ::Gitlab::Metrics.record_duration_for_status?(status)
|
||||
self.class.http_request_duration_seconds.observe({ method: method }, elapsed)
|
||||
end
|
||||
|
||||
[status, headers, body]
|
||||
rescue StandardError
|
||||
RequestsRackMiddleware.rack_uncaught_errors_count.increment
|
||||
self.class.rack_uncaught_errors_count.increment
|
||||
raise
|
||||
ensure
|
||||
if health_endpoint
|
||||
RequestsRackMiddleware.http_health_requests_total.increment(status: status.to_s, method: method)
|
||||
self.class.http_health_requests_total.increment(status: status.to_s, method: method)
|
||||
else
|
||||
RequestsRackMiddleware.http_requests_total.increment(
|
||||
self.class.http_requests_total.increment(
|
||||
status: status.to_s,
|
||||
method: method,
|
||||
feature_category: feature_category.presence || FEATURE_CATEGORY_DEFAULT
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ module Gitlab
|
|||
def safe_sample
|
||||
sample
|
||||
rescue StandardError => e
|
||||
Gitlab::AppLogger.warn("#{self.class}: #{e}, stopping")
|
||||
::Gitlab::AppLogger.warn("#{self.class}: #{e}, stopping")
|
||||
stop
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def current_transaction
|
||||
Transaction.current
|
||||
::Gitlab::Metrics::Transaction.current
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ module Gitlab
|
|||
private
|
||||
|
||||
def current_transaction
|
||||
Transaction.current
|
||||
::Gitlab::Metrics::Transaction.current
|
||||
end
|
||||
|
||||
def metric_cache_operation_duration_seconds
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ module Gitlab
|
|||
attach_to :active_record
|
||||
|
||||
def sql(event)
|
||||
return if !Transaction.current || event.payload.fetch(:cached, event.payload[:name] == 'CACHE')
|
||||
return if !::Gitlab::QueryLimiting::Transaction.current || event.payload.fetch(:cached, event.payload[:name] == 'CACHE')
|
||||
|
||||
Transaction.current.increment
|
||||
Transaction.current.executed_sql(event.payload[:sql])
|
||||
::Gitlab::QueryLimiting::Transaction.current.increment
|
||||
::Gitlab::QueryLimiting::Transaction.current.executed_sql(event.payload[:sql])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def call(env)
|
||||
transaction, retval = Transaction.run do
|
||||
transaction, retval = ::Gitlab::QueryLimiting::Transaction.run do
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Usage
|
||||
module Metrics
|
||||
module Aggregates
|
||||
UNION_OF_AGGREGATED_METRICS = 'OR'
|
||||
INTERSECTION_OF_AGGREGATED_METRICS = 'AND'
|
||||
ALLOWED_METRICS_AGGREGATIONS = [UNION_OF_AGGREGATED_METRICS, INTERSECTION_OF_AGGREGATED_METRICS].freeze
|
||||
AGGREGATED_METRICS_PATH = Rails.root.join('config/metrics/aggregates/*.yml')
|
||||
AggregatedMetricError = Class.new(StandardError)
|
||||
UnknownAggregationOperator = Class.new(AggregatedMetricError)
|
||||
UnknownAggregationSource = Class.new(AggregatedMetricError)
|
||||
DisallowedAggregationTimeFrame = Class.new(AggregatedMetricError)
|
||||
|
||||
DATABASE_SOURCE = 'database'
|
||||
REDIS_SOURCE = 'redis'
|
||||
|
||||
SOURCES = {
|
||||
DATABASE_SOURCE => Sources::PostgresHll,
|
||||
REDIS_SOURCE => Sources::RedisHll
|
||||
}.freeze
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -4,23 +4,6 @@ module Gitlab
|
|||
module Usage
|
||||
module Metrics
|
||||
module Aggregates
|
||||
UNION_OF_AGGREGATED_METRICS = 'OR'
|
||||
INTERSECTION_OF_AGGREGATED_METRICS = 'AND'
|
||||
ALLOWED_METRICS_AGGREGATIONS = [UNION_OF_AGGREGATED_METRICS, INTERSECTION_OF_AGGREGATED_METRICS].freeze
|
||||
AGGREGATED_METRICS_PATH = Rails.root.join('config/metrics/aggregates/*.yml')
|
||||
AggregatedMetricError = Class.new(StandardError)
|
||||
UnknownAggregationOperator = Class.new(AggregatedMetricError)
|
||||
UnknownAggregationSource = Class.new(AggregatedMetricError)
|
||||
DisallowedAggregationTimeFrame = Class.new(AggregatedMetricError)
|
||||
|
||||
DATABASE_SOURCE = 'database'
|
||||
REDIS_SOURCE = 'redis'
|
||||
|
||||
SOURCES = {
|
||||
DATABASE_SOURCE => Sources::PostgresHll,
|
||||
REDIS_SOURCE => Sources::RedisHll
|
||||
}.freeze
|
||||
|
||||
class Aggregate
|
||||
include Gitlab::Usage::TimeFrame
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Usage
|
||||
module Metrics
|
||||
module Aggregates
|
||||
module Sources
|
||||
UnionNotAvailable = Class.new(AggregatedMetricError)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -5,8 +5,6 @@ module Gitlab
|
|||
module Metrics
|
||||
module Aggregates
|
||||
module Sources
|
||||
UnionNotAvailable = Class.new(AggregatedMetricError)
|
||||
|
||||
class RedisHll
|
||||
extend Calculations::Intersection
|
||||
def self.calculate_metrics_union(metric_names:, start_date:, end_date:, recorded_at: nil)
|
||||
|
|
|
|||
|
|
@ -6526,12 +6526,17 @@ msgstr ""
|
|||
msgid "Checkout"
|
||||
msgstr ""
|
||||
|
||||
msgid "Checkout|$%{selectedPlanPrice} per pack per year"
|
||||
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
|
||||
msgstr ""
|
||||
|
||||
msgid "Checkout|$%{selectedPlanPrice} per user per year"
|
||||
msgstr ""
|
||||
|
||||
msgid "Checkout|%d CI minute pack"
|
||||
msgid_plural "Checkout|%d CI minute packs"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -6541,15 +6546,17 @@ msgstr ""
|
|||
msgid "Checkout|%{name}'s GitLab subscription"
|
||||
msgstr ""
|
||||
|
||||
msgid "Checkout|%{quantity} CI minute packs"
|
||||
msgstr ""
|
||||
|
||||
msgid "Checkout|%{selectedPlanText} plan"
|
||||
msgstr ""
|
||||
|
||||
msgid "Checkout|%{startDate} - %{endDate}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Checkout|%{totalCiMinutes} CI minute"
|
||||
msgid_plural "Checkout|%{totalCiMinutes} CI minutes"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "Checkout|%{totalCiMinutes} CI minutes"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -6565,7 +6572,7 @@ msgstr ""
|
|||
msgid "Checkout|Billing address"
|
||||
msgstr ""
|
||||
|
||||
msgid "Checkout|CI minute packs"
|
||||
msgid "Checkout|CI minute pack"
|
||||
msgstr ""
|
||||
|
||||
msgid "Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year."
|
||||
|
|
|
|||
|
|
@ -18,9 +18,11 @@ require_relative '../config/settings'
|
|||
require_relative 'support/rspec'
|
||||
require 'active_support/all'
|
||||
|
||||
ActiveSupport::Dependencies.autoload_paths << 'lib'
|
||||
ActiveSupport::Dependencies.autoload_paths << 'ee/lib'
|
||||
ActiveSupport::Dependencies.autoload_paths << 'jh/lib'
|
||||
unless ActiveSupport::Dependencies.autoload_paths.frozen?
|
||||
ActiveSupport::Dependencies.autoload_paths << 'lib'
|
||||
ActiveSupport::Dependencies.autoload_paths << 'ee/lib'
|
||||
ActiveSupport::Dependencies.autoload_paths << 'jh/lib'
|
||||
end
|
||||
|
||||
ActiveSupport::XmlMini.backend = 'Nokogiri'
|
||||
|
||||
|
|
|
|||
|
|
@ -267,28 +267,11 @@ describe('Pipeline graph wrapper', () => {
|
|||
});
|
||||
|
||||
describe('view dropdown', () => {
|
||||
describe('when pipelineGraphLayersView feature flag is off', () => {
|
||||
beforeEach(async () => {
|
||||
createComponentWithApollo();
|
||||
jest.runOnlyPendingTimers();
|
||||
await wrapper.vm.$nextTick();
|
||||
});
|
||||
|
||||
it('does not appear', () => {
|
||||
expect(getViewSelector().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when pipelineGraphLayersView feature flag is on', () => {
|
||||
describe('default', () => {
|
||||
let layersFn;
|
||||
beforeEach(async () => {
|
||||
layersFn = jest.spyOn(parsingUtils, 'listByLayers');
|
||||
createComponentWithApollo({
|
||||
provide: {
|
||||
glFeatures: {
|
||||
pipelineGraphLayersView: true,
|
||||
},
|
||||
},
|
||||
mountFn: mount,
|
||||
});
|
||||
|
||||
|
|
@ -326,14 +309,9 @@ describe('Pipeline graph wrapper', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('when pipelineGraphLayersView feature flag is on and layers view is selected', () => {
|
||||
describe('when layers view is selected', () => {
|
||||
beforeEach(async () => {
|
||||
createComponentWithApollo({
|
||||
provide: {
|
||||
glFeatures: {
|
||||
pipelineGraphLayersView: true,
|
||||
},
|
||||
},
|
||||
data: {
|
||||
currentViewType: LAYER_VIEW,
|
||||
},
|
||||
|
|
@ -356,14 +334,9 @@ describe('Pipeline graph wrapper', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('when pipelineGraphLayersView feature flag is on, layers view is selected, and links are active', () => {
|
||||
describe('when layers view is selected, and links are active', () => {
|
||||
beforeEach(async () => {
|
||||
createComponentWithApollo({
|
||||
provide: {
|
||||
glFeatures: {
|
||||
pipelineGraphLayersView: true,
|
||||
},
|
||||
},
|
||||
data: {
|
||||
currentViewType: LAYER_VIEW,
|
||||
showLinks: true,
|
||||
|
|
@ -384,11 +357,6 @@ describe('Pipeline graph wrapper', () => {
|
|||
describe('when hover tip would otherwise show, but it has been previously dismissed', () => {
|
||||
beforeEach(async () => {
|
||||
createComponentWithApollo({
|
||||
provide: {
|
||||
glFeatures: {
|
||||
pipelineGraphLayersView: true,
|
||||
},
|
||||
},
|
||||
data: {
|
||||
currentViewType: LAYER_VIEW,
|
||||
showLinks: true,
|
||||
|
|
@ -412,11 +380,6 @@ describe('Pipeline graph wrapper', () => {
|
|||
localStorage.setItem(VIEW_TYPE_KEY, LAYER_VIEW);
|
||||
|
||||
createComponentWithApollo({
|
||||
provide: {
|
||||
glFeatures: {
|
||||
pipelineGraphLayersView: true,
|
||||
},
|
||||
},
|
||||
mountFn: mount,
|
||||
});
|
||||
|
||||
|
|
@ -444,11 +407,6 @@ describe('Pipeline graph wrapper', () => {
|
|||
localStorage.setItem(VIEW_TYPE_KEY, LAYER_VIEW);
|
||||
|
||||
createComponentWithApollo({
|
||||
provide: {
|
||||
glFeatures: {
|
||||
pipelineGraphLayersView: true,
|
||||
},
|
||||
},
|
||||
mountFn: mount,
|
||||
getPipelineDetailsHandler: jest.fn().mockResolvedValue(nonNeedsResponse),
|
||||
});
|
||||
|
|
@ -472,11 +430,6 @@ describe('Pipeline graph wrapper', () => {
|
|||
nonNeedsResponse.data.project.pipeline.usesNeeds = false;
|
||||
|
||||
createComponentWithApollo({
|
||||
provide: {
|
||||
glFeatures: {
|
||||
pipelineGraphLayersView: true,
|
||||
},
|
||||
},
|
||||
mountFn: mount,
|
||||
getPipelineDetailsHandler: jest.fn().mockResolvedValue(nonNeedsResponse),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -183,18 +183,17 @@ RSpec.describe Gitlab::Database::LoadBalancing::RackMiddleware, :redis do
|
|||
describe '#clear' do
|
||||
it 'clears the currently used host and session' do
|
||||
lb = double(:lb)
|
||||
session = double(:session)
|
||||
session = spy(:session)
|
||||
|
||||
allow(middleware).to receive(:load_balancer).and_return(lb)
|
||||
|
||||
expect(lb).to receive(:release_host)
|
||||
|
||||
stub_const('Gitlab::Database::LoadBalancing::RackMiddleware::Session',
|
||||
session)
|
||||
|
||||
expect(session).to receive(:clear_session)
|
||||
stub_const('Gitlab::Database::LoadBalancing::Session', session)
|
||||
|
||||
middleware.clear
|
||||
|
||||
expect(session).to have_received(:clear_session)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -57,22 +57,21 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
|
|||
.and_yield
|
||||
end
|
||||
|
||||
it 'starts service discovery in a new thread' do
|
||||
expect(service)
|
||||
.to receive(:refresh_if_necessary)
|
||||
.and_return(5)
|
||||
it 'runs service discovery once before starting the worker thread' do
|
||||
expect(service).to receive(:perform_service_discovery).ordered.and_return(5)
|
||||
|
||||
expect(service)
|
||||
.to receive(:rand)
|
||||
.and_return(2)
|
||||
expect(Thread).to receive(:new).ordered.and_call_original # Thread starts
|
||||
|
||||
expect(service)
|
||||
.to receive(:sleep)
|
||||
.with(7)
|
||||
expect(service).to receive(:rand).ordered.and_return(2)
|
||||
expect(service).to receive(:sleep).ordered.with(7) # Sleep runs after thread starts
|
||||
|
||||
expect(service).to receive(:perform_service_discovery).ordered.and_return(1)
|
||||
|
||||
service.start.join
|
||||
end
|
||||
end
|
||||
|
||||
describe '#perform_service_discovery' do
|
||||
it 'reports exceptions to Sentry' do
|
||||
error = StandardError.new
|
||||
|
||||
|
|
@ -84,15 +83,7 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
|
|||
.to receive(:track_exception)
|
||||
.with(error)
|
||||
|
||||
expect(service)
|
||||
.to receive(:rand)
|
||||
.and_return(2)
|
||||
|
||||
expect(service)
|
||||
.to receive(:sleep)
|
||||
.with(62)
|
||||
|
||||
service.start.join
|
||||
service.perform_service_discovery
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ RSpec.describe BackfillIssuesUpvotesCount do
|
|||
let!(:award_emoji3) { award_emoji.create!( name: 'thumbsup', awardable_type: 'Issue', awardable_id: issue3.id) }
|
||||
let!(:award_emoji4) { award_emoji.create!( name: 'thumbsup', awardable_type: 'Issue', awardable_id: issue4.id) }
|
||||
|
||||
it 'correctly schedules background migrations' do
|
||||
it 'correctly schedules background migrations', :aggregate_failures do
|
||||
stub_const("#{described_class.name}::BATCH_SIZE", 2)
|
||||
|
||||
Sidekiq::Testing.fake! do
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe ReleaseHighlight, :clean_gitlab_redis_cache do
|
||||
let(:fixture_dir_glob) { Dir.glob(File.join('spec', 'fixtures', 'whats_new', '*.yml')).grep(/\d*\_(\d*\_\d*)\.yml$/) }
|
||||
let(:fixture_dir_glob) { Dir.glob(File.join(Rails.root, 'spec', 'fixtures', 'whats_new', '*.yml')).grep(/\d*\_(\d*\_\d*)\.yml$/) }
|
||||
|
||||
before do
|
||||
allow(Dir).to receive(:glob).with(Rails.root.join('data', 'whats_new', '*.yml')).and_return(fixture_dir_glob)
|
||||
|
|
@ -193,4 +193,12 @@ RSpec.describe ReleaseHighlight, :clean_gitlab_redis_cache do
|
|||
expect(subject).to eq('Free')
|
||||
end
|
||||
end
|
||||
|
||||
describe '.file_paths' do
|
||||
it 'joins relative file paths with the root path to avoid caching the root url' do
|
||||
allow(described_class).to receive(:relative_file_paths).and_return([+'/a.yml'])
|
||||
|
||||
expect(described_class.file_paths.first).to eq("#{Rails.root}/a.yml")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'fast_spec_helper'
|
||||
|
||||
ActiveSupport::Dependencies.autoload_paths << 'app/services'
|
||||
require_relative '../../app/services/service_response'
|
||||
|
||||
RSpec.describe ServiceResponse do
|
||||
describe '.success' do
|
||||
|
|
|
|||
Loading…
Reference in New Issue