124 lines
2.9 KiB
Ruby
124 lines
2.9 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
module Ci
|
||
|
class CreateWebIdeTerminalService < ::BaseService
|
||
|
include ::Gitlab::Utils::StrongMemoize
|
||
|
|
||
|
TerminalCreationError = Class.new(StandardError)
|
||
|
|
||
|
TERMINAL_NAME = 'terminal'.freeze
|
||
|
|
||
|
attr_reader :terminal
|
||
|
|
||
|
def execute
|
||
|
check_access!
|
||
|
validate_params!
|
||
|
load_terminal_config!
|
||
|
|
||
|
pipeline = create_pipeline!
|
||
|
success(pipeline: pipeline)
|
||
|
rescue TerminalCreationError => e
|
||
|
error(e.message)
|
||
|
rescue ActiveRecord::RecordInvalid => e
|
||
|
error("Failed to persist the pipeline: #{e.message}")
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def create_pipeline!
|
||
|
build_pipeline.tap do |pipeline|
|
||
|
pipeline.stages << terminal_stage_seed(pipeline).to_resource
|
||
|
pipeline.save!
|
||
|
|
||
|
Ci::ProcessPipelineService
|
||
|
.new(pipeline)
|
||
|
.execute(nil, initial_process: true)
|
||
|
|
||
|
pipeline_created_counter.increment(source: :webide)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def build_pipeline
|
||
|
Ci::Pipeline.new(
|
||
|
project: project,
|
||
|
user: current_user,
|
||
|
source: :webide,
|
||
|
config_source: :webide_source,
|
||
|
ref: ref,
|
||
|
sha: sha,
|
||
|
tag: false,
|
||
|
before_sha: Gitlab::Git::BLANK_SHA
|
||
|
)
|
||
|
end
|
||
|
|
||
|
def terminal_stage_seed(pipeline)
|
||
|
attributes = {
|
||
|
name: TERMINAL_NAME,
|
||
|
index: 0,
|
||
|
builds: [terminal_build_seed]
|
||
|
}
|
||
|
|
||
|
Gitlab::Ci::Pipeline::Seed::Stage.new(pipeline, attributes, [])
|
||
|
end
|
||
|
|
||
|
def terminal_build_seed
|
||
|
terminal.merge(
|
||
|
name: TERMINAL_NAME,
|
||
|
stage: TERMINAL_NAME,
|
||
|
user: current_user,
|
||
|
scheduling_type: :stage)
|
||
|
end
|
||
|
|
||
|
def load_terminal_config!
|
||
|
result = ::Ci::WebIdeConfigService.new(project, current_user, sha: sha).execute
|
||
|
raise TerminalCreationError, result[:message] if result[:status] != :success
|
||
|
|
||
|
@terminal = result[:terminal]
|
||
|
raise TerminalCreationError, 'Terminal is not configured' unless terminal
|
||
|
end
|
||
|
|
||
|
def validate_params!
|
||
|
unless sha
|
||
|
raise TerminalCreationError, 'Ref does not exist'
|
||
|
end
|
||
|
|
||
|
unless branch_exists?
|
||
|
raise TerminalCreationError, 'Ref needs to be a branch'
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def check_access!
|
||
|
unless can?(current_user, :create_web_ide_terminal, project)
|
||
|
raise TerminalCreationError, 'Insufficient permissions to create a terminal'
|
||
|
end
|
||
|
|
||
|
if terminal_active?
|
||
|
raise TerminalCreationError, 'There is already a terminal running'
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def pipeline_created_counter
|
||
|
@pipeline_created_counter ||= Gitlab::Metrics
|
||
|
.counter(:pipelines_created_total, "Counter of pipelines created")
|
||
|
end
|
||
|
|
||
|
def terminal_active?
|
||
|
project.active_webide_pipelines(user: current_user).exists?
|
||
|
end
|
||
|
|
||
|
def ref
|
||
|
strong_memoize(:ref) do
|
||
|
Gitlab::Git.ref_name(params[:ref])
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def branch_exists?
|
||
|
project.repository.branch_exists?(ref)
|
||
|
end
|
||
|
|
||
|
def sha
|
||
|
project.commit(params[:ref]).try(:id)
|
||
|
end
|
||
|
end
|
||
|
end
|