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

Commit

Permalink
virtcontainers: add method for calculating cpuset for sandbox
Browse files Browse the repository at this point in the history
Calculate sandbox's CPUSet as the union of each of the container's
CPUSets.

Signed-off-by: Eric Ernst <[email protected]>
  • Loading branch information
Eric Ernst committed Jul 16, 2020
1 parent a885b1b commit 1aa0cec
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 0 deletions.
22 changes: 22 additions & 0 deletions virtcontainers/sandbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
"github.com/kata-containers/runtime/virtcontainers/store"
"github.com/kata-containers/runtime/virtcontainers/types"
"github.com/kata-containers/runtime/virtcontainers/utils"
"k8s.io/kubernetes/pkg/kubelet/cm/cpuset"
)

const (
Expand Down Expand Up @@ -2216,3 +2217,24 @@ func (s *Sandbox) GetPatchedOCISpec() *specs.Spec {
func (s *Sandbox) GetOOMEvent() (string, error) {
return s.agent.getOOMEvent()
}

// 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
}
106 changes: 106 additions & 0 deletions virtcontainers/sandbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1630,3 +1630,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)
}
})
}
}

0 comments on commit 1aa0cec

Please sign in to comment.