summaryrefslogtreecommitdiff
path: root/app/models/ci
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-02-18 09:45:46 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-02-18 09:45:46 +0000
commita7b3560714b4d9cc4ab32dffcd1f74a284b93580 (patch)
tree7452bd5c3545c2fa67a28aa013835fb4fa071baf /app/models/ci
parentee9173579ae56a3dbfe5afe9f9410c65bb327ca7 (diff)
downloadgitlab-ce-a7b3560714b4d9cc4ab32dffcd1f74a284b93580.tar.gz
Add latest changes from gitlab-org/gitlab@14-8-stable-eev14.8.0-rc42
Diffstat (limited to 'app/models/ci')
-rw-r--r--app/models/ci/namespace_mirror.rb4
-rw-r--r--app/models/ci/pipeline.rb26
-rw-r--r--app/models/ci/runner.rb120
3 files changed, 73 insertions, 77 deletions
diff --git a/app/models/ci/namespace_mirror.rb b/app/models/ci/namespace_mirror.rb
index ce3faf3546b..d5cbbb96134 100644
--- a/app/models/ci/namespace_mirror.rb
+++ b/app/models/ci/namespace_mirror.rb
@@ -6,7 +6,7 @@ module Ci
class NamespaceMirror < ApplicationRecord
belongs_to :namespace
- scope :contains_namespace, -> (id) do
+ scope :by_group_and_descendants, -> (id) do
where('traversal_ids @> ARRAY[?]::int[]', id)
end
@@ -32,7 +32,7 @@ module Ci
private
def sync_children_namespaces!(namespace_id, traversal_ids)
- contains_namespace(namespace_id)
+ by_group_and_descendants(namespace_id)
.where.not(namespace_id: namespace_id)
.update_all(
"traversal_ids = ARRAY[#{sanitize_sql(traversal_ids.join(','))}]::int[] || traversal_ids[array_position(traversal_ids, #{sanitize_sql(namespace_id)}) + 1:]"
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 00d331df4c3..a1311b8555f 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -40,6 +40,10 @@ module Ci
# https://gitlab.com/gitlab-org/gitlab/-/issues/259010
attr_accessor :merged_yaml
+ # This is used to retain access to the method defined by `Ci::HasRef`
+ # before being overridden in this class.
+ alias_method :jobs_git_ref, :git_ref
+
belongs_to :project, inverse_of: :all_pipelines
belongs_to :user
belongs_to :auto_canceled_by, class_name: 'Ci::Pipeline'
@@ -72,8 +76,6 @@ module Ci
has_many :build_trace_chunks, class_name: 'Ci::BuildTraceChunk', through: :builds, source: :trace_chunks
has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id # rubocop:disable Cop/ActiveRecordDependent
has_many :variables, class_name: 'Ci::PipelineVariable'
- has_many :deployments, through: :builds
- has_many :environments, -> { distinct.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338658') }, through: :deployments
has_many :latest_builds, -> { latest.with_project_and_metadata }, foreign_key: :commit_id, inverse_of: :pipeline, class_name: 'Ci::Build'
has_many :downloadable_artifacts, -> do
not_expired.or(where_exists(::Ci::Pipeline.artifacts_locked.where('ci_pipelines.id = ci_builds.commit_id'))).downloadable.with_job
@@ -352,7 +354,7 @@ module Ci
#
# ref - The name (or names) of the branch(es)/tag(s) to limit the list of
# pipelines to.
- # sha - The commit SHA (or mutliple SHAs) to limit the list of pipelines to.
+ # sha - The commit SHA (or multiple SHAs) to limit the list of pipelines to.
# limit - This limits a backlog search, default to 100.
def self.newest_first(ref: nil, sha: nil, limit: 100)
relation = order(id: :desc)
@@ -1163,7 +1165,11 @@ module Ci
end
def merge_request?
- merge_request_id.present?
+ if Feature.enabled?(:ci_pipeline_merge_request_presence_check, default_enabled: :yaml)
+ merge_request_id.present? && merge_request
+ else
+ merge_request_id.present?
+ end
end
def external_pull_request?
@@ -1284,18 +1290,6 @@ module Ci
end
end
- def create_deployment_in_separate_transaction?
- strong_memoize(:create_deployment_in_separate_transaction) do
- ::Feature.enabled?(:create_deployment_in_separate_transaction, project, default_enabled: :yaml)
- end
- end
-
- def use_variables_builder_definitions?
- strong_memoize(:use_variables_builder_definitions) do
- ::Feature.enabled?(:ci_use_variables_builder_definitions, project, default_enabled: :yaml)
- end
- end
-
private
def add_message(severity, content)
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 809c245d2b9..11150e839a3 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -13,7 +13,7 @@ module Ci
include TaggableQueries
include Presentable
- add_authentication_token_field :token, encrypted: :optional
+ add_authentication_token_field :token, encrypted: :optional, expires_at: :compute_token_expiration, expiration_enforced?: :token_expiration_enforced?
enum access_level: {
not_protected: 0,
@@ -67,7 +67,7 @@ module Ci
has_many :builds
has_many :runner_projects, inverse_of: :runner, autosave: true, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
- has_many :projects, through: :runner_projects
+ has_many :projects, through: :runner_projects, disable_joins: true
has_many :runner_namespaces, inverse_of: :runner, autosave: true
has_many :groups, through: :runner_namespaces, disable_joins: true
@@ -101,7 +101,7 @@ module Ci
}
scope :belonging_to_group_or_project_descendants, -> (group_id) {
- group_ids = Ci::NamespaceMirror.contains_namespace(group_id).select(:namespace_id)
+ group_ids = Ci::NamespaceMirror.by_group_and_descendants(group_id).select(:namespace_id)
project_ids = Ci::ProjectMirror.by_namespace_id(group_ids).select(:project_id)
group_runners = joins(:runner_namespaces).where(ci_runner_namespaces: { namespace_id: group_ids })
@@ -119,30 +119,6 @@ module Ci
.where(ci_runner_namespaces: { namespace_id: group_self_and_ancestors_ids })
}
- # deprecated
- # split this into: belonging_to_group & belonging_to_group_and_ancestors
- scope :legacy_belonging_to_group, -> (group_id, include_ancestors: false) {
- groups = ::Group.where(id: group_id)
- groups = groups.self_and_ancestors if include_ancestors
-
- joins(:runner_namespaces)
- .where(ci_runner_namespaces: { namespace_id: groups })
- .allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336433')
- }
-
- # deprecated
- scope :legacy_belonging_to_group_or_project, -> (group_id, project_id) {
- groups = ::Group.where(id: group_id)
-
- group_runners = joins(:runner_namespaces).where(ci_runner_namespaces: { namespace_id: groups })
- project_runners = joins(:runner_projects).where(ci_runner_projects: { project_id: project_id })
-
- union_sql = ::Gitlab::SQL::Union.new([group_runners, project_runners]).to_sql
-
- from("(#{union_sql}) #{table_name}")
- .allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336433')
- }
-
scope :belonging_to_parent_group_of_project, -> (project_id) {
raise ArgumentError, "only 1 project_id allowed for performance reasons" unless project_id.is_a?(Integer)
@@ -152,11 +128,23 @@ module Ci
}
scope :owned_or_instance_wide, -> (project_id) do
+ project = project_id.respond_to?(:shared_runners) ? project_id : Project.find(project_id)
+
from_union(
[
belonging_to_project(project_id),
- belonging_to_parent_group_of_project(project_id),
- instance_type
+ project.group_runners_enabled? ? belonging_to_parent_group_of_project(project_id) : nil,
+ project.shared_runners
+ ].compact,
+ remove_duplicates: false
+ )
+ end
+
+ scope :group_or_instance_wide, -> (group) do
+ from_union(
+ [
+ belonging_to_group_and_ancestors(group.id),
+ group.shared_runners
],
remove_duplicates: false
)
@@ -179,6 +167,8 @@ module Ci
scope :order_contacted_at_desc, -> { order(contacted_at: :desc) }
scope :order_created_at_asc, -> { order(created_at: :asc) }
scope :order_created_at_desc, -> { order(created_at: :desc) }
+ scope :order_token_expires_at_asc, -> { order(token_expires_at: :asc) }
+ scope :order_token_expires_at_desc, -> { order(token_expires_at: :desc) }
scope :with_tags, -> { preload(:tags) }
validate :tag_constraints
@@ -210,7 +200,9 @@ module Ci
validates :config, json_schema: { filename: 'ci_runner_config' }
- validates :maintainer_note, length: { maximum: 255 }
+ validates :maintenance_note, length: { maximum: 255 }
+
+ alias_attribute :maintenance_note, :maintainer_note
# Searches for runners matching the given query.
#
@@ -247,6 +239,10 @@ module Ci
order_contacted_at_desc
when 'created_at_asc'
order_created_at_asc
+ when 'token_expires_at_asc'
+ order_token_expires_at_asc
+ when 'token_expires_at_desc'
+ order_token_expires_at_desc
else
order_created_at_desc
end
@@ -360,27 +356,12 @@ module Ci
runner_projects.any?
end
- # TODO: remove this method in favor of `matches_build?` once feature flag is removed
- # https://gitlab.com/gitlab-org/gitlab/-/issues/323317
- def can_pick?(build)
- if Feature.enabled?(:ci_runners_short_circuit_assignable_for, self, default_enabled: :yaml)
- matches_build?(build)
- else
- # Run `matches_build?` checks before, since they are cheaper than
- # `assignable_for?`.
- #
- matches_build?(build) && assignable_for?(build.project_id)
- end
- end
-
def match_build_if_online?(build)
- active? && online? && can_pick?(build)
+ active? && online? && matches_build?(build)
end
def only_for?(project)
- ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338659') do
- projects == [project]
- end
+ !runner_projects.where.not(project_id: project.id).exists?
end
def short_sha
@@ -388,8 +369,6 @@ module Ci
end
def tag_list
- return super unless Feature.enabled?(:ci_preload_runner_tags, default_enabled: :yaml)
-
if tags.loaded?
tags.map(&:name)
else
@@ -455,6 +434,10 @@ module Ci
tick_runner_queue if matches_build?(build)
end
+ def matches_build?(build)
+ runner_matcher.matches?(build.build_matcher)
+ end
+
def uncached_contacted_at
read_attribute(:contacted_at)
end
@@ -465,6 +448,21 @@ module Ci
end
end
+ def compute_token_expiration
+ case runner_type
+ when 'instance_type'
+ compute_token_expiration_instance
+ when 'group_type'
+ compute_token_expiration_group
+ when 'project_type'
+ compute_token_expiration_project
+ end
+ end
+
+ def self.token_expiration_enforced?
+ Feature.enabled?(:enforce_runner_token_expires_at, default_enabled: :yaml)
+ end
+
private
EXECUTOR_NAME_TO_TYPES = {
@@ -484,6 +482,20 @@ module Ci
EXECUTOR_TYPE_TO_NAMES = EXECUTOR_NAME_TO_TYPES.invert.freeze
+ def compute_token_expiration_instance
+ return unless expiration_interval = Gitlab::CurrentSettings.runner_token_expiration_interval
+
+ expiration_interval.seconds.from_now
+ end
+
+ def compute_token_expiration_group
+ ::Group.where(id: runner_namespaces.map(&:namespace_id)).map(&:effective_runner_token_expiration_interval).compact.min&.from_now
+ end
+
+ def compute_token_expiration_project
+ Project.where(id: runner_projects.map(&:project_id)).map(&:effective_runner_token_expiration_interval).compact.min&.from_now
+ end
+
def cleanup_runner_queue
Gitlab::Redis::SharedState.with do |redis|
redis.del(runner_queue_key)
@@ -510,12 +522,6 @@ module Ci
end
end
- # TODO: remove this method once feature flag ci_runners_short_circuit_assignable_for
- # is removed. https://gitlab.com/gitlab-org/gitlab/-/issues/323317
- def assignable_for?(project_id)
- self.class.owned_or_instance_wide(project_id).where(id: self.id).any?
- end
-
def no_projects
if runner_projects.any?
errors.add(:runner, 'cannot have projects assigned')
@@ -539,10 +545,6 @@ module Ci
errors.add(:runner, 'needs to be assigned to exactly one group')
end
end
-
- def matches_build?(build)
- runner_matcher.matches?(build.build_matcher)
- end
end
end