Add CGroupDriver function to cruntime interface

pull/6287/head
Anders F Björklund 2020-01-12 18:43:18 +01:00
parent 0a9e8b03b8
commit 27f8adf912
6 changed files with 119 additions and 0 deletions

View File

@ -240,6 +240,29 @@ func (r *Containerd) LoadImage(path string) error {
return nil
}
// CGroupDriver returns cgroup driver ("cgroupfs" or "systemd")
func (r *Containerd) CGroupDriver() (string, error) {
info, err := getCRIInfo(r.Runner)
if err != nil {
return "", err
}
if info["config"] == nil {
return "", errors.Wrapf(err, "missing config")
}
config, ok := info["config"].(map[string]interface{})
if !ok {
return "", errors.Wrapf(err, "config not map")
}
cgroupManager := "cgroupfs" // default
switch config["systemdCgroup"] {
case false:
cgroupManager = "cgroupfs"
case true:
cgroupManager = "systemd"
}
return cgroupManager, nil
}
// KubeletOptions returns kubelet options for a containerd
func (r *Containerd) KubeletOptions() map[string]string {
return map[string]string{

View File

@ -19,6 +19,7 @@ package cruntime
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"html/template"
"os/exec"
@ -406,6 +407,23 @@ image-endpoint: unix://{{.Socket}}
return nil
}
// getCRIInfo returns current information
func getCRIInfo(cr CommandRunner) (map[string]interface{}, error) {
args := []string{"crictl", "info"}
c := exec.Command("sudo", args...)
rr, err := cr.RunCmd(c)
if err != nil {
return nil, errors.Wrap(err, "get cri info")
}
info := rr.Stdout.String()
jsonMap := make(map[string]interface{})
err = json.Unmarshal([]byte(info), &jsonMap)
if err != nil {
return nil, err
}
return jsonMap, nil
}
// generateCRIOConfig sets up /etc/crio/crio.conf
func generateCRIOConfig(cr CommandRunner, imageRepository string) error {
cPath := crioConfigFile

View File

@ -143,6 +143,26 @@ func (r *CRIO) LoadImage(path string) error {
return nil
}
// CGroupDriver returns cgroup driver ("cgroupfs" or "systemd")
func (r *CRIO) CGroupDriver() (string, error) {
c := exec.Command("crio", "config")
rr, err := r.Runner.RunCmd(c)
if err != nil {
return "", err
}
cgroupManager := "cgroupfs" // default
for _, line := range strings.Split(rr.Stdout.String(), "\n") {
if strings.HasPrefix(line, "cgroup_manager") {
// cgroup_manager = "cgroupfs"
f := strings.Split(strings.TrimSpace(line), " = ")
if len(f) == 2 {
cgroupManager = strings.Trim(f[1], "\"")
}
}
}
return cgroupManager, nil
}
// KubeletOptions returns kubelet options for a runtime.
func (r *CRIO) KubeletOptions() map[string]string {
return map[string]string{

View File

@ -49,6 +49,8 @@ type Manager interface {
// Style is an associated StyleEnum for Name()
Style() out.StyleEnum
// CGroupDriver returns cgroup driver ("cgroupfs" or "systemd")
CGroupDriver() (string, error)
// KubeletOptions returns kubelet options for a runtime.
KubeletOptions() map[string]string
// SocketPath returns the path to the socket file for a given runtime

View File

@ -54,6 +54,33 @@ func TestName(t *testing.T) {
}
}
func TestCGroupDriver(t *testing.T) {
var tests = []struct {
runtime string
want string
}{
{"docker", "cgroupfs"},
{"crio", "cgroupfs"},
{"containerd", "cgroupfs"},
}
for _, tc := range tests {
t.Run(tc.runtime, func(t *testing.T) {
r, err := New(Config{Type: tc.runtime, Runner: NewFakeRunner(t)})
if err != nil {
t.Fatalf("New(%s): %v", tc.runtime, err)
}
got, err := r.CGroupDriver()
if err != nil {
t.Fatalf("CGroupDriver(): %v", err)
}
if diff := cmp.Diff(tc.want, got); diff != "" {
t.Errorf("CGroupDriver(%s) returned diff (-want +got):\n%s", tc.runtime, diff)
}
})
}
}
func TestKubeletOptions(t *testing.T) {
var tests = []struct {
runtime string
@ -199,6 +226,12 @@ func (f *FakeRunner) docker(args []string, _ bool) (string, error) {
if args[1] == "--format" && args[2] == "'{{.Server.Version}}'" {
return "18.06.2-ce", nil
}
case "info":
if args[1] == "--format" && args[2] == "'{{.CgroupDriver}}'" {
return "cgroupfs", nil
}
}
return "", nil
}
@ -208,6 +241,9 @@ func (f *FakeRunner) crio(args []string, _ bool) (string, error) { //nolint (res
if args[0] == "--version" {
return "crio version 1.13.0", nil
}
if args[0] == "config" {
return "# Cgroup management implementation used for the runtime.\ncgroup_manager = \"cgroupfs\"\n", nil
}
return "", nil
}
@ -225,6 +261,15 @@ func (f *FakeRunner) containerd(args []string, _ bool) (string, error) {
// crictl is a fake implementation of crictl
func (f *FakeRunner) crictl(args []string, _ bool) (string, error) {
switch cmd := args[0]; cmd {
case "info":
return `{
"status": {
},
"config": {
"systemdCgroup": false
},
"golang": "go1.11.13"
}`, nil
case "ps":
// crictl ps -a --name=apiserver --state=Running --quiet
if args[1] == "-a" && strings.HasPrefix(args[2], "--name") {

View File

@ -127,6 +127,17 @@ func (r *Docker) LoadImage(path string) error {
}
// CGroupDriver returns cgroup driver ("cgroupfs" or "systemd")
func (r *Docker) CGroupDriver() (string, error) {
// Note: the server daemon has to be running, for this call to return successfully
c := exec.Command("docker", "info", "--format", "'{{.CgroupDriver}}'")
rr, err := r.Runner.RunCmd(c)
if err != nil {
return "", err
}
return strings.Split(rr.Stdout.String(), "\n")[0], nil
}
// KubeletOptions returns kubelet options for a runtime.
func (r *Docker) KubeletOptions() map[string]string {
return map[string]string{