diff options
Diffstat (limited to 'app/models')
| -rw-r--r-- | app/models/ci/namespace_mirror.rb | 4 | ||||
| -rw-r--r-- | app/models/group.rb | 4 | ||||
| -rw-r--r-- | app/models/user.rb | 77 |
3 files changed, 73 insertions, 12 deletions
diff --git a/app/models/ci/namespace_mirror.rb b/app/models/ci/namespace_mirror.rb index cff63c00e07..ce3faf3546b 100644 --- a/app/models/ci/namespace_mirror.rb +++ b/app/models/ci/namespace_mirror.rb @@ -10,6 +10,10 @@ module Ci where('traversal_ids @> ARRAY[?]::int[]', id) end + scope :contains_any_of_namespaces, -> (ids) do + where('traversal_ids && ARRAY[?]::int[]', ids) + end + scope :by_namespace_id, -> (namespace_id) { where(namespace_id: namespace_id) } class << self diff --git a/app/models/group.rb b/app/models/group.rb index 92d7fddf736..4e675d3eb8a 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -776,6 +776,10 @@ class Group < Namespace super || build_dependency_proxy_image_ttl_policy end + def dependency_proxy_setting + super || build_dependency_proxy_setting + end + def crm_enabled? crm_settings&.enabled? end diff --git a/app/models/user.rb b/app/models/user.rb index 3f9f5b39922..8e954aac1ba 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1605,23 +1605,32 @@ class User < ApplicationRecord def ci_owned_runners @ci_owned_runners ||= begin - project_runners = Ci::RunnerProject - .where(project: authorized_projects(Gitlab::Access::MAINTAINER)) - .joins(:runner) - .select('ci_runners.*') - - group_runners = Ci::RunnerNamespace - .where(namespace_id: owned_groups.self_and_descendant_ids) - .joins(:runner) - .select('ci_runners.*') - - Ci::Runner.from_union([project_runners, group_runners]).allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336436') + if ci_owned_runners_cross_joins_fix_enabled? + Ci::Runner + .from_union([ci_owned_project_runners_from_project_members, + ci_owned_project_runners_from_group_members, + ci_owned_group_runners]) + else + Ci::Runner + .from_union([ci_legacy_owned_project_runners, ci_legacy_owned_group_runners]) + .allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336436') + end end end def owns_runner?(runner) - ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336436') do + if ci_owned_runners_cross_joins_fix_enabled? ci_owned_runners.exists?(runner.id) + else + ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336436') do + ci_owned_runners.exists?(runner.id) + end + end + end + + def ci_owned_runners_cross_joins_fix_enabled? + strong_memoize(:ci_owned_runners_cross_joins_fix_enabled) do + Feature.enabled?(:ci_owned_runners_cross_joins_fix, self, default_enabled: :yaml) end end @@ -2199,6 +2208,50 @@ class User < ApplicationRecord ::Gitlab::Auth::Ldap::Access.allowed?(self) end + + def ci_legacy_owned_project_runners + Ci::RunnerProject + .select('ci_runners.*') + .joins(:runner) + .where(project: authorized_projects(Gitlab::Access::MAINTAINER)) + end + + def ci_legacy_owned_group_runners + Ci::RunnerNamespace + .select('ci_runners.*') + .joins(:runner) + .where(namespace_id: owned_groups.self_and_descendant_ids) + end + + def ci_owned_project_runners_from_project_members + Ci::RunnerProject + .select('ci_runners.*') + .joins(:runner) + .where(project: project_members.where('access_level >= ?', Gitlab::Access::MAINTAINER).pluck(:source_id)) + end + + def ci_owned_project_runners_from_group_members + Ci::RunnerProject + .select('ci_runners.*') + .joins(:runner) + .joins('JOIN ci_project_mirrors ON ci_project_mirrors.project_id = ci_runner_projects.project_id') + .joins('JOIN ci_namespace_mirrors ON ci_namespace_mirrors.namespace_id = ci_project_mirrors.namespace_id') + .merge(ci_namespace_mirrors_for_group_members(Gitlab::Access::MAINTAINER)) + end + + def ci_owned_group_runners + Ci::RunnerNamespace + .select('ci_runners.*') + .joins(:runner) + .joins('JOIN ci_namespace_mirrors ON ci_namespace_mirrors.namespace_id = ci_runner_namespaces.namespace_id') + .merge(ci_namespace_mirrors_for_group_members(Gitlab::Access::OWNER)) + end + + def ci_namespace_mirrors_for_group_members(level) + Ci::NamespaceMirror.contains_any_of_namespaces( + group_members.where('access_level >= ?', level).pluck(:source_id) + ) + end end User.prepend_mod_with('User') |
