70 lines
1.5 KiB
Go
70 lines
1.5 KiB
Go
|
package versions
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/docker/docker/api/types"
|
||
|
"github.com/docker/docker/client"
|
||
|
)
|
||
|
|
||
|
type Container struct {
|
||
|
id string
|
||
|
Names []string `json:"names"`
|
||
|
ImageTags []string `json:"images"`
|
||
|
ImageDigests []string `json:"digests"`
|
||
|
}
|
||
|
|
||
|
type VersionMonitor struct {
|
||
|
ctx context.Context
|
||
|
dockerClt client.ContainerAPIClient
|
||
|
imageClt client.ImageAPIClient
|
||
|
}
|
||
|
|
||
|
func (m *VersionMonitor) buildContainerDetails(c types.Container) (Container, error) {
|
||
|
var res Container
|
||
|
|
||
|
details, _, err := m.imageClt.ImageInspectWithRaw(m.ctx, c.Image)
|
||
|
if err != nil {
|
||
|
return res, fmt.Errorf("failed to inspect container %s: %w", c.ID, err)
|
||
|
}
|
||
|
return Container{
|
||
|
id: c.ID,
|
||
|
Names: c.Names,
|
||
|
ImageTags: details.RepoTags,
|
||
|
ImageDigests: details.RepoDigests,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
func (m *VersionMonitor) GetRunningContainers() ([]Container, error) {
|
||
|
containers, err := m.dockerClt.ContainerList(m.ctx, types.ContainerListOptions{})
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("failed to get list of running containers: %w", err)
|
||
|
}
|
||
|
|
||
|
res := []Container{}
|
||
|
|
||
|
for _, c := range containers {
|
||
|
detailedContainer, err := m.buildContainerDetails(c)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("failed to get details for container %s: %w", c.ID, err)
|
||
|
}
|
||
|
res = append(res, detailedContainer)
|
||
|
}
|
||
|
|
||
|
return res, nil
|
||
|
}
|
||
|
|
||
|
func New(ctx context.Context) *VersionMonitor {
|
||
|
clt, err := client.NewClientWithOpts(client.FromEnv)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
return &VersionMonitor{
|
||
|
ctx: ctx,
|
||
|
dockerClt: clt,
|
||
|
imageClt: clt,
|
||
|
}
|
||
|
}
|