Skip to content

Commit f209a82

Browse files
authored
Merge pull request #11860 from thaJeztah/oci_no_panic
pkg/oci: prevent panic for some platform-specific options
2 parents cada132 + b0052d9 commit f209a82

File tree

2 files changed

+225
-11
lines changed

2 files changed

+225
-11
lines changed

pkg/oci/spec_opts.go

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,9 +1483,12 @@ func WithWindowsDevice(idType, id string) SpecOpts {
14831483
}
14841484
}
14851485

1486-
// WithMemorySwap sets the container's swap in bytes
1486+
// WithMemorySwap sets the container's swap in bytes. It is a no-op on non-Linux specs.
14871487
func WithMemorySwap(swap int64) SpecOpts {
14881488
return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
1489+
if s.Linux == nil {
1490+
return nil
1491+
}
14891492
setResources(s)
14901493
if s.Linux.Resources.Memory == nil {
14911494
s.Linux.Resources.Memory = &specs.LinuxMemory{}
@@ -1495,9 +1498,12 @@ func WithMemorySwap(swap int64) SpecOpts {
14951498
}
14961499
}
14971500

1498-
// WithPidsLimit sets the container's pid limit or maximum
1501+
// WithPidsLimit sets the container's pid limit or maximum. It is a no-op on non-Linux specs.
14991502
func WithPidsLimit(limit int64) SpecOpts {
15001503
return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
1504+
if s.Linux == nil {
1505+
return nil
1506+
}
15011507
setResources(s)
15021508
if s.Linux.Resources.Pids == nil {
15031509
s.Linux.Resources.Pids = &specs.LinuxPids{}
@@ -1507,64 +1513,87 @@ func WithPidsLimit(limit int64) SpecOpts {
15071513
}
15081514
}
15091515

1510-
// WithBlockIO sets the container's blkio parameters
1516+
// WithBlockIO sets the container's blkio parameters. It is a no-op on non-Linux specs.
15111517
func WithBlockIO(blockio *specs.LinuxBlockIO) SpecOpts {
15121518
return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
1519+
if s.Linux == nil {
1520+
return nil
1521+
}
15131522
setResources(s)
15141523
s.Linux.Resources.BlockIO = blockio
15151524
return nil
15161525
}
15171526
}
15181527

1519-
// WithCPUShares sets the container's cpu shares
1528+
// WithCPUShares sets the container's cpu shares. It is a no-op on non-Linux specs.
15201529
func WithCPUShares(shares uint64) SpecOpts {
15211530
return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
1531+
if s.Linux == nil {
1532+
return nil
1533+
}
15221534
setCPU(s)
15231535
s.Linux.Resources.CPU.Shares = &shares
15241536
return nil
15251537
}
15261538
}
15271539

1528-
// WithCPUs sets the container's cpus/cores for use by the container
1540+
// WithCPUs sets the container's cpus/cores for use by the container. It is a no-op on non-Linux specs.
15291541
func WithCPUs(cpus string) SpecOpts {
15301542
return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
1543+
if s.Linux == nil {
1544+
return nil
1545+
}
15311546
setCPU(s)
15321547
s.Linux.Resources.CPU.Cpus = cpus
15331548
return nil
15341549
}
15351550
}
15361551

1537-
// WithCPUsMems sets the container's cpu mems for use by the container
1552+
// WithCPUsMems sets the container's cpu mems for use by the container. It is a no-op on non-Linux specs.
15381553
func WithCPUsMems(mems string) SpecOpts {
15391554
return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
1555+
if s.Linux == nil {
1556+
return nil
1557+
}
15401558
setCPU(s)
15411559
s.Linux.Resources.CPU.Mems = mems
15421560
return nil
15431561
}
15441562
}
15451563

1546-
// WithCPUCFS sets the container's Completely fair scheduling (CFS) quota and period
1564+
// WithCPUCFS sets the container's Completely fair scheduling (CFS) quota and period.
1565+
// It is a no-op on non-Linux specs.
15471566
func WithCPUCFS(quota int64, period uint64) SpecOpts {
15481567
return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
1568+
if s.Linux == nil {
1569+
return nil
1570+
}
15491571
setCPU(s)
15501572
s.Linux.Resources.CPU.Quota = &quota
15511573
s.Linux.Resources.CPU.Period = &period
15521574
return nil
15531575
}
15541576
}
15551577

1556-
// WithCPUBurst sets the container's cpu burst
1578+
// WithCPUBurst sets the container's cpu burst. It is a no-op on non-Linux specs.
15571579
func WithCPUBurst(burst uint64) SpecOpts {
15581580
return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
1581+
if s.Linux == nil {
1582+
return nil
1583+
}
15591584
setCPU(s)
15601585
s.Linux.Resources.CPU.Burst = &burst
15611586
return nil
15621587
}
15631588
}
15641589

