runner.rb 4.1 KB
Newer Older
1
module API
2 3
  class Runner < Grape::API
    helpers ::API::Helpers::Runner
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

    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 :locked, type: Boolean, desc: 'Should Runner be locked for current project'
        optional :run_untagged, type: Boolean, desc: 'Should Runner handle untagged jobs'
        optional :tag_list, type: Array[String], desc: %q(List of Runner's tags)
      end
      post '/' do
        attributes = attributes_for_keys [:description, :locked, :run_untagged, :tag_list]

        runner =
          if runner_registration_token_valid?
            # Create shared runner. Requires admin access
24
            Ci::Runner.create(attributes.merge(is_shared: true))
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
          elsif project = Project.find_by(runners_token: params[:token])
            # Create a specific runner for project.
            project.runners.create(attributes)
          end

        return forbidden! unless runner

        if runner.id
          runner.update(get_runner_version_from_params)
          present runner, with: Entities::RunnerRegistrationDetails
        else
          not_found!
        end
      end

      desc 'Deletes a registered Runner' do
41
        http_codes [[204, 'Runner was deleted'], [403, 'Forbidden']]
42 43 44 45 46 47
      end
      params do
        requires :token, type: String, desc: %q(Runner's authentication token)
      end
      delete '/' do
        authenticate_runner!
48
        Ci::Runner.find_by_token(params[:token]).destroy
49 50
      end
    end
Tomasz Maczukin's avatar
Tomasz Maczukin committed
51 52 53

    resource :jobs do
      desc 'Request a job' do
54
        success Entities::JobRequest::Response
Tomasz Maczukin's avatar
Tomasz Maczukin committed
55 56 57
      end
      params do
        requires :token, type: String, desc: %q(Runner's authentication token)
58 59
        optional :last_update, type: String, desc: %q(Runner's queue last_update token)
        optional :info, type: Hash, desc: %q(Runner's metadata)
Tomasz Maczukin's avatar
Tomasz Maczukin committed
60 61 62 63 64 65 66 67 68
      end
      post '/request' do
        authenticate_runner!
        not_found! 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)
Tomasz Maczukin's avatar
Tomasz Maczukin committed
69
          return job_not_found!
Tomasz Maczukin's avatar
Tomasz Maczukin committed
70 71 72
        end

        new_update = current_runner.ensure_runner_queue_value
73
        result = ::Ci::RegisterJobService.new(current_runner).execute
Tomasz Maczukin's avatar
Tomasz Maczukin committed
74 75 76 77 78

        if result.valid?
          if result.build
            Gitlab::Metrics.add_event(:build_found,
                                      project: result.build.project.path_with_namespace)
79
            present result.build, with: Entities::JobRequest::Response
Tomasz Maczukin's avatar
Tomasz Maczukin committed
80 81 82
          else
            Gitlab::Metrics.add_event(:build_not_found)
            header 'X-GitLab-Last-Update', new_update
Tomasz Maczukin's avatar
Tomasz Maczukin committed
83
            job_not_found!
Tomasz Maczukin's avatar
Tomasz Maczukin committed
84 85 86 87 88 89 90
          end
        else
          # We received build that is invalid due to concurrency conflict
          Gitlab::Metrics.add_event(:build_invalid)
          conflict!
        end
      end
Tomasz Maczukin's avatar
Tomasz Maczukin committed
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116

      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
Tomasz Maczukin's avatar
Tomasz Maczukin committed
117
    end
118 119
  end
end