mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-30 01:02:33 +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 (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
@ -26,6 +27,7 @@ import (
|
||||
|
||||
"github.com/kata-containers/runtime/pkg/katautils"
|
||||
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
@ -311,7 +313,12 @@ var kataCheckCLICommand = cli.Command{
|
||||
span, _ := katautils.Trace(ctx, "kata-check")
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@ -332,7 +339,7 @@ var kataCheckCLICommand = cli.Command{
|
||||
kataLog.Info(successMessageCapable)
|
||||
|
||||
if os.Geteuid() == 0 {
|
||||
err = archHostCanCreateVMContainer()
|
||||
err = archHostCanCreateVMContainer(runtimeConfig.HypervisorType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -7,11 +7,13 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sirupsen/logrus"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -24,6 +26,17 @@ const (
|
||||
msgKernelVirtio = "Host kernel accelerator for virtio"
|
||||
msgKernelVirtioNet = "Host kernel accelerator for virtio network"
|
||||
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
|
||||
@ -33,6 +46,28 @@ const (
|
||||
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
|
||||
var cpuType int
|
||||
|
||||
@ -49,7 +84,7 @@ var archRequiredCPUAttribs map[string]string
|
||||
// required module parameters.
|
||||
var archRequiredKernelModules map[string]kernelModule
|
||||
|
||||
func setCPUtype() error {
|
||||
func setCPUtype(hypervisorType vc.HypervisorType) error {
|
||||
cpuType = getCPUtype()
|
||||
|
||||
if cpuType == cpuTypeUnknown {
|
||||
@ -66,64 +101,88 @@ func setCPUtype() error {
|
||||
"unrestricted_guest": "Y",
|
||||
}
|
||||
}
|
||||
archRequiredCPUFlags = map[string]string{
|
||||
"vmx": "Virtualization support",
|
||||
"lm": "64Bit CPU",
|
||||
"sse4_1": "SSE4.1",
|
||||
}
|
||||
archRequiredCPUAttribs = map[string]string{
|
||||
archGenuineIntel: "Intel Architecture CPU",
|
||||
}
|
||||
archRequiredKernelModules = map[string]kernelModule{
|
||||
"kvm": {
|
||||
desc: msgKernelVM,
|
||||
required: true,
|
||||
},
|
||||
"kvm_intel": {
|
||||
desc: "Intel KVM",
|
||||
parameters: kvmIntelParams,
|
||||
required: true,
|
||||
},
|
||||
"vhost": {
|
||||
desc: msgKernelVirtio,
|
||||
required: true,
|
||||
},
|
||||
"vhost_net": {
|
||||
desc: msgKernelVirtioNet,
|
||||
required: true,
|
||||
},
|
||||
"vhost_vsock": {
|
||||
desc: msgKernelVirtioVhostVsock,
|
||||
required: false,
|
||||
},
|
||||
|
||||
switch hypervisorType {
|
||||
case "firecracker":
|
||||
fallthrough
|
||||
case "qemu":
|
||||
archRequiredCPUFlags = map[string]string{
|
||||
cpuFlagVMX: "Virtualization support",
|
||||
cpuFlagLM: "64Bit CPU",
|
||||
cpuFlagSSE4_1: "SSE4.1",
|
||||
}
|
||||
archRequiredCPUAttribs = map[string]string{
|
||||
archGenuineIntel: "Intel Architecture CPU",
|
||||
}
|
||||
archRequiredKernelModules = map[string]kernelModule{
|
||||
kernelModkvm: {
|
||||
desc: msgKernelVM,
|
||||
},
|
||||
kernelModkvmintel: {
|
||||
desc: "Intel KVM",
|
||||
parameters: kvmIntelParams,
|
||||
},
|
||||
kernelModvhost: {
|
||||
desc: msgKernelVirtio,
|
||||
},
|
||||
kernelModvhostnet: {
|
||||
desc: msgKernelVirtioNet,
|
||||
},
|
||||
kernelModvhostvsock: {
|
||||
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 {
|
||||
archRequiredCPUFlags = map[string]string{
|
||||
"svm": "Virtualization support",
|
||||
"lm": "64Bit CPU",
|
||||
"sse4_1": "SSE4.1",
|
||||
cpuFlagSVM: "Virtualization support",
|
||||
cpuFlagLM: "64Bit CPU",
|
||||
cpuFlagSSE4_1: "SSE4.1",
|
||||
}
|
||||
archRequiredCPUAttribs = map[string]string{
|
||||
archAuthenticAMD: "AMD Architecture CPU",
|
||||
}
|
||||
archRequiredKernelModules = map[string]kernelModule{
|
||||
"kvm": {
|
||||
kernelModkvm: {
|
||||
desc: msgKernelVM,
|
||||
required: true,
|
||||
},
|
||||
"kvm_amd": {
|
||||
kernelModkvmamd: {
|
||||
desc: "AMD KVM",
|
||||
required: true,
|
||||
},
|
||||
"vhost": {
|
||||
kernelModvhost: {
|
||||
desc: msgKernelVirtio,
|
||||
required: true,
|
||||
},
|
||||
"vhost_net": {
|
||||
kernelModvhostnet: {
|
||||
desc: msgKernelVirtioNet,
|
||||
required: true,
|
||||
},
|
||||
"vhost_vsock": {
|
||||
kernelModvhostvsock: {
|
||||
desc: msgKernelVirtioVhostVsock,
|
||||
required: false,
|
||||
},
|
||||
@ -155,8 +214,72 @@ func kvmIsUsable() error {
|
||||
return genericKvmIsUsable()
|
||||
}
|
||||
|
||||
func archHostCanCreateVMContainer() error {
|
||||
return kvmIsUsable()
|
||||
// acrnIsUsable determines if it will be possible to create a full virtual machine
|
||||
// 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
|
||||
|
@ -55,6 +55,9 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
_, config, err := makeRuntimeConfig(dir)
|
||||
assert.NoError(err)
|
||||
|
||||
savedSysModuleDir := sysModuleDir
|
||||
savedProcCPUInfo := procCPUInfo
|
||||
|
||||
@ -108,6 +111,7 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
||||
|
||||
ctx := createCLIContext(nil)
|
||||
ctx.App.Name = "foo"
|
||||
ctx.App.Metadata["runtimeConfig"] = config
|
||||
|
||||
// create buffer to save logger output
|
||||
buf := &bytes.Buffer{}
|
||||
@ -514,6 +518,10 @@ foo : bar
|
||||
func TestSetCPUtype(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
savedArchRequiredCPUFlags := archRequiredCPUFlags
|
||||
savedArchRequiredCPUAttribs := archRequiredCPUAttribs
|
||||
savedArchRequiredKernelModules := archRequiredKernelModules
|
||||
@ -528,7 +536,10 @@ func TestSetCPUtype(t *testing.T) {
|
||||
archRequiredCPUAttribs = map[string]string{}
|
||||
archRequiredKernelModules = map[string]kernelModule{}
|
||||
|
||||
setCPUtype()
|
||||
_, config, err := makeRuntimeConfig(tmpdir)
|
||||
assert.NoError(err)
|
||||
|
||||
setCPUtype(config.HypervisorType)
|
||||
|
||||
assert.NotEmpty(archRequiredCPUFlags)
|
||||
assert.NotEmpty(archRequiredCPUAttribs)
|
||||
|
@ -8,6 +8,7 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@ -56,7 +57,7 @@ var archRequiredKVMExtensions = map[string]kvmExtension{
|
||||
},
|
||||
}
|
||||
|
||||
func setCPUtype() error {
|
||||
func setCPUtype(hypervisorType vc.HypervisorType) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -84,7 +85,7 @@ func checkKVMExtensions() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func archHostCanCreateVMContainer() error {
|
||||
func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error {
|
||||
if err := kvmIsUsable(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -36,6 +36,9 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
_, config, err := makeRuntimeConfig(dir)
|
||||
assert.NoError(err)
|
||||
|
||||
savedSysModuleDir := sysModuleDir
|
||||
savedProcCPUInfo := procCPUInfo
|
||||
|
||||
@ -78,6 +81,7 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
||||
|
||||
ctx := createCLIContext(nil)
|
||||
ctx.App.Name = "foo"
|
||||
ctx.App.Metadata["runtimeConfig"] = config
|
||||
|
||||
// create buffer to save logger output
|
||||
buf := &bytes.Buffer{}
|
||||
|
@ -8,6 +8,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -16,6 +18,10 @@ import (
|
||||
func testSetCPUTypeGeneric(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
savedArchRequiredCPUFlags := archRequiredCPUFlags
|
||||
savedArchRequiredCPUAttribs := archRequiredCPUAttribs
|
||||
savedArchRequiredKernelModules := archRequiredKernelModules
|
||||
@ -30,7 +36,10 @@ func testSetCPUTypeGeneric(t *testing.T) {
|
||||
assert.Empty(archRequiredCPUAttribs)
|
||||
assert.NotEmpty(archRequiredKernelModules)
|
||||
|
||||
setCPUtype()
|
||||
_, config, err := makeRuntimeConfig(tmpdir)
|
||||
assert.NoError(err)
|
||||
|
||||
setCPUtype(config.HypervisorType)
|
||||
|
||||
assert.Equal(archRequiredCPUFlags, savedArchRequiredCPUFlags)
|
||||
assert.Equal(archRequiredCPUAttribs, savedArchRequiredCPUAttribs)
|
||||
|
@ -8,12 +8,13 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/kata-containers/runtime/pkg/katautils"
|
||||
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||
"github.com/sirupsen/logrus"
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -55,11 +56,11 @@ var archRequiredKernelModules = map[string]kernelModule{
|
||||
},
|
||||
}
|
||||
|
||||
func setCPUtype() error {
|
||||
func setCPUtype(hypervisorType vc.HypervisorType) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func archHostCanCreateVMContainer() error {
|
||||
func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error {
|
||||
return kvmIsUsable()
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,9 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
_, config, err := makeRuntimeConfig(dir)
|
||||
assert.NoError(err)
|
||||
|
||||
savedSysModuleDir := sysModuleDir
|
||||
savedProcCPUInfo := procCPUInfo
|
||||
|
||||
@ -98,6 +101,7 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
||||
|
||||
ctx := createCLIContext(nil)
|
||||
ctx.App.Name = "foo"
|
||||
ctx.App.Metadata["runtimeConfig"] = config
|
||||
|
||||
// create buffer to save logger output
|
||||
buf := &bytes.Buffer{}
|
||||
|
@ -7,8 +7,10 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sirupsen/logrus"
|
||||
"strings"
|
||||
|
||||
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -42,7 +44,7 @@ var archRequiredKernelModules = map[string]kernelModule{
|
||||
},
|
||||
}
|
||||
|
||||
func setCPUtype() error {
|
||||
func setCPUtype(hypervisorType vc.HypervisorType) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -52,7 +54,7 @@ func kvmIsUsable() error {
|
||||
return genericKvmIsUsable()
|
||||
}
|
||||
|
||||
func archHostCanCreateVMContainer() error {
|
||||
func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error {
|
||||
return kvmIsUsable()
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,9 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
_, config, err := makeRuntimeConfig(dir)
|
||||
assert.NoError(err)
|
||||
|
||||
savedSysModuleDir := sysModuleDir
|
||||
savedProcCPUInfo := procCPUInfo
|
||||
|
||||
@ -97,6 +100,7 @@ func TestCCCheckCLIFunction(t *testing.T) {
|
||||
|
||||
ctx := createCLIContext(nil)
|
||||
ctx.App.Name = "foo"
|
||||
ctx.App.Metadata["runtimeConfig"] = config
|
||||
|
||||
// create buffer to save logger output
|
||||
buf := &bytes.Buffer{}
|
||||
|
@ -659,6 +659,9 @@ func TestCheckCLIFunctionFail(t *testing.T) {
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
_, config, err := makeRuntimeConfig(dir)
|
||||
assert.NoError(err)
|
||||
|
||||
oldProcCPUInfo := procCPUInfo
|
||||
|
||||
// doesn't exist
|
||||
@ -670,6 +673,7 @@ func TestCheckCLIFunctionFail(t *testing.T) {
|
||||
|
||||
ctx := createCLIContext(nil)
|
||||
ctx.App.Name = "foo"
|
||||
ctx.App.Metadata["runtimeConfig"] = config
|
||||
|
||||
fn, ok := kataCheckCLICommand.Action.(func(context *cli.Context) error)
|
||||
assert.True(ok)
|
||||
|
@ -9,9 +9,8 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
runtim "runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"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) {
|
||||
err = setCPUtype()
|
||||
err = setCPUtype(config.HypervisorType)
|
||||
if err != nil {
|
||||
return EnvInfo{}, err
|
||||
}
|
||||
|
102
cli/main.go
102
cli/main.go
@ -254,54 +254,54 @@ func beforeSubcommands(c *cli.Context) error {
|
||||
|
||||
handleShowConfig(c)
|
||||
|
||||
if userWantsUsage(c) || (c.NArg() == 1 && (c.Args()[0] == checkCmd)) {
|
||||
if userWantsUsage(c) {
|
||||
// No setup required if the user just
|
||||
// wants to see the usage statement or are
|
||||
// running a command that does not manipulate
|
||||
// containers.
|
||||
// wants to see the usage statement.
|
||||
return nil
|
||||
}
|
||||
|
||||
if path := c.GlobalString("log"); path != "" {
|
||||
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"))
|
||||
}
|
||||
|
||||
ignoreLogging := false
|
||||
var traceRootSpan string
|
||||
|
||||
// Add the name of the sub-command to each log entry for easier
|
||||
// debugging.
|
||||
cmdName := c.Args().First()
|
||||
if c.App.Command(cmdName) != nil {
|
||||
kataLog = kataLog.WithField("command", cmdName)
|
||||
subCmdIsCheckCmd := (c.NArg() == 1 && (c.Args()[0] == checkCmd))
|
||||
if !subCmdIsCheckCmd {
|
||||
if path := c.GlobalString("log"); path != "" {
|
||||
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
|
||||
}
|
||||
|
||||
// Name for the root span (used for tracing) now the
|
||||
// sub-command name is known.
|
||||
traceRootSpan = name + " " + cmdName
|
||||
}
|
||||
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"))
|
||||
}
|
||||
|
||||
// Since a context is required, pass a new (throw-away) one - we
|
||||
// cannot use the main context as tracing hasn't been enabled yet
|
||||
// (meaning any spans created at this point will be silently ignored).
|
||||
setExternalLoggers(context.Background(), kataLog)
|
||||
// Add the name of the sub-command to each log entry for easier
|
||||
// debugging.
|
||||
cmdName := c.Args().First()
|
||||
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 {
|
||||
// simply report the logging setup
|
||||
ignoreLogging = true
|
||||
// Since a context is required, pass a new (throw-away) one - we
|
||||
// cannot use the main context as tracing hasn't been enabled yet
|
||||
// (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)
|
||||
@ -309,19 +309,21 @@ func beforeSubcommands(c *cli.Context) error {
|
||||
fatal(err)
|
||||
}
|
||||
|
||||
debug = runtimeConfig.Debug
|
||||
crashOnError = runtimeConfig.Debug
|
||||
if !subCmdIsCheckCmd {
|
||||
debug = runtimeConfig.Debug
|
||||
crashOnError = runtimeConfig.Debug
|
||||
|
||||
if traceRootSpan != "" {
|
||||
// Create the tracer.
|
||||
//
|
||||
// Note: no spans are created until the command-line has been parsed.
|
||||
// This delays collection of trace data slightly but benefits the user by
|
||||
// ensuring the first span is the name of the sub-command being
|
||||
// invoked from the command-line.
|
||||
err = setupTracing(c, traceRootSpan)
|
||||
if err != nil {
|
||||
return err
|
||||
if traceRootSpan != "" {
|
||||
// Create the tracer.
|
||||
//
|
||||
// Note: no spans are created until the command-line has been parsed.
|
||||
// This delays collection of trace data slightly but benefits the user by
|
||||
// ensuring the first span is the name of the sub-command being
|
||||
// invoked from the command-line.
|
||||
err = setupTracing(c, traceRootSpan)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user