From 07d6f361595479deef19f27b779a11a34efd36df Mon Sep 17 00:00:00 2001 From: yusing Date: Sun, 17 Aug 2025 01:47:58 +0800 Subject: [PATCH] feat(docker): include full labels, mountpoints and image details --- go.mod | 1 + go.sum | 2 ++ internal/docker/container.go | 8 ++++++-- internal/docker/container_helper.go | 15 ++++++++++----- internal/types/docker.go | 14 +++++++++----- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index fc2aa107..cc5edeea 100644 --- a/go.mod +++ b/go.mod @@ -226,6 +226,7 @@ require ( github.com/swaggo/files v1.0.1 github.com/swaggo/gin-swagger v1.6.0 github.com/swaggo/swag v1.16.6 + github.com/yusing/ds v0.1.0 ) require ( diff --git a/go.sum b/go.sum index b45bc8f4..42cf92e5 100644 --- a/go.sum +++ b/go.sum @@ -1745,6 +1745,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusing/ds v0.1.0 h1:aiZs7jPMN3MEChUsddMYjpZFHhhAmkxrwRyIUnGy5AU= +github.com/yusing/ds v0.1.0/go.mod h1:KC785+mtt+Bau0LLR+slExDaUjeiqLT1k9Or6Rpryh4= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= diff --git a/internal/docker/container.go b/internal/docker/container.go index cb2624ae..11472d75 100644 --- a/internal/docker/container.go +++ b/internal/docker/container.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "maps" "net" "net/url" "strconv" @@ -26,6 +27,8 @@ var ( ) func FromDocker(c *container.Summary, dockerHost string) (res *types.Container) { + actualLabels := maps.Clone(c.Labels) + _, isExplicit := c.Labels[LabelAliases] helper := containerHelper{c} if !isExplicit { @@ -46,7 +49,8 @@ func FromDocker(c *container.Summary, dockerHost string) (res *types.Container) ContainerName: helper.getName(), ContainerID: c.ID, - Labels: c.Labels, + Labels: c.Labels, + ActualLabels: actualLabels, Mounts: helper.getMounts(), @@ -136,7 +140,7 @@ var databaseMPs = map[string]struct{}{ } func isDatabase(c *types.Container) bool { - for _, m := range c.Mounts { + for _, m := range c.Mounts.Iter { if _, ok := databaseMPs[m]; ok { return true } diff --git a/internal/docker/container_helper.go b/internal/docker/container_helper.go index c311ef44..34fe1e49 100644 --- a/internal/docker/container_helper.go +++ b/internal/docker/container_helper.go @@ -4,6 +4,7 @@ import ( "strings" "github.com/docker/docker/api/types/container" + "github.com/yusing/ds/ordered" "github.com/yusing/go-proxy/internal/types" "github.com/yusing/go-proxy/internal/utils/strutils" ) @@ -33,10 +34,10 @@ func (c containerHelper) getName() string { return strings.TrimPrefix(c.Names[0], "/") } -func (c containerHelper) getMounts() []string { - m := make([]string, len(c.Mounts)) - for i, v := range c.Mounts { - m[i] = v.Destination +func (c containerHelper) getMounts() *ordered.Map[string, string] { + m := ordered.NewMap[string, string](ordered.WithCapacity(len(c.Mounts))) + for _, v := range c.Mounts { + m.Set(v.Source, v.Destination) } return m } @@ -44,7 +45,11 @@ func (c containerHelper) getMounts() []string { func (c containerHelper) parseImage() *types.ContainerImage { colonSep := strutils.SplitRune(c.Image, ':') slashSep := strutils.SplitRune(colonSep[0], '/') - im := new(types.ContainerImage) + _, sha256, _ := strings.Cut(c.ImageID, ":") + im := &types.ContainerImage{ + SHA256: sha256, + Version: c.Labels["org.opencontainers.image.version"], + } if len(slashSep) > 1 { im.Author = strings.Join(slashSep[:len(slashSep)-1], "/") im.Name = slashSep[len(slashSep)-1] diff --git a/internal/types/docker.go b/internal/types/docker.go index 866cd223..f61fc9e3 100644 --- a/internal/types/docker.go +++ b/internal/types/docker.go @@ -4,6 +4,7 @@ import ( "encoding/json" "github.com/docker/docker/api/types/container" + "github.com/yusing/ds/ordered" "github.com/yusing/go-proxy/agent/pkg/agent" "github.com/yusing/go-proxy/internal/gperr" "github.com/yusing/go-proxy/internal/utils" @@ -23,10 +24,11 @@ type ( Agent *agent.AgentConfig `json:"agent"` - Labels map[string]string `json:"-"` + Labels map[string]string `json:"-"` // for creating routes + ActualLabels map[string]string `json:"labels"` // for displaying in UI IdlewatcherConfig *IdlewatcherConfig `json:"idlewatcher_config"` - Mounts []string `json:"mounts"` + Mounts *ordered.Map[string, string] `json:"mounts,omitempty" swaggertype:"object,string"` // source:destination Network string `json:"network,omitempty"` PublicPortMapping PortMapping `json:"public_ports"` // non-zero publicPort:types.Port @@ -43,9 +45,11 @@ type ( Errors *ContainerError `json:"errors" swaggertype:"string"` } // @name Container ContainerImage struct { - Author string `json:"author,omitempty"` - Name string `json:"name"` - Tag string `json:"tag,omitempty"` + Author string `json:"author,omitempty"` + Name string `json:"name"` + Tag string `json:"tag,omitempty"` + SHA256 string `json:"sha256,omitempty"` + Version string `json:"version,omitempty"` } // @name ContainerImage ContainerError struct {