From ebcedb2a67b9f69bd52f3cb9a231fcce64a7a279 Mon Sep 17 00:00:00 2001 From: Amir Raminfar Date: Thu, 10 Apr 2025 16:31:23 -0700 Subject: [PATCH] chore: cleans up proto tranformation (#3791) --- internal/agent/client.go | 81 ++------------------------------ internal/agent/server.go | 72 +++------------------------- internal/container/types.go | 66 ++++++++++++++++++++++++++ internal/container/types_test.go | 25 ++++++++++ 4 files changed, 100 insertions(+), 144 deletions(-) create mode 100644 internal/container/types_test.go diff --git a/internal/agent/client.go b/internal/agent/client.go index 67a43c96..d05d2c56 100644 --- a/internal/agent/client.go +++ b/internal/agent/client.go @@ -14,7 +14,6 @@ import ( "github.com/amir20/dozzle/internal/agent/pb" "github.com/amir20/dozzle/internal/container" - "github.com/amir20/dozzle/internal/utils" "github.com/rs/zerolog/log" orderedmap "github.com/wk8/go-ordered-map/v2" "google.golang.org/grpc" @@ -253,24 +252,7 @@ func (c *Client) StreamNewContainers(ctx context.Context, containers chan<- cont return rpcErrToErr(err) } - containers <- container.Container{ - ID: resp.Container.Id, - Name: resp.Container.Name, - Image: resp.Container.Image, - Labels: resp.Container.Labels, - Group: resp.Container.Group, - Created: resp.Container.Created.AsTime(), - State: resp.Container.State, - Health: resp.Container.Health, - Host: resp.Container.Host, - Tty: resp.Container.Tty, - StartedAt: resp.Container.Started.AsTime(), - FinishedAt: resp.Container.Finished.AsTime(), - Command: resp.Container.Command, - MemoryLimit: resp.Container.MemoryLimit, - CPULimit: resp.Container.CpuLimit, - FullyLoaded: resp.Container.FullyLoaded, - } + containers <- container.FromProto(resp.Container) } } @@ -280,36 +262,7 @@ func (c *Client) FindContainer(ctx context.Context, containerID string) (contain return container.Container{}, err } - var stats []container.ContainerStat - - for _, stat := range response.Container.Stats { - stats = append(stats, container.ContainerStat{ - ID: stat.Id, - CPUPercent: stat.CpuPercent, - MemoryPercent: stat.MemoryPercent, - MemoryUsage: stat.MemoryUsage, - }) - } - - return container.Container{ - ID: response.Container.Id, - Name: response.Container.Name, - Image: response.Container.Image, - Labels: response.Container.Labels, - Group: response.Container.Group, - Created: response.Container.Created.AsTime(), - State: response.Container.State, - Health: response.Container.Health, - Host: response.Container.Host, - Tty: response.Container.Tty, - Command: response.Container.Command, - StartedAt: response.Container.Started.AsTime(), - FinishedAt: response.Container.Finished.AsTime(), - Stats: utils.RingBufferFrom(300, stats), - MemoryLimit: response.Container.MemoryLimit, - CPULimit: response.Container.CpuLimit, - FullyLoaded: response.Container.FullyLoaded, - }, nil + return container.FromProto(response.Container), nil } func (c *Client) ListContainers(ctx context.Context, labels container.ContainerLabels) ([]container.Container, error) { @@ -329,35 +282,7 @@ func (c *Client) ListContainers(ctx context.Context, labels container.ContainerL containers := make([]container.Container, 0) for _, c := range response.Containers { - var stats []container.ContainerStat - for _, stat := range c.Stats { - stats = append(stats, container.ContainerStat{ - ID: stat.Id, - CPUPercent: stat.CpuPercent, - MemoryPercent: stat.MemoryPercent, - MemoryUsage: stat.MemoryUsage, - }) - } - - containers = append(containers, container.Container{ - ID: c.Id, - Name: c.Name, - Image: c.Image, - Labels: c.Labels, - Group: c.Group, - Created: c.Created.AsTime(), - State: c.State, - Health: c.Health, - Host: c.Host, - Tty: c.Tty, - Command: c.Command, - StartedAt: c.Started.AsTime(), - FinishedAt: c.Finished.AsTime(), - Stats: utils.RingBufferFrom(300, stats), - MemoryLimit: c.MemoryLimit, - CPULimit: c.CpuLimit, - FullyLoaded: c.FullyLoaded, - }) + containers = append(containers, container.FromProto(c)) } return containers, nil diff --git a/internal/agent/server.go b/internal/agent/server.go index ce662739..611c6d5f 100644 --- a/internal/agent/server.go +++ b/internal/agent/server.go @@ -189,26 +189,9 @@ func (s *server) FindContainer(ctx context.Context, in *pb.FindContainerRequest) if err != nil { return nil, status.Error(codes.NotFound, err.Error()) } - + c := container.ToProto() return &pb.FindContainerResponse{ - Container: &pb.Container{ - Id: container.ID, - Name: container.Name, - Image: container.Image, - Command: container.Command, - Created: timestamppb.New(container.Created), - State: container.State, - Health: container.Health, - Host: container.Host, - Tty: container.Tty, - Labels: container.Labels, - Group: container.Group, - Started: timestamppb.New(container.StartedAt), - Finished: timestamppb.New(container.FinishedAt), - MemoryLimit: container.MemoryLimit, - CpuLimit: container.CPULimit, - FullyLoaded: container.FullyLoaded, - }, + Container: &c, }, nil } @@ -226,37 +209,9 @@ func (s *server) ListContainers(ctx context.Context, in *pb.ListContainersReques } var pbContainers []*pb.Container - for _, container := range containers { - var pbStats []*pb.ContainerStat - for _, stat := range container.Stats.Data() { - pbStats = append(pbStats, &pb.ContainerStat{ - Id: stat.ID, - CpuPercent: stat.CPUPercent, - MemoryPercent: stat.MemoryPercent, - MemoryUsage: stat.MemoryUsage, - }) - } - - pbContainers = append(pbContainers, &pb.Container{ - Id: container.ID, - Name: container.Name, - Image: container.Image, - Created: timestamppb.New(container.Created), - State: container.State, - Health: container.Health, - Host: container.Host, - Tty: container.Tty, - Labels: container.Labels, - Group: container.Group, - Started: timestamppb.New(container.StartedAt), - Finished: timestamppb.New(container.FinishedAt), - Stats: pbStats, - Command: container.Command, - MemoryLimit: container.MemoryLimit, - CpuLimit: container.CPULimit, - FullyLoaded: container.FullyLoaded, - }) + c := container.ToProto() + pbContainers = append(pbContainers, &c) } return &pb.ListContainersResponse{ @@ -286,24 +241,9 @@ func (s *server) StreamContainerStarted(in *pb.StreamContainerStartedRequest, ou for { select { case container := <-containers: + c := container.ToProto() out.Send(&pb.StreamContainerStartedResponse{ - Container: &pb.Container{ - Id: container.ID, - Name: container.Name, - Image: container.Image, - Created: timestamppb.New(container.Created), - State: container.State, - Health: container.Health, - Host: container.Host, - Tty: container.Tty, - Labels: container.Labels, - Group: container.Group, - Started: timestamppb.New(container.StartedAt), - Finished: timestamppb.New(container.FinishedAt), - MemoryLimit: container.MemoryLimit, - CpuLimit: container.CPULimit, - FullyLoaded: container.FullyLoaded, - }, + Container: &c, }) case <-out.Context().Done(): return nil diff --git a/internal/container/types.go b/internal/container/types.go index bcdf4164..17ac3a06 100644 --- a/internal/container/types.go +++ b/internal/container/types.go @@ -6,7 +6,9 @@ import ( "strings" "time" + "github.com/amir20/dozzle/internal/agent/pb" "github.com/amir20/dozzle/internal/utils" + "google.golang.org/protobuf/types/known/timestamppb" ) // Container represents an internal representation of docker containers @@ -30,6 +32,70 @@ type Container struct { FullyLoaded bool `json:"-,omitempty"` } +func (container Container) ToProto() pb.Container { + var pbStats []*pb.ContainerStat + for _, stat := range container.Stats.Data() { + pbStats = append(pbStats, &pb.ContainerStat{ + Id: stat.ID, + CpuPercent: stat.CPUPercent, + MemoryPercent: stat.MemoryPercent, + MemoryUsage: stat.MemoryUsage, + }) + } + + return pb.Container{ + Id: container.ID, + Name: container.Name, + Image: container.Image, + Created: timestamppb.New(container.Created), + State: container.State, + Health: container.Health, + Host: container.Host, + Tty: container.Tty, + Labels: container.Labels, + Group: container.Group, + Started: timestamppb.New(container.StartedAt), + Finished: timestamppb.New(container.FinishedAt), + Stats: pbStats, + Command: container.Command, + MemoryLimit: container.MemoryLimit, + CpuLimit: container.CPULimit, + FullyLoaded: container.FullyLoaded, + } +} + +func FromProto(c *pb.Container) Container { + var stats []ContainerStat + for _, stat := range c.Stats { + stats = append(stats, ContainerStat{ + ID: stat.Id, + CPUPercent: stat.CpuPercent, + MemoryPercent: stat.MemoryPercent, + MemoryUsage: stat.MemoryUsage, + }) + } + + return Container{ + ID: c.Id, + Name: c.Name, + Image: c.Image, + Labels: c.Labels, + Group: c.Group, + Created: c.Created.AsTime(), + State: c.State, + Health: c.Health, + Host: c.Host, + Tty: c.Tty, + Command: c.Command, + StartedAt: c.Started.AsTime(), + FinishedAt: c.Finished.AsTime(), + Stats: utils.RingBufferFrom(300, stats), + MemoryLimit: c.MemoryLimit, + CPULimit: c.CpuLimit, + FullyLoaded: c.FullyLoaded, + } +} + // ContainerStat represent stats instant for a container type ContainerStat struct { ID string `json:"id"` diff --git a/internal/container/types_test.go b/internal/container/types_test.go new file mode 100644 index 00000000..b53ab470 --- /dev/null +++ b/internal/container/types_test.go @@ -0,0 +1,25 @@ +package container + +import ( + "testing" + + "github.com/amir20/dozzle/internal/utils" + "github.com/go-faker/faker/v4" + "github.com/go-faker/faker/v4/pkg/options" + "github.com/stretchr/testify/assert" +) + +func TestProto(t *testing.T) { + expected := Container{} + faker.FakeData(&expected, options.WithFieldsToIgnore("Stats")) + expected.FinishedAt = expected.FinishedAt.UTC() + expected.Created = expected.Created.UTC() + expected.StartedAt = expected.StartedAt.UTC() + expected.Stats = utils.NewRingBuffer[ContainerStat](300) + + pb := expected.ToProto() + actual := FromProto(&pb) + + assert.Equal(t, expected, actual) + +}