move common api types to api package

This commit is contained in:
Pavel Sviderski
2024-12-05 15:17:36 +10:00
parent 88ce2d5181
commit 3ac166e6cb
7 changed files with 80 additions and 83 deletions
@@ -1,4 +1,4 @@
package service package api
import ( import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@@ -12,7 +12,6 @@ const (
LabelServiceMode = "uncloud.service.mode" LabelServiceMode = "uncloud.service.mode"
) )
// TODO: move to api package.
type Container struct { type Container struct {
types.Container types.Container
} }
@@ -1,4 +1,4 @@
package service package api
import ( import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
+46 -3
View File
@@ -1,5 +1,11 @@
package api package api
import (
"encoding/json"
"fmt"
"uncloud/internal/machine/api/pb"
)
const ( const (
ServiceModeReplicated = "replicated" ServiceModeReplicated = "replicated"
ServiceModeGlobal = "global" ServiceModeGlobal = "global"
@@ -19,7 +25,44 @@ type ContainerSpec struct {
Init *bool Init *bool
} }
type MachineContainerID struct { type Service struct {
MachineID string ID string
ContainerID string Name string
Mode string
Containers []MachineContainer
}
type MachineContainer struct {
MachineID string
Container Container
}
func ServiceFromProto(s *pb.Service) (Service, error) {
var err error
containers := make([]MachineContainer, len(s.Containers))
for i, sc := range s.Containers {
containers[i], err = machineContainerFromProto(sc)
if err != nil {
return Service{}, err
}
}
return Service{
ID: s.Id,
Name: s.Name,
Mode: s.Mode,
Containers: containers,
}, nil
}
func machineContainerFromProto(sc *pb.Service_Container) (MachineContainer, error) {
var c Container
if err := json.Unmarshal(sc.Container, &c); err != nil {
return MachineContainer{}, fmt.Errorf("unmarshal container: %w", err)
}
return MachineContainer{
MachineID: sc.MachineId,
Container: c,
}, nil
} }
+24 -20
View File
@@ -19,7 +19,6 @@ import (
"uncloud/internal/machine/api/pb" "uncloud/internal/machine/api/pb"
machinedocker "uncloud/internal/machine/docker" machinedocker "uncloud/internal/machine/docker"
"uncloud/internal/secret" "uncloud/internal/secret"
"uncloud/internal/service"
) )
// ServiceOptions contains all the options for creating a service. // ServiceOptions contains all the options for creating a service.
@@ -36,7 +35,12 @@ type ServiceOptions struct {
type RunServiceResponse struct { type RunServiceResponse struct {
ID string ID string
Name string Name string
Containers []api.MachineContainerID Containers []MachineContainerID
}
type MachineContainerID struct {
MachineID string
ContainerID string
} }
func (cli *Client) RunService(ctx context.Context, spec api.ServiceSpec) (RunServiceResponse, error) { func (cli *Client) RunService(ctx context.Context, spec api.ServiceSpec) (RunServiceResponse, error) {
@@ -124,7 +128,7 @@ func (cli *Client) runReplicatedService(ctx context.Context, id string, spec api
return resp, fmt.Errorf("run container: %w", err) return resp, fmt.Errorf("run container: %w", err)
} }
resp.Containers = append(resp.Containers, api.MachineContainerID{ resp.Containers = append(resp.Containers, MachineContainerID{
MachineID: m.Machine.Id, MachineID: m.Machine.Id,
ContainerID: runResp.ID, ContainerID: runResp.ID,
}) })
@@ -152,13 +156,13 @@ func (cli *Client) runContainer(
Cmd: spec.Container.Command, Cmd: spec.Container.Command,
Image: spec.Container.Image, Image: spec.Container.Image,
Labels: map[string]string{ Labels: map[string]string{
service.LabelServiceID: serviceID, api.LabelServiceID: serviceID,
service.LabelServiceName: spec.Name, api.LabelServiceName: spec.Name,
service.LabelManaged: "", api.LabelManaged: "",
}, },
} }
if spec.Mode == api.ServiceModeGlobal { if spec.Mode == api.ServiceModeGlobal {
config.Labels[service.LabelServiceMode] = api.ServiceModeGlobal config.Labels[api.LabelServiceMode] = api.ServiceModeGlobal
} }
hostConfig := &container.HostConfig{ hostConfig := &container.HostConfig{
@@ -223,7 +227,7 @@ func (cli *Client) runGlobalService(ctx context.Context, id string, spec api.Ser
return resp, fmt.Errorf("run container: %w", err) return resp, fmt.Errorf("run container: %w", err)
} }
resp.Containers = append(resp.Containers, api.MachineContainerID{ resp.Containers = append(resp.Containers, MachineContainerID{
MachineID: m.Machine.Id, MachineID: m.Machine.Id,
ContainerID: runResp.ID, ContainerID: runResp.ID,
}) })
@@ -252,8 +256,8 @@ func firstAvailableMachine(machines []*pb.MachineMember) *pb.MachineMember {
// InspectService returns detailed information about a service and its containers. // InspectService returns detailed information about a service and its containers.
// The id parameter can be either a service ID or name. // The id parameter can be either a service ID or name.
func (cli *Client) InspectService(ctx context.Context, id string) (service.Service, error) { func (cli *Client) InspectService(ctx context.Context, id string) (api.Service, error) {
var svc service.Service var svc api.Service
machines, err := cli.ListMachines(ctx) machines, err := cli.ListMachines(ctx)
if err != nil { if err != nil {
@@ -278,8 +282,8 @@ func (cli *Client) InspectService(ctx context.Context, id string) (service.Servi
opts := container.ListOptions{ opts := container.ListOptions{
All: true, All: true,
Filters: filters.NewArgs( Filters: filters.NewArgs(
filters.Arg("label", service.LabelServiceID), filters.Arg("label", api.LabelServiceID),
filters.Arg("label", service.LabelManaged), filters.Arg("label", api.LabelManaged),
), ),
} }
machineContainers, err := cli.ListContainers(listCtx, opts) machineContainers, err := cli.ListContainers(listCtx, opts)
@@ -289,7 +293,7 @@ func (cli *Client) InspectService(ctx context.Context, id string) (service.Servi
// Collect all containers on all machines that belong to the specified service. // Collect all containers on all machines that belong to the specified service.
foundByID := false foundByID := false
var containers []service.MachineContainer var containers []api.MachineContainer
for _, mc := range machineContainers { for _, mc := range machineContainers {
// Metadata can be nil if the request was broadcasted to only one machine. // Metadata can be nil if the request was broadcasted to only one machine.
if mc.Metadata == nil && len(machineContainers) > 1 { if mc.Metadata == nil && len(machineContainers) > 1 {
@@ -318,9 +322,9 @@ func (cli *Client) InspectService(ctx context.Context, id string) (service.Servi
} }
for _, c := range mc.Containers { for _, c := range mc.Containers {
ctr := service.Container{Container: c} ctr := api.Container{Container: c}
if ctr.ServiceID() == id || ctr.ServiceName() == id { if ctr.ServiceID() == id || ctr.ServiceName() == id {
containers = append(containers, service.MachineContainer{ containers = append(containers, api.MachineContainer{
MachineID: machineID, MachineID: machineID,
Container: ctr, Container: ctr,
}) })
@@ -340,7 +344,7 @@ func (cli *Client) InspectService(ctx context.Context, id string) (service.Servi
// may not prevent this), or a service name might match another service's ID. In these cases, matching by ID takes // may not prevent this), or a service name might match another service's ID. In these cases, matching by ID takes
// priority over matching by name. // priority over matching by name.
if foundByID { if foundByID {
containers = slices.DeleteFunc(containers, func(mc service.MachineContainer) bool { containers = slices.DeleteFunc(containers, func(mc api.MachineContainer) bool {
return mc.Container.ServiceID() != id return mc.Container.ServiceID() != id
}) })
} else { } else {
@@ -353,7 +357,7 @@ func (cli *Client) InspectService(ctx context.Context, id string) (service.Servi
} }
} }
svc = service.Service{ svc = api.Service{
ID: containers[0].Container.ServiceID(), ID: containers[0].Container.ServiceID(),
Name: containers[0].Container.ServiceName(), Name: containers[0].Container.ServiceName(),
Mode: containers[0].Container.ServiceMode(), Mode: containers[0].Container.ServiceMode(),
@@ -369,8 +373,8 @@ func (cli *Client) InspectService(ctx context.Context, id string) (service.Servi
// InspectServiceFromStore returns detailed information about a service and its containers from the distributed store. // InspectServiceFromStore returns detailed information about a service and its containers from the distributed store.
// Due to eventual consistency of the store, the returned information may not reflect the most recent changes. // Due to eventual consistency of the store, the returned information may not reflect the most recent changes.
// The id parameter can be either a service ID or name. // The id parameter can be either a service ID or name.
func (cli *Client) InspectServiceFromStore(ctx context.Context, id string) (service.Service, error) { func (cli *Client) InspectServiceFromStore(ctx context.Context, id string) (api.Service, error) {
var svc service.Service var svc api.Service
resp, err := cli.MachineClient.InspectService(ctx, &pb.InspectServiceRequest{Id: id}) resp, err := cli.MachineClient.InspectService(ctx, &pb.InspectServiceRequest{Id: id})
if err != nil { if err != nil {
@@ -382,7 +386,7 @@ func (cli *Client) InspectServiceFromStore(ctx context.Context, id string) (serv
return svc, err return svc, err
} }
svc, err = service.FromProto(resp.Service) svc, err = api.ServiceFromProto(resp.Service)
if err != nil { if err != nil {
return svc, fmt.Errorf("from proto: %w", err) return svc, fmt.Errorf("from proto: %w", err)
} }
+4 -4
View File
@@ -10,8 +10,8 @@ import (
"github.com/docker/docker/client" "github.com/docker/docker/client"
"log/slog" "log/slog"
"time" "time"
"uncloud/internal/api"
"uncloud/internal/machine/store" "uncloud/internal/machine/store"
"uncloud/internal/service"
) )
const ( const (
@@ -152,8 +152,8 @@ func (m *Manager) syncContainersToStore(ctx context.Context) error {
// List only Uncloud service containers identified by their labels. // List only Uncloud service containers identified by their labels.
containers, err := m.client.ContainerList(ctx, dockercontainer.ListOptions{ containers, err := m.client.ContainerList(ctx, dockercontainer.ListOptions{
Filters: filters.NewArgs( Filters: filters.NewArgs(
filters.Arg("label", service.LabelServiceID), filters.Arg("label", api.LabelServiceID),
filters.Arg("label", service.LabelServiceName), filters.Arg("label", api.LabelServiceName),
), ),
}) })
if err != nil { if err != nil {
@@ -185,7 +185,7 @@ func (m *Manager) syncContainersToStore(ctx context.Context) error {
// Create or update the current Docker containers in the store. // Create or update the current Docker containers in the store.
for _, dc := range containers { for _, dc := range containers {
c := &service.Container{Container: dc} c := &api.Container{Container: dc}
if err = m.store.CreateOrUpdateContainer(ctx, c, m.machineID); err != nil { if err = m.store.CreateOrUpdateContainer(ctx, c, m.machineID); err != nil {
storeErr = errors.Join(storeErr, fmt.Errorf("create or update container %q: %w", c.ID, err)) storeErr = errors.Join(storeErr, fmt.Errorf("create or update container %q: %w", c.ID, err))
} }
+4 -4
View File
@@ -8,7 +8,7 @@ import (
"log/slog" "log/slog"
"strings" "strings"
"time" "time"
"uncloud/internal/service" "uncloud/internal/api"
) )
const ( const (
@@ -22,7 +22,7 @@ const (
) )
type ContainerRecord struct { type ContainerRecord struct {
Container *service.Container Container *api.Container
MachineID string MachineID string
SyncStatus string SyncStatus string
UpdatedAt time.Time UpdatedAt time.Time
@@ -47,7 +47,7 @@ type DeleteOptions struct {
// CreateOrUpdateContainer creates a new container record or updates an existing one in the store database. // CreateOrUpdateContainer creates a new container record or updates an existing one in the store database.
// The container is associated with the given machine ID that indicates which machine the container is running on. // The container is associated with the given machine ID that indicates which machine the container is running on.
func (s *Store) CreateOrUpdateContainer(ctx context.Context, c *service.Container, machineID string) error { func (s *Store) CreateOrUpdateContainer(ctx context.Context, c *api.Container, machineID string) error {
cJSON, err := json.Marshal(c) cJSON, err := json.Marshal(c)
if err != nil { if err != nil {
return fmt.Errorf("marshal container: %w", err) return fmt.Errorf("marshal container: %w", err)
@@ -113,7 +113,7 @@ func (s *Store) ListContainers(ctx context.Context, opts ListOptions) ([]*Contai
return nil, fmt.Errorf("scan container record: %w", err) return nil, fmt.Errorf("scan container record: %w", err)
} }
var c service.Container var c api.Container
if err = json.Unmarshal([]byte(cJSON), &c); err != nil { if err = json.Unmarshal([]byte(cJSON), &c); err != nil {
return nil, fmt.Errorf("unmarshal container: %w", err) return nil, fmt.Errorf("unmarshal container: %w", err)
} }
-49
View File
@@ -1,49 +0,0 @@
package service
import (
"encoding/json"
"fmt"
"uncloud/internal/machine/api/pb"
)
type Service struct {
ID string
Name string
Mode string
Containers []MachineContainer
}
type MachineContainer struct {
MachineID string
Container Container
}
func FromProto(s *pb.Service) (Service, error) {
var err error
containers := make([]MachineContainer, len(s.Containers))
for i, sc := range s.Containers {
containers[i], err = machineContainerFromProto(sc)
if err != nil {
return Service{}, err
}
}
return Service{
ID: s.Id,
Name: s.Name,
Mode: s.Mode,
Containers: containers,
}, nil
}
func machineContainerFromProto(sc *pb.Service_Container) (MachineContainer, error) {
var c Container
if err := json.Unmarshal(sc.Container, &c); err != nil {
return MachineContainer{}, fmt.Errorf("unmarshal container: %w", err)
}
return MachineContainer{
MachineID: sc.MachineId,
Container: c,
}, nil
}