Class: Ci::CancelPipelineService

Inherits:
Object
  • Object
show all
Includes:
Gitlab::Allowable, Gitlab::OptimisticLocking
Defined in:
app/services/ci/cancel_pipeline_service.rb

Overview

Cancel a pipelines cancelable jobs and optionally it’s child pipelines cancelable jobs

Constant Summary

Constants included from Gitlab::OptimisticLocking

Gitlab::OptimisticLocking::MAX_RETRIES

Instance Method Summary collapse

Methods included from Gitlab::Allowable

#can?, #can_all?, #can_any?

Methods included from Gitlab::OptimisticLocking

log_optimistic_lock_retries, retry_lock, retry_lock_histogram, retry_lock_logger

Constructor Details

#initialize(pipeline:, current_user:, cascade_to_children: true, auto_canceled_by_pipeline: nil, execute_async: true, safe_cancellation: false) ⇒ CancelPipelineService

Returns a new instance of CancelPipelineService.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'app/services/ci/cancel_pipeline_service.rb', line 14

def initialize(
  pipeline:,
  current_user:,
  cascade_to_children: true,
  auto_canceled_by_pipeline: nil,
  execute_async: true,
  safe_cancellation: false)
  @pipeline = pipeline
  @current_user = current_user
  @cascade_to_children = cascade_to_children
  @auto_canceled_by_pipeline = auto_canceled_by_pipeline
  @execute_async = execute_async
  @safe_cancellation = safe_cancellation
end

Instance Method Details

#executeObject



29
30
31
32
33
# File 'app/services/ci/cancel_pipeline_service.rb', line 29

def execute
  return permission_error_response unless can?(current_user, :cancel_pipeline, pipeline)

  force_execute
end

#force_executeObject

This method should be used only when we want to always cancel the pipeline without checking whether the current_user has permissions to do so, or when we don’t have a current_user available in the context.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'app/services/ci/cancel_pipeline_service.rb', line 38

def force_execute
  return ServiceResponse.error(message: 'No pipeline provided', reason: :no_pipeline) unless pipeline

  unless pipeline.cancelable?
    return ServiceResponse.error(message: 'Pipeline is not cancelable', reason: :pipeline_not_cancelable)
  end

  log_pipeline_being_canceled
  update_auto_canceled_pipeline_attributes

  if @safe_cancellation
    # Only build and bridge (trigger) jobs can be interruptible.
    # We do not cancel GenericCommitStatuses because they can't have the `interruptible` attribute.
    jobs = pipeline.processables.cancelable.with_interruptible_true

    cancel_jobs(jobs)
  else
    cancel_jobs(pipeline.cancelable_statuses)
  end

  cancel_children if cascade_to_children?

  ServiceResponse.success
end