Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a new config parameter to automatically attach to container using specific shells #548

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pkg/config/app_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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{},
Expand Down
27 changes: 24 additions & 3 deletions pkg/gui/containers_panel.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,11 +449,32 @@ func (gui *Gui) containerExecShell(container *commands.Container) error {
commandObject := gui.DockerCommand.NewCommandObject(commands.CommandObject{
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)
cmd := gui.OSCommand.ExecutableFromString(command)
// attach and return the subprocess error
cmd := gui.OSCommand.ExecutableFromString(resolvedCommand)
return gui.runSubprocess(cmd)
}

Expand Down
30 changes: 24 additions & 6 deletions pkg/gui/subprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,34 @@ 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())
}

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.Stderr = os.Stdout
cmd.Stdin = os.Stdin
Expand All @@ -58,9 +74,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)
}

Expand All @@ -69,4 +85,6 @@ func (gui *Gui) runCommand(cmd *exec.Cmd, msg string) {
cmd.Stderr = io.Discard

gui.promptToReturn()

return err
}