mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 19:13:34 +00:00
chore(images): initialise Docker service with containerd client
This commit is contained in:
@@ -14,6 +14,9 @@ require (
|
|||||||
github.com/charmbracelet/huh v0.6.0
|
github.com/charmbracelet/huh v0.6.0
|
||||||
github.com/charmbracelet/lipgloss v1.1.0
|
github.com/charmbracelet/lipgloss v1.1.0
|
||||||
github.com/compose-spec/compose-go/v2 v2.4.5
|
github.com/compose-spec/compose-go/v2 v2.4.5
|
||||||
|
github.com/containerd/containerd/v2 v2.1.1
|
||||||
|
github.com/containerd/errdefs v1.0.0
|
||||||
|
github.com/containerd/log v0.1.0
|
||||||
github.com/containerd/platforms v1.0.0-rc.1
|
github.com/containerd/platforms v1.0.0-rc.1
|
||||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
|
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
|
||||||
github.com/deckarep/golang-set/v2 v2.8.0
|
github.com/deckarep/golang-set/v2 v2.8.0
|
||||||
@@ -24,6 +27,7 @@ require (
|
|||||||
github.com/docker/docker v27.4.0-rc.2+incompatible
|
github.com/docker/docker v27.4.0-rc.2+incompatible
|
||||||
github.com/docker/go-connections v0.5.0
|
github.com/docker/go-connections v0.5.0
|
||||||
github.com/docker/go-units v0.5.0
|
github.com/docker/go-units v0.5.0
|
||||||
|
github.com/dustin/go-humanize v1.0.1
|
||||||
github.com/goccy/go-yaml v1.17.1
|
github.com/goccy/go-yaml v1.17.1
|
||||||
github.com/google/go-cmp v0.7.0
|
github.com/google/go-cmp v0.7.0
|
||||||
github.com/google/go-containerregistry v0.20.2
|
github.com/google/go-containerregistry v0.20.2
|
||||||
@@ -101,12 +105,9 @@ require (
|
|||||||
github.com/containerd/console v1.0.4 // indirect
|
github.com/containerd/console v1.0.4 // indirect
|
||||||
github.com/containerd/containerd v1.7.24 // indirect
|
github.com/containerd/containerd v1.7.24 // indirect
|
||||||
github.com/containerd/containerd/api v1.9.0 // indirect
|
github.com/containerd/containerd/api v1.9.0 // indirect
|
||||||
github.com/containerd/containerd/v2 v2.1.1 // indirect
|
|
||||||
github.com/containerd/continuity v0.4.5 // indirect
|
github.com/containerd/continuity v0.4.5 // indirect
|
||||||
github.com/containerd/errdefs v1.0.0 // indirect
|
|
||||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||||
github.com/containerd/fifo v1.1.0 // indirect
|
github.com/containerd/fifo v1.1.0 // indirect
|
||||||
github.com/containerd/log v0.1.0 // indirect
|
|
||||||
github.com/containerd/plugin v1.0.0 // indirect
|
github.com/containerd/plugin v1.0.0 // indirect
|
||||||
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
|
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
|
||||||
github.com/containerd/ttrpc v1.2.7 // indirect
|
github.com/containerd/ttrpc v1.2.7 // indirect
|
||||||
@@ -127,7 +128,6 @@ require (
|
|||||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
|
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
|
||||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
|
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
|
||||||
github.com/docker/go-metrics v0.0.1 // indirect
|
github.com/docker/go-metrics v0.0.1 // indirect
|
||||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
|
||||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||||
github.com/fatih/color v1.17.0 // indirect
|
github.com/fatih/color v1.17.0 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package containerd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/v2/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Client is a containerd client for image operations.
|
||||||
|
type Client struct {
|
||||||
|
Client *client.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient creates a new containerd client connected to the given socket path.
|
||||||
|
func NewClient(sockPath string) (*Client, error) {
|
||||||
|
if sockPath == "" {
|
||||||
|
return nil, fmt.Errorf("containerd socket path is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := client.New(
|
||||||
|
sockPath,
|
||||||
|
client.WithDefaultNamespace("moby"),
|
||||||
|
client.WithTimeout(60*time.Second),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Client{Client: c}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes the containerd client connection.
|
||||||
|
func (c *Client) Close() error {
|
||||||
|
if c.Client != nil {
|
||||||
|
return c.Client.Close()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -63,25 +63,16 @@ type Server struct {
|
|||||||
waitForNetworkReady func(ctx context.Context) error
|
waitForNetworkReady func(ctx context.Context) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerOption configures the Docker server.
|
type ServerOptions struct {
|
||||||
type ServerOption func(*Server)
|
// TODO: verify if we still need the network readiness checks as the cluster controller ensures the network
|
||||||
|
// is ready before starting the network API server. It may still be needed when communicating with the local
|
||||||
// WithNetworkReady sets the network readiness check function.
|
// API server but in this case we should probably fail until the cluster is initialised.
|
||||||
func WithNetworkReady(networkReady func() bool) ServerOption {
|
NetworkReady func() bool
|
||||||
return func(s *Server) {
|
WaitForNetworkReady func(ctx context.Context) error
|
||||||
s.networkReady = networkReady
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithWaitForNetworkReady sets the network readiness wait function.
|
|
||||||
func WithWaitForNetworkReady(waitForNetworkReady func(ctx context.Context) error) ServerOption {
|
|
||||||
return func(s *Server) {
|
|
||||||
s.waitForNetworkReady = waitForNetworkReady
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServer creates a new Docker gRPC server with the provided Docker service.
|
// NewServer creates a new Docker gRPC server with the provided Docker service.
|
||||||
func NewServer(service *Service, db *sqlx.DB, internalDNSIP func() netip.Addr, opts ...ServerOption) *Server {
|
func NewServer(service *Service, db *sqlx.DB, internalDNSIP func() netip.Addr, opts ServerOptions) *Server {
|
||||||
s := &Server{
|
s := &Server{
|
||||||
client: service.Client,
|
client: service.Client,
|
||||||
service: service,
|
service: service,
|
||||||
@@ -89,9 +80,8 @@ func NewServer(service *Service, db *sqlx.DB, internalDNSIP func() netip.Addr, o
|
|||||||
internalDNSIP: internalDNSIP,
|
internalDNSIP: internalDNSIP,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, opt := range opts {
|
s.networkReady = opts.NetworkReady
|
||||||
opt(s)
|
s.waitForNetworkReady = opts.WaitForNetworkReady
|
||||||
}
|
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
@@ -731,7 +721,9 @@ func (s *Server) injectConfigs(ctx context.Context, containerID string, configs
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copy the config content directly into the container
|
// Copy the config content directly into the container
|
||||||
if err := s.copyContentToContainer(ctx, containerID, config.Content, targetPath, uid, gid, fileMode); err != nil {
|
if err := s.copyContentToContainer(
|
||||||
|
ctx, containerID, config.Content, targetPath, uid, gid, fileMode,
|
||||||
|
); err != nil {
|
||||||
return fmt.Errorf("copy config file '%s' to container: %w", config.Name, err)
|
return fmt.Errorf("copy config file '%s' to container: %w", config.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,20 +12,26 @@ import (
|
|||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
|
"github.com/psviderski/uncloud/internal/containerd"
|
||||||
"github.com/psviderski/uncloud/pkg/api"
|
"github.com/psviderski/uncloud/pkg/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Service provides higher-level Docker operations that extends Docker API with Uncloud-specific data
|
// Service provides higher-level Docker operations that extends Docker API with Uncloud-specific data
|
||||||
// from the machine database.
|
// from the machine database.
|
||||||
type Service struct {
|
type Service struct {
|
||||||
|
// Client is a Docker client for managing Docker resources.
|
||||||
Client *client.Client
|
Client *client.Client
|
||||||
|
// containerd is a containerd client for accessing containerd images.
|
||||||
|
containerd *containerd.Client
|
||||||
|
// db is a connection to the machine database.
|
||||||
db *sqlx.DB
|
db *sqlx.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewService creates a new Docker service instance.
|
// NewService creates a new Docker service instance.
|
||||||
func NewService(client *client.Client, db *sqlx.DB) *Service {
|
func NewService(client *client.Client, containerdClient *containerd.Client, db *sqlx.DB) *Service {
|
||||||
return &Service{
|
return &Service{
|
||||||
Client: client,
|
Client: client,
|
||||||
|
containerd: containerdClient,
|
||||||
db: db,
|
db: db,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
|
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/go-connections/sockets"
|
"github.com/docker/go-connections/sockets"
|
||||||
|
"github.com/psviderski/uncloud/internal/containerd"
|
||||||
"github.com/psviderski/uncloud/internal/corrosion"
|
"github.com/psviderski/uncloud/internal/corrosion"
|
||||||
"github.com/psviderski/uncloud/internal/docker"
|
"github.com/psviderski/uncloud/internal/docker"
|
||||||
"github.com/psviderski/uncloud/internal/fs"
|
"github.com/psviderski/uncloud/internal/fs"
|
||||||
@@ -255,7 +256,14 @@ func NewMachine(config *Config) (*Machine, error) {
|
|||||||
return nil, fmt.Errorf("init machine database: %w", err)
|
return nil, fmt.Errorf("init machine database: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
dockerService := machinedocker.NewService(config.DockerClient, db)
|
if config.ContainerdSockPath == "" {
|
||||||
|
return nil, errors.New("containerd socket path must be configured")
|
||||||
|
}
|
||||||
|
containerdClient, err := containerd.NewClient(config.ContainerdSockPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("create containerd client: %w", err)
|
||||||
|
}
|
||||||
|
dockerService := machinedocker.NewService(config.DockerClient, containerdClient, db)
|
||||||
|
|
||||||
// Init a local gRPC proxy server that proxies requests to the local or remote machine API servers.
|
// Init a local gRPC proxy server that proxies requests to the local or remote machine API servers.
|
||||||
proxyDirector := apiproxy.NewDirector(config.MachineSockPath, constants.MachineAPIPort)
|
proxyDirector := apiproxy.NewDirector(config.MachineSockPath, constants.MachineAPIPort)
|
||||||
@@ -283,9 +291,10 @@ func NewMachine(config *Config) (*Machine, error) {
|
|||||||
internalDNSIP := func() netip.Addr {
|
internalDNSIP := func() netip.Addr {
|
||||||
return m.IP()
|
return m.IP()
|
||||||
}
|
}
|
||||||
m.dockerServer = machinedocker.NewServer(dockerService, db, internalDNSIP,
|
m.dockerServer = machinedocker.NewServer(dockerService, db, internalDNSIP, machinedocker.ServerOptions{
|
||||||
machinedocker.WithNetworkReady(m.IsNetworkReady),
|
NetworkReady: m.IsNetworkReady,
|
||||||
machinedocker.WithWaitForNetworkReady(m.WaitForNetworkReady))
|
WaitForNetworkReady: m.WaitForNetworkReady,
|
||||||
|
})
|
||||||
caddyServer := caddyconfig.NewServer(caddyconfig.NewService(config.CaddyConfigDir))
|
caddyServer := caddyconfig.NewServer(caddyconfig.NewService(config.CaddyConfigDir))
|
||||||
m.localMachineServer = newGRPCServer(m, c, m.dockerServer, caddyServer)
|
m.localMachineServer = newGRPCServer(m, c, m.dockerServer, caddyServer)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user