mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 10:25:42 +03:00
nomad: thread alloc fit failure reason through
This commit is contained in:
@@ -45,45 +45,45 @@ func FilterTerminalAllocs(allocs []*Allocation) []*Allocation {
|
||||
// The netIdx can optionally be provided if its already been computed.
|
||||
// If the netIdx is provided, it is assumed that the client has already
|
||||
// ensured there are no collisions.
|
||||
func AllocsFit(node *Node, allocs []*Allocation, netIdx *NetworkIndex) (bool, *Resources, error) {
|
||||
func AllocsFit(node *Node, allocs []*Allocation, netIdx *NetworkIndex) (bool, string, *Resources, error) {
|
||||
// Compute the utilization from zero
|
||||
used := new(Resources)
|
||||
|
||||
// Add the reserved resources of the node
|
||||
if node.Reserved != nil {
|
||||
if err := used.Add(node.Reserved); err != nil {
|
||||
return false, nil, err
|
||||
return false, "", nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// For each alloc, add the resources
|
||||
for _, alloc := range allocs {
|
||||
if err := used.Add(alloc.Resources); err != nil {
|
||||
return false, nil, err
|
||||
return false, "", nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the node resources are a super set of those
|
||||
// that are being allocated
|
||||
if !node.Resources.Superset(used) {
|
||||
return false, used, nil
|
||||
if superset, dimension := node.Resources.Superset(used); !superset {
|
||||
return false, dimension, used, nil
|
||||
}
|
||||
|
||||
// Create the network index if missing
|
||||
if netIdx == nil {
|
||||
netIdx = NewNetworkIndex()
|
||||
if netIdx.SetNode(node) || netIdx.AddAllocs(allocs) {
|
||||
return false, used, nil
|
||||
return false, "reserved port collision", used, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the network is overcommitted
|
||||
if netIdx.Overcommitted() {
|
||||
return false, used, nil
|
||||
return false, "bandwidth exceeded", used, nil
|
||||
}
|
||||
|
||||
// Allocations fit!
|
||||
return true, used, nil
|
||||
return true, "", used, nil
|
||||
}
|
||||
|
||||
// ScoreFit is used to score the fit based on the Google work published here:
|
||||
|
||||
@@ -66,7 +66,7 @@ func TestAllocsFit_PortsOvercommitted(t *testing.T) {
|
||||
}
|
||||
|
||||
// Should fit one allocation
|
||||
fit, _, err := AllocsFit(n, []*Allocation{a1}, nil)
|
||||
fit, _, _, err := AllocsFit(n, []*Allocation{a1}, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
@@ -75,7 +75,7 @@ func TestAllocsFit_PortsOvercommitted(t *testing.T) {
|
||||
}
|
||||
|
||||
// Should not fit second allocation
|
||||
fit, _, err = AllocsFit(n, []*Allocation{a1, a1}, nil)
|
||||
fit, _, _, err = AllocsFit(n, []*Allocation{a1, a1}, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
@@ -130,7 +130,7 @@ func TestAllocsFit(t *testing.T) {
|
||||
}
|
||||
|
||||
// Should fit one allocation
|
||||
fit, used, err := AllocsFit(n, []*Allocation{a1}, nil)
|
||||
fit, _, used, err := AllocsFit(n, []*Allocation{a1}, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
@@ -147,7 +147,7 @@ func TestAllocsFit(t *testing.T) {
|
||||
}
|
||||
|
||||
// Should not fit second allocation
|
||||
fit, used, err = AllocsFit(n, []*Allocation{a1, a1}, nil)
|
||||
fit, _, used, err = AllocsFit(n, []*Allocation{a1, a1}, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
@@ -563,20 +563,20 @@ func (r *Resources) NetIndex(n *NetworkResource) int {
|
||||
// Superset checks if one set of resources is a superset
|
||||
// of another. This ignores network resources, and the NetworkIndex
|
||||
// should be used for that.
|
||||
func (r *Resources) Superset(other *Resources) bool {
|
||||
func (r *Resources) Superset(other *Resources) (bool, string) {
|
||||
if r.CPU < other.CPU {
|
||||
return false
|
||||
return false, "cpu exhausted"
|
||||
}
|
||||
if r.MemoryMB < other.MemoryMB {
|
||||
return false
|
||||
return false, "memory exhausted"
|
||||
}
|
||||
if r.DiskMB < other.DiskMB {
|
||||
return false
|
||||
return false, "disk exhausted"
|
||||
}
|
||||
if r.IOPS < other.IOPS {
|
||||
return false
|
||||
return false, "iops exhausted"
|
||||
}
|
||||
return true
|
||||
return true, ""
|
||||
}
|
||||
|
||||
// Add adds the resources of the delta to this, potentially
|
||||
@@ -617,8 +617,10 @@ type NetworkResource struct {
|
||||
func (n *NetworkResource) Copy() *NetworkResource {
|
||||
newR := new(NetworkResource)
|
||||
*newR = *n
|
||||
newR.ReservedPorts = make([]int, len(n.ReservedPorts))
|
||||
copy(newR.ReservedPorts, n.ReservedPorts)
|
||||
if n.ReservedPorts != nil {
|
||||
newR.ReservedPorts = make([]int, len(n.ReservedPorts))
|
||||
copy(newR.ReservedPorts, n.ReservedPorts)
|
||||
}
|
||||
return newR
|
||||
}
|
||||
|
||||
|
||||
@@ -38,16 +38,16 @@ func TestResource_Superset(t *testing.T) {
|
||||
IOPS: 50,
|
||||
}
|
||||
|
||||
if !r1.Superset(r1) {
|
||||
if s, _ := r1.Superset(r1); !s {
|
||||
t.Fatalf("bad")
|
||||
}
|
||||
if !r1.Superset(r2) {
|
||||
if s, _ := r1.Superset(r2); !s {
|
||||
t.Fatalf("bad")
|
||||
}
|
||||
if r2.Superset(r1) {
|
||||
if s, _ := r2.Superset(r1); s {
|
||||
t.Fatalf("bad")
|
||||
}
|
||||
if !r2.Superset(r2) {
|
||||
if s, _ := r2.Superset(r2); !s {
|
||||
t.Fatalf("bad")
|
||||
}
|
||||
}
|
||||
@@ -142,7 +142,7 @@ func TestResource_Add_Network(t *testing.T) {
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expect.Networks, r1.Networks) {
|
||||
t.Fatalf("bad: %#v %#v", expect, r1)
|
||||
t.Fatalf("bad: %#v %#v", expect.Networks[0], r1.Networks[0])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user