Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-10-07 15:12:09 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-10-07 15:12:09 +0300
commit43c3400c67f6470d4a19f143008990ee142dd828 (patch)
tree2268d48d59023e8353c6ab55290e8031e224dacc /app
parentbc935f05bc8d7dd89c3e7c88f90264e90b636e07 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/container.js48
-rw-r--r--app/controllers/search_controller.rb5
-rw-r--r--app/models/protected_branch.rb2
-rw-r--r--app/models/user.rb1
-rw-r--r--app/services/container_expiration_policies/cleanup_service.rb4
-rw-r--r--app/services/issues/close_service.rb4
-rw-r--r--app/services/projects/container_repository/cleanup_tags_service.rb168
-rw-r--r--app/workers/ci/stuck_builds/drop_running_worker.rb17
-rw-r--r--app/workers/cleanup_container_repository_worker.rb4
-rw-r--r--app/workers/stuck_ci_jobs_worker.rb17
11 files changed, 153 insertions, 119 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
index 7ea24171aa8..b2c9d28a88b 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
@@ -117,7 +117,7 @@ export default {
</script>
<template>
- <section class="media-section mr-widget-border-top" data-testid="widget-extension">
+ <section class="media-section" data-testid="widget-extension">
<div class="media gl-p-5">
<status-icon
:name="$options.name"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/container.js b/app/assets/javascripts/vue_merge_request_widget/components/extensions/container.js
index 46046d16fcf..b9dfd3bd41e 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/container.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/container.js
@@ -1,3 +1,4 @@
+import { __ } from '~/locale';
import { registeredExtensions } from './index';
export default {
@@ -12,23 +13,42 @@ export default {
if (extensions.length === 0) return null;
- return h('div', {}, [
- ...extensions.map((extension) =>
+ return h(
+ 'div',
+ {
+ attrs: {
+ role: 'region',
+ 'aria-label': __('Merge request reports'),
+ },
+ },
+ [
h(
- { ...extension },
+ 'ul',
{
- props: {
- ...extension.props.reduce(
- (acc, key) => ({
- ...acc,
- [key]: this.mr[key],
- }),
- {},
- ),
- },
+ class: 'gl-p-0 gl-m-0 gl-list-style-none',
},
+ [
+ ...extensions.map((extension, index) =>
+ h('li', { attrs: { class: index > 0 && 'mr-widget-border-top' } }, [
+ h(
+ { ...extension },
+ {
+ props: {
+ ...extension.props.reduce(
+ (acc, key) => ({
+ ...acc,
+ [key]: this.mr[key],
+ }),
+ {},
+ ),
+ },
+ },
+ ),
+ ]),
+ ),
+ ],
),
- ),
- ]);
+ ],
+ );
},
};
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index 5fd4d21b260..0a18559fc81 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -12,6 +12,7 @@ class SearchController < ApplicationController
around_action :allow_gitaly_ref_name_caching
before_action :block_anonymous_global_searches, :check_scope_global_search_enabled, except: :opensearch
+ before_action :strip_surrounding_whitespace_from_search, except: :opensearch
skip_before_action :authenticate_user!
requires_cross_project_access if: -> do
search_term_present = params[:search].present? || params[:term].present?
@@ -197,6 +198,10 @@ class SearchController < ApplicationController
def count_action_name?
action_name.to_sym == :count
end
+
+ def strip_surrounding_whitespace_from_search
+ %i(term search).each { |param| params[param]&.strip! }
+ end
end
SearchController.prepend_mod_with('SearchController')
diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb
index 3d32144e0f8..b4e2d17c3e5 100644
--- a/app/models/protected_branch.rb
+++ b/app/models/protected_branch.rb
@@ -10,6 +10,8 @@ class ProtectedBranch < ApplicationRecord
scope :allowing_force_push,
-> { where(allow_force_push: true) }
+ scope :get_ids_by_name, -> (name) { where(name: name).pluck(:id) }
+
protected_ref_access_levels :merge, :push
def self.protected_ref_accessible_to?(ref, user, project:, action:, protected_refs: nil)
diff --git a/app/models/user.rb b/app/models/user.rb
index f4e6069ac9a..25a2588a6a7 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -457,6 +457,7 @@ class User < ApplicationRecord
scope :dormant, -> { active.where('last_activity_on <= ?', MINIMUM_INACTIVE_DAYS.day.ago.to_date) }
scope :with_no_activity, -> { active.where(last_activity_on: nil) }
scope :by_provider_and_extern_uid, ->(provider, extern_uid) { joins(:identities).merge(Identity.with_extern_uid(provider, extern_uid)) }
+ scope :get_ids_by_username, -> (username) { where(username: username).pluck(:id) }
def preferred_language
read_attribute('preferred_language') ||
diff --git a/app/services/container_expiration_policies/cleanup_service.rb b/app/services/container_expiration_policies/cleanup_service.rb
index 52530b91578..0da5e552c48 100644
--- a/app/services/container_expiration_policies/cleanup_service.rb
+++ b/app/services/container_expiration_policies/cleanup_service.rb
@@ -24,8 +24,8 @@ module ContainerExpirationPolicies
begin
service_result = Projects::ContainerRepository::CleanupTagsService
- .new(project, nil, policy_params.merge('container_expiration_policy' => true))
- .execute(repository)
+ .new(repository, nil, policy_params.merge('container_expiration_policy' => true))
+ .execute
rescue StandardError
repository.cleanup_unfinished!
diff --git a/app/services/issues/close_service.rb b/app/services/issues/close_service.rb
index 856f6932d61..ac846c769a3 100644
--- a/app/services/issues/close_service.rb
+++ b/app/services/issues/close_service.rb
@@ -91,11 +91,11 @@ module Issues
end
end
- def store_first_mentioned_in_commit_at(issue, merge_request)
+ def store_first_mentioned_in_commit_at(issue, merge_request, max_commit_lookup: 100)
metrics = issue.metrics
return if metrics.nil? || metrics.first_mentioned_in_commit_at
- first_commit_timestamp = merge_request.commits(limit: 1).first.try(:authored_date)
+ first_commit_timestamp = merge_request.commits(limit: max_commit_lookup).last.try(:authored_date)
return unless first_commit_timestamp
metrics.update!(first_mentioned_in_commit_at: first_commit_timestamp)
diff --git a/app/services/projects/container_repository/cleanup_tags_service.rb b/app/services/projects/container_repository/cleanup_tags_service.rb
index 064cdce6f10..3a60de0f1ee 100644
--- a/app/services/projects/container_repository/cleanup_tags_service.rb
+++ b/app/services/projects/container_repository/cleanup_tags_service.rb
@@ -2,148 +2,152 @@
module Projects
module ContainerRepository
- class CleanupTagsService < BaseService
+ class CleanupTagsService
+ include BaseServiceUtility
include ::Gitlab::Utils::StrongMemoize
- def execute(container_repository)
- return error('access denied') unless can_destroy?
- return error('invalid regex') unless valid_regex?
+ def initialize(container_repository, user = nil, params = {})
+ @container_repository = container_repository
+ @current_user = user
+ @params = params.dup
- tags = container_repository.tags
- original_size = tags.size
+ @project = container_repository.project
+ @tags = container_repository.tags
+ tags_size = @tags.size
+ @counts = {
+ original_size: tags_size,
+ cached_tags_count: 0
+ }
+ end
- tags = without_latest(tags)
- tags = filter_by_name(tags)
+ def execute
+ return error('access denied') unless can_destroy?
+ return error('invalid regex') unless valid_regex?
- before_truncate_size = tags.size
- tags = truncate(tags)
- after_truncate_size = tags.size
+ filter_out_latest
+ filter_by_name
- cached_tags_count = populate_tags_from_cache(container_repository, tags) || 0
+ truncate
+ populate_from_cache
- tags = filter_keep_n(container_repository, tags)
- tags = filter_by_older_than(container_repository, tags)
+ filter_keep_n
+ filter_by_older_than
- delete_tags(container_repository, tags).tap do |result|
- result[:original_size] = original_size
- result[:before_truncate_size] = before_truncate_size
- result[:after_truncate_size] = after_truncate_size
- result[:cached_tags_count] = cached_tags_count
- result[:before_delete_size] = tags.size
+ delete_tags.merge(@counts).tap do |result|
+ result[:before_delete_size] = @tags.size
result[:deleted_size] = result[:deleted]&.size
- result[:status] = :error if before_truncate_size != after_truncate_size
+ result[:status] = :error if @counts[:before_truncate_size] != @counts[:after_truncate_size]
end
end
private
- def delete_tags(container_repository, tags)
- return success(deleted: []) unless tags.any?
-
- tag_names = tags.map(&:name)
+ def delete_tags
+ return success(deleted: []) unless @tags.any?
service = Projects::ContainerRepository::DeleteTagsService.new(
- container_repository.project,
- current_user,
- tags: tag_names,
- container_expiration_policy: params['container_expiration_policy']
+ @project,
+ @current_user,
+ tags: @tags.map(&:name),
+ container_expiration_policy: container_expiration_policy
)
- service.execute(container_repository)
+ service.execute(@container_repository)
end
- def without_latest(tags)
- tags.reject(&:latest?)
+ def filter_out_latest
+ @tags.reject!(&:latest?)
end
- def order_by_date(tags)
+ def order_by_date
now = DateTime.current
- tags.sort_by { |tag| tag.created_at || now }.reverse
+ @tags.sort_by! { |tag| tag.created_at || now }
+ .reverse!
end
- def filter_by_name(tags)
- regex_delete = ::Gitlab::UntrustedRegexp.new("\\A#{params['name_regex_delete'] || params['name_regex']}\\z")
- regex_retain = ::Gitlab::UntrustedRegexp.new("\\A#{params['name_regex_keep']}\\z")
+ def filter_by_name
+ regex_delete = ::Gitlab::UntrustedRegexp.new("\\A#{name_regex_delete || name_regex}\\z")
+ regex_retain = ::Gitlab::UntrustedRegexp.new("\\A#{name_regex_keep}\\z")
- tags.select do |tag|
+ @tags.select! do |tag|
# regex_retain will override any overlapping matches by regex_delete
regex_delete.match?(tag.name) && !regex_retain.match?(tag.name)
end
end
- def filter_keep_n(container_repository, tags)
- return tags unless params['keep_n']
+ def filter_keep_n
+ return unless keep_n
- tags = order_by_date(tags)
- cache_tags(container_repository, tags.first(keep_n))
- tags.drop(keep_n)
+ order_by_date
+ cache_tags(@tags.first(keep_n_as_integer))
+ @tags = @tags.drop(keep_n_as_integer)
end
- def filter_by_older_than(container_repository, tags)
- return tags unless older_than
+ def filter_by_older_than
+ return unless older_than
older_than_timestamp = older_than_in_seconds.ago
- tags, tags_to_keep = tags.partition do |tag|
+ @tags, tags_to_keep = @tags.partition do |tag|
tag.created_at && tag.created_at < older_than_timestamp
end
- cache_tags(container_repository, tags_to_keep)
-
- tags
+ cache_tags(tags_to_keep)
end
def can_destroy?
- return true if params['container_expiration_policy']
+ return true if container_expiration_policy
- can?(current_user, :destroy_container_image, project)
+ can?(@current_user, :destroy_container_image, @project)
end
def valid_regex?
%w(name_regex_delete name_regex name_regex_keep).each do |param_name|
- regex = params[param_name]
+ regex = @params[param_name]
::Gitlab::UntrustedRegexp.new(regex) unless regex.blank?
end
true
rescue RegexpError => e
- ::Gitlab::ErrorTracking.log_exception(e, project_id: project.id)
+ ::Gitlab::ErrorTracking.log_exception(e, project_id: @project.id)
false
end
- def truncate(tags)
- return tags unless throttling_enabled?
- return tags if max_list_size == 0
+ def truncate
+ @counts[:before_truncate_size] = @tags.size
+ @counts[:after_truncate_size] = @tags.size
+
+ return unless throttling_enabled?
+ return if max_list_size == 0
# truncate the list to make sure that after the #filter_keep_n
# execution, the resulting list will be max_list_size
- truncated_size = max_list_size + keep_n
+ truncated_size = max_list_size + keep_n_as_integer
- return tags if tags.size <= truncated_size
+ return if @tags.size <= truncated_size
- tags.sample(truncated_size)
+ @tags = @tags.sample(truncated_size)
+ @counts[:after_truncate_size] = @tags.size
end
- def populate_tags_from_cache(container_repository, tags)
- cache(container_repository).populate(tags) if caching_enabled?(container_repository)
+ def populate_from_cache
+ @counts[:cached_tags_count] = cache.populate(@tags) if caching_enabled?
end
- def cache_tags(container_repository, tags)
- cache(container_repository).insert(tags, older_than_in_seconds) if caching_enabled?(container_repository)
+ def cache_tags(tags)
+ cache.insert(tags, older_than_in_seconds) if caching_enabled?
end
- def cache(container_repository)
- # TODO Implement https://gitlab.com/gitlab-org/gitlab/-/issues/340277 to avoid passing
- # the container repository parameter which is bad for a memoized function
+ def cache
strong_memoize(:cache) do
- ::Projects::ContainerRepository::CacheTagsCreatedAtService.new(container_repository)
+ ::Projects::ContainerRepository::CacheTagsCreatedAtService.new(@container_repository)
end
end
- def caching_enabled?(container_repository)
- params['container_expiration_policy'] &&
+ def caching_enabled?
+ container_expiration_policy &&
older_than.present? &&
- Feature.enabled?(:container_registry_expiration_policies_caching, container_repository.project)
+ Feature.enabled?(:container_registry_expiration_policies_caching, @project)
end
def throttling_enabled?
@@ -155,7 +159,11 @@ module Projects
end
def keep_n
- params['keep_n'].to_i
+ @params['keep_n']
+ end
+
+ def keep_n_as_integer
+ keep_n.to_i
end
def older_than_in_seconds
@@ -165,7 +173,23 @@ module Projects
end
def older_than
- params['older_than']
+ @params['older_than']
+ end
+
+ def name_regex_delete
+ @params['name_regex_delete']
+ end
+
+ def name_regex
+ @params['name_regex']
+ end
+
+ def name_regex_keep
+ @params['name_regex_keep']
+ end
+
+ def container_expiration_policy
+ @params['container_expiration_policy']
end
end
end
diff --git a/app/workers/ci/stuck_builds/drop_running_worker.rb b/app/workers/ci/stuck_builds/drop_running_worker.rb
index 35326bf74c9..db571fdc38d 100644
--- a/app/workers/ci/stuck_builds/drop_running_worker.rb
+++ b/app/workers/ci/stuck_builds/drop_running_worker.rb
@@ -4,6 +4,7 @@ module Ci
module StuckBuilds
class DropRunningWorker
include ApplicationWorker
+ include ExclusiveLeaseGuard
idempotent!
@@ -17,26 +18,16 @@ module Ci
feature_category :continuous_integration
- EXCLUSIVE_LEASE_KEY = 'ci_stuck_builds_drop_running_worker_lease'
-
def perform
- return unless try_obtain_lease
-
- begin
+ try_obtain_lease do
Ci::StuckBuilds::DropRunningService.new.execute
- ensure
- remove_lease
end
end
private
- def try_obtain_lease
- @uuid = Gitlab::ExclusiveLease.new(EXCLUSIVE_LEASE_KEY, timeout: 30.minutes).try_obtain
- end
-
- def remove_lease
- Gitlab::ExclusiveLease.cancel(EXCLUSIVE_LEASE_KEY, @uuid)
+ def lease_timeout
+ 30.minutes
end
end
end
diff --git a/app/workers/cleanup_container_repository_worker.rb b/app/workers/cleanup_container_repository_worker.rb
index 9adc026ced2..7274ecf62f9 100644
--- a/app/workers/cleanup_container_repository_worker.rb
+++ b/app/workers/cleanup_container_repository_worker.rb
@@ -28,8 +28,8 @@ class CleanupContainerRepositoryWorker
end
result = Projects::ContainerRepository::CleanupTagsService
- .new(project, current_user, params)
- .execute(container_repository)
+ .new(container_repository, current_user, params)
+ .execute
if run_by_container_expiration_policy? && result[:status] == :success
container_repository.reset_expiration_policy_started_at!
diff --git a/app/workers/stuck_ci_jobs_worker.rb b/app/workers/stuck_ci_jobs_worker.rb
index 6282c9200b1..72fcf06dce1 100644
--- a/app/workers/stuck_ci_jobs_worker.rb
+++ b/app/workers/stuck_ci_jobs_worker.rb
@@ -2,6 +2,7 @@
class StuckCiJobsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
+ include ExclusiveLeaseGuard
# rubocop:disable Scalability/CronWorkerContext
# This is an instance-wide cleanup query, so there's no meaningful
@@ -14,28 +15,18 @@ class StuckCiJobsWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :continuous_integration
worker_resource_boundary :cpu
- EXCLUSIVE_LEASE_KEY = 'stuck_ci_builds_worker_lease'
-
def perform
Ci::StuckBuilds::DropRunningWorker.perform_in(20.minutes)
Ci::StuckBuilds::DropScheduledWorker.perform_in(40.minutes)
- return unless try_obtain_lease
-
- begin
+ try_obtain_lease do
Ci::StuckBuilds::DropService.new.execute
- ensure
- remove_lease
end
end
private
- def try_obtain_lease
- @uuid = Gitlab::ExclusiveLease.new(EXCLUSIVE_LEASE_KEY, timeout: 30.minutes).try_obtain
- end
-
- def remove_lease
- Gitlab::ExclusiveLease.cancel(EXCLUSIVE_LEASE_KEY, @uuid)
+ def lease_timeout
+ 30.minutes
end
end