mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-21 23:01:03 +00:00
support running in non-docker-compose context
This commit is contained in:
parent
87c6208577
commit
b02c92da33
6 changed files with 121 additions and 78 deletions
|
|
@ -46,13 +46,20 @@ func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Translat
|
|||
return nil, err
|
||||
}
|
||||
|
||||
inDockerComposeProject := true
|
||||
err = osCommand.RunCommand(config.UserConfig.CommandTemplates.CheckDockerComposeConfig)
|
||||
if err != nil {
|
||||
inDockerComposeProject = false
|
||||
log.Warn(err.Error())
|
||||
}
|
||||
|
||||
return &DockerCommand{
|
||||
Log: log,
|
||||
OSCommand: osCommand,
|
||||
Tr: tr,
|
||||
Config: config,
|
||||
Client: cli,
|
||||
InDockerComposeProject: true, // TODO: determine this at startup
|
||||
InDockerComposeProject: inDockerComposeProject,
|
||||
ErrorChan: errorChan,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,12 +110,13 @@ type CommandTemplatesConfig struct {
|
|||
RebuildService string `yaml:"rebuildService,omitempty"`
|
||||
|
||||
// ViewContainerLogs is for viewing the container logs in a subprocess. We have this as a separate command in case you want to show all the logs rather than just tail them for the sake of reducing CPU load when in the lazydocker GUI
|
||||
ViewContainerLogs string `yaml:"viewContainerLogs,omitempty"`
|
||||
ContainerLogs string `yaml:"containerLogs,omitempty"`
|
||||
ContainerTTYLogs string `yaml:"containerTTYLogs,omitempty"`
|
||||
AllLogs string `yaml:"allLogs,omitempty"`
|
||||
ViewAllLogs string `yaml:"viewAlLogs,omitempty"`
|
||||
DockerComposeConfig string `yaml:"dockerComposeConfig,omitempty"`
|
||||
ViewContainerLogs string `yaml:"viewContainerLogs,omitempty"`
|
||||
ContainerLogs string `yaml:"containerLogs,omitempty"`
|
||||
ContainerTTYLogs string `yaml:"containerTTYLogs,omitempty"`
|
||||
AllLogs string `yaml:"allLogs,omitempty"`
|
||||
ViewAllLogs string `yaml:"viewAlLogs,omitempty"`
|
||||
DockerComposeConfig string `yaml:"dockerComposeConfig,omitempty"`
|
||||
CheckDockerComposeConfig string `yaml:"checkDockerComposeConfig,omitempty"`
|
||||
}
|
||||
|
||||
type OSConfig struct {
|
||||
|
|
@ -163,17 +164,18 @@ func GetDefaultConfig() UserConfig {
|
|||
Reporting: "undetermined",
|
||||
ConfirmOnQuit: false,
|
||||
CommandTemplates: CommandTemplatesConfig{
|
||||
RestartService: "docker-compose restart {{ .Name }}",
|
||||
RebuildService: "docker-compose up -d --build {{ .Name }}",
|
||||
DockerCompose: "apdev compose",
|
||||
StopService: "apdev stop {{ .Name }}",
|
||||
ServiceLogs: "apdev logs {{ .Name }}",
|
||||
ContainerLogs: "docker logs --timestamps --follow --tail=100 {{ .ID }}",
|
||||
ViewContainerLogs: "docker logs --timestamps --follow --tail=100 {{ .ID }}",
|
||||
ContainerTTYLogs: "docker logs --follow --tail=100 {{ .ID }}",
|
||||
AllLogs: "apdev logs --tail=100",
|
||||
ViewAllLogs: "apdev logs",
|
||||
DockerComposeConfig: "apdev compose config",
|
||||
RestartService: "docker-compose restart {{ .Name }}",
|
||||
RebuildService: "docker-compose up -d --build {{ .Name }}",
|
||||
DockerCompose: "docker-compose",
|
||||
StopService: "docker-compose stop {{ .Name }}",
|
||||
ServiceLogs: "docker-compose logs {{ .Name }}",
|
||||
AllLogs: "docker-compose logs --tail=100",
|
||||
ViewAllLogs: "docker-compose logs",
|
||||
DockerComposeConfig: "docker-compose config",
|
||||
CheckDockerComposeConfig: "docker-compose config --quiet",
|
||||
ContainerLogs: "docker logs --timestamps --follow --tail=100 {{ .ID }}",
|
||||
ViewContainerLogs: "docker logs --timestamps --follow --tail=100 {{ .ID }}",
|
||||
ContainerTTYLogs: "docker logs --follow --tail=100 {{ .ID }}",
|
||||
},
|
||||
OS: GetPlatformDefaultConfig(),
|
||||
Update: UpdateConfig{
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ type Gui struct {
|
|||
waitForIntro sync.WaitGroup
|
||||
T *tasks.TaskManager
|
||||
ErrorChan chan error
|
||||
CyclableViews []string
|
||||
}
|
||||
|
||||
type servicePanelState struct {
|
||||
|
|
@ -122,9 +123,13 @@ type guiState struct {
|
|||
|
||||
// NewGui builds a new gui handler
|
||||
func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand *commands.OSCommand, tr *i18n.TranslationSet, config *config.AppConfig, errorChan chan error) (*Gui, error) {
|
||||
previousView := "containers"
|
||||
if dockerCommand.InDockerComposeProject {
|
||||
previousView = "services"
|
||||
}
|
||||
|
||||
initialState := guiState{
|
||||
PreviousView: "services",
|
||||
PreviousView: previousView,
|
||||
Platform: *oSCommand.Platform,
|
||||
Panels: &panelStates{
|
||||
Services: &servicePanelState{SelectedLine: -1, ContextIndex: 0},
|
||||
|
|
@ -139,6 +144,11 @@ func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand
|
|||
},
|
||||
}
|
||||
|
||||
cyclableViews := []string{"status", "containers", "images", "volumes"}
|
||||
if dockerCommand.InDockerComposeProject {
|
||||
cyclableViews = []string{"status", "services", "containers", "images", "volumes"}
|
||||
}
|
||||
|
||||
gui := &Gui{
|
||||
Log: log,
|
||||
DockerCommand: dockerCommand,
|
||||
|
|
@ -150,6 +160,7 @@ func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand
|
|||
statusManager: &statusManager{},
|
||||
T: tasks.NewTaskManager(log),
|
||||
ErrorChan: errorChan,
|
||||
CyclableViews: cyclableViews,
|
||||
}
|
||||
|
||||
gui.GenerateSentinelErrors()
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||
if currView != nil {
|
||||
viewName := currView.Name()
|
||||
usePreviouseView := true
|
||||
for _, view := range cyclableViews {
|
||||
for _, view := range gui.CyclableViews {
|
||||
if view == viewName {
|
||||
currentCyclebleView = viewName
|
||||
usePreviouseView = false
|
||||
|
|
@ -92,15 +92,26 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||
|
||||
usableSpace := height - 4
|
||||
|
||||
tallPanels := 4
|
||||
|
||||
vHeights := map[string]int{
|
||||
"status": 3,
|
||||
"services": usableSpace/tallPanels + usableSpace%tallPanels,
|
||||
"containers": usableSpace / tallPanels,
|
||||
"images": usableSpace / tallPanels,
|
||||
"volumes": usableSpace / tallPanels,
|
||||
"options": 1,
|
||||
tallPanels := 3
|
||||
var vHeights map[string]int
|
||||
if gui.DockerCommand.InDockerComposeProject {
|
||||
tallPanels++
|
||||
vHeights = map[string]int{
|
||||
"status": 3,
|
||||
"services": usableSpace/tallPanels + usableSpace%tallPanels,
|
||||
"containers": usableSpace / tallPanels,
|
||||
"images": usableSpace / tallPanels,
|
||||
"volumes": usableSpace / tallPanels,
|
||||
"options": 1,
|
||||
}
|
||||
} else {
|
||||
vHeights = map[string]int{
|
||||
"status": 3,
|
||||
"containers": usableSpace/tallPanels + usableSpace%tallPanels,
|
||||
"images": usableSpace / tallPanels,
|
||||
"volumes": usableSpace / tallPanels,
|
||||
"options": 1,
|
||||
}
|
||||
}
|
||||
|
||||
if height < 28 {
|
||||
|
|
@ -110,12 +121,14 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||
}
|
||||
vHeights = map[string]int{
|
||||
"status": defaultHeight,
|
||||
"services": defaultHeight,
|
||||
"containers": defaultHeight,
|
||||
"images": defaultHeight,
|
||||
"volumes": defaultHeight,
|
||||
"options": defaultHeight,
|
||||
}
|
||||
if gui.DockerCommand.InDockerComposeProject {
|
||||
vHeights["services"] = defaultHeight
|
||||
}
|
||||
vHeights[currentCyclebleView] = height - defaultHeight*tallPanels - 1
|
||||
}
|
||||
|
||||
|
|
@ -148,25 +161,30 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||
v.FgColor = gocui.ColorWhite
|
||||
}
|
||||
|
||||
servicesView, err := g.SetViewBeneath("services", "status", vHeights["services"])
|
||||
if err != nil {
|
||||
if err.Error() != "unknown view" {
|
||||
return err
|
||||
}
|
||||
servicesView.Highlight = true
|
||||
servicesView.Title = gui.Tr.ServicesTitle
|
||||
servicesView.FgColor = gocui.ColorWhite
|
||||
var servicesView *gocui.View
|
||||
aboveContainersView := "status"
|
||||
if gui.DockerCommand.InDockerComposeProject {
|
||||
aboveContainersView = "services"
|
||||
servicesView, err = g.SetViewBeneath("services", "status", vHeights["services"])
|
||||
if err != nil {
|
||||
if err.Error() != "unknown view" {
|
||||
return err
|
||||
}
|
||||
servicesView.Highlight = true
|
||||
servicesView.Title = gui.Tr.ServicesTitle
|
||||
servicesView.FgColor = gocui.ColorWhite
|
||||
|
||||
gui.focusPoint(0, gui.State.Panels.Services.SelectedLine, len(gui.DockerCommand.Services), servicesView)
|
||||
gui.focusPoint(0, gui.State.Panels.Services.SelectedLine, len(gui.DockerCommand.Services), servicesView)
|
||||
}
|
||||
}
|
||||
|
||||
containersView, err := g.SetViewBeneath("containers", "services", vHeights["containers"])
|
||||
containersView, err := g.SetViewBeneath("containers", aboveContainersView, vHeights["containers"])
|
||||
if err != nil {
|
||||
if err.Error() != "unknown view" {
|
||||
return err
|
||||
}
|
||||
containersView.Highlight = true
|
||||
if gui.Config.UserConfig.Gui.ShowAllContainers {
|
||||
if gui.Config.UserConfig.Gui.ShowAllContainers || !gui.DockerCommand.InDockerComposeProject {
|
||||
containersView.Title = gui.Tr.ContainersTitle
|
||||
} else {
|
||||
containersView.Title = gui.Tr.StandaloneContainersTitle
|
||||
|
|
@ -255,6 +273,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||
lineCount int
|
||||
}
|
||||
|
||||
// TODO: find out if I should add the services view to this.
|
||||
listViews := map[*gocui.View]listViewState{
|
||||
containersView: {selectedLine: gui.State.Panels.Containers.SelectedLine, lineCount: len(gui.DockerCommand.Containers)},
|
||||
imagesView: {selectedLine: gui.State.Panels.Images.SelectedLine, lineCount: len(gui.DockerCommand.Images)},
|
||||
|
|
|
|||
|
|
@ -9,11 +9,17 @@ import (
|
|||
)
|
||||
|
||||
func (gui *Gui) getStatusContexts() []string {
|
||||
return []string{"logs", "credits", "config"}
|
||||
if gui.DockerCommand.InDockerComposeProject {
|
||||
return []string{"logs", "credits", "config"}
|
||||
}
|
||||
return []string{"credits"}
|
||||
}
|
||||
|
||||
func (gui *Gui) getStatusContextTitles() []string {
|
||||
return []string{gui.Tr.LogsTitle, gui.Tr.CreditsTitle, gui.Tr.ConfigTitle}
|
||||
if gui.DockerCommand.InDockerComposeProject {
|
||||
return []string{gui.Tr.LogsTitle, gui.Tr.CreditsTitle, gui.Tr.ConfigTitle}
|
||||
}
|
||||
return []string{gui.Tr.CreditsTitle}
|
||||
}
|
||||
|
||||
func (gui *Gui) refreshStatus() error {
|
||||
|
|
@ -71,20 +77,20 @@ func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error {
|
|||
}
|
||||
|
||||
func (gui *Gui) renderCredits() error {
|
||||
mainView := gui.getMainView()
|
||||
mainView.Autoscroll = false
|
||||
mainView.Wrap = true
|
||||
|
||||
dashboardString := strings.Join(
|
||||
[]string{
|
||||
lazydockerTitle(),
|
||||
"Copyright (c) 2019 Jesse Duffield",
|
||||
"Keybindings: https://github.com/jesseduffield/lazydocker/blob/master/docs/keybindings",
|
||||
"Config Options: https://github.com/jesseduffield/lazydocker/blob/master/docs/Config.md",
|
||||
"Raise an Issue: https://github.com/jesseduffield/lazydocker/issues",
|
||||
}, "\n\n")
|
||||
|
||||
go gui.T.NewTask(func(stop chan struct{}) {
|
||||
mainView := gui.getMainView()
|
||||
mainView.Autoscroll = false
|
||||
mainView.Wrap = true
|
||||
|
||||
dashboardString := strings.Join(
|
||||
[]string{
|
||||
lazydockerTitle(),
|
||||
"Copyright (c) 2019 Jesse Duffield",
|
||||
"Keybindings: https://github.com/jesseduffield/lazydocker/blob/master/docs/keybindings",
|
||||
"Config Options: https://github.com/jesseduffield/lazydocker/blob/master/docs/Config.md",
|
||||
"Raise an Issue: https://github.com/jesseduffield/lazydocker/issues",
|
||||
}, "\n\n")
|
||||
|
||||
gui.renderString(gui.g, "main", dashboardString)
|
||||
})
|
||||
|
||||
|
|
@ -92,11 +98,11 @@ func (gui *Gui) renderCredits() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) renderAllLogs() error {
|
||||
mainView := gui.getMainView()
|
||||
mainView.Autoscroll = true
|
||||
mainView.Wrap = true
|
||||
|
||||
go gui.T.NewTask(func(stop chan struct{}) {
|
||||
mainView := gui.getMainView()
|
||||
mainView.Autoscroll = true
|
||||
mainView.Wrap = true
|
||||
|
||||
gui.clearMainView()
|
||||
|
||||
cmd := gui.OSCommand.RunCustomCommand(gui.Config.UserConfig.CommandTemplates.AllLogs)
|
||||
|
|
@ -121,11 +127,11 @@ func (gui *Gui) renderAllLogs() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) renderDockerComposeConfig() error {
|
||||
mainView := gui.getMainView()
|
||||
mainView.Autoscroll = false
|
||||
mainView.Wrap = true
|
||||
|
||||
go gui.T.NewTask(func(stop chan struct{}) {
|
||||
mainView := gui.getMainView()
|
||||
mainView.Autoscroll = false
|
||||
mainView.Wrap = true
|
||||
|
||||
config := gui.DockerCommand.DockerComposeConfig()
|
||||
gui.renderString(gui.g, "main", config)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ import (
|
|||
"github.com/spkg/bom"
|
||||
)
|
||||
|
||||
var cyclableViews = []string{"status", "services", "containers", "images", "volumes"}
|
||||
|
||||
func (gui *Gui) refreshSidePanels(g *gocui.Gui) error {
|
||||
// not refreshing containers and services here given that we do it every few milliseconds anyway
|
||||
if err := gui.refreshImages(); err != nil {
|
||||
|
|
@ -26,16 +24,16 @@ func (gui *Gui) refreshSidePanels(g *gocui.Gui) error {
|
|||
|
||||
func (gui *Gui) nextView(g *gocui.Gui, v *gocui.View) error {
|
||||
var focusedViewName string
|
||||
if v == nil || v.Name() == cyclableViews[len(cyclableViews)-1] {
|
||||
focusedViewName = cyclableViews[0]
|
||||
if v == nil || v.Name() == gui.CyclableViews[len(gui.CyclableViews)-1] {
|
||||
focusedViewName = gui.CyclableViews[0]
|
||||
} else {
|
||||
viewName := v.Name()
|
||||
for i := range cyclableViews {
|
||||
if viewName == cyclableViews[i] {
|
||||
focusedViewName = cyclableViews[i+1]
|
||||
for i := range gui.CyclableViews {
|
||||
if viewName == gui.CyclableViews[i] {
|
||||
focusedViewName = gui.CyclableViews[i+1]
|
||||
break
|
||||
}
|
||||
if i == len(cyclableViews)-1 {
|
||||
if i == len(gui.CyclableViews)-1 {
|
||||
gui.Log.Info("not in list of views")
|
||||
return nil
|
||||
}
|
||||
|
|
@ -51,16 +49,16 @@ func (gui *Gui) nextView(g *gocui.Gui, v *gocui.View) error {
|
|||
|
||||
func (gui *Gui) previousView(g *gocui.Gui, v *gocui.View) error {
|
||||
var focusedViewName string
|
||||
if v == nil || v.Name() == cyclableViews[0] {
|
||||
focusedViewName = cyclableViews[len(cyclableViews)-1]
|
||||
if v == nil || v.Name() == gui.CyclableViews[0] {
|
||||
focusedViewName = gui.CyclableViews[len(gui.CyclableViews)-1]
|
||||
} else {
|
||||
viewName := v.Name()
|
||||
for i := range cyclableViews {
|
||||
if viewName == cyclableViews[i] {
|
||||
focusedViewName = cyclableViews[i-1]
|
||||
for i := range gui.CyclableViews {
|
||||
if viewName == gui.CyclableViews[i] {
|
||||
focusedViewName = gui.CyclableViews[i-1]
|
||||
break
|
||||
}
|
||||
if i == len(cyclableViews)-1 {
|
||||
if i == len(gui.CyclableViews)-1 {
|
||||
gui.Log.Info("not in list of views")
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue