Skip to content

Commit 22e16bf

Browse files
committed
feat(better modals + ssh contexsts)
1 parent 6d8ae98 commit 22e16bf

30 files changed

Lines changed: 2470 additions & 395 deletions

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ require (
1111
github.com/guptarohit/asciigraph v0.7.3
1212
github.com/lucasb-eyer/go-colorful v1.3.0
1313
github.com/rivo/tview v0.42.0
14-
golang.org/x/net v0.47.0
14+
golang.org/x/net v0.55.0
1515
gopkg.in/yaml.v3 v3.0.1
1616
)
1717

@@ -48,9 +48,9 @@ require (
4848
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect
4949
go.opentelemetry.io/otel/metric v1.39.0 // indirect
5050
go.opentelemetry.io/otel/trace v1.39.0 // indirect
51-
golang.org/x/sys v0.40.0 // indirect
52-
golang.org/x/term v0.39.0 // indirect
53-
golang.org/x/text v0.33.0 // indirect
51+
golang.org/x/sys v0.46.0 // indirect
52+
golang.org/x/term v0.44.0 // indirect
53+
golang.org/x/text v0.38.0 // indirect
5454
golang.org/x/time v0.14.0 // indirect
5555
)
5656

go.sum

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
129129
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
130130
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
131131
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
132-
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
133-
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
132+
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
133+
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
134134
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
135135
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
136136
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -141,20 +141,20 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
141141
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
142142
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
143143
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
144-
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
145-
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
144+
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
145+
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
146146
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
147147
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
148148
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
149-
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
150-
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
149+
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
150+
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
151151
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
152152
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
153153
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
154154
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
155155
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
156-
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
157-
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
156+
golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
157+
golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4=
158158
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
159159
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
160160
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

internal/dao/compose/compose.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ func (m *Manager) List() ([]common.Resource, error) {
124124
continue
125125
}
126126

127+
projects[proj].total++
127128
switch c.State {
128129
case "running":
129130
projects[proj].running++
@@ -132,11 +133,6 @@ func (m *Manager) List() ([]common.Resource, error) {
132133
}
133134
}
134135

135-
for name, data := range projects {
136-
total := m.countServices(name, data.configPaths)
137-
data.total = total - data.jobs
138-
}
139-
140136
var res []common.Resource
141137
for name, data := range projects {
142138
status := "Ready"

internal/dao/docker.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ type DockerClient struct {
9999
// Guard against concurrent async refreshes
100100
refreshMu sync.Mutex
101101
refreshing map[string]bool
102+
103+
// Cached SSH context check
104+
isSSHOnce sync.Once
105+
isSSH bool
102106
}
103107

104108
func NewDockerClient(contextName string, apiTimeout time.Duration, defaultContext string) (*DockerClient, error) {
@@ -638,6 +642,22 @@ func (d *DockerClient) CreateContext(name, description, host string) error {
638642
return nil
639643
}
640644

645+
func (d *DockerClient) UpdateContext(name, description, host string) error {
646+
args := []string{"context", "update", name}
647+
if description != "" {
648+
args = append(args, "--description", description)
649+
}
650+
if host != "" {
651+
args = append(args, "--docker", fmt.Sprintf("host=%s", host))
652+
}
653+
cmd := exec.Command("docker", args...)
654+
output, err := cmd.CombinedOutput()
655+
if err != nil {
656+
return fmt.Errorf("error updating context: %v, output: %s", err, string(output))
657+
}
658+
return nil
659+
}
660+
641661
func (d *DockerClient) ListPlugins() ([]PluginInfo, error) {
642662
cmd := exec.Command("docker", "plugin", "ls", "--format", "{{json .}}")
643663
output, err := cmd.CombinedOutput()
@@ -956,6 +976,99 @@ func (d *DockerClient) ListVolumesForContainer(id string) ([]common.Resource, er
956976
return result, nil
957977
}
958978

979+
func (d *DockerClient) IsSSHContext() bool {
980+
d.isSSHOnce.Do(func() {
981+
ctxList, err := ListContexts()
982+
if err != nil {
983+
return
984+
}
985+
for _, c := range ctxList {
986+
if c.Name == d.ContextName {
987+
d.isSSH = strings.HasPrefix(c.DockerEndpoint, "ssh://")
988+
return
989+
}
990+
}
991+
})
992+
return d.isSSH
993+
}
994+
995+
func (d *DockerClient) GetSSHHost() string {
996+
ctxList, err := ListContexts()
997+
if err != nil {
998+
return ""
999+
}
1000+
for _, c := range ctxList {
1001+
if c.Name == d.ContextName {
1002+
host := strings.TrimPrefix(c.DockerEndpoint, "ssh://")
1003+
return host
1004+
}
1005+
}
1006+
return ""
1007+
}
1008+
1009+
type ContainerPortInfo struct {
1010+
ContainerPort uint16
1011+
HostPort uint16
1012+
Protocol string
1013+
IP string
1014+
}
1015+
1016+
func (d *DockerClient) GetContainerIP(id string) (string, error) {
1017+
cj, err := d.Cli.ContainerInspect(d.Ctx, id)
1018+
if err != nil {
1019+
return "", err
1020+
}
1021+
if cj.NetworkSettings == nil {
1022+
return "", fmt.Errorf("no network settings for container %s", id)
1023+
}
1024+
for _, n := range cj.NetworkSettings.Networks {
1025+
if n.IPAddress != "" {
1026+
return n.IPAddress, nil
1027+
}
1028+
}
1029+
return "", fmt.Errorf("no IP found for container %s", id)
1030+
}
1031+
1032+
func (d *DockerClient) GetContainerPorts(id string) ([]ContainerPortInfo, error) {
1033+
cj, err := d.Cli.ContainerInspect(d.Ctx, id)
1034+
if err != nil {
1035+
return nil, err
1036+
}
1037+
1038+
var ports []ContainerPortInfo
1039+
1040+
if cj.NetworkSettings != nil {
1041+
for port, bindings := range cj.NetworkSettings.Ports {
1042+
cp := ContainerPortInfo{
1043+
ContainerPort: uint16(port.Int()),
1044+
Protocol: port.Proto(),
1045+
}
1046+
if len(bindings) > 0 {
1047+
cp.HostPort = parsePort(bindings[0].HostPort)
1048+
cp.IP = bindings[0].HostIP
1049+
}
1050+
ports = append(ports, cp)
1051+
}
1052+
}
1053+
1054+
if len(ports) == 0 && cj.Config != nil {
1055+
for port := range cj.Config.ExposedPorts {
1056+
ports = append(ports, ContainerPortInfo{
1057+
ContainerPort: uint16(port.Int()),
1058+
Protocol: port.Proto(),
1059+
})
1060+
}
1061+
}
1062+
1063+
return ports, nil
1064+
}
1065+
1066+
func parsePort(s string) uint16 {
1067+
var p int
1068+
fmt.Sscanf(s, "%d", &p)
1069+
return uint16(p)
1070+
}
1071+
9591072
func (d *DockerClient) ListNetworksForContainer(id string) ([]common.Resource, error) {
9601073
// 1. Get container network info (cache first, API fallback)
9611074
d.cacheMu.RLock()

0 commit comments

Comments
 (0)