Selaa lähdekoodia

Merge pull request #381 from docker/fix-logs-windows

Get the real width of the terminal
Guillaume Tardif 5 vuotta sitten
vanhempi
sitoutus
1fbdbbbbe3
6 muutettua tiedostoa jossa 40 lisäystä ja 18 poistoa
  1. 7 6
      azure/aci.go
  2. 1 1
      azure/backend.go
  3. 12 5
      cli/cmd/logs.go
  4. 12 4
      cli/cmd/run/run.go
  5. 1 0
      containers/api.go
  6. 7 2
      tests/aci-e2e/e2e-aci_test.go

+ 7 - 6
azure/aci.go

@@ -27,7 +27,6 @@ import (
 	"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
 	"github.com/Azure/go-autorest/autorest"
 	"github.com/Azure/go-autorest/autorest/to"
-	"github.com/buger/goterm"
 	tm "github.com/buger/goterm"
 	"github.com/gobwas/ws"
 	"github.com/gobwas/ws/wsutil"
@@ -245,8 +244,7 @@ func getACIContainerLogs(ctx context.Context, aciContext store.AciContext, conta
 	return *logs.Content, err
 }
 
-func streamLogs(ctx context.Context, aciContext store.AciContext, containerGroupName, containerName string, out io.Writer) error {
-	terminalWidth := goterm.Width()
+func streamLogs(ctx context.Context, aciContext store.AciContext, containerGroupName, containerName string, req containers.LogsRequest) error {
 	numLines := 0
 	for {
 		select {
@@ -266,12 +264,12 @@ func streamLogs(ctx context.Context, aciContext store.AciContext, containerGroup
 			// a real logs streaming api soon.
 			b := aec.EmptyBuilder
 			b = b.Up(uint(numLines))
-			fmt.Fprint(out, b.Column(0).ANSI)
+			fmt.Fprint(req.Writer, b.Column(0).ANSI)
 
-			numLines = getBacktrackLines(logLines, terminalWidth)
+			numLines = getBacktrackLines(logLines, req.Width)
 
 			for i := 0; i < currentOutput-1; i++ {
-				fmt.Fprintln(out, logLines[i])
+				fmt.Fprintln(req.Writer, logLines[i])
 			}
 
 			select {
@@ -284,6 +282,9 @@ func streamLogs(ctx context.Context, aciContext store.AciContext, containerGroup
 }
 
 func getBacktrackLines(lines []string, terminalWidth int) int {
+	if terminalWidth == 0 { // no terminal width has been set, do not divide by zero
+		return len(lines)
+	}
 	numLines := 0
 	for i := 0; i < len(lines)-1; i++ {
 		numLines++

+ 1 - 1
azure/backend.go

@@ -239,7 +239,7 @@ func (cs *aciContainerService) Logs(ctx context.Context, containerName string, r
 	var tail *int32
 
 	if req.Follow {
-		return streamLogs(ctx, cs.ctx, groupName, containerAciName, req.Writer)
+		return streamLogs(ctx, cs.ctx, groupName, containerAciName, req)
 	}
 
 	if req.Tail != "all" {

+ 12 - 5
cli/cmd/logs.go

@@ -57,16 +57,23 @@ func runLogs(ctx context.Context, containerName string, opts logsOpts) error {
 	if err != nil {
 		return errors.Wrap(err, "cannot connect to backend")
 	}
-	var con io.Writer = os.Stdout
-	if c, err := console.ConsoleFromFile(os.Stdout); err == nil {
-		con = c
-	}
 
 	req := containers.LogsRequest{
 		Follow: opts.Follow,
 		Tail:   opts.Tail,
-		Writer: con,
 	}
 
+	var con io.Writer = os.Stdout
+	if c, err := console.ConsoleFromFile(os.Stdout); err == nil {
+		size, err := c.Size()
+		if err != nil {
+			return err
+		}
+		req.Width = int(size.Width)
+		con = c
+	}
+
+	req.Writer = con
+
 	return c.ContainerService().Logs(ctx, containerName, req)
 }

+ 12 - 4
cli/cmd/run/run.go

@@ -73,19 +73,27 @@ func runRun(ctx context.Context, image string, opts run.Opts) error {
 	if err != nil {
 		return err
 	}
+
 	if !opts.Detach {
 		var con io.Writer = os.Stdout
+		req := containers.LogsRequest{
+			Follow: true,
+		}
 		if c, err := console.ConsoleFromFile(os.Stdout); err == nil {
+			size, err := c.Size()
+			if err != nil {
+				return err
+			}
+			req.Width = int(size.Width)
 			con = c
 		}
 
-		req := containers.LogsRequest{
-			Follow: true,
-			Writer: con,
-		}
+		req.Writer = con
 
 		return c.ContainerService().Logs(ctx, opts.Name, req)
 	}
+
 	fmt.Println(opts.Name)
+
 	return nil
 }

+ 1 - 0
containers/api.go

@@ -86,6 +86,7 @@ type ExecRequest struct {
 type LogsRequest struct {
 	Follow bool
 	Tail   string
+	Width  int
 	Writer io.Writer
 }
 

+ 7 - 2
tests/aci-e2e/e2e-aci_test.go

@@ -142,13 +142,18 @@ func (s *E2eACISuite) TestACIRunSingleContainer() {
 		outChan := make(chan string)
 
 		go func() {
-			output, _ := ctx.Exec()
+			output, err := ctx.Exec()
+			// check the process is cancelled by the test, not another unexpected error
+			Expect(err.Error()).To(ContainSubstring("timed out"))
 			outChan <- output
 		}()
+		// Ensure logs -- follow is strated before we curl nginx
+		time.Sleep(5 * time.Second)
 
 		s.NewCommand("curl", nginxExposedURL+"/test").ExecOrDie()
 		// Give the `logs --follow` a little time to get logs of the curl call
-		time.Sleep(10 * time.Second)
+		time.Sleep(5 * time.Second)
+
 		// Trigger a timeout to make ctx.Exec exit
 		timeChan <- time.Now()