mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-25 08:31:03 +00:00
support docker daemon going down randomly
This commit is contained in:
parent
4c916477ba
commit
5ab4ef6f8c
8 changed files with 46 additions and 16 deletions
6
main.go
6
main.go
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/go-errors/errors"
|
"github.com/go-errors/errors"
|
||||||
"github.com/jesseduffield/lazydocker/pkg/app"
|
"github.com/jesseduffield/lazydocker/pkg/app"
|
||||||
"github.com/jesseduffield/lazydocker/pkg/config"
|
"github.com/jesseduffield/lazydocker/pkg/config"
|
||||||
|
|
@ -50,6 +51,11 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if client.IsErrConnectionFailed(err) {
|
||||||
|
log.Println(app.Tr.ConnectionFailed)
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
newErr := errors.Wrap(err, 0)
|
newErr := errors.Wrap(err, 0)
|
||||||
stackTrace := newErr.ErrorStack()
|
stackTrace := newErr.ErrorStack()
|
||||||
app.Log.Error(stackTrace)
|
app.Log.Error(stackTrace)
|
||||||
|
|
|
||||||
|
|
@ -283,7 +283,7 @@ func (c *Container) GetDisplayCPUPerc() string {
|
||||||
|
|
||||||
percentage, err := strconv.ParseFloat(strings.TrimSuffix(stats.CPUPerc, "%"), 32)
|
percentage, err := strconv.ParseFloat(strings.TrimSuffix(stats.CPUPerc, "%"), 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Log.Error(err)
|
// probably complaining about not being able to convert '--'
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ func GetDefaultConfig() UserConfig {
|
||||||
StopService: "{{ .DockerCompose }} stop {{ .Service.Name }}",
|
StopService: "{{ .DockerCompose }} stop {{ .Service.Name }}",
|
||||||
ServiceLogs: "{{ .DockerCompose }} logs --since=60m --follow {{ .Service.Name }}",
|
ServiceLogs: "{{ .DockerCompose }} logs --since=60m --follow {{ .Service.Name }}",
|
||||||
ViewServiceLogs: "{{ .DockerCompose }} logs --follow {{ .Service.Name }}",
|
ViewServiceLogs: "{{ .DockerCompose }} logs --follow {{ .Service.Name }}",
|
||||||
AllLogs: "{{ .DockerCompose }} logs --since=60m --follow",
|
AllLogs: "{{ .DockerCompose }} logs --tail=300 --follow",
|
||||||
ViewAllLogs: "{{ .DockerCompose }} logs",
|
ViewAllLogs: "{{ .DockerCompose }} logs",
|
||||||
DockerComposeConfig: "{{ .DockerCompose }} config",
|
DockerComposeConfig: "{{ .DockerCompose }} config",
|
||||||
CheckDockerComposeConfig: "{{ .DockerCompose }} config --quiet",
|
CheckDockerComposeConfig: "{{ .DockerCompose }} config --quiet",
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,11 @@ func (gui *Gui) renderLogs(container *commands.Container, template string, setup
|
||||||
return gui.T.NewTickerTask(time.Millisecond*200, nil, func(stop, notifyStopped chan struct{}) {
|
return gui.T.NewTickerTask(time.Millisecond*200, nil, func(stop, notifyStopped chan struct{}) {
|
||||||
gui.clearMainView()
|
gui.clearMainView()
|
||||||
|
|
||||||
cmd := container.TTYLogsCommand()
|
command := utils.ApplyTemplate(
|
||||||
|
template,
|
||||||
|
gui.DockerCommand.NewCommandObject(commands.CommandObject{Container: container}),
|
||||||
|
)
|
||||||
|
cmd := gui.OSCommand.RunCustomCommand(command)
|
||||||
|
|
||||||
setup(cmd)
|
setup(cmd)
|
||||||
|
|
||||||
|
|
@ -211,6 +215,7 @@ func (gui *Gui) renderLogs(container *commands.Container, template string, setup
|
||||||
go func() {
|
go func() {
|
||||||
<-stop
|
<-stop
|
||||||
cmd.Process.Kill()
|
cmd.Process.Kill()
|
||||||
|
gui.Log.Info("killed container logs process")
|
||||||
return
|
return
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -137,15 +137,11 @@ func (gui *Gui) renderServiceLogs(service *commands.Service) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if service.Container == nil {
|
if service.Container == nil {
|
||||||
gui.Log.Warn("container is nil")
|
|
||||||
return gui.T.NewTask(func(stop chan struct{}) {
|
return gui.T.NewTask(func(stop chan struct{}) {
|
||||||
gui.Log.Warn("about to clear main view")
|
|
||||||
gui.clearMainView()
|
gui.clearMainView()
|
||||||
gui.Log.Warn("cleared main view")
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.Log.Warn("about to render container logs for service ", service.Name)
|
|
||||||
return gui.renderContainerLogs(service.Container)
|
return gui.renderContainerLogs(service.Container)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ type TranslationSet struct {
|
||||||
AnonymousReportingPrompt string
|
AnonymousReportingPrompt string
|
||||||
ConfirmQuit string
|
ConfirmQuit string
|
||||||
ErrorOccurred string
|
ErrorOccurred string
|
||||||
|
ConnectionFailed string
|
||||||
Donate string
|
Donate string
|
||||||
Cancel string
|
Cancel string
|
||||||
CustomCommandTitle string
|
CustomCommandTitle string
|
||||||
|
|
@ -84,9 +85,10 @@ func englishSet() TranslationSet {
|
||||||
RunningSubprocess: "running subprocess",
|
RunningSubprocess: "running subprocess",
|
||||||
NoViewMachingNewLineFocusedSwitchStatement: "No view matching newLineFocused switch statement",
|
NoViewMachingNewLineFocusedSwitchStatement: "No view matching newLineFocused switch statement",
|
||||||
|
|
||||||
ErrorOccurred: "An error occurred! Please create an issue at https://github.com/jesseduffield/lazydocker/issues",
|
ErrorOccurred: "An error occurred! Please create an issue at https://github.com/jesseduffield/lazydocker/issues",
|
||||||
Donate: "Donate",
|
ConnectionFailed: "connection to docker client failed. You may need to restart the docker client",
|
||||||
Confirm: "Confirm",
|
Donate: "Donate",
|
||||||
|
Confirm: "Confirm",
|
||||||
|
|
||||||
Navigate: "navigate",
|
Navigate: "navigate",
|
||||||
Execute: "execute",
|
Execute: "execute",
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,9 @@ func (t *TaskManager) NewTask(f func(stop chan struct{})) error {
|
||||||
notifyStopped := make(chan struct{})
|
notifyStopped := make(chan struct{})
|
||||||
|
|
||||||
if t.currentTask != nil {
|
if t.currentTask != nil {
|
||||||
|
t.Log.Info("asking task to stop")
|
||||||
t.currentTask.Stop()
|
t.currentTask.Stop()
|
||||||
|
t.Log.Info("task stopped")
|
||||||
}
|
}
|
||||||
|
|
||||||
t.currentTask = &Task{
|
t.currentTask = &Task{
|
||||||
|
|
@ -57,6 +59,7 @@ func (t *TaskManager) NewTask(f func(stop chan struct{})) error {
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
f(stop)
|
f(stop)
|
||||||
|
t.Log.Info("returned from function, closing notifyStopped")
|
||||||
close(notifyStopped)
|
close(notifyStopped)
|
||||||
}()
|
}()
|
||||||
}()
|
}()
|
||||||
|
|
@ -66,14 +69,17 @@ func (t *TaskManager) NewTask(f func(stop chan struct{})) error {
|
||||||
|
|
||||||
func (t *Task) Stop() {
|
func (t *Task) Stop() {
|
||||||
close(t.stop)
|
close(t.stop)
|
||||||
|
t.Log.Info("closed stop channel, waiting for notifyStopped message")
|
||||||
<-t.notifyStopped
|
<-t.notifyStopped
|
||||||
|
t.Log.Info("received notifystopped message")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTickerTask is a convenience function for making a new task that repeats some action once per e.g. second
|
// NewTickerTask is a convenience function for making a new task that repeats some action once per e.g. second
|
||||||
// the before function gets called after the lock is obtained, but before the ticker starts.
|
// the before function gets called after the lock is obtained, but before the ticker starts.
|
||||||
|
// if you handle a message on the stop channel in f() you need to send a message on the notifyStopped channel because returning is not sufficient. Here, unlike in a regular task, simply returning means we're now going to wait till the next tick to run again.
|
||||||
func (t *TaskManager) NewTickerTask(duration time.Duration, before func(stop chan struct{}), f func(stop, notifyStopped chan struct{})) error {
|
func (t *TaskManager) NewTickerTask(duration time.Duration, before func(stop chan struct{}), f func(stop, notifyStopped chan struct{})) error {
|
||||||
notifyStopped := make(chan struct{})
|
notifyStopped := make(chan struct{}, 10)
|
||||||
|
|
||||||
return t.NewTask(func(stop chan struct{}) {
|
return t.NewTask(func(stop chan struct{}) {
|
||||||
if before != nil {
|
if before != nil {
|
||||||
|
|
@ -81,14 +87,17 @@ func (t *TaskManager) NewTickerTask(duration time.Duration, before func(stop cha
|
||||||
}
|
}
|
||||||
tickChan := time.NewTicker(duration)
|
tickChan := time.NewTicker(duration)
|
||||||
// calling f first so that we're not waiting for the first tick
|
// calling f first so that we're not waiting for the first tick
|
||||||
f(stop, notifyStopped)
|
// f(stop, notifyStopped)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-notifyStopped:
|
case <-notifyStopped:
|
||||||
|
t.Log.Info("exiting ticker task due to notifyStopped channel")
|
||||||
return
|
return
|
||||||
case <-stop:
|
case <-stop:
|
||||||
|
t.Log.Info("exiting ticker task due to stopped cahnnel")
|
||||||
return
|
return
|
||||||
case <-tickChan.C:
|
case <-tickChan.C:
|
||||||
|
t.Log.Info("running ticker task again")
|
||||||
f(stop, notifyStopped)
|
f(stop, notifyStopped)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,21 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "fmt"
|
import "log"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var arr []string
|
c := make(chan struct{})
|
||||||
arr = nil
|
|
||||||
fmt.Println(len(arr))
|
close(c)
|
||||||
|
|
||||||
|
close(c)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-c:
|
||||||
|
log.Println("hmm")
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-c:
|
||||||
|
log.Println("okay")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue