diff --git a/pkg/commands/docker.go b/pkg/commands/docker.go index 9b4e825f..2433162b 100644 --- a/pkg/commands/docker.go +++ b/pkg/commands/docker.go @@ -15,6 +15,7 @@ import ( "github.com/acarl005/stripansi" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/filters" "github.com/docker/docker/client" "github.com/imdario/mergo" "github.com/jesseduffield/lazydocker/pkg/commands/ssh" @@ -40,6 +41,7 @@ type DockerCommand struct { ErrorChan chan error ContainerMutex sync.Mutex ServiceMutex sync.Mutex + ImageMutex sync.Mutex Services []*Service Containers []*Container // DisplayContainers is the array of containers we will display in the containers panel. If Gui.ShowAllContainers is false, this will only be those containers which aren't based on a service. This reduces clutter and duplication in the UI @@ -452,3 +454,53 @@ func (c *DockerCommand) DockerComposeConfig() string { } return output } + +// RefreshImages returns a slice of docker images +func (c *DockerCommand) RefreshImages() error { + c.ImageMutex.Lock() + defer c.ImageMutex.Unlock() + images, err := c.Client.ImageList(context.Background(), types.ImageListOptions{}) + if err != nil { + return err + } + + ownImages := make([]*Image, len(images)) + + for i, image := range images { + // func (cli *Client) ImageHistory(ctx context.Context, imageID string) ([]image.HistoryResponseItem, error) + + firstTag := "" + tags := image.RepoTags + if len(tags) > 0 { + firstTag = tags[0] + } + + nameParts := strings.Split(firstTag, ":") + tag := "" + name := "none" + if len(nameParts) > 1 { + tag = nameParts[len(nameParts)-1] + name = strings.Join(nameParts[:len(nameParts)-1], ":") + } + + ownImages[i] = &Image{ + ID: image.ID, + Name: name, + Tag: tag, + Image: image, + Client: c.Client, + OSCommand: c.OSCommand, + Log: c.Log, + DockerCommand: c, + } + } + + c.Images = ownImages + return nil +} + +// PruneImages prunes images +func (c *DockerCommand) PruneImages() error { + _, err := c.Client.ImagesPrune(context.Background(), filters.Args{}) + return err +} diff --git a/pkg/commands/image.go b/pkg/commands/image.go index fb8cee76..c5e3b797 100644 --- a/pkg/commands/image.go +++ b/pkg/commands/image.go @@ -2,11 +2,11 @@ package commands import ( "context" - "github.com/docker/docker/api/types/image" "strings" + "github.com/docker/docker/api/types/image" + "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/filters" "github.com/docker/docker/client" "github.com/fatih/color" "github.com/jesseduffield/lazydocker/pkg/utils" @@ -100,50 +100,3 @@ func (i *Image) RenderHistory() (string, error) { return utils.RenderList(layers, utils.WithHeader([]string{"ID", "TAG", "SIZE", "COMMAND"})) } - -// RefreshImages returns a slice of docker images -func (c *DockerCommand) RefreshImages() ([]*Image, error) { - images, err := c.Client.ImageList(context.Background(), types.ImageListOptions{}) - if err != nil { - return nil, err - } - - ownImages := make([]*Image, len(images)) - - for i, image := range images { - // func (cli *Client) ImageHistory(ctx context.Context, imageID string) ([]image.HistoryResponseItem, error) - - firstTag := "" - tags := image.RepoTags - if len(tags) > 0 { - firstTag = tags[0] - } - - nameParts := strings.Split(firstTag, ":") - tag := "" - name := "none" - if len(nameParts) > 1 { - tag = nameParts[len(nameParts)-1] - name = strings.Join(nameParts[:len(nameParts)-1], ":") - } - - ownImages[i] = &Image{ - ID: image.ID, - Name: name, - Tag: tag, - Image: image, - Client: c.Client, - OSCommand: c.OSCommand, - Log: c.Log, - DockerCommand: c, - } - } - - return ownImages, nil -} - -// PruneImages prunes images -func (c *DockerCommand) PruneImages() error { - _, err := c.Client.ImagesPrune(context.Background(), filters.Args{}) - return err -} diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index fad2864d..9d1e5085 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -246,6 +246,7 @@ func (gui *Gui) Run() error { gui.goEvery(time.Millisecond*30, gui.reRenderMain) gui.goEvery(dockerRefreshInterval, gui.refreshProject) gui.goEvery(dockerRefreshInterval, gui.refreshContainersAndServices) + gui.goEvery(time.Millisecond*30000, gui.refreshImages) gui.goEvery(dockerRefreshInterval, gui.refreshVolumes) gui.goEvery(time.Millisecond*1000, gui.DockerCommand.UpdateContainerDetails) gui.goEvery(time.Millisecond*1000, gui.checkForContextChange) diff --git a/pkg/gui/images_panel.go b/pkg/gui/images_panel.go index 878ce1ac..ae23da43 100644 --- a/pkg/gui/images_panel.go +++ b/pkg/gui/images_panel.go @@ -105,7 +105,7 @@ func (gui *Gui) refreshImages() error { // if the ImagesView hasn't been instantiated yet we just return return nil } - if err := gui.refreshStateImages(); err != nil { + if err := gui.DockerCommand.RefreshImages(); err != nil { return err } @@ -135,18 +135,6 @@ func (gui *Gui) refreshImages() error { return nil } -// TODO: leave this to DockerCommand -func (gui *Gui) refreshStateImages() error { - Images, err := gui.DockerCommand.RefreshImages() - if err != nil { - return err - } - - gui.DockerCommand.Images = Images - - return nil -} - func (gui *Gui) handleImagesNextLine(g *gocui.Gui, v *gocui.View) error { if gui.popupPanelFocused() || gui.g.CurrentView() != v { return nil diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index d7a327d4..9495e1cb 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -12,9 +12,9 @@ import ( 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 { - return err - } + // if err := gui.refreshImages(); err != nil { + // return err + // } return nil }