15651590
// WithCPURT sets the container's realtime scheduling (RT) runtime and period.
1591+
// It is a no-op on non-Linux specs.
15661592
func WithCPURT(runtime int64, period uint64) SpecOpts {
15671593
return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
1594+
if s.Linux == nil {
1595+
return nil
1596+
}
15681597
setCPU(s)
15691598
s.Linux.Resources.CPU.RealtimeRuntime = &runtime
15701599
s.Linux.Resources.CPU.RealtimePeriod = &period
@@ -1590,29 +1619,38 @@ func WithRdt(closID, l3CacheSchema, memBwSchema string) SpecOpts {
15901619
}
15911620

15921621
// WithWindowsCPUCount sets the `Windows.Resources.CPU.Count` section to the
1593-
// `count` specified.
1622+
// `count` specified. It is a no-op for non-Windows specs.
15941623
func WithWindowsCPUCount(count uint64) SpecOpts {
15951624
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
1625+
if s.Windows == nil {
1626+
return nil
1627+
}
15961628
setCPUWindows(s)
15971629
s.Windows.Resources.CPU.Count = &count
15981630
return nil
15991631
}
16001632
}
16011633

16021634
// WithWindowsCPUShares sets the `Windows.Resources.CPU.Shares` section to the
1603-
// `shares` specified.
1635+
// `shares` specified. It is a no-op for non-Windows specs.
16041636
func WithWindowsCPUShares(shares uint16) SpecOpts {
16051637
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
1638+
if s.Windows == nil {
1639+
return nil
1640+
}
16061641
setCPUWindows(s)
16071642
s.Windows.Resources.CPU.Shares = &shares
16081643
return nil
16091644
}
16101645
}
16111646

