diff --git a/cmd/nerdctl/container/container_run_cgroup_linux_test.go b/cmd/nerdctl/container/container_run_cgroup_linux_test.go index 8b423d970ba..4ac4fef7563 100644 --- a/cmd/nerdctl/container/container_run_cgroup_linux_test.go +++ b/cmd/nerdctl/container/container_run_cgroup_linux_test.go @@ -18,6 +18,7 @@ package container import ( "bytes" + "context" "fmt" "os" "path/filepath" @@ -27,6 +28,7 @@ import ( "gotest.tools/v3/assert" "github.com/containerd/cgroups/v3" + containerd "github.com/containerd/containerd/v2/client" "github.com/containerd/continuity/testutil/loopback" "github.com/containerd/nerdctl/v2/pkg/cmd/container" @@ -170,6 +172,27 @@ func TestRunCgroupV1(t *testing.T) { base.Cmd("run", "--rm", "--cpu-quota", "42000", "--cpu-period", "100000", "--cpuset-mems", "0", "--memory", "42m", "--memory-reservation", "6m", "--memory-swap", "100m", "--memory-swappiness", "0", "--pids-limit", "42", "--cpu-shares", "2000", "--cpuset-cpus", "0-1", testutil.AlpineImage, "cat", quota, period, cpusetMems, memoryLimit, memoryReservation, memorySwap, memorySwappiness, pidsLimit, cpuShare, cpusetCpus).AssertOutExactly(expected) } +// TestIssue3781 tests https://github.com/containerd/nerdctl/issues/3781 +func TestIssue3781(t *testing.T) { + t.Parallel() + base := testutil.NewBase(t) + containerName := testutil.Identifier(t) + base.Cmd("run", "-d", containerName, testutil.AlpineImage, "sh", "-c", "sleep infinity").AssertOK() + defer func() { + base.Cmd("rm", "-f", containerName) + }() + base.Cmd("run", "update", "--cpuset-cpus", "0-1", containerName).AssertOK() + addr := base.ContainerdAddress() + client, err := containerd.New(addr, containerd.WithDefaultNamespace(testutil.Namespace)) + assert.NilError(base.T, err) + ctx := context.Background() + container, err := client.LoadContainer(ctx, containerName) + assert.NilError(base.T, err) + spec, err := container.Spec(ctx) + assert.NilError(base.T, err) + assert.Equal(t, spec.Linux.Resources.Pids, nil) +} + func TestRunDevice(t *testing.T) { if os.Geteuid() != 0 || userns.RunningInUserNS() { t.Skip("test requires the root in the initial user namespace") diff --git a/cmd/nerdctl/container/container_update.go b/cmd/nerdctl/container/container_update.go index 15c8e6526ef..c1805608b7a 100644 --- a/cmd/nerdctl/container/container_update.go +++ b/cmd/nerdctl/container/container_update.go @@ -266,16 +266,18 @@ func updateContainer(ctx context.Context, client *containerd.Client, id string, if spec.Linux.Resources == nil { spec.Linux.Resources = &runtimespec.LinuxResources{} } - if spec.Linux.Resources.BlockIO == nil { - spec.Linux.Resources.BlockIO = &runtimespec.LinuxBlockIO{} - } if cmd.Flags().Changed("blkio-weight") { + if spec.Linux.Resources.BlockIO == nil { + spec.Linux.Resources.BlockIO = &runtimespec.LinuxBlockIO{} + } if spec.Linux.Resources.BlockIO.Weight != &opts.BlkioWeight { spec.Linux.Resources.BlockIO.Weight = &opts.BlkioWeight } } - if spec.Linux.Resources.CPU == nil { - spec.Linux.Resources.CPU = &runtimespec.LinuxCPU{} + if cmd.Flags().Changed("cpu-shares") || cmd.Flags().Changed("cpu-quota") || cmd.Flags().Changed("cpu-period") || cmd.Flags().Changed("cpus") || cmd.Flags().Changed("cpuset-mems") || cmd.Flags().Changed("cpuset-cpus") { + if spec.Linux.Resources.CPU == nil { + spec.Linux.Resources.CPU = &runtimespec.LinuxCPU{} + } } if cmd.Flags().Changed("cpu-shares") { if spec.Linux.Resources.CPU.Shares != &opts.CPUShares { @@ -308,8 +310,10 @@ func updateContainer(ctx context.Context, client *containerd.Client, id string, spec.Linux.Resources.CPU.Cpus = opts.CpusetCpus } } - if spec.Linux.Resources.Memory == nil { - spec.Linux.Resources.Memory = &runtimespec.LinuxMemory{} + if cmd.Flags().Changed("memory") || cmd.Flags().Changed("memory-reservation") { + if spec.Linux.Resources.Memory == nil { + spec.Linux.Resources.Memory = &runtimespec.LinuxMemory{} + } } if cmd.Flags().Changed("memory") { if spec.Linux.Resources.Memory.Limit != &opts.MemoryLimitInBytes { @@ -324,10 +328,10 @@ func updateContainer(ctx context.Context, client *containerd.Client, id string, spec.Linux.Resources.Memory.Reservation = &opts.MemoryReservation } } - if spec.Linux.Resources.Pids == nil { - spec.Linux.Resources.Pids = &runtimespec.LinuxPids{} - } if cmd.Flags().Changed("pids-limit") { + if spec.Linux.Resources.Pids == nil { + spec.Linux.Resources.Pids = &runtimespec.LinuxPids{} + } if spec.Linux.Resources.Pids.Limit != opts.PidsLimit { spec.Linux.Resources.Pids.Limit = opts.PidsLimit }