mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-25 08:31:03 +00:00
Merge pull request #534 from jesseduffield/fix-buggy-log-rendering
Fix buggy log rendering
This commit is contained in:
commit
0f1b8c9848
5 changed files with 55 additions and 19 deletions
|
|
@ -140,7 +140,9 @@ func (c *Container) RenderTop(ctx context.Context) (string, error) {
|
||||||
return utils.RenderTable(append([][]string{result.Titles}, result.Processes...))
|
return utils.RenderTable(append([][]string{result.Titles}, result.Processes...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DetailsLoaded tells us whether we have yet loaded the details for a container. Because this is an asynchronous operation, sometimes we have the container before we have its details.
|
// DetailsLoaded tells us whether we have yet loaded the details for a container.
|
||||||
|
// Sometimes it takes some time for a container to have its details loaded
|
||||||
|
// after it starts.
|
||||||
func (c *Container) DetailsLoaded() bool {
|
func (c *Container) DetailsLoaded() bool {
|
||||||
return c.Details.ContainerJSONBase != nil
|
return c.Details.ContainerJSONBase != nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
cliconfig "github.com/docker/cli/cli/config"
|
cliconfig "github.com/docker/cli/cli/config"
|
||||||
|
|
@ -209,7 +210,7 @@ func (c *DockerCommand) GetContainers(existingContainers []*Container) ([]*Conta
|
||||||
for i, container := range containers {
|
for i, container := range containers {
|
||||||
var newContainer *Container
|
var newContainer *Container
|
||||||
|
|
||||||
// check if we already data stored against the container
|
// check if we already have data stored against the container
|
||||||
for _, existingContainer := range existingContainers {
|
for _, existingContainer := range existingContainers {
|
||||||
if existingContainer.ID == container.ID {
|
if existingContainer.ID == container.ID {
|
||||||
newContainer = existingContainer
|
newContainer = existingContainer
|
||||||
|
|
@ -244,6 +245,8 @@ func (c *DockerCommand) GetContainers(existingContainers []*Container) ([]*Conta
|
||||||
ownContainers[i] = newContainer
|
ownContainers[i] = newContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.SetContainerDetails(ownContainers)
|
||||||
|
|
||||||
return ownContainers, nil
|
return ownContainers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -278,24 +281,35 @@ func (c *DockerCommand) GetServices() ([]*Service, error) {
|
||||||
return services, nil
|
return services, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateContainerDetails attaches the details returned from docker inspect to each of the containers
|
func (c *DockerCommand) RefreshContainerDetails(containers []*Container) error {
|
||||||
// this contains a bit more info than what you get from the go-docker client
|
|
||||||
func (c *DockerCommand) UpdateContainerDetails(containers []*Container) error {
|
|
||||||
c.ContainerMutex.Lock()
|
c.ContainerMutex.Lock()
|
||||||
defer c.ContainerMutex.Unlock()
|
defer c.ContainerMutex.Unlock()
|
||||||
|
|
||||||
for _, container := range containers {
|
c.SetContainerDetails(containers)
|
||||||
details, err := c.Client.ContainerInspect(context.Background(), container.ID)
|
|
||||||
if err != nil {
|
|
||||||
c.Log.Error(err)
|
|
||||||
} else {
|
|
||||||
container.Details = details
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attaches the details returned from docker inspect to each of the containers
|
||||||
|
// this contains a bit more info than what you get from the go-docker client
|
||||||
|
func (c *DockerCommand) SetContainerDetails(containers []*Container) {
|
||||||
|
wg := sync.WaitGroup{}
|
||||||
|
for _, container := range containers {
|
||||||
|
container := container
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
details, err := c.Client.ContainerInspect(context.Background(), container.ID)
|
||||||
|
if err != nil {
|
||||||
|
c.Log.Error(err)
|
||||||
|
} else {
|
||||||
|
container.Details = details
|
||||||
|
}
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
// ViewAllLogs attaches to a subprocess viewing all the logs from docker-compose
|
// ViewAllLogs attaches to a subprocess viewing all the logs from docker-compose
|
||||||
func (c *DockerCommand) ViewAllLogs() (*exec.Cmd, error) {
|
func (c *DockerCommand) ViewAllLogs() (*exec.Cmd, error) {
|
||||||
cmd := c.OSCommand.ExecutableFromString(
|
cmd := c.OSCommand.ExecutableFromString(
|
||||||
|
|
|
||||||
|
|
@ -114,10 +114,29 @@ func (gui *Gui) writeContainerLogs(container *commands.Container, ctx context.Co
|
||||||
Follow: true,
|
Follow: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
gui.Log.Error(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer readCloser.Close()
|
||||||
|
|
||||||
if container.DetailsLoaded() && container.Details.Config.Tty {
|
if !container.DetailsLoaded() {
|
||||||
|
// loop until the details load or context is cancelled, using timer
|
||||||
|
ticker := time.NewTicker(time.Millisecond * 100)
|
||||||
|
defer ticker.Stop()
|
||||||
|
outer:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil
|
||||||
|
case <-ticker.C:
|
||||||
|
if container.DetailsLoaded() {
|
||||||
|
break outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if container.Details.Config.Tty {
|
||||||
_, err = io.Copy(writer, readCloser)
|
_, err = io.Copy(writer, readCloser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -176,11 +176,9 @@ func (gui *Gui) goEvery(interval time.Duration, function func() error) {
|
||||||
ticker := time.NewTicker(interval)
|
ticker := time.NewTicker(interval)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
if gui.PauseBackgroundThreads {
|
if !gui.PauseBackgroundThreads {
|
||||||
return
|
_ = function()
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = function()
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
@ -294,7 +292,7 @@ func (gui *Gui) setPanels() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) updateContainerDetails() error {
|
func (gui *Gui) updateContainerDetails() error {
|
||||||
return gui.DockerCommand.UpdateContainerDetails(gui.Panels.Containers.List.GetAllItems())
|
return gui.DockerCommand.RefreshContainerDetails(gui.Panels.Containers.List.GetAllItems())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) refresh() {
|
func (gui *Gui) refresh() {
|
||||||
|
|
|
||||||
|
|
@ -65,9 +65,12 @@ func (t *TaskManager) NewTask(f func(ctx context.Context)) error {
|
||||||
|
|
||||||
t.waitingMutex.Lock()
|
t.waitingMutex.Lock()
|
||||||
defer t.waitingMutex.Unlock()
|
defer t.waitingMutex.Unlock()
|
||||||
|
t.taskIDMutex.Lock()
|
||||||
if taskID < t.newTaskId {
|
if taskID < t.newTaskId {
|
||||||
|
t.taskIDMutex.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
t.taskIDMutex.Unlock()
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
notifyStopped := make(chan struct{})
|
notifyStopped := make(chan struct{})
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue