137 lines
4.0 KiB
Ruby
137 lines
4.0 KiB
Ruby
require 'travis/api/app'
|
|
require 'travis/api/workers/job_cancellation'
|
|
require 'travis/api/workers/job_restart'
|
|
|
|
class Travis::Api::App
|
|
class Endpoint
|
|
class Jobs < Endpoint
|
|
include Helpers::Accept
|
|
|
|
get '/' do
|
|
prefer_follower do
|
|
respond_with service(:find_jobs, params)
|
|
end
|
|
end
|
|
|
|
get '/:id' do
|
|
job = service(:find_job, params).run
|
|
if job && job.repository
|
|
respond_with job
|
|
else
|
|
json = { error: { message: "The job(#{params[:id]}) couldn't be found" } }
|
|
status 404
|
|
respond_with json
|
|
end
|
|
end
|
|
|
|
post '/:id/cancel' do
|
|
Metriks.meter("api.request.cancel_job").mark
|
|
|
|
service = self.service(:cancel_job, params.merge(source: 'api'))
|
|
if !service.authorized?
|
|
json = { error: {
|
|
message: "You don't have access to cancel job(#{params[:id]})"
|
|
} }
|
|
|
|
Metriks.meter("api.request.cancel_job.unauthorized").mark
|
|
status 403
|
|
respond_with json
|
|
elsif !service.can_cancel?
|
|
json = { error: {
|
|
message: "The job(#{params[:id]}) can't be canceled",
|
|
code: 'cant_cancel'
|
|
} }
|
|
|
|
Metriks.meter("api.request.cancel_job.cant_cancel").mark
|
|
status 422
|
|
respond_with json
|
|
else
|
|
Travis::Sidekiq::JobCancellation.perform_async(id: params[:id], user_id: current_user.id, source: 'api')
|
|
|
|
Metriks.meter("api.request.cancel_job.success").mark
|
|
status 204
|
|
end
|
|
end
|
|
|
|
post '/:id/restart' do
|
|
Metriks.meter("api.request.restart_job").mark
|
|
|
|
service = self.service(:reset_model, job_id: params[:id])
|
|
if !service.accept?
|
|
status 400
|
|
result = false
|
|
else
|
|
Travis::Sidekiq::JobRestart.perform_async(id: params[:id], user_id: current_user.id)
|
|
status 202
|
|
result = true
|
|
end
|
|
respond_with(result: result, flash: service.messages)
|
|
end
|
|
|
|
get '/:job_id/log' do
|
|
resource = service(:find_log, params).run
|
|
if (resource && resource.removed_at) && accepts?('application/json')
|
|
respond_with resource
|
|
elsif (!resource || resource.archived?)
|
|
# the way we use responders makes it hard to validate proper format
|
|
# automatically here, so we need to check it explicitly
|
|
if accepts?('text/plain')
|
|
archived_log_path = archive_url("/jobs/#{params[:job_id]}/log.txt")
|
|
|
|
if params[:cors_hax]
|
|
status 204
|
|
headers['Access-Control-Expose-Headers'] = 'Location'
|
|
headers['Location'] = archived_log_path
|
|
else
|
|
redirect archived_log_path, 307
|
|
end
|
|
else
|
|
status 406
|
|
end
|
|
else
|
|
respond_with resource
|
|
end
|
|
end
|
|
|
|
patch '/:id/log', scope: :private do |id|
|
|
begin
|
|
self.service(:remove_log, params).run
|
|
rescue Travis::AuthorizationDenied => ade
|
|
status 401
|
|
{ error: { message: ade.message } }
|
|
rescue Travis::JobUnfinished, Travis::LogAlreadyRemoved => e
|
|
status 409
|
|
{ error: { message: e.message } }
|
|
rescue => e
|
|
status 500
|
|
{ error: { message: "Unexpected error occurred: #{e.message}" } }
|
|
end
|
|
end
|
|
|
|
get "/:job_id/annotations" do
|
|
respond_with service(:find_annotations, params)
|
|
end
|
|
|
|
post "/:job_id/annotations" do
|
|
if params[:status] && params[:description]
|
|
annotation = service(:update_annotation, params).run
|
|
|
|
status annotation ? 204 : 401
|
|
else
|
|
status 422
|
|
|
|
{ "error" => "Must include status and description" }
|
|
end
|
|
end
|
|
|
|
def archive_url(path)
|
|
"https://s3.amazonaws.com/#{hostname('archive')}#{path}"
|
|
end
|
|
|
|
def hostname(name)
|
|
"#{name}#{'-staging' if Travis.env == 'staging'}.#{Travis.config.host.split('.')[-2, 2].join('.')}"
|
|
end
|
|
end
|
|
end
|
|
end
|