Files
kata-containers/cli/kata-env.go
Jose Carlos Venegas Munoz b65063248f config: add option SandboxCgroupOnly
add option to eneable only pod cgroup (SandboxCgroupOnly)

Depends-on: github.com/kata-containers/tests#1824

Fixes: #1879
Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2019-08-29 14:08:04 -05:00

495 lines
10 KiB
Go

// Copyright (c) 2017-2019 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
package main
import (
"encoding/json"
"errors"
"os"
runtim "runtime"
"strings"
"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.23"
// 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
SandboxCgroupOnly 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
SharedFS string
}
// 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
Debug bool
Trace bool
TraceMode string
TraceType 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,
SandboxCgroupOnly: config.SandboxCgroupOnly,
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, error) {
agent := AgentInfo{
Type: string(config.AgentType),
}
switch config.AgentType {
case vc.KataContainersAgent:
agentConfig, ok := config.AgentConfig.(vc.KataAgentConfig)
if !ok {
return AgentInfo{}, errors.New("cannot determine Kata agent config")
}
agent.Debug = agentConfig.Debug
agent.Trace = agentConfig.Trace
agent.TraceMode = agentConfig.TraceMode
agent.TraceType = agentConfig.TraceType
default:
// Nothing useful to report for the other agent types
}
return agent, nil
}
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,
SharedFS: config.HypervisorConfig.SharedFS,
}
}
func getEnvInfo(configFile string, config oci.RuntimeConfig) (env EnvInfo, err error) {
err = setCPUtype(config.HypervisorType)
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, err := getAgentInfo(config)
if err != nil {
return EnvInfo{}, err
}
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)
},
}