diff options
Diffstat (limited to 'lib/api/runner.rb')
-rw-r--r-- | lib/api/runner.rb | 297 |
1 files changed, 0 insertions, 297 deletions
diff --git a/lib/api/runner.rb b/lib/api/runner.rb deleted file mode 100644 index 5f08ebe4a06..00000000000 --- a/lib/api/runner.rb +++ /dev/null @@ -1,297 +0,0 @@ -# frozen_string_literal: true - -module API - class Runner < Grape::API - helpers ::API::Helpers::Runner - - resource :runners do - desc 'Registers a new Runner' do - success Entities::RunnerRegistrationDetails - http_codes [[201, 'Runner was created'], [403, 'Forbidden']] - end - params do - requires :token, type: String, desc: 'Registration token' - optional :description, type: String, desc: %q(Runner's description) - optional :info, type: Hash, desc: %q(Runner's metadata) - optional :active, type: Boolean, desc: 'Should Runner be active' - optional :locked, type: Boolean, desc: 'Should Runner be locked for current project' - optional :access_level, type: String, values: Ci::Runner.access_levels.keys, - desc: 'The access_level of the runner' - optional :run_untagged, type: Boolean, desc: 'Should Runner handle untagged jobs' - optional :tag_list, type: Array[String], desc: %q(List of Runner's tags) - optional :maximum_timeout, type: Integer, desc: 'Maximum timeout set when this Runner will handle the job' - end - post '/' do - attributes = attributes_for_keys([:description, :active, :locked, :run_untagged, :tag_list, :access_level, :maximum_timeout]) - .merge(get_runner_details_from_request) - - attributes = - if runner_registration_token_valid? - # Create shared runner. Requires admin access - attributes.merge(runner_type: :instance_type) - elsif project = Project.find_by_runners_token(params[:token]) - # Create a specific runner for the project - attributes.merge(runner_type: :project_type, projects: [project]) - elsif group = Group.find_by_runners_token(params[:token]) - # Create a specific runner for the group - attributes.merge(runner_type: :group_type, groups: [group]) - else - forbidden! - end - - runner = Ci::Runner.create(attributes) - - if runner.persisted? - present runner, with: Entities::RunnerRegistrationDetails - else - render_validation_error!(runner) - end - end - - desc 'Deletes a registered Runner' do - http_codes [[204, 'Runner was deleted'], [403, 'Forbidden']] - end - params do - requires :token, type: String, desc: %q(Runner's authentication token) - end - delete '/' do - authenticate_runner! - - runner = Ci::Runner.find_by_token(params[:token]) - - destroy_conditionally!(runner) - end - - desc 'Validates authentication credentials' do - http_codes [[200, 'Credentials are valid'], [403, 'Forbidden']] - end - params do - requires :token, type: String, desc: %q(Runner's authentication token) - end - post '/verify' do - authenticate_runner! - status 200 - end - end - - resource :jobs do - before do - Gitlab::ApplicationContext.push( - user: -> { current_job&.user }, - project: -> { current_job&.project } - ) - end - - desc 'Request a job' do - success Entities::JobRequest::Response - http_codes [[201, 'Job was scheduled'], - [204, 'No job for Runner'], - [403, 'Forbidden']] - end - params do - requires :token, type: String, desc: %q(Runner's authentication token) - optional :last_update, type: String, desc: %q(Runner's queue last_update token) - optional :info, type: Hash, desc: %q(Runner's metadata) do - optional :name, type: String, desc: %q(Runner's name) - optional :version, type: String, desc: %q(Runner's version) - optional :revision, type: String, desc: %q(Runner's revision) - optional :platform, type: String, desc: %q(Runner's platform) - optional :architecture, type: String, desc: %q(Runner's architecture) - optional :executor, type: String, desc: %q(Runner's executor) - optional :features, type: Hash, desc: %q(Runner's features) - end - optional :session, type: Hash, desc: %q(Runner's session data) do - optional :url, type: String, desc: %q(Session's url) - optional :certificate, type: String, desc: %q(Session's certificate) - optional :authorization, type: String, desc: %q(Session's authorization) - end - optional :job_age, type: Integer, desc: %q(Job should be older than passed age in seconds to be ran on runner) - end - post '/request' do - authenticate_runner! - - unless current_runner.active? - header 'X-GitLab-Last-Update', current_runner.ensure_runner_queue_value - break no_content! - end - - runner_params = declared_params(include_missing: false) - - if current_runner.runner_queue_value_latest?(runner_params[:last_update]) - header 'X-GitLab-Last-Update', runner_params[:last_update] - Gitlab::Metrics.add_event(:build_not_found_cached) - break no_content! - end - - new_update = current_runner.ensure_runner_queue_value - result = ::Ci::RegisterJobService.new(current_runner).execute(runner_params) - - if result.valid? - if result.build - Gitlab::Metrics.add_event(:build_found) - present Ci::BuildRunnerPresenter.new(result.build), with: Entities::JobRequest::Response - else - Gitlab::Metrics.add_event(:build_not_found) - header 'X-GitLab-Last-Update', new_update - no_content! - end - else - # We received build that is invalid due to concurrency conflict - Gitlab::Metrics.add_event(:build_invalid) - conflict! - end - end - - desc 'Updates a job' do - http_codes [[200, 'Job was updated'], [403, 'Forbidden']] - end - params do - requires :token, type: String, desc: %q(Runners's authentication token) - requires :id, type: Integer, desc: %q(Job's ID) - optional :trace, type: String, desc: %q(Job's full trace) - optional :state, type: String, desc: %q(Job's status: success, failed) - optional :failure_reason, type: String, desc: %q(Job's failure_reason) - end - put '/:id' do - job = authenticate_job! - - job.trace.set(params[:trace]) if params[:trace] - - Gitlab::Metrics.add_event(:update_build) - - case params[:state].to_s - when 'running' - job.touch if job.needs_touch? - when 'success' - job.success! - when 'failed' - job.drop!(params[:failure_reason] || :unknown_failure) - end - end - - desc 'Appends a patch to the job trace' do - http_codes [[202, 'Trace was patched'], - [400, 'Missing Content-Range header'], - [403, 'Forbidden'], - [416, 'Range not satisfiable']] - end - params do - requires :id, type: Integer, desc: %q(Job's ID) - optional :token, type: String, desc: %q(Job's authentication token) - end - patch '/:id/trace' do - job = authenticate_job! - - error!('400 Missing header Content-Range', 400) unless request.headers.key?('Content-Range') - content_range = request.headers['Content-Range'] - content_range = content_range.split('-') - - # TODO: - # it seems that `Content-Range` as formatted by runner is wrong, - # the `byte_end` should point to final byte, but it points byte+1 - # that means that we have to calculate end of body, - # as we cannot use `content_length[1]` - # Issue: https://gitlab.com/gitlab-org/gitlab-runner/issues/3275 - - body_data = request.body.read - body_start = content_range[0].to_i - body_end = body_start + body_data.bytesize - - stream_size = job.trace.append(body_data, body_start) - unless stream_size == body_end - break error!('416 Range Not Satisfiable', 416, { 'Range' => "0-#{stream_size}" }) - end - - status 202 - header 'Job-Status', job.status - header 'Range', "0-#{stream_size}" - header 'X-GitLab-Trace-Update-Interval', job.trace.update_interval.to_s - end - - desc 'Authorize artifacts uploading for job' do - http_codes [[200, 'Upload allowed'], - [403, 'Forbidden'], - [405, 'Artifacts support not enabled'], - [413, 'File too large']] - end - params do - requires :id, type: Integer, desc: %q(Job's ID) - optional :token, type: String, desc: %q(Job's authentication token) - optional :filesize, type: Integer, desc: %q(Artifacts filesize) - optional :artifact_type, type: String, desc: %q(The type of artifact), - default: 'archive', values: Ci::JobArtifact.file_types.keys - end - post '/:id/artifacts/authorize' do - not_allowed! unless Gitlab.config.artifacts.enabled - require_gitlab_workhorse! - Gitlab::Workhorse.verify_api_request!(headers) - - job = authenticate_job! - - service = Ci::AuthorizeJobArtifactService.new(job, params, max_size: max_artifacts_size(job)) - - forbidden! if service.forbidden? - file_too_large! if service.too_large? - - status 200 - content_type Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE - service.headers - end - - desc 'Upload artifacts for job' do - success Entities::JobRequest::Response - http_codes [[201, 'Artifact uploaded'], - [400, 'Bad request'], - [403, 'Forbidden'], - [405, 'Artifacts support not enabled'], - [413, 'File too large']] - end - params do - requires :id, type: Integer, desc: %q(Job's ID) - requires :file, type: ::API::Validations::Types::WorkhorseFile, desc: %(The artifact file to store (generated by Multipart middleware)) - optional :token, type: String, desc: %q(Job's authentication token) - optional :expire_in, type: String, desc: %q(Specify when artifacts should expire) - optional :artifact_type, type: String, desc: %q(The type of artifact), - default: 'archive', values: Ci::JobArtifact.file_types.keys - optional :artifact_format, type: String, desc: %q(The format of artifact), - default: 'zip', values: Ci::JobArtifact.file_formats.keys - optional :metadata, type: ::API::Validations::Types::WorkhorseFile, desc: %(The artifact metadata to store (generated by Multipart middleware)) - end - post '/:id/artifacts' do - not_allowed! unless Gitlab.config.artifacts.enabled - require_gitlab_workhorse! - - job = authenticate_job! - - artifacts = params[:file] - metadata = params[:metadata] - - file_too_large! unless artifacts.size < max_artifacts_size(job) - - result = Ci::CreateJobArtifactsService.new(job.project).execute(job, artifacts, params, metadata_file: metadata) - - if result[:status] == :success - status :created - else - render_api_error!(result[:message], result[:http_status]) - end - end - - desc 'Download the artifacts file for job' do - http_codes [[200, 'Upload allowed'], - [403, 'Forbidden'], - [404, 'Artifact not found']] - end - params do - requires :id, type: Integer, desc: %q(Job's ID) - optional :token, type: String, desc: %q(Job's authentication token) - optional :direct_download, default: false, type: Boolean, desc: %q(Perform direct download from remote storage instead of proxying artifacts) - end - get '/:id/artifacts' do - job = authenticate_job!(require_running: false) - - present_carrierwave_file!(job.artifacts_file, supports_direct_download: params[:direct_download]) - end - end - end -end |