From ab20edb5c469a405e0765e38473aa140f08f145b Mon Sep 17 00:00:00 2001 From: Armon Dadgar Date: Sun, 13 Sep 2015 18:38:11 -0700 Subject: [PATCH] nomad: thread alloc fit failure reason through --- nomad/structs/funcs.go | 16 ++++++++-------- nomad/structs/funcs_test.go | 8 ++++---- nomad/structs/structs.go | 18 ++++++++++-------- nomad/structs/structs_test.go | 10 +++++----- 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/nomad/structs/funcs.go b/nomad/structs/funcs.go index 4d2bae575..dab040525 100644 --- a/nomad/structs/funcs.go +++ b/nomad/structs/funcs.go @@ -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: diff --git a/nomad/structs/funcs_test.go b/nomad/structs/funcs_test.go index 06899b151..bda87a0aa 100644 --- a/nomad/structs/funcs_test.go +++ b/nomad/structs/funcs_test.go @@ -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) } diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index a49e1b385..d688c033b 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -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 } diff --git a/nomad/structs/structs_test.go b/nomad/structs/structs_test.go index 259f51135..2f24e2e17 100644 --- a/nomad/structs/structs_test.go +++ b/nomad/structs/structs_test.go @@ -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]) } }