From 5377f337b80dc2d8eb0b638116d1be346e36b362 Mon Sep 17 00:00:00 2001 From: Alex Dadgar Date: Thu, 5 May 2016 21:32:01 -0700 Subject: [PATCH] Check if network asks have changed when checking task updates --- nomad/structs/network.go | 1 + scheduler/util.go | 46 +++++++++++++++++++++++++++++++++++++--- scheduler/util_test.go | 18 ++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/nomad/structs/network.go b/nomad/structs/network.go index c55f71b72..7f4435121 100644 --- a/nomad/structs/network.go +++ b/nomad/structs/network.go @@ -203,6 +203,7 @@ func (idx *NetworkIndex) AssignNetwork(ask *NetworkResource) (out *NetworkResour offer := &NetworkResource{ Device: n.Device, IP: ipStr, + MBits: ask.MBits, ReservedPorts: ask.ReservedPorts, DynamicPorts: ask.DynamicPorts, } diff --git a/scheduler/util.go b/scheduler/util.go index 794fca3ba..ee7d1aed4 100644 --- a/scheduler/util.go +++ b/scheduler/util.go @@ -302,19 +302,59 @@ func tasksUpdated(a, b *structs.TaskGroup) bool { if !reflect.DeepEqual(at.Env, bt.Env) { return true } - if !reflect.DeepEqual(at.Resources, bt.Resources) { - return true - } if !reflect.DeepEqual(at.Meta, bt.Meta) { return true } if !reflect.DeepEqual(at.Artifacts, bt.Artifacts) { return true } + + // Inspect the network to see if the dynamic ports are different + if len(at.Resources.Networks) != len(bt.Resources.Networks) { + return true + } + for idx := range at.Resources.Networks { + an := at.Resources.Networks[idx] + bn := bt.Resources.Networks[idx] + + if an.MBits != bn.MBits { + return true + } + + aPorts, bPorts := networkPortMap(an), networkPortMap(bn) + if !reflect.DeepEqual(aPorts, bPorts) { + return true + } + } + + // Inspect the non-network resources + if ar, br := at.Resources, bt.Resources; ar.CPU != br.CPU { + return true + } else if ar.MemoryMB != br.MemoryMB { + return true + } else if ar.DiskMB != br.DiskMB { + return true + } else if ar.IOPS != br.IOPS { + return true + } } return false } +// networkPortMap takes a network resource and returns a map of port labels to +// values. The value for dynamic ports is disregarded even if it is set. This +// makes this function suitable for comparing two network resources for changes. +func networkPortMap(n *structs.NetworkResource) map[string]int { + m := make(map[string]int, len(n.DynamicPorts)+len(n.ReservedPorts)) + for _, p := range n.ReservedPorts { + m[p.Label] = p.Value + } + for _, p := range n.DynamicPorts { + m[p.Label] = -1 + } + return m +} + // setStatus is used to update the status of the evaluation func setStatus(logger *log.Logger, planner Planner, eval, nextEval *structs.Evaluation, status, desc string) error { logger.Printf("[DEBUG] sched: %#v: setting status to %s", eval, status) diff --git a/scheduler/util_test.go b/scheduler/util_test.go index c4fa2fa30..0ec57cd78 100644 --- a/scheduler/util_test.go +++ b/scheduler/util_test.go @@ -404,6 +404,24 @@ func TestTasksUpdated(t *testing.T) { if !tasksUpdated(j1.TaskGroups[0], j11.TaskGroups[0]) { t.Fatalf("bad") } + + j12 := mock.Job() + j12.TaskGroups[0].Tasks[0].Resources.Networks[0].MBits = 100 + if !tasksUpdated(j1.TaskGroups[0], j12.TaskGroups[0]) { + t.Fatalf("bad") + } + + j13 := mock.Job() + j13.TaskGroups[0].Tasks[0].Resources.Networks[0].DynamicPorts[0].Label = "foobar" + if !tasksUpdated(j1.TaskGroups[0], j13.TaskGroups[0]) { + t.Fatalf("bad") + } + + j14 := mock.Job() + j14.TaskGroups[0].Tasks[0].Resources.Networks[0].ReservedPorts = []structs.Port{{Label: "foo", Value: 1312}} + if !tasksUpdated(j1.TaskGroups[0], j14.TaskGroups[0]) { + t.Fatalf("bad") + } } func TestEvictAndPlace_LimitLessThanAllocs(t *testing.T) {