BigW Consortium Gitlab

builds.rb 7.41 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
module Ci
  module API
    # Builds API
    class Builds < Grape::API
      resource :builds do
        # Runs oldest pending build by runner - Runners only
        #
        # Parameters:
        #   token (required) - The uniq token of runner
        #
        # Example Request:
        #   POST /builds/register
        post "register" do
          authenticate_runner!
          required_attributes! [:token]
          not_found! unless current_runner.active?
17
          update_runner_info
18 19 20 21

          build = Ci::RegisterBuildService.new.execute(current_runner)

          if build
22 23 24
            Gitlab::Metrics.add_event(:build_found,
                                      project: build.project.path_with_namespace)

25
            present build, with: Entities::BuildDetails
26
          else
27 28
            Gitlab::Metrics.add_event(:build_not_found)

29
            build_not_found!
30 31 32 33 34 35 36 37 38 39 40 41 42 43
          end
        end

        # Update an existing build - Runners only
        #
        # Parameters:
        #   id (required) - The ID of a project
        #   state (optional) - The state of a build
        #   trace (optional) - The trace of a build
        # Example Request:
        #   PUT /builds/:id
        put ":id" do
          authenticate_runner!
          build = Ci::Build.where(runner_id: current_runner.id).running.find(params[:id])
44 45
          forbidden!('Build has been erased!') if build.erased?

46 47
          update_runner_info

48 49
          build.update_attributes(trace: params[:trace]) if params[:trace]

50 51 52
          Gitlab::Metrics.add_event(:update_build,
                                    project: build.project.path_with_namespace)

53 54 55 56 57 58 59
          case params[:state].to_s
          when 'success'
            build.success
          when 'failed'
            build.drop
          end
        end
60

61 62 63 64 65 66 67
        # Send incremental log update - Runners only
        #
        # Parameters:
        #   id (required) - The ID of a build
        # Body:
        #   content of logs to append
        # Headers:
68
        #   Content-Range (required) - range of content that was sent
69
        #   BUILD-TOKEN (required) - The build authorization token
70 71
        # Example Request:
        #   PATCH /builds/:id/trace.txt
72
        patch ":id/trace.txt" do
Tomasz Maczukin committed
73 74 75
          build = Ci::Build.find_by_id(params[:id])
          not_found! unless build
          authenticate_build_token!(build)
76 77
          forbidden!('Build has been erased!') if build.erased?

Tomasz Maczukin committed
78 79 80 81
          error!('400 Missing header Content-Range', 400) unless request.headers.has_key?('Content-Range')
          content_range = request.headers['Content-Range']
          content_range = content_range.split('-')

82 83 84
          current_length = build.trace_length
          unless current_length == content_range[0].to_i
            return error!('416 Range Not Satisfiable', 416, { 'Range' => "0-#{current_length}" })
Tomasz Maczukin committed
85 86
          end

87
          build.append_trace(request.body.read, content_range[0].to_i)
Tomasz Maczukin committed
88 89 90 91

          status 202
          header 'Build-Status', build.status
          header 'Range', "0-#{build.trace_length}"
92 93
        end

94 95 96 97 98
        # Authorize artifacts uploading for build - Runners only
        #
        # Parameters:
        #   id (required) - The ID of a build
        #   token (required) - The build authorization token
99
        #   filesize (optional) - the size of uploaded file
100 101 102 103
        # Example Request:
        #   POST /builds/:id/artifacts/authorize
        post ":id/artifacts/authorize" do
          require_gitlab_workhorse!
104
          Gitlab::Workhorse.verify_api_request!(headers)
105
          not_allowed! unless Gitlab.config.artifacts.enabled
106 107 108 109 110 111 112 113 114 115 116
          build = Ci::Build.find_by_id(params[:id])
          not_found! unless build
          authenticate_build_token!(build)
          forbidden!('build is not running') unless build.running?

          if params[:filesize]
            file_size = params[:filesize].to_i
            file_to_large! unless file_size < max_artifacts_size
          end

          status 200
117 118
          content_type Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE
          Gitlab::Workhorse.artifact_upload_ok
119 120 121 122 123 124 125
        end

        # Upload artifacts to build - Runners only
        #
        # Parameters:
        #   id (required) - The ID of a build
        #   token (required) - The build authorization token
126
        #   file (required) - Artifacts file
127
        #   expire_in (optional) - Specify when artifacts should expire (ex. 7d)
128 129 130 131
        # Parameters (accelerated by GitLab Workhorse):
        #   file.path - path to locally stored body (generated by Workhorse)
        #   file.name - real filename as send in Content-Disposition
        #   file.type - real content type as send in Content-Type
132
        #   metadata.path - path to locally stored body (generated by Workhorse)
133
        #   metadata.name - filename (generated by Workhorse)
134 135 136 137 138 139 140 141 142
        # Headers:
        #   BUILD-TOKEN (required) - The build authorization token, the same as token
        # Body:
        #   The file content
        #
        # Example Request:
        #   POST /builds/:id/artifacts
        post ":id/artifacts" do
          require_gitlab_workhorse!
143
          not_allowed! unless Gitlab.config.artifacts.enabled
144 145 146
          build = Ci::Build.find_by_id(params[:id])
          not_found! unless build
          authenticate_build_token!(build)
147
          forbidden!('Build is not running!') unless build.running?
148
          forbidden!('Build has been erased!') if build.erased?
149

150
          artifacts_upload_path = ArtifactUploader.artifacts_upload_path
151 152 153 154
          artifacts = uploaded_file(:file, artifacts_upload_path)
          metadata = uploaded_file(:metadata, artifacts_upload_path)

          bad_request!('Missing artifacts file!') unless artifacts
155
          file_to_large! unless artifacts.size < max_artifacts_size
156

157 158
          build.artifacts_file = artifacts
          build.artifacts_metadata = metadata
159
          build.artifacts_expire_in = params['expire_in']
160

161
          if build.save
162
            present(build, with: Entities::BuildDetails)
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
          else
            render_validation_error!(build)
          end
        end

        # Download the artifacts file from build - Runners only
        #
        # Parameters:
        #   id (required) - The ID of a build
        #   token (required) - The build authorization token
        # Headers:
        #   BUILD-TOKEN (required) - The build authorization token, the same as token
        # Example Request:
        #   GET /builds/:id/artifacts
        get ":id/artifacts" do
          build = Ci::Build.find_by_id(params[:id])
          not_found! unless build
          authenticate_build_token!(build)
          artifacts_file = build.artifacts_file

          unless artifacts_file.file_storage?
            return redirect_to build.artifacts_file.url
          end

          unless artifacts_file.exists?
            not_found!
          end

          present_file!(artifacts_file.path, artifacts_file.filename)
        end

194
        # Remove the artifacts file from build - Runners only
195 196 197 198 199 200 201 202 203 204 205 206
        #
        # Parameters:
        #   id (required) - The ID of a build
        #   token (required) - The build authorization token
        # Headers:
        #   BUILD-TOKEN (required) - The build authorization token, the same as token
        # Example Request:
        #   DELETE /builds/:id/artifacts
        delete ":id/artifacts" do
          build = Ci::Build.find_by_id(params[:id])
          not_found! unless build
          authenticate_build_token!(build)
207

208
          build.erase_artifacts!
209
        end
210 211 212 213
      end
    end
  end
end