16121647
// WithWindowsCPUMaximum sets the `Windows.Resources.CPU.Maximum` section to the
1613-
// `max` specified.
1648+
// `max` specified. It is a no-op for non-Windows specs.
16141649
func WithWindowsCPUMaximum(max uint16) SpecOpts {
16151650
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
1651+
if s.Windows == nil {
1652+
return nil
1653+
}
16161654
setCPUWindows(s)
16171655
s.Windows.Resources.CPU.Maximum = &max
16181656
return nil

pkg/oci/spec_opts_test.go

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ import (
4242
"github.com/containerd/errdefs"
4343
)
4444

45+
var emptySpecs = map[string]Spec{
46+
"empty": {},
47+
"linux": {Linux: &specs.Linux{}},
48+
"windows": {Windows: &specs.Windows{}},
49+
}
50+
4551
type blob []byte
4652

4753
func (b blob) ReadAt(p []byte, off int64) (int, error) {
@@ -416,6 +422,131 @@ func TestWithMemoryLimit(t *testing.T) {
416422
}
417423
}
418424

425+
func TestWithMemorySwap(t *testing.T) {
426+
for name, spec := range emptySpecs {
427+
t.Run(name, func(t *testing.T) {
428+
expected := int64(123)
429+
err := WithMemorySwap(expected)(nil, nil, nil, &spec)
430+
assert.NoError(t, err)
431+
if name == "linux" {
432+
assert.Equal(t, expected, *spec.Linux.Resources.Memory.Swap)
433+
} else {
434+
assert.Empty(t, spec.Linux, "should not have modified spec")
435+
}
436+
})
437+
}
438+
}
439+
440+
func TestWithPidsLimit(t *testing.T) {
441+
for name, spec := range emptySpecs {
442+
t.Run(name, func(t *testing.T) {
443+
expected := int64(123)
444+
err := WithPidsLimit(expected)(nil, nil, nil, &spec)
445+
assert.NoError(t, err)
446+
if name == "linux" {
447+
assert.Equal(t, expected, spec.Linux.Resources.Pids.Limit)
448+
} else {
449+
assert.Empty(t, spec.Linux, "should not have modified spec")
450+
}
451+
})
452+
}
453+
}
454+
455+
func TestWithBlockIO(t *testing.T) {
456+
for name, spec := range emptySpecs {
457+
t.Run(name, func(t *testing.T) {
458+
v := uint16(123)
459+
expected := &specs.LinuxBlockIO{
460+
Weight: &v,
461+
LeafWeight: &v,
462+
}
463+
err := WithBlockIO(expected)(nil, nil, nil, &spec)
464+
assert.NoError(t, err)
465+
if name == "linux" {
466+
assert.Equal(t, expected, spec.Linux.Resources.BlockIO)
467+
} else {
468+
assert.Empty(t, spec.Linux, "should not have modified spec")
469+
}
470+
})
471+
}
472+
}
473+
474+
func TestWithCPUShares(t *testing.T) {
475+
for name, spec := range emptySpecs {
476+
t.Run(name, func(t *testing.T) {
477+
expected := uint64(123)
478+
err := WithCPUShares(expected)(nil, nil, nil, &spec)
479+
assert.NoError(t, err)
480+
if name == "linux" {
481+
assert.Equal(t, expected, *spec.Linux.Resources.CPU.Shares)
482+
} else {
483+
assert.Empty(t, spec.Linux, "should not have modified spec")
484+
}
485+
})
486+
}
487+
}
488+
489+
func TestWithCPUs(t *testing.T) {
490+
for name, spec := range emptySpecs {
491+
t.Run(name, func(t *testing.T) {
492+
expected := "0,1"
493+
err := WithCPUs(expected)(nil, nil, nil, &spec)
494+
assert.NoError(t, err)
495+
if name == "linux" {
496+
assert.Equal(t, expected, spec.Linux.Resources.CPU.Cpus)
497+
} else {
498+
assert.Empty(t, spec.Linux, "should not have modified spec")
499+
}
500+
})
501+
}
502+
}
503+
504+
func TestWithCPUsMems(t *testing.T) {
505+
for name, spec := range emptySpecs {
506+
t.Run(name, func(t *testing.T) {
507+
expected := "0,1"
508+
err := WithCPUsMems(expected)(nil, nil, nil, &spec)
509+
assert.NoError(t, err)
510+
if name == "linux" {
511+
assert.Equal(t, expected, spec.Linux.Resources.CPU.Mems)
512+
} else {
513+
assert.Empty(t, spec.Linux, "should not have modified spec")
514+
}
515+
})
516+
}
517+
}
518+
519+
func TestWithCPUBurst(t *testing.T) {
520+
for name, spec := range emptySpecs {
521+
t.Run(name, func(t *testing.T) {
522+
expected := uint64(123)
523+
err := WithCPUBurst(expected)(nil, nil, nil, &spec)
524+
assert.NoError(t, err)
525+
if name == "linux" {
526+
assert.Equal(t, expected, *spec.Linux.Resources.CPU.Burst)
527+
} else {
528+
assert.Empty(t, spec.Linux, "should not have modified spec")
529+
}
530+
})
531+
}
532+
}
533+
534+
func TestWithCPURT(t *testing.T) {
535+
for name, spec := range emptySpecs {
536+
t.Run(name, func(t *testing.T) {
537+
expectedRT, expectedPeriod := int64(123), uint64(456)
538+
err := WithCPURT(expectedRT, expectedPeriod)(nil, nil, nil, &spec)
539+
assert.NoError(t, err)
540+
if name == "linux" {
541+
assert.Equal(t, expectedRT, *spec.Linux.Resources.CPU.RealtimeRuntime)
542+
assert.Equal(t, expectedPeriod, *spec.Linux.Resources.CPU.RealtimePeriod)
543+
} else {
544+
assert.Empty(t, spec.Linux, "should not have modified spec")
545+
}
546+
})
547+
}
548+
}
549+
419550
func isEqualStringArrays(values, expected []string) bool {
420551
if len(values) != len(expected) {
421552
return false
@@ -770,3 +901,48 @@ func TestWithWindowsDevice(t *testing.T) {
770901
})
771902
}
772903
}
904+
905+
func TestWithWindowsCPUCount(t *testing.T) {
906+
for name, spec := range emptySpecs {
907+
t.Run(name, func(t *testing.T) {
908+
expected := uint64(123)
909+
err := WithWindowsCPUCount(expected)(nil, nil, nil, &spec)
910+
assert.NoError(t, err)
911+
if name == "windows" {
912+
assert.Equal(t, expected, *spec.Windows.Resources.CPU.Count)
913+
} else {
914+
assert.Empty(t, spec.Windows, "should not have modified spec")
915+
}
916+
})
917+
}
918+
}
919+
920+
func TestWithWindowsCPUShares(t *testing.T) {
921+
for name, spec := range emptySpecs {
922+
t.Run(name, func(t *testing.T) {
923+
expected := uint16(123)
924+
err := WithWindowsCPUShares(expected)(nil, nil, nil, &spec)
925+
assert.NoError(t, err)
926+
if name == "windows" {
927+
assert.Equal(t, expected, *spec.Windows.Resources.CPU.Shares)
928+
} else {
929+
assert.Empty(t, spec.Windows, "should not have modified spec")
930+
}
931+
})
932+
}
933+
}
934+
935+
func TestWithWindowsCPUMaximum(t *testing.T) {
936+
for name, spec := range emptySpecs {
937+
t.Run(name, func(t *testing.T) {
938+
expected := uint16(123)
939+
err := WithWindowsCPUMaximum(expected)(nil, nil, nil, &spec)
940+
assert.NoError(t, err)
941+
if name == "windows" {
942+
assert.Equal(t, expected, *spec.Windows.Resources.CPU.Maximum)
943+
} else {
944+
assert.Empty(t, spec.Windows, "should not have modified spec")
945+
}
946+
})
947+
}
948+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy