mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-30 09:13:29 +00:00
kata-check: Check and validate type-1 hypervisor for kata
ACRN hypervisor is a type-1 hypervisor and this patch adds support to check and validate if the system is capable of running kata containers with ACRN hypervisor. Depends-on: github.com/kata-containers/tests#1793 v3->v4: Implemented a generic way to identify hypervisor and test VM creation. v2->v3: 1. Removed cgo structs and defined go structs. 2. Suppressed lint warnings due to unused createVM struct. v1->v2: 1. Created an issue #1784 to address TODO item. 2. Fixed formatting of the log message. 3. Currently ACRN is only supported on amd64. So moved ACRN specific code to kata-check_amd64.go. Fixes: #1778 Signed-off-by: Vijay Dhanraj <vijay.dhanraj@intel.com>
This commit is contained in:
parent
4d26ceee79
commit
adcac9368f
@ -16,6 +16,7 @@ const int ioctl_KVM_CHECK_EXTENSION = KVM_CHECK_EXTENSION;
|
|||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@ -26,6 +27,7 @@ import (
|
|||||||
|
|
||||||
"github.com/kata-containers/runtime/pkg/katautils"
|
"github.com/kata-containers/runtime/pkg/katautils"
|
||||||
vc "github.com/kata-containers/runtime/virtcontainers"
|
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||||
|
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@ -311,7 +313,12 @@ var kataCheckCLICommand = cli.Command{
|
|||||||
span, _ := katautils.Trace(ctx, "kata-check")
|
span, _ := katautils.Trace(ctx, "kata-check")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
err = setCPUtype()
|
runtimeConfig, ok := context.App.Metadata["runtimeConfig"].(oci.RuntimeConfig)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("kata-check: cannot determine runtime config")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = setCPUtype(runtimeConfig.HypervisorType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -332,7 +339,7 @@ var kataCheckCLICommand = cli.Command{
|
|||||||
kataLog.Info(successMessageCapable)
|
kataLog.Info(successMessageCapable)
|
||||||
|
|
||||||
if os.Geteuid() == 0 {
|
if os.Geteuid() == 0 {
|
||||||
err = archHostCanCreateVMContainer()
|
err = archHostCanCreateVMContainer(runtimeConfig.HypervisorType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,13 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
vc "github.com/kata-containers/runtime/virtcontainers"
|
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -24,6 +26,17 @@ const (
|
|||||||
msgKernelVirtio = "Host kernel accelerator for virtio"
|
msgKernelVirtio = "Host kernel accelerator for virtio"
|
||||||
msgKernelVirtioNet = "Host kernel accelerator for virtio network"
|
msgKernelVirtioNet = "Host kernel accelerator for virtio network"
|
||||||
msgKernelVirtioVhostVsock = "Host Support for Linux VM Sockets"
|
msgKernelVirtioVhostVsock = "Host Support for Linux VM Sockets"
|
||||||
|
cpuFlagVMX = "vmx"
|
||||||
|
cpuFlagLM = "lm"
|
||||||
|
cpuFlagSVM = "svm"
|
||||||
|
cpuFlagSSE4_1 = "sse4_1"
|
||||||
|
kernelModvhm = "vhm_dev"
|
||||||
|
kernelModvhost = "vhost"
|
||||||
|
kernelModvhostnet = "vhost_net"
|
||||||
|
kernelModvhostvsock = "vhost_vsock"
|
||||||
|
kernelModkvm = "kvm"
|
||||||
|
kernelModkvmintel = "kvm_intel"
|
||||||
|
kernelModkvmamd = "kvm_amd"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CPU types
|
// CPU types
|
||||||
@ -33,6 +46,28 @@ const (
|
|||||||
cpuTypeUnknown = -1
|
cpuTypeUnknown = -1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const acrnDevice = "/dev/acrn_vhm"
|
||||||
|
|
||||||
|
// ioctl_ACRN_CREATE_VM is the IOCTL to create VM in ACRN.
|
||||||
|
// Current Linux mainstream kernel doesn't have support for ACRN.
|
||||||
|
// Due to this several macros are not defined in Linux headers.
|
||||||
|
// Until the support is available, directly use the value instead
|
||||||
|
// of macros.
|
||||||
|
//https://github.com/kata-containers/runtime/issues/1784
|
||||||
|
const ioctl_ACRN_CREATE_VM = 0x43000010 //nolint
|
||||||
|
const ioctl_ACRN_DESTROY_VM = 0x43000011 //nolint
|
||||||
|
|
||||||
|
type acrn_create_vm struct { //nolint
|
||||||
|
vmid uint16 //nolint
|
||||||
|
reserved0 uint16 //nolint
|
||||||
|
vcpu_num uint16 //nolint
|
||||||
|
reserved1 uint16 //nolint
|
||||||
|
uuid [16]uint8
|
||||||
|
vm_flag uint64 //nolint
|
||||||
|
req_buf uint64 //nolint
|
||||||
|
reserved2 [16]uint8 //nolint
|
||||||
|
}
|
||||||
|
|
||||||
// cpuType save the CPU type
|
// cpuType save the CPU type
|
||||||
var cpuType int
|
var cpuType int
|
||||||
|
|
||||||
@ -49,7 +84,7 @@ var archRequiredCPUAttribs map[string]string
|
|||||||
// required module parameters.
|
// required module parameters.
|
||||||
var archRequiredKernelModules map[string]kernelModule
|
var archRequiredKernelModules map[string]kernelModule
|
||||||
|
|
||||||
func setCPUtype() error {
|
func setCPUtype(hypervisorType vc.HypervisorType) error {
|
||||||
cpuType = getCPUtype()
|
cpuType = getCPUtype()
|
||||||
|
|
||||||
if cpuType == cpuTypeUnknown {
|
if cpuType == cpuTypeUnknown {
|
||||||
@ -66,64 +101,88 @@ func setCPUtype() error {
|
|||||||
"unrestricted_guest": "Y",
|
"unrestricted_guest": "Y",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
archRequiredCPUFlags = map[string]string{
|
|
||||||
"vmx": "Virtualization support",
|
switch hypervisorType {
|
||||||
"lm": "64Bit CPU",
|
case "firecracker":
|
||||||
"sse4_1": "SSE4.1",
|
fallthrough
|
||||||
}
|
case "qemu":
|
||||||
archRequiredCPUAttribs = map[string]string{
|
archRequiredCPUFlags = map[string]string{
|
||||||
archGenuineIntel: "Intel Architecture CPU",
|
cpuFlagVMX: "Virtualization support",
|
||||||
}
|
cpuFlagLM: "64Bit CPU",
|
||||||
archRequiredKernelModules = map[string]kernelModule{
|
cpuFlagSSE4_1: "SSE4.1",
|
||||||
"kvm": {
|
}
|
||||||
desc: msgKernelVM,
|
archRequiredCPUAttribs = map[string]string{
|
||||||
required: true,
|
archGenuineIntel: "Intel Architecture CPU",
|
||||||
},
|
}
|
||||||
"kvm_intel": {
|
archRequiredKernelModules = map[string]kernelModule{
|
||||||
desc: "Intel KVM",
|
kernelModkvm: {
|
||||||
parameters: kvmIntelParams,
|
desc: msgKernelVM,
|
||||||
required: true,
|
},
|
||||||
},
|
kernelModkvmintel: {
|
||||||
"vhost": {
|
desc: "Intel KVM",
|
||||||
desc: msgKernelVirtio,
|
parameters: kvmIntelParams,
|
||||||
required: true,
|
},
|
||||||
},
|
kernelModvhost: {
|
||||||
"vhost_net": {
|
desc: msgKernelVirtio,
|
||||||
desc: msgKernelVirtioNet,
|
},
|
||||||
required: true,
|
kernelModvhostnet: {
|
||||||
},
|
desc: msgKernelVirtioNet,
|
||||||
"vhost_vsock": {
|
},
|
||||||
desc: msgKernelVirtioVhostVsock,
|
kernelModvhostvsock: {
|
||||||
required: false,
|
desc: msgKernelVirtioVhostVsock,
|
||||||
},
|
required: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
case "acrn":
|
||||||
|
archRequiredCPUFlags = map[string]string{
|
||||||
|
cpuFlagLM: "64Bit CPU",
|
||||||
|
cpuFlagSSE4_1: "SSE4.1",
|
||||||
|
}
|
||||||
|
archRequiredCPUAttribs = map[string]string{
|
||||||
|
archGenuineIntel: "Intel Architecture CPU",
|
||||||
|
}
|
||||||
|
archRequiredKernelModules = map[string]kernelModule{
|
||||||
|
kernelModvhm: {
|
||||||
|
desc: "Intel ACRN",
|
||||||
|
},
|
||||||
|
kernelModvhost: {
|
||||||
|
desc: msgKernelVirtio,
|
||||||
|
},
|
||||||
|
kernelModvhostnet: {
|
||||||
|
desc: msgKernelVirtioNet,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("setCPUtype: Unknown hypervisor type %s", hypervisorType)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if cpuType == cpuTypeAMD {
|
} else if cpuType == cpuTypeAMD {
|
||||||
archRequiredCPUFlags = map[string]string{
|
archRequiredCPUFlags = map[string]string{
|
||||||
"svm": "Virtualization support",
|
cpuFlagSVM: "Virtualization support",
|
||||||
"lm": "64Bit CPU",
|
cpuFlagLM: "64Bit CPU",
|
||||||
"sse4_1": "SSE4.1",
|
cpuFlagSSE4_1: "SSE4.1",
|
||||||
}
|
}
|
||||||
archRequiredCPUAttribs = map[string]string{
|
archRequiredCPUAttribs = map[string]string{
|
||||||
archAuthenticAMD: "AMD Architecture CPU",
|
archAuthenticAMD: "AMD Architecture CPU",
|
||||||
}
|
}
|
||||||
archRequiredKernelModules = map[string]kernelModule{
|
archRequiredKernelModules = map[string]kernelModule{
|
||||||
"kvm": {
|
kernelModkvm: {
|
||||||
desc: msgKernelVM,
|
desc: msgKernelVM,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
"kvm_amd": {
|
kernelModkvmamd: {
|
||||||
desc: "AMD KVM",
|
desc: "AMD KVM",
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
"vhost": {
|
kernelModvhost: {
|
||||||
desc: msgKernelVirtio,
|
desc: msgKernelVirtio,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
"vhost_net": {
|
kernelModvhostnet: {
|
||||||
desc: msgKernelVirtioNet,
|
desc: msgKernelVirtioNet,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
"vhost_vsock": {
|
kernelModvhostvsock: {
|
||||||
desc: msgKernelVirtioVhostVsock,
|
desc: msgKernelVirtioVhostVsock,
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
@ -155,8 +214,72 @@ func kvmIsUsable() error {
|
|||||||
return genericKvmIsUsable()
|
return genericKvmIsUsable()
|
||||||
}
|
}
|
||||||
|
|
||||||
func archHostCanCreateVMContainer() error {
|
// acrnIsUsable determines if it will be possible to create a full virtual machine
|
||||||
return kvmIsUsable()
|
// by creating a minimal VM and then deleting it.
|
||||||
|
func acrnIsUsable() error {
|
||||||
|
flags := syscall.O_RDWR | syscall.O_CLOEXEC
|
||||||
|
|
||||||
|
f, err := syscall.Open(acrnDevice, flags, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer syscall.Close(f)
|
||||||
|
|
||||||
|
fieldLogger := kataLog.WithField("check-type", "full")
|
||||||
|
|
||||||
|
fieldLogger.WithField("device", acrnDevice).Info("device available")
|
||||||
|
|
||||||
|
createVM := acrn_create_vm{
|
||||||
|
uuid: [16]uint8{
|
||||||
|
0xd2, 0x79, 0x54, 0x38, 0x25, 0xd6, 0x11, 0xe8,
|
||||||
|
0x86, 0x4e, 0xcb, 0x7a, 0x18, 0xb3, 0x46, 0x43,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
ret, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
|
||||||
|
uintptr(f),
|
||||||
|
uintptr(ioctl_ACRN_CREATE_VM),
|
||||||
|
uintptr(unsafe.Pointer(&createVM)))
|
||||||
|
if ret != 0 || errno != 0 {
|
||||||
|
if errno == syscall.EBUSY {
|
||||||
|
fieldLogger.WithField("reason", "another hypervisor running").Error("cannot create VM")
|
||||||
|
}
|
||||||
|
fieldLogger.WithFields(logrus.Fields{
|
||||||
|
"ret": ret,
|
||||||
|
"errno": errno,
|
||||||
|
}).Info("Create VM Error")
|
||||||
|
return errno
|
||||||
|
}
|
||||||
|
|
||||||
|
ret, _, errno = syscall.Syscall(syscall.SYS_IOCTL,
|
||||||
|
uintptr(f),
|
||||||
|
uintptr(ioctl_ACRN_DESTROY_VM),
|
||||||
|
0)
|
||||||
|
if ret != 0 || errno != 0 {
|
||||||
|
fieldLogger.WithFields(logrus.Fields{
|
||||||
|
"ret": ret,
|
||||||
|
"errno": errno,
|
||||||
|
}).Info("Destroy VM Error")
|
||||||
|
return errno
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldLogger.WithField("feature", "create-vm").Info("feature available")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error {
|
||||||
|
|
||||||
|
switch hypervisorType {
|
||||||
|
case "qemu":
|
||||||
|
fallthrough
|
||||||
|
case "firecracker":
|
||||||
|
return kvmIsUsable()
|
||||||
|
case "acrn":
|
||||||
|
return acrnIsUsable()
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("archHostCanCreateVMContainer: Unknown hypervisor type %s", hypervisorType)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// hostIsVMContainerCapable checks to see if the host is theoretically capable
|
// hostIsVMContainerCapable checks to see if the host is theoretically capable
|
||||||
|
@ -55,6 +55,9 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
_, config, err := makeRuntimeConfig(dir)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
savedSysModuleDir := sysModuleDir
|
savedSysModuleDir := sysModuleDir
|
||||||
savedProcCPUInfo := procCPUInfo
|
savedProcCPUInfo := procCPUInfo
|
||||||
|
|
||||||
@ -108,6 +111,7 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
|||||||
|
|
||||||
ctx := createCLIContext(nil)
|
ctx := createCLIContext(nil)
|
||||||
ctx.App.Name = "foo"
|
ctx.App.Name = "foo"
|
||||||
|
ctx.App.Metadata["runtimeConfig"] = config
|
||||||
|
|
||||||
// create buffer to save logger output
|
// create buffer to save logger output
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
@ -514,6 +518,10 @@ foo : bar
|
|||||||
func TestSetCPUtype(t *testing.T) {
|
func TestSetCPUtype(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tmpdir, err := ioutil.TempDir("", "")
|
||||||
|
assert.NoError(err)
|
||||||
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
savedArchRequiredCPUFlags := archRequiredCPUFlags
|
savedArchRequiredCPUFlags := archRequiredCPUFlags
|
||||||
savedArchRequiredCPUAttribs := archRequiredCPUAttribs
|
savedArchRequiredCPUAttribs := archRequiredCPUAttribs
|
||||||
savedArchRequiredKernelModules := archRequiredKernelModules
|
savedArchRequiredKernelModules := archRequiredKernelModules
|
||||||
@ -528,7 +536,10 @@ func TestSetCPUtype(t *testing.T) {
|
|||||||
archRequiredCPUAttribs = map[string]string{}
|
archRequiredCPUAttribs = map[string]string{}
|
||||||
archRequiredKernelModules = map[string]kernelModule{}
|
archRequiredKernelModules = map[string]kernelModule{}
|
||||||
|
|
||||||
setCPUtype()
|
_, config, err := makeRuntimeConfig(tmpdir)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
setCPUtype(config.HypervisorType)
|
||||||
|
|
||||||
assert.NotEmpty(archRequiredCPUFlags)
|
assert.NotEmpty(archRequiredCPUFlags)
|
||||||
assert.NotEmpty(archRequiredCPUAttribs)
|
assert.NotEmpty(archRequiredCPUAttribs)
|
||||||
|
@ -8,6 +8,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -56,7 +57,7 @@ var archRequiredKVMExtensions = map[string]kvmExtension{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func setCPUtype() error {
|
func setCPUtype(hypervisorType vc.HypervisorType) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +85,7 @@ func checkKVMExtensions() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func archHostCanCreateVMContainer() error {
|
func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error {
|
||||||
if err := kvmIsUsable(); err != nil {
|
if err := kvmIsUsable(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,9 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
_, config, err := makeRuntimeConfig(dir)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
savedSysModuleDir := sysModuleDir
|
savedSysModuleDir := sysModuleDir
|
||||||
savedProcCPUInfo := procCPUInfo
|
savedProcCPUInfo := procCPUInfo
|
||||||
|
|
||||||
@ -78,6 +81,7 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
|||||||
|
|
||||||
ctx := createCLIContext(nil)
|
ctx := createCLIContext(nil)
|
||||||
ctx.App.Name = "foo"
|
ctx.App.Name = "foo"
|
||||||
|
ctx.App.Metadata["runtimeConfig"] = config
|
||||||
|
|
||||||
// create buffer to save logger output
|
// create buffer to save logger output
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -16,6 +18,10 @@ import (
|
|||||||
func testSetCPUTypeGeneric(t *testing.T) {
|
func testSetCPUTypeGeneric(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tmpdir, err := ioutil.TempDir("", "")
|
||||||
|
assert.NoError(err)
|
||||||
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
savedArchRequiredCPUFlags := archRequiredCPUFlags
|
savedArchRequiredCPUFlags := archRequiredCPUFlags
|
||||||
savedArchRequiredCPUAttribs := archRequiredCPUAttribs
|
savedArchRequiredCPUAttribs := archRequiredCPUAttribs
|
||||||
savedArchRequiredKernelModules := archRequiredKernelModules
|
savedArchRequiredKernelModules := archRequiredKernelModules
|
||||||
@ -30,7 +36,10 @@ func testSetCPUTypeGeneric(t *testing.T) {
|
|||||||
assert.Empty(archRequiredCPUAttribs)
|
assert.Empty(archRequiredCPUAttribs)
|
||||||
assert.NotEmpty(archRequiredKernelModules)
|
assert.NotEmpty(archRequiredKernelModules)
|
||||||
|
|
||||||
setCPUtype()
|
_, config, err := makeRuntimeConfig(tmpdir)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
setCPUtype(config.HypervisorType)
|
||||||
|
|
||||||
assert.Equal(archRequiredCPUFlags, savedArchRequiredCPUFlags)
|
assert.Equal(archRequiredCPUFlags, savedArchRequiredCPUFlags)
|
||||||
assert.Equal(archRequiredCPUAttribs, savedArchRequiredCPUAttribs)
|
assert.Equal(archRequiredCPUAttribs, savedArchRequiredCPUAttribs)
|
||||||
|
@ -8,12 +8,13 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/kata-containers/runtime/pkg/katautils"
|
"github.com/kata-containers/runtime/pkg/katautils"
|
||||||
|
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -55,11 +56,11 @@ var archRequiredKernelModules = map[string]kernelModule{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func setCPUtype() error {
|
func setCPUtype(hypervisorType vc.HypervisorType) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func archHostCanCreateVMContainer() error {
|
func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error {
|
||||||
return kvmIsUsable()
|
return kvmIsUsable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,9 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
_, config, err := makeRuntimeConfig(dir)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
savedSysModuleDir := sysModuleDir
|
savedSysModuleDir := sysModuleDir
|
||||||
savedProcCPUInfo := procCPUInfo
|
savedProcCPUInfo := procCPUInfo
|
||||||
|
|
||||||
@ -98,6 +101,7 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
|||||||
|
|
||||||
ctx := createCLIContext(nil)
|
ctx := createCLIContext(nil)
|
||||||
ctx.App.Name = "foo"
|
ctx.App.Name = "foo"
|
||||||
|
ctx.App.Metadata["runtimeConfig"] = config
|
||||||
|
|
||||||
// create buffer to save logger output
|
// create buffer to save logger output
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
|
@ -7,8 +7,10 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -42,7 +44,7 @@ var archRequiredKernelModules = map[string]kernelModule{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func setCPUtype() error {
|
func setCPUtype(hypervisorType vc.HypervisorType) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +54,7 @@ func kvmIsUsable() error {
|
|||||||
return genericKvmIsUsable()
|
return genericKvmIsUsable()
|
||||||
}
|
}
|
||||||
|
|
||||||
func archHostCanCreateVMContainer() error {
|
func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error {
|
||||||
return kvmIsUsable()
|
return kvmIsUsable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,9 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
_, config, err := makeRuntimeConfig(dir)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
savedSysModuleDir := sysModuleDir
|
savedSysModuleDir := sysModuleDir
|
||||||
savedProcCPUInfo := procCPUInfo
|
savedProcCPUInfo := procCPUInfo
|
||||||
|
|
||||||
@ -97,6 +100,7 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
|||||||
|
|
||||||
ctx := createCLIContext(nil)
|
ctx := createCLIContext(nil)
|
||||||
ctx.App.Name = "foo"
|
ctx.App.Name = "foo"
|
||||||
|
ctx.App.Metadata["runtimeConfig"] = config
|
||||||
|
|
||||||
// create buffer to save logger output
|
// create buffer to save logger output
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
|
@ -659,6 +659,9 @@ func TestCheckCLIFunctionFail(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
_, config, err := makeRuntimeConfig(dir)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
oldProcCPUInfo := procCPUInfo
|
oldProcCPUInfo := procCPUInfo
|
||||||
|
|
||||||
// doesn't exist
|
// doesn't exist
|
||||||
@ -670,6 +673,7 @@ func TestCheckCLIFunctionFail(t *testing.T) {
|
|||||||
|
|
||||||
ctx := createCLIContext(nil)
|
ctx := createCLIContext(nil)
|
||||||
ctx.App.Name = "foo"
|
ctx.App.Name = "foo"
|
||||||
|
ctx.App.Metadata["runtimeConfig"] = config
|
||||||
|
|
||||||
fn, ok := kataCheckCLICommand.Action.(func(context *cli.Context) error)
|
fn, ok := kataCheckCLICommand.Action.(func(context *cli.Context) error)
|
||||||
assert.True(ok)
|
assert.True(ok)
|
||||||
|
@ -9,9 +9,8 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
|
|
||||||
runtim "runtime"
|
runtim "runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
"github.com/kata-containers/runtime/pkg/katautils"
|
"github.com/kata-containers/runtime/pkg/katautils"
|
||||||
@ -358,7 +357,7 @@ func getHypervisorInfo(config oci.RuntimeConfig) HypervisorInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getEnvInfo(configFile string, config oci.RuntimeConfig) (env EnvInfo, err error) {
|
func getEnvInfo(configFile string, config oci.RuntimeConfig) (env EnvInfo, err error) {
|
||||||
err = setCPUtype()
|
err = setCPUtype(config.HypervisorType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return EnvInfo{}, err
|
return EnvInfo{}, err
|
||||||
}
|
}
|
||||||
|
102
cli/main.go
102
cli/main.go
@ -254,54 +254,54 @@ func beforeSubcommands(c *cli.Context) error {
|
|||||||
|
|
||||||
handleShowConfig(c)
|
handleShowConfig(c)
|
||||||
|
|
||||||
if userWantsUsage(c) || (c.NArg() == 1 && (c.Args()[0] == checkCmd)) {
|
if userWantsUsage(c) {
|
||||||
// No setup required if the user just
|
// No setup required if the user just
|
||||||
// wants to see the usage statement or are
|
// wants to see the usage statement.
|
||||||
// running a command that does not manipulate
|
|
||||||
// containers.
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if path := c.GlobalString("log"); path != "" {
|
ignoreLogging := false
|
||||||
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND|os.O_SYNC, 0640)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
kataLog.Logger.Out = f
|
|
||||||
}
|
|
||||||
|
|
||||||
switch c.GlobalString("log-format") {
|
|
||||||
case "text":
|
|
||||||
// retain logrus's default.
|
|
||||||
case "json":
|
|
||||||
kataLog.Logger.Formatter = new(logrus.JSONFormatter)
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("unknown log-format %q", c.GlobalString("log-format"))
|
|
||||||
}
|
|
||||||
|
|
||||||
var traceRootSpan string
|
var traceRootSpan string
|
||||||
|
|
||||||
// Add the name of the sub-command to each log entry for easier
|
subCmdIsCheckCmd := (c.NArg() == 1 && (c.Args()[0] == checkCmd))
|
||||||
// debugging.
|
if !subCmdIsCheckCmd {
|
||||||
cmdName := c.Args().First()
|
if path := c.GlobalString("log"); path != "" {
|
||||||
if c.App.Command(cmdName) != nil {
|
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND|os.O_SYNC, 0640)
|
||||||
kataLog = kataLog.WithField("command", cmdName)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
kataLog.Logger.Out = f
|
||||||
|
}
|
||||||
|
|
||||||
// Name for the root span (used for tracing) now the
|
switch c.GlobalString("log-format") {
|
||||||
// sub-command name is known.
|
case "text":
|
||||||
traceRootSpan = name + " " + cmdName
|
// retain logrus's default.
|
||||||
}
|
case "json":
|
||||||
|
kataLog.Logger.Formatter = new(logrus.JSONFormatter)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown log-format %q", c.GlobalString("log-format"))
|
||||||
|
}
|
||||||
|
|
||||||
// Since a context is required, pass a new (throw-away) one - we
|
// Add the name of the sub-command to each log entry for easier
|
||||||
// cannot use the main context as tracing hasn't been enabled yet
|
// debugging.
|
||||||
// (meaning any spans created at this point will be silently ignored).
|
cmdName := c.Args().First()
|
||||||
setExternalLoggers(context.Background(), kataLog)
|
if c.App.Command(cmdName) != nil {
|
||||||
|
kataLog = kataLog.WithField("command", cmdName)
|
||||||
|
|
||||||
ignoreLogging := false
|
// Name for the root span (used for tracing) now the
|
||||||
|
// sub-command name is known.
|
||||||
|
traceRootSpan = name + " " + cmdName
|
||||||
|
}
|
||||||
|
|
||||||
if c.NArg() == 1 && c.Args()[0] == envCmd {
|
// Since a context is required, pass a new (throw-away) one - we
|
||||||
// simply report the logging setup
|
// cannot use the main context as tracing hasn't been enabled yet
|
||||||
ignoreLogging = true
|
// (meaning any spans created at this point will be silently ignored).
|
||||||
|
setExternalLoggers(context.Background(), kataLog)
|
||||||
|
|
||||||
|
if c.NArg() == 1 && c.Args()[0] == envCmd {
|
||||||
|
// simply report the logging setup
|
||||||
|
ignoreLogging = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configFile, runtimeConfig, err = katautils.LoadConfiguration(c.GlobalString(configFilePathOption), ignoreLogging, false)
|
configFile, runtimeConfig, err = katautils.LoadConfiguration(c.GlobalString(configFilePathOption), ignoreLogging, false)
|
||||||
@ -309,19 +309,21 @@ func beforeSubcommands(c *cli.Context) error {
|
|||||||
fatal(err)
|
fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
debug = runtimeConfig.Debug
|
if !subCmdIsCheckCmd {
|
||||||
crashOnError = runtimeConfig.Debug
|
debug = runtimeConfig.Debug
|
||||||
|
crashOnError = runtimeConfig.Debug
|
||||||
|
|
||||||
if traceRootSpan != "" {
|
if traceRootSpan != "" {
|
||||||
// Create the tracer.
|
// Create the tracer.
|
||||||
//
|
//
|
||||||
// Note: no spans are created until the command-line has been parsed.
|
// Note: no spans are created until the command-line has been parsed.
|
||||||
// This delays collection of trace data slightly but benefits the user by
|
// This delays collection of trace data slightly but benefits the user by
|
||||||
// ensuring the first span is the name of the sub-command being
|
// ensuring the first span is the name of the sub-command being
|
||||||
// invoked from the command-line.
|
// invoked from the command-line.
|
||||||
err = setupTracing(c, traceRootSpan)
|
err = setupTracing(c, traceRootSpan)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user