mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-21 23:01:03 +00:00
more stuff
This commit is contained in:
parent
159a1883e5
commit
3cfa4a2bda
7 changed files with 74 additions and 20 deletions
|
|
@ -21,13 +21,15 @@ type App struct {
|
|||
DockerCommand *commands.DockerCommand
|
||||
Gui *gui.Gui
|
||||
Tr *i18n.Localizer
|
||||
ErrorChan chan error
|
||||
}
|
||||
|
||||
// NewApp bootstrap a new application
|
||||
func NewApp(config *config.AppConfig) (*App, error) {
|
||||
app := &App{
|
||||
closers: []io.Closer{},
|
||||
Config: config,
|
||||
closers: []io.Closer{},
|
||||
Config: config,
|
||||
ErrorChan: make(chan error),
|
||||
}
|
||||
var err error
|
||||
app.Log = log.NewLogger(config, "23432119147a4367abf7c0de2aa99a2d")
|
||||
|
|
@ -36,11 +38,11 @@ func NewApp(config *config.AppConfig) (*App, error) {
|
|||
|
||||
// here is the place to make use of the docker-compose.yml file in the current directory
|
||||
|
||||
app.DockerCommand, err = commands.NewDockerCommand(app.Log, app.OSCommand, app.Tr, app.Config)
|
||||
app.DockerCommand, err = commands.NewDockerCommand(app.Log, app.OSCommand, app.Tr, app.Config, app.ErrorChan)
|
||||
if err != nil {
|
||||
return app, err
|
||||
}
|
||||
app.Gui, err = gui.NewGui(app.Log, app.DockerCommand, app.OSCommand, app.Tr, config)
|
||||
app.Gui, err = gui.NewGui(app.Log, app.DockerCommand, app.OSCommand, app.Tr, config, app.ErrorChan)
|
||||
if err != nil {
|
||||
return app, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package commands
|
|||
import (
|
||||
"context"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -32,6 +33,12 @@ type Container struct {
|
|||
Details Details
|
||||
}
|
||||
|
||||
type DetailsCollection struct {
|
||||
InspectDetails Details
|
||||
CLIStats ContainerCliStat
|
||||
ClientStats ContainerStats
|
||||
}
|
||||
|
||||
type Details struct {
|
||||
ID string `json:"Id"`
|
||||
Created time.Time `json:"Created"`
|
||||
|
|
@ -239,7 +246,31 @@ type ContainerCliStat struct {
|
|||
|
||||
// GetDisplayStrings returns the dispaly string of Container
|
||||
func (c *Container) GetDisplayStrings(isFocused bool) []string {
|
||||
return []string{utils.ColoredString(c.Container.State, c.GetColor()), utils.ColoredString(c.Name, color.FgWhite), c.Stats.CPUPerc}
|
||||
return []string{utils.ColoredString(c.Container.State, c.GetColor()), utils.ColoredString(c.Name, color.FgWhite), c.GetDisplayCPUPerc()}
|
||||
}
|
||||
|
||||
// GetDisplayCPUPerc colors the cpu percentage based on how extreme it is
|
||||
func (c *Container) GetDisplayCPUPerc() string {
|
||||
if c.Stats.CPUPerc == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
percentage, err := strconv.ParseFloat(strings.TrimSuffix(c.Stats.CPUPerc, "%"), 32)
|
||||
if err != nil {
|
||||
c.Log.Error(err)
|
||||
return ""
|
||||
}
|
||||
|
||||
var clr color.Attribute
|
||||
if percentage > 90 {
|
||||
clr = color.FgRed
|
||||
} else if percentage > 50 {
|
||||
clr = color.FgYellow
|
||||
} else {
|
||||
clr = color.FgWhite
|
||||
}
|
||||
|
||||
return utils.ColoredString(c.Stats.CPUPerc, clr)
|
||||
}
|
||||
|
||||
// GetColor Container color
|
||||
|
|
@ -301,7 +332,7 @@ func (c *Container) RestartService() error {
|
|||
// Attach attaches the container
|
||||
func (c *Container) Attach() (*exec.Cmd, error) {
|
||||
// verify that we can in fact attach to this container
|
||||
if !c.Details.Config.AttachStdin {
|
||||
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")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@ type DockerCommand struct {
|
|||
Config *config.AppConfig
|
||||
Client *client.Client
|
||||
InDockerComposeProject bool
|
||||
ErrorChan chan error
|
||||
}
|
||||
|
||||
// NewDockerCommand it runs git commands
|
||||
func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Localizer, config *config.AppConfig) (*DockerCommand, error) {
|
||||
func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Localizer, config *config.AppConfig, errorChan chan error) (*DockerCommand, error) {
|
||||
cli, err := client.NewEnvClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -40,17 +41,19 @@ func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Localize
|
|||
Config: config,
|
||||
Client: cli,
|
||||
InDockerComposeProject: true, // TODO: determine this at startup
|
||||
ErrorChan: errorChan,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateContainerStats takes a slice of containers and returns the same slice but with new stats added
|
||||
// TODO: consider using this for everything stats-related
|
||||
func (c *DockerCommand) UpdateContainerStats(containers []*Container) ([]*Container, error) {
|
||||
func (c *DockerCommand) UpdateContainerStats(containers []*Container) {
|
||||
// TODO: consider using a stream rather than polling
|
||||
command := `docker stats --all --no-trunc --no-stream --format '{{json .}}'`
|
||||
output, err := c.OSCommand.RunCommandWithOutput(command)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
c.ErrorChan <- err
|
||||
return
|
||||
}
|
||||
|
||||
jsonStats := "[" + strings.Join(
|
||||
|
|
@ -63,7 +66,8 @@ func (c *DockerCommand) UpdateContainerStats(containers []*Container) ([]*Contai
|
|||
|
||||
var stats []ContainerCliStat
|
||||
if err := json.Unmarshal([]byte(jsonStats), &stats); err != nil {
|
||||
return nil, err
|
||||
c.ErrorChan <- err
|
||||
return
|
||||
}
|
||||
|
||||
for _, stat := range stats {
|
||||
|
|
@ -74,7 +78,9 @@ func (c *DockerCommand) UpdateContainerStats(containers []*Container) ([]*Contai
|
|||
}
|
||||
}
|
||||
|
||||
return containers, nil
|
||||
c.Log.Warn("updated containers")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetContainersAndServices returns a slice of docker containers
|
||||
|
|
@ -147,10 +153,7 @@ func (c *DockerCommand) GetContainers() ([]*Container, error) {
|
|||
|
||||
c.UpdateContainerDetails(ownContainers)
|
||||
|
||||
// ownContainers, err = c.UpdateContainerStats(ownContainers)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
c.UpdateContainerStats(ownContainers)
|
||||
|
||||
return ownContainers, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ func (s *Service) GetDisplayStrings(isFocused bool) []string {
|
|||
}
|
||||
|
||||
cont := s.Container
|
||||
return []string{utils.ColoredString(cont.Container.State, cont.GetColor()), utils.ColoredString(s.Name, color.FgWhite), cont.Stats.CPUPerc}
|
||||
return []string{utils.ColoredString(cont.Container.State, cont.GetColor()), utils.ColoredString(s.Name, color.FgWhite), cont.GetDisplayCPUPerc()}
|
||||
}
|
||||
|
||||
// Remove removes the service's containers
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ func (gui *Gui) handleContainerSelect(g *gocui.Gui, v *gocui.View) error {
|
|||
if err != gui.Errors.ErrNoContainers {
|
||||
return err
|
||||
}
|
||||
return gui.renderString(g, "main", gui.Tr.SLocalize("NoChangedContainers"))
|
||||
return nil
|
||||
}
|
||||
|
||||
key := container.ID + "-" + gui.getContainerContexts()[gui.State.Panels.Containers.ContextIndex]
|
||||
|
|
@ -171,7 +171,7 @@ func (gui *Gui) renderContainerLogs(mainView *gocui.View, container *commands.Co
|
|||
mainView.Autoscroll = true
|
||||
mainView.Title = "Logs"
|
||||
|
||||
if container.Details.Config.AttachStdin {
|
||||
if container.Details.Config.OpenStdin {
|
||||
return gui.renderLogsForTTYContainer(mainView, container)
|
||||
}
|
||||
return gui.renderLogsForRegularContainer(mainView, container)
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ type Gui struct {
|
|||
statusManager *statusManager
|
||||
waitForIntro sync.WaitGroup
|
||||
T *tasks.TaskManager
|
||||
ErrorChan chan error
|
||||
}
|
||||
|
||||
type servicePanelState struct {
|
||||
|
|
@ -118,10 +119,11 @@ type guiState struct {
|
|||
SubProcessOutput string
|
||||
MainProcessMutex sync.Mutex
|
||||
MainProcessChan chan struct{}
|
||||
Stats map[string]commands.ContainerStats
|
||||
}
|
||||
|
||||
// NewGui builds a new gui handler
|
||||
func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand *commands.OSCommand, tr *i18n.Localizer, config *config.AppConfig) (*Gui, error) {
|
||||
func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand *commands.OSCommand, tr *i18n.Localizer, config *config.AppConfig, errorChan chan error) (*Gui, error) {
|
||||
|
||||
initialState := guiState{
|
||||
Containers: make([]*commands.Container, 0),
|
||||
|
|
@ -151,11 +153,13 @@ func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand
|
|||
Log: log,
|
||||
DockerCommand: dockerCommand,
|
||||
OSCommand: oSCommand,
|
||||
// TODO: look into this warning
|
||||
State: initialState,
|
||||
Config: config,
|
||||
Tr: tr,
|
||||
statusManager: &statusManager{},
|
||||
T: tasks.NewTaskManager(log),
|
||||
ErrorChan: errorChan,
|
||||
}
|
||||
|
||||
gui.GenerateSentinelErrors()
|
||||
|
|
@ -535,6 +539,12 @@ func (gui *Gui) Run() error {
|
|||
gui.goEvery(time.Millisecond*500, gui.refreshContainersAndServices)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
for err := range gui.ErrorChan {
|
||||
gui.createErrorPanel(gui.g, err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
g.SetManager(gocui.ManagerFunc(gui.layout), gocui.ManagerFunc(gui.getFocusLayout()))
|
||||
|
||||
if err = gui.keybindings(g); err != nil {
|
||||
|
|
@ -546,7 +556,11 @@ func (gui *Gui) Run() error {
|
|||
}
|
||||
|
||||
func (gui *Gui) reRenderMain() error {
|
||||
if gui.getMainView().IsTainted() {
|
||||
mainView := gui.getMainView()
|
||||
if mainView == nil {
|
||||
return nil
|
||||
}
|
||||
if mainView.IsTainted() {
|
||||
gui.g.Update(func(g *gocui.Gui) error {
|
||||
return nil
|
||||
})
|
||||
|
|
|
|||
|
|
@ -856,5 +856,9 @@ func addEnglish(i18nObject *i18n.Bundle) error {
|
|||
ID: "PruningStatus",
|
||||
Other: "pruning",
|
||||
},
|
||||
&i18n.Message{
|
||||
ID: "StopService",
|
||||
Other: "Are you sure you want to stop this service's containers? (enter/esc)",
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue