diff options
Diffstat (limited to 'app/services/ci')
-rw-r--r-- | app/services/ci/build_report_result_service.rb | 1 | ||||
-rw-r--r-- | app/services/ci/change_variable_service.rb | 33 | ||||
-rw-r--r-- | app/services/ci/change_variables_service.rb | 11 | ||||
-rw-r--r-- | app/services/ci/create_cross_project_pipeline_service.rb | 2 | ||||
-rw-r--r-- | app/services/ci/create_job_artifacts_service.rb | 2 | ||||
-rw-r--r-- | app/services/ci/create_pipeline_service.rb | 53 | ||||
-rw-r--r-- | app/services/ci/create_web_ide_terminal_service.rb | 2 | ||||
-rw-r--r-- | app/services/ci/pipeline_processing/legacy_processing_service.rb | 122 | ||||
-rw-r--r-- | app/services/ci/process_pipeline_service.rb | 14 | ||||
-rw-r--r-- | app/services/ci/register_job_service.rb | 28 | ||||
-rw-r--r-- | app/services/ci/retry_pipeline_service.rb | 8 |
11 files changed, 79 insertions, 197 deletions
diff --git a/app/services/ci/build_report_result_service.rb b/app/services/ci/build_report_result_service.rb index 758ba1c73bf..ca66ad8249d 100644 --- a/app/services/ci/build_report_result_service.rb +++ b/app/services/ci/build_report_result_service.rb @@ -3,7 +3,6 @@ module Ci class BuildReportResultService def execute(build) - return unless Feature.enabled?(:build_report_summary, build.project) return unless build.has_test_reports? build.report_results.create!( diff --git a/app/services/ci/change_variable_service.rb b/app/services/ci/change_variable_service.rb new file mode 100644 index 00000000000..f515a335d54 --- /dev/null +++ b/app/services/ci/change_variable_service.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module Ci + class ChangeVariableService < BaseContainerService + def execute + case params[:action] + when :create + container.variables.create(params[:variable_params]) + when :update + variable.tap do |target_variable| + target_variable.update(params[:variable_params].except(:key)) + end + when :destroy + variable.tap do |target_variable| + target_variable.destroy + end + end + end + + private + + def variable + params[:variable] || find_variable + end + + def find_variable + identifier = params[:variable_params].slice(:id).presence || params[:variable_params].slice(:key) + container.variables.find_by!(identifier) # rubocop:disable CodeReuse/ActiveRecord + end + end +end + +::Ci::ChangeVariableService.prepend_if_ee('EE::Ci::ChangeVariableService') diff --git a/app/services/ci/change_variables_service.rb b/app/services/ci/change_variables_service.rb new file mode 100644 index 00000000000..3337eb09411 --- /dev/null +++ b/app/services/ci/change_variables_service.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Ci + class ChangeVariablesService < BaseContainerService + def execute + container.update(params) + end + end +end + +::Ci::ChangeVariablesService.prepend_if_ee('EE::Ci::ChangeVariablesService') diff --git a/app/services/ci/create_cross_project_pipeline_service.rb b/app/services/ci/create_cross_project_pipeline_service.rb index 1700312b941..23207d809d4 100644 --- a/app/services/ci/create_cross_project_pipeline_service.rb +++ b/app/services/ci/create_cross_project_pipeline_service.rb @@ -98,7 +98,7 @@ module Ci end def can_update_branch?(target_ref) - ::Gitlab::UserAccess.new(current_user, project: downstream_project).can_update_branch?(target_ref) + ::Gitlab::UserAccess.new(current_user, container: downstream_project).can_update_branch?(target_ref) end def downstream_project diff --git a/app/services/ci/create_job_artifacts_service.rb b/app/services/ci/create_job_artifacts_service.rb index 9a6e103e5dd..cd3807e0495 100644 --- a/app/services/ci/create_job_artifacts_service.rb +++ b/app/services/ci/create_job_artifacts_service.rb @@ -25,7 +25,7 @@ module Ci if lsif?(artifact_type) headers[:ProcessLsif] = true - headers[:ProcessLsifReferences] = Feature.enabled?(:code_navigation_references, project, default_enabled: false) + headers[:ProcessLsifReferences] = Feature.enabled?(:code_navigation_references, project, default_enabled: true) end success(headers: headers) diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index 2d7f5014aa9..70ad18e80eb 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -19,9 +19,13 @@ module Ci Gitlab::Ci::Pipeline::Chain::Limit::Size, Gitlab::Ci::Pipeline::Chain::Validate::External, Gitlab::Ci::Pipeline::Chain::Populate, + Gitlab::Ci::Pipeline::Chain::StopDryRun, Gitlab::Ci::Pipeline::Chain::Create, Gitlab::Ci::Pipeline::Chain::Limit::Activity, - Gitlab::Ci::Pipeline::Chain::Limit::JobActivity].freeze + Gitlab::Ci::Pipeline::Chain::Limit::JobActivity, + Gitlab::Ci::Pipeline::Chain::CancelPendingPipelines, + Gitlab::Ci::Pipeline::Chain::Metrics, + Gitlab::Ci::Pipeline::Chain::Pipeline::Process].freeze # Create a new pipeline in the specified project. # @@ -68,21 +72,14 @@ module Ci bridge: bridge, **extra_options(options)) - sequence = Gitlab::Ci::Pipeline::Chain::Sequence - .new(pipeline, command, SEQUENCE) + # Ensure we never persist the pipeline when dry_run: true + @pipeline.readonly! if command.dry_run? - sequence.build! do |pipeline, sequence| - schedule_head_pipeline_update + Gitlab::Ci::Pipeline::Chain::Sequence + .new(pipeline, command, SEQUENCE) + .build! - if sequence.complete? - cancel_pending_pipelines if project.auto_cancel_pending_pipelines? - pipeline_created_counter.increment(source: source) - - Ci::ProcessPipelineService - .new(pipeline) - .execute(nil, initial_process: true) - end - end + schedule_head_pipeline_update if pipeline.persisted? # If pipeline is not persisted, try to recover IID pipeline.reset_project_iid unless pipeline.persisted? || @@ -110,38 +107,14 @@ module Ci commit.try(:id) end - def cancel_pending_pipelines - Gitlab::OptimisticLocking.retry_lock(auto_cancelable_pipelines) do |cancelables| - cancelables.find_each do |cancelable| - cancelable.auto_cancel_running(pipeline) - end - end - end - - # rubocop: disable CodeReuse/ActiveRecord - def auto_cancelable_pipelines - project.ci_pipelines - .where(ref: pipeline.ref) - .where.not(id: pipeline.same_family_pipeline_ids) - .where.not(sha: project.commit(pipeline.ref).try(:id)) - .alive_or_scheduled - .with_only_interruptible_builds - end - # rubocop: enable CodeReuse/ActiveRecord - - def pipeline_created_counter - @pipeline_created_counter ||= Gitlab::Metrics - .counter(:pipelines_created_total, "Counter of pipelines created") - end - def schedule_head_pipeline_update pipeline.all_merge_requests.opened.each do |merge_request| UpdateHeadPipelineForMergeRequestWorker.perform_async(merge_request.id) end end - def extra_options(content: nil) - { content: content } + def extra_options(content: nil, dry_run: false) + { content: content, dry_run: dry_run } end end end diff --git a/app/services/ci/create_web_ide_terminal_service.rb b/app/services/ci/create_web_ide_terminal_service.rb index 29d40756ab4..4f1bf0447d2 100644 --- a/app/services/ci/create_web_ide_terminal_service.rb +++ b/app/services/ci/create_web_ide_terminal_service.rb @@ -32,7 +32,7 @@ module Ci Ci::ProcessPipelineService .new(pipeline) - .execute(nil, initial_process: true) + .execute pipeline_created_counter.increment(source: :webide) end diff --git a/app/services/ci/pipeline_processing/legacy_processing_service.rb b/app/services/ci/pipeline_processing/legacy_processing_service.rb deleted file mode 100644 index 56fbc7271da..00000000000 --- a/app/services/ci/pipeline_processing/legacy_processing_service.rb +++ /dev/null @@ -1,122 +0,0 @@ -# frozen_string_literal: true - -module Ci - module PipelineProcessing - class LegacyProcessingService - include Gitlab::Utils::StrongMemoize - - attr_reader :pipeline - - def initialize(pipeline) - @pipeline = pipeline - end - - def execute(trigger_build_ids = nil, initial_process: false) - success = process_stages_for_stage_scheduling - - # we evaluate dependent needs, - # only when the another job has finished - success = process_dag_builds_without_needs || success if initial_process - success = process_dag_builds_with_needs(trigger_build_ids) || success - - @pipeline.update_legacy_status - - success - end - - private - - def process_stages_for_stage_scheduling - stage_indexes_of_created_stage_scheduled_processables.flat_map do |index| - process_stage_for_stage_scheduling(index) - end.any? - end - - def process_stage_for_stage_scheduling(index) - current_status = status_for_prior_stages(index) - - return unless Ci::HasStatus::COMPLETED_STATUSES.include?(current_status) - - created_stage_scheduled_processables_in_stage(index).find_each.select do |build| - process_build(build, current_status) - end.any? - end - - def process_dag_builds_without_needs - created_processables.scheduling_type_dag.without_needs.each do |build| - process_build(build, 'success') - end - end - - def process_dag_builds_with_needs(trigger_build_ids) - return false unless trigger_build_ids.present? - - # we find processables that are dependent: - # 1. because of current dependency, - trigger_build_names = pipeline.processables.latest - .for_ids(trigger_build_ids).names - - # 2. does not have builds that not yet complete - incomplete_build_names = pipeline.processables.latest - .incomplete.names - - # Each found processable is guaranteed here to have completed status - created_processables - .scheduling_type_dag - .with_needs(trigger_build_names) - .without_needs(incomplete_build_names) - .find_each - .map(&method(:process_dag_build_with_needs)) - .any? - end - - def process_dag_build_with_needs(build) - current_status = status_for_build_needs(build.needs.map(&:name)) - - return unless Ci::HasStatus::COMPLETED_STATUSES.include?(current_status) - - process_build(build, current_status) - end - - def process_build(build, current_status) - Gitlab::OptimisticLocking.retry_lock(build) do |subject| - Ci::ProcessBuildService.new(project, subject.user) - .execute(subject, current_status) - end - end - - def status_for_prior_stages(index) - pipeline.processables.status_for_prior_stages(index, project: pipeline.project) - end - - def status_for_build_needs(needs) - pipeline.processables.status_for_names(needs, project: pipeline.project) - end - - # rubocop: disable CodeReuse/ActiveRecord - def stage_indexes_of_created_stage_scheduled_processables - created_stage_scheduled_processables.order(:stage_idx) - .pluck(Arel.sql('DISTINCT stage_idx')) - end - # rubocop: enable CodeReuse/ActiveRecord - - def created_stage_scheduled_processables_in_stage(index) - created_stage_scheduled_processables - .with_preloads - .for_stage(index) - end - - def created_stage_scheduled_processables - created_processables.scheduling_type_stage - end - - def created_processables - pipeline.processables.created - end - - def project - pipeline.project - end - end - end -end diff --git a/app/services/ci/process_pipeline_service.rb b/app/services/ci/process_pipeline_service.rb index 1f24dce0458..d84ef5fbb93 100644 --- a/app/services/ci/process_pipeline_service.rb +++ b/app/services/ci/process_pipeline_service.rb @@ -8,20 +8,14 @@ module Ci @pipeline = pipeline end - def execute(trigger_build_ids = nil, initial_process: false) + def execute increment_processing_counter update_retried - if ::Gitlab::Ci::Features.atomic_processing?(pipeline.project) - Ci::PipelineProcessing::AtomicProcessingService - .new(pipeline) - .execute - else - Ci::PipelineProcessing::LegacyProcessingService - .new(pipeline) - .execute(trigger_build_ids, initial_process: initial_process) - end + Ci::PipelineProcessing::AtomicProcessingService + .new(pipeline) + .execute end def metrics diff --git a/app/services/ci/register_job_service.rb b/app/services/ci/register_job_service.rb index 3797ea1d96c..04d620d1d38 100644 --- a/app/services/ci/register_job_service.rb +++ b/app/services/ci/register_job_service.rb @@ -107,23 +107,15 @@ module Ci build.runner_id = runner.id build.runner_session_attributes = params[:session] if params[:session].present? - unless build.has_valid_build_dependencies? - build.drop!(:missing_dependency_failure) - return false - end - - unless build.supported_runner?(params.dig(:info, :features)) - build.drop!(:runner_unsupported) - return false - end + failure_reason, _ = pre_assign_runner_checks.find { |_, check| check.call(build, params) } - if build.archived? - build.drop!(:archived_failure) - return false + if failure_reason + build.drop!(failure_reason) + else + build.run! end - build.run! - true + !failure_reason end def scheduler_failure!(build) @@ -238,6 +230,14 @@ module Ci def job_queue_duration_seconds @job_queue_duration_seconds ||= Gitlab::Metrics.histogram(:job_queue_duration_seconds, 'Request handling execution time', {}, JOB_QUEUE_DURATION_SECONDS_BUCKETS) end + + def pre_assign_runner_checks + { + missing_dependency_failure: -> (build, _) { !build.has_valid_build_dependencies? }, + runner_unsupported: -> (build, params) { !build.supported_runner?(params.dig(:info, :features)) }, + archived_failure: -> (build, _) { build.archived? } + } + end end end diff --git a/app/services/ci/retry_pipeline_service.rb b/app/services/ci/retry_pipeline_service.rb index 4229be6c7d7..2f52f0a39c1 100644 --- a/app/services/ci/retry_pipeline_service.rb +++ b/app/services/ci/retry_pipeline_service.rb @@ -22,12 +22,6 @@ module Ci needs += build.needs.map(&:name) end - # In a DAG, the dependencies may have already completed. Figure out - # which builds have succeeded and use them to update the pipeline. If we don't - # do this, then builds will be stuck in the created state since their dependencies - # will never run. - completed_build_ids = pipeline.find_successful_build_ids_by_names(needs) if needs.any? - pipeline.builds.latest.skipped.find_each do |skipped| retry_optimistic_lock(skipped) { |build| build.process } end @@ -38,7 +32,7 @@ module Ci Ci::ProcessPipelineService .new(pipeline) - .execute(completed_build_ids, initial_process: true) + .execute end end end |