diff options
| -rw-r--r-- | app/models/ci/build.rb | 10 | ||||
| -rw-r--r-- | lib/api/entities.rb | 4 | ||||
| -rw-r--r-- | lib/api/helpers/runner.rb | 8 | ||||
| -rw-r--r-- | lib/api/runner.rb | 20 | ||||
| -rw-r--r-- | spec/requests/api/runner_spec.rb | 78 |
5 files changed, 91 insertions, 29 deletions
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 53fc0d87823..ad0be70c32a 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -539,6 +539,16 @@ module Ci Gitlab::Ci::Build::Credentials::Factory.new(self).create! end + def dependencies + depended_jobs = depends_on_builds + + return depended_jobs unless options[:dependencies].present? + + depended_jobs.select do |job| + options[:dependencies].include?(job.name) + end + end + private def update_artifacts_size diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 0a12ee72d49..5954aea8041 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -768,7 +768,7 @@ module API end class Dependency < Grape::Entity - expose :id, :name + expose :id, :name, :token expose :artifacts_file, using: ArtifactFile, if: ->(job, _) { job.artifacts? } end @@ -796,7 +796,7 @@ module API expose :artifacts, using: Artifacts expose :cache, using: Cache expose :credentials, using: Credentials - expose :depends_on_builds, as: :dependencies, using: Dependency + expose :dependencies, using: Dependency end end end diff --git a/lib/api/helpers/runner.rb b/lib/api/helpers/runner.rb index ec2bcaed929..74848a6e144 100644 --- a/lib/api/helpers/runner.rb +++ b/lib/api/helpers/runner.rb @@ -41,14 +41,6 @@ module API (Time.now - current_runner.contacted_at) >= contacted_at_max_age end - def job_not_found! - if headers['User-Agent'].to_s =~ /gitlab(-ci-multi)?-runner \d+\.\d+\.\d+(~beta\.\d+\.g[0-9a-f]+)? / - no_content! - else - not_found! - end - end - def validate_job!(job) not_found! unless job diff --git a/lib/api/runner.rb b/lib/api/runner.rb index c700d2ef4a1..4c9db2c8716 100644 --- a/lib/api/runner.rb +++ b/lib/api/runner.rb @@ -47,11 +47,25 @@ module API authenticate_runner! Ci::Runner.find_by_token(params[:token]).destroy 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 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) @@ -60,13 +74,13 @@ module API end post '/request' do authenticate_runner! - not_found! unless current_runner.active? + no_content! unless current_runner.active? update_runner_info if current_runner.is_runner_queue_value_latest?(params[:last_update]) header 'X-GitLab-Last-Update', params[:last_update] Gitlab::Metrics.add_event(:build_not_found_cached) - return job_not_found! + return no_content! end new_update = current_runner.ensure_runner_queue_value @@ -80,7 +94,7 @@ module API else Gitlab::Metrics.add_event(:build_not_found) header 'X-GitLab-Last-Update', new_update - job_not_found! + no_content! end else # We received build that is invalid due to concurrency conflict diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb index 442b2df1952..044b989e5ba 100644 --- a/spec/requests/api/runner_spec.rb +++ b/spec/requests/api/runner_spec.rb @@ -152,6 +152,34 @@ describe API::Runner do end end end + + describe 'POST /api/v4/runners/verify' do + let(:runner) { create(:ci_runner) } + + context 'when no token is provided' do + it 'returns 400 error' do + post api('/runners/verify') + + expect(response).to have_http_status :bad_request + end + end + + context 'when invalid token is provided' do + it 'returns 403 error' do + post api('/runners/verify'), token: 'invalid-token' + + expect(response).to have_http_status 403 + end + end + + context 'when valid token is provided' do + it 'verifies Runner credentials' do + post api('/runners/verify'), token: runner.token + + expect(response).to have_http_status 200 + end + end + end end describe '/api/v4/jobs' do @@ -220,18 +248,6 @@ describe API::Runner do it { expect(response).to have_http_status(204) } end end - - context "when runner doesn't send version in User-Agent" do - let(:user_agent) { 'Go-http-client/1.1' } - - it { expect(response).to have_http_status(404) } - end - - context "when runner doesn't have a User-Agent" do - let(:user_agent) { nil } - - it { expect(response).to have_http_status(404) } - end end context 'when no token is provided' do @@ -254,10 +270,10 @@ describe API::Runner do context 'when Runner is not active' do let(:runner) { create(:ci_runner, :inactive) } - it 'returns 404 error' do + it 'returns 204 error' do request_job - expect(response).to have_http_status 404 + expect(response).to have_http_status 204 end end @@ -401,9 +417,39 @@ describe API::Runner do end context 'when project and pipeline have multiple jobs' do + let!(:job) { create(:ci_build_tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) } + let!(:job2) { create(:ci_build_tag, pipeline: pipeline, name: 'rubocop', stage: 'test', stage_idx: 0) } let!(:test_job) { create(:ci_build, pipeline: pipeline, name: 'deploy', stage: 'deploy', stage_idx: 1) } - before { job.success } + before do + job.success + job2.success + end + + it 'returns dependent jobs' do + request_job + + expect(response).to have_http_status(201) + expect(json_response['id']).to eq(test_job.id) + expect(json_response['dependencies'].count).to eq(2) + expect(json_response['dependencies']).to include({ 'id' => job.id, 'name' => job.name, 'token' => job.token }, + { 'id' => job2.id, 'name' => job2.name, 'token' => job2.token }) + end + end + + context 'when explicit dependencies are defined' do + let!(:job) { create(:ci_build_tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) } + let!(:job2) { create(:ci_build_tag, pipeline: pipeline, name: 'rubocop', stage: 'test', stage_idx: 0) } + let!(:test_job) do + create(:ci_build, pipeline: pipeline, token: 'test-job-token', name: 'deploy', + stage: 'deploy', stage_idx: 1, + options: { dependencies: [job2.name] }) + end + + before do + job.success + job2.success + end it 'returns dependent jobs' do request_job @@ -411,7 +457,7 @@ describe API::Runner do expect(response).to have_http_status(201) expect(json_response['id']).to eq(test_job.id) expect(json_response['dependencies'].count).to eq(1) - expect(json_response['dependencies'][0]).to include('id' => job.id, 'name' => 'spinach') + expect(json_response['dependencies'][0]).to include('id' => job2.id, 'name' => job2.name, 'token' => job2.token) end end |
