Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
sandbox: Join cgroup sandbox on create.
Browse files Browse the repository at this point in the history
When a new sandbox is created, join to its cgroup path
this will create all proxy, shim, etc in the sandbox cgroup.

Fixes: #1879

Signed-off-by: Jose Carlos Venegas Munoz <[email protected]>
  • Loading branch information
jcvenegas committed Aug 29, 2019
1 parent 2fcb8bb commit 074418f
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 0 deletions.
12 changes: 12 additions & 0 deletions virtcontainers/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,18 @@ func createSandboxFromConfig(ctx context.Context, sandboxConfig SandboxConfig, f
return nil, err
}

// Move runtime to sandbox cgroup so all process are created there.
if s.config.SandboxCgroupOnly {
if err := s.setupSandboxCgroupOnly(); err != nil {
return nil, err

}
if err := s.joinSandboxCgroup(); err != nil {
return nil, err

}
}

// cleanup sandbox resources in case of any failure
defer func() {
if err != nil {
Expand Down
71 changes: 71 additions & 0 deletions virtcontainers/sandbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ package virtcontainers

import (
"context"
"encoding/json"
"fmt"
"io"
"math"
"net"
"os"
"path/filepath"
"strings"
"sync"
"syscall"
Expand Down Expand Up @@ -2069,3 +2071,72 @@ func (s *Sandbox) cpuResources() *specs.LinuxCPU {

return validCPUResources(cpu)
}

// setupSandboxCgroup creates sandbox cgroups for the sandbox config
func (s *Sandbox) setupSandboxCgroupOnly() error {
var PodSandboxConfig *ContainerConfig

if s.config == nil {
return fmt.Errorf("Sandbox config is nil")
}

for _, cConfig := range s.config.Containers {
if cConfig.Annotations[annotations.ContainerTypeKey] == string(PodSandbox) {
PodSandboxConfig = &cConfig
break
}
}

if PodSandboxConfig == nil {
return fmt.Errorf("Failed to find cgroup path for Sandbox: Container of type '%s' not found", PodSandbox)
}

configJSON, ok := PodSandboxConfig.Annotations[annotations.ConfigJSONKey]
if !ok {
return fmt.Errorf("Could not find json config in annotations for container '%s'", PodSandboxConfig.ID)
}

var spec specs.Spec
if err := json.Unmarshal([]byte(configJSON), &spec); err != nil {
return err
}

if spec.Linux == nil {
// Cgroup path is optional, just skip the setup
return nil
}
validContainerCgroup := utils.ValidCgroupPath(spec.Linux.CgroupsPath)

// Use the parent cgroup of the container sandbox as the sandbox cgroup

s.state.CgroupPath = filepath.Join(filepath.Dir(validContainerCgroup), cgroupKataPrefix+"_"+PodSandboxConfig.ID)
_, err := cgroupsNewFunc(cgroups.V1, cgroups.StaticPath(s.state.CgroupPath), &specs.LinuxResources{})
if err != nil {
return fmt.Errorf("Could not create sandbox cgroup in %v: %v", s.state.CgroupPath, err)

}

return nil
}

// joinSandboxCgroup adds the runtime PID to the sandbox defined in sandboxes' CgroupPath
func (s *Sandbox) joinSandboxCgroup() error {

if s.state.CgroupPath == "" {
// This is an optional value
return nil
}

cgroup, err := cgroupsLoadFunc(cgroups.V1, cgroups.StaticPath(s.state.CgroupPath))
if err != nil {
return fmt.Errorf("Could not load sandbox cgroup in %v: %v", s.state.CgroupPath, err)
}

s.Logger().WithField("cgroup:", s.state.CgroupPath).Debug("joining to sandbox cgroup")
runtimePid := os.Getpid()

if err := cgroup.Add(cgroups.Process{Pid: runtimePid}); err != nil {
return fmt.Errorf("Could not add runtime PID %d to sandbox cgroup: %v", runtimePid, err)
}
return nil
}
94 changes: 94 additions & 0 deletions virtcontainers/sandbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1473,3 +1473,97 @@ func TestSandboxExperimentalFeature(t *testing.T) {
assert.NotNil(t, exp.Get(testFeature.Name))
assert.True(t, sconfig.valid())
}

func TestSandbox_joinSandboxCgroup(t *testing.T) {

mockValidCgroup := &Sandbox{}
mockValidCgroup.state.CgroupPath = "/my/cgroup"

tests := []struct {
name string
s *Sandbox
wantErr bool
}{
{"New Config", &Sandbox{}, false},
{"Mock cgroup path", mockValidCgroup, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := tt.s.joinSandboxCgroup(); (err != nil) != tt.wantErr {
t.Errorf("Sandbox.joinSandboxCgroup() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

func TestSandbox_SetupSandboxCgroupOnly(t *testing.T) {
sandboxContainer := ContainerConfig{}
sandboxContainer.Annotations = make(map[string]string)
sandboxContainer.Annotations[annotations.ContainerTypeKey] = string(PodSandbox)

emptyJSONLinux := ContainerConfig{}
emptyJSONLinux.Annotations = make(map[string]string)
emptyJSONLinux.Annotations[annotations.ContainerTypeKey] = string(PodSandbox)
emptyJSONLinux.Annotations[annotations.ConfigJSONKey] = "{}"

successfulContainer := ContainerConfig{}
successfulContainer.Annotations = make(map[string]string)
successfulContainer.Annotations[annotations.ContainerTypeKey] = string(PodSandbox)
successfulContainer.Annotations[annotations.ConfigJSONKey] = "{\"linux\": { \"cgroupsPath\": \"/myRuntime/myContainer\" }}"

tests := []struct {
name string
s *Sandbox
wantErr bool
}{
{
"New sandbox",
&Sandbox{},
true,
},
{
"New sandbox, new config",
&Sandbox{config: &SandboxConfig{}},
true,
},
{
"sandbox, container no sandbox type",
&Sandbox{
config: &SandboxConfig{Containers: []ContainerConfig{
{},
}}},
true,
},
{
"sandbox, container sandbox type",
&Sandbox{
config: &SandboxConfig{Containers: []ContainerConfig{
sandboxContainer,
}}},
true,
},
{
"sandbox, empty linux json",
&Sandbox{
config: &SandboxConfig{Containers: []ContainerConfig{
emptyJSONLinux,
}}},
false,
},
{
"sandbox, successful config",
&Sandbox{
config: &SandboxConfig{Containers: []ContainerConfig{
successfulContainer,
}}},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := tt.s.setupSandboxCgroupOnly(); (err != nil) != tt.wantErr {
t.Errorf("Sandbox.SetupSandboxCgroupOnly() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

0 comments on commit 074418f

Please sign in to comment.