progress on attaching properly

This commit is contained in:
Jesse Duffield 2019-05-19 14:10:03 +10:00
parent 2e9a80fe6c
commit 88758de164

View file

@ -5,7 +5,12 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"os"
"os/exec"
"os/signal"
"strings"
"syscall"
"time"
"github.com/docker/docker/api/types"
@ -14,6 +19,8 @@ import (
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazydocker/pkg/commands"
"github.com/jesseduffield/lazydocker/pkg/utils"
"github.com/jesseduffield/pty"
"golang.org/x/crypto/ssh/terminal"
"golang.org/x/xerrors"
)
@ -50,10 +57,10 @@ func (gui *Gui) handleContainersFocus(g *gocui.Gui, v *gocui.View) error {
gui.State.Panels.Containers.SelectedLine = newSelectedLine
if prevSelectedLine == newSelectedLine && gui.currentViewName() == v.Name() {
return gui.handleContainerPress(gui.g, v)
} else {
return gui.handleContainerSelect(gui.g, v)
return nil
}
return gui.handleContainerSelect(gui.g, v)
}
func (gui *Gui) handleContainerSelect(g *gocui.Gui, v *gocui.View) error {
@ -69,6 +76,12 @@ func (gui *Gui) handleContainerSelect(g *gocui.Gui, v *gocui.View) error {
return gui.renderString(g, "main", gui.Tr.SLocalize("NoChangedContainers"))
}
// if we are in an attached state, we won't do anything here
// TODO: generalise
if strings.HasPrefix(gui.State.Panels.Main.ObjectKey, "attached-") {
return nil
}
key := container.ID + "-" + gui.getContainerContexts()[gui.State.Panels.Containers.ContextIndex]
if gui.State.Panels.Main.ObjectKey == key {
return nil
@ -263,10 +276,6 @@ func (gui *Gui) handleContainersPrevLine(g *gocui.Gui, v *gocui.View) error {
return gui.handleContainerSelect(gui.g, v)
}
func (gui *Gui) handleContainerPress(g *gocui.Gui, v *gocui.View) error {
return nil
}
func (gui *Gui) handleContainersPrevContext(g *gocui.Gui, v *gocui.View) error {
contexts := gui.getContainerContexts()
if gui.State.Panels.Containers.ContextIndex >= len(contexts)-1 {
@ -394,11 +403,65 @@ func (gui *Gui) handleContainerAttach(g *gocui.Gui, v *gocui.View) error {
return nil
}
subProcess := container.Attach()
if subProcess != nil {
gui.SubProcess = subProcess
return gui.Errors.ErrSubProcess
gui.State.Panels.Main.WriterID++
// Create arbitrary command.
c := exec.Command("bash")
// Start the command with a pty.
ptmx, err := pty.Start(c)
if err != nil {
return err
}
// Handle pty size.
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGWINCH)
go func() {
for range ch {
x, y := gui.getMainView().Size()
if err := pty.Setsize(ptmx, &pty.Winsize{Cols: uint16(x), Rows: uint16(y), X: 0, Y: 0}); err != nil {
gui.Log.Error(err)
}
}
}()
ch <- syscall.SIGWINCH // Initial resize.
go func() {
// Set stdin in raw mode.
oldState, err := terminal.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
panic(err)
}
defer func() { _ = terminal.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort.
defer func() { _ = ptmx.Close() }() // Best effort.
go func() { _, _ = io.Copy(ptmx, os.Stdin) }()
mainView := gui.getMainView()
mainView.Clear()
mainView.Autoscroll = true
gui.State.Panels.Main.ObjectKey = "attached-" + container.ID
scanner := bufio.NewScanner(ptmx)
scanner.Split(bufio.ScanRunes)
content := ""
for scanner.Scan() {
content += scanner.Text()
gui.Log.Warn("content")
gui.Log.Warn(content)
gui.renderString(gui.g, "main", content)
}
// reset object key
gui.State.Panels.Main.ObjectKey = ""
gui.State.Panels.Main.WriterID++
gui.handleContainerSelect(gui.g, v)
}()
return nil
}