mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-25 00:21:04 +00:00
support custom commands that filter down to service names
This commit is contained in:
parent
4856a3d872
commit
4e86732cf2
6 changed files with 102 additions and 60 deletions
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/go-errors/errors"
|
"github.com/go-errors/errors"
|
||||||
"github.com/jesseduffield/lazydocker/pkg/config"
|
"github.com/jesseduffield/lazydocker/pkg/config"
|
||||||
|
"github.com/jesseduffield/lazydocker/pkg/i18n"
|
||||||
"github.com/jesseduffield/lazydocker/pkg/utils"
|
"github.com/jesseduffield/lazydocker/pkg/utils"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
@ -39,6 +40,7 @@ type Container struct {
|
||||||
Details Details
|
Details Details
|
||||||
MonitoringStats bool
|
MonitoringStats bool
|
||||||
DockerCommand LimitedDockerCommand
|
DockerCommand LimitedDockerCommand
|
||||||
|
Tr *i18n.TranslationSet
|
||||||
}
|
}
|
||||||
|
|
||||||
// Details is a struct containing what we get back from `docker inspect` on a container
|
// Details is a struct containing what we get back from `docker inspect` on a container
|
||||||
|
|
@ -342,7 +344,11 @@ func (c *Container) Restart() error {
|
||||||
func (c *Container) Attach() (*exec.Cmd, error) {
|
func (c *Container) Attach() (*exec.Cmd, error) {
|
||||||
// verify that we can in fact attach to this container
|
// verify that we can in fact attach to this container
|
||||||
if !c.Details.Config.OpenStdin {
|
if !c.Details.Config.OpenStdin {
|
||||||
return nil, errors.New("Container does not support attaching. You must either run the service with the '-it' flag or use `stdin_open: true, tty: true` in the docker-compose.yml file")
|
return nil, errors.New(c.Tr.UnattachableContainerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Container.State == "exited" {
|
||||||
|
return nil, errors.New(c.Tr.CannotAttachStoppedContainerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := c.OSCommand.PrepareSubProcess("docker", "attach", "--sig-proxy=false", c.ID)
|
cmd := c.OSCommand.PrepareSubProcess("docker", "attach", "--sig-proxy=false", c.ID)
|
||||||
|
|
|
||||||
|
|
@ -303,6 +303,7 @@ func (c *DockerCommand) GetContainers() ([]*Container, error) {
|
||||||
Log: c.Log,
|
Log: c.Log,
|
||||||
Config: c.Config,
|
Config: c.Config,
|
||||||
DockerCommand: c,
|
DockerCommand: c,
|
||||||
|
Tr: c.Tr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -183,11 +183,17 @@ type CustomCommands struct {
|
||||||
|
|
||||||
// CustomCommand is a template for a command we want to run against a service or container
|
// CustomCommand is a template for a command we want to run against a service or container
|
||||||
type CustomCommand struct {
|
type CustomCommand struct {
|
||||||
|
// Name is the name of the command, purely for visual display
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
|
||||||
// Attach tells us whether to switch to a subprocess to interact with the called program, or just read its output. If Attach is set to false, the command will run in the background. I'm open to the idea of having a third option where the output plays in the main panel.
|
// Attach tells us whether to switch to a subprocess to interact with the called program, or just read its output. If Attach is set to false, the command will run in the background. I'm open to the idea of having a third option where the output plays in the main panel.
|
||||||
Attach bool
|
Attach bool `yaml:"attach"`
|
||||||
|
|
||||||
// Command is the command we want to run. We can use the go templates here as well. One example might be `{{ .DockerCompose }} exec {{ .Service.Name }} /bin/sh`
|
// Command is the command we want to run. We can use the go templates here as well. One example might be `{{ .DockerCompose }} exec {{ .Service.Name }} /bin/sh`
|
||||||
Command string
|
Command string `yaml:"command"`
|
||||||
|
|
||||||
|
// ServiceNames is used to restrict this command to just one or more services. An example might be 'rails migrate' for your rails api service(s). This field has no effect on customcommands under the 'communications' part of the customCommand config.
|
||||||
|
ServiceNames []string `yaml:"serviceNames"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDefaultConfig returns the application default configuration
|
// GetDefaultConfig returns the application default configuration
|
||||||
|
|
@ -226,8 +232,9 @@ func GetDefaultConfig() UserConfig {
|
||||||
CustomCommands: CustomCommands{
|
CustomCommands: CustomCommands{
|
||||||
Containers: []CustomCommand{
|
Containers: []CustomCommand{
|
||||||
{
|
{
|
||||||
Attach: true,
|
Name: "bash",
|
||||||
Command: "docker exec -it {{ .Container.ID }} /bin/sh",
|
Command: "docker exec -it {{ .Container.ID }} /bin/sh",
|
||||||
|
Attach: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Services: []CustomCommand{},
|
Services: []CustomCommand{},
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/fatih/color"
|
||||||
"github.com/jesseduffield/lazydocker/pkg/commands"
|
"github.com/jesseduffield/lazydocker/pkg/commands"
|
||||||
"github.com/jesseduffield/lazydocker/pkg/config"
|
"github.com/jesseduffield/lazydocker/pkg/config"
|
||||||
"github.com/jesseduffield/lazydocker/pkg/utils"
|
"github.com/jesseduffield/lazydocker/pkg/utils"
|
||||||
|
|
@ -10,13 +11,14 @@ type customCommandOption struct {
|
||||||
customCommand config.CustomCommand
|
customCommand config.CustomCommand
|
||||||
description string
|
description string
|
||||||
command string
|
command string
|
||||||
|
name string
|
||||||
runCommand bool
|
runCommand bool
|
||||||
attach bool
|
attach bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDisplayStrings is a function.
|
// GetDisplayStrings is a function.
|
||||||
func (r *customCommandOption) GetDisplayStrings(isFocused bool) []string {
|
func (r *customCommandOption) GetDisplayStrings(isFocused bool) []string {
|
||||||
return []string{r.description}
|
return []string{r.name, utils.ColoredString(r.description, color.FgCyan)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) createCustomCommandMenu(customCommands []config.CustomCommand, commandObject commands.CommandObject) error {
|
func (gui *Gui) createCustomCommandMenu(customCommands []config.CustomCommand, commandObject commands.CommandObject) error {
|
||||||
|
|
@ -30,11 +32,12 @@ func (gui *Gui) createCustomCommandMenu(customCommands []config.CustomCommand, c
|
||||||
command: resolvedCommand,
|
command: resolvedCommand,
|
||||||
runCommand: true,
|
runCommand: true,
|
||||||
attach: command.Attach,
|
attach: command.Attach,
|
||||||
|
name: command.Name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
options[len(options)-1] = &customCommandOption{
|
options[len(options)-1] = &customCommandOption{
|
||||||
description: gui.Tr.Cancel,
|
name: gui.Tr.Cancel,
|
||||||
runCommand: false,
|
runCommand: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMenuPress := func(index int) error {
|
handleMenuPress := func(index int) error {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/go-errors/errors"
|
"github.com/go-errors/errors"
|
||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
"github.com/jesseduffield/lazydocker/pkg/commands"
|
"github.com/jesseduffield/lazydocker/pkg/commands"
|
||||||
|
"github.com/jesseduffield/lazydocker/pkg/config"
|
||||||
"github.com/jesseduffield/lazydocker/pkg/utils"
|
"github.com/jesseduffield/lazydocker/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -376,7 +377,25 @@ func (gui *Gui) handleServicesCustomCommand(g *gocui.Gui, v *gocui.View) error {
|
||||||
Container: service.Container,
|
Container: service.Container,
|
||||||
})
|
})
|
||||||
|
|
||||||
customCommands := gui.Config.UserConfig.CustomCommands.Services
|
var customCommands []config.CustomCommand
|
||||||
|
|
||||||
|
customServiceCommands := gui.Config.UserConfig.CustomCommands.Services
|
||||||
|
// we only include service commands if they have no serviceNames defined or if our service happens to be one of the serviceNames defined
|
||||||
|
L:
|
||||||
|
for _, cmd := range customServiceCommands {
|
||||||
|
if len(cmd.ServiceNames) == 0 {
|
||||||
|
customCommands = append(customCommands, cmd)
|
||||||
|
continue L
|
||||||
|
}
|
||||||
|
for _, serviceName := range cmd.ServiceNames {
|
||||||
|
if serviceName == service.Name {
|
||||||
|
// appending these to the top given they're more likely to be selected
|
||||||
|
customCommands = append([]config.CustomCommand{cmd}, customCommands...)
|
||||||
|
continue L
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if service.Container != nil {
|
if service.Container != nil {
|
||||||
customCommands = append(customCommands, gui.Config.UserConfig.CustomCommands.Containers...)
|
customCommands = append(customCommands, gui.Config.UserConfig.CustomCommands.Containers...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,54 +23,57 @@ type TranslationSet struct {
|
||||||
ConfirmQuit string
|
ConfirmQuit string
|
||||||
ErrorOccurred string
|
ErrorOccurred string
|
||||||
ConnectionFailed string
|
ConnectionFailed string
|
||||||
Donate string
|
UnattachableContainerError string
|
||||||
Cancel string
|
CannotAttachStoppedContainerError string
|
||||||
CustomCommandTitle string
|
|
||||||
Remove string
|
Donate string
|
||||||
ForceRemove string
|
Cancel string
|
||||||
RemoveWithVolumes string
|
CustomCommandTitle string
|
||||||
MustForceToRemoveContainer string
|
Remove string
|
||||||
Confirm string
|
ForceRemove string
|
||||||
Return string
|
RemoveWithVolumes string
|
||||||
FocusMain string
|
MustForceToRemoveContainer string
|
||||||
StopContainer string
|
Confirm string
|
||||||
RestartingStatus string
|
Return string
|
||||||
StoppingStatus string
|
FocusMain string
|
||||||
RemovingStatus string
|
StopContainer string
|
||||||
RunningCustomCommandStatus string
|
RestartingStatus string
|
||||||
RemoveService string
|
StoppingStatus string
|
||||||
Stop string
|
RemovingStatus string
|
||||||
Restart string
|
RunningCustomCommandStatus string
|
||||||
Rebuild string
|
RemoveService string
|
||||||
Recreate string
|
Stop string
|
||||||
PreviousContext string
|
Restart string
|
||||||
NextContext string
|
Rebuild string
|
||||||
Attach string
|
Recreate string
|
||||||
ViewLogs string
|
PreviousContext string
|
||||||
ServicesTitle string
|
NextContext string
|
||||||
ContainersTitle string
|
Attach string
|
||||||
StandaloneContainersTitle string
|
ViewLogs string
|
||||||
TopTitle string
|
ServicesTitle string
|
||||||
ImagesTitle string
|
ContainersTitle string
|
||||||
VolumesTitle string
|
StandaloneContainersTitle string
|
||||||
NoContainers string
|
TopTitle string
|
||||||
NoContainer string
|
ImagesTitle string
|
||||||
NoImages string
|
VolumesTitle string
|
||||||
NoVolumes string
|
NoContainers string
|
||||||
RemoveImage string
|
NoContainer string
|
||||||
RemoveVolume string
|
NoImages string
|
||||||
RemoveWithoutPrune string
|
NoVolumes string
|
||||||
PruneImages string
|
RemoveImage string
|
||||||
PruneContainers string
|
RemoveVolume string
|
||||||
PruneVolumes string
|
RemoveWithoutPrune string
|
||||||
ConfirmPruneContainers string
|
PruneImages string
|
||||||
ConfirmPruneImages string
|
PruneContainers string
|
||||||
ConfirmPruneVolumes string
|
PruneVolumes string
|
||||||
PruningStatus string
|
ConfirmPruneContainers string
|
||||||
StopService string
|
ConfirmPruneImages string
|
||||||
PressEnterToReturn string
|
ConfirmPruneVolumes string
|
||||||
ViewRestartOptions string
|
PruningStatus string
|
||||||
RunCustomCommand string
|
StopService string
|
||||||
|
PressEnterToReturn string
|
||||||
|
ViewRestartOptions string
|
||||||
|
RunCustomCommand string
|
||||||
|
|
||||||
LogsTitle string
|
LogsTitle string
|
||||||
ConfigTitle string
|
ConfigTitle string
|
||||||
|
|
@ -91,10 +94,13 @@ 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",
|
||||||
ConnectionFailed: "connection to docker client failed. You may need to restart the docker client",
|
ConnectionFailed: "connection to docker client failed. You may need to restart the docker client",
|
||||||
Donate: "Donate",
|
UnattachableContainerError: "Container does not support attaching. You must either run the service with the '-it' flag or use `stdin_open: true, tty: true` in the docker-compose.yml file",
|
||||||
Confirm: "Confirm",
|
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)",
|
||||||
|
|
||||||
|
Donate: "Donate",
|
||||||
|
Confirm: "Confirm",
|
||||||
|
|
||||||
Return: "return",
|
Return: "return",
|
||||||
FocusMain: "focus main panel",
|
FocusMain: "focus main panel",
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue