mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-04 11:06:21 +00:00
cli: add AMD support to kata-check
Added support for identifying AMD CPUs in the `kata-check` CLI command. Signed-off-by: George Kennedy <george.kennedy@oracle.com> Fixes #476.
This commit is contained in:
parent
67b5841153
commit
4326ea874a
@ -283,6 +283,8 @@ var kataCheckCLICommand = cli.Command{
|
|||||||
Usage: "tests if system can run " + project,
|
Usage: "tests if system can run " + project,
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
|
|
||||||
|
setCPUtype()
|
||||||
|
|
||||||
details := vmContainerCapableDetails{
|
details := vmContainerCapableDetails{
|
||||||
cpuInfoFile: procCPUInfo,
|
cpuInfoFile: procCPUInfo,
|
||||||
requiredCPUFlags: archRequiredCPUFlags,
|
requiredCPUFlags: archRequiredCPUFlags,
|
||||||
|
@ -7,52 +7,124 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
cpuFlagsTag = genericCPUFlagsTag
|
cpuFlagsTag = genericCPUFlagsTag
|
||||||
archCPUVendorField = genericCPUVendorField
|
archCPUVendorField = genericCPUVendorField
|
||||||
archCPUModelField = genericCPUModelField
|
archCPUModelField = genericCPUModelField
|
||||||
|
archGenuineIntel = "GenuineIntel"
|
||||||
|
archAuthenticAMD = "AuthenticAMD"
|
||||||
|
msgKernelVM = "Kernel-based Virtual Machine"
|
||||||
|
msgKernelVirtio = "Host kernel accelerator for virtio"
|
||||||
|
msgKernelVirtioNet = "Host kernel accelerator for virtio network"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// CPU types
|
||||||
|
const (
|
||||||
|
cpuTypeIntel = 0
|
||||||
|
cpuTypeAMD = 1
|
||||||
|
cpuTypeUnknown = -1
|
||||||
|
)
|
||||||
|
|
||||||
|
// cpuType save the CPU type
|
||||||
|
var cpuType int
|
||||||
|
|
||||||
// archRequiredCPUFlags maps a CPU flag value to search for and a
|
// archRequiredCPUFlags maps a CPU flag value to search for and a
|
||||||
// human-readable description of that value.
|
// human-readable description of that value.
|
||||||
var archRequiredCPUFlags = map[string]string{
|
var archRequiredCPUFlags map[string]string
|
||||||
"vmx": "Virtualization support",
|
|
||||||
"lm": "64Bit CPU",
|
|
||||||
"sse4_1": "SSE4.1",
|
|
||||||
}
|
|
||||||
|
|
||||||
// archRequiredCPUAttribs maps a CPU (non-CPU flag) attribute value to search for
|
// archRequiredCPUAttribs maps a CPU (non-CPU flag) attribute value to search for
|
||||||
// and a human-readable description of that value.
|
// and a human-readable description of that value.
|
||||||
var archRequiredCPUAttribs = map[string]string{
|
var archRequiredCPUAttribs map[string]string
|
||||||
"GenuineIntel": "Intel Architecture CPU",
|
|
||||||
}
|
|
||||||
|
|
||||||
// archRequiredKernelModules maps a required module name to a human-readable
|
// archRequiredKernelModules maps a required module name to a human-readable
|
||||||
// description of the modules functionality and an optional list of
|
// description of the modules functionality and an optional list of
|
||||||
// required module parameters.
|
// required module parameters.
|
||||||
var archRequiredKernelModules = map[string]kernelModule{
|
var archRequiredKernelModules map[string]kernelModule
|
||||||
"kvm": {
|
|
||||||
desc: "Kernel-based Virtual Machine",
|
func setCPUtype() {
|
||||||
},
|
cpuType = getCPUtype()
|
||||||
"kvm_intel": {
|
|
||||||
desc: "Intel KVM",
|
if cpuType == cpuTypeUnknown {
|
||||||
parameters: map[string]string{
|
kataLog.Fatal("Unknown CPU Type")
|
||||||
"nested": "Y",
|
exit(1)
|
||||||
// "VMX Unrestricted mode support". This is used
|
} else if cpuType == cpuTypeIntel {
|
||||||
// as a heuristic to determine if the system is
|
archRequiredCPUFlags = map[string]string{
|
||||||
// "new enough" to run a Kata Container
|
"vmx": "Virtualization support",
|
||||||
// (atleast a Westmere).
|
"lm": "64Bit CPU",
|
||||||
"unrestricted_guest": "Y",
|
"sse4_1": "SSE4.1",
|
||||||
},
|
}
|
||||||
},
|
archRequiredCPUAttribs = map[string]string{
|
||||||
"vhost": {
|
archGenuineIntel: "Intel Architecture CPU",
|
||||||
desc: "Host kernel accelerator for virtio",
|
}
|
||||||
},
|
archRequiredKernelModules = map[string]kernelModule{
|
||||||
"vhost_net": {
|
"kvm": {
|
||||||
desc: "Host kernel accelerator for virtio network",
|
desc: msgKernelVM,
|
||||||
},
|
},
|
||||||
|
"kvm_intel": {
|
||||||
|
desc: "Intel KVM",
|
||||||
|
parameters: map[string]string{
|
||||||
|
"nested": "Y",
|
||||||
|
// "VMX Unrestricted mode support". This is used
|
||||||
|
// as a heuristic to determine if the system is
|
||||||
|
// "new enough" to run a Kata Container
|
||||||
|
// (atleast a Westmere).
|
||||||
|
"unrestricted_guest": "Y",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"vhost": {
|
||||||
|
desc: msgKernelVirtio,
|
||||||
|
},
|
||||||
|
"vhost_net": {
|
||||||
|
desc: msgKernelVirtioNet,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else if cpuType == cpuTypeAMD {
|
||||||
|
archRequiredCPUFlags = map[string]string{
|
||||||
|
"svm": "Virtualization support",
|
||||||
|
"lm": "64Bit CPU",
|
||||||
|
"sse4_1": "SSE4.1",
|
||||||
|
}
|
||||||
|
archRequiredCPUAttribs = map[string]string{
|
||||||
|
archAuthenticAMD: "AMD Architecture CPU",
|
||||||
|
}
|
||||||
|
archRequiredKernelModules = map[string]kernelModule{
|
||||||
|
"kvm": {
|
||||||
|
desc: msgKernelVM,
|
||||||
|
},
|
||||||
|
"kvm_amd": {
|
||||||
|
desc: "AMD KVM",
|
||||||
|
parameters: map[string]string{
|
||||||
|
"nested": "1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"vhost": {
|
||||||
|
desc: msgKernelVirtio,
|
||||||
|
},
|
||||||
|
"vhost_net": {
|
||||||
|
desc: msgKernelVirtioNet,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCPUtype() int {
|
||||||
|
content, err := ioutil.ReadFile("/proc/cpuinfo")
|
||||||
|
if err != nil {
|
||||||
|
kataLog.WithError(err).Error("failed to read file")
|
||||||
|
return cpuTypeUnknown
|
||||||
|
}
|
||||||
|
str := string(content)
|
||||||
|
if strings.Contains(str, archGenuineIntel) {
|
||||||
|
return cpuTypeIntel
|
||||||
|
} else if strings.Contains(str, archAuthenticAMD) {
|
||||||
|
return cpuTypeAMD
|
||||||
|
} else {
|
||||||
|
return cpuTypeUnknown
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// kvmIsUsable determines if it will be possible to create a full virtual machine
|
// kvmIsUsable determines if it will be possible to create a full virtual machine
|
||||||
|
@ -73,13 +73,26 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cpuData := []testCPUData{
|
var cpuData []testCPUData
|
||||||
{"GenuineIntel", "lm vmx sse4_1", false},
|
var moduleData []testModuleData
|
||||||
}
|
|
||||||
|
|
||||||
moduleData := []testModuleData{
|
if cpuType == cpuTypeIntel {
|
||||||
{filepath.Join(sysModuleDir, "kvm_intel/parameters/unrestricted_guest"), false, "Y"},
|
cpuData = []testCPUData{
|
||||||
{filepath.Join(sysModuleDir, "kvm_intel/parameters/nested"), false, "Y"},
|
{archGenuineIntel, "lm vmx sse4_1", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
moduleData = []testModuleData{
|
||||||
|
{filepath.Join(sysModuleDir, "kvm_intel/parameters/unrestricted_guest"), false, "Y"},
|
||||||
|
{filepath.Join(sysModuleDir, "kvm_intel/parameters/nested"), false, "Y"},
|
||||||
|
}
|
||||||
|
} else if cpuType == cpuTypeAMD {
|
||||||
|
cpuData = []testCPUData{
|
||||||
|
{archAuthenticAMD, "lm svm sse4_1", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
moduleData = []testModuleData{
|
||||||
|
{filepath.Join(sysModuleDir, "kvm_amd/parameters/nested"), false, "1"},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
devNull, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0666)
|
devNull, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0666)
|
||||||
@ -175,7 +188,7 @@ func TestCheckCheckKernelModulesNoNesting(t *testing.T) {
|
|||||||
{filepath.Join(sysModuleDir, "kvm_intel/parameters/nested"), false, "N"},
|
{filepath.Join(sysModuleDir, "kvm_intel/parameters/nested"), false, "N"},
|
||||||
}
|
}
|
||||||
|
|
||||||
vendor := "GenuineIntel"
|
vendor := archGenuineIntel
|
||||||
flags := "vmx lm sse4_1 hypervisor"
|
flags := "vmx lm sse4_1 hypervisor"
|
||||||
|
|
||||||
_, err = checkKernelModules(requiredModules, archKernelParamHandler)
|
_, err = checkKernelModules(requiredModules, archKernelParamHandler)
|
||||||
@ -259,7 +272,7 @@ func TestCheckCheckKernelModulesNoUnrestrictedGuest(t *testing.T) {
|
|||||||
{filepath.Join(sysModuleDir, "kvm_intel/parameters/unrestricted_guest"), false, "N"},
|
{filepath.Join(sysModuleDir, "kvm_intel/parameters/unrestricted_guest"), false, "N"},
|
||||||
}
|
}
|
||||||
|
|
||||||
vendor := "GenuineIntel"
|
vendor := archGenuineIntel
|
||||||
flags := "vmx lm sse4_1"
|
flags := "vmx lm sse4_1"
|
||||||
|
|
||||||
_, err = checkKernelModules(requiredModules, archKernelParamHandler)
|
_, err = checkKernelModules(requiredModules, archKernelParamHandler)
|
||||||
@ -334,20 +347,40 @@ func TestCheckHostIsVMContainerCapable(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cpuData := []testCPUData{
|
var cpuData []testCPUData
|
||||||
{"", "", true},
|
var moduleData []testModuleData
|
||||||
{"Intel", "", true},
|
|
||||||
{"GenuineIntel", "", true},
|
|
||||||
{"GenuineIntel", "lm", true},
|
|
||||||
{"GenuineIntel", "lm vmx", true},
|
|
||||||
{"GenuineIntel", "lm vmx sse4_1", false},
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleData := []testModuleData{
|
if cpuType == cpuTypeIntel {
|
||||||
{filepath.Join(sysModuleDir, "kvm"), true, ""},
|
cpuData = []testCPUData{
|
||||||
{filepath.Join(sysModuleDir, "kvm_intel"), true, ""},
|
{"", "", true},
|
||||||
{filepath.Join(sysModuleDir, "kvm_intel/parameters/nested"), false, "Y"},
|
{"Intel", "", true},
|
||||||
{filepath.Join(sysModuleDir, "kvm_intel/parameters/unrestricted_guest"), false, "Y"},
|
{archGenuineIntel, "", true},
|
||||||
|
{archGenuineIntel, "lm", true},
|
||||||
|
{archGenuineIntel, "lm vmx", true},
|
||||||
|
{archGenuineIntel, "lm vmx sse4_1", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
moduleData = []testModuleData{
|
||||||
|
{filepath.Join(sysModuleDir, "kvm"), true, ""},
|
||||||
|
{filepath.Join(sysModuleDir, "kvm_intel"), true, ""},
|
||||||
|
{filepath.Join(sysModuleDir, "kvm_intel/parameters/nested"), false, "Y"},
|
||||||
|
{filepath.Join(sysModuleDir, "kvm_intel/parameters/unrestricted_guest"), false, "Y"},
|
||||||
|
}
|
||||||
|
} else if cpuType == cpuTypeAMD {
|
||||||
|
cpuData = []testCPUData{
|
||||||
|
{"", "", true},
|
||||||
|
{"AMD", "", true},
|
||||||
|
{archAuthenticAMD, "", true},
|
||||||
|
{archAuthenticAMD, "lm", true},
|
||||||
|
{archAuthenticAMD, "lm svm", true},
|
||||||
|
{archAuthenticAMD, "lm svm sse4_1", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
moduleData = []testModuleData{
|
||||||
|
{filepath.Join(sysModuleDir, "kvm"), true, ""},
|
||||||
|
{filepath.Join(sysModuleDir, "kvm_amd"), true, ""},
|
||||||
|
{filepath.Join(sysModuleDir, "kvm_amd/parameters/nested"), false, "1"},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setupCheckHostIsVMContainerCapable(assert, cpuInfoFile, cpuData, moduleData)
|
setupCheckHostIsVMContainerCapable(assert, cpuInfoFile, cpuData, moduleData)
|
||||||
|
@ -40,6 +40,9 @@ var archRequiredKernelModules = map[string]kernelModule{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setCPUtype() {
|
||||||
|
}
|
||||||
|
|
||||||
// kvmIsUsable determines if it will be possible to create a full virtual machine
|
// kvmIsUsable determines if it will be possible to create a full virtual machine
|
||||||
// by creating a minimal VM and then deleting it.
|
// by creating a minimal VM and then deleting it.
|
||||||
func kvmIsUsable() error {
|
func kvmIsUsable() error {
|
||||||
|
@ -44,6 +44,9 @@ var archRequiredKernelModules = map[string]kernelModule{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setCPUtype() {
|
||||||
|
}
|
||||||
|
|
||||||
func archHostCanCreateVMContainer() error {
|
func archHostCanCreateVMContainer() error {
|
||||||
return kvmIsUsable()
|
return kvmIsUsable()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user