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/services/ci')
-rw-r--r--app/services/ci/archive_trace_service.rb4
-rw-r--r--app/services/ci/deployments/destroy_service.rb18
-rw-r--r--app/services/ci/destroy_pipeline_service.rb2
-rw-r--r--app/services/ci/job_artifacts/create_service.rb2
-rw-r--r--app/services/ci/job_artifacts/destroy_batch_service.rb4
-rw-r--r--app/services/ci/list_config_variables_service.rb4
-rw-r--r--app/services/ci/parse_dotenv_artifact_service.rb2
-rw-r--r--app/services/ci/register_job_service.rb18
-rw-r--r--app/services/ci/retry_job_service.rb12
-rw-r--r--app/services/ci/runners/assign_runner_service.rb10
-rw-r--r--app/services/ci/runners/bulk_delete_runners_service.rb36
-rw-r--r--app/services/ci/runners/process_runner_version_update_service.rb27
-rw-r--r--app/services/ci/runners/reconcile_existing_runner_versions_service.rb14
-rw-r--r--app/services/ci/runners/register_runner_service.rb4
-rw-r--r--app/services/ci/runners/reset_registration_token_service.rb10
-rw-r--r--app/services/ci/runners/unassign_runner_service.rb10
-rw-r--r--app/services/ci/runners/unregister_runner_service.rb1
-rw-r--r--app/services/ci/stuck_builds/drop_helpers.rb12
-rw-r--r--app/services/ci/track_failed_build_service.rb49
-rw-r--r--app/services/ci/update_build_state_service.rb2
20 files changed, 203 insertions, 38 deletions
diff --git a/app/services/ci/archive_trace_service.rb b/app/services/ci/archive_trace_service.rb
index 7b1d2207460..9705a236d98 100644
--- a/app/services/ci/archive_trace_service.rb
+++ b/app/services/ci/archive_trace_service.rb
@@ -62,8 +62,8 @@ module Ci
failed_archive_counter.increment
Sidekiq.logger.warn(class: worker_name,
- message: "Failed to archive trace. message: #{error.message}.",
- job_id: job.id)
+ message: "Failed to archive trace. message: #{error.message}.",
+ job_id: job.id)
Gitlab::ErrorTracking
.track_and_raise_for_dev_exception(error,
diff --git a/app/services/ci/deployments/destroy_service.rb b/app/services/ci/deployments/destroy_service.rb
new file mode 100644
index 00000000000..ac51fa55537
--- /dev/null
+++ b/app/services/ci/deployments/destroy_service.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Ci
+ module Deployments
+ class DestroyService < BaseService
+ def execute(deployment)
+ raise Gitlab::Access::AccessDeniedError unless can?(current_user, :destroy_deployment, deployment)
+
+ return ServiceResponse.error(message: 'Cannot destroy running deployment') if deployment&.running?
+ return ServiceResponse.error(message: 'Deployment currently deployed to environment') if deployment&.last?
+
+ project.destroy_deployment_by_id(deployment)
+
+ ServiceResponse.success(message: 'Deployment destroyed')
+ end
+ end
+ end
+end
diff --git a/app/services/ci/destroy_pipeline_service.rb b/app/services/ci/destroy_pipeline_service.rb
index d85e52e1312..1c563396162 100644
--- a/app/services/ci/destroy_pipeline_service.rb
+++ b/app/services/ci/destroy_pipeline_service.rb
@@ -7,7 +7,7 @@ module Ci
Ci::ExpirePipelineCacheService.new.execute(pipeline, delete: true)
- pipeline.cancel_running if pipeline.cancelable?
+ pipeline.cancel_running(cascade_to_children: true, execute_async: false) if pipeline.cancelable?
# The pipeline, the builds, job and pipeline artifacts all get destroyed here.
# Ci::Pipeline#destroy triggers fast destroy on job_artifacts and
diff --git a/app/services/ci/job_artifacts/create_service.rb b/app/services/ci/job_artifacts/create_service.rb
index 05f8e804c67..af56eb221d5 100644
--- a/app/services/ci/job_artifacts/create_service.rb
+++ b/app/services/ci/job_artifacts/create_service.rb
@@ -126,6 +126,8 @@ module Ci
job.update_column(:artifacts_expire_at, artifact.expire_at)
end
+ Gitlab::Ci::Artifacts::Logger.log_created(artifact)
+
success(artifact: artifact)
rescue ActiveRecord::RecordNotUnique => error
track_exception(error, params)
diff --git a/app/services/ci/job_artifacts/destroy_batch_service.rb b/app/services/ci/job_artifacts/destroy_batch_service.rb
index 9d6b413ce59..54ec2c671c6 100644
--- a/app/services/ci/job_artifacts/destroy_batch_service.rb
+++ b/app/services/ci/job_artifacts/destroy_batch_service.rb
@@ -53,8 +53,10 @@ module Ci
update_project_statistics! if update_stats
increment_monitoring_statistics(artifacts_count, artifacts_bytes)
+ Gitlab::Ci::Artifacts::Logger.log_deleted(@job_artifacts, 'Ci::JobArtifacts::DestroyBatchService#execute')
+
success(destroyed_artifacts_count: artifacts_count,
- statistics_updates: affected_project_statistics)
+ statistics_updates: affected_project_statistics)
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/services/ci/list_config_variables_service.rb b/app/services/ci/list_config_variables_service.rb
index 88dac514bb9..c791a89b804 100644
--- a/app/services/ci/list_config_variables_service.rb
+++ b/app/services/ci/list_config_variables_service.rb
@@ -26,8 +26,8 @@ module Ci
return {} unless config
result = Gitlab::Ci::YamlProcessor.new(config, project: project,
- user: current_user,
- sha: sha).execute
+ user: current_user,
+ sha: sha).execute
result.valid? ? result.variables_with_data : {}
end
diff --git a/app/services/ci/parse_dotenv_artifact_service.rb b/app/services/ci/parse_dotenv_artifact_service.rb
index 40e2cd82b4f..fd13ed245cf 100644
--- a/app/services/ci/parse_dotenv_artifact_service.rb
+++ b/app/services/ci/parse_dotenv_artifact_service.rb
@@ -40,7 +40,7 @@ module Ci
key, value = scan_line!(line)
variables[key] = Ci::JobVariable.new(job_id: artifact.job_id,
- source: :dotenv, key: key, value: value)
+ source: :dotenv, key: key, value: value)
end
end
diff --git a/app/services/ci/register_job_service.rb b/app/services/ci/register_job_service.rb
index 8969b95b81f..b357855db12 100644
--- a/app/services/ci/register_job_service.rb
+++ b/app/services/ci/register_job_service.rb
@@ -4,6 +4,8 @@ module Ci
# This class responsible for assigning
# proper pending build to runner on runner API request
class RegisterJobService
+ include ::Gitlab::Ci::Artifacts::Logger
+
attr_reader :runner, :metrics
TEMPORARY_LOCK_TIMEOUT = 3.seconds
@@ -220,10 +222,26 @@ module Ci
# We need to use the presenter here because Gitaly calls in the presenter
# may fail, and we need to ensure the response has been generated.
presented_build = ::Ci::BuildRunnerPresenter.new(build) # rubocop:disable CodeReuse/Presenter
+
+ log_artifacts_context(build)
+ log_build_dependencies_size(presented_build)
+
build_json = ::API::Entities::Ci::JobRequest::Response.new(presented_build).to_json
Result.new(build, build_json, true)
end
+ def log_build_dependencies_size(presented_build)
+ return unless ::Feature.enabled?(:ci_build_dependencies_artifacts_logger, type: :ops)
+
+ presented_build.all_dependencies.then do |dependencies|
+ size = dependencies.sum do |build|
+ build.available_artifacts? ? build.artifacts_file.size : 0
+ end
+
+ log_build_dependencies(size: size, count: dependencies.size) if size > 0
+ end
+ end
+
def assign_runner!(build, params)
build.runner_id = runner.id
build.runner_session_attributes = params[:session] if params[:session].present?
diff --git a/app/services/ci/retry_job_service.rb b/app/services/ci/retry_job_service.rb
index e0ced3d0197..25bda8a6380 100644
--- a/app/services/ci/retry_job_service.rb
+++ b/app/services/ci/retry_job_service.rb
@@ -4,10 +4,10 @@ module Ci
class RetryJobService < ::BaseService
include Gitlab::Utils::StrongMemoize
- def execute(job)
+ def execute(job, variables: [])
if job.retryable?
job.ensure_scheduling_type!
- new_job = retry_job(job)
+ new_job = retry_job(job, variables: variables)
ServiceResponse.success(payload: { job: new_job })
else
@@ -19,7 +19,7 @@ module Ci
end
# rubocop: disable CodeReuse/ActiveRecord
- def clone!(job)
+ def clone!(job, variables: [])
# Cloning a job requires a strict type check to ensure
# the attributes being used for the clone are taken straight
# from the model and not overridden by other abstractions.
@@ -27,7 +27,7 @@ module Ci
check_access!(job)
- new_job = job.clone(current_user: current_user)
+ new_job = job.clone(current_user: current_user, new_job_variables_attributes: variables)
new_job.run_after_commit do
::Ci::CopyCrossDatabaseAssociationsService.new.execute(job, new_job)
@@ -55,8 +55,8 @@ module Ci
def check_assignable_runners!(job); end
- def retry_job(job)
- clone!(job).tap do |new_job|
+ def retry_job(job, variables: [])
+ clone!(job, variables: variables).tap do |new_job|
check_assignable_runners!(new_job) if new_job.is_a?(Ci::Build)
next if new_job.failed?
diff --git a/app/services/ci/runners/assign_runner_service.rb b/app/services/ci/runners/assign_runner_service.rb
index 886cd3a4e44..290f945cc72 100644
--- a/app/services/ci/runners/assign_runner_service.rb
+++ b/app/services/ci/runners/assign_runner_service.rb
@@ -13,9 +13,15 @@ module Ci
end
def execute
- return false unless @user.present? && @user.can?(:assign_runner, @runner)
+ unless @user.present? && @user.can?(:assign_runner, @runner)
+ return ServiceResponse.error(message: 'user not allowed to assign runner', http_status: :forbidden)
+ end
- @runner.assign_to(@project, @user)
+ if @runner.assign_to(@project, @user)
+ ServiceResponse.success
+ else
+ ServiceResponse.error(message: 'failed to assign runner')
+ end
end
private
diff --git a/app/services/ci/runners/bulk_delete_runners_service.rb b/app/services/ci/runners/bulk_delete_runners_service.rb
new file mode 100644
index 00000000000..ce07aa541c2
--- /dev/null
+++ b/app/services/ci/runners/bulk_delete_runners_service.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Ci
+ module Runners
+ class BulkDeleteRunnersService
+ attr_reader :runners
+
+ RUNNER_LIMIT = 50
+
+ # @param runners [Array<Ci::Runner, Integer>] the runners to unregister/destroy
+ def initialize(runners:)
+ @runners = runners
+ end
+
+ def execute
+ if @runners
+ # Delete a few runners immediately
+ return ServiceResponse.success(payload: delete_runners)
+ end
+
+ ServiceResponse.success(payload: { deleted_count: 0, deleted_ids: [] })
+ end
+
+ private
+
+ def delete_runners
+ # rubocop:disable CodeReuse/ActiveRecord
+ runners_to_be_deleted = Ci::Runner.where(id: @runners).limit(RUNNER_LIMIT)
+ # rubocop:enable CodeReuse/ActiveRecord
+ deleted_ids = runners_to_be_deleted.destroy_all.map(&:id) # rubocop: disable Cop/DestroyAll
+
+ { deleted_count: deleted_ids.count, deleted_ids: deleted_ids }
+ end
+ end
+ end
+end
diff --git a/app/services/ci/runners/process_runner_version_update_service.rb b/app/services/ci/runners/process_runner_version_update_service.rb
new file mode 100644
index 00000000000..c8a5e42ccab
--- /dev/null
+++ b/app/services/ci/runners/process_runner_version_update_service.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Ci
+ module Runners
+ class ProcessRunnerVersionUpdateService
+ def initialize(version)
+ @version = version
+ end
+
+ def execute
+ return ServiceResponse.error(message: 'version not present') unless @version
+
+ _, status = upgrade_check_service.check_runner_upgrade_suggestion(@version)
+ return ServiceResponse.error(message: 'upgrade version check failed') if status == :error
+
+ Ci::RunnerVersion.upsert({ version: @version, status: status })
+ ServiceResponse.success(payload: { upgrade_status: status.to_s })
+ end
+
+ private
+
+ def upgrade_check_service
+ @runner_upgrade_check ||= Gitlab::Ci::RunnerUpgradeCheck.new(::Gitlab::VERSION)
+ end
+ end
+ end
+end
diff --git a/app/services/ci/runners/reconcile_existing_runner_versions_service.rb b/app/services/ci/runners/reconcile_existing_runner_versions_service.rb
index e04079bfe27..1950d82845b 100644
--- a/app/services/ci/runners/reconcile_existing_runner_versions_service.rb
+++ b/app/services/ci/runners/reconcile_existing_runner_versions_service.rb
@@ -3,8 +3,6 @@
module Ci
module Runners
class ReconcileExistingRunnerVersionsService
- include BaseServiceUtility
-
VERSION_BATCH_SIZE = 100
def execute
@@ -12,7 +10,7 @@ module Ci
total_deleted = cleanup_runner_versions(insert_result[:versions_from_runners])
total_updated = update_status_on_outdated_runner_versions(insert_result[:versions_from_runners])
- success({
+ ServiceResponse.success(payload: {
total_inserted: insert_result[:new_record_count],
total_updated: total_updated,
total_deleted: total_deleted
@@ -22,7 +20,7 @@ module Ci
private
def upgrade_check
- Gitlab::Ci::RunnerUpgradeCheck.instance
+ @runner_upgrade_check ||= Gitlab::Ci::RunnerUpgradeCheck.new(::Gitlab::VERSION)
end
# rubocop: disable CodeReuse/ActiveRecord
@@ -74,13 +72,11 @@ module Ci
end
def runner_version_with_updated_status(runner_version)
- version = runner_version['version']
- suggestion = upgrade_check.check_runner_upgrade_status(version)
- new_status = suggestion.each_key.first
+ _, new_status = upgrade_check.check_runner_upgrade_suggestion(runner_version.version)
- if new_status != :error && new_status != runner_version['status'].to_sym
+ if new_status != :error && new_status != runner_version.status.to_sym
{
- version: version,
+ version: runner_version.version,
status: Ci::RunnerVersion.statuses[new_status]
}
end
diff --git a/app/services/ci/runners/register_runner_service.rb b/app/services/ci/runners/register_runner_service.rb
index 6588cd7e248..ae9b8bc8a16 100644
--- a/app/services/ci/runners/register_runner_service.rb
+++ b/app/services/ci/runners/register_runner_service.rb
@@ -6,7 +6,7 @@ module Ci
def execute(registration_token, attributes)
runner_type_attrs = extract_runner_type_attrs(registration_token)
- return unless runner_type_attrs
+ return ServiceResponse.error(message: 'invalid token supplied', http_status: :forbidden) unless runner_type_attrs
runner = ::Ci::Runner.new(attributes.merge(runner_type_attrs))
@@ -20,7 +20,7 @@ module Ci
end
end
- runner
+ ServiceResponse.success(payload: { runner: runner })
end
private
diff --git a/app/services/ci/runners/reset_registration_token_service.rb b/app/services/ci/runners/reset_registration_token_service.rb
index 81a70a771cf..dddbfb78d44 100644
--- a/app/services/ci/runners/reset_registration_token_service.rb
+++ b/app/services/ci/runners/reset_registration_token_service.rb
@@ -11,15 +11,19 @@ module Ci
end
def execute
- return unless @user.present? && @user.can?(:update_runners_registration_token, scope)
+ unless @user.present? && @user.can?(:update_runners_registration_token, scope)
+ return ServiceResponse.error(message: 'user not allowed to update runners registration token')
+ end
if scope.respond_to?(:runners_registration_token)
scope.reset_runners_registration_token!
- scope.runners_registration_token
+ runners_token = scope.runners_registration_token
else
scope.reset_runners_token!
- scope.runners_token
+ runners_token = scope.runners_token
end
+
+ ServiceResponse.success(payload: { new_registration_token: runners_token })
end
private
diff --git a/app/services/ci/runners/unassign_runner_service.rb b/app/services/ci/runners/unassign_runner_service.rb
index 1e46cf6add8..c40e5e0d44e 100644
--- a/app/services/ci/runners/unassign_runner_service.rb
+++ b/app/services/ci/runners/unassign_runner_service.rb
@@ -13,9 +13,15 @@ module Ci
end
def execute
- return false unless @user.present? && @user.can?(:assign_runner, @runner)
+ unless @user.present? && @user.can?(:assign_runner, @runner)
+ return ServiceResponse.error(message: 'user not allowed to assign runner')
+ end
- @runner_project.destroy
+ if @runner_project.destroy
+ ServiceResponse.success
+ else
+ ServiceResponse.error(message: 'failed to destroy runner project')
+ end
end
private
diff --git a/app/services/ci/runners/unregister_runner_service.rb b/app/services/ci/runners/unregister_runner_service.rb
index 4ee1e73c458..742b21f77df 100644
--- a/app/services/ci/runners/unregister_runner_service.rb
+++ b/app/services/ci/runners/unregister_runner_service.rb
@@ -14,6 +14,7 @@ module Ci
def execute
@runner&.destroy
+ ServiceResponse.success
end
end
end
diff --git a/app/services/ci/stuck_builds/drop_helpers.rb b/app/services/ci/stuck_builds/drop_helpers.rb
index 048b52c6e13..dca50963883 100644
--- a/app/services/ci/stuck_builds/drop_helpers.rb
+++ b/app/services/ci/stuck_builds/drop_helpers.rb
@@ -56,12 +56,12 @@ module Ci
def log_dropping_message(type, build, reason)
Gitlab::AppLogger.info(class: self.class.name,
- message: "Dropping #{type} build",
- build_stuck_type: type,
- build_id: build.id,
- runner_id: build.runner_id,
- build_status: build.status,
- build_failure_reason: reason)
+ message: "Dropping #{type} build",
+ build_stuck_type: type,
+ build_id: build.id,
+ runner_id: build.runner_id,
+ build_status: build.status,
+ build_failure_reason: reason)
end
end
end
diff --git a/app/services/ci/track_failed_build_service.rb b/app/services/ci/track_failed_build_service.rb
new file mode 100644
index 00000000000..caf7034234c
--- /dev/null
+++ b/app/services/ci/track_failed_build_service.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+# This service tracks failed CI builds using Snowplow.
+#
+# @param build [Ci::Build] the build that failed.
+# @param exit_code [Int] the resulting exit code.
+module Ci
+ class TrackFailedBuildService
+ SCHEMA_URL = 'iglu:com.gitlab/ci_build_failed/jsonschema/1-0-0'
+
+ def initialize(build:, exit_code:, failure_reason:)
+ @build = build
+ @exit_code = exit_code
+ @failure_reason = failure_reason
+ end
+
+ def execute
+ # rubocop:disable Style/IfUnlessModifier
+ unless @build.failed?
+ return ServiceResponse.error(message: 'Attempted to track a non-failed CI build')
+ end
+
+ # rubocop:enable Style/IfUnlessModifier
+
+ context = SnowplowTracker::SelfDescribingJson.new(SCHEMA_URL, payload)
+
+ ::Gitlab::Tracking.event(
+ 'ci::build',
+ 'failed',
+ context: [context],
+ user: @build.user,
+ project: @build.project_id)
+
+ ServiceResponse.success
+ end
+
+ private
+
+ def payload
+ {
+ build_id: @build.id,
+ build_name: @build.name,
+ build_artifact_types: @build.job_artifact_types,
+ exit_code: @exit_code,
+ failure_reason: @failure_reason
+ }
+ end
+ end
+end
diff --git a/app/services/ci/update_build_state_service.rb b/app/services/ci/update_build_state_service.rb
index a74ddcfaf06..835d5f9a16c 100644
--- a/app/services/ci/update_build_state_service.rb
+++ b/app/services/ci/update_build_state_service.rb
@@ -105,7 +105,7 @@ module Ci
Result.new(status: 200)
when 'failed'
- build.drop_with_exit_code!(params[:failure_reason] || :unknown_failure, params[:exit_code])
+ build.drop_with_exit_code!(params[:failure_reason], params[:exit_code])
Result.new(status: 200)
else