BigW Consortium Gitlab

builds.rb 6.94 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
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!
          update_runner_last_contact
16
          update_runner_info
17 18 19 20 21 22
          required_attributes! [:token]
          not_found! unless current_runner.active?

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

          if build
23
            present build, with: Entities::BuildDetails
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
          else
            not_found!
          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!
          update_runner_last_contact
          build = Ci::Build.where(runner_id: current_runner.id).running.find(params[:id])
41 42
          forbidden!('Build has been erased!') if build.erased?

43 44 45 46 47 48 49 50 51
          build.update_attributes(trace: params[:trace]) if params[:trace]

          case params[:state].to_s
          when 'success'
            build.success
          when 'failed'
            build.drop
          end
        end
52

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

Tomasz Maczukin committed
70 71 72 73
          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('-')

74 75 76
          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
77 78
          end

79
          build.append_trace(request.body.read, content_range[0].to_i)
Tomasz Maczukin committed
80 81 82 83

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

86 87 88 89 90
        # Authorize artifacts uploading for build - Runners only
        #
        # Parameters:
        #   id (required) - The ID of a build
        #   token (required) - The build authorization token
91
        #   filesize (optional) - the size of uploaded file
92 93 94 95
        # Example Request:
        #   POST /builds/:id/artifacts/authorize
        post ":id/artifacts/authorize" do
          require_gitlab_workhorse!
96
          not_allowed! unless Gitlab.config.artifacts.enabled
97 98 99 100 101 102 103 104 105 106 107
          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
Kamil Trzcinski committed
108
          { TempPath: ArtifactUploader.artifacts_upload_path }
109 110 111 112 113 114 115
        end

        # Upload artifacts to build - Runners only
        #
        # Parameters:
        #   id (required) - The ID of a build
        #   token (required) - The build authorization token
116
        #   file (required) - Artifacts file
117 118 119 120
        # 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
121
        #   metadata.path - path to locally stored body (generated by Workhorse)
122
        #   metadata.name - filename (generated by Workhorse)
123 124 125 126 127 128 129 130 131
        # 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!
132
          not_allowed! unless Gitlab.config.artifacts.enabled
133 134 135
          build = Ci::Build.find_by_id(params[:id])
          not_found! unless build
          authenticate_build_token!(build)
136
          forbidden!('Build is not running!') unless build.running?
137
          forbidden!('Build has been erased!') if build.erased?
138

139
          artifacts_upload_path = ArtifactUploader.artifacts_upload_path
140 141 142 143
          artifacts = uploaded_file(:file, artifacts_upload_path)
          metadata = uploaded_file(:metadata, artifacts_upload_path)

          bad_request!('Missing artifacts file!') unless artifacts
144
          file_to_large! unless artifacts.size < max_artifacts_size
145

146 147
          build.artifacts_file = artifacts
          build.artifacts_metadata = metadata
148

149
          if build.save
150
            present(build, with: Entities::BuildDetails)
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
          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

182
        # Remove the artifacts file from build - Runners only
183 184 185 186 187 188 189 190 191 192 193 194
        #
        # 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)
195

196
          build.remove_artifacts_file!
197
          build.remove_artifacts_metadata!
198
        end
199 200 201 202
      end
    end
  end
end