From 001ad0de2d56551eac8006a2562d360dd7b0cabb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=89AU?= Date: Sat, 15 Jun 2024 19:18:09 +0200 Subject: [PATCH 1/6] change stop to be start stop --- pkg/commands/container.go | 6 ++++++ pkg/gui/containers_panel.go | 14 +++++++++++++- pkg/gui/keybindings.go | 4 ++-- pkg/i18n/english.go | 4 ++++ 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/pkg/commands/container.go b/pkg/commands/container.go index b45feef7..e7a4fdd2 100644 --- a/pkg/commands/container.go +++ b/pkg/commands/container.go @@ -59,6 +59,12 @@ func (c *Container) Remove(options dockerTypes.ContainerRemoveOptions) error { return nil } +// Start starts the container +func (c *Container) Start() error { + c.Log.Warn(fmt.Sprintf("starting container %s", c.Name)) + return c.Client.ContainerStart(context.Background(), c.ID, dockerTypes.ContainerStartOptions{}) +} + // Stop stops the container func (c *Container) Stop() error { c.Log.Warn(fmt.Sprintf("stopping container %s", c.Name)) diff --git a/pkg/gui/containers_panel.go b/pkg/gui/containers_panel.go index 24965c6c..541c6990 100644 --- a/pkg/gui/containers_panel.go +++ b/pkg/gui/containers_panel.go @@ -342,6 +342,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 { return gui.WithWaitingStatus(gui.Tr.PausingStatus, func() (err error) { if container.Details.State.Paused { @@ -367,12 +369,22 @@ func (gui *Gui) handleContainerPause(g *gocui.Gui, v *gocui.View) error { return gui.PauseContainer(container) } -func (gui *Gui) handleContainerStop(g *gocui.Gui, v *gocui.View) error { +func (gui *Gui) handleContainerStartStop(g *gocui.Gui, v *gocui.View) error { container, err := gui.Panels.Containers.GetSelectedItem() if err != nil { return nil } + if !(container.Container.State == "exited" || container.Container.State == "running") { + return gui.createErrorPanel(gui.Tr.CannotStartStop) + } + + if container.Container.State == "exited" { + return gui.WithWaitingStatus(gui.Tr.StoppingStatus, func() error { + return container.Start() + }) + } + 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 { if err := container.Stop(); err != nil { diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 424f47c5..5290132f 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -210,8 +210,8 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { ViewName: "containers", Key: 's', Modifier: gocui.ModNone, - Handler: gui.handleContainerStop, - Description: gui.Tr.Stop, + Handler: gui.handleContainerStartStop, + Description: gui.Tr.StartStop, }, { ViewName: "containers", diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 0d4f8222..8085f5d9 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -26,6 +26,7 @@ type TranslationSet struct { CannotAttachStoppedContainerError string CannotAccessDockerSocketError string CannotKillChildError string + CannotStartStop string Donate string Cancel string @@ -59,6 +60,7 @@ type TranslationSet struct { Down string DownWithVolumes string Start string + StartStop string Rebuild string Recreate string PreviousContext string @@ -153,6 +155,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)", 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.", + CannotStartStop: "Cannot start stop this container", Donate: "Donate", Confirm: "Confirm", @@ -182,6 +185,7 @@ func englishSet() TranslationSet { Down: "down project", DownWithVolumes: "down project with volumes", Start: "start", + StartStop: "start/stop", Rebuild: "rebuild", Recreate: "recreate", PreviousContext: "previous tab", From 636b10d4b61e314d247b37c9b6381ea057277b6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=89AU?= Date: Sun, 16 Jun 2024 00:16:06 +0200 Subject: [PATCH 2/6] bubble up errors on command running --- pkg/gui/subprocess.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pkg/gui/subprocess.go b/pkg/gui/subprocess.go index b41ac475..943b4fe0 100644 --- a/pkg/gui/subprocess.go +++ b/pkg/gui/subprocess.go @@ -26,7 +26,7 @@ func (gui *Gui) runSubprocessWithMessage(cmd *exec.Cmd, msg string) error { gui.PauseBackgroundThreads = true - gui.runCommand(cmd, msg) + err := gui.runCommand(cmd, msg) if err := gui.g.Resume(); err != nil { return gui.createErrorPanel(err.Error()) @@ -34,7 +34,7 @@ func (gui *Gui) runSubprocessWithMessage(cmd *exec.Cmd, msg string) error { gui.PauseBackgroundThreads = false - return nil + return err } func (gui *Gui) runCommand(cmd *exec.Cmd, msg string) { @@ -58,9 +58,9 @@ func (gui *Gui) runCommand(cmd *exec.Cmd, msg string) { if msg != "" { fmt.Fprintf(os.Stdout, "\n%s\n\n", utils.ColoredString(msg, color.FgGreen)) } - if err := cmd.Run(); err != nil { - // not handling the error explicitly because usually we're going to see it - // in the output anyway + err := cmd.Run() + + if err != nil { gui.Log.Error(err) } @@ -69,4 +69,6 @@ func (gui *Gui) runCommand(cmd *exec.Cmd, msg string) { cmd.Stderr = io.Discard gui.promptToReturn() + + return err } From 50f3a6ca0f8eddde46b285441942e66f827c26eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=89AU?= Date: Sun, 16 Jun 2024 00:16:13 +0200 Subject: [PATCH 3/6] add silent command running --- pkg/gui/subprocess.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pkg/gui/subprocess.go b/pkg/gui/subprocess.go index 943b4fe0..05549ce6 100644 --- a/pkg/gui/subprocess.go +++ b/pkg/gui/subprocess.go @@ -37,7 +37,23 @@ func (gui *Gui) runSubprocessWithMessage(cmd *exec.Cmd, msg string) error { 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.Stderr = os.Stdout cmd.Stdin = os.Stdin From a5df084847ff85035d5bb489310ef756231792f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=89AU?= Date: Sun, 16 Jun 2024 00:16:39 +0200 Subject: [PATCH 4/6] add new config option to add handle preferred shells to execute on the container --- pkg/config/app_config.go | 4 ++++ pkg/gui/containers_panel.go | 27 ++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go index d35a244d..c87bad62 100644 --- a/pkg/config/app_config.go +++ b/pkg/config/app_config.go @@ -216,6 +216,9 @@ type CommandTemplatesConfig struct { // ServiceTop is the command for viewing the processes under a given service 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 @@ -398,6 +401,7 @@ func GetDefaultConfig() UserConfig { DockerComposeConfig: "{{ .DockerCompose }} config", CheckDockerComposeConfig: "{{ .DockerCompose }} config --quiet", ServiceTop: "{{ .DockerCompose }} top {{ .Service.Name }}", + PreferredExecShells: []string{}, }, CustomCommands: CustomCommands{ Containers: []CustomCommand{}, diff --git a/pkg/gui/containers_panel.go b/pkg/gui/containers_panel.go index 541c6990..c936630c 100644 --- a/pkg/gui/containers_panel.go +++ b/pkg/gui/containers_panel.go @@ -461,11 +461,32 @@ func (gui *Gui) containerExecShell(container *commands.Container) error { commandObject := gui.DockerCommand.NewCommandObject(commands.CommandObject{ Container: container, }) + var command string + shell := "" - // 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) + 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) + } + + cmd := gui.OSCommand.ExecutableFromString(command) // attach and return the subprocess error - cmd := gui.OSCommand.ExecutableFromString(resolvedCommand) return gui.runSubprocess(cmd) } From 02c86b199494930f1440acdbfb3fbbc875adff26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=89AU?= Date: Sun, 8 Sep 2024 22:07:18 +0200 Subject: [PATCH 5/6] unbreak feature --- pkg/commands/container.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/commands/container.go b/pkg/commands/container.go index 41f2a00d..99ca14e0 100644 --- a/pkg/commands/container.go +++ b/pkg/commands/container.go @@ -62,7 +62,7 @@ func (c *Container) Remove(options container.RemoveOptions) error { // Start starts the container func (c *Container) Start() error { c.Log.Warn(fmt.Sprintf("starting container %s", c.Name)) - return c.Client.ContainerStart(context.Background(), c.ID, dockerTypes.ContainerStartOptions{}) + return c.Client.ContainerStart(context.Background(), c.ID, container.StartOptions{}) } // Stop stops the container From 8d9a96eb9d45eaf6cf6d48ab63830f0aa4e3780e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=89AU?= Date: Wed, 18 Dec 2024 17:55:25 +0100 Subject: [PATCH 6/6] fix gofumpt --- docs/keybindings/Keybindings_de.md | 2 +- docs/keybindings/Keybindings_en.md | 2 +- docs/keybindings/Keybindings_es.md | 2 +- docs/keybindings/Keybindings_fr.md | 2 +- docs/keybindings/Keybindings_nl.md | 2 +- docs/keybindings/Keybindings_pl.md | 2 +- docs/keybindings/Keybindings_pt.md | 2 +- docs/keybindings/Keybindings_tr.md | 2 +- docs/keybindings/Keybindings_zh.md | 2 +- pkg/gui/subprocess.go | 1 - 10 files changed, 9 insertions(+), 10 deletions(-) diff --git a/docs/keybindings/Keybindings_de.md b/docs/keybindings/Keybindings_de.md index f463e21b..9dfa3140 100644 --- a/docs/keybindings/Keybindings_de.md +++ b/docs/keybindings/Keybindings_de.md @@ -19,7 +19,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct d: entfernen e: hide/show stopped containers p: pause - s: anhalten + s: start/stop r: neustarten a: anbinden m: zeige Protokolle diff --git a/docs/keybindings/Keybindings_en.md b/docs/keybindings/Keybindings_en.md index a5a8ff3f..6639c6b1 100644 --- a/docs/keybindings/Keybindings_en.md +++ b/docs/keybindings/Keybindings_en.md @@ -19,7 +19,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct d: remove e: hide/show stopped containers p: pause - s: stop + s: start/stop r: restart a: attach m: view logs diff --git a/docs/keybindings/Keybindings_es.md b/docs/keybindings/Keybindings_es.md index ff4eee14..314e58ea 100644 --- a/docs/keybindings/Keybindings_es.md +++ b/docs/keybindings/Keybindings_es.md @@ -19,7 +19,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct d: borrar e: esconder/mostrar contenedores parados p: pausa - s: parar + s: start/stop r: reiniciar a: attach m: ver logs diff --git a/docs/keybindings/Keybindings_fr.md b/docs/keybindings/Keybindings_fr.md index 64fb4197..369fbafd 100644 --- a/docs/keybindings/Keybindings_fr.md +++ b/docs/keybindings/Keybindings_fr.md @@ -19,7 +19,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct d: supprimer e: cacher/montrer les conteneurs arrêtés p: pause - s: arrêter + s: start/stop r: redémarrer a: attacher m: voir les enregistrements diff --git a/docs/keybindings/Keybindings_nl.md b/docs/keybindings/Keybindings_nl.md index 3de0c93e..d784855a 100644 --- a/docs/keybindings/Keybindings_nl.md +++ b/docs/keybindings/Keybindings_nl.md @@ -19,7 +19,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct d: verwijder e: verberg gestopte containers p: pause - s: stop + s: start/stop r: herstart a: verbinden m: bekijk logs diff --git a/docs/keybindings/Keybindings_pl.md b/docs/keybindings/Keybindings_pl.md index 8d46b0ef..0b99a9e1 100644 --- a/docs/keybindings/Keybindings_pl.md +++ b/docs/keybindings/Keybindings_pl.md @@ -19,7 +19,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct d: usuń e: hide/show stopped containers p: pause - s: zatrzymaj + s: start/stop r: restartuj a: przyczep m: pokaż logi diff --git a/docs/keybindings/Keybindings_pt.md b/docs/keybindings/Keybindings_pt.md index 41604314..c703a641 100644 --- a/docs/keybindings/Keybindings_pt.md +++ b/docs/keybindings/Keybindings_pt.md @@ -19,7 +19,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct d: remover e: ocultar/mostrar contêineres parados p: pausar - s: parar + s: start/stop r: reiniciar a: anexar m: ver logs diff --git a/docs/keybindings/Keybindings_tr.md b/docs/keybindings/Keybindings_tr.md index 018f68c2..0ceea241 100644 --- a/docs/keybindings/Keybindings_tr.md +++ b/docs/keybindings/Keybindings_tr.md @@ -19,7 +19,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct d: kaldır e: hide/show stopped containers p: pause - s: durdur + s: start/stop r: yeniden başlat a: bağlan/iliştir m: kayıt defterini görüntüle diff --git a/docs/keybindings/Keybindings_zh.md b/docs/keybindings/Keybindings_zh.md index 8b1607dd..38f49708 100644 --- a/docs/keybindings/Keybindings_zh.md +++ b/docs/keybindings/Keybindings_zh.md @@ -19,7 +19,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct d: 移除 e: 隐藏/显示已停止的容器 p: 暂停 - s: 停止 + s: start/stop r: 重新启动 a: attach m: 查看日志 diff --git a/pkg/gui/subprocess.go b/pkg/gui/subprocess.go index 05549ce6..300bfca4 100644 --- a/pkg/gui/subprocess.go +++ b/pkg/gui/subprocess.go @@ -75,7 +75,6 @@ func (gui *Gui) runCommand(cmd *exec.Cmd, msg string) error { fmt.Fprintf(os.Stdout, "\n%s\n\n", utils.ColoredString(msg, color.FgGreen)) } err := cmd.Run() - if err != nil { gui.Log.Error(err) }