mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 19:13:34 +00:00
chore: implement VolumesConstraint to only schedule on machines with required volumes
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
package scheduler
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
"github.com/psviderski/uncloud/pkg/api"
|
||||
)
|
||||
|
||||
@@ -15,6 +17,7 @@ type Constraint interface {
|
||||
Description() string
|
||||
}
|
||||
|
||||
// constraintsFromSpec derives scheduling constraints from the service specification.
|
||||
func constraintsFromSpec(spec api.ServiceSpec) []Constraint {
|
||||
var constraints []Constraint
|
||||
|
||||
@@ -24,7 +27,18 @@ func constraintsFromSpec(spec api.ServiceSpec) []Constraint {
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: inspect and add VolumeConstraint.
|
||||
// Add a VolumesConstraint for named Docker volumes that are mounted in the container.
|
||||
var volumes []api.VolumeSpec
|
||||
for _, m := range spec.Container.VolumeMounts {
|
||||
if v, ok := spec.Volume(m.VolumeName); ok && v.Type == api.VolumeTypeVolume {
|
||||
volumes = append(volumes, v)
|
||||
}
|
||||
}
|
||||
if len(volumes) > 0 {
|
||||
constraints = append(constraints, &VolumesConstraint{
|
||||
Volumes: volumes,
|
||||
})
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
@@ -45,5 +59,51 @@ func (c *PlacementConstraint) Evaluate(machine *Machine) bool {
|
||||
}
|
||||
|
||||
func (c *PlacementConstraint) Description() string {
|
||||
slices.Sort(c.Machines)
|
||||
return "Placement constraint by machines: " + strings.Join(c.Machines, ", ")
|
||||
}
|
||||
|
||||
// VolumesConstraint restricts container placement to machines that have the required named Docker volumes.
|
||||
type VolumesConstraint struct {
|
||||
// Volumes is a list of named Docker volumes of type api.VolumeTypeVolume that must exist on the machine.
|
||||
Volumes []api.VolumeSpec
|
||||
}
|
||||
|
||||
// Evaluate determines if a machine has all the required volumes.
|
||||
// Returns true if all required volumes exist on the machine or if there are no required volumes.
|
||||
func (c *VolumesConstraint) Evaluate(machine *Machine) bool {
|
||||
if len(c.Volumes) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, v := range c.Volumes {
|
||||
if v.Type != api.VolumeTypeVolume {
|
||||
continue
|
||||
}
|
||||
|
||||
// TODO: should we check the volume driver to be local or any matched volume by name is ok?
|
||||
if !slices.ContainsFunc(machine.Volumes, func(vol volume.Volume) bool {
|
||||
return vol.Name == v.DockerVolumeName()
|
||||
}) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *VolumesConstraint) Description() string {
|
||||
volumeNames := make([]string, 0, len(c.Volumes))
|
||||
for _, v := range c.Volumes {
|
||||
if v.Type == api.VolumeTypeVolume {
|
||||
volumeNames = append(volumeNames, v.DockerVolumeName())
|
||||
}
|
||||
}
|
||||
slices.Sort(volumeNames)
|
||||
|
||||
if len(volumeNames) == 0 {
|
||||
return "No volumes constraint"
|
||||
}
|
||||
|
||||
return "Volumes: " + strings.Join(volumeNames, ", ")
|
||||
}
|
||||
|
||||
@@ -53,5 +53,7 @@ func (s *ServiceScheduler) evaluateConstraints(machine *Machine) bool {
|
||||
}
|
||||
|
||||
func (s *ServiceScheduler) ScheduleContainer() ([]*pb.MachineInfo, error) {
|
||||
// TODO: organise machines in a heap and supply a sort function from the strategy. Each scheduled container
|
||||
// should update the machine and reorder it in the heap.
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user