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:
Vijay Dhanraj 2019-06-08 12:42:31 -07:00
parent 4d26ceee79
commit adcac9368f
13 changed files with 279 additions and 108 deletions

View File

@ -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
} }

View File

@ -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

View File

@ -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)

View File

@ -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
} }

View File

@ -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{}

View File

@ -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)

View File

@ -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()
} }

View File

@ -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{}

View File

@ -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()
} }

View File

@ -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{}

View File

@ -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)

View File

@ -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
} }

View File

@ -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
}
} }
} }