Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backend/remote: fix bufio.Scanner: token too long #20242

Merged
merged 1 commit into from
Feb 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 27 additions & 13 deletions backend/remote/backend_apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bufio"
"context"
"fmt"
"io"
"log"

tfe "github.com/hashicorp/go-tfe"
Expand Down Expand Up @@ -202,22 +203,35 @@ func (b *Remote) opApply(stopCtx, cancelCtx context.Context, op *backend.Operati
if err != nil {
return r, generalError("Failed to retrieve logs", err)
}
scanner := bufio.NewScanner(logs)
reader := bufio.NewReaderSize(logs, 64*1024)

skip := 0
for scanner.Scan() {
// Skip the first 3 lines to prevent duplicate output.
if skip < 3 {
skip++
continue
}
if b.CLI != nil {
b.CLI.Output(b.Colorize().Color(scanner.Text()))
if b.CLI != nil {
skip := 0
for next := true; next; {
var l, line []byte

for isPrefix := true; isPrefix; {
l, isPrefix, err = reader.ReadLine()
if err != nil {
if err != io.EOF {
return r, generalError("Failed to read logs", err)
}
next = false
}
line = append(line, l...)
}

// Skip the first 3 lines to prevent duplicate output.
if skip < 3 {
skip++
continue
}

if next || len(line) > 0 {
b.CLI.Output(b.Colorize().Color(string(line)))
}
}
}
if err := scanner.Err(); err != nil {
return r, generalError("Failed to read logs", err)
}

return r, nil
}
Expand Down
27 changes: 20 additions & 7 deletions backend/remote/backend_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"errors"
"fmt"
"io"
"math"
"time"

Expand Down Expand Up @@ -227,7 +228,7 @@ func (b *Remote) checkPolicy(stopCtx, cancelCtx context.Context, op *backend.Ope
if err != nil {
return generalError("Failed to retrieve policy check logs", err)
}
scanner := bufio.NewScanner(logs)
reader := bufio.NewReaderSize(logs, 64*1024)

// Retrieve the policy check to get its current status.
pc, err := b.client.PolicyChecks.Read(stopCtx, pc.ID)
Expand All @@ -249,14 +250,26 @@ func (b *Remote) checkPolicy(stopCtx, cancelCtx context.Context, op *backend.Ope
b.CLI.Output(b.Colorize().Color(msgPrefix + ":\n"))
}

for scanner.Scan() {
if b.CLI != nil {
b.CLI.Output(b.Colorize().Color(scanner.Text()))
if b.CLI != nil {
for next := true; next; {
var l, line []byte

for isPrefix := true; isPrefix; {
l, isPrefix, err = reader.ReadLine()
if err != nil {
if err != io.EOF {
return generalError("Failed to read logs", err)
}
next = false
}
line = append(line, l...)
}

if next || len(line) > 0 {
b.CLI.Output(b.Colorize().Color(string(line)))
}
}
}
if err := scanner.Err(); err != nil {
return generalError("Failed to read logs", err)
}

switch pc.Status {
case tfe.PolicyPasses:
Expand Down
27 changes: 20 additions & 7 deletions backend/remote/backend_plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"os"
Expand Down Expand Up @@ -253,16 +254,28 @@ func (b *Remote) plan(stopCtx, cancelCtx context.Context, op *backend.Operation,
if err != nil {
return r, generalError("Failed to retrieve logs", err)
}
scanner := bufio.NewScanner(logs)
reader := bufio.NewReaderSize(logs, 64*1024)

for scanner.Scan() {
if b.CLI != nil {
b.CLI.Output(b.Colorize().Color(scanner.Text()))
if b.CLI != nil {
for next := true; next; {
var l, line []byte

for isPrefix := true; isPrefix; {
l, isPrefix, err = reader.ReadLine()
if err != nil {
if err != io.EOF {
return r, generalError("Failed to read logs", err)
}
next = false
}
line = append(line, l...)
}

if next || len(line) > 0 {
b.CLI.Output(b.Colorize().Color(string(line)))
}
}
}
if err := scanner.Err(); err != nil {
return r, generalError("Failed to read logs", err)
}

// Retrieve the run to get its current status.
r, err = b.client.Runs.Read(stopCtx, r.ID)
Expand Down
30 changes: 30 additions & 0 deletions backend/remote/backend_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,36 @@ func TestRemote_planBasic(t *testing.T) {
}
}

func TestRemote_planLongLine(t *testing.T) {
b := testBackendDefault(t)

op, configCleanup := testOperationPlan(t, "./test-fixtures/plan-long-line")
defer configCleanup()

op.Workspace = backend.DefaultStateName

run, err := b.Operation(context.Background(), op)
if err != nil {
t.Fatalf("error starting operation: %v", err)
}

<-run.Done()
if run.Result != backend.OperationSuccess {
t.Fatalf("operation failed: %s", b.CLI.(*cli.MockUi).ErrorWriter.String())
}
if run.PlanEmpty {
t.Fatal("expected a non-empty plan")
}

output := b.CLI.(*cli.MockUi).OutputWriter.String()
if !strings.Contains(output, "Running plan in the remote backend") {
t.Fatalf("expected remote backend header in output: %s", output)
}
if !strings.Contains(output, "1 to add, 0 to change, 0 to destroy") {
t.Fatalf("expected plan summery in output: %s", output)
}
}

func TestRemote_planWithoutPermissions(t *testing.T) {
b := testBackendNoDefault(t)

Expand Down
5 changes: 5 additions & 0 deletions backend/remote/test-fixtures/plan-long-line/main.tf

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions backend/remote/test-fixtures/plan-long-line/plan.log

Large diffs are not rendered by default.