aboutsummaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorCharlie Doern <cdoern@redhat.com>2022-08-09 09:25:03 -0400
committerCharlie Doern <cdoern@redhat.com>2022-09-01 13:02:01 -0400
commit050f3291b9ef8788510b78c543055638275eb20f (patch)
tree327a081bd2243ffcbdf786a940b1dc82d041bea5 /libpod
parent0085fbb488eec30e71e6cced6a06dbdb134e32a6 (diff)
downloadpodman-050f3291b9ef8788510b78c543055638275eb20f.tar.gz
podman-050f3291b9ef8788510b78c543055638275eb20f.tar.bz2
podman-050f3291b9ef8788510b78c543055638275eb20f.zip
implement podman update
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: this command is also now supported in the libpod api via the /libpod/containers/<CID>/update endpoint where the resource limits are passed inthe request body and follow the OCI resource spec format –memory –cpus –cpuset-cpus –cpuset-mems –memory-swap –memory-reservation –cpu-shares –cpu-quota –cpu-period –blkio-weight –cpu-rt-period –cpu-rt-runtime -device-read-bps -device-write-bps -device-read-iops -device-write-iops -memory-swappiness -blkio-weight-device resolves #15067 Signed-off-by: Charlie Doern <cdoern@redhat.com>
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_api.go10
-rw-r--r--libpod/container_internal.go9
-rw-r--r--libpod/oci.go4
-rw-r--r--libpod/oci_conmon_common.go46
-rw-r--r--libpod/oci_missing.go6
5 files changed, 75 insertions, 0 deletions
diff --git a/libpod/container_api.go b/libpod/container_api.go
index 2ff4bfe08..f88e38ce1 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -16,6 +16,7 @@ import (
"github.com/containers/podman/v4/libpod/events"
"github.com/containers/podman/v4/pkg/signal"
"github.com/containers/storage/pkg/archive"
+ spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
)
@@ -98,6 +99,15 @@ func (c *Container) Start(ctx context.Context, recursive bool) error {
return c.start()
}
+// Update updates the given container.
+// only the cgroup config can be updated and therefore only a linux resource spec is passed.
+func (c *Container) Update(res *spec.LinuxResources) error {
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
+ return c.update(res)
+}
+
// StartAndAttach starts a container and attaches to it.
// This acts as a combination of the Start and Attach APIs, ensuring proper
// ordering of the two such that no output from the container is lost (e.g. the
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 7d390ec21..32674235a 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -2352,3 +2352,12 @@ func (c *Container) extractSecretToCtrStorage(secr *ContainerSecret) error {
}
return nil
}
+
+// update calls the ociRuntime update function to modify a cgroup config after container creation
+func (c *Container) update(resources *spec.LinuxResources) error {
+ if err := c.ociRuntime.UpdateContainer(c, resources); err != nil {
+ return err
+ }
+ logrus.Debugf("updated container %s", c.ID())
+ return nil
+}
diff --git a/libpod/oci.go b/libpod/oci.go
index 70053db1b..e5b9a0dcd 100644
--- a/libpod/oci.go
+++ b/libpod/oci.go
@@ -5,6 +5,7 @@ import (
"github.com/containers/common/pkg/resize"
"github.com/containers/podman/v4/libpod/define"
+ "github.com/opencontainers/runtime-spec/specs-go"
)
// OCIRuntime is an implementation of an OCI runtime.
@@ -148,6 +149,9 @@ type OCIRuntime interface {
// RuntimeInfo returns verbose information about the runtime.
RuntimeInfo() (*define.ConmonInfo, *define.OCIRuntimeInfo, error)
+
+ // UpdateContainer updates the given container's cgroup configuration.
+ UpdateContainer(ctr *Container, res *specs.LinuxResources) error
}
// AttachOptions are options used when attached to a container or an exec
diff --git a/libpod/oci_conmon_common.go b/libpod/oci_conmon_common.go
index b96f92d3a..cc65e1261 100644
--- a/libpod/oci_conmon_common.go
+++ b/libpod/oci_conmon_common.go
@@ -307,6 +307,52 @@ func (r *ConmonOCIRuntime) StartContainer(ctr *Container) error {
return nil
}
+// UpdateContainer updates the given container's cgroup configuration
+func (r *ConmonOCIRuntime) UpdateContainer(ctr *Container, resources *spec.LinuxResources) error {
+ runtimeDir, err := util.GetRuntimeDir()
+ if err != nil {
+ return err
+ }
+ env := []string{fmt.Sprintf("XDG_RUNTIME_DIR=%s", runtimeDir)}
+ if path, ok := os.LookupEnv("PATH"); ok {
+ env = append(env, fmt.Sprintf("PATH=%s", path))
+ }
+ args := r.runtimeFlags
+ args = append(args, "update")
+ tempFile, additionalArgs, err := generateResourceFile(resources)
+ if err != nil {
+ return err
+ }
+ defer os.Remove(tempFile)
+
+ args = append(args, additionalArgs...)
+ return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, env, r.path, append(args, ctr.ID())...)
+}
+
+func generateResourceFile(res *spec.LinuxResources) (string, []string, error) {
+ flags := []string{}
+ if res == nil {
+ return "", flags, nil
+ }
+
+ f, err := ioutil.TempFile("", "podman")
+ if err != nil {
+ return "", nil, err
+ }
+
+ j, err := json.Marshal(res)
+ if err != nil {
+ return "", nil, err
+ }
+ _, err = f.WriteString(string(j))
+ if err != nil {
+ return "", nil, err
+ }
+
+ flags = append(flags, "--resources="+f.Name())
+ return f.Name(), flags, nil
+}
+
// KillContainer sends the given signal to the given container.
// If all is set, send to all PIDs in the container.
// All is only supported if the container created cgroups.
diff --git a/libpod/oci_missing.go b/libpod/oci_missing.go
index 2ab2b4577..bbf2957ff 100644
--- a/libpod/oci_missing.go
+++ b/libpod/oci_missing.go
@@ -8,6 +8,7 @@ import (
"github.com/containers/common/pkg/resize"
"github.com/containers/podman/v4/libpod/define"
+ spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
)
@@ -80,6 +81,11 @@ func (r *MissingRuntime) StartContainer(ctr *Container) error {
return r.printError()
}
+// UpdateContainer is not available as the runtime is missing
+func (r *MissingRuntime) UpdateContainer(ctr *Container, resources *spec.LinuxResources) error {
+ return r.printError()
+}
+
// KillContainer is not available as the runtime is missing
// TODO: We could attempt to unix.Kill() the PID as recorded in the state if we
// really want to smooth things out? Won't be perfect, but if the container has