mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-26 18:44:47 +01:00
Fixes #1226 Add new flag "experimental" for supporting underworking features. Some features are under developing which are not ready for release, there're also some features which will break compatibility which is not suitable to be merged into a kata minor release(x version in x.y.z) For getting these features above merged earlier for more testing, we can mark them as "experimental" features, and move them to formal features when they are ready. Signed-off-by: Wei Zhang <zhangwei555@huawei.com>
471 lines
9.8 KiB
Go
471 lines
9.8 KiB
Go
// Copyright (c) 2017-2018 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"os"
|
|
"strings"
|
|
|
|
runtim "runtime"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
"github.com/kata-containers/runtime/pkg/katautils"
|
|
vc "github.com/kata-containers/runtime/virtcontainers"
|
|
exp "github.com/kata-containers/runtime/virtcontainers/experimental"
|
|
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
|
|
vcUtils "github.com/kata-containers/runtime/virtcontainers/utils"
|
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
|
"github.com/urfave/cli"
|
|
)
|
|
|
|
// Semantic version for the output of the command.
|
|
//
|
|
// XXX: Increment for every change to the output format
|
|
// (meaning any change to the EnvInfo type).
|
|
const formatVersion = "1.0.21"
|
|
|
|
// MetaInfo stores information on the format of the output itself
|
|
type MetaInfo struct {
|
|
// output format version
|
|
Version string
|
|
}
|
|
|
|
// KernelInfo stores kernel details
|
|
type KernelInfo struct {
|
|
Path string
|
|
Parameters string
|
|
}
|
|
|
|
// InitrdInfo stores initrd image details
|
|
type InitrdInfo struct {
|
|
Path string
|
|
}
|
|
|
|
// ImageInfo stores root filesystem image details
|
|
type ImageInfo struct {
|
|
Path string
|
|
}
|
|
|
|
// CPUInfo stores host CPU details
|
|
type CPUInfo struct {
|
|
Vendor string
|
|
Model string
|
|
}
|
|
|
|
// RuntimeConfigInfo stores runtime config details.
|
|
type RuntimeConfigInfo struct {
|
|
Path string
|
|
}
|
|
|
|
// RuntimeInfo stores runtime details.
|
|
type RuntimeInfo struct {
|
|
Version RuntimeVersionInfo
|
|
Config RuntimeConfigInfo
|
|
Debug bool
|
|
Trace bool
|
|
DisableGuestSeccomp bool
|
|
DisableNewNetNs bool
|
|
Experimental []exp.Feature
|
|
Path string
|
|
}
|
|
|
|
// RuntimeVersionInfo stores details of the runtime version
|
|
type RuntimeVersionInfo struct {
|
|
Semver string
|
|
Commit string
|
|
OCI string
|
|
}
|
|
|
|
// HypervisorInfo stores hypervisor details
|
|
type HypervisorInfo struct {
|
|
MachineType string
|
|
Version string
|
|
Path string
|
|
BlockDeviceDriver string
|
|
EntropySource string
|
|
Msize9p uint32
|
|
MemorySlots uint32
|
|
Debug bool
|
|
UseVSock bool
|
|
}
|
|
|
|
// ProxyInfo stores proxy details
|
|
type ProxyInfo struct {
|
|
Type string
|
|
Version string
|
|
Path string
|
|
Debug bool
|
|
}
|
|
|
|
// ShimInfo stores shim details
|
|
type ShimInfo struct {
|
|
Type string
|
|
Version string
|
|
Path string
|
|
Debug bool
|
|
}
|
|
|
|
// AgentInfo stores agent details
|
|
type AgentInfo struct {
|
|
Type string
|
|
}
|
|
|
|
// DistroInfo stores host operating system distribution details.
|
|
type DistroInfo struct {
|
|
Name string
|
|
Version string
|
|
}
|
|
|
|
// HostInfo stores host details
|
|
type HostInfo struct {
|
|
Kernel string
|
|
Architecture string
|
|
Distro DistroInfo
|
|
CPU CPUInfo
|
|
VMContainerCapable bool
|
|
SupportVSocks bool
|
|
}
|
|
|
|
// NetmonInfo stores netmon details
|
|
type NetmonInfo struct {
|
|
Version string
|
|
Path string
|
|
Debug bool
|
|
Enable bool
|
|
}
|
|
|
|
// EnvInfo collects all information that will be displayed by the
|
|
// env command.
|
|
//
|
|
// XXX: Any changes must be coupled with a change to formatVersion.
|
|
type EnvInfo struct {
|
|
Meta MetaInfo
|
|
Runtime RuntimeInfo
|
|
Hypervisor HypervisorInfo
|
|
Image ImageInfo
|
|
Kernel KernelInfo
|
|
Initrd InitrdInfo
|
|
Proxy ProxyInfo
|
|
Shim ShimInfo
|
|
Agent AgentInfo
|
|
Host HostInfo
|
|
Netmon NetmonInfo
|
|
}
|
|
|
|
func getMetaInfo() MetaInfo {
|
|
return MetaInfo{
|
|
Version: formatVersion,
|
|
}
|
|
}
|
|
|
|
func getRuntimeInfo(configFile string, config oci.RuntimeConfig) RuntimeInfo {
|
|
runtimeVersion := RuntimeVersionInfo{
|
|
Semver: version,
|
|
Commit: commit,
|
|
OCI: specs.Version,
|
|
}
|
|
|
|
runtimeConfig := RuntimeConfigInfo{
|
|
Path: configFile,
|
|
}
|
|
|
|
runtimePath, _ := os.Executable()
|
|
|
|
return RuntimeInfo{
|
|
Debug: config.Debug,
|
|
Trace: config.Trace,
|
|
Version: runtimeVersion,
|
|
Config: runtimeConfig,
|
|
Path: runtimePath,
|
|
DisableNewNetNs: config.DisableNewNetNs,
|
|
Experimental: config.Experimental,
|
|
DisableGuestSeccomp: config.DisableGuestSeccomp,
|
|
}
|
|
}
|
|
|
|
func getHostInfo() (HostInfo, error) {
|
|
hostKernelVersion, err := getKernelVersion()
|
|
if err != nil {
|
|
return HostInfo{}, err
|
|
}
|
|
|
|
hostDistroName, hostDistroVersion, err := getDistroDetails()
|
|
if err != nil {
|
|
return HostInfo{}, err
|
|
}
|
|
|
|
cpuVendor, cpuModel, err := getCPUDetails()
|
|
if err != nil {
|
|
return HostInfo{}, err
|
|
}
|
|
|
|
hostVMContainerCapable := true
|
|
if runtim.GOARCH == "ppc64le" {
|
|
hostVMContainerCapable = false
|
|
}
|
|
|
|
details := vmContainerCapableDetails{
|
|
cpuInfoFile: procCPUInfo,
|
|
requiredCPUFlags: archRequiredCPUFlags,
|
|
requiredCPUAttribs: archRequiredCPUAttribs,
|
|
requiredKernelModules: archRequiredKernelModules,
|
|
}
|
|
|
|
if err = hostIsVMContainerCapable(details); err != nil {
|
|
hostVMContainerCapable = false
|
|
}
|
|
|
|
hostDistro := DistroInfo{
|
|
Name: hostDistroName,
|
|
Version: hostDistroVersion,
|
|
}
|
|
|
|
hostCPU := CPUInfo{
|
|
Vendor: cpuVendor,
|
|
Model: cpuModel,
|
|
}
|
|
|
|
host := HostInfo{
|
|
Kernel: hostKernelVersion,
|
|
Architecture: arch,
|
|
Distro: hostDistro,
|
|
CPU: hostCPU,
|
|
VMContainerCapable: hostVMContainerCapable,
|
|
SupportVSocks: vcUtils.SupportsVsocks(),
|
|
}
|
|
|
|
return host, nil
|
|
}
|
|
|
|
func getProxyInfo(config oci.RuntimeConfig) (ProxyInfo, error) {
|
|
if config.ProxyType == vc.NoProxyType {
|
|
return ProxyInfo{Type: string(config.ProxyType)}, nil
|
|
}
|
|
|
|
proxyConfig := config.ProxyConfig
|
|
version, err := getCommandVersion(proxyConfig.Path)
|
|
if err != nil {
|
|
version = unknown
|
|
}
|
|
|
|
proxy := ProxyInfo{
|
|
Type: string(config.ProxyType),
|
|
Version: version,
|
|
Path: proxyConfig.Path,
|
|
Debug: proxyConfig.Debug,
|
|
}
|
|
|
|
return proxy, nil
|
|
}
|
|
|
|
func getNetmonInfo(config oci.RuntimeConfig) (NetmonInfo, error) {
|
|
netmonConfig := config.NetmonConfig
|
|
|
|
version, err := getCommandVersion(netmonConfig.Path)
|
|
if err != nil {
|
|
version = unknown
|
|
}
|
|
|
|
netmon := NetmonInfo{
|
|
Version: version,
|
|
Path: netmonConfig.Path,
|
|
Debug: netmonConfig.Debug,
|
|
Enable: netmonConfig.Enable,
|
|
}
|
|
|
|
return netmon, nil
|
|
}
|
|
|
|
func getCommandVersion(cmd string) (string, error) {
|
|
return katautils.RunCommand([]string{cmd, "--version"})
|
|
}
|
|
|
|
func getShimInfo(config oci.RuntimeConfig) (ShimInfo, error) {
|
|
shimConfig, ok := config.ShimConfig.(vc.ShimConfig)
|
|
if !ok {
|
|
return ShimInfo{}, errors.New("cannot determine shim config")
|
|
}
|
|
|
|
shimPath := shimConfig.Path
|
|
|
|
version, err := getCommandVersion(shimPath)
|
|
if err != nil {
|
|
version = unknown
|
|
}
|
|
|
|
shim := ShimInfo{
|
|
Type: string(config.ShimType),
|
|
Version: version,
|
|
Path: shimPath,
|
|
Debug: shimConfig.Debug,
|
|
}
|
|
|
|
return shim, nil
|
|
}
|
|
|
|
func getAgentInfo(config oci.RuntimeConfig) AgentInfo {
|
|
agent := AgentInfo{
|
|
Type: string(config.AgentType),
|
|
}
|
|
|
|
return agent
|
|
}
|
|
|
|
func getHypervisorInfo(config oci.RuntimeConfig) HypervisorInfo {
|
|
hypervisorPath := config.HypervisorConfig.HypervisorPath
|
|
|
|
version, err := getCommandVersion(hypervisorPath)
|
|
if err != nil {
|
|
version = unknown
|
|
}
|
|
|
|
return HypervisorInfo{
|
|
Debug: config.HypervisorConfig.Debug,
|
|
MachineType: config.HypervisorConfig.HypervisorMachineType,
|
|
Version: version,
|
|
Path: hypervisorPath,
|
|
BlockDeviceDriver: config.HypervisorConfig.BlockDeviceDriver,
|
|
Msize9p: config.HypervisorConfig.Msize9p,
|
|
UseVSock: config.HypervisorConfig.UseVSock,
|
|
MemorySlots: config.HypervisorConfig.MemSlots,
|
|
EntropySource: config.HypervisorConfig.EntropySource,
|
|
}
|
|
}
|
|
|
|
func getEnvInfo(configFile string, config oci.RuntimeConfig) (env EnvInfo, err error) {
|
|
err = setCPUtype()
|
|
if err != nil {
|
|
return EnvInfo{}, err
|
|
}
|
|
|
|
meta := getMetaInfo()
|
|
|
|
runtime := getRuntimeInfo(configFile, config)
|
|
|
|
host, err := getHostInfo()
|
|
if err != nil {
|
|
return EnvInfo{}, err
|
|
}
|
|
|
|
proxy, _ := getProxyInfo(config)
|
|
|
|
netmon, _ := getNetmonInfo(config)
|
|
|
|
shim, err := getShimInfo(config)
|
|
if err != nil {
|
|
return EnvInfo{}, err
|
|
}
|
|
|
|
agent := getAgentInfo(config)
|
|
|
|
hypervisor := getHypervisorInfo(config)
|
|
|
|
image := ImageInfo{
|
|
Path: config.HypervisorConfig.ImagePath,
|
|
}
|
|
|
|
kernel := KernelInfo{
|
|
Path: config.HypervisorConfig.KernelPath,
|
|
Parameters: strings.Join(vc.SerializeParams(config.HypervisorConfig.KernelParams, "="), " "),
|
|
}
|
|
|
|
initrd := InitrdInfo{
|
|
Path: config.HypervisorConfig.InitrdPath,
|
|
}
|
|
|
|
env = EnvInfo{
|
|
Meta: meta,
|
|
Runtime: runtime,
|
|
Hypervisor: hypervisor,
|
|
Image: image,
|
|
Kernel: kernel,
|
|
Initrd: initrd,
|
|
Proxy: proxy,
|
|
Shim: shim,
|
|
Agent: agent,
|
|
Host: host,
|
|
Netmon: netmon,
|
|
}
|
|
|
|
return env, nil
|
|
}
|
|
|
|
func handleSettings(file *os.File, c *cli.Context) error {
|
|
if file == nil {
|
|
return errors.New("Invalid output file specified")
|
|
}
|
|
|
|
configFile, ok := c.App.Metadata["configFile"].(string)
|
|
if !ok {
|
|
return errors.New("cannot determine config file")
|
|
}
|
|
|
|
runtimeConfig, ok := c.App.Metadata["runtimeConfig"].(oci.RuntimeConfig)
|
|
if !ok {
|
|
return errors.New("cannot determine runtime config")
|
|
}
|
|
|
|
env, err := getEnvInfo(configFile, runtimeConfig)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if c.Bool("json") {
|
|
return writeJSONSettings(env, file)
|
|
}
|
|
|
|
return writeTOMLSettings(env, file)
|
|
}
|
|
|
|
func writeTOMLSettings(env EnvInfo, file *os.File) error {
|
|
encoder := toml.NewEncoder(file)
|
|
|
|
err := encoder.Encode(env)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func writeJSONSettings(env EnvInfo, file *os.File) error {
|
|
encoder := json.NewEncoder(file)
|
|
|
|
// Make it more human readable
|
|
encoder.SetIndent("", " ")
|
|
|
|
err := encoder.Encode(env)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
var kataEnvCLICommand = cli.Command{
|
|
Name: envCmd,
|
|
Usage: "display settings. Default to TOML",
|
|
Flags: []cli.Flag{
|
|
cli.BoolFlag{
|
|
Name: "json",
|
|
Usage: "Format output as JSON",
|
|
},
|
|
},
|
|
Action: func(context *cli.Context) error {
|
|
ctx, err := cliContextToContext(context)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
span, _ := katautils.Trace(ctx, "kata-env")
|
|
defer span.Finish()
|
|
|
|
return handleSettings(defaultOutputFile, context)
|
|
},
|
|
}
|