summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models/ci/build.rb10
-rw-r--r--lib/api/entities.rb4
-rw-r--r--lib/api/helpers/runner.rb8
-rw-r--r--lib/api/runner.rb20
-rw-r--r--spec/requests/api/runner_spec.rb78
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