Browse code

Merge pull request #21315 from hqhq/hq_check_quota

Add validation for cpu period and quota

Sebastiaan van Stijn authored on 2016/03/25 06:10:48
Showing 3 changed files
... ...
@@ -1441,7 +1441,7 @@ func (daemon *Daemon) verifyContainerSettings(hostConfig *containertypes.HostCon
1441 1441
 		if config.WorkingDir != "" {
1442 1442
 			config.WorkingDir = filepath.FromSlash(config.WorkingDir) // Ensure in platform semantics
1443 1443
 			if !system.IsAbs(config.WorkingDir) {
1444
-				return nil, fmt.Errorf("The working directory '%s' is invalid. It needs to be an absolute path.", config.WorkingDir)
1444
+				return nil, fmt.Errorf("The working directory '%s' is invalid. It needs to be an absolute path", config.WorkingDir)
1445 1445
 			}
1446 1446
 		}
1447 1447
 
... ...
@@ -334,10 +334,10 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi
334 334
 		resources.MemorySwap = -1
335 335
 	}
336 336
 	if resources.Memory > 0 && resources.MemorySwap > 0 && resources.MemorySwap < resources.Memory {
337
-		return warnings, fmt.Errorf("Minimum memoryswap limit should be larger than memory limit, see usage.")
337
+		return warnings, fmt.Errorf("Minimum memoryswap limit should be larger than memory limit, see usage")
338 338
 	}
339 339
 	if resources.Memory == 0 && resources.MemorySwap > 0 && !update {
340
-		return warnings, fmt.Errorf("You should always set the Memory limit when using Memoryswap limit, see usage.")
340
+		return warnings, fmt.Errorf("You should always set the Memory limit when using Memoryswap limit, see usage")
341 341
 	}
342 342
 	if resources.MemorySwappiness != nil && *resources.MemorySwappiness != -1 && !sysInfo.MemorySwappiness {
343 343
 		warnings = append(warnings, "Your kernel does not support memory swappiness capabilities, memory swappiness discarded.")
... ...
@@ -347,7 +347,7 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi
347 347
 	if resources.MemorySwappiness != nil {
348 348
 		swappiness := *resources.MemorySwappiness
349 349
 		if swappiness < -1 || swappiness > 100 {
350
-			return warnings, fmt.Errorf("Invalid value: %v, valid memory swappiness range is 0-100.", swappiness)
350
+			return warnings, fmt.Errorf("Invalid value: %v, valid memory swappiness range is 0-100", swappiness)
351 351
 		}
352 352
 	}
353 353
 	if resources.MemoryReservation > 0 && !sysInfo.MemoryReservation {
... ...
@@ -356,7 +356,7 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi
356 356
 		resources.MemoryReservation = 0
357 357
 	}
358 358
 	if resources.Memory > 0 && resources.MemoryReservation > 0 && resources.Memory < resources.MemoryReservation {
359
-		return warnings, fmt.Errorf("Minimum memory limit should be larger than memory reservation limit, see usage.")
359
+		return warnings, fmt.Errorf("Minimum memory limit should be larger than memory reservation limit, see usage")
360 360
 	}
361 361
 	if resources.KernelMemory > 0 && !sysInfo.KernelMemory {
362 362
 		warnings = append(warnings, "Your kernel does not support kernel memory limit capabilities. Limitation discarded.")
... ...
@@ -397,11 +397,17 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi
397 397
 		logrus.Warnf("Your kernel does not support CPU cfs period. Period discarded.")
398 398
 		resources.CPUPeriod = 0
399 399
 	}
400
+	if resources.CPUPeriod > 0 && (resources.CPUPeriod < 1000 || resources.CPUQuota > 1000000) {
401
+		return warnings, fmt.Errorf("CPU cfs period can not be less than 1ms (i.e. 1000) or larger than 1s (i.e. 1000000)")
402
+	}
400 403
 	if resources.CPUQuota > 0 && !sysInfo.CPUCfsQuota {
401 404
 		warnings = append(warnings, "Your kernel does not support CPU cfs quota. Quota discarded.")
402 405
 		logrus.Warnf("Your kernel does not support CPU cfs quota. Quota discarded.")
403 406
 		resources.CPUQuota = 0
404 407
 	}
408
+	if resources.CPUQuota > 0 && resources.CPUQuota < 1000 {
409
+		return warnings, fmt.Errorf("CPU cfs quota can not be less than 1ms (i.e. 1000)")
410
+	}
405 411
 
406 412
 	// cpuset subsystem checks and adjustments
407 413
 	if (resources.CpusetCpus != "" || resources.CpusetMems != "") && !sysInfo.Cpuset {
... ...
@@ -412,17 +418,17 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi
412 412
 	}
413 413
 	cpusAvailable, err := sysInfo.IsCpusetCpusAvailable(resources.CpusetCpus)
414 414
 	if err != nil {
415
-		return warnings, fmt.Errorf("Invalid value %s for cpuset cpus.", resources.CpusetCpus)
415
+		return warnings, fmt.Errorf("Invalid value %s for cpuset cpus", resources.CpusetCpus)
416 416
 	}
417 417
 	if !cpusAvailable {
418
-		return warnings, fmt.Errorf("Requested CPUs are not available - requested %s, available: %s.", resources.CpusetCpus, sysInfo.Cpus)
418
+		return warnings, fmt.Errorf("Requested CPUs are not available - requested %s, available: %s", resources.CpusetCpus, sysInfo.Cpus)
419 419
 	}
420 420
 	memsAvailable, err := sysInfo.IsCpusetMemsAvailable(resources.CpusetMems)
421 421
 	if err != nil {
422
-		return warnings, fmt.Errorf("Invalid value %s for cpuset mems.", resources.CpusetMems)
422
+		return warnings, fmt.Errorf("Invalid value %s for cpuset mems", resources.CpusetMems)
423 423
 	}
424 424
 	if !memsAvailable {
425
-		return warnings, fmt.Errorf("Requested memory nodes are not available - requested %s, available: %s.", resources.CpusetMems, sysInfo.Mems)
425
+		return warnings, fmt.Errorf("Requested memory nodes are not available - requested %s, available: %s", resources.CpusetMems, sysInfo.Mems)
426 426
 	}
427 427
 
428 428
 	// blkio subsystem checks and adjustments
... ...
@@ -432,7 +438,7 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi
432 432
 		resources.BlkioWeight = 0
433 433
 	}
