virtcontainers: add method for calculating cpuset for sandbox

Calculate sandbox's CPUSet as the union of each of the container's
CPUSets.

Signed-off-by: Eric Ernst <eric.g.ernst@gmail.com>
This commit is contained in:
Eric Ernst 2020-10-12 16:56:01 -07:00 committed by Eric Ernst
parent c88820454d
commit b812d4f7fa
2 changed files with 128 additions and 0 deletions

View File

@ -43,6 +43,7 @@ import (
vcTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/types"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
"k8s.io/kubernetes/pkg/kubelet/cm/cpuset"
)
const (
@ -2275,3 +2276,24 @@ func (s *Sandbox) GetOOMEvent() (string, error) {
func (s *Sandbox) GetAgentURL() (string, error) {
return s.agent.getAgentURL()
}
// getSandboxCPUSet returns the union of each of the sandbox's containers' CPU sets
// as a string in canonical linux CPU list format
func (s *Sandbox) getSandboxCPUSet() (string, error) {
if s.config == nil {
return "", nil
}
result := cpuset.NewCPUSet()
for _, ctr := range s.config.Containers {
if ctr.Resources.CPU != nil {
currSet, err := cpuset.Parse(ctr.Resources.CPU.Cpus)
if err != nil {
return "", fmt.Errorf("unable to parse CPUset for container %s", ctr.ID)
}
result = result.Union(currSet)
}
}
return result.String(), nil
}

View File

@ -1419,3 +1419,109 @@ func TestSandbox_SetupSandboxCgroup(t *testing.T) {
})
}
}
func getContainerConfigWithCPUSet(cpuset string) ContainerConfig {
return ContainerConfig{
Resources: specs.LinuxResources{
CPU: &specs.LinuxCPU{
Cpus: cpuset,
},
},
}
}
func getSimpleSandbox(cpuset0, cpuset1, cpuset2 string) *Sandbox {
sandbox := Sandbox{}
sandbox.config = &SandboxConfig{
Containers: []ContainerConfig{
getContainerConfigWithCPUSet(cpuset0),
getContainerConfigWithCPUSet(cpuset1),
getContainerConfigWithCPUSet(cpuset2),
},
}
return &sandbox
}
func TestGetSandboxCpuSet(t *testing.T) {
tests := []struct {
name string
cpuset0 string
cpuset1 string
cpuset2 string
result string
wantErr bool
}{
{
"single, no cpuset",
"",
"",
"",
"",
false,
},
{
"single cpuset",
"0",
"",
"",
"0",
false,
},
{
"two duplicate cpuset",
"0",
"0",
"",
"0",
false,
},
{
"3 cpusets",
"0-3",
"5-7",
"1",
"0-3,5-7",
false,
},
{
"weird, but should be okay",
"0-3",
"99999",
"",
"0-3,99999",
false,
},
{
"two, overlapping cpuset",
"0-3",
"1-2",
"",
"0-3",
false,
},
{
"garbage, should fail",
"7 beard-seconds",
"Audrey + 7",
"Elliott - 17",
"",
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := getSimpleSandbox(tt.cpuset0, tt.cpuset1, tt.cpuset2)
res, err := s.getSandboxCPUSet()
if (err != nil) != tt.wantErr {
t.Errorf("getSandboxCPUSet() error = %v, wantErr %v", err, tt.wantErr)
}
if res != tt.result {
t.Errorf("getSandboxCPUSet() result = %s, wanted result %s", res, tt.result)
}
})
}
}