mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-25 08:31:03 +00:00
Merge 8d9a96eb9d into 7e7aadc207
This commit is contained in:
commit
ff87a1864d
14 changed files with 79 additions and 21 deletions
|
|
@ -20,7 +20,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>d</kbd>: entfernen
|
<kbd>d</kbd>: entfernen
|
||||||
<kbd>e</kbd>: hide/show stopped containers
|
<kbd>e</kbd>: hide/show stopped containers
|
||||||
<kbd>p</kbd>: pause
|
<kbd>p</kbd>: pause
|
||||||
<kbd>s</kbd>: anhalten
|
<kbd>s</kbd>: start/stop
|
||||||
<kbd>r</kbd>: neustarten
|
<kbd>r</kbd>: neustarten
|
||||||
<kbd>a</kbd>: anbinden
|
<kbd>a</kbd>: anbinden
|
||||||
<kbd>m</kbd>: zeige Protokolle
|
<kbd>m</kbd>: zeige Protokolle
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>d</kbd>: remove
|
<kbd>d</kbd>: remove
|
||||||
<kbd>e</kbd>: hide/show stopped containers
|
<kbd>e</kbd>: hide/show stopped containers
|
||||||
<kbd>p</kbd>: pause
|
<kbd>p</kbd>: pause
|
||||||
<kbd>s</kbd>: stop
|
<kbd>s</kbd>: start/stop
|
||||||
<kbd>r</kbd>: restart
|
<kbd>r</kbd>: restart
|
||||||
<kbd>a</kbd>: attach
|
<kbd>a</kbd>: attach
|
||||||
<kbd>m</kbd>: view logs
|
<kbd>m</kbd>: view logs
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>d</kbd>: borrar
|
<kbd>d</kbd>: borrar
|
||||||
<kbd>e</kbd>: esconder/mostrar contenedores parados
|
<kbd>e</kbd>: esconder/mostrar contenedores parados
|
||||||
<kbd>p</kbd>: pausa
|
<kbd>p</kbd>: pausa
|
||||||
<kbd>s</kbd>: parar
|
<kbd>s</kbd>: start/stop
|
||||||
<kbd>r</kbd>: reiniciar
|
<kbd>r</kbd>: reiniciar
|
||||||
<kbd>a</kbd>: attach
|
<kbd>a</kbd>: attach
|
||||||
<kbd>m</kbd>: ver logs
|
<kbd>m</kbd>: ver logs
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>d</kbd>: supprimer
|
<kbd>d</kbd>: supprimer
|
||||||
<kbd>e</kbd>: cacher/montrer les conteneurs arrêtés
|
<kbd>e</kbd>: cacher/montrer les conteneurs arrêtés
|
||||||
<kbd>p</kbd>: pause
|
<kbd>p</kbd>: pause
|
||||||
<kbd>s</kbd>: arrêter
|
<kbd>s</kbd>: start/stop
|
||||||
<kbd>r</kbd>: redémarrer
|
<kbd>r</kbd>: redémarrer
|
||||||
<kbd>a</kbd>: attacher
|
<kbd>a</kbd>: attacher
|
||||||
<kbd>m</kbd>: voir les enregistrements
|
<kbd>m</kbd>: voir les enregistrements
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>d</kbd>: verwijder
|
<kbd>d</kbd>: verwijder
|
||||||
<kbd>e</kbd>: verberg gestopte containers
|
<kbd>e</kbd>: verberg gestopte containers
|
||||||
<kbd>p</kbd>: pause
|
<kbd>p</kbd>: pause
|
||||||
<kbd>s</kbd>: stop
|
<kbd>s</kbd>: start/stop
|
||||||
<kbd>r</kbd>: herstart
|
<kbd>r</kbd>: herstart
|
||||||
<kbd>a</kbd>: verbinden
|
<kbd>a</kbd>: verbinden
|
||||||
<kbd>m</kbd>: bekijk logs
|
<kbd>m</kbd>: bekijk logs
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>d</kbd>: usuń
|
<kbd>d</kbd>: usuń
|
||||||
<kbd>e</kbd>: hide/show stopped containers
|
<kbd>e</kbd>: hide/show stopped containers
|
||||||
<kbd>p</kbd>: pause
|
<kbd>p</kbd>: pause
|
||||||
<kbd>s</kbd>: zatrzymaj
|
<kbd>s</kbd>: start/stop
|
||||||
<kbd>r</kbd>: restartuj
|
<kbd>r</kbd>: restartuj
|
||||||
<kbd>a</kbd>: przyczep
|
<kbd>a</kbd>: przyczep
|
||||||
<kbd>m</kbd>: pokaż logi
|
<kbd>m</kbd>: pokaż logi
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>d</kbd>: remover
|
<kbd>d</kbd>: remover
|
||||||
<kbd>e</kbd>: ocultar/mostrar contêineres parados
|
<kbd>e</kbd>: ocultar/mostrar contêineres parados
|
||||||
<kbd>p</kbd>: pausar
|
<kbd>p</kbd>: pausar
|
||||||
<kbd>s</kbd>: parar
|
<kbd>s</kbd>: start/stop
|
||||||
<kbd>r</kbd>: reiniciar
|
<kbd>r</kbd>: reiniciar
|
||||||
<kbd>a</kbd>: anexar
|
<kbd>a</kbd>: anexar
|
||||||
<kbd>m</kbd>: ver logs
|
<kbd>m</kbd>: ver logs
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>d</kbd>: kaldır
|
<kbd>d</kbd>: kaldır
|
||||||
<kbd>e</kbd>: hide/show stopped containers
|
<kbd>e</kbd>: hide/show stopped containers
|
||||||
<kbd>p</kbd>: pause
|
<kbd>p</kbd>: pause
|
||||||
<kbd>s</kbd>: durdur
|
<kbd>s</kbd>: start/stop
|
||||||
<kbd>r</kbd>: yeniden başlat
|
<kbd>r</kbd>: yeniden başlat
|
||||||
<kbd>a</kbd>: bağlan/iliştir
|
<kbd>a</kbd>: bağlan/iliştir
|
||||||
<kbd>m</kbd>: kayıt defterini görüntüle
|
<kbd>m</kbd>: kayıt defterini görüntüle
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||||
<kbd>d</kbd>: 移除
|
<kbd>d</kbd>: 移除
|
||||||
<kbd>e</kbd>: 隐藏/显示已停止的容器
|
<kbd>e</kbd>: 隐藏/显示已停止的容器
|
||||||
<kbd>p</kbd>: 暂停
|
<kbd>p</kbd>: 暂停
|
||||||
<kbd>s</kbd>: 停止
|
<kbd>s</kbd>: start/stop
|
||||||
<kbd>r</kbd>: 重新启动
|
<kbd>r</kbd>: 重新启动
|
||||||
<kbd>a</kbd>: attach
|
<kbd>a</kbd>: attach
|
||||||
<kbd>m</kbd>: 查看日志
|
<kbd>m</kbd>: 查看日志
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,9 @@ type CommandTemplatesConfig struct {
|
||||||
|
|
||||||
// ServiceTop is the command for viewing the processes under a given service
|
// ServiceTop is the command for viewing the processes under a given service
|
||||||
ServiceTop string `yaml:"serviceTop,omitempty"`
|
ServiceTop string `yaml:"serviceTop,omitempty"`
|
||||||
|
|
||||||
|
// List of shells that, in given order, will be tried when attaching to a container.
|
||||||
|
PreferredExecShells []string `yaml:"preferedExecShell,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// OSConfig contains config on the level of the os
|
// OSConfig contains config on the level of the os
|
||||||
|
|
@ -402,6 +405,7 @@ func GetDefaultConfig() UserConfig {
|
||||||
DockerComposeConfig: "{{ .DockerCompose }} config",
|
DockerComposeConfig: "{{ .DockerCompose }} config",
|
||||||
CheckDockerComposeConfig: "{{ .DockerCompose }} config --quiet",
|
CheckDockerComposeConfig: "{{ .DockerCompose }} config --quiet",
|
||||||
ServiceTop: "{{ .DockerCompose }} top {{ .Service.Name }}",
|
ServiceTop: "{{ .DockerCompose }} top {{ .Service.Name }}",
|
||||||
|
PreferredExecShells: []string{},
|
||||||
},
|
},
|
||||||
CustomCommands: CustomCommands{
|
CustomCommands: CustomCommands{
|
||||||
Containers: []CustomCommand{},
|
Containers: []CustomCommand{},
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,8 @@ func (gui *Gui) handleContainersRemoveMenu(g *gocui.Gui, v *gocui.View) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: do same thing for start
|
||||||
|
// Fix UI not showing it being paused (it should say unpaused)
|
||||||
func (gui *Gui) PauseContainer(container *commands.Container) error {
|
func (gui *Gui) PauseContainer(container *commands.Container) error {
|
||||||
return gui.WithWaitingStatus(gui.Tr.PausingStatus, func() (err error) {
|
return gui.WithWaitingStatus(gui.Tr.PausingStatus, func() (err error) {
|
||||||
if container.Details.State.Paused {
|
if container.Details.State.Paused {
|
||||||
|
|
@ -384,12 +386,22 @@ func (gui *Gui) handleContainerPause(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gui.PauseContainer(ctr)
|
return gui.PauseContainer(ctr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleContainerStop(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleContainerStartStop(g *gocui.Gui, v *gocui.View) error {
|
||||||
ctr, err := gui.Panels.Containers.GetSelectedItem()
|
ctr, err := gui.Panels.Containers.GetSelectedItem()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !(ctr.Container.State == "exited" || ctr.Container.State == "running") {
|
||||||
|
return gui.createErrorPanel(gui.Tr.CannotStartStop)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctr.Container.State == "exited" {
|
||||||
|
return gui.WithWaitingStatus(gui.Tr.StoppingStatus, func() error {
|
||||||
|
return ctr.Start()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return gui.createConfirmationPanel(gui.Tr.Confirm, gui.Tr.StopContainer, func(g *gocui.Gui, v *gocui.View) error {
|
return gui.createConfirmationPanel(gui.Tr.Confirm, gui.Tr.StopContainer, func(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gui.WithWaitingStatus(gui.Tr.StoppingStatus, func() error {
|
return gui.WithWaitingStatus(gui.Tr.StoppingStatus, func() error {
|
||||||
if err := ctr.Stop(); err != nil {
|
if err := ctr.Stop(); err != nil {
|
||||||
|
|
@ -466,11 +478,32 @@ func (gui *Gui) containerExecShell(container *commands.Container) error {
|
||||||
commandObject := gui.DockerCommand.NewCommandObject(commands.CommandObject{
|
commandObject := gui.DockerCommand.NewCommandObject(commands.CommandObject{
|
||||||
Container: container,
|
Container: container,
|
||||||
})
|
})
|
||||||
|
var command string
|
||||||
|
shell := ""
|
||||||
|
|
||||||
|
preferredExecShells := gui.Config.UserConfig.CommandTemplates.PreferredExecShells
|
||||||
|
if len(preferredExecShells) > 0 {
|
||||||
|
for _, preferredExecShell := range preferredExecShells {
|
||||||
|
command := utils.ApplyTemplate(fmt.Sprintf("docker exec {{ .Container.ID }} which %s", preferredExecShell), commandObject)
|
||||||
|
|
||||||
|
err := gui.runCommandSilently(gui.OSCommand.ExecutableFromString(command))
|
||||||
|
if err == nil {
|
||||||
|
shell = preferredExecShell
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Use SDK
|
||||||
|
// Use default implementation in case we cannot fulfill user's preference
|
||||||
|
if shell == "" {
|
||||||
|
command = utils.ApplyTemplate("docker exec -it {{ .Container.ID }} /bin/sh -c 'eval $(grep ^$(id -un): /etc/passwd | cut -d : -f 7-)'", commandObject)
|
||||||
|
} else {
|
||||||
|
command = utils.ApplyTemplate(fmt.Sprintf("docker exec -it {{ .Container.ID }} %s", shell), commandObject)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: use SDK
|
|
||||||
resolvedCommand := utils.ApplyTemplate("docker exec -it {{ .Container.ID }} /bin/sh -c 'eval $(grep ^$(id -un): /etc/passwd | cut -d : -f 7-)'", commandObject)
|
|
||||||
// attach and return the subprocess error
|
// attach and return the subprocess error
|
||||||
cmd := gui.OSCommand.ExecutableFromString(resolvedCommand)
|
cmd := gui.OSCommand.ExecutableFromString(command)
|
||||||
return gui.runSubprocess(cmd)
|
return gui.runSubprocess(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -210,8 +210,8 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
||||||
ViewName: "containers",
|
ViewName: "containers",
|
||||||
Key: 's',
|
Key: 's',
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: gui.handleContainerStop,
|
Handler: gui.handleContainerStartStop,
|
||||||
Description: gui.Tr.Stop,
|
Description: gui.Tr.StartStop,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "containers",
|
ViewName: "containers",
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ func (gui *Gui) runSubprocessWithMessage(cmd *exec.Cmd, msg string) error {
|
||||||
|
|
||||||
gui.PauseBackgroundThreads = true
|
gui.PauseBackgroundThreads = true
|
||||||
|
|
||||||
gui.runCommand(cmd, msg)
|
err := gui.runCommand(cmd, msg)
|
||||||
|
|
||||||
if err := gui.g.Resume(); err != nil {
|
if err := gui.g.Resume(); err != nil {
|
||||||
return gui.createErrorPanel(err.Error())
|
return gui.createErrorPanel(err.Error())
|
||||||
|
|
@ -34,10 +34,26 @@ func (gui *Gui) runSubprocessWithMessage(cmd *exec.Cmd, msg string) error {
|
||||||
|
|
||||||
gui.PauseBackgroundThreads = false
|
gui.PauseBackgroundThreads = false
|
||||||
|
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) runCommand(cmd *exec.Cmd, msg string) {
|
func (gui *Gui) runCommandSilently(cmd *exec.Cmd) error {
|
||||||
|
stop := make(chan os.Signal, 1)
|
||||||
|
defer signal.Stop(stop)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
signal.Notify(stop, os.Interrupt)
|
||||||
|
<-stop
|
||||||
|
|
||||||
|
if err := gui.OSCommand.Kill(cmd); err != nil {
|
||||||
|
gui.Log.Error(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return cmd.Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) runCommand(cmd *exec.Cmd, msg string) error {
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stdout
|
cmd.Stderr = os.Stdout
|
||||||
cmd.Stdin = os.Stdin
|
cmd.Stdin = os.Stdin
|
||||||
|
|
@ -58,9 +74,8 @@ func (gui *Gui) runCommand(cmd *exec.Cmd, msg string) {
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
fmt.Fprintf(os.Stdout, "\n%s\n\n", utils.ColoredString(msg, color.FgGreen))
|
fmt.Fprintf(os.Stdout, "\n%s\n\n", utils.ColoredString(msg, color.FgGreen))
|
||||||
}
|
}
|
||||||
if err := cmd.Run(); err != nil {
|
err := cmd.Run()
|
||||||
// not handling the error explicitly because usually we're going to see it
|
if err != nil {
|
||||||
// in the output anyway
|
|
||||||
gui.Log.Error(err)
|
gui.Log.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,4 +84,6 @@ func (gui *Gui) runCommand(cmd *exec.Cmd, msg string) {
|
||||||
cmd.Stderr = io.Discard
|
cmd.Stderr = io.Discard
|
||||||
|
|
||||||
gui.promptToReturn()
|
gui.promptToReturn()
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ type TranslationSet struct {
|
||||||
CannotAttachStoppedContainerError string
|
CannotAttachStoppedContainerError string
|
||||||
CannotAccessDockerSocketError string
|
CannotAccessDockerSocketError string
|
||||||
CannotKillChildError string
|
CannotKillChildError string
|
||||||
|
CannotStartStop string
|
||||||
|
|
||||||
Donate string
|
Donate string
|
||||||
Cancel string
|
Cancel string
|
||||||
|
|
@ -59,6 +60,7 @@ type TranslationSet struct {
|
||||||
Down string
|
Down string
|
||||||
DownWithVolumes string
|
DownWithVolumes string
|
||||||
Start string
|
Start string
|
||||||
|
StartStop string
|
||||||
Rebuild string
|
Rebuild string
|
||||||
Recreate string
|
Recreate string
|
||||||
PreviousContext string
|
PreviousContext string
|
||||||
|
|
@ -161,6 +163,7 @@ func englishSet() TranslationSet {
|
||||||
CannotAttachStoppedContainerError: "You cannot attach to a stopped container, you need to start it first (which you can actually do with the 'r' key) (yes I'm too lazy to do this automatically for you) (pretty cool that I get to communicate one-on-one with you in the form of an error message though)",
|
CannotAttachStoppedContainerError: "You cannot attach to a stopped container, you need to start it first (which you can actually do with the 'r' key) (yes I'm too lazy to do this automatically for you) (pretty cool that I get to communicate one-on-one with you in the form of an error message though)",
|
||||||
CannotAccessDockerSocketError: "Can't access docker socket at: unix:///var/run/docker.sock\nRun lazydocker as root or read https://docs.docker.com/install/linux/linux-postinstall/",
|
CannotAccessDockerSocketError: "Can't access docker socket at: unix:///var/run/docker.sock\nRun lazydocker as root or read https://docs.docker.com/install/linux/linux-postinstall/",
|
||||||
CannotKillChildError: "Waited three seconds for child process to stop. There may be an orphan process that continues to run on your system.",
|
CannotKillChildError: "Waited three seconds for child process to stop. There may be an orphan process that continues to run on your system.",
|
||||||
|
CannotStartStop: "Cannot start stop this container",
|
||||||
|
|
||||||
Donate: "Donate",
|
Donate: "Donate",
|
||||||
Confirm: "Confirm",
|
Confirm: "Confirm",
|
||||||
|
|
@ -190,6 +193,7 @@ func englishSet() TranslationSet {
|
||||||
Down: "down project",
|
Down: "down project",
|
||||||
DownWithVolumes: "down project with volumes",
|
DownWithVolumes: "down project with volumes",
|
||||||
Start: "start",
|
Start: "start",
|
||||||
|
StartStop: "start/stop",
|
||||||
Rebuild: "rebuild",
|
Rebuild: "rebuild",
|
||||||
Recreate: "recreate",
|
Recreate: "recreate",
|
||||||
PreviousContext: "previous tab",
|
PreviousContext: "previous tab",
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue