Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
2dedd78ef5
commit
f4d51a9f71
|
@ -717,7 +717,7 @@ GEM
|
|||
reverse_markdown (~> 1.0)
|
||||
rugged (>= 0.24, < 2.0)
|
||||
thor (>= 0.19, < 2.0)
|
||||
listen (3.2.1)
|
||||
listen (3.6.0)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
locale (2.1.3)
|
||||
|
@ -1198,7 +1198,7 @@ GEM
|
|||
simplecov-html (~> 0.11)
|
||||
simplecov-cobertura (1.3.1)
|
||||
simplecov (~> 0.8)
|
||||
simplecov-html (0.12.2)
|
||||
simplecov-html (0.12.3)
|
||||
sixarm_ruby_unaccent (1.2.0)
|
||||
slack-messenger (2.3.4)
|
||||
snowplow-tracker (0.6.1)
|
||||
|
|
|
@ -25,6 +25,11 @@ export default {
|
|||
required: false,
|
||||
default: false,
|
||||
},
|
||||
isBinary: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
activeViewerType: {
|
||||
type: String,
|
||||
required: false,
|
||||
|
@ -81,6 +86,7 @@ export default {
|
|||
:raw-path="blob.rawPath"
|
||||
:active-viewer="viewer"
|
||||
:has-render-error="hasRenderError"
|
||||
:is-binary="isBinary"
|
||||
@copy="proxyCopyRequest"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -32,6 +32,11 @@ export default {
|
|||
required: false,
|
||||
default: false,
|
||||
},
|
||||
isBinary: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
downloadUrl() {
|
||||
|
@ -43,6 +48,9 @@ export default {
|
|||
getBlobHashTarget() {
|
||||
return `[data-blob-hash="${this.blobHash}"]`;
|
||||
},
|
||||
showCopyButton() {
|
||||
return !this.hasRenderError && !this.isBinary;
|
||||
},
|
||||
},
|
||||
BTN_COPY_CONTENTS_TITLE,
|
||||
BTN_DOWNLOAD_TITLE,
|
||||
|
@ -52,7 +60,7 @@ export default {
|
|||
<template>
|
||||
<gl-button-group data-qa-selector="default_actions_container">
|
||||
<gl-button
|
||||
v-if="!hasRenderError"
|
||||
v-if="showCopyButton"
|
||||
v-gl-tooltip.hover
|
||||
:aria-label="$options.BTN_COPY_CONTENTS_TITLE"
|
||||
:title="$options.BTN_COPY_CONTENTS_TITLE"
|
||||
|
@ -65,6 +73,7 @@ export default {
|
|||
variant="default"
|
||||
/>
|
||||
<gl-button
|
||||
v-if="!isBinary"
|
||||
v-gl-tooltip.hover
|
||||
:aria-label="$options.BTN_RAW_TITLE"
|
||||
:title="$options.BTN_RAW_TITLE"
|
||||
|
|
|
@ -7,4 +7,5 @@ fragment TimelogFragment on Timelog {
|
|||
note {
|
||||
body
|
||||
}
|
||||
summary
|
||||
}
|
||||
|
|
|
@ -169,6 +169,7 @@ export default {
|
|||
<blob-header
|
||||
:blob="blobInfo"
|
||||
:hide-viewer-switcher="!hasRichViewer || isBinary"
|
||||
:is-binary="isBinary"
|
||||
:active-viewer-type="viewer.type"
|
||||
:has-render-error="hasRenderError"
|
||||
@viewer-changed="switchViewer"
|
||||
|
|
|
@ -62,8 +62,8 @@ export default {
|
|||
formatDate(date) {
|
||||
return formatDate(date, TIME_DATE_FORMAT);
|
||||
},
|
||||
getNote(note) {
|
||||
return note?.body;
|
||||
getSummary(summary, note) {
|
||||
return summary ?? note?.body;
|
||||
},
|
||||
getTotalTimeSpent() {
|
||||
const seconds = this.report.reduce((acc, item) => acc + item.timeSpent, 0);
|
||||
|
@ -81,7 +81,7 @@ export default {
|
|||
{ key: 'spentAt', label: __('Spent At'), sortable: true },
|
||||
{ key: 'user', label: __('User'), sortable: true },
|
||||
{ key: 'timeSpent', label: __('Time Spent'), sortable: true },
|
||||
{ key: 'note', label: __('Note'), sortable: true },
|
||||
{ key: 'summary', label: __('Summary / Note'), sortable: true },
|
||||
],
|
||||
};
|
||||
</script>
|
||||
|
@ -107,8 +107,8 @@ export default {
|
|||
<div>{{ getTotalTimeSpent() }}</div>
|
||||
</template>
|
||||
|
||||
<template #cell(note)="{ item: { note } }">
|
||||
<div>{{ getNote(note) }}</div>
|
||||
<template #cell(summary)="{ item: { summary, note } }">
|
||||
<div>{{ getSummary(summary, note) }}</div>
|
||||
</template>
|
||||
<template #foot(note)> </template>
|
||||
</gl-table>
|
||||
|
|
|
@ -71,7 +71,7 @@ class Admin::SessionsController < ApplicationController
|
|||
::Users::ValidateOtpService.new(user).execute(user_params[:otp_attempt])
|
||||
valid_otp_attempt = otp_validation_result[:status] == :success
|
||||
|
||||
return valid_otp_attempt if Gitlab::Database.read_only?
|
||||
return valid_otp_attempt if Gitlab::Database.main.read_only?
|
||||
|
||||
valid_otp_attempt || user.invalidate_otp_backup_code!(user_params[:otp_attempt])
|
||||
end
|
||||
|
|
|
@ -27,7 +27,7 @@ module Boards
|
|||
list_service = Boards::Issues::ListService.new(board_parent, current_user, filter_params)
|
||||
issues = issues_from(list_service)
|
||||
|
||||
if Gitlab::Database.read_write? && !board.disabled_for?(current_user)
|
||||
if Gitlab::Database.main.read_write? && !board.disabled_for?(current_user)
|
||||
Issue.move_nulls_to_end(issues)
|
||||
end
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ module AuthenticatesWithTwoFactorForAdminMode
|
|||
# Remove any lingering user data from login
|
||||
session.delete(:otp_user_id)
|
||||
|
||||
user.save! unless Gitlab::Database.read_only?
|
||||
user.save! unless Gitlab::Database.main.read_only?
|
||||
|
||||
# The admin user has successfully passed 2fa, enable admin mode ignoring password
|
||||
enable_admin_mode
|
||||
|
|
|
@ -148,7 +148,7 @@ module IssuableActions
|
|||
# on GET requests.
|
||||
# This is just a fail-safe in case notes_filter is sent via GET request in GitLab Geo.
|
||||
# In some cases, we also force the filter to not be persisted with the `persist_filter` param
|
||||
if Gitlab::Database.read_only? || params[:persist_filter] == 'false'
|
||||
if Gitlab::Database.main.read_only? || params[:persist_filter] == 'false'
|
||||
notes_filter_param || current_user&.notes_filter_for(issuable)
|
||||
else
|
||||
notes_filter = current_user&.set_notes_filter(notes_filter_param, issuable) || notes_filter_param
|
||||
|
|
|
@ -17,7 +17,7 @@ module RecordUserLastActivity
|
|||
|
||||
def set_user_last_activity
|
||||
return unless request.get?
|
||||
return if Gitlab::Database.read_only?
|
||||
return if Gitlab::Database.main.read_only?
|
||||
|
||||
if current_user && current_user.last_activity_on != Date.today
|
||||
Users::ActivityService.new(current_user).execute
|
||||
|
|
|
@ -41,7 +41,7 @@ module SortingPreference
|
|||
sort_param = params[:sort]
|
||||
sort_param ||= user_preference[field]
|
||||
|
||||
return sort_param if Gitlab::Database.read_only?
|
||||
return sort_param if Gitlab::Database.main.read_only?
|
||||
|
||||
if user_preference[field] != sort_param
|
||||
user_preference.update(field => sort_param)
|
||||
|
|
|
@ -77,7 +77,7 @@ module Repositories
|
|||
|
||||
def update_fetch_statistics
|
||||
return unless project
|
||||
return if Gitlab::Database.read_only?
|
||||
return if Gitlab::Database.main.read_only?
|
||||
return unless repo_type.project?
|
||||
|
||||
OnboardingProgressService.async(project.namespace_id).execute(action: :git_pull)
|
||||
|
|
|
@ -126,7 +126,7 @@ module Repositories
|
|||
|
||||
# Overridden in EE
|
||||
def batch_operation_disallowed?
|
||||
upload_request? && Gitlab::Database.read_only?
|
||||
upload_request? && Gitlab::Database.main.read_only?
|
||||
end
|
||||
|
||||
# Overridden in EE
|
||||
|
|
|
@ -29,7 +29,7 @@ module Mutations
|
|||
end
|
||||
|
||||
def ready?(**args)
|
||||
raise_resource_not_available_error! ERROR_MESSAGE if Gitlab::Database.read_only?
|
||||
raise_resource_not_available_error! ERROR_MESSAGE if Gitlab::Database.main.read_only?
|
||||
|
||||
missing_args = self.class.arguments.values
|
||||
.reject { |arg| arg.accepts?(args.fetch(arg.keyword, :not_given)) }
|
||||
|
|
|
@ -23,6 +23,10 @@ module Mutations
|
|||
required: false,
|
||||
description: 'The IDs of labels to be removed from the issue.'
|
||||
|
||||
argument :label_ids, [GraphQL::Types::ID],
|
||||
required: false,
|
||||
description: 'The IDs of labels to be set. Replaces existing issue labels.'
|
||||
|
||||
argument :state_event, Types::IssueStateEventEnum,
|
||||
description: 'Close or reopen an issue.',
|
||||
required: false
|
||||
|
@ -31,6 +35,8 @@ module Mutations
|
|||
issue = authorized_find!(project_path: project_path, iid: iid)
|
||||
project = issue.project
|
||||
|
||||
args = parse_arguments(args)
|
||||
|
||||
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
|
||||
::Issues::UpdateService.new(project: project, current_user: current_user, params: args, spam_params: spam_params).execute(issue)
|
||||
|
||||
|
@ -39,6 +45,32 @@ module Mutations
|
|||
errors: errors_on_object(issue)
|
||||
}
|
||||
end
|
||||
|
||||
def ready?(label_ids: [], add_label_ids: [], remove_label_ids: [], **args)
|
||||
if label_ids.any? && (add_label_ids.any? || remove_label_ids.any?)
|
||||
raise Gitlab::Graphql::Errors::ArgumentError, 'labelIds is mutually exclusive with any of addLabelIds or removeLabelIds'
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def parse_arguments(args)
|
||||
args[:add_label_ids] = parse_label_ids(args[:add_label_ids])
|
||||
args[:remove_label_ids] = parse_label_ids(args[:remove_label_ids])
|
||||
args[:label_ids] = parse_label_ids(args[:label_ids])
|
||||
|
||||
args
|
||||
end
|
||||
|
||||
def parse_label_ids(ids)
|
||||
ids&.map do |gid|
|
||||
GitlabSchema.parse_gid(gid, expected_type: ::Label).model_id
|
||||
rescue Gitlab::Graphql::Errors::ArgumentError
|
||||
gid
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Resolvers
|
||||
class MergeRequestsCountResolver < BaseResolver
|
||||
type GraphQL::Types::Int, null: true
|
||||
|
||||
def resolve
|
||||
BatchLoader::GraphQL.for(object.id).batch do |ids, loader, args|
|
||||
counts = MergeRequestsClosingIssues.count_for_collection(ids, context[:current_user]).to_h
|
||||
|
||||
ids.each do |id|
|
||||
loader.call(id, counts[id] || 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -60,6 +60,9 @@ module Types
|
|||
description: 'Number of upvotes the issue has received.'
|
||||
field :downvotes, GraphQL::Types::Int, null: false,
|
||||
description: 'Number of downvotes the issue has received.'
|
||||
field :merge_requests_count, GraphQL::Types::Int, null: false,
|
||||
description: 'Number of merge requests that close the issue on merge.',
|
||||
resolver: Resolvers::MergeRequestsCountResolver
|
||||
field :user_notes_count, GraphQL::Types::Int, null: false,
|
||||
description: 'Number of user notes of the issue.',
|
||||
resolver: Resolvers::UserNotesCountResolver
|
||||
|
|
|
@ -36,6 +36,10 @@ module Types
|
|||
null: true,
|
||||
description: 'The note where the quick action to add the logged time was executed.'
|
||||
|
||||
field :summary, GraphQL::Types::String,
|
||||
null: true,
|
||||
description: 'The summary of how the time was spent.'
|
||||
|
||||
def user
|
||||
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.user_id).find
|
||||
end
|
||||
|
|
|
@ -344,7 +344,7 @@ module ApplicationHelper
|
|||
|
||||
# Overridden in EE
|
||||
def read_only_message
|
||||
return unless Gitlab::Database.read_only?
|
||||
return unless Gitlab::Database.main.read_only?
|
||||
|
||||
_('You are on a read-only GitLab instance.')
|
||||
end
|
||||
|
|
|
@ -219,11 +219,11 @@ module ApplicationSettingImplementation
|
|||
end
|
||||
|
||||
def home_page_url_column_exists?
|
||||
::Gitlab::Database.cached_column_exists?(:application_settings, :home_page_url)
|
||||
::Gitlab::Database.main.cached_column_exists?(:application_settings, :home_page_url)
|
||||
end
|
||||
|
||||
def help_page_support_url_column_exists?
|
||||
::Gitlab::Database.cached_column_exists?(:application_settings, :help_page_support_url)
|
||||
::Gitlab::Database.main.cached_column_exists?(:application_settings, :help_page_support_url)
|
||||
end
|
||||
|
||||
def disabled_oauth_sign_in_sources=(sources)
|
||||
|
|
|
@ -127,7 +127,7 @@ module CascadingNamespaceSettingAttribute
|
|||
end
|
||||
|
||||
def alias_boolean(attribute)
|
||||
return unless Gitlab::Database.exists? && type_for_attribute(attribute).type == :boolean
|
||||
return unless Gitlab::Database.main.exists? && type_for_attribute(attribute).type == :boolean
|
||||
|
||||
alias_method :"#{attribute}?", attribute
|
||||
end
|
||||
|
|
|
@ -34,7 +34,7 @@ module DeprecatedAssignee
|
|||
end
|
||||
|
||||
def assignee_ids
|
||||
if Gitlab::Database.read_only? && pending_assignees_population?
|
||||
if Gitlab::Database.main.read_only? && pending_assignees_population?
|
||||
return Array(deprecated_assignee_id)
|
||||
end
|
||||
|
||||
|
@ -43,7 +43,7 @@ module DeprecatedAssignee
|
|||
end
|
||||
|
||||
def assignees
|
||||
if Gitlab::Database.read_only? && pending_assignees_population?
|
||||
if Gitlab::Database.main.read_only? && pending_assignees_population?
|
||||
return User.where(id: deprecated_assignee_id)
|
||||
end
|
||||
|
||||
|
@ -56,7 +56,7 @@ module DeprecatedAssignee
|
|||
# This will make the background migration process quicker (#26496) as it'll have less
|
||||
# assignee_id rows to look through.
|
||||
def nullify_deprecated_assignee
|
||||
return unless persisted? && Gitlab::Database.read_only?
|
||||
return unless persisted? && Gitlab::Database.main.read_only?
|
||||
|
||||
update_column(:assignee_id, nil)
|
||||
end
|
||||
|
|
|
@ -39,7 +39,7 @@ module Sha256Attribute
|
|||
end
|
||||
|
||||
def database_exists?
|
||||
Gitlab::Database.exists?
|
||||
Gitlab::Database.main.exists?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,7 +32,7 @@ module ShaAttribute
|
|||
end
|
||||
|
||||
def database_exists?
|
||||
Gitlab::Database.exists?
|
||||
Gitlab::Database.main.exists?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -41,7 +41,7 @@ module TokenAuthenticatableStrategies
|
|||
# Resets the token, but only saves when the database is in read & write mode
|
||||
def reset_token!(instance)
|
||||
write_new_token(instance)
|
||||
instance.save! if Gitlab::Database.read_write?
|
||||
instance.save! if Gitlab::Database.main.read_write?
|
||||
end
|
||||
|
||||
def self.fabricate(model, field, options)
|
||||
|
|
|
@ -39,7 +39,7 @@ module X509SerialNumberAttribute
|
|||
end
|
||||
|
||||
def database_exists?
|
||||
Gitlab::Database.exists?
|
||||
Gitlab::Database.main.exists?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -289,7 +289,7 @@ class Deployment < ApplicationRecord
|
|||
"#{id} as deployment_id",
|
||||
"#{environment_id} as environment_id").to_sql
|
||||
|
||||
# We don't use `Gitlab::Database.bulk_insert` here so that we don't need to
|
||||
# We don't use `Gitlab::Database.main.bulk_insert` here so that we don't need to
|
||||
# first pluck lots of IDs into memory.
|
||||
#
|
||||
# We also ignore any duplicates so this method can be called multiple times
|
||||
|
|
|
@ -88,7 +88,7 @@ module DesignManagement
|
|||
|
||||
rows = design_actions.map { |action| action.row_attrs(version) }
|
||||
|
||||
Gitlab::Database.bulk_insert(::DesignManagement::Action.table_name, rows) # rubocop:disable Gitlab/BulkInsert
|
||||
Gitlab::Database.main.bulk_insert(::DesignManagement::Action.table_name, rows) # rubocop:disable Gitlab/BulkInsert
|
||||
version.designs.reset
|
||||
version.validate!
|
||||
design_actions.each(&:performed)
|
||||
|
|
|
@ -78,6 +78,7 @@ class Environment < ApplicationRecord
|
|||
scope :for_name, -> (name) { where(name: name) }
|
||||
scope :preload_cluster, -> { preload(last_deployment: :cluster) }
|
||||
scope :auto_stoppable, -> (limit) { available.where('auto_stop_at < ?', Time.zone.now).limit(limit) }
|
||||
scope :auto_deletable, -> (limit) { stopped.where('auto_delete_at < ?', Time.zone.now).limit(limit) }
|
||||
|
||||
##
|
||||
# Search environments which have names like the given query.
|
||||
|
|
|
@ -11,6 +11,7 @@ class JiraConnectInstallation < ApplicationRecord
|
|||
validates :client_key, presence: true, uniqueness: true
|
||||
validates :shared_secret, presence: true
|
||||
validates :base_url, presence: true, public_url: true
|
||||
validates :instance_url, public_url: true, allow_blank: true
|
||||
|
||||
scope :for_project, -> (project) {
|
||||
distinct
|
||||
|
|
|
@ -175,6 +175,8 @@ class Member < ApplicationRecord
|
|||
after_update :post_update_hook, unless: [:pending?, :importing?], if: :hook_prerequisites_met?
|
||||
after_destroy :destroy_notification_setting
|
||||
after_destroy :post_destroy_hook, unless: :pending?, if: :hook_prerequisites_met?
|
||||
after_save :log_invitation_token_cleanup
|
||||
|
||||
after_commit :refresh_member_authorized_projects
|
||||
|
||||
default_value_for :notification_level, NotificationSetting.levels[:global]
|
||||
|
@ -449,6 +451,13 @@ class Member < ApplicationRecord
|
|||
def project_bot?
|
||||
user&.project_bot?
|
||||
end
|
||||
|
||||
def log_invitation_token_cleanup
|
||||
return true unless Gitlab.com? && invite? && invite_accepted_at?
|
||||
|
||||
error = StandardError.new("Invitation token is present but invite was already accepted!")
|
||||
Gitlab::ErrorTracking.track_exception(error, attributes.slice(%w["invite_accepted_at created_at source_type source_id user_id id"]))
|
||||
end
|
||||
end
|
||||
|
||||
Member.prepend_mod_with('Member')
|
||||
|
|
|
@ -26,7 +26,7 @@ class MergeRequestContextCommit < ApplicationRecord
|
|||
|
||||
# create MergeRequestContextCommit by given commit sha and it's diff file record
|
||||
def self.bulk_insert(rows, **args)
|
||||
Gitlab::Database.bulk_insert('merge_request_context_commits', rows, **args) # rubocop:disable Gitlab/BulkInsert
|
||||
Gitlab::Database.main.bulk_insert('merge_request_context_commits', rows, **args) # rubocop:disable Gitlab/BulkInsert
|
||||
end
|
||||
|
||||
def to_commit
|
||||
|
|
|
@ -14,7 +14,7 @@ class MergeRequestContextCommitDiffFile < ApplicationRecord
|
|||
|
||||
# create MergeRequestContextCommitDiffFile by given diff file record(s)
|
||||
def self.bulk_insert(*args)
|
||||
Gitlab::Database.bulk_insert('merge_request_context_commit_diff_files', *args) # rubocop:disable Gitlab/BulkInsert
|
||||
Gitlab::Database.main.bulk_insert('merge_request_context_commit_diff_files', *args) # rubocop:disable Gitlab/BulkInsert
|
||||
end
|
||||
|
||||
def path
|
||||
|
|
|
@ -515,7 +515,7 @@ class MergeRequestDiff < ApplicationRecord
|
|||
|
||||
transaction do
|
||||
MergeRequestDiffFile.where(merge_request_diff_id: id).delete_all
|
||||
Gitlab::Database.bulk_insert('merge_request_diff_files', rows) # rubocop:disable Gitlab/BulkInsert
|
||||
Gitlab::Database.main.bulk_insert('merge_request_diff_files', rows) # rubocop:disable Gitlab/BulkInsert
|
||||
save!
|
||||
end
|
||||
|
||||
|
@ -535,7 +535,7 @@ class MergeRequestDiff < ApplicationRecord
|
|||
|
||||
transaction do
|
||||
MergeRequestDiffFile.where(merge_request_diff_id: id).delete_all
|
||||
Gitlab::Database.bulk_insert('merge_request_diff_files', rows) # rubocop:disable Gitlab/BulkInsert
|
||||
Gitlab::Database.main.bulk_insert('merge_request_diff_files', rows) # rubocop:disable Gitlab/BulkInsert
|
||||
update!(stored_externally: false)
|
||||
end
|
||||
|
||||
|
@ -595,7 +595,7 @@ class MergeRequestDiff < ApplicationRecord
|
|||
rows = build_external_merge_request_diff_files(rows) if use_external_diff?
|
||||
|
||||
# Faster inserts
|
||||
Gitlab::Database.bulk_insert('merge_request_diff_files', rows) # rubocop:disable Gitlab/BulkInsert
|
||||
Gitlab::Database.main.bulk_insert('merge_request_diff_files', rows) # rubocop:disable Gitlab/BulkInsert
|
||||
end
|
||||
|
||||
def build_external_diff_tempfile(rows)
|
||||
|
|
|
@ -63,7 +63,7 @@ class MergeRequestDiffCommit < ApplicationRecord
|
|||
)
|
||||
end
|
||||
|
||||
Gitlab::Database.bulk_insert(self.table_name, rows) # rubocop:disable Gitlab/BulkInsert
|
||||
Gitlab::Database.main.bulk_insert(self.table_name, rows) # rubocop:disable Gitlab/BulkInsert
|
||||
end
|
||||
|
||||
def self.prepare_commits_for_bulk_insert(commits)
|
||||
|
|
|
@ -587,7 +587,7 @@ class Note < ApplicationRecord
|
|||
end
|
||||
|
||||
def post_processed_cache_key
|
||||
cache_key_items = [cache_key]
|
||||
cache_key_items = [cache_key, author.cache_key]
|
||||
cache_key_items << Digest::SHA1.hexdigest(redacted_note_html) if redacted_note_html.present?
|
||||
|
||||
cache_key_items.join(':')
|
||||
|
|
|
@ -2818,11 +2818,11 @@ class Project < ApplicationRecord
|
|||
end
|
||||
|
||||
def cache_has_external_wiki
|
||||
update_column(:has_external_wiki, integrations.external_wikis.any?) if Gitlab::Database.read_write?
|
||||
update_column(:has_external_wiki, integrations.external_wikis.any?) if Gitlab::Database.main.read_write?
|
||||
end
|
||||
|
||||
def cache_has_external_issue_tracker
|
||||
update_column(:has_external_issue_tracker, integrations.external_issue_trackers.any?) if Gitlab::Database.read_write?
|
||||
update_column(:has_external_issue_tracker, integrations.external_issue_trackers.any?) if Gitlab::Database.main.read_write?
|
||||
end
|
||||
|
||||
def active_runners_with_tags
|
||||
|
|
|
@ -38,7 +38,7 @@ class ProjectStatistics < ApplicationRecord
|
|||
end
|
||||
|
||||
def refresh!(only: [])
|
||||
return if Gitlab::Database.read_only?
|
||||
return if Gitlab::Database.main.read_only?
|
||||
|
||||
COLUMNS_TO_REFRESH.each do |column, generator|
|
||||
if only.empty? || only.include?(column)
|
||||
|
|
|
@ -34,7 +34,7 @@ class SnippetStatistics < ApplicationRecord
|
|||
end
|
||||
|
||||
def refresh!
|
||||
return if Gitlab::Database.read_only?
|
||||
return if Gitlab::Database.main.read_only?
|
||||
|
||||
update_commit_count
|
||||
update_repository_size
|
||||
|
|
|
@ -80,7 +80,7 @@ class User < ApplicationRecord
|
|||
# to limit database writes to at most once every hour
|
||||
# rubocop: disable CodeReuse/ServiceClass
|
||||
def update_tracked_fields!(request)
|
||||
return if Gitlab::Database.read_only?
|
||||
return if Gitlab::Database.main.read_only?
|
||||
|
||||
update_tracked_fields(request)
|
||||
|
||||
|
@ -363,7 +363,7 @@ class User < ApplicationRecord
|
|||
end
|
||||
|
||||
before_transition do
|
||||
!Gitlab::Database.read_only?
|
||||
!Gitlab::Database.main.read_only?
|
||||
end
|
||||
|
||||
# rubocop: disable CodeReuse/ServiceClass
|
||||
|
@ -848,11 +848,11 @@ class User < ApplicationRecord
|
|||
end
|
||||
|
||||
def remember_me!
|
||||
super if ::Gitlab::Database.read_write?
|
||||
super if ::Gitlab::Database.main.read_write?
|
||||
end
|
||||
|
||||
def forget_me!
|
||||
super if ::Gitlab::Database.read_write?
|
||||
super if ::Gitlab::Database.main.read_write?
|
||||
end
|
||||
|
||||
def disable_two_factor!
|
||||
|
@ -1750,7 +1750,7 @@ class User < ApplicationRecord
|
|||
#
|
||||
# rubocop: disable CodeReuse/ServiceClass
|
||||
def increment_failed_attempts!
|
||||
return if ::Gitlab::Database.read_only?
|
||||
return if ::Gitlab::Database.main.read_only?
|
||||
|
||||
increment_failed_attempts
|
||||
|
||||
|
@ -1994,7 +1994,7 @@ class User < ApplicationRecord
|
|||
def consume_otp!
|
||||
if self.consumed_timestep != current_otp_timestep
|
||||
self.consumed_timestep = current_otp_timestep
|
||||
return Gitlab::Database.read_only? ? true : save(validate: false)
|
||||
return Gitlab::Database.main.read_only? ? true : save(validate: false)
|
||||
end
|
||||
|
||||
false
|
||||
|
|
|
@ -111,7 +111,7 @@ class AuditEventService
|
|||
end
|
||||
|
||||
def log_security_event_to_database
|
||||
return if Gitlab::Database.read_only?
|
||||
return if Gitlab::Database.main.read_only?
|
||||
|
||||
event = AuditEvent.new(base_payload.merge(details: @details))
|
||||
save_or_track event
|
||||
|
@ -120,7 +120,7 @@ class AuditEventService
|
|||
end
|
||||
|
||||
def log_authentication_event_to_database
|
||||
return unless Gitlab::Database.read_write? && authentication_event?
|
||||
return unless Gitlab::Database.main.read_write? && authentication_event?
|
||||
|
||||
event = AuthenticationEvent.new(authentication_event_payload)
|
||||
save_or_track event
|
||||
|
|
|
@ -4,7 +4,7 @@ module Boards
|
|||
module Visits
|
||||
class CreateService < Boards::BaseService
|
||||
def execute(board)
|
||||
return unless current_user && Gitlab::Database.read_write?
|
||||
return unless current_user && Gitlab::Database.main.read_write?
|
||||
return unless board
|
||||
|
||||
model.visited!(current_user, board)
|
||||
|
|
|
@ -11,11 +11,12 @@ module Ci
|
|||
Gitlab::Ci::Pipeline::Chain::Validate::Abilities,
|
||||
Gitlab::Ci::Pipeline::Chain::Validate::Repository,
|
||||
Gitlab::Ci::Pipeline::Chain::Validate::SecurityOrchestrationPolicy,
|
||||
Gitlab::Ci::Pipeline::Chain::Skip,
|
||||
Gitlab::Ci::Pipeline::Chain::Config::Content,
|
||||
Gitlab::Ci::Pipeline::Chain::Config::Process,
|
||||
Gitlab::Ci::Pipeline::Chain::Validate::AfterConfig,
|
||||
Gitlab::Ci::Pipeline::Chain::RemoveUnwantedChatJobs,
|
||||
Gitlab::Ci::Pipeline::Chain::Skip,
|
||||
Gitlab::Ci::Pipeline::Chain::LegacySkip,
|
||||
Gitlab::Ci::Pipeline::Chain::SeedBlock,
|
||||
Gitlab::Ci::Pipeline::Chain::EvaluateWorkflowRules,
|
||||
Gitlab::Ci::Pipeline::Chain::Seed,
|
||||
|
|
|
@ -181,12 +181,12 @@ module DesignManagement
|
|||
)
|
||||
end
|
||||
|
||||
# TODO Replace `Gitlab::Database.bulk_insert` with `BulkInsertSafe`
|
||||
# TODO Replace `Gitlab::Database.main.bulk_insert` with `BulkInsertSafe`
|
||||
# once https://gitlab.com/gitlab-org/gitlab/-/issues/247718 is fixed.
|
||||
# When this is fixed, we can remove the call to
|
||||
# `with_project_iid_supply` above, since the objects will be instantiated
|
||||
# and callbacks (including `ensure_project_iid!`) will fire.
|
||||
::Gitlab::Database.bulk_insert( # rubocop:disable Gitlab/BulkInsert
|
||||
::Gitlab::Database.main.bulk_insert( # rubocop:disable Gitlab/BulkInsert
|
||||
DesignManagement::Design.table_name,
|
||||
new_rows,
|
||||
return_ids: true
|
||||
|
@ -207,9 +207,9 @@ module DesignManagement
|
|||
)
|
||||
end
|
||||
|
||||
# TODO Replace `Gitlab::Database.bulk_insert` with `BulkInsertSafe`
|
||||
# TODO Replace `Gitlab::Database.main.bulk_insert` with `BulkInsertSafe`
|
||||
# once https://gitlab.com/gitlab-org/gitlab/-/issues/247718 is fixed.
|
||||
::Gitlab::Database.bulk_insert( # rubocop:disable Gitlab/BulkInsert
|
||||
::Gitlab::Database.main.bulk_insert( # rubocop:disable Gitlab/BulkInsert
|
||||
DesignManagement::Version.table_name,
|
||||
new_rows,
|
||||
return_ids: true
|
||||
|
@ -239,7 +239,7 @@ module DesignManagement
|
|||
end
|
||||
|
||||
# We cannot use `BulkInsertSafe` because of the uploader mounted in `Action`.
|
||||
::Gitlab::Database.bulk_insert( # rubocop:disable Gitlab/BulkInsert
|
||||
::Gitlab::Database.main.bulk_insert( # rubocop:disable Gitlab/BulkInsert
|
||||
DesignManagement::Action.table_name,
|
||||
new_rows
|
||||
)
|
||||
|
@ -278,7 +278,7 @@ module DesignManagement
|
|||
|
||||
# We cannot use `BulkInsertSafe` due to the LfsObjectsProject#update_project_statistics
|
||||
# callback that fires after_commit.
|
||||
::Gitlab::Database.bulk_insert( # rubocop:disable Gitlab/BulkInsert
|
||||
::Gitlab::Database.main.bulk_insert( # rubocop:disable Gitlab/BulkInsert
|
||||
LfsObjectsProject.table_name,
|
||||
new_rows,
|
||||
on_conflict: :do_nothing # Upsert
|
||||
|
|
|
@ -99,7 +99,7 @@ module Issuable
|
|||
yield(event)
|
||||
end.compact
|
||||
|
||||
Gitlab::Database.bulk_insert(table_name, events) # rubocop:disable Gitlab/BulkInsert
|
||||
Gitlab::Database.main.bulk_insert(table_name, events) # rubocop:disable Gitlab/BulkInsert
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ module Keys
|
|||
end
|
||||
|
||||
def update?
|
||||
return false if ::Gitlab::Database.read_only?
|
||||
return false if ::Gitlab::Database.main.read_only?
|
||||
|
||||
last_used = key.last_used_at
|
||||
|
||||
|
|
|
@ -166,7 +166,7 @@ module MergeRequests
|
|||
strong_memoize(:service_error) do
|
||||
if !merge_request
|
||||
ServiceResponse.error(message: 'Invalid argument')
|
||||
elsif Gitlab::Database.read_only?
|
||||
elsif Gitlab::Database.main.read_only?
|
||||
ServiceResponse.error(message: 'Unsupported operation')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -76,7 +76,7 @@ module Packages
|
|||
end
|
||||
|
||||
def database
|
||||
::Gitlab::Database
|
||||
::Gitlab::Database.main
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,7 +11,7 @@ module Packages
|
|||
::Gitlab::UsageDataCounters::PackageEventCounter.count(event_name)
|
||||
end
|
||||
|
||||
if Feature.enabled?(:collect_package_events) && Gitlab::Database.read_write?
|
||||
if Feature.enabled?(:collect_package_events) && Gitlab::Database.main.read_write?
|
||||
::Packages::Event.create!(
|
||||
event_type: event_name,
|
||||
originator: current_user&.id,
|
||||
|
|
|
@ -41,7 +41,7 @@ module Packages
|
|||
}
|
||||
end
|
||||
|
||||
::Gitlab::Database.bulk_insert(::Packages::Nuget::DependencyLinkMetadatum.table_name, rows.compact) # rubocop:disable Gitlab/BulkInsert
|
||||
::Gitlab::Database.main.bulk_insert(::Packages::Nuget::DependencyLinkMetadatum.table_name, rows.compact) # rubocop:disable Gitlab/BulkInsert
|
||||
end
|
||||
|
||||
def raw_dependency_for(dependency)
|
||||
|
|
|
@ -15,7 +15,7 @@ module Packages
|
|||
tags_to_create = @tags - existing_tags
|
||||
|
||||
@package.tags.with_name(tags_to_destroy).delete_all if tags_to_destroy.any?
|
||||
::Gitlab::Database.bulk_insert(Packages::Tag.table_name, rows(tags_to_create)) if tags_to_create.any? # rubocop:disable Gitlab/BulkInsert
|
||||
::Gitlab::Database.main.bulk_insert(Packages::Tag.table_name, rows(tags_to_create)) if tags_to_create.any? # rubocop:disable Gitlab/BulkInsert
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -18,7 +18,7 @@ module PersonalAccessTokens
|
|||
private
|
||||
|
||||
def update?
|
||||
return false if ::Gitlab::Database.read_only?
|
||||
return false if ::Gitlab::Database.main.read_only?
|
||||
|
||||
last_used = @personal_access_token.last_used_at
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ module Projects
|
|||
.update_all(share: update[:share])
|
||||
end
|
||||
|
||||
Gitlab::Database.bulk_insert( # rubocop:disable Gitlab/BulkInsert
|
||||
Gitlab::Database.main.bulk_insert( # rubocop:disable Gitlab/BulkInsert
|
||||
RepositoryLanguage.table_name,
|
||||
detection.insertions(matching_programming_languages)
|
||||
)
|
||||
|
|
|
@ -38,7 +38,7 @@ module Projects
|
|||
rows = existent_lfs_objects
|
||||
.not_linked_to_project(project)
|
||||
.map { |existing_lfs_object| { project_id: project.id, lfs_object_id: existing_lfs_object.id } }
|
||||
Gitlab::Database.bulk_insert(:lfs_objects_projects, rows) # rubocop:disable Gitlab/BulkInsert
|
||||
Gitlab::Database.main.bulk_insert(:lfs_objects_projects, rows) # rubocop:disable Gitlab/BulkInsert
|
||||
iterations += 1
|
||||
|
||||
linked_existing_objects += existent_lfs_objects.map(&:oid)
|
||||
|
|
|
@ -19,7 +19,7 @@ class Repositories::DestroyService < Repositories::BaseService
|
|||
# never be triggered on a read-only instance.
|
||||
#
|
||||
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/223272
|
||||
if Gitlab::Database.read_only?
|
||||
if Gitlab::Database.main.read_only?
|
||||
Repositories::ShellDestroyService.new(current_repository).execute
|
||||
else
|
||||
container.run_after_commit do
|
||||
|
|
|
@ -23,7 +23,7 @@ module ResourceEvents
|
|||
label_hash.merge(label_id: label.id, action: ResourceLabelEvent.actions['remove'])
|
||||
end
|
||||
|
||||
Gitlab::Database.bulk_insert(ResourceLabelEvent.table_name, labels) # rubocop:disable Gitlab/BulkInsert
|
||||
Gitlab::Database.main.bulk_insert(ResourceLabelEvent.table_name, labels) # rubocop:disable Gitlab/BulkInsert
|
||||
resource.expire_note_etag_cache
|
||||
|
||||
Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_label_changed_action(author: user) if resource.is_a?(Issue)
|
||||
|
|
|
@ -25,7 +25,7 @@ module Suggestions
|
|||
end
|
||||
|
||||
rows.in_groups_of(100, false) do |rows|
|
||||
Gitlab::Database.bulk_insert('suggestions', rows) # rubocop:disable Gitlab/BulkInsert
|
||||
Gitlab::Database.main.bulk_insert('suggestions', rows) # rubocop:disable Gitlab/BulkInsert
|
||||
end
|
||||
|
||||
Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter.track_add_suggestion_action(user: @note.author)
|
||||
|
|
|
@ -23,7 +23,7 @@ module Users
|
|||
private
|
||||
|
||||
def record_activity
|
||||
return if Gitlab::Database.read_only?
|
||||
return if Gitlab::Database.main.read_only?
|
||||
|
||||
today = Date.today
|
||||
|
||||
|
|
|
@ -28,11 +28,12 @@ module Users
|
|||
params[:emoji] = UserStatus::DEFAULT_EMOJI if params[:emoji].blank?
|
||||
params[:availability] = UserStatus.availabilities[:not_set] unless new_user_availability
|
||||
|
||||
user_status.update(params)
|
||||
bump_user if user_status.update(params)
|
||||
end
|
||||
|
||||
def remove_status
|
||||
UserStatus.delete(target_user.id)
|
||||
bump_user if UserStatus.delete(target_user.id).nonzero?
|
||||
true
|
||||
end
|
||||
|
||||
def user_status
|
||||
|
@ -48,5 +49,12 @@ module Users
|
|||
def new_user_availability
|
||||
UserStatus.availabilities[params[:availability]]
|
||||
end
|
||||
|
||||
def bump_user
|
||||
# Intentionally not calling `touch` as that will trigger other callbacks
|
||||
# on target_user (e.g. after_touch, after_commit, after_rollback) and we
|
||||
# don't need them to happen here.
|
||||
target_user.update_column(:updated_at, Time.current)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -152,9 +152,9 @@
|
|||
%span.float-right
|
||||
#{Rails::VERSION::STRING}
|
||||
%p
|
||||
= Gitlab::Database.human_adapter_name
|
||||
= Gitlab::Database.main.human_adapter_name
|
||||
%span.float-right
|
||||
= Gitlab::Database.version
|
||||
= Gitlab::Database.main.version
|
||||
%p
|
||||
= _('Redis')
|
||||
%span.float-right
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
= render_if_exists "layouts/nav/ee/security_link" # EE-specific
|
||||
|
||||
= render_if_exists "layouts/nav/ee/push_rules_link" # EE-specific
|
||||
|
||||
- if group_sidebar_link?(:runners)
|
||||
|
|
|
@ -256,6 +256,15 @@
|
|||
:weight: 1
|
||||
:idempotent: true
|
||||
:tags: []
|
||||
- :name: cronjob:environments_auto_delete_cron
|
||||
:worker_name: Environments::AutoDeleteCronWorker
|
||||
:feature_category: :continuous_delivery
|
||||
:has_external_dependencies:
|
||||
:urgency: :low
|
||||
:resource_boundary: :unknown
|
||||
:weight: 1
|
||||
:idempotent: true
|
||||
:tags: []
|
||||
- :name: cronjob:environments_auto_stop_cron
|
||||
:worker_name: Environments::AutoStopCronWorker
|
||||
:feature_category: :continuous_delivery
|
||||
|
|
|
@ -124,7 +124,7 @@ module GitGarbageCollectMethods
|
|||
def update_repository_statistics(resource)
|
||||
resource.repository.expire_statistics_caches
|
||||
|
||||
return if Gitlab::Database.read_only? # GitGarbageCollectWorker may be run on a Geo secondary
|
||||
return if Gitlab::Database.main.read_only? # GitGarbageCollectWorker may be run on a Geo secondary
|
||||
|
||||
update_db_repository_statistics(resource)
|
||||
end
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Environments
|
||||
class AutoDeleteCronWorker
|
||||
include ApplicationWorker
|
||||
include ::Gitlab::LoopHelpers
|
||||
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
|
||||
|
||||
data_consistency :always
|
||||
feature_category :continuous_delivery
|
||||
deduplicate :until_executed, including_scheduled: true
|
||||
idempotent!
|
||||
|
||||
LOOP_TIMEOUT = 45.minutes
|
||||
LOOP_LIMIT = 1000
|
||||
BATCH_SIZE = 100
|
||||
|
||||
def perform
|
||||
loop_until(timeout: LOOP_TIMEOUT, limit: LOOP_LIMIT) do
|
||||
destroy_in_batch
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def destroy_in_batch
|
||||
environments = Environment.auto_deletable(BATCH_SIZE)
|
||||
|
||||
return false if environments.empty?
|
||||
|
||||
environments.each(&:destroy)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -54,7 +54,7 @@ module Gitlab
|
|||
|
||||
label_link_attrs << build_label_attrs(issue_id, import_label_id.to_i)
|
||||
|
||||
Gitlab::Database.bulk_insert(LabelLink.table_name, label_link_attrs) # rubocop:disable Gitlab/BulkInsert
|
||||
Gitlab::Database.main.bulk_insert(LabelLink.table_name, label_link_attrs) # rubocop:disable Gitlab/BulkInsert
|
||||
end
|
||||
|
||||
def assign_issue(project_id, issue_id, assignee_ids)
|
||||
|
@ -62,7 +62,7 @@ module Gitlab
|
|||
|
||||
assignee_attrs = assignee_ids.map { |user_id| { issue_id: issue_id, user_id: user_id } }
|
||||
|
||||
Gitlab::Database.bulk_insert(IssueAssignee.table_name, assignee_attrs) # rubocop:disable Gitlab/BulkInsert
|
||||
Gitlab::Database.main.bulk_insert(IssueAssignee.table_name, assignee_attrs) # rubocop:disable Gitlab/BulkInsert
|
||||
end
|
||||
|
||||
def build_label_attrs(issue_id, label_id)
|
||||
|
|
|
@ -11,7 +11,7 @@ class PagesDomainVerificationCronWorker # rubocop:disable Scalability/Idempotent
|
|||
worker_resource_boundary :cpu
|
||||
|
||||
def perform
|
||||
return if Gitlab::Database.read_only?
|
||||
return if Gitlab::Database.main.read_only?
|
||||
|
||||
PagesDomain.needs_verification.with_logging_info.find_each do |domain|
|
||||
with_context(project: domain.project) do
|
||||
|
|
|
@ -12,7 +12,7 @@ class PagesDomainVerificationWorker # rubocop:disable Scalability/IdempotentWork
|
|||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def perform(domain_id)
|
||||
return if Gitlab::Database.read_only?
|
||||
return if Gitlab::Database.main.read_only?
|
||||
|
||||
domain = PagesDomain.find_by(id: domain_id)
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ class ProjectCacheWorker
|
|||
# statistics to become accurate if they were already updated once in the
|
||||
# last 15 minutes.
|
||||
def update_statistics(project, statistics = [])
|
||||
return if Gitlab::Database.read_only?
|
||||
return if Gitlab::Database.main.read_only?
|
||||
return unless try_obtain_lease_for(project.id, statistics)
|
||||
|
||||
Projects::UpdateStatisticsService.new(project, nil, statistics: statistics).execute
|
||||
|
|
|
@ -23,7 +23,7 @@ module Projects
|
|||
end
|
||||
|
||||
def cleanup_orphan_lfs_file_references(resource)
|
||||
return if Gitlab::Database.read_only? # GitGarbageCollectWorker may be run on a Geo secondary
|
||||
return if Gitlab::Database.main.read_only? # GitGarbageCollectWorker may be run on a Geo secondary
|
||||
|
||||
::Gitlab::Cleanup::OrphanLfsFileReferences.new(resource, dry_run: false, logger: logger).run!
|
||||
rescue StandardError => err
|
||||
|
|
|
@ -12,7 +12,7 @@ class ScheduleMergeRequestCleanupRefsWorker
|
|||
idempotent!
|
||||
|
||||
def perform
|
||||
return if Gitlab::Database.read_only?
|
||||
return if Gitlab::Database.main.read_only?
|
||||
return unless Feature.enabled?(:merge_request_refs_cleanup, default_enabled: false)
|
||||
|
||||
MergeRequestCleanupRefsWorker.perform_with_capacity
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
### Performance (1 change)
|
||||
|
||||
- Memoize Gitlab::Database.version.
|
||||
- Memoize Gitlab::Database.main.version.
|
||||
|
||||
|
||||
## 10.8.2 (2018-05-28)
|
||||
|
|
|
@ -2006,7 +2006,7 @@
|
|||
- Don't delete assigned MRs/issues when user is deleted.
|
||||
- Remove new branch button for confidential issues.
|
||||
- Don't allow project guests to subscribe to merge requests through the API. (Robert Schilling)
|
||||
- Don't connect in Gitlab::Database.adapter_name.
|
||||
- Don't connect in Gitlab::Database.main.adapter_name.
|
||||
- Prevent users from creating notes on resources they can't access.
|
||||
- Ignore encrypted attributes in Import/Export.
|
||||
- Change rspec test to guarantee window is resized before visiting page.
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: ci_skip_before_parsing_yaml
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66147
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337167
|
||||
milestone: '14.2'
|
||||
type: development
|
||||
group: group::pipeline execution
|
||||
default_enabled: false
|
|
@ -470,6 +470,9 @@ production: &base
|
|||
# Stop expired environments
|
||||
environments_auto_stop_cron_worker:
|
||||
cron: "24 * * * *"
|
||||
# Delete stopped environments
|
||||
environments_auto_delete_cron_worker:
|
||||
cron: "34 * * * *"
|
||||
# Periodically run 'git fsck' on all repositories. If started more than
|
||||
# once per hour you will have concurrent 'git fsck' jobs.
|
||||
repository_check_worker:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
raise "PostgreSQL is the only supported database from GitLab 12.1" unless
|
||||
Gitlab::Database.postgresql?
|
||||
Gitlab::Database.main.postgresql?
|
||||
|
||||
Gitlab::Database.check_postgres_version_and_print_warning
|
||||
|
|
|
@ -444,6 +444,9 @@ Settings.cron_jobs['ci_schedule_delete_objects_worker']['job_class'] = 'Ci::Sche
|
|||
Settings.cron_jobs['environments_auto_stop_cron_worker'] ||= Settingslogic.new({})
|
||||
Settings.cron_jobs['environments_auto_stop_cron_worker']['cron'] ||= '24 * * * *'
|
||||
Settings.cron_jobs['environments_auto_stop_cron_worker']['job_class'] = 'Environments::AutoStopCronWorker'
|
||||
Settings.cron_jobs['environments_auto_delete_cron_worker'] ||= Settingslogic.new({})
|
||||
Settings.cron_jobs['environments_auto_delete_cron_worker']['cron'] ||= '34 * * * *'
|
||||
Settings.cron_jobs['environments_auto_delete_cron_worker']['job_class'] = 'Environments::AutoDeleteCronWorker'
|
||||
Settings.cron_jobs['repository_check_worker'] ||= Settingslogic.new({})
|
||||
Settings.cron_jobs['repository_check_worker']['cron'] ||= '20 * * * *'
|
||||
Settings.cron_jobs['repository_check_worker']['job_class'] = 'RepositoryCheck::DispatchWorker'
|
||||
|
|
|
@ -14,7 +14,7 @@ end
|
|||
|
||||
if defined?(ActiveRecord::Base)
|
||||
Gitlab::Cluster::LifecycleEvents.on_before_fork do
|
||||
raise 'ActiveRecord connection not established. Unable to start.' unless Gitlab::Database.exists?
|
||||
raise 'ActiveRecord connection not established. Unable to start.' unless Gitlab::Database.main.exists?
|
||||
|
||||
# the following is highly recommended for Rails + "preload_app true"
|
||||
# as there's no need for the master process to hold a connection
|
||||
|
|
|
@ -10,8 +10,8 @@ if Gitlab::Runtime.console?
|
|||
puts " GitLab:".ljust(justify) + "#{Gitlab::VERSION} (#{Gitlab.revision}) #{Gitlab.ee? ? 'EE' : 'FOSS'}"
|
||||
puts " GitLab Shell:".ljust(justify) + "#{Gitlab::VersionInfo.parse(Gitlab::Shell.version)}"
|
||||
|
||||
if Gitlab::Database.exists?
|
||||
puts " #{Gitlab::Database.human_adapter_name}:".ljust(justify) + Gitlab::Database.version
|
||||
if Gitlab::Database.main.exists?
|
||||
puts " #{Gitlab::Database.main.human_adapter_name}:".ljust(justify) + Gitlab::Database.main.version
|
||||
|
||||
Gitlab.ee do
|
||||
if Gitlab::Geo.connected? && Gitlab::Geo.enabled?
|
||||
|
|
|
@ -20,16 +20,16 @@ Gitlab.ee do
|
|||
end
|
||||
end
|
||||
|
||||
db_config = Gitlab::Database.config ||
|
||||
db_config = Gitlab::Database.main.config ||
|
||||
Rails.application.config.database_configuration[Rails.env]
|
||||
|
||||
ActiveRecord::Base.establish_connection(
|
||||
db_config.merge(pool: Gitlab::Database.default_pool_size)
|
||||
db_config.merge(pool: Gitlab::Database.main.default_pool_size)
|
||||
)
|
||||
|
||||
Gitlab.ee do
|
||||
if Gitlab::Runtime.sidekiq? && Gitlab::Geo.geo_database_configured?
|
||||
Rails.configuration.geo_database['pool'] = Gitlab::Database.default_pool_size
|
||||
Rails.configuration.geo_database['pool'] = Gitlab::Database.main.default_pool_size
|
||||
Geo::TrackingBase.establish_connection(Rails.configuration.geo_database)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
# `Shard.connected?` could be cached and return true even though the table doesn't exist
|
||||
return unless Shard.connected?
|
||||
return unless ActiveRecord::Migrator.current_version >= 20190402150158
|
||||
return if Gitlab::Database.read_only?
|
||||
return if Gitlab::Database.main.read_only?
|
||||
|
||||
Shard.populate!
|
||||
|
|
|
@ -20,7 +20,7 @@ module Sidekiq
|
|||
module NoEnqueueingFromTransactions
|
||||
%i(perform_async perform_at perform_in).each do |name|
|
||||
define_method(name) do |*args|
|
||||
if !Sidekiq::Worker.skip_transaction_check && Gitlab::Database.inside_transaction?
|
||||
if !Sidekiq::Worker.skip_transaction_check && Gitlab::Database.main.inside_transaction?
|
||||
begin
|
||||
raise Sidekiq::Worker::EnqueueFromTransactionError, <<~MSG
|
||||
`#{self}.#{name}` cannot be called inside a transaction as this can lead to
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
if Gitlab::Database::LoadBalancing.enable?
|
||||
Gitlab::Database.disable_prepared_statements
|
||||
Gitlab::Database.main.disable_prepared_statements
|
||||
|
||||
Gitlab::Application.configure do |config|
|
||||
config.middleware.use(Gitlab::Database::LoadBalancing::RackMiddleware)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddIsRemovedToEscalationRules < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
add_column :incident_management_escalation_rules, :is_removed, :boolean, null: false, default: false
|
||||
end
|
||||
end
|
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class UpdateEscalationRuleFkForPendingAlertEscalations < ActiveRecord::Migration[6.1]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
include Gitlab::Database::PartitioningMigrationHelpers
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
OLD_FOREIGN_KEY_CONSTRAINT = 'fk_rails_057c1e3d87'
|
||||
|
||||
# Swap foreign key contrainst from ON DELETE SET NULL to ON DELETE CASCADE
|
||||
def up
|
||||
remove_foreign_key_if_exists :incident_management_pending_alert_escalations, :incident_management_escalation_rules, name: OLD_FOREIGN_KEY_CONSTRAINT
|
||||
|
||||
add_concurrent_partitioned_foreign_key :incident_management_pending_alert_escalations,
|
||||
:incident_management_escalation_rules,
|
||||
column: :rule_id
|
||||
end
|
||||
|
||||
def down
|
||||
remove_foreign_key_if_exists :incident_management_pending_alert_escalations, :incident_management_escalation_rules, column: :rule_id
|
||||
|
||||
add_concurrent_partitioned_foreign_key :incident_management_pending_alert_escalations,
|
||||
:incident_management_escalation_rules,
|
||||
column: :rule_id,
|
||||
on_delete: :nullify,
|
||||
name: OLD_FOREIGN_KEY_CONSTRAINT
|
||||
end
|
||||
end
|
|
@ -0,0 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveScheduleAndStatusNullConstraintsFromPendingEscalationsAlert < ActiveRecord::Migration[6.1]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
# In preparation of removal of these columns in 14.3.
|
||||
def up
|
||||
with_lock_retries do
|
||||
change_column_null :incident_management_pending_alert_escalations, :status, true
|
||||
change_column_null :incident_management_pending_alert_escalations, :schedule_id, true
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
backfill_from_rules_and_disallow_column_null :status, value: :status
|
||||
backfill_from_rules_and_disallow_column_null :schedule_id, value: :oncall_schedule_id
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def backfill_from_rules_and_disallow_column_null(column, value:)
|
||||
with_lock_retries do
|
||||
execute <<~SQL
|
||||
UPDATE incident_management_pending_alert_escalations AS escalations
|
||||
SET #{column} = rules.#{value}
|
||||
FROM incident_management_escalation_rules AS rules
|
||||
WHERE rule_id = rules.id
|
||||
AND escalations.#{column} IS NULL
|
||||
SQL
|
||||
|
||||
change_column_null :incident_management_pending_alert_escalations, column, false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CreateIndexOnEnvironmentsAutoDeleteAt < ActiveRecord::Migration[6.1]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'index_environments_on_state_and_auto_delete_at'
|
||||
|
||||
def up
|
||||
add_concurrent_index :environments,
|
||||
%i[auto_delete_at],
|
||||
where: "auto_delete_at IS NOT NULL AND state = 'stopped'",
|
||||
name: INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name :environments, INDEX_NAME
|
||||
end
|
||||
end
|
|
@ -20,7 +20,7 @@ class MigrateSamlIdentitiesToScimIdentities < ActiveRecord::Migration[6.0]
|
|||
record.attributes.extract!("extern_uid", "user_id", "group_id", "active", "created_at", "updated_at")
|
||||
end
|
||||
|
||||
Gitlab::Database.bulk_insert(:scim_identities, data_to_insert, on_conflict: :do_nothing) # rubocop:disable Gitlab/BulkInsert
|
||||
Gitlab::Database.main.bulk_insert(:scim_identities, data_to_insert, on_conflict: :do_nothing) # rubocop:disable Gitlab/BulkInsert
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddNonNullConstraintForEscalationRuleOnPendingAlertEscalations < ActiveRecord::Migration[6.1]
|
||||
ELAPSED_WHOLE_MINUTES_IN_SECONDS = <<~SQL
|
||||
ABS(ROUND(
|
||||
EXTRACT(EPOCH FROM (escalations.process_at - escalations.created_at))/60*60
|
||||
))
|
||||
SQL
|
||||
|
||||
INSERT_RULES_FOR_ESCALATIONS_WITHOUT_RULES = <<~SQL
|
||||
INSERT INTO incident_management_escalation_rules (policy_id, oncall_schedule_id, status, elapsed_time_seconds, is_removed)
|
||||
SELECT
|
||||
policies.id,
|
||||
schedule_id,
|
||||
status,
|
||||
#{ELAPSED_WHOLE_MINUTES_IN_SECONDS} AS elapsed_time_seconds,
|
||||
TRUE
|
||||
FROM incident_management_pending_alert_escalations AS escalations
|
||||
INNER JOIN incident_management_oncall_schedules AS schedules ON schedules.id = schedule_id
|
||||
INNER JOIN incident_management_escalation_policies AS policies ON policies.project_id = schedules.project_id
|
||||
WHERE rule_id IS NULL
|
||||
GROUP BY policies.id, schedule_id, status, elapsed_time_seconds
|
||||
ON CONFLICT DO NOTHING;
|
||||
SQL
|
||||
|
||||
UPDATE_EMPTY_RULE_IDS = <<~SQL
|
||||
UPDATE incident_management_pending_alert_escalations AS escalations
|
||||
SET rule_id = rules.id
|
||||
FROM incident_management_pending_alert_escalations AS through_escalations
|
||||
INNER JOIN incident_management_oncall_schedules AS schedules ON schedules.id = through_escalations.schedule_id
|
||||
INNER JOIN incident_management_escalation_policies AS policies ON policies.project_id = schedules.project_id
|
||||
INNER JOIN incident_management_escalation_rules AS rules ON rules.policy_id = policies.id
|
||||
WHERE escalations.rule_id IS NULL
|
||||
AND rules.status = escalations.status
|
||||
AND rules.oncall_schedule_id = escalations.schedule_id
|
||||
AND rules.elapsed_time_seconds = #{ELAPSED_WHOLE_MINUTES_IN_SECONDS};
|
||||
SQL
|
||||
|
||||
DELETE_LEFTOVER_ESCALATIONS_WITHOUT_RULES = 'DELETE FROM incident_management_pending_alert_escalations WHERE rule_id IS NULL;'
|
||||
|
||||
# For each alert which has a pending escalation without a corresponding rule,
|
||||
# create a rule with the expected attributes for the project's policy.
|
||||
#
|
||||
# Deletes all escalations without rules/policy & adds non-null constraint for rule_id.
|
||||
def up
|
||||
exec_query INSERT_RULES_FOR_ESCALATIONS_WITHOUT_RULES
|
||||
exec_query UPDATE_EMPTY_RULE_IDS
|
||||
exec_query DELETE_LEFTOVER_ESCALATIONS_WITHOUT_RULES
|
||||
|
||||
change_column_null :incident_management_pending_alert_escalations, :rule_id, false
|
||||
end
|
||||
|
||||
def down
|
||||
change_column_null :incident_management_pending_alert_escalations, :rule_id, true
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
ac95292b2ab05f17ed13cb8e95ace0660e6dc82e33d6ef1cccd02890abf6c739
|
|
@ -0,0 +1 @@
|
|||
9f3a39b11f250f64e4e6b8623279604c1dba14330f45c26840f6e0b46f7d48a7
|
|
@ -0,0 +1 @@
|
|||
7b20c623b58982ba5d228902c6da6d10245edf3874ece9b02d58e8560d2d5d96
|
|
@ -0,0 +1 @@
|
|||
f16b563bbfa15b97143e82d2a1e78e9d9805d13e02e3a0845369d4ce3204b3cc
|
|
@ -0,0 +1 @@
|
|||
b64ba2a9ee42497aa9f60ca76f4925076cb77e73fd79bb9b10362cd48d11252b
|
|
@ -257,13 +257,13 @@ PARTITION BY RANGE (created_at);
|
|||
|
||||
CREATE TABLE incident_management_pending_alert_escalations (
|
||||
id bigint NOT NULL,
|
||||
rule_id bigint,
|
||||
rule_id bigint NOT NULL,
|
||||
alert_id bigint NOT NULL,
|
||||
schedule_id bigint NOT NULL,
|
||||
schedule_id bigint,
|
||||
process_at timestamp with time zone NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
status smallint NOT NULL
|
||||
status smallint
|
||||
)
|
||||
PARTITION BY RANGE (process_at);
|
||||
|
||||
|
@ -13975,7 +13975,8 @@ CREATE TABLE incident_management_escalation_rules (
|
|||
policy_id bigint NOT NULL,
|
||||
oncall_schedule_id bigint NOT NULL,
|
||||
status smallint NOT NULL,
|
||||
elapsed_time_seconds integer NOT NULL
|
||||
elapsed_time_seconds integer NOT NULL,
|
||||
is_removed boolean DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
CREATE SEQUENCE incident_management_escalation_rules_id_seq
|
||||
|
@ -23676,6 +23677,8 @@ CREATE INDEX index_environments_on_project_id_and_tier ON environments USING btr
|
|||
|
||||
CREATE INDEX index_environments_on_project_id_state_environment_type ON environments USING btree (project_id, state, environment_type);
|
||||
|
||||
CREATE INDEX index_environments_on_state_and_auto_delete_at ON environments USING btree (auto_delete_at) WHERE ((auto_delete_at IS NOT NULL) AND ((state)::text = 'stopped'::text));
|
||||
|
||||
CREATE INDEX index_environments_on_state_and_auto_stop_at ON environments USING btree (state, auto_stop_at) WHERE ((auto_stop_at IS NOT NULL) AND ((state)::text = 'available'::text));
|
||||
|
||||
CREATE UNIQUE INDEX index_epic_board_list_preferences_on_user_and_list ON boards_epic_list_user_preferences USING btree (user_id, epic_list_id);
|
||||
|
@ -26729,9 +26732,6 @@ ALTER TABLE ONLY terraform_state_versions
|
|||
ALTER TABLE ONLY ci_build_report_results
|
||||
ADD CONSTRAINT fk_rails_056d298d48 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE incident_management_pending_alert_escalations
|
||||
ADD CONSTRAINT fk_rails_057c1e3d87 FOREIGN KEY (rule_id) REFERENCES incident_management_escalation_rules(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE ONLY ci_daily_build_group_report_results
|
||||
ADD CONSTRAINT fk_rails_0667f7608c FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
|
@ -28208,6 +28208,9 @@ ALTER TABLE ONLY approval_project_rules_users
|
|||
ALTER TABLE ONLY insights
|
||||
ADD CONSTRAINT fk_rails_f36fda3932 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE incident_management_pending_alert_escalations
|
||||
ADD CONSTRAINT fk_rails_f3d17bc8af FOREIGN KEY (rule_id) REFERENCES incident_management_escalation_rules(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY board_group_recent_visits
|
||||
ADD CONSTRAINT fk_rails_f410736518 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 175 KiB After Width: | Height: | Size: 50 KiB |
|
@ -4176,6 +4176,7 @@ Input type: `UpdateIssueInput`
|
|||
| <a id="mutationupdateissueepicid"></a>`epicId` | [`EpicID`](#epicid) | The ID of the parent epic. NULL when removing the association. |
|
||||
| <a id="mutationupdateissuehealthstatus"></a>`healthStatus` | [`HealthStatus`](#healthstatus) | The desired health status. |
|
||||
| <a id="mutationupdateissueiid"></a>`iid` | [`String!`](#string) | The IID of the issue to mutate. |
|
||||
| <a id="mutationupdateissuelabelids"></a>`labelIds` | [`[ID!]`](#id) | The IDs of labels to be set. Replaces existing issue labels. |
|
||||
| <a id="mutationupdateissuelocked"></a>`locked` | [`Boolean`](#boolean) | Indicates discussion is locked on the issue. |
|
||||
| <a id="mutationupdateissuemilestoneid"></a>`milestoneId` | [`ID`](#id) | The ID of the milestone to assign to the issue. On update milestone will be removed if set to null. |
|
||||
| <a id="mutationupdateissueprojectpath"></a>`projectPath` | [`ID!`](#id) | The project the issue to mutate is in. |
|
||||
|
@ -9080,6 +9081,7 @@ Relationship between an epic and an issue.
|
|||
| <a id="epicissueiid"></a>`iid` | [`ID!`](#id) | Internal ID of the issue. |
|
||||
| <a id="epicissueiteration"></a>`iteration` | [`Iteration`](#iteration) | Iteration of the issue. |
|
||||
| <a id="epicissuelabels"></a>`labels` | [`LabelConnection`](#labelconnection) | Labels of the issue. (see [Connections](#connections)) |
|
||||
| <a id="epicissuemergerequestscount"></a>`mergeRequestsCount` | [`Int!`](#int) | Number of merge requests that close the issue on merge. |
|
||||
| <a id="epicissuemetricimages"></a>`metricImages` | [`[MetricImage!]`](#metricimage) | Metric images associated to the issue. |
|
||||
| <a id="epicissuemilestone"></a>`milestone` | [`Milestone`](#milestone) | Milestone of the issue. |
|
||||
| <a id="epicissuemoved"></a>`moved` | [`Boolean`](#boolean) | Indicates if issue got moved from other project. |
|
||||
|
@ -10153,6 +10155,7 @@ Returns [`VulnerabilitySeveritiesCount`](#vulnerabilityseveritiescount).
|
|||
| <a id="issueiid"></a>`iid` | [`ID!`](#id) | Internal ID of the issue. |
|
||||
| <a id="issueiteration"></a>`iteration` | [`Iteration`](#iteration) | Iteration of the issue. |
|
||||
| <a id="issuelabels"></a>`labels` | [`LabelConnection`](#labelconnection) | Labels of the issue. (see [Connections](#connections)) |
|
||||
| <a id="issuemergerequestscount"></a>`mergeRequestsCount` | [`Int!`](#int) | Number of merge requests that close the issue on merge. |
|
||||
| <a id="issuemetricimages"></a>`metricImages` | [`[MetricImage!]`](#metricimage) | Metric images associated to the issue. |
|
||||
| <a id="issuemilestone"></a>`milestone` | [`Milestone`](#milestone) | Milestone of the issue. |
|
||||
| <a id="issuemoved"></a>`moved` | [`Boolean`](#boolean) | Indicates if issue got moved from other project. |
|
||||
|
@ -13482,6 +13485,7 @@ Represents a historically accurate report about the timebox.
|
|||
| <a id="timelogmergerequest"></a>`mergeRequest` | [`MergeRequest`](#mergerequest) | The merge request that logged time was added to. |
|
||||
| <a id="timelognote"></a>`note` | [`Note`](#note) | The note where the quick action to add the logged time was executed. |
|
||||
| <a id="timelogspentat"></a>`spentAt` | [`Time`](#time) | Timestamp of when the time tracked was spent at. |
|
||||
| <a id="timelogsummary"></a>`summary` | [`String`](#string) | The summary of how the time was spent. |
|
||||
| <a id="timelogtimespent"></a>`timeSpent` | [`Int!`](#int) | The time spent displayed in seconds. |
|
||||
| <a id="timeloguser"></a>`user` | [`UserCore!`](#usercore) | The user that logged the time. |
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 34 KiB |
Binary file not shown.
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 32 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue