Skip to content

Commit

Permalink
implement podman update
Browse files Browse the repository at this point in the history
podman update allows users to change the cgroup configuration of an existing container using the already defined resource limits flags
from podman create/run. The supported flags in crun are:

–memory
–cpus
–cpuset-cpus
–cpuset-mems
–memory-swap
–memory-reservation
–cpu-shares
–cpu-quota
–cpu-period
–blkio-weight
–cpu-rt-period
–cpu-rt-runtime

resolves containers#15067

Signed-off-by: Charlie Doern <cdoern@redhat.com>
  • Loading branch information
cdoern committed Aug 9, 2022
1 parent 28607a9 commit 5de47a9
Show file tree
Hide file tree
Showing 27 changed files with 579 additions and 165 deletions.
113 changes: 113 additions & 0 deletions cmd/podman/containers/update.go
@@ -0,0 +1,113 @@
package containers

import (
"context"
"fmt"

"github.com/containers/podman/v4/cmd/podman/common"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/specgen"
"github.com/containers/podman/v4/pkg/specgenutil"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/spf13/cobra"
)

var (
updateDescription = `Updates the cgroup configuration of a given container`

updateCommand = &cobra.Command{
Use: "update [options] CONTAINER",
Short: "update an existing container",
Long: updateDescription,
RunE: update,
Args: cobra.ExactArgs(1),
ValidArgsFunction: common.AutocompleteContainers,
Example: `podman update --cpus=5 foobar_container`,
}

containerUpdateCommand = &cobra.Command{
Args: updateCommand.Args,
Use: updateCommand.Use,
Short: updateCommand.Short,
Long: updateCommand.Long,
RunE: updateCommand.RunE,
ValidArgsFunction: updateCommand.ValidArgsFunction,
Example: `podman container update --cpus=5 foobar_container`,
}
)
var (
updateOpts entities.ContainerCreateOptions
)

func ValidateUpdateOptions(cmd *cobra.Command, opts *entities.ContainerCreateOptions) error {
argsNotSupported := []string{
"device-read-bps",
"device-write-bps",
"device-read-iops",
"device-write-iops",
"memory-swappiness",
"blkio-weight-device",
}
for _, arg := range argsNotSupported {
if cmd.Flag(arg).Changed {
return fmt.Errorf("%s option not yet supported", arg)
}
}
return nil
}

func updateFlags(cmd *cobra.Command) {
common.DefineCreateDefaults(&updateOpts)
common.DefineCreateFlags(cmd, &updateOpts, false, false)

}

func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: updateCommand,
})
updateFlags(updateCommand)

registry.Commands = append(registry.Commands, registry.CliCommand{
Command: containerUpdateCommand,
Parent: containerCmd,
})
updateFlags(containerUpdateCommand)

}

func update(cmd *cobra.Command, args []string) error {
var err error

// crun does not yet allow for all resource limits
if err = ValidateUpdateOptions(cmd, &updateOpts); err != nil {
return fmt.Errorf("%w: %s", define.ErrInvalidArg, err.Error())
}

// so here we are going to want to maybe create a new type and/or fill out a
// container resource spec. Might make sense to go specgen -->

s := &specgen.SpecGenerator{}
s.ResourceLimits = &specs.LinuxResources{}
resources := s.ResourceLimits

// JUST pass the resource limits. We do not need an entire specgen.
resources, err = specgenutil.GetResources(s, &updateOpts)
if err != nil {
return err
}

opts := &entities.ContainerUpdateOptions{
NameOrID: args[0],
Resources: resources,
}
rep, err := registry.ContainerEngine().ContainerUpdate(context.Background(), opts)
if err != nil {
return err
}
fmt.Println(rep)
return nil

}
3 changes: 3 additions & 0 deletions docs/source/markdown/options/blkio-weight.md
@@ -0,0 +1,3 @@
#### **--blkio-weight**=*weight*

Block IO weight (relative weight) accepts a weight value between 10 and 1000.
10 changes: 10 additions & 0 deletions docs/source/markdown/options/cpu-period.md
@@ -0,0 +1,10 @@
#### **--cpu-period**=*limit*

Set the CPU period for the Completely Fair Scheduler (CFS), which is a
duration in microseconds. Once the container's CPU quota is used up, it will
not be scheduled to run until the current period ends. Defaults to 100000
microseconds.

On some systems, changing the CPU limits may not be allowed for non-root
users. For more details, see
https://github.com/containers/podman/blob/main/troubleshooting.md#26-running-containers-with-cpu-limits-fails-with-a-permissions-error
12 changes: 12 additions & 0 deletions docs/source/markdown/options/cpu-quota.md
@@ -0,0 +1,12 @@
#### **--cpu-quota**=*limit*

Limit the CPU Completely Fair Scheduler (CFS) quota.

Limit the container's CPU usage. By default, containers run with the full
CPU resource. The limit is a number in microseconds. If you provide a number,
the container will be allowed to use that much CPU time until the CPU period
ends (controllable via **--cpu-period**).

On some systems, changing the CPU limits may not be allowed for non-root
users. For more details, see
https://github.com/containers/podman/blob/main/troubleshooting.md#26-running-containers-with-cpu-limits-fails-with-a-permissions-error
8 changes: 8 additions & 0 deletions docs/source/markdown/options/cpu-rt-period.md
@@ -0,0 +1,8 @@

#### **--cpu-rt-period**=*microseconds*

Limit the CPU real-time period in microseconds

Limit the container's Real Time CPU usage. This flag tell the kernel to restrict the container's Real Time CPU usage to the period you specify.

This flag is not supported on cgroups V2 systems.
10 changes: 10 additions & 0 deletions docs/source/markdown/options/cpu-rt-runtime.md
@@ -0,0 +1,10 @@
#### **--cpu-rt-runtime**=*microseconds*

Limit the CPU real-time runtime in microseconds

Limit the containers Real Time CPU usage. This flag tells the kernel to limit the amount of time in a given CPU period Real Time tasks may consume. Ex:
Period of 1,000,000us and Runtime of 950,000us means that this container could consume 95% of available CPU and leave the remaining 5% to normal priority tasks.

The sum of all runtimes across containers cannot exceed the amount allotted to the parent cgroup.

This flag is not supported on cgroups V2 systems.
37 changes: 37 additions & 0 deletions docs/source/markdown/options/cpu-shares.md
@@ -0,0 +1,37 @@
#### **--cpu-shares**, **-c**=*shares*

CPU shares (relative weight)

By default, all containers get the same proportion of CPU cycles. This proportion
can be modified by changing the container's CPU share weighting relative
to the weighting of all other running containers.

To modify the proportion from the default of 1024, use the **--cpu-shares**
flag to set the weighting to 2 or higher.

The proportion will only apply when CPU-intensive processes are running.
When tasks in one container are idle, other containers can use the
left-over CPU time. The actual amount of CPU time will vary depending on
the number of containers running on the system.

For example, consider three containers, one has a cpu-share of 1024 and
two others have a cpu-share setting of 512. When processes in all three
containers attempt to use 100% of CPU, the first container would receive
50% of the total CPU time. If you add a fourth container with a cpu-share
of 1024, the first container only gets 33% of the CPU. The remaining containers
receive 16.5%, 16.5% and 33% of the CPU.

On a multi-core system, the shares of CPU time are distributed over all CPU
cores. Even if a container is limited to less than 100% of CPU time, it can
use 100% of each individual CPU core.

For example, consider a system with more than three cores.
If the container _C0_ is started with **--cpu-shares=512** running one process,
and another container _C1_ with **--cpu-shares=1024** running two processes,
this can result in the following division of CPU shares:

| PID | container | CPU | CPU share |
| ---- | ----------- | ------- | ------------ |
| 100 | C0 | 0 | 100% of CPU0 |
| 101 | C1 | 1 | 100% of CPU1 |
| 102 | C1 | 2 | 100% of CPU2 |
9 changes: 9 additions & 0 deletions docs/source/markdown/options/cpus.md
@@ -0,0 +1,9 @@
#### **--cpus**=*number*

Number of CPUs. The default is *0.0* which means no limit. This is shorthand
for **--cpu-period** and **--cpu-quota**, so you may only set either
**--cpus** or **--cpu-period** and **--cpu-quota**.

On some systems, changing the CPU limits may not be allowed for non-root
users. For more details, see
https://github.com/containers/podman/blob/main/troubleshooting.md#26-running-containers-with-cpu-limits-fails-with-a-permissions-error
3 changes: 3 additions & 0 deletions docs/source/markdown/options/cpuset-cpus.md
@@ -0,0 +1,3 @@
#### **--cpuset-cpus**=*cpus*

CPUs in which to allow execution (0-3, 0,1)
7 changes: 7 additions & 0 deletions docs/source/markdown/options/cpuset-mems.md
@@ -0,0 +1,7 @@
#### **--cpuset-mems**=*nodes*

Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.

If you have four memory nodes on your system (0-3), use `--cpuset-mems=0,1`
then processes in your container will only use memory from the first
two memory nodes.
9 changes: 9 additions & 0 deletions docs/source/markdown/options/memory-reservation.md
@@ -0,0 +1,9 @@
#### **--memory-reservation**=*limit*

Memory soft limit (format: `<number>[<unit>]`, where unit = b (bytes), k (kibibytes), m (mebibytes), or g (gibibytes))

After setting memory reservation, when the system detects memory contention
or low memory, containers are forced to restrict their consumption to their
reservation. So you should always set the value below **--memory**, otherwise the
hard limit will take precedence. By default, memory reservation will be the same
as memory limit.
10 changes: 10 additions & 0 deletions docs/source/markdown/options/memory-swap.md
@@ -0,0 +1,10 @@
#### **--memory-swap**=*limit*

A limit value equal to memory plus swap. Must be used with the **-m**
(**--memory**) flag. The swap `LIMIT` should always be larger than **-m**
(**--memory**) value. By default, the swap `LIMIT` will be set to double
the value of --memory.

The format of `LIMIT` is `<number>[<unit>]`. Unit can be `b` (bytes),
`k` (kibibytes), `m` (mebibytes), or `g` (gibibytes). If you don't specify a
unit, `b` is used. Set LIMIT to `-1` to enable unlimited swap.
9 changes: 9 additions & 0 deletions docs/source/markdown/options/memory.md
@@ -0,0 +1,9 @@
#### **--memory**, **-m**=*limit*

Memory limit (format: `<number>[<unit>]`, where unit = b (bytes), k (kibibytes), m (mebibytes), or g (gibibytes))

Allows you to constrain the memory available to a container. If the host
supports swap memory, then the **-m** memory setting can be larger than physical
RAM. If a limit of 0 is specified (not using **-m**), the container's memory is
not limited. The actual limit may be rounded up to a multiple of the operating
system's page size (the value would be very large, that's millions of trillions).

0 comments on commit 5de47a9

Please sign in to comment.