chore: map compose volumes to server spec, initial volume scheduling

This commit is contained in:
Pavel Sviderski
2025-04-21 21:25:26 +10:00
parent 143e68cc95
commit e5957d9d6b
7 changed files with 292 additions and 41 deletions
+43 -2
View File
@@ -3,9 +3,11 @@ package deploy
import (
"context"
"fmt"
"github.com/docker/docker/api/types/container"
"github.com/psviderski/uncloud/pkg/api"
"strings"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/volume"
"github.com/psviderski/uncloud/pkg/api"
)
// Operation represents a single atomic operation in a deployment process.
@@ -109,6 +111,45 @@ func (o *RemoveContainerOperation) String() string {
o.ServiceID, o.ContainerID, o.MachineID)
}
// CreateVolumeOperation creates a volume on a specific machine.
type CreateVolumeOperation struct {
VolumeSpec api.VolumeSpec
MachineID string
}
func (o *CreateVolumeOperation) Execute(ctx context.Context, cli Client) error {
if o.VolumeSpec.Type != api.VolumeTypeVolume {
return fmt.Errorf("invalid volume type: '%s', expected '%s'", o.VolumeSpec.Type, api.VolumeTypeVolume)
}
opts := volume.CreateOptions{
Name: o.VolumeSpec.DockerVolumeName(),
}
if o.VolumeSpec.VolumeOptions != nil {
if o.VolumeSpec.VolumeOptions.Driver != nil {
opts.Driver = o.VolumeSpec.VolumeOptions.Driver.Name
opts.DriverOpts = o.VolumeSpec.VolumeOptions.Driver.Options
}
opts.Labels = o.VolumeSpec.VolumeOptions.Labels
}
if _, err := cli.CreateVolume(ctx, o.MachineID, opts); err != nil {
return fmt.Errorf("create volume: %w", err)
}
return nil
}
func (o *CreateVolumeOperation) Format(resolver NameResolver) string {
machineName := resolver.MachineName(o.MachineID)
return fmt.Sprintf("%s: Create volume [name=%s]", machineName, o.VolumeSpec.DockerVolumeName())
}
func (o *CreateVolumeOperation) String() string {
return fmt.Sprintf("CreateVolumeOperation[volume=%s, machine_id=%s]",
o.VolumeSpec.DockerVolumeName(), o.MachineID)
}
// SequenceOperation is a composite operation that executes a sequence of operations in order.
type SequenceOperation struct {
Operations []Operation
+2
View File
@@ -150,6 +150,8 @@ type ImageResolverClient interface {
api.MachineClient
}
// TODO(lhf): as of April 2025, ImageDigestResolver is not used in the codebase and considered more harmful
// than helpful. It's safe to remove it.
type ImageDigestResolver struct {
Ctx context.Context
Client ImageResolverClient
@@ -21,6 +21,9 @@ type Constraint interface {
func constraintsFromSpec(spec api.ServiceSpec) []Constraint {
var constraints []Constraint
// TODO: add placement constraint based on the supported platforms of the image.
// TODO: add placement constraint to limit machines with the image if pull policy is never.
if len(spec.Placement.Machines) > 0 {
constraints = append(constraints, &PlacementConstraint{
Machines: spec.Placement.Machines,