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
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/ci/runner.rb')
-rw-r--r--app/models/ci/runner.rb61
1 files changed, 38 insertions, 23 deletions
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 09ac0fa69e7..6fefe95769b 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -17,7 +17,10 @@ module Ci
extend ::Gitlab::Utils::Override
- add_authentication_token_field :token, encrypted: :optional, expires_at: :compute_token_expiration
+ add_authentication_token_field :token,
+ encrypted: :optional,
+ expires_at: :compute_token_expiration,
+ format_with_prefix: :prefix_for_new_and_legacy_runner
enum access_level: {
not_protected: 0,
@@ -54,6 +57,9 @@ module Ci
# The `STALE_TIMEOUT` constant defines the how far past the last contact or creation date a runner will be considered stale
STALE_TIMEOUT = 3.months
+ # Only allow authentication token to be visible for a short while
+ REGISTRATION_AVAILABILITY_TIME = 1.hour
+
AVAILABLE_TYPES_LEGACY = %w[specific shared].freeze
AVAILABLE_TYPES = runner_types.keys.freeze
AVAILABLE_STATUSES = %w[active paused online offline never_contacted stale].freeze # TODO: Remove in %16.0: active, paused. Relevant issue: https://gitlab.com/gitlab-org/gitlab/-/issues/344648
@@ -81,8 +87,13 @@ module Ci
scope :active, -> (value = true) { where(active: value) }
scope :paused, -> { active(false) }
scope :online, -> { where('contacted_at > ?', online_contact_time_deadline) }
- scope :recent, -> { where('ci_runners.created_at >= :date OR ci_runners.contacted_at >= :date', date: stale_deadline) }
- scope :stale, -> { where('ci_runners.created_at < :date AND (ci_runners.contacted_at IS NULL OR ci_runners.contacted_at < :date)', date: stale_deadline) }
+ scope :recent, -> do
+ where('ci_runners.created_at >= :datetime OR ci_runners.contacted_at >= :datetime', datetime: stale_deadline)
+ end
+ scope :stale, -> do
+ where('ci_runners.created_at <= :datetime AND ' \
+ '(ci_runners.contacted_at IS NULL OR ci_runners.contacted_at <= :datetime)', datetime: stale_deadline)
+ end
scope :offline, -> { where(arel_table[:contacted_at].lteq(online_contact_time_deadline)) }
scope :never_contacted, -> { where(contacted_at: nil) }
scope :ordered, -> { order(id: :desc) }
@@ -185,6 +196,7 @@ module Ci
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) }
+ scope :with_creator, -> { preload(:creator) }
validate :tag_constraints
validates :access_level, presence: true
@@ -332,7 +344,7 @@ module Ci
def stale?
return false unless created_at
- [created_at, contacted_at].compact.max < self.class.stale_deadline
+ [created_at, contacted_at].compact.max <= self.class.stale_deadline
end
def status(legacy_mode = nil)
@@ -434,7 +446,7 @@ module Ci
ensure_runner_queue_value == value if value.present?
end
- def heartbeat(values)
+ def heartbeat(values, update_contacted_at: true)
##
# We can safely ignore writes performed by a runner heartbeat. We do
# not want to upgrade database connection proxy to use the primary
@@ -442,20 +454,18 @@ module Ci
#
::Gitlab::Database::LoadBalancing::Session.without_sticky_writes do
values = values&.slice(:version, :revision, :platform, :architecture, :ip_address, :config, :executor) || {}
- values[:contacted_at] = Time.current
+ values[:contacted_at] = Time.current if update_contacted_at
if values.include?(:executor)
values[:executor_type] = EXECUTOR_NAME_TO_TYPES.fetch(values.delete(:executor), :unknown)
end
- cache_attributes(values)
+ new_version = values[:version]
+ schedule_runner_version_update(new_version) if new_version && values[:version] != version
- # We save data without validation, it will always change due to `contacted_at`
- if persist_cached_data?
- version_updated = values.include?(:version) && values[:version] != version
+ merge_cache_attributes(values)
- update_columns(values)
- schedule_runner_version_update if version_updated
- end
+ # We save data without validation, it will always change due to `contacted_at`
+ update_columns(values) if persist_cached_data?
end
end
@@ -488,17 +498,16 @@ module Ci
end
end
- override :format_token
- def format_token(token)
- return token if registration_token_registration_type?
-
- "#{CREATED_RUNNER_TOKEN_PREFIX}#{token}"
- end
-
def ensure_machine(system_xid, &blk)
RunnerMachine.safe_find_or_create_by!(runner_id: id, system_xid: system_xid.to_s, &blk) # rubocop: disable Performance/ActiveRecordSubtransactionMethods
end
+ def registration_available?
+ authenticated_user_registration_type? &&
+ created_at > REGISTRATION_AVAILABILITY_TIME.ago &&
+ !runner_machines.any?
+ end
+
private
scope :with_upgrade_status, ->(upgrade_status) do
@@ -594,10 +603,16 @@ module Ci
# TODO Remove in 16.0 when runners are known to send a system_id
# For now, heartbeats with version updates might result in two Sidekiq jobs being queued if a runner has a system_id
# This is not a problem since the jobs are deduplicated on the version
- def schedule_runner_version_update
- return unless version
+ def schedule_runner_version_update(new_version)
+ return unless new_version && Gitlab::Ci::RunnerReleases.instance.enabled?
+
+ Ci::Runners::ProcessRunnerVersionUpdateWorker.perform_async(new_version)
+ end
+
+ def prefix_for_new_and_legacy_runner
+ return if registration_token_registration_type?
- Ci::Runners::ProcessRunnerVersionUpdateWorker.perform_async(version)
+ CREATED_RUNNER_TOKEN_PREFIX
end
end
end