434 434
 	if resources.BlkioWeight > 0 && (resources.BlkioWeight < 10 || resources.BlkioWeight > 1000) {
435
-		return warnings, fmt.Errorf("Range of blkio weight is from 10 to 1000.")
435
+		return warnings, fmt.Errorf("Range of blkio weight is from 10 to 1000")
436 436
 	}
437 437
 	if len(resources.BlkioWeightDevice) > 0 && !sysInfo.BlkioWeightDevice {
438 438
 		warnings = append(warnings, "Your kernel does not support Block I/O weight_device.")
... ...
@@ -512,7 +518,7 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.
512 512
 	}
513 513
 
514 514
 	if hostConfig.OomScoreAdj < -1000 || hostConfig.OomScoreAdj > 1000 {
515
-		return warnings, fmt.Errorf("Invalid value %d, range for oom score adj is [-1000, 1000].", hostConfig.OomScoreAdj)
515
+		return warnings, fmt.Errorf("Invalid value %d, range for oom score adj is [-1000, 1000]", hostConfig.OomScoreAdj)
516 516
 	}
517 517
 	if sysInfo.IPv4ForwardingDisabled {
518 518
 		warnings = append(warnings, "IPv4 forwarding is disabled. Networking will not work.")
... ...
@@ -1419,7 +1419,7 @@ func (s *DockerSuite) TestPostContainersCreateWithWrongCpusetValues(c *check.C)
1419 1419
 	status, body, err := sockRequest("POST", "/containers/create?name="+name, c1)
1420 1420
 	c.Assert(err, checker.IsNil)
1421 1421
 	c.Assert(status, checker.Equals, http.StatusInternalServerError)
1422
-	expected := "Invalid value 1-42,, for cpuset cpus.\n"
1422
+	expected := "Invalid value 1-42,, for cpuset cpus\n"
1423 1423
 	c.Assert(string(body), checker.Equals, expected)
1424 1424
 
1425 1425
 	c2 := struct {
... ...
@@ -1430,7 +1430,7 @@ func (s *DockerSuite) TestPostContainersCreateWithWrongCpusetValues(c *check.C)
1430 1430
 	status, body, err = sockRequest("POST", "/containers/create?name="+name, c2)
1431 1431
 	c.Assert(err, checker.IsNil)
1432 1432
 	c.Assert(status, checker.Equals, http.StatusInternalServerError)
1433
-	expected = "Invalid value 42-3,1-- for cpuset mems.\n"
1433
+	expected = "Invalid value 42-3,1-- for cpuset mems\n"
1434 1434
 	c.Assert(string(body), checker.Equals, expected)
1435 1435
 }
1436 1436
 
... ...
@@ -1598,7 +1598,7 @@ func (s *DockerSuite) TestPostContainersCreateWithOomScoreAdjInvalidRange(c *che
1598 1598
 	status, b, err := sockRequest("POST", "/containers/create?name="+name, config)
1599 1599
 	c.Assert(err, check.IsNil)
1600 1600
 	c.Assert(status, check.Equals, http.StatusInternalServerError)
1601
-	expected := "Invalid value 1001, range for oom score adj is [-1000, 1000]."
1601
+	expected := "Invalid value 1001, range for oom score adj is [-1000, 1000]"
1602 1602
 	if !strings.Contains(string(b), expected) {
1603 1603
 		c.Fatalf("Expected output to contain %q, got %q", expected, string(b))
1604 1604
 	}
... ...
@@ -1611,7 +1611,7 @@ func (s *DockerSuite) TestPostContainersCreateWithOomScoreAdjInvalidRange(c *che
1611 1611
 	status, b, err = sockRequest("POST", "/containers/create?name="+name, config)
1612 1612
 	c.Assert(err, check.IsNil)
1613 1613
 	c.Assert(status, check.Equals, http.StatusInternalServerError)
1614
-	expected = "Invalid value -1001, range for oom score adj is [-1000, 1000]."
1614
+	expected = "Invalid value -1001, range for oom score adj is [-1000, 1000]"
1615 1615
 	if !strings.Contains(string(b), expected) {
1616 1616
 		c.Fatalf("Expected output to contain %q, got %q", expected, string(b))
1617 1617
 	}