diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container_api.go | 10 | ||||
-rw-r--r-- | libpod/container_internal.go | 9 | ||||
-rw-r--r-- | libpod/define/config.go | 2 | ||||
-rw-r--r-- | libpod/kube.go | 17 | ||||
-rw-r--r-- | libpod/oci.go | 4 | ||||
-rw-r--r-- | libpod/oci_conmon_common.go | 46 | ||||
-rw-r--r-- | libpod/oci_missing.go | 6 | ||||
-rw-r--r-- | libpod/runtime.go | 8 | ||||
-rw-r--r-- | libpod/runtime_test.go | 28 |
9 files changed, 122 insertions, 8 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/define/config.go b/libpod/define/config.go index 34c1a675d..1fad5cc9a 100644 --- a/libpod/define/config.go +++ b/libpod/define/config.go @@ -85,4 +85,4 @@ const PassthroughLogging = "passthrough" const RLimitDefaultValue = uint64(1048576) // BindMountPrefix distinguishes its annotations from others -const BindMountPrefix = "bind-mount-options:" +const BindMountPrefix = "bind-mount-options" diff --git a/libpod/kube.go b/libpod/kube.go index a0fb52973..d4414aabd 100644 --- a/libpod/kube.go +++ b/libpod/kube.go @@ -385,7 +385,7 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po return nil, err } for k, v := range annotations { - podAnnotations[define.BindMountPrefix+k] = TruncateKubeAnnotation(v) + podAnnotations[define.BindMountPrefix] = TruncateKubeAnnotation(k + ":" + v) } // Since port bindings for the pod are handled by the // infra container, wipe them here only if we are sharing the net namespace @@ -468,12 +468,15 @@ func newPodObject(podName string, annotations map[string]string, initCtrs, conta CreationTimestamp: v12.Now(), Annotations: annotations, } + // Set enableServiceLinks to false as podman doesn't use the service port environment variables + enableServiceLinks := false ps := v1.PodSpec{ - Containers: containers, - Hostname: hostname, - HostNetwork: hostNetwork, - InitContainers: initCtrs, - Volumes: volumes, + Containers: containers, + Hostname: hostname, + HostNetwork: hostNetwork, + InitContainers: initCtrs, + Volumes: volumes, + EnableServiceLinks: &enableServiceLinks, } if dnsOptions != nil && (len(dnsOptions.Nameservers)+len(dnsOptions.Searches)+len(dnsOptions.Options) > 0) { ps.DNSConfig = dnsOptions @@ -526,7 +529,7 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod, return nil, err } for k, v := range annotations { - kubeAnnotations[define.BindMountPrefix+k] = TruncateKubeAnnotation(v) + kubeAnnotations[define.BindMountPrefix] = TruncateKubeAnnotation(k + ":" + v) } if isInit { kubeInitCtrs = append(kubeInitCtrs, kubeCtr) 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 diff --git a/libpod/runtime.go b/libpod/runtime.go index 9b97fd724..1503b2344 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -5,6 +5,7 @@ import ( "context" "errors" "fmt" + "math/rand" "os" "path/filepath" "strings" @@ -112,6 +113,13 @@ type Runtime struct { secretsManager *secrets.SecretsManager } +func init() { + // generateName calls namesgenerator.GetRandomName which the + // global RNG from math/rand. Seed it here to make sure we + // don't get the same name every time. + rand.Seed(time.Now().UnixNano()) +} + // SetXdgDirs ensures the XDG_RUNTIME_DIR env and XDG_CONFIG_HOME variables are set. // containers/image uses XDG_RUNTIME_DIR to locate the auth file, XDG_CONFIG_HOME is // use for the containers.conf configuration file. diff --git a/libpod/runtime_test.go b/libpod/runtime_test.go new file mode 100644 index 000000000..2e16c7fcd --- /dev/null +++ b/libpod/runtime_test.go @@ -0,0 +1,28 @@ +package libpod + +import ( + "math/rand" + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_generateName(t *testing.T) { + state, path, _, err := getEmptyBoltState() + assert.NoError(t, err) + defer os.RemoveAll(path) + defer state.Close() + + r := &Runtime{ + state: state, + } + + // Test that (*Runtime).generateName returns different names + // if called twice, even if the global RNG has the default + // seed. + n1, _ := r.generateName() + rand.Seed(1) + n2, _ := r.generateName() + assert.NotEqual(t, n1, n2) +} |