diff options
author | Tomasz Maczukin <tomasz@maczukin.pl> | 2017-02-28 12:52:08 +0100 |
---|---|---|
committer | Tomasz Maczukin <tomasz@maczukin.pl> | 2017-03-02 17:45:46 +0100 |
commit | d5f7e5421157dbd1be134247dfec318c0db546a8 (patch) | |
tree | 21bdabb649cb1986eac60f6e2320c9de2ae1c668 | |
parent | fb8210ad19dcf012ffd1a99a649846d82870b8af (diff) | |
download | gitlab-ce-d5f7e5421157dbd1be134247dfec318c0db546a8.tar.gz |
Add job update API
-rw-r--r-- | lib/api/helpers/runner.rb | 11 | ||||
-rw-r--r-- | lib/api/runner.rb | 30 | ||||
-rw-r--r-- | spec/requests/api/runner_spec.rb | 48 |
3 files changed, 86 insertions, 3 deletions
diff --git a/lib/api/helpers/runner.rb b/lib/api/helpers/runner.rb index 8204adbcfe5..15eb6b932ed 100644 --- a/lib/api/helpers/runner.rb +++ b/lib/api/helpers/runner.rb @@ -39,13 +39,22 @@ module API (Time.now - current_runner.contacted_at) >= contacted_at_max_age end - def build_not_found! + def job_not_found! if headers['User-Agent'].to_s.match(/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 + + yield if block_given? + + forbidden!('Project has been deleted!') unless job.project + forbidden!('Job has been erased!') if job.erased? + end end end end diff --git a/lib/api/runner.rb b/lib/api/runner.rb index ada1073c8dc..b57fbdabab9 100644 --- a/lib/api/runner.rb +++ b/lib/api/runner.rb @@ -66,7 +66,7 @@ module API 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 build_not_found! + return job_not_found! end new_update = current_runner.ensure_runner_queue_value @@ -80,7 +80,7 @@ module API else Gitlab::Metrics.add_event(:build_not_found) header 'X-GitLab-Last-Update', new_update - build_not_found! + job_not_found! end else # We received build that is invalid due to concurrency conflict @@ -88,6 +88,32 @@ module API 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(Job's authentication token) + requires :id, type: Fixnum, 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) + end + put '/:id' do + job = Ci::Build.find_by_id(params[:id]) + authenticate_job!(job) + + job.update_attributes(trace: params[:trace]) if params[:trace] + + Gitlab::Metrics.add_event(:update_build, + project: job.project.path_with_namespace) + + case params[:state].to_s + when 'success' + job.success + when 'failed' + job.drop + end + end end end end diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb index 73264eea71d..21f2d7635ff 100644 --- a/spec/requests/api/runner_spec.rb +++ b/spec/requests/api/runner_spec.rb @@ -432,5 +432,53 @@ describe API::Runner do end end end + + describe 'PUT /api/v4/jobs/:id' do + let(:job) { create(:ci_build, :pending, :trace, pipeline: pipeline, runner_id: runner.id) } + + before { job.run! } + + context 'when status is given' do + it 'mark job as succeeded' do + update_job(state: 'success') + expect(job.reload.status).to eq 'success' + end + + it 'mark job as failed' do + update_job(state: 'failed') + expect(job.reload.status).to eq 'failed' + end + end + + context 'when tace is given' do + it 'updates a running build' do + update_job(trace: 'BUILD TRACE UPDATED') + + expect(response).to have_http_status(200) + expect(job.reload.trace).to eq 'BUILD TRACE UPDATED' + end + end + + context 'when no trace is given' do + it 'does not override trace information' do + update_job + expect(job.reload.trace).to eq 'BUILD TRACE' + end + end + + context 'when job has been erased' do + let(:job) { create(:ci_build, runner_id: runner.id, erased_at: Time.now) } + + it 'responds with forbidden' do + update_job + expect(response).to have_http_status(403) + end + end + + def update_job(token = job.token, **params) + new_params = params.merge(token: token) + put api("/jobs/#{job.id}"), new_params + end + end end end |