Skip to content

Commit b05963b

Browse files
committed
feat(add docker plugin object)
1 parent bec1686 commit b05963b

9 files changed

Lines changed: 359 additions & 6 deletions

File tree

internal/dao/docker.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"crypto/tls"
66
"crypto/x509"
7+
"encoding/json"
78
"fmt"
89
"io"
910
"log"
@@ -51,6 +52,13 @@ type Task = task.Task
5152
type ComposeProject = compose.ComposeProject
5253

5354
// Cached container info for instant scoped queries (drill-down)
55+
type PluginInfo struct {
56+
ID string
57+
Name string
58+
Description string
59+
Enabled bool
60+
}
61+
5462
type containerInfoCache struct {
5563
Mounts []mountInfoCache
5664
NetIDs map[string]bool
@@ -626,6 +634,88 @@ func (d *DockerClient) CreateContext(name, description, host string) error {
626634
return nil
627635
}
628636

637+
func (d *DockerClient) ListPlugins() ([]PluginInfo, error) {
638+
cmd := exec.Command("docker", "plugin", "ls", "--format", "{{json .}}")
639+
output, err := cmd.CombinedOutput()
640+
if err != nil {
641+
return nil, fmt.Errorf("error listing plugins: %v, output: %s", err, string(output))
642+
}
643+
644+
var plugins []PluginInfo
645+
for _, line := range strings.Split(strings.TrimSpace(string(output)), "\n") {
646+
if line == "" {
647+
continue
648+
}
649+
var p struct {
650+
ID string `json:"ID"`
651+
Name string `json:"Name"`
652+
Description string `json:"Description"`
653+
Enabled bool `json:"Enabled"`
654+
PluginReference string `json:"PluginReference"`
655+
}
656+
if err := json.Unmarshal([]byte(line), &p); err != nil {
657+
continue
658+
}
659+
plugins = append(plugins, PluginInfo{
660+
ID: p.ID,
661+
Name: p.Name,
662+
Description: p.Description,
663+
Enabled: p.Enabled,
664+
})
665+
}
666+
return plugins, nil
667+
}
668+
669+
func (d *DockerClient) InspectPlugin(name string) (string, error) {
670+
cmd := exec.Command("docker", "plugin", "inspect", name)
671+
output, err := cmd.CombinedOutput()
672+
if err != nil {
673+
return "", fmt.Errorf("error inspecting plugin: %v, output: %s", err, string(output))
674+
}
675+
return string(output), nil
676+
}
677+
678+
func (d *DockerClient) RemovePlugin(name string, force bool) error {
679+
args := []string{"plugin", "rm"}
680+
if force {
681+
args = append(args, "-f")
682+
}
683+
args = append(args, name)
684+
cmd := exec.Command("docker", args...)
685+
output, err := cmd.CombinedOutput()
686+
if err != nil {
687+
return fmt.Errorf("error removing plugin: %v, output: %s", err, string(output))
688+
}
689+
return nil
690+
}
691+
692+
func (d *DockerClient) EnablePlugin(name string) error {
693+
cmd := exec.Command("docker", "plugin", "enable", name)
694+
output, err := cmd.CombinedOutput()
695+
if err != nil {
696+
return fmt.Errorf("error enabling plugin: %v, output: %s", err, string(output))
697+
}
698+
return nil
699+
}
700+
701+
func (d *DockerClient) DisablePlugin(name string) error {
702+
cmd := exec.Command("docker", "plugin", "disable", name)
703+
output, err := cmd.CombinedOutput()
704+
if err != nil {
705+
return fmt.Errorf("error disabling plugin: %v, output: %s", err, string(output))
706+
}
707+
return nil
708+
}
709+
710+
func (d *DockerClient) InstallPlugin(name string) error {
711+
cmd := exec.Command("docker", "plugin", "install", "--grant-all-permissions", name)
712+
output, err := cmd.CombinedOutput()
713+
if err != nil {
714+
return fmt.Errorf("error installing plugin: %v, output: %s", err, string(output))
715+
}
716+
return nil
717+
}
718+
629719
func (d *DockerClient) ListTasks() ([]common.Resource, error) {
630720
return d.Task.List()
631721
}

internal/ui/app.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/jr-k/d4s/internal/ui/views/configs"
2929
"github.com/jr-k/d4s/internal/ui/views/secrets"
3030
"github.com/jr-k/d4s/internal/ui/views/contexts"
31+
"github.com/jr-k/d4s/internal/ui/views/plugins"
3132
"github.com/jr-k/d4s/internal/ui/views/stacks"
3233
"github.com/jr-k/d4s/internal/ui/views/tasks"
3334
"github.com/jr-k/d4s/internal/ui/views/services"
@@ -390,6 +391,18 @@ func (a *App) initUI() {
390391
}
391392
a.Views[styles.TitleContexts] = vContexts
392393

394+
// Plugins
395+
vPlugins := view.NewResourceView(a, styles.TitlePlugins)
396+
vPlugins.ShortcutsFunc = plugins.GetShortcuts
397+
vPlugins.FetchFunc = plugins.Fetch
398+
vPlugins.InspectFunc = plugins.Inspect
399+
vPlugins.RemoveFunc = plugins.Remove
400+
vPlugins.Headers = plugins.Headers
401+
vPlugins.InputHandler = func(event *tcell.EventKey) *tcell.EventKey {
402+
return plugins.InputHandler(vPlugins, event)
403+
}
404+
a.Views[styles.TitlePlugins] = vPlugins
405+
393406
for title, view := range a.Views {
394407
a.Pages.AddPage(title, view.Table, true, false)
395408
}
@@ -603,6 +616,8 @@ func (a *App) resolveDefaultView() string {
603616
return styles.TitleTasks
604617
case "contexts", "context":
605618
return styles.TitleContexts
619+
case "plugins", "plugin":
620+
return styles.TitlePlugins
606621
default:
607622
return styles.TitleContainers
608623
}

internal/ui/app_navigation.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ func (a *App) ExecuteCmd(cmd string) {
4949
switchToRoot(styles.TitleTasks)
5050
case "o", "ctx", "context", "contexts":
5151
switchToRoot(styles.TitleContexts)
52+
case "g", "pl", "plugin", "plugins":
53+
switchToRoot(styles.TitlePlugins)
5254
case "h", "help", "?":
5355
a.Pages.AddPage("help", a.Help, true, true)
5456
default:

internal/ui/components/command/command.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ var availableCommands = []string{
118118
"stacks",
119119
"tasks",
120120
"contexts",
121+
"plugins",
121122
"help",
122123
"aliases",
123124
"q",
@@ -132,6 +133,7 @@ var availableCommands = []string{
132133
"k",
133134
"t",
134135
"o",
136+
"g",
135137
"d",
136138
}
137139

internal/ui/dialogs/help.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ func NewHelpView(app common.AppController) tview.Primitive {
2929
{fmt.Sprintf("[%s]:c[-] Containers", k), fmt.Sprintf("[%s]:i[-] Images", k)},
3030
{fmt.Sprintf("[%s]:v[-] Volumes", k), fmt.Sprintf("[%s]:n[-] Networks", k)},
3131
{fmt.Sprintf("[%s]:p[-] Compose", k), fmt.Sprintf("[%s]:o[-] Contexts", k)},
32+
{fmt.Sprintf("[%s]:g[-] Plugins", k), ""},
3233
{"", ""},
3334
{fmt.Sprintf("[%s::b]SWARM", a), ""},
3435
{fmt.Sprintf("[%s]:d[-] Nodes", k), fmt.Sprintf("[%s]:t[-] Tasks", k)},

internal/ui/styles/styles.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ const (
139139
TitleStacks = "Stacks"
140140
TitleTasks = "Tasks"
141141
TitleContexts = "Contexts"
142+
TitlePlugins = "Plugins"
142143
)
143144

144145
// invertColor inverts a tcell.Color by flipping its lightness while preserving hue and saturation.

internal/ui/views/aliases/aliases.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ func Fetch(app common.AppController, v *view.ResourceView) ([]dao.Resource, erro
7070
{Title: styles.TitleStacks, Resource: "stacks", Group: "swarm", Shortcuts: []string{"k", "st", "stack", "stacks"}},
7171
{Title: styles.TitleTasks, Resource: "tasks", Group: "swarm", Shortcuts: []string{"t", "task", "tasks"}},
7272
{Title: styles.TitleContexts, Resource: "contexts", Group: "docker", Shortcuts: []string{"o", "ctx", "context", "contexts"}},
73+
{Title: styles.TitlePlugins, Resource: "plugins", Group: "docker", Shortcuts: []string{"g", "pl", "plugin", "plugins"}},
7374
{Title: styles.TitleCompose, Resource: "compose", Group: "compose", Shortcuts: []string{"p", "cp", "compose", "project", "projects"}},
7475
}
7576

internal/ui/views/contexts/contexts.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,18 @@ type Context struct {
2424

2525
func (c Context) GetID() string { return c.Name }
2626
func (c Context) GetCells() []string {
27-
current := ""
27+
current := "False"
2828
if c.Current {
29-
current = ""
29+
current = "True"
3030
}
3131
return []string{c.Name, current, c.Description, c.Endpoint}
3232
}
3333

3434
func (c Context) GetStatusColor() (tcell.Color, tcell.Color) {
3535
if c.Current {
36-
return styles.ColorStatusGreen, styles.ColorBlack
36+
return styles.ColorIdle, styles.ColorBlack
3737
}
38-
return styles.ColorIdle, styles.ColorBlack
38+
return styles.ColorStatusGray, styles.ColorBlack
3939
}
4040

4141
func (c Context) GetColumnValue(column string) string {
@@ -44,9 +44,9 @@ func (c Context) GetColumnValue(column string) string {
4444
return c.Name
4545
case "current":
4646
if c.Current {
47-
return ""
47+
return "True"
4848
}
49-
return ""
49+
return "False"
5050
case "description":
5151
return c.Description
5252
case "endpoint":

0 commit comments

Comments
 (0)