12199: Ensure scratch space for tmp mounts when choosing node type.
authorTom Clegg <tclegg@veritasgenetics.com>
Tue, 13 Feb 2018 20:10:40 +0000 (15:10 -0500)
committerTom Clegg <tclegg@veritasgenetics.com>
Tue, 13 Feb 2018 20:10:40 +0000 (15:10 -0500)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg@veritasgenetics.com>

lib/dispatchcloud/node_size.go
lib/dispatchcloud/node_size_test.go

index 3b72c4aeeb730af9bfa1b4b6cc8bc3115d48e6cd..34f83a6efdeca89e485029025131baa1ff133ac9 100644 (file)
@@ -24,20 +24,28 @@ var (
 // ChooseInstanceType returns the cheapest available
 // arvados.InstanceType big enough to run ctr.
 func ChooseInstanceType(cc *arvados.Cluster, ctr *arvados.Container) (best arvados.InstanceType, err error) {
-       needVCPUs := ctr.RuntimeConstraints.VCPUs
-       needRAM := ctr.RuntimeConstraints.RAM + ctr.RuntimeConstraints.KeepCacheRAM
-
-       needRAM = (needRAM * 100) / int64(100-discountConfiguredRAMPercent)
-
        if len(cc.InstanceTypes) == 0 {
                err = ErrInstanceTypesNotConfigured
                return
        }
 
+       needScratch := int64(0)
+       for _, m := range ctr.Mounts {
+               if m.Kind == "tmp" {
+                       needScratch += m.Capacity
+               }
+       }
+
+       needVCPUs := ctr.RuntimeConstraints.VCPUs
+
+       needRAM := ctr.RuntimeConstraints.RAM + ctr.RuntimeConstraints.KeepCacheRAM
+       needRAM = (needRAM * 100) / int64(100-discountConfiguredRAMPercent)
+
        err = ErrConstraintsNotSatisfiable
        for _, it := range cc.InstanceTypes {
                switch {
                case err == nil && it.Price > best.Price:
+               case it.Scratch < needScratch:
                case it.RAM < needRAM:
                case it.VCPUs < needVCPUs:
                case it.Price == best.Price && (it.RAM < best.RAM || it.VCPUs < best.VCPUs):
index bc628b51600d67f9639ea9c0bfd4ba5008e56694..0c02a0e3e1be45bfeb6b2371287a4ce664de1d98 100644 (file)
@@ -11,6 +11,8 @@ import (
 
 var _ = check.Suite(&NodeSizeSuite{})
 
+const GiB = int64(1 << 30)
+
 type NodeSizeSuite struct{}
 
 func (*NodeSizeSuite) TestChooseNotConfigured(c *check.C) {
@@ -24,41 +26,58 @@ func (*NodeSizeSuite) TestChooseNotConfigured(c *check.C) {
 }
 
 func (*NodeSizeSuite) TestChooseUnsatisfiable(c *check.C) {
+       checkUnsatisfiable := func(ctr *arvados.Container) {
+               _, err := ChooseInstanceType(&arvados.Cluster{InstanceTypes: []arvados.InstanceType{
+                       {Price: 1.1, RAM: 1000000000, VCPUs: 2, Name: "small1"},
+                       {Price: 2.2, RAM: 2000000000, VCPUs: 4, Name: "small2"},
+                       {Price: 4.4, RAM: 4000000000, VCPUs: 8, Name: "small4", Scratch: GiB},
+               }}, ctr)
+               c.Check(err, check.Equals, ErrConstraintsNotSatisfiable)
+       }
+
        for _, rc := range []arvados.RuntimeConstraints{
                {RAM: 9876543210, VCPUs: 2},
                {RAM: 1234567890, VCPUs: 20},
                {RAM: 1234567890, VCPUs: 2, KeepCacheRAM: 9876543210},
        } {
-               _, err := ChooseInstanceType(&arvados.Cluster{InstanceTypes: []arvados.InstanceType{
-                       {Price: 1.1, RAM: 1000000000, VCPUs: 2, Name: "small1"},
-                       {Price: 2.2, RAM: 2000000000, VCPUs: 4, Name: "small2"},
-                       {Price: 4.4, RAM: 4000000000, VCPUs: 8, Name: "small4"},
-               }}, &arvados.Container{RuntimeConstraints: rc})
-               c.Check(err, check.Equals, ErrConstraintsNotSatisfiable)
+               checkUnsatisfiable(&arvados.Container{RuntimeConstraints: rc})
        }
+       checkUnsatisfiable(&arvados.Container{
+               Mounts:             map[string]arvados.Mount{"/tmp": {Kind: "tmp", Capacity: 2 * GiB}},
+               RuntimeConstraints: arvados.RuntimeConstraints{RAM: 12345, VCPUs: 1},
+       })
 }
 
 func (*NodeSizeSuite) TestChoose(c *check.C) {
        for _, menu := range [][]arvados.InstanceType{
                {
-                       {Price: 4.4, RAM: 4000000000, VCPUs: 8, Name: "costly"},
-                       {Price: 2.2, RAM: 2000000000, VCPUs: 4, Name: "best"},
-                       {Price: 1.1, RAM: 1000000000, VCPUs: 2, Name: "small"},
+                       {Price: 4.4, RAM: 4000000000, VCPUs: 8, Scratch: 2 * GiB, Name: "costly"},
+                       {Price: 2.2, RAM: 2000000000, VCPUs: 4, Scratch: 2 * GiB, Name: "best"},
+                       {Price: 1.1, RAM: 1000000000, VCPUs: 2, Scratch: 2 * GiB, Name: "small"},
                },
                {
-                       {Price: 4.4, RAM: 4000000000, VCPUs: 8, Name: "costly"},
-                       {Price: 2.2, RAM: 2000000000, VCPUs: 4, Name: "goodenough"},
-                       {Price: 2.2, RAM: 4000000000, VCPUs: 4, Name: "best"},
-                       {Price: 1.1, RAM: 1000000000, VCPUs: 2, Name: "small"},
+                       {Price: 4.4, RAM: 4000000000, VCPUs: 8, Scratch: 2 * GiB, Name: "costly"},
+                       {Price: 2.2, RAM: 2000000000, VCPUs: 4, Scratch: 2 * GiB, Name: "goodenough"},
+                       {Price: 2.2, RAM: 4000000000, VCPUs: 4, Scratch: 2 * GiB, Name: "best"},
+                       {Price: 1.1, RAM: 1000000000, VCPUs: 2, Scratch: 2 * GiB, Name: "small"},
                },
                {
-                       {Price: 1.1, RAM: 1000000000, VCPUs: 2, Name: "small"},
-                       {Price: 2.2, RAM: 2000000000, VCPUs: 4, Name: "goodenough"},
-                       {Price: 2.2, RAM: 4000000000, VCPUs: 4, Name: "best"},
-                       {Price: 4.4, RAM: 4000000000, VCPUs: 8, Name: "costly"},
+                       {Price: 1.1, RAM: 1000000000, VCPUs: 2, Scratch: 2 * GiB, Name: "small"},
+                       {Price: 2.2, RAM: 2000000000, VCPUs: 4, Scratch: 2 * GiB, Name: "goodenough"},
+                       {Price: 2.2, RAM: 4000000000, VCPUs: 4, Scratch: 2 * GiB, Name: "best"},
+                       {Price: 4.4, RAM: 4000000000, VCPUs: 8, Scratch: 2 * GiB, Name: "costly"},
+               },
+               {
+                       {Price: 1.1, RAM: 1000000000, VCPUs: 2, Scratch: GiB, Name: "small"},
+                       {Price: 2.2, RAM: 2000000000, VCPUs: 4, Scratch: GiB, Name: "nearly"},
+                       {Price: 3.3, RAM: 4000000000, VCPUs: 4, Scratch: 2 * GiB, Name: "best"},
+                       {Price: 4.4, RAM: 4000000000, VCPUs: 8, Scratch: 2 * GiB, Name: "costly"},
                },
        } {
                best, err := ChooseInstanceType(&arvados.Cluster{InstanceTypes: menu}, &arvados.Container{
+                       Mounts: map[string]arvados.Mount{
+                               "/tmp": {Kind: "tmp", Capacity: 2 * GiB},
+                       },
                        RuntimeConstraints: arvados.RuntimeConstraints{
                                VCPUs:        2,
                                RAM:          987654321,
@@ -69,5 +88,6 @@ func (*NodeSizeSuite) TestChoose(c *check.C) {
                c.Check(best.Name, check.Equals, "best")
                c.Check(best.RAM >= 1234567890, check.Equals, true)
                c.Check(best.VCPUs >= 2, check.Equals, true)
+               c.Check(best.Scratch >= 2*GiB, check.Equals, true)
        }
 }