mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-22 07:11:01 +00:00
initial take on attaching to container via SDK
This commit is contained in:
parent
cca69e64f3
commit
7a78175eff
5 changed files with 78 additions and 11 deletions
1
go.mod
1
go.mod
|
|
@ -33,6 +33,7 @@ require (
|
|||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad
|
||||
github.com/stretchr/testify v1.2.2
|
||||
github.com/tcnksm/go-gitconfig v0.1.2
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522
|
||||
gopkg.in/yaml.v2 v2.2.2 // indirect
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,9 +2,14 @@ package commands
|
|||
|
||||
import (
|
||||
"context"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
|
|
@ -341,18 +346,80 @@ func (c *Container) Restart() error {
|
|||
}
|
||||
|
||||
// Attach attaches the container
|
||||
func (c *Container) Attach() (*exec.Cmd, error) {
|
||||
func (c *Container) Attach() error {
|
||||
// verify that we can in fact attach to this container
|
||||
if !c.Details.Config.OpenStdin {
|
||||
return nil, errors.New(c.Tr.UnattachableContainerError)
|
||||
return errors.New(c.Tr.UnattachableContainerError)
|
||||
}
|
||||
|
||||
if c.Container.State == "exited" {
|
||||
return nil, errors.New(c.Tr.CannotAttachStoppedContainerError)
|
||||
return errors.New(c.Tr.CannotAttachStoppedContainerError)
|
||||
}
|
||||
|
||||
cmd := c.OSCommand.PrepareSubProcess("docker", "attach", "--sig-proxy=false", c.ID)
|
||||
return cmd, nil
|
||||
options := types.ContainerAttachOptions{
|
||||
Stream: true,
|
||||
Stdin: c.Details.Config.OpenStdin,
|
||||
Stdout: true,
|
||||
Stderr: true,
|
||||
}
|
||||
|
||||
hijack, err := c.Client.ContainerAttach(context.Background(), c.ID, options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.Details.Config.OpenStdin {
|
||||
fd := int(os.Stdin.Fd())
|
||||
|
||||
if terminal.IsTerminal(fd) {
|
||||
oldState, err := terminal.MakeRaw(fd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer terminal.Restore(fd, oldState)
|
||||
|
||||
go c.resizeIfChanged(fd)
|
||||
go io.Copy(hijack.Conn, os.Stdin)
|
||||
}
|
||||
}
|
||||
|
||||
_, err = io.Copy(os.Stdout, hijack.Conn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hijack.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) resizeIfChanged(fd int) {
|
||||
channel := make(chan os.Signal)
|
||||
signal.Notify(channel, syscall.SIGWINCH)
|
||||
|
||||
for {
|
||||
<-channel
|
||||
c.Resize(fd)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Container) Resize(fd int) error {
|
||||
width, height, err := terminal.GetSize(fd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
options := types.ResizeOptions{
|
||||
Height: uint(height),
|
||||
Width: uint(width),
|
||||
}
|
||||
|
||||
err = c.Client.ContainerResize(context.Background(), c.ID, options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Top returns process information
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ func (s *Service) Restart() error {
|
|||
}
|
||||
|
||||
// Attach attaches to the service
|
||||
func (s *Service) Attach() (*exec.Cmd, error) {
|
||||
func (s *Service) Attach() error {
|
||||
return s.Container.Attach()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -467,12 +467,13 @@ func (gui *Gui) handleContainerAttach(g *gocui.Gui, v *gocui.View) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
c, err := container.Attach()
|
||||
err = container.Attach()
|
||||
if err != nil {
|
||||
return gui.createErrorPanel(gui.g, err.Error())
|
||||
}
|
||||
|
||||
gui.SubProcess = c
|
||||
gui.RunWithSubprocesses()
|
||||
|
||||
return gui.Errors.ErrSubProcess
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -256,13 +256,11 @@ func (gui *Gui) handleServiceAttach(g *gocui.Gui, v *gocui.View) error {
|
|||
return gui.createErrorPanel(gui.g, gui.Tr.NoContainers)
|
||||
}
|
||||
|
||||
c, err := service.Attach()
|
||||
|
||||
err = service.Attach()
|
||||
if err != nil {
|
||||
return gui.createErrorPanel(gui.g, err.Error())
|
||||
}
|
||||
|
||||
gui.SubProcess = c
|
||||
return gui.Errors.ErrSubProcess
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue