From dd29283a880dd5b02c462777e18b2bc29ab7ce97 Mon Sep 17 00:00:00 2001
From: Tomasz Maczukin <tomasz@maczukin.pl>
Date: Sat, 9 Apr 2016 01:21:18 +0200
Subject: [PATCH] Make sure that appending is done on a valid length

---
 app/models/ci/build.rb              |  9 +++++----
 lib/ci/api/builds.rb                | 12 +++++++++++-
 spec/requests/ci/api/builds_spec.rb |  2 +-
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 9eee4b423cc..9ac6e7e1bfb 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -231,10 +231,10 @@ module Ci
     end
 
     def trace_length
-      unless trace.present?
-        0
+      if raw_trace
+        raw_trace.length
       else
-        trace.length
+        0
       end
     end
 
@@ -250,9 +250,10 @@ module Ci
     end
     private :recreate_trace_dir
 
-    def append_trace(trace_part)
+    def append_trace(trace_part, offset)
       recreate_trace_dir
 
+      File.truncate(path_to_trace, offset)
       File.open(path_to_trace, 'a') do |f|
         f.write(trace_part)
       end
diff --git a/lib/ci/api/builds.rb b/lib/ci/api/builds.rb
index decee3739c8..776129d90e0 100644
--- a/lib/ci/api/builds.rb
+++ b/lib/ci/api/builds.rb
@@ -50,6 +50,16 @@ module Ci
           end
         end
 
+        # Send incremental log update - Runners only
+        #
+        # Parameters:
+        #   id (required) - The ID of a build
+        # Body:
+        #   content of logs to append
+        # Headers:
+        #   Content-Range: range of conntent that was sent
+        # Example Request:
+        #   PATCH /builds/:id/trace.txt
         patch ":id/trace.txt" do
           build = Ci::Build.find_by_id(params[:id])
           not_found! unless build
@@ -64,7 +74,7 @@ module Ci
             return error!('416 Range Not Satisfiable', 416, { 'Range' => "0-#{build.trace_length}" })
           end
 
-          build.append_trace(request.body.read)
+          build.append_trace(request.body.read, content_range[0].to_i)
 
           status 202
           header 'Build-Status', build.status
diff --git a/spec/requests/ci/api/builds_spec.rb b/spec/requests/ci/api/builds_spec.rb
index eb8c476c882..ebd16c7efbe 100644
--- a/spec/requests/ci/api/builds_spec.rb
+++ b/spec/requests/ci/api/builds_spec.rb
@@ -195,7 +195,7 @@ describe Ci::API::API do
         it { expect(response.status).to eq 400 }
       end
 
-      context 'when build has been erased' do
+      context 'when build has been errased' do
         let(:build) { create(:ci_build, runner_id: runner.id, erased_at: Time.now) }
 
         it { expect(response.status).to eq 403 }
-- 
GitLab