mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-29 21:03:03 +00:00
Merge pull request #1442 from jodh-intel/add-agent-trace-support
Add agent trace support
This commit is contained in:
commit
f4fe31e74d
62
Gopkg.lock
generated
62
Gopkg.lock
generated
@ -2,7 +2,7 @@
|
||||
|
||||
|
||||
[[projects]]
|
||||
digest = "1:79896046d0807ae89b74ae106b6cb0b346c201c02fc57b7c56017edad7493a61"
|
||||
digest = "1:5d72bbcc9c8667b11c3dc3cbe681c5a6f71e5096744c0bf7726ab5c6425d5dc4"
|
||||
name = "github.com/BurntSushi/toml"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
@ -10,7 +10,7 @@
|
||||
version = "v0.3.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:26b14a6dc72ace253599e969997d5ecf2143c63833c015179786bc756c76eaa4"
|
||||
digest = "1:2be791e7b333ff7c06f8fb3dc18a7d70580e9399dbdffd352621d067ff260b6e"
|
||||
name = "github.com/Microsoft/go-winio"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
@ -18,7 +18,7 @@
|
||||
version = "v0.4.12"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e4eec8e05fe8611837a9b34a787cf9c714a2fd9228a0a1f41dd2ccccbaa21b7e"
|
||||
digest = "1:a8e16b4caf3575365c9aa3380d9418f31dd0b810596faebfe3a15c37fabeee4a"
|
||||
name = "github.com/Microsoft/hcsshim"
|
||||
packages = [
|
||||
".",
|
||||
@ -65,16 +65,6 @@
|
||||
revision = "ccb8e960c48f04d6935e72476ae4a51028f9e22f"
|
||||
version = "v9"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f1bb062def4356e0ffacbf80952a122489df3d26887249a6d351f5b3c98d4c16"
|
||||
name = "github.com/clearcontainers/proxy"
|
||||
packages = [
|
||||
"api",
|
||||
"client",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "1d2a6a3ea132a86abd0731408b7dc34f2fc17d55"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:8ecb89af7dfe3ac401bdb0c9390b134ef96a97e85f732d2b0604fb7b3977839f"
|
||||
@ -99,7 +89,7 @@
|
||||
revision = "0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c572858cf95490994cee8faa84a57a8942f735e1a8b6a5a7876d13192754c05e"
|
||||
digest = "1:b1ddab63ebf3a38cdc2a80fa1f00c45e8dc98e27387968ccc0e5275a43f6cb5e"
|
||||
name = "github.com/containerd/containerd"
|
||||
packages = [
|
||||
"api/events",
|
||||
@ -120,7 +110,7 @@
|
||||
revision = "f05672357f56f26751a521175c5a96fc21fa8603"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4f06807f78ebb5fd6d5fcd539885c0a0be60732eda47189a7feb486ff60a519d"
|
||||
digest = "1:e7c346f795db5a431ca8bd284faed7aa5b4d544ba6538b20a39b968473f47774"
|
||||
name = "github.com/containerd/cri-containerd"
|
||||
packages = [
|
||||
"pkg/annotations",
|
||||
@ -216,7 +206,7 @@
|
||||
version = "v0.3.3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2cbc5d9ad66b4eb1e82862757985de8c24d8ca299500e669998694329d05bfc9"
|
||||
digest = "1:351337e3b022de09e72306f1f9711314cc4bd407c15e8d328e218c655fd55731"
|
||||
name = "github.com/firecracker-microvm/firecracker-go-sdk"
|
||||
packages = [
|
||||
"client",
|
||||
@ -228,7 +218,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:e30aea4f7e276dc80a7041b9e436b45a4c6636e5ba554de835b07beb0f97cc74"
|
||||
digest = "1:ce0cdcf4a121add67d3c6f7cc08e6233275d0f417852f025b790d35da88fab10"
|
||||
name = "github.com/globalsign/mgo"
|
||||
packages = [
|
||||
"bson",
|
||||
@ -245,7 +235,7 @@
|
||||
revision = "20b96f641a5ea98f2f8619ff4f3e061cff4833bd"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5b7a60e28d9315ba79fb73e6294e5823997673ee64797d28ba2dc7bf71dc6ba6"
|
||||
digest = "1:e101aa2e25fac7e82ba4d2f66807eedd4bcf11abc5afcb4a4629a88f9a652b84"
|
||||
name = "github.com/go-openapi/analysis"
|
||||
packages = [
|
||||
".",
|
||||
@ -288,7 +278,7 @@
|
||||
version = "v0.18.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:36b4e8fb9b6f5896fe776b279a6e3a4115ab7d0258d0e0d2ac9c6c58e12531c7"
|
||||
digest = "1:757a8958779fedcfddafb3ac93f707876db7b4fbc71b76fbc25450b3f057025e"
|
||||
name = "github.com/go-openapi/runtime"
|
||||
packages = [
|
||||
".",
|
||||
@ -345,7 +335,7 @@
|
||||
version = "v5.0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:34e8cbba4f0ad2eeda81c98d3f53af4c5862518ec0ebae38730fc36f8a7705f0"
|
||||
digest = "1:0dfc35f448d29c2ff6a29fb3a6643f44175dc2a07925b1add2dea74e1dd6bf8d"
|
||||
name = "github.com/gogo/protobuf"
|
||||
packages = [
|
||||
"gogoproto",
|
||||
@ -358,7 +348,7 @@
|
||||
revision = "342cbe0a04158f6dcb03ca0079991a51a4248c02"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a8b59d8995b50db3b206d9160817e00aace183e456cb60abf5157de16d12e3c9"
|
||||
digest = "1:2d0636a8c490d2272dd725db26f74a537111b99b9dbdda0d8b98febe63702aa4"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = [
|
||||
"proto",
|
||||
@ -405,16 +395,9 @@
|
||||
pruneopts = "NUT"
|
||||
revision = "48dd1c031530fce9bf16b0f6a7305979cedd8fc9"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:04054595e5c5a35d1553a7f3464d18577caf597445d643992998643df56d4afd"
|
||||
name = "github.com/kubernetes-incubator/cri-o"
|
||||
packages = ["pkg/annotations"]
|
||||
pruneopts = "NUT"
|
||||
revision = "3394b3b2d6af0e41d185bb695c6378be5dd4d61d"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:ebd709f6c64e850ee37ffd662604b647934ba1b7da39c7ba26381d634a4b6d4d"
|
||||
digest = "1:84a5a2b67486d5d67060ac393aa255d05d24ed5ee41daecd5635ec22657b6492"
|
||||
name = "github.com/mailru/easyjson"
|
||||
packages = [
|
||||
"buffer",
|
||||
@ -447,7 +430,7 @@
|
||||
version = "v1.0.0-rc1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d4dcb47c4324ed0af861eda17778f56229d44422819770972183bee0217f9cff"
|
||||
digest = "1:26537bc93f1e164bbc305117029de9933656ff81c4549609939212aca20a4710"
|
||||
name = "github.com/opencontainers/runc"
|
||||
packages = [
|
||||
"libcontainer/configs",
|
||||
@ -467,7 +450,7 @@
|
||||
revision = "5806c35637336642129d03657419829569abc5aa"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7fea98b6541d058ba0ae5496d57d420d396a3f121a0aec64b4ec2171b0a93846"
|
||||
digest = "1:7da29c22bcc5c2ffb308324377dc00b5084650348c2799e573ed226d8cc9faf0"
|
||||
name = "github.com/opentracing/opentracing-go"
|
||||
packages = [
|
||||
".",
|
||||
@ -518,7 +501,7 @@
|
||||
version = "v0.9.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e2930b698575a7f45df1eaa5473c76109b04a87d6a464e674a68f9c1dff244a1"
|
||||
digest = "1:432ba4d123dc14d6e3b71ca22051bd1a5aa20a8e466e47edabd9af46405c5cfb"
|
||||
name = "github.com/sirupsen/logrus"
|
||||
packages = [
|
||||
".",
|
||||
@ -535,7 +518,7 @@
|
||||
revision = "890a5c3458b43e6104ff5da8dfa139d013d77544"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d43a3612c85e592ffcefdbc426d3fc0bdbc71435c930664bef8c36034181d681"
|
||||
digest = "1:87dee780f88f86f300bbd90116e933347cf4a3c65c1960072d412597a8896d50"
|
||||
name = "github.com/uber/jaeger-client-go"
|
||||
packages = [
|
||||
".",
|
||||
@ -576,7 +559,7 @@
|
||||
revision = "ac249472b7de27a9e8990819566d9be95ab5b816"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e53b4392978149151080be2de940b1cfbb542c3b2bc3281e091678a3626397f8"
|
||||
digest = "1:51b28ecbdddc7e0260899b64d8cf13343bb8f66b4b00585b46c775509755095a"
|
||||
name = "github.com/vishvananda/netlink"
|
||||
packages = [
|
||||
".",
|
||||
@ -601,7 +584,7 @@
|
||||
revision = "8dd112bcdc25174059e45e07517d9fc663123347"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5985d67e107c875e2584b5a65f1590adee7677a4e44eb7e62cd54c7709abba4a"
|
||||
digest = "1:b20c63a56900e442d5f435613fefc9392cbe8849467510fcc3869dbdad9441bb"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"context",
|
||||
@ -616,7 +599,7 @@
|
||||
revision = "a8b9294777976932365dabb6640cf1468d95c70f"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:bfb083c1c1ae3c793c66773f32fa2f5934241d8c6327636f4761f269d018a171"
|
||||
digest = "1:2fd19a8bed3f4ba8e3b26620f114efec5f39c7b02635a89a915b1cbaefeab5ff"
|
||||
name = "golang.org/x/sys"
|
||||
packages = [
|
||||
"unix",
|
||||
@ -626,7 +609,7 @@
|
||||
revision = "1d2aa6dbdea45adaaebb9905d0666e4537563829"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4e48d0d8df75f1bd0a0afe837599fc9ad96b59eecdd1900fc0dcceccaa5fdffc"
|
||||
digest = "1:e33513a825fcd765e97b5de639a2f7547542d1a8245df0cef18e1fd390b778a9"
|
||||
name = "golang.org/x/text"
|
||||
packages = [
|
||||
"collate",
|
||||
@ -658,7 +641,7 @@
|
||||
revision = "5fe7a883aa19554f42890211544aa549836af7b7"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c09d7ef1564ca6aee8193b8b9d2d831cb69d29581f53b1b1e6331142d07fddbd"
|
||||
digest = "1:3d43152515ea791363eb0d1d21378fbf70e7df4a3954fd315898532cf5e64a8c"
|
||||
name = "google.golang.org/grpc"
|
||||
packages = [
|
||||
".",
|
||||
@ -701,8 +684,6 @@
|
||||
analyzer-version = 1
|
||||
input-imports = [
|
||||
"github.com/BurntSushi/toml",
|
||||
"github.com/clearcontainers/proxy/api",
|
||||
"github.com/clearcontainers/proxy/client",
|
||||
"github.com/containerd/cgroups",
|
||||
"github.com/containerd/containerd/api/events",
|
||||
"github.com/containerd/containerd/api/types",
|
||||
@ -735,7 +716,6 @@
|
||||
"github.com/kata-containers/agent/pkg/types",
|
||||
"github.com/kata-containers/agent/protocols/client",
|
||||
"github.com/kata-containers/agent/protocols/grpc",
|
||||
"github.com/kubernetes-incubator/cri-o/pkg/annotations",
|
||||
"github.com/mitchellh/mapstructure",
|
||||
"github.com/opencontainers/runc/libcontainer/configs",
|
||||
"github.com/opencontainers/runc/libcontainer/specconv",
|
||||
|
@ -1,7 +1,3 @@
|
||||
[[constraint]]
|
||||
name = "github.com/clearcontainers/proxy"
|
||||
revision = "1d2a6a3ea132a86abd0731408b7dc34f2fc17d55"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/containernetworking/plugins"
|
||||
revision = "7f98c94613021d8b57acfa1a2f0c8d0f6fd7ae5a"
|
||||
|
@ -222,8 +222,30 @@ path = "@SHIMPATH@"
|
||||
#enable_tracing = true
|
||||
|
||||
[agent.@PROJECT_TYPE@]
|
||||
# There is no field for this section. The goal is only to be able to
|
||||
# specify which type of agent the user wants to use.
|
||||
# If enabled, make the agent display debug-level messages.
|
||||
# (default: disabled)
|
||||
#enable_debug = true
|
||||
|
||||
# Enable agent tracing.
|
||||
#
|
||||
# If enabled, the default trace mode is "dynamic" and the
|
||||
# default trace type is "isolated". The trace mode and type are set
|
||||
# explicity with the `trace_type=` and `trace_mode=` options.
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
# - Tracing is ONLY enabled when `enable_tracing` is set: explicitly
|
||||
# setting `trace_mode=` and/or `trace_type=` without setting `enable_tracing`
|
||||
# will NOT activate agent tracing.
|
||||
#
|
||||
# - See https://github.com/kata-containers/agent/blob/master/TRACING.md for
|
||||
# full details.
|
||||
#
|
||||
# (default: disabled)
|
||||
#enable_tracing = true
|
||||
#
|
||||
#trace_mode = "dynamic"
|
||||
#trace_type = "isolated"
|
||||
|
||||
[netmon]
|
||||
# If enabled, the network monitoring process gets started when the
|
||||
|
@ -274,8 +274,30 @@ path = "@SHIMPATH@"
|
||||
#enable_tracing = true
|
||||
|
||||
[agent.@PROJECT_TYPE@]
|
||||
# There is no field for this section. The goal is only to be able to
|
||||
# specify which type of agent the user wants to use.
|
||||
# If enabled, make the agent display debug-level messages.
|
||||
# (default: disabled)
|
||||
#enable_debug = true
|
||||
|
||||
# Enable agent tracing.
|
||||
#
|
||||
# If enabled, the default trace mode is "dynamic" and the
|
||||
# default trace type is "isolated". The trace mode and type are set
|
||||
# explicity with the `trace_type=` and `trace_mode=` options.
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
# - Tracing is ONLY enabled when `enable_tracing` is set: explicitly
|
||||
# setting `trace_mode=` and/or `trace_type=` without setting `enable_tracing`
|
||||
# will NOT activate agent tracing.
|
||||
#
|
||||
# - See https://github.com/kata-containers/agent/blob/master/TRACING.md for
|
||||
# full details.
|
||||
#
|
||||
# (default: disabled)
|
||||
#enable_tracing = true
|
||||
#
|
||||
#trace_mode = "dynamic"
|
||||
#trace_type = "isolated"
|
||||
|
||||
[netmon]
|
||||
# If enabled, the network monitoring process gets started when the
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2018 Intel Corporation
|
||||
// Copyright (c) 2017-2019 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
@ -27,7 +27,7 @@ import (
|
||||
//
|
||||
// XXX: Increment for every change to the output format
|
||||
// (meaning any change to the EnvInfo type).
|
||||
const formatVersion = "1.0.21"
|
||||
const formatVersion = "1.0.23"
|
||||
|
||||
// MetaInfo stores information on the format of the output itself
|
||||
type MetaInfo struct {
|
||||
@ -112,7 +112,11 @@ type ShimInfo struct {
|
||||
|
||||
// AgentInfo stores agent details
|
||||
type AgentInfo struct {
|
||||
Type string
|
||||
Type string
|
||||
Debug bool
|
||||
Trace bool
|
||||
TraceMode string
|
||||
TraceType string
|
||||
}
|
||||
|
||||
// DistroInfo stores host operating system distribution details.
|
||||
@ -308,12 +312,26 @@ func getShimInfo(config oci.RuntimeConfig) (ShimInfo, error) {
|
||||
return shim, nil
|
||||
}
|
||||
|
||||
func getAgentInfo(config oci.RuntimeConfig) AgentInfo {
|
||||
func getAgentInfo(config oci.RuntimeConfig) (AgentInfo, error) {
|
||||
agent := AgentInfo{
|
||||
Type: string(config.AgentType),
|
||||
}
|
||||
|
||||
return agent
|
||||
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 {
|
||||
@ -361,7 +379,10 @@ func getEnvInfo(configFile string, config oci.RuntimeConfig) (env EnvInfo, err e
|
||||
return EnvInfo{}, err
|
||||
}
|
||||
|
||||
agent := getAgentInfo(config)
|
||||
agent, err := getAgentInfo(config)
|
||||
if err != nil {
|
||||
return EnvInfo{}, err
|
||||
}
|
||||
|
||||
hypervisor := getHypervisorInfo(config)
|
||||
|
||||
|
@ -24,8 +24,7 @@ import (
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"strconv"
|
||||
|
||||
"github.com/kata-containers/runtime/pkg/katatestutils"
|
||||
"github.com/kata-containers/runtime/pkg/katautils"
|
||||
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -36,12 +35,6 @@ const testShimVersion = "shim version 0.1"
|
||||
const testNetmonVersion = "netmon version 0.1"
|
||||
const testHypervisorVersion = "QEMU emulator version 2.7.0+git.741f430a96-6.1, Copyright (c) 2003-2016 Fabrice Bellard and the QEMU Project developers"
|
||||
|
||||
const defaultVCPUCount uint32 = 1
|
||||
const defaultMaxVCPUCount uint32 = 0
|
||||
const defaultMemSize uint32 = 2048 // MiB
|
||||
const defaultMsize9p uint32 = 8192
|
||||
const defaultGuestHookPath string = ""
|
||||
|
||||
var (
|
||||
hypervisorDebug = false
|
||||
proxyDebug = false
|
||||
@ -49,6 +42,8 @@ var (
|
||||
runtimeTrace = false
|
||||
shimDebug = false
|
||||
netmonDebug = false
|
||||
agentDebug = false
|
||||
agentTrace = false
|
||||
)
|
||||
|
||||
// makeVersionBinary creates a shell script with the specified file
|
||||
@ -81,47 +76,6 @@ func createConfig(configPath string, fileData string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeRuntimeConfigFileData(hypervisor, hypervisorPath, kernelPath, imagePath, kernelParams, machineType, shimPath, proxyPath, netmonPath, logPath string, disableBlock bool, blockDeviceDriver string, enableIOThreads bool, hotplugVFIOOnRootBus, disableNewNetNs bool) string {
|
||||
return `
|
||||
# Runtime configuration file
|
||||
|
||||
[hypervisor.` + hypervisor + `]
|
||||
path = "` + hypervisorPath + `"
|
||||
kernel = "` + kernelPath + `"
|
||||
block_device_driver = "` + blockDeviceDriver + `"
|
||||
kernel_params = "` + kernelParams + `"
|
||||
image = "` + imagePath + `"
|
||||
machine_type = "` + machineType + `"
|
||||
default_vcpus = ` + strconv.FormatUint(uint64(defaultVCPUCount), 10) + `
|
||||
default_maxvcpus = ` + strconv.FormatUint(uint64(defaultMaxVCPUCount), 10) + `
|
||||
default_memory = ` + strconv.FormatUint(uint64(defaultMemSize), 10) + `
|
||||
disable_block_device_use = ` + strconv.FormatBool(disableBlock) + `
|
||||
enable_iothreads = ` + strconv.FormatBool(enableIOThreads) + `
|
||||
hotplug_vfio_on_root_bus = ` + strconv.FormatBool(hotplugVFIOOnRootBus) + `
|
||||
msize_9p = ` + strconv.FormatUint(uint64(defaultMsize9p), 10) + `
|
||||
enable_debug = ` + strconv.FormatBool(hypervisorDebug) + `
|
||||
guest_hook_path = "` + defaultGuestHookPath + `"
|
||||
|
||||
[proxy.kata]
|
||||
enable_debug = ` + strconv.FormatBool(proxyDebug) + `
|
||||
path = "` + proxyPath + `"
|
||||
|
||||
[shim.kata]
|
||||
path = "` + shimPath + `"
|
||||
enable_debug = ` + strconv.FormatBool(shimDebug) + `
|
||||
|
||||
[agent.kata]
|
||||
|
||||
[netmon]
|
||||
path = "` + netmonPath + `"
|
||||
enable_debug = ` + strconv.FormatBool(netmonDebug) + `
|
||||
|
||||
[runtime]
|
||||
enable_debug = ` + strconv.FormatBool(runtimeDebug) + `
|
||||
enable_tracing = ` + strconv.FormatBool(runtimeTrace) + `
|
||||
disable_new_netns= ` + strconv.FormatBool(disableNewNetNs)
|
||||
}
|
||||
|
||||
func makeRuntimeConfig(prefixDir string) (configFile string, config oci.RuntimeConfig, err error) {
|
||||
const logPath = "/log/path"
|
||||
hypervisorPath := filepath.Join(prefixDir, "hypervisor")
|
||||
@ -172,23 +126,40 @@ func makeRuntimeConfig(prefixDir string) (configFile string, config oci.RuntimeC
|
||||
return "", oci.RuntimeConfig{}, err
|
||||
}
|
||||
|
||||
runtimeConfig := makeRuntimeConfigFileData(
|
||||
"qemu",
|
||||
hypervisorPath,
|
||||
kernelPath,
|
||||
imagePath,
|
||||
kernelParams,
|
||||
machineType,
|
||||
shimPath,
|
||||
proxyPath,
|
||||
netmonPath,
|
||||
logPath,
|
||||
disableBlock,
|
||||
blockStorageDriver,
|
||||
enableIOThreads,
|
||||
hotplugVFIOOnRootBus,
|
||||
disableNewNetNs,
|
||||
)
|
||||
hypConfig := katautils.GetDefaultHypervisorConfig()
|
||||
|
||||
configFileOptions := katatestutils.RuntimeConfigOptions{
|
||||
Hypervisor: "qemu",
|
||||
HypervisorPath: hypervisorPath,
|
||||
KernelPath: kernelPath,
|
||||
ImagePath: imagePath,
|
||||
KernelParams: kernelParams,
|
||||
MachineType: machineType,
|
||||
ShimPath: shimPath,
|
||||
ProxyPath: proxyPath,
|
||||
NetmonPath: netmonPath,
|
||||
LogPath: logPath,
|
||||
DefaultGuestHookPath: hypConfig.GuestHookPath,
|
||||
DisableBlock: disableBlock,
|
||||
BlockDeviceDriver: blockStorageDriver,
|
||||
EnableIOThreads: enableIOThreads,
|
||||
HotplugVFIOOnRootBus: hotplugVFIOOnRootBus,
|
||||
DisableNewNetNs: disableNewNetNs,
|
||||
DefaultVCPUCount: hypConfig.NumVCPUs,
|
||||
DefaultMaxVCPUCount: hypConfig.DefaultMaxVCPUs,
|
||||
DefaultMemSize: hypConfig.MemorySize,
|
||||
DefaultMsize9p: hypConfig.Msize9p,
|
||||
HypervisorDebug: hypervisorDebug,
|
||||
RuntimeDebug: runtimeDebug,
|
||||
RuntimeTrace: runtimeTrace,
|
||||
ProxyDebug: proxyDebug,
|
||||
ShimDebug: shimDebug,
|
||||
NetmonDebug: netmonDebug,
|
||||
AgentDebug: agentDebug,
|
||||
AgentTrace: agentTrace,
|
||||
}
|
||||
|
||||
runtimeConfig := katatestutils.MakeRuntimeConfigFileData(configFileOptions)
|
||||
|
||||
configFile = path.Join(prefixDir, "runtime.toml")
|
||||
err = createConfig(configFile, runtimeConfig)
|
||||
@ -239,8 +210,20 @@ func getExpectedShimDetails(config oci.RuntimeConfig) (ShimInfo, error) {
|
||||
}
|
||||
|
||||
func getExpectedAgentDetails(config oci.RuntimeConfig) (AgentInfo, error) {
|
||||
|
||||
agentConfig, ok := config.AgentConfig.(vc.KataAgentConfig)
|
||||
if !ok {
|
||||
return AgentInfo{}, fmt.Errorf("expected KataAgentConfig, got %T", config.AgentConfig)
|
||||
}
|
||||
|
||||
return AgentInfo{
|
||||
Type: string(config.AgentType),
|
||||
Type: string(config.AgentType),
|
||||
Debug: agentConfig.Debug,
|
||||
Trace: agentConfig.Trace,
|
||||
|
||||
// No trace mode/type set by default
|
||||
TraceMode: "",
|
||||
TraceType: "",
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -519,6 +502,8 @@ func TestEnvGetEnvInfo(t *testing.T) {
|
||||
runtimeDebug = toggle
|
||||
runtimeTrace = toggle
|
||||
shimDebug = toggle
|
||||
agentDebug = toggle
|
||||
agentTrace = toggle
|
||||
|
||||
configFile, config, err := makeRuntimeConfig(tmpdir)
|
||||
assert.NoError(t, err)
|
||||
@ -832,8 +817,33 @@ func TestEnvGetAgentInfo(t *testing.T) {
|
||||
expectedAgent, err := getExpectedAgentDetails(config)
|
||||
assert.NoError(t, err)
|
||||
|
||||
agent := getAgentInfo(config)
|
||||
agent, err := getAgentInfo(config)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, expectedAgent, agent)
|
||||
|
||||
agentConfig, ok := config.AgentConfig.(vc.KataAgentConfig)
|
||||
assert.True(t, ok)
|
||||
|
||||
agentConfig.Debug = true
|
||||
config.AgentConfig = agentConfig
|
||||
agent, err = getAgentInfo(config)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, agent.Debug)
|
||||
|
||||
agentConfig.Trace = true
|
||||
agentConfig.TraceMode = "traceMode"
|
||||
agentConfig.TraceType = "traceType"
|
||||
config.AgentConfig = agentConfig
|
||||
agent, err = getAgentInfo(config)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, agent.Trace)
|
||||
assert.Equal(t, agent.TraceMode, "traceMode")
|
||||
assert.Equal(t, agent.TraceType, "traceType")
|
||||
|
||||
config.AgentConfig = "I am the wrong type"
|
||||
_, err = getAgentInfo(config)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func testEnvShowTOMLSettings(t *testing.T, tmpdir string, tmpfile *os.File) error {
|
||||
|
87
pkg/katatestutils/utils.go
Normal file
87
pkg/katatestutils/utils.go
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright (c) 2018-2019 Intel Corporation
|
||||
// Copyright (c) 2018 HyperHQ Inc.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package katatestutils
|
||||
|
||||
import "strconv"
|
||||
|
||||
type RuntimeConfigOptions struct {
|
||||
Hypervisor string
|
||||
HypervisorPath string
|
||||
DefaultVCPUCount uint32
|
||||
DefaultMaxVCPUCount uint32
|
||||
DefaultMemSize uint32
|
||||
DefaultMsize9p uint32
|
||||
DefaultGuestHookPath string
|
||||
KernelPath string
|
||||
ImagePath string
|
||||
KernelParams string
|
||||
MachineType string
|
||||
ShimPath string
|
||||
ProxyPath string
|
||||
NetmonPath string
|
||||
LogPath string
|
||||
BlockDeviceDriver string
|
||||
AgentTraceMode string
|
||||
AgentTraceType string
|
||||
DisableBlock bool
|
||||
EnableIOThreads bool
|
||||
HotplugVFIOOnRootBus bool
|
||||
DisableNewNetNs bool
|
||||
HypervisorDebug bool
|
||||
RuntimeDebug bool
|
||||
RuntimeTrace bool
|
||||
ProxyDebug bool
|
||||
ShimDebug bool
|
||||
NetmonDebug bool
|
||||
AgentDebug bool
|
||||
AgentTrace bool
|
||||
}
|
||||
|
||||
func MakeRuntimeConfigFileData(config RuntimeConfigOptions) string {
|
||||
return `
|
||||
# Runtime configuration file
|
||||
|
||||
[hypervisor.` + config.Hypervisor + `]
|
||||
path = "` + config.HypervisorPath + `"
|
||||
kernel = "` + config.KernelPath + `"
|
||||
block_device_driver = "` + config.BlockDeviceDriver + `"
|
||||
kernel_params = "` + config.KernelParams + `"
|
||||
image = "` + config.ImagePath + `"
|
||||
machine_type = "` + config.MachineType + `"
|
||||
default_vcpus = ` + strconv.FormatUint(uint64(config.DefaultVCPUCount), 10) + `
|
||||
default_maxvcpus = ` + strconv.FormatUint(uint64(config.DefaultMaxVCPUCount), 10) + `
|
||||
default_memory = ` + strconv.FormatUint(uint64(config.DefaultMemSize), 10) + `
|
||||
disable_block_device_use = ` + strconv.FormatBool(config.DisableBlock) + `
|
||||
enable_iothreads = ` + strconv.FormatBool(config.EnableIOThreads) + `
|
||||
hotplug_vfio_on_root_bus = ` + strconv.FormatBool(config.HotplugVFIOOnRootBus) + `
|
||||
msize_9p = ` + strconv.FormatUint(uint64(config.DefaultMsize9p), 10) + `
|
||||
enable_debug = ` + strconv.FormatBool(config.HypervisorDebug) + `
|
||||
guest_hook_path = "` + config.DefaultGuestHookPath + `"
|
||||
|
||||
[proxy.kata]
|
||||
enable_debug = ` + strconv.FormatBool(config.ProxyDebug) + `
|
||||
path = "` + config.ProxyPath + `"
|
||||
|
||||
[shim.kata]
|
||||
path = "` + config.ShimPath + `"
|
||||
enable_debug = ` + strconv.FormatBool(config.ShimDebug) + `
|
||||
|
||||
[agent.kata]
|
||||
enable_debug = ` + strconv.FormatBool(config.AgentDebug) + `
|
||||
enable_tracing = ` + strconv.FormatBool(config.AgentTrace) + `
|
||||
trace_mode = "` + config.AgentTraceMode + `"` + `
|
||||
trace_type = "` + config.AgentTraceType + `"` + `
|
||||
|
||||
[netmon]
|
||||
path = "` + config.NetmonPath + `"
|
||||
enable_debug = ` + strconv.FormatBool(config.NetmonDebug) + `
|
||||
|
||||
[runtime]
|
||||
enable_debug = ` + strconv.FormatBool(config.RuntimeDebug) + `
|
||||
enable_tracing = ` + strconv.FormatBool(config.RuntimeTrace) + `
|
||||
disable_new_netns= ` + strconv.FormatBool(config.DisableNewNetNs)
|
||||
}
|
@ -136,6 +136,10 @@ type shim struct {
|
||||
}
|
||||
|
||||
type agent struct {
|
||||
Debug bool `toml:"enable_debug"`
|
||||
Tracing bool `toml:"enable_tracing"`
|
||||
TraceMode string `toml:"trace_mode"`
|
||||
TraceType string `toml:"trace_type"`
|
||||
}
|
||||
|
||||
type netmon struct {
|
||||
@ -388,6 +392,22 @@ func (s shim) trace() bool {
|
||||
return s.Tracing
|
||||
}
|
||||
|
||||
func (a agent) debug() bool {
|
||||
return a.Debug
|
||||
}
|
||||
|
||||
func (a agent) trace() bool {
|
||||
return a.Tracing
|
||||
}
|
||||
|
||||
func (a agent) traceMode() string {
|
||||
return a.TraceMode
|
||||
}
|
||||
|
||||
func (a agent) traceType() string {
|
||||
return a.TraceType
|
||||
}
|
||||
|
||||
func (n netmon) enable() bool {
|
||||
return n.Enable
|
||||
}
|
||||
@ -630,21 +650,32 @@ func updateRuntimeConfigProxy(configPath string, tomlConf tomlConfig, config *oc
|
||||
|
||||
func updateRuntimeConfigAgent(configPath string, tomlConf tomlConfig, config *oci.RuntimeConfig, builtIn bool) error {
|
||||
if builtIn {
|
||||
var agentConfig vc.KataAgentConfig
|
||||
|
||||
// If the agent config section isn't a Kata one, just default
|
||||
// to everything being disabled.
|
||||
agentConfig, _ = config.AgentConfig.(vc.KataAgentConfig)
|
||||
|
||||
config.AgentType = vc.KataContainersAgent
|
||||
config.AgentConfig = vc.KataAgentConfig{
|
||||
LongLiveConn: true,
|
||||
UseVSock: config.HypervisorConfig.UseVSock,
|
||||
Debug: agentConfig.Debug,
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
for k := range tomlConf.Agent {
|
||||
for k, agent := range tomlConf.Agent {
|
||||
switch k {
|
||||
case kataAgentTableType:
|
||||
config.AgentType = vc.KataContainersAgent
|
||||
config.AgentConfig = vc.KataAgentConfig{
|
||||
UseVSock: config.HypervisorConfig.UseVSock,
|
||||
UseVSock: config.HypervisorConfig.UseVSock,
|
||||
Debug: agent.debug(),
|
||||
Trace: agent.trace(),
|
||||
TraceMode: agent.traceMode(),
|
||||
TraceType: agent.traceType(),
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("%s agent type is not supported", k)
|
||||
@ -705,6 +736,22 @@ func SetKernelParams(runtimeConfig *oci.RuntimeConfig) error {
|
||||
}
|
||||
}
|
||||
|
||||
// next, check for agent specific kernel params
|
||||
if agentConfig, ok := runtimeConfig.AgentConfig.(vc.KataAgentConfig); ok {
|
||||
err := vc.KataAgentSetDefaultTraceConfigOptions(&agentConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
params := vc.KataAgentKernelParams(agentConfig)
|
||||
|
||||
for _, p := range params {
|
||||
if err := (runtimeConfig).AddKernelParam(p); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now re-add the user-specified values so that they take priority.
|
||||
for _, p := range userKernelParams {
|
||||
if err := (runtimeConfig).AddKernelParam(p); err != nil {
|
||||
@ -752,10 +799,8 @@ func updateRuntimeConfig(configPath string, tomlConf tomlConfig, config *oci.Run
|
||||
return nil
|
||||
}
|
||||
|
||||
func initConfig() (config oci.RuntimeConfig, err error) {
|
||||
var defaultAgentConfig interface{}
|
||||
|
||||
defaultHypervisorConfig := vc.HypervisorConfig{
|
||||
func GetDefaultHypervisorConfig() vc.HypervisorConfig {
|
||||
return vc.HypervisorConfig{
|
||||
HypervisorPath: defaultHypervisorPath,
|
||||
KernelPath: defaultKernelPath,
|
||||
ImagePath: defaultImagePath,
|
||||
@ -767,6 +812,7 @@ func initConfig() (config oci.RuntimeConfig, err error) {
|
||||
DefaultMaxVCPUs: defaultMaxVCPUCount,
|
||||
MemorySize: defaultMemSize,
|
||||
MemOffset: defaultMemOffset,
|
||||
DisableBlockDeviceUse: defaultDisableBlockDeviceUse,
|
||||
DefaultBridges: defaultBridgesCount,
|
||||
MemPrealloc: defaultEnableMemPrealloc,
|
||||
HugePages: defaultEnableHugePages,
|
||||
@ -782,6 +828,10 @@ func initConfig() (config oci.RuntimeConfig, err error) {
|
||||
HotplugVFIOOnRootBus: defaultHotplugVFIOOnRootBus,
|
||||
GuestHookPath: defaultGuestHookPath,
|
||||
}
|
||||
}
|
||||
|
||||
func initConfig() (config oci.RuntimeConfig, err error) {
|
||||
var defaultAgentConfig interface{}
|
||||
|
||||
err = config.InterNetworkModel.SetModel(defaultInterNetworkingModel)
|
||||
if err != nil {
|
||||
@ -792,7 +842,7 @@ func initConfig() (config oci.RuntimeConfig, err error) {
|
||||
|
||||
config = oci.RuntimeConfig{
|
||||
HypervisorType: defaultHypervisor,
|
||||
HypervisorConfig: defaultHypervisorConfig,
|
||||
HypervisorConfig: GetDefaultHypervisorConfig(),
|
||||
AgentType: defaultAgent,
|
||||
AgentConfig: defaultAgentConfig,
|
||||
ProxyType: defaultProxy,
|
||||
|
@ -15,11 +15,11 @@ import (
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
goruntime "runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"github.com/kata-containers/runtime/pkg/katatestutils"
|
||||
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
|
||||
"github.com/kata-containers/runtime/virtcontainers/utils"
|
||||
@ -30,8 +30,11 @@ var (
|
||||
hypervisorDebug = false
|
||||
proxyDebug = false
|
||||
runtimeDebug = false
|
||||
runtimeTrace = false
|
||||
shimDebug = false
|
||||
netmonDebug = false
|
||||
agentDebug = false
|
||||
agentTrace = false
|
||||
)
|
||||
|
||||
type testRuntimeConfig struct {
|
||||
@ -43,46 +46,6 @@ type testRuntimeConfig struct {
|
||||
LogPath string
|
||||
}
|
||||
|
||||
func makeRuntimeConfigFileData(hypervisor, hypervisorPath, kernelPath, imagePath, kernelParams, machineType, shimPath, proxyPath, netmonPath, logPath string, disableBlock bool, blockDeviceDriver string, enableIOThreads bool, hotplugVFIOOnRootBus, disableNewNetNs bool) string {
|
||||
return `
|
||||
# Runtime configuration file
|
||||
|
||||
[hypervisor.` + hypervisor + `]
|
||||
path = "` + hypervisorPath + `"
|
||||
kernel = "` + kernelPath + `"
|
||||
block_device_driver = "` + blockDeviceDriver + `"
|
||||
kernel_params = "` + kernelParams + `"
|
||||
image = "` + imagePath + `"
|
||||
machine_type = "` + machineType + `"
|
||||
default_vcpus = ` + strconv.FormatUint(uint64(defaultVCPUCount), 10) + `
|
||||
default_maxvcpus = ` + strconv.FormatUint(uint64(defaultMaxVCPUCount), 10) + `
|
||||
default_memory = ` + strconv.FormatUint(uint64(defaultMemSize), 10) + `
|
||||
disable_block_device_use = ` + strconv.FormatBool(disableBlock) + `
|
||||
enable_iothreads = ` + strconv.FormatBool(enableIOThreads) + `
|
||||
hotplug_vfio_on_root_bus = ` + strconv.FormatBool(hotplugVFIOOnRootBus) + `
|
||||
msize_9p = ` + strconv.FormatUint(uint64(defaultMsize9p), 10) + `
|
||||
enable_debug = ` + strconv.FormatBool(hypervisorDebug) + `
|
||||
guest_hook_path = "` + defaultGuestHookPath + `"
|
||||
|
||||
[proxy.kata]
|
||||
enable_debug = ` + strconv.FormatBool(proxyDebug) + `
|
||||
path = "` + proxyPath + `"
|
||||
|
||||
[shim.kata]
|
||||
path = "` + shimPath + `"
|
||||
enable_debug = ` + strconv.FormatBool(shimDebug) + `
|
||||
|
||||
[agent.kata]
|
||||
|
||||
[netmon]
|
||||
path = "` + netmonPath + `"
|
||||
enable_debug = ` + strconv.FormatBool(netmonDebug) + `
|
||||
|
||||
[runtime]
|
||||
enable_debug = ` + strconv.FormatBool(runtimeDebug) + `
|
||||
disable_new_netns= ` + strconv.FormatBool(disableNewNetNs)
|
||||
}
|
||||
|
||||
func createConfig(configPath string, fileData string) error {
|
||||
|
||||
err := ioutil.WriteFile(configPath, []byte(fileData), testFileMode)
|
||||
@ -121,7 +84,38 @@ func createAllRuntimeConfigFiles(dir, hypervisor string) (config testRuntimeConf
|
||||
hotplugVFIOOnRootBus := true
|
||||
disableNewNetNs := false
|
||||
|
||||
runtimeConfigFileData := makeRuntimeConfigFileData(hypervisor, hypervisorPath, kernelPath, imagePath, kernelParams, machineType, shimPath, proxyPath, netmonPath, logPath, disableBlockDevice, blockDeviceDriver, enableIOThreads, hotplugVFIOOnRootBus, disableNewNetNs)
|
||||
configFileOptions := katatestutils.RuntimeConfigOptions{
|
||||
Hypervisor: "qemu",
|
||||
HypervisorPath: hypervisorPath,
|
||||
KernelPath: kernelPath,
|
||||
ImagePath: imagePath,
|
||||
KernelParams: kernelParams,
|
||||
MachineType: machineType,
|
||||
ShimPath: shimPath,
|
||||
ProxyPath: proxyPath,
|
||||
NetmonPath: netmonPath,
|
||||
LogPath: logPath,
|
||||
DefaultGuestHookPath: defaultGuestHookPath,
|
||||
DisableBlock: disableBlockDevice,
|
||||
BlockDeviceDriver: blockDeviceDriver,
|
||||
EnableIOThreads: enableIOThreads,
|
||||
HotplugVFIOOnRootBus: hotplugVFIOOnRootBus,
|
||||
DisableNewNetNs: disableNewNetNs,
|
||||
DefaultVCPUCount: defaultVCPUCount,
|
||||
DefaultMaxVCPUCount: defaultMaxVCPUCount,
|
||||
DefaultMemSize: defaultMemSize,
|
||||
DefaultMsize9p: defaultMsize9p,
|
||||
HypervisorDebug: hypervisorDebug,
|
||||
RuntimeDebug: runtimeDebug,
|
||||
RuntimeTrace: runtimeTrace,
|
||||
ProxyDebug: proxyDebug,
|
||||
ShimDebug: shimDebug,
|
||||
NetmonDebug: netmonDebug,
|
||||
AgentDebug: agentDebug,
|
||||
AgentTrace: agentTrace,
|
||||
}
|
||||
|
||||
runtimeConfigFileData := katatestutils.MakeRuntimeConfigFileData(configFileOptions)
|
||||
|
||||
configPath := path.Join(dir, "runtime.toml")
|
||||
err = createConfig(configPath, runtimeConfigFileData)
|
||||
@ -1207,6 +1201,25 @@ func TestShimDefaults(t *testing.T) {
|
||||
assert.True(s.trace())
|
||||
}
|
||||
|
||||
func TestAgentDefaults(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
a := agent{}
|
||||
|
||||
assert.Equal(a.debug(), a.Debug)
|
||||
|
||||
a.Debug = true
|
||||
assert.Equal(a.debug(), a.Debug)
|
||||
|
||||
assert.Equal(a.trace(), a.Tracing)
|
||||
|
||||
a.Tracing = true
|
||||
assert.Equal(a.trace(), a.Tracing)
|
||||
|
||||
assert.Equal(a.traceMode(), a.TraceMode)
|
||||
assert.Equal(a.traceType(), a.TraceType)
|
||||
}
|
||||
|
||||
func TestGetDefaultConfigFilePaths(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
202
vendor/github.com/clearcontainers/proxy/COPYING
generated
vendored
202
vendor/github.com/clearcontainers/proxy/COPYING
generated
vendored
@ -1,202 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
84
vendor/github.com/clearcontainers/proxy/api/doc.go
generated
vendored
84
vendor/github.com/clearcontainers/proxy/api/doc.go
generated
vendored
@ -1,84 +0,0 @@
|
||||
// Copyright (c) 2017 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package api defines the API cc-proxy exposes to clients (processes
|
||||
// connecting to the proxy AF_UNIX socket).
|
||||
//
|
||||
// This package contains the low level definitions of the protocol, frame
|
||||
// structure and the various payloads that can be sent and received.
|
||||
//
|
||||
// The proxy protocol is composed of commands, responses and notifications.
|
||||
// They all share the same frame structure: a header followed by an optional
|
||||
// payload.
|
||||
//
|
||||
// • Commands are always initiated by a client, never by the proxy itself.
|
||||
//
|
||||
// • Responses are sent by the proxy to acknowledge commands.
|
||||
//
|
||||
// • Notifications are sent by either the proxy or clients and do not generate
|
||||
// responses.
|
||||
//
|
||||
// Frame Structure
|
||||
//
|
||||
// The frame format is illustrated below:
|
||||
//
|
||||
// 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
|
||||
// 0 1 2 3 4 5 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// ┌───────────────────────────┬───────────────┬───────────────┐
|
||||
// │ Version │ Header Length │ Reserved │
|
||||
// ├───────────────────────────┼─────┬─┬───────┼───────────────┤
|
||||
// │ Reserved │ Res.│E│ Type │ Opcode │
|
||||
// ├───────────────────────────┴─────┴─┴───────┴───────────────┤
|
||||
// │ Payload Length │
|
||||
// ├───────────────────────────────────────────────────────────┤
|
||||
// │ │
|
||||
// │ Payload │
|
||||
// │ │
|
||||
// │ (variable length, optional and opcode-specific) │
|
||||
// │ │
|
||||
// └───────────────────────────────────────────────────────────┘
|
||||
//
|
||||
// All header fields are encoded in network order (big endian).
|
||||
//
|
||||
// • Version (16 bits) is the proxy protocol version. See api.Version for
|
||||
// details about what information it encodes.
|
||||
//
|
||||
// • Header Length (8 bits) is the length of the header in number of 32-bit
|
||||
// words. Header Length is greater or equal to 3 (12 bytes).
|
||||
//
|
||||
// • Type (4 bits) is the frame type: command (0x0), response (0x1),
|
||||
// stream (0x2) or notification (0x3).
|
||||
//
|
||||
// • Opcode (8 bits) specifies the kind of command, response, stream or
|
||||
// notification this frame represents. In conjunction with Type, this field
|
||||
// will dictate the payload content.
|
||||
//
|
||||
// • E, Error. This flag is set when a response returns an error. Currently
|
||||
// Error can ony be set in response frames.
|
||||
//
|
||||
// • Payload Length (32 bits) is in bytes.
|
||||
//
|
||||
// • Payload is optional data that can be sent with the various frames.
|
||||
// Commands, responses and notifications usually encode their payloads in JSON
|
||||
// while stream frames have raw data payloads.
|
||||
//
|
||||
// • Reserved fields are reserved for future use and must be zeroed.
|
||||
//
|
||||
// Frame Size and Header Length
|
||||
//
|
||||
// The full size of a frame is (Header Length + Payload Length). The Payload
|
||||
// starts at offset Header Length from the start of the frame.
|
||||
//
|
||||
// It is guaranteed that future header sizes will be at least 12 bytes.
|
||||
package api
|
235
vendor/github.com/clearcontainers/proxy/api/frame.go
generated
vendored
235
vendor/github.com/clearcontainers/proxy/api/frame.go
generated
vendored
@ -1,235 +0,0 @@
|
||||
// Copyright (c) 2017 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// Version encodes the proxy protocol version.
|
||||
//
|
||||
// List of changes:
|
||||
//
|
||||
// • version 2: initial version released with Clear Containers 3.0
|
||||
//
|
||||
// ⚠⚠⚠ backward incompatible with version 1 ⚠⚠⚠
|
||||
//
|
||||
// List of changes:
|
||||
//
|
||||
// • Changed the frame header to include additional fields: version,
|
||||
// header length, type and opcode.
|
||||
// • Added a log messages for clients to insert log entries to the
|
||||
// consolidated proxy log.
|
||||
//
|
||||
// • version 1: initial version released with Clear Containers 2.1
|
||||
const Version = 2
|
||||
|
||||
// FrameType is the type of frame and is part of the frame header.
|
||||
type FrameType int
|
||||
|
||||
const (
|
||||
// TypeCommand is a command from a client to the proxy.
|
||||
TypeCommand FrameType = iota
|
||||
// TypeResponse is a command response back from the proxy to a client.
|
||||
TypeResponse
|
||||
// TypeStream is a stream of data from a client to the proxy. Streams
|
||||
// are to be forwarded onto the VM agent.
|
||||
TypeStream
|
||||
// TypeNotification is a notification sent by either the proxy or
|
||||
// clients. Notifications are one way only and do not prompt a
|
||||
// response.
|
||||
TypeNotification
|
||||
// TypeMax is the number of types.
|
||||
TypeMax
|
||||
)
|
||||
|
||||
const unknown = "unknown"
|
||||
|
||||
// String implements Stringer for FrameType.
|
||||
func (t FrameType) String() string {
|
||||
switch t {
|
||||
case TypeCommand:
|
||||
return "command"
|
||||
case TypeResponse:
|
||||
return "response"
|
||||
case TypeStream:
|
||||
return "stream"
|
||||
case TypeNotification:
|
||||
return "notification"
|
||||
default:
|
||||
return unknown
|
||||
}
|
||||
}
|
||||
|
||||
// Command is the kind of command being sent. In the frame header, Opcode must
|
||||
// have one of these values when Type is api.TypeCommand.
|
||||
type Command int
|
||||
|
||||
const (
|
||||
// CmdRegisterVM registers a new VM/POD.
|
||||
CmdRegisterVM Command = iota
|
||||
// CmdUnregisterVM unregisters a VM/POD.
|
||||
CmdUnregisterVM
|
||||
// CmdAttachVM attaches to a registered VM.
|
||||
CmdAttachVM
|
||||
// CmdHyper sends a hyperstart command through the proxy.
|
||||
CmdHyper
|
||||
// CmdConnectShim identifies the client as a shim.
|
||||
CmdConnectShim
|
||||
// CmdDisconnectShim unregisters a shim. DisconnectShim is a bit
|
||||
// special and doesn't send a Response back but closes the connection.
|
||||
CmdDisconnectShim
|
||||
// CmdSignal sends a signal to the process inside the VM. A client
|
||||
// needs to be connected as a shim before it can issue that command.
|
||||
CmdSignal
|
||||
// CmdMax is the number of commands.
|
||||
CmdMax
|
||||
)
|
||||
|
||||
// String implements Stringer for Command.
|
||||
func (t Command) String() string {
|
||||
switch t {
|
||||
case CmdRegisterVM:
|
||||
return "RegisterVM"
|
||||
case CmdUnregisterVM:
|
||||
return "UnregisterVM"
|
||||
case CmdAttachVM:
|
||||
return "AttachVM"
|
||||
case CmdHyper:
|
||||
return "Hyper"
|
||||
case CmdConnectShim:
|
||||
return "ConnectShim"
|
||||
case CmdDisconnectShim:
|
||||
return "DisconnectShim"
|
||||
case CmdSignal:
|
||||
return "Signal"
|
||||
default:
|
||||
return unknown
|
||||
}
|
||||
}
|
||||
|
||||
// Stream is the kind of stream being sent. In the frame header, Opcode must
|
||||
// have one of the these values when Type is api.TypeStream.
|
||||
type Stream int
|
||||
|
||||
const (
|
||||
// StreamStdin is a stream conveying stdin data.
|
||||
StreamStdin Stream = iota
|
||||
// StreamStdout is a stream conveying stdout data.
|
||||
StreamStdout
|
||||
// StreamStderr is a stream conveying stderr data.
|
||||
StreamStderr
|
||||
// StreamLog is a stream conveying structured logs messages. Each Log frame
|
||||
// contains a JSON object which fields are the structured log. By convention
|
||||
// it would be nice to have a few common fields in log entries to ease
|
||||
// post-processing. See the LogEntry payload for details.
|
||||
StreamLog
|
||||
// StreamMax is the number of stream types.
|
||||
StreamMax
|
||||
)
|
||||
|
||||
// String implements Stringer for Stream.
|
||||
func (s Stream) String() string {
|
||||
switch s {
|
||||
case StreamStdin:
|
||||
return "stdin"
|
||||
case StreamStdout:
|
||||
return "stdout"
|
||||
case StreamStderr:
|
||||
return "stderr"
|
||||
case StreamLog:
|
||||
return "log"
|
||||
default:
|
||||
return unknown
|
||||
}
|
||||
}
|
||||
|
||||
// Notification is the kind of notification being sent. In the frame header,
|
||||
// Opcode must have one of the these values when Type is api.TypeNotification.
|
||||
type Notification int
|
||||
|
||||
const (
|
||||
// NotificationProcessExited is sent to signal a process in the VM has exited.
|
||||
NotificationProcessExited = iota
|
||||
// NotificationMax is the number of notification types.
|
||||
NotificationMax
|
||||
)
|
||||
|
||||
// String implements Stringer for Notification.
|
||||
func (n Notification) String() string {
|
||||
switch n {
|
||||
case NotificationProcessExited:
|
||||
return "ProcessExited"
|
||||
default:
|
||||
return unknown
|
||||
}
|
||||
}
|
||||
|
||||
// FrameHeader is the header of a Frame.
|
||||
type FrameHeader struct {
|
||||
Version int
|
||||
// HeaderLength in the size of the header in bytes (the on-wire
|
||||
// HeaderLength is in number of 32-bits words tough).
|
||||
HeaderLength int
|
||||
Type FrameType
|
||||
Opcode int
|
||||
PayloadLength int
|
||||
InError bool
|
||||
}
|
||||
|
||||
// Frame is the basic communication unit with the proxy.
|
||||
type Frame struct {
|
||||
Header FrameHeader
|
||||
Payload []byte
|
||||
}
|
||||
|
||||
// NewFrame creates a new Frame with type t, operand op and given payload.
|
||||
func NewFrame(t FrameType, op int, payload []byte) *Frame {
|
||||
return &Frame{
|
||||
Header: FrameHeader{
|
||||
Version: Version,
|
||||
HeaderLength: minHeaderLength,
|
||||
Type: t,
|
||||
Opcode: op,
|
||||
PayloadLength: len(payload),
|
||||
},
|
||||
Payload: payload,
|
||||
}
|
||||
}
|
||||
|
||||
// NewFrameJSON creates a new Frame with type t, operand op and given payload.
|
||||
// The payload structure is marshalled into JSON.
|
||||
func NewFrameJSON(t FrameType, op int, payload interface{}) (*Frame, error) {
|
||||
var data []byte
|
||||
|
||||
if payload != nil {
|
||||
var err error
|
||||
|
||||
if data, err = json.Marshal(payload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &Frame{
|
||||
Header: FrameHeader{
|
||||
Version: Version,
|
||||
HeaderLength: minHeaderLength,
|
||||
Type: t,
|
||||
Opcode: op,
|
||||
PayloadLength: len(data),
|
||||
},
|
||||
Payload: data,
|
||||
}, nil
|
||||
}
|
183
vendor/github.com/clearcontainers/proxy/api/payload.go
generated
vendored
183
vendor/github.com/clearcontainers/proxy/api/payload.go
generated
vendored
@ -1,183 +0,0 @@
|
||||
// Copyright (c) 2016,2017 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// The RegisterVM payload is issued first after connecting to the proxy socket.
|
||||
// It is used to let the proxy know about a new container on the system along
|
||||
// with the paths go hyperstart's command and I/O channels (AF_UNIX sockets).
|
||||
//
|
||||
// Console can be used to indicate the path of a socket linked to the VM
|
||||
// console. The proxy can output this data when asked for verbose output.
|
||||
//
|
||||
// {
|
||||
// "containerId": "756535dc6e9ab9b560f84c8...",
|
||||
// "ctlSerial": "/tmp/sh.hyper.channel.0.sock",
|
||||
// "ioSerial": "/tmp/sh.hyper.channel.1.sock",
|
||||
// "numIOStreams: 1
|
||||
// }
|
||||
type RegisterVM struct {
|
||||
ContainerID string `json:"containerId"`
|
||||
CtlSerial string `json:"ctlSerial"`
|
||||
IoSerial string `json:"ioSerial"`
|
||||
Console string `json:"console,omitempty"`
|
||||
// NumIOStreams asks for a number of I/O tokens. An I/O token
|
||||
// represents the communication between a container process inside
|
||||
// the VM and a shim process outside the VM. This communication
|
||||
// includes I/O streams (stdin, out, err) but also signals, exit
|
||||
// status, ...
|
||||
// The response frame will contain NumIOStreams I/O tokens.
|
||||
NumIOStreams int `json:"numIOStreams,omitempty"`
|
||||
}
|
||||
|
||||
// IOResponse is the response data in RegisterVMResponse and AttachVMResponse
|
||||
// when the client is asking for I/O tokens from the proxy (NumIOStreams > 0).
|
||||
type IOResponse struct {
|
||||
// URL is the URL a shim process should connect to in order to initiate
|
||||
// the I/O communication with the process inside the VM
|
||||
URL string
|
||||
// IOTokens is a array of I/O tokens of length NumIOStreams. See
|
||||
// RegisterVM for some details on I/O tokens.
|
||||
Tokens []string `json:"tokens"`
|
||||
}
|
||||
|
||||
// RegisterVMResponse is the result from a successful RegisterVM.
|
||||
//
|
||||
// {
|
||||
// "io": {
|
||||
// "url": "unix:///run/clearcontainers/proxy.sock",
|
||||
// "tokens": [
|
||||
// "bwgxfmQj9uG3YCsFHrvontwDw41CJJ76Y7qVt4Bi9wc="
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
type RegisterVMResponse struct {
|
||||
// IO contains the proxy answer when asking for I/O tokens.
|
||||
IO IOResponse `json:"io,omitempty"`
|
||||
}
|
||||
|
||||
// The AttachVM payload can be used to associate clients to an already known
|
||||
// VM. AttachVM cannot be issued if a RegisterVM for this container hasn't been
|
||||
// issued beforehand.
|
||||
//
|
||||
// {
|
||||
// "containerId": "756535dc6e9ab9b560f84c8...".
|
||||
// "numIOStreams: 1
|
||||
// }
|
||||
type AttachVM struct {
|
||||
ContainerID string `json:"containerId"`
|
||||
// NumIOStreams asks for a number of I/O tokens. See RegisterVM for
|
||||
// some details on I/O tokens.
|
||||
NumIOStreams int `json:"numIOStreams,omitempty"`
|
||||
}
|
||||
|
||||
// AttachVMResponse is the result from a successful AttachVM.
|
||||
//
|
||||
// {
|
||||
// "io": {
|
||||
// "url": "unix:///run/clearcontainers/proxy.sock",
|
||||
// "tokens": [
|
||||
// "bwgxfmQj9uG3YCsFHrvontwDw41CJJ76Y7qVt4Bi9wc="
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
type AttachVMResponse struct {
|
||||
// IO contains the proxy answer when asking for I/O tokens.
|
||||
IO IOResponse `json:"io,omitempty"`
|
||||
}
|
||||
|
||||
// The UnregisterVM payload does the opposite of what RegisterVM does,
|
||||
// indicating to the proxy it should release resources created by RegisterVM
|
||||
// for the container identified by containerId.
|
||||
//
|
||||
// {
|
||||
// "containerId": "756535dc6e9ab9b560f84c8..."
|
||||
// }
|
||||
type UnregisterVM struct {
|
||||
ContainerID string `json:"containerId"`
|
||||
}
|
||||
|
||||
// The Hyper payload will forward an hyperstart command to hyperstart.
|
||||
//
|
||||
// Note: the newcontainer and execmd hyperstart commands start one or more
|
||||
// processes. When sending those commands, tokens acquired through either
|
||||
// RegisterVM or AttachVM need to be sent along in the tokens array. The number
|
||||
// of tokens sent has to match the number of processes to be started.
|
||||
//
|
||||
// {
|
||||
// "hyperName": "newcontainer",
|
||||
// "tokens": [
|
||||
// "bwgxfmQj9uG3YCsFHrvontwDw41CJJ76Y7qVt4Bi9wc="
|
||||
// ],
|
||||
// "data": {
|
||||
// "id": "756535dc6e9ab9b560f84c8...",
|
||||
// "rootfs": "/foo/bar",
|
||||
// ...
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
type Hyper struct {
|
||||
HyperName string `json:"hyperName"`
|
||||
Tokens []string `json:"tokens"`
|
||||
Data json.RawMessage `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// ConnectShim identifies a shim against the proxy. A shim process is a process
|
||||
// running on host shadowing a container process running inside the VM. A shim
|
||||
// will forward stdin and signals to the process inside the VM and will receive
|
||||
// stdout, stderr and the exit status.
|
||||
type ConnectShim struct {
|
||||
// Token is id corresponding to the process the shim wants to handle
|
||||
// the I/O streams, signals, exit status for. Tokens are allocated with
|
||||
// a call to RegisterVM or AttachVM.
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// DisconnectShim unregister a shim from the proxy.
|
||||
type DisconnectShim struct {
|
||||
}
|
||||
|
||||
// Signal is used to send signals to the container process inside the VM. This
|
||||
// payload is only valid after a successful ConnectShim.
|
||||
type Signal struct {
|
||||
SignalNumber int `json:"signalNumber"`
|
||||
// Columns is only valid for SIGWINCH and is the new number of columns of
|
||||
// the terminal.
|
||||
Columns int `json:"columns,omitempty"`
|
||||
// Rows is only valid for SIGWINCH and is the new number of rows of the
|
||||
// terminal.
|
||||
Rows int `json:"rows,omitempty"`
|
||||
}
|
||||
|
||||
// ErrorResponse is the payload send in Responses where the Error flag is set.
|
||||
type ErrorResponse struct {
|
||||
Message string `json:"msg"`
|
||||
}
|
||||
|
||||
// LogEntry is the payload for the StreamLog data.
|
||||
type LogEntry struct {
|
||||
// Source is the source of the log entry. One of "shim" or "runtime".
|
||||
Source string `json:"source"`
|
||||
// ContainerID is the ID of the container the log entry is for (optional).
|
||||
ContainerID string `json:"containerId,omitempty"`
|
||||
// Level is the verbosity level of the log entry. One of "debug", "info", "warn"
|
||||
// or "error".
|
||||
Level string `json:"level"`
|
||||
// Message is the log message
|
||||
Message string `json:"msg"`
|
||||
}
|
213
vendor/github.com/clearcontainers/proxy/api/protocol.go
generated
vendored
213
vendor/github.com/clearcontainers/proxy/api/protocol.go
generated
vendored
@ -1,213 +0,0 @@
|
||||
// Copyright (c) 2016 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// minHeaderLength is the length of the header in the version 2 of protocol.
|
||||
// It is guaranteed later versions will have a header at least that big.
|
||||
const minHeaderLength = 12 // in bytes
|
||||
|
||||
// A Request is a JSON message sent from a client to the proxy. This message
|
||||
// embed a payload identified by "id". A payload can have data associated with
|
||||
// it. It's useful to think of Request as an RPC call with "id" as function
|
||||
// name and "data" as arguments.
|
||||
//
|
||||
// The list of possible payloads are documented in this package.
|
||||
//
|
||||
// Each Request has a corresponding Response message sent back from the proxy.
|
||||
type Request struct {
|
||||
ID string `json:"id"`
|
||||
Data json.RawMessage `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// A Response is a JSON message sent back from the proxy to a client after a
|
||||
// Request has been issued. The Response holds the result of the Request,
|
||||
// including its success state and optional data. It's useful to think of
|
||||
// Response as the result of an RPC call with ("success", "error") describing
|
||||
// if the call has been successful and "data" holding the optional results.
|
||||
type Response struct {
|
||||
Success bool `json:"success"`
|
||||
Error string `json:"error,omitempty"`
|
||||
Data map[string]interface{} `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// Offsets (in bytes) of frame headers fields.
|
||||
const (
|
||||
versionOffset = 0
|
||||
headerLengthOffset = 2
|
||||
typeOffset = 6
|
||||
flagsOffset = 6
|
||||
opcodeOffset = 7
|
||||
payloadLengthOffset = 8
|
||||
)
|
||||
|
||||
// Size (in bytes) of frame header fields (when larger than 1 byte).
|
||||
const (
|
||||
versionSize = 2
|
||||
payloadLengthSize = 4
|
||||
)
|
||||
|
||||
// Masks needed to extract fields
|
||||
const (
|
||||
typeMask = 0x0f
|
||||
flagsMask = 0xf0
|
||||
)
|
||||
|
||||
func maxOpcodeForFrameType(t FrameType) int {
|
||||
switch t {
|
||||
default:
|
||||
fallthrough
|
||||
case TypeCommand:
|
||||
return int(CmdMax)
|
||||
case TypeResponse:
|
||||
return int(CmdMax)
|
||||
case TypeStream:
|
||||
return int(StreamMax)
|
||||
case TypeNotification:
|
||||
return int(NotificationMax)
|
||||
}
|
||||
}
|
||||
|
||||
// ReadFrame reads a full frame (header and payload) from r.
|
||||
func ReadFrame(r io.Reader) (*Frame, error) {
|
||||
// Read the header.
|
||||
buf := make([]byte, minHeaderLength)
|
||||
n, err := r.Read(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n != minHeaderLength {
|
||||
return nil, errors.New("frame: couldn't read the full header")
|
||||
}
|
||||
|
||||
// Decode it.
|
||||
frame := &Frame{}
|
||||
header := &frame.Header
|
||||
header.Version = int(binary.BigEndian.Uint16(buf[versionOffset : versionOffset+versionSize]))
|
||||
if header.Version < 2 || header.Version > Version {
|
||||
return nil, fmt.Errorf("frame: bad version %d", header.Version)
|
||||
}
|
||||
header.HeaderLength = int(buf[headerLengthOffset]) * 4
|
||||
header.Type = FrameType(buf[typeOffset] & typeMask)
|
||||
flags := buf[flagsOffset] & flagsMask
|
||||
if flags&flagInError != 0 {
|
||||
header.InError = true
|
||||
}
|
||||
if header.Type >= TypeMax {
|
||||
return nil, fmt.Errorf("frame: bad type %s", header.Type)
|
||||
}
|
||||
header.Opcode = int(buf[opcodeOffset])
|
||||
if header.Opcode >= maxOpcodeForFrameType(header.Type) {
|
||||
return nil, fmt.Errorf("frame: bad opcode (%d) for type %s", header.Opcode,
|
||||
header.Type)
|
||||
}
|
||||
header.PayloadLength = int(binary.BigEndian.Uint32(buf[payloadLengthOffset : payloadLengthOffset+payloadLengthSize]))
|
||||
|
||||
// Read the payload.
|
||||
received := 0
|
||||
need := header.HeaderLength - minHeaderLength + header.PayloadLength
|
||||
payload := make([]byte, need)
|
||||
for received < need {
|
||||
n, err := r.Read(payload[received:need])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
received += n
|
||||
}
|
||||
|
||||
// Skip the bytes part of a bigger header than expected to just keep
|
||||
// the payload.
|
||||
frame.Payload = payload[header.HeaderLength-minHeaderLength : need]
|
||||
|
||||
return frame, nil
|
||||
}
|
||||
|
||||
const (
|
||||
flagInError = 1 << (4 + iota)
|
||||
)
|
||||
|
||||
// WriteFrame writes a frame into w.
|
||||
//
|
||||
// Note that frame.Header.PayloadLength dictates the amount of data of
|
||||
// frame.Payload to write, so frame.Header.Payload must be less or equal to
|
||||
// len(frame.Payload).
|
||||
func WriteFrame(w io.Writer, frame *Frame) error {
|
||||
header := &frame.Header
|
||||
|
||||
if len(frame.Payload) < header.PayloadLength {
|
||||
return fmt.Errorf("frame: bad payload length %d",
|
||||
header.PayloadLength)
|
||||
}
|
||||
|
||||
// Prepare the header.
|
||||
len := minHeaderLength + header.PayloadLength
|
||||
buf := make([]byte, len)
|
||||
binary.BigEndian.PutUint16(buf[versionOffset:versionOffset+versionSize], uint16(header.Version))
|
||||
buf[headerLengthOffset] = byte(header.HeaderLength / 4)
|
||||
flags := byte(0)
|
||||
if frame.Header.InError {
|
||||
flags |= flagInError
|
||||
}
|
||||
buf[typeOffset] = flags | byte(header.Type)&typeMask
|
||||
buf[opcodeOffset] = byte(header.Opcode)
|
||||
binary.BigEndian.PutUint32(buf[payloadLengthOffset:payloadLengthOffset+payloadLengthSize],
|
||||
uint32(header.PayloadLength))
|
||||
|
||||
// Write payload if needed
|
||||
if header.PayloadLength > 0 {
|
||||
copy(buf[minHeaderLength:], frame.Payload[0:header.PayloadLength])
|
||||
}
|
||||
|
||||
n, err := w.Write(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if n != len {
|
||||
return errors.New("frame: couldn't write frame")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteCommand is a convenience wrapper around WriteFrame to send commands.
|
||||
func WriteCommand(w io.Writer, op Command, payload []byte) error {
|
||||
return WriteFrame(w, NewFrame(TypeCommand, int(op), payload))
|
||||
}
|
||||
|
||||
// WriteResponse is a convenience wrapper around WriteFrame to send responses.
|
||||
func WriteResponse(w io.Writer, op Command, inError bool, payload []byte) error {
|
||||
frame := NewFrame(TypeResponse, int(op), payload)
|
||||
frame.Header.InError = inError
|
||||
return WriteFrame(w, frame)
|
||||
}
|
||||
|
||||
// WriteStream is a convenience wrapper around WriteFrame to send stream packets.
|
||||
func WriteStream(w io.Writer, op Stream, payload []byte) error {
|
||||
return WriteFrame(w, NewFrame(TypeStream, int(op), payload))
|
||||
}
|
||||
|
||||
// WriteNotification is a convenience wrapper around WriteFrame to send notifications.
|
||||
func WriteNotification(w io.Writer, op Notification, payload []byte) error {
|
||||
return WriteFrame(w, NewFrame(TypeNotification, int(op), payload))
|
||||
}
|
410
vendor/github.com/clearcontainers/proxy/client/client.go
generated
vendored
410
vendor/github.com/clearcontainers/proxy/client/client.go
generated
vendored
@ -1,410 +0,0 @@
|
||||
// Copyright (c) 2016 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"syscall"
|
||||
|
||||
"github.com/clearcontainers/proxy/api"
|
||||
)
|
||||
|
||||
// The Client struct can be used to issue proxy API calls with a convenient
|
||||
// high level API.
|
||||
type Client struct {
|
||||
conn net.Conn
|
||||
}
|
||||
|
||||
// NewClient creates a new client object to communicate with the proxy using
|
||||
// the connection conn. The user should call Close() once finished with the
|
||||
// client object to close conn.
|
||||
func NewClient(conn net.Conn) *Client {
|
||||
return &Client{
|
||||
conn: conn,
|
||||
}
|
||||
}
|
||||
|
||||
// Close a client, closing the underlying AF_UNIX socket.
|
||||
func (client *Client) Close() {
|
||||
client.conn.Close()
|
||||
}
|
||||
|
||||
func (client *Client) sendCommandFull(cmd api.Command, payload interface{},
|
||||
waitForResponse bool) (*api.Frame, error) {
|
||||
var data []byte
|
||||
var frame *api.Frame
|
||||
var err error
|
||||
|
||||
if payload != nil {
|
||||
if data, err = json.Marshal(payload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := api.WriteCommand(client.conn, cmd, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !waitForResponse {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if frame, err = api.ReadFrame(client.conn); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cmd == api.CmdSignal {
|
||||
payloadSignal, ok := payload.(*api.Signal)
|
||||
if !ok {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if payloadSignal.SignalNumber == int(syscall.SIGKILL) ||
|
||||
payloadSignal.SignalNumber == int(syscall.SIGTERM) {
|
||||
if frame.Header.Type != api.TypeNotification {
|
||||
return nil, fmt.Errorf("unexpected frame type %v", frame.Header.Type)
|
||||
}
|
||||
|
||||
if frame, err = api.ReadFrame(client.conn); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if frame.Header.Type != api.TypeResponse {
|
||||
return nil, fmt.Errorf("unexpected frame type %v", frame.Header.Type)
|
||||
}
|
||||
|
||||
if frame.Header.Opcode != int(cmd) {
|
||||
return nil, fmt.Errorf("unexpected opcode %v", frame.Header.Opcode)
|
||||
}
|
||||
|
||||
return frame, nil
|
||||
}
|
||||
|
||||
func (client *Client) sendCommand(cmd api.Command, payload interface{}) (*api.Frame, error) {
|
||||
return client.sendCommandFull(cmd, payload, true)
|
||||
}
|
||||
|
||||
func (client *Client) sendCommandNoResponse(cmd api.Command, payload interface{}) error {
|
||||
_, err := client.sendCommandFull(cmd, payload, false)
|
||||
return err
|
||||
}
|
||||
|
||||
func errorFromResponse(resp *api.Frame) error {
|
||||
// We should always have an error with the response, but better safe
|
||||
// than sorry.
|
||||
if !resp.Header.InError {
|
||||
return nil
|
||||
}
|
||||
|
||||
decoded := api.ErrorResponse{}
|
||||
if err := json.Unmarshal(resp.Payload, &decoded); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if decoded.Message == "" {
|
||||
return errors.New("unknown error")
|
||||
}
|
||||
|
||||
return errors.New(decoded.Message)
|
||||
}
|
||||
|
||||
func unmarshalResponse(resp *api.Frame, decoded interface{}) error {
|
||||
if len(resp.Payload) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(resp.Payload, decoded); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterVMOptions holds extra arguments one can pass to the RegisterVM
|
||||
// function.
|
||||
//
|
||||
// See the api.RegisterVM payload for more details.
|
||||
type RegisterVMOptions struct {
|
||||
Console string
|
||||
NumIOStreams int
|
||||
}
|
||||
|
||||
// RegisterVMReturn contains the return values from RegisterVM.
|
||||
//
|
||||
// See the api.RegisterVM and api.RegisterVMResponse payloads.
|
||||
type RegisterVMReturn api.RegisterVMResponse
|
||||
|
||||
// RegisterVM wraps the api.RegisterVM payload.
|
||||
//
|
||||
// See payload description for more details.
|
||||
func (client *Client) RegisterVM(containerID, ctlSerial, ioSerial string,
|
||||
options *RegisterVMOptions) (*RegisterVMReturn, error) {
|
||||
payload := api.RegisterVM{
|
||||
ContainerID: containerID,
|
||||
CtlSerial: ctlSerial,
|
||||
IoSerial: ioSerial,
|
||||
}
|
||||
|
||||
if options != nil {
|
||||
payload.Console = options.Console
|
||||
payload.NumIOStreams = options.NumIOStreams
|
||||
}
|
||||
|
||||
resp, err := client.sendCommand(api.CmdRegisterVM, &payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := errorFromResponse(resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
decoded := RegisterVMReturn{}
|
||||
err = unmarshalResponse(resp, &decoded)
|
||||
return &decoded, err
|
||||
}
|
||||
|
||||
// AttachVMOptions holds extra arguments one can pass to the AttachVM function.
|
||||
//
|
||||
// See the api.AttachVM payload for more details.
|
||||
type AttachVMOptions struct {
|
||||
NumIOStreams int
|
||||
}
|
||||
|
||||
// AttachVMReturn contains the return values from AttachVM.
|
||||
//
|
||||
// See the api.AttachVM and api.AttachVMResponse payloads.
|
||||
type AttachVMReturn api.AttachVMResponse
|
||||
|
||||
// AttachVM wraps the api.AttachVM payload.
|
||||
//
|
||||
// See the api.AttachVM payload description for more details.
|
||||
func (client *Client) AttachVM(containerID string, options *AttachVMOptions) (*AttachVMReturn, error) {
|
||||
payload := api.AttachVM{
|
||||
ContainerID: containerID,
|
||||
}
|
||||
|
||||
if options != nil {
|
||||
payload.NumIOStreams = options.NumIOStreams
|
||||
}
|
||||
|
||||
resp, err := client.sendCommand(api.CmdAttachVM, &payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := errorFromResponse(resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
decoded := AttachVMReturn{}
|
||||
err = unmarshalResponse(resp, &decoded)
|
||||
return &decoded, err
|
||||
}
|
||||
|
||||
// Hyper wraps the Hyper payload (see payload description for more details)
|
||||
func (client *Client) Hyper(hyperName string, hyperMessage interface{}) ([]byte, error) {
|
||||
return client.HyperWithTokens(hyperName, nil, hyperMessage)
|
||||
}
|
||||
|
||||
// HyperWithTokens is a Hyper variant where the users can specify a list of I/O tokens.
|
||||
//
|
||||
// See the api.Hyper payload description for more details.
|
||||
func (client *Client) HyperWithTokens(hyperName string, tokens []string, hyperMessage interface{}) ([]byte, error) {
|
||||
var data []byte
|
||||
|
||||
if hyperMessage != nil {
|
||||
var err error
|
||||
|
||||
data, err = json.Marshal(hyperMessage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
hyper := api.Hyper{
|
||||
HyperName: hyperName,
|
||||
Data: data,
|
||||
}
|
||||
|
||||
if tokens != nil {
|
||||
hyper.Tokens = tokens
|
||||
}
|
||||
|
||||
resp, err := client.sendCommand(api.CmdHyper, &hyper)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = errorFromResponse(resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.Payload, errorFromResponse(resp)
|
||||
}
|
||||
|
||||
// UnregisterVM wraps the api.UnregisterVM payload.
|
||||
//
|
||||
// See the api.UnregisterVM payload description for more details.
|
||||
func (client *Client) UnregisterVM(containerID string) error {
|
||||
payload := api.UnregisterVM{
|
||||
ContainerID: containerID,
|
||||
}
|
||||
|
||||
resp, err := client.sendCommand(api.CmdUnregisterVM, &payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return errorFromResponse(resp)
|
||||
}
|
||||
|
||||
// ConnectShim wraps the api.CmdConnectShim command and associated
|
||||
// api.ConnectShim payload.
|
||||
func (client *Client) ConnectShim(token string) error {
|
||||
payload := api.ConnectShim{
|
||||
Token: token,
|
||||
}
|
||||
|
||||
resp, err := client.sendCommand(api.CmdConnectShim, &payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return errorFromResponse(resp)
|
||||
}
|
||||
|
||||
// DisconnectShim wraps the api.CmdDisconnectShim command and associated
|
||||
// api.DisconnectShim payload.
|
||||
func (client *Client) DisconnectShim() error {
|
||||
return client.sendCommandNoResponse(api.CmdDisconnectShim, nil)
|
||||
}
|
||||
|
||||
func (client *Client) signal(signal syscall.Signal, columns, rows int) error {
|
||||
payload := api.Signal{
|
||||
SignalNumber: int(signal),
|
||||
Columns: columns,
|
||||
Rows: rows,
|
||||
}
|
||||
|
||||
resp, err := client.sendCommand(api.CmdSignal, &payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return errorFromResponse(resp)
|
||||
}
|
||||
|
||||
// Kill wraps the api.CmdSignal command and can be used by a shim to send a
|
||||
// signal to the associated process.
|
||||
func (client *Client) Kill(signal syscall.Signal) error {
|
||||
return client.signal(signal, 0, 0)
|
||||
}
|
||||
|
||||
// SendTerminalSize wraps the api.CmdSignal command and can be used by a shim
|
||||
// to send a new signal to the associated process.
|
||||
func (client *Client) SendTerminalSize(columns, rows int) error {
|
||||
return client.signal(syscall.SIGWINCH, columns, rows)
|
||||
}
|
||||
|
||||
func (client *Client) sendStream(op api.Stream, data []byte) error {
|
||||
return api.WriteStream(client.conn, op, data)
|
||||
}
|
||||
|
||||
// SendStdin sends stdin data. This can only be used from shim clients.
|
||||
func (client *Client) SendStdin(data []byte) error {
|
||||
return client.sendStream(api.StreamStdin, data)
|
||||
}
|
||||
|
||||
// LogLevel is the severity of log entries.
|
||||
type LogLevel uint8
|
||||
|
||||
const (
|
||||
// LogLevelDebug is for log messages only useful debugging.
|
||||
LogLevelDebug LogLevel = iota
|
||||
// LogLevelInfo is for reporting landmark events.
|
||||
LogLevelInfo
|
||||
// LogLevelWarn is for reporting warnings.
|
||||
LogLevelWarn
|
||||
// LogLevelError is for reporting errors.
|
||||
LogLevelError
|
||||
|
||||
logLevelMax
|
||||
)
|
||||
|
||||
var levelToString = []string{"debug", "info", "warn", "error"}
|
||||
|
||||
// String implements stringer for LogLevel.
|
||||
func (l LogLevel) String() string {
|
||||
if l < logLevelMax {
|
||||
return levelToString[l]
|
||||
}
|
||||
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
// LogSource is the source of log entries
|
||||
type LogSource uint8
|
||||
|
||||
const (
|
||||
// LogSourceRuntime represents a runtime.
|
||||
LogSourceRuntime LogSource = iota
|
||||
// LogSourceShim represents a shim.
|
||||
LogSourceShim
|
||||
|
||||
logSourceMax
|
||||
)
|
||||
|
||||
var sourceToString = []string{"runtime", "shim"}
|
||||
|
||||
// String implements stringer for LogSource
|
||||
func (s LogSource) String() string {
|
||||
if s < logSourceMax {
|
||||
return sourceToString[s]
|
||||
}
|
||||
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
// Log sends log entries.
|
||||
func (client *Client) Log(level LogLevel, source LogSource, containerID string, args ...interface{}) {
|
||||
payload := api.LogEntry{
|
||||
Level: level.String(),
|
||||
Source: source.String(),
|
||||
ContainerID: containerID,
|
||||
Message: fmt.Sprint(args...),
|
||||
}
|
||||
|
||||
data, _ := json.Marshal(&payload)
|
||||
_ = client.sendStream(api.StreamLog, data)
|
||||
}
|
||||
|
||||
// Logf sends log entries.
|
||||
func (client *Client) Logf(level LogLevel, source LogSource, containerID string, format string, args ...interface{}) {
|
||||
payload := api.LogEntry{
|
||||
Level: level.String(),
|
||||
Source: source.String(),
|
||||
ContainerID: containerID,
|
||||
Message: fmt.Sprintf(format, args...),
|
||||
}
|
||||
|
||||
data, _ := json.Marshal(&payload)
|
||||
_ = client.sendStream(api.StreamLog, data)
|
||||
}
|
970
vendor/github.com/kata-containers/agent/protocols/grpc/agent.pb.go
generated
vendored
970
vendor/github.com/kata-containers/agent/protocols/grpc/agent.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
49
vendor/github.com/mdlayher/vsock/conn_linux.go
generated
vendored
49
vendor/github.com/mdlayher/vsock/conn_linux.go
generated
vendored
@ -3,7 +3,6 @@
|
||||
package vsock
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
@ -11,31 +10,40 @@ import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var (
|
||||
// errDeadlinesNotImplemented is returned by the SetDeadline family of methods
|
||||
// for conn, because access is not yet available to the runtime network poller
|
||||
// for non-standard sockets types.
|
||||
// See: https://github.com/golang/go/issues/10565.
|
||||
errDeadlinesNotImplemented = errors.New("vsock: deadlines not implemented")
|
||||
)
|
||||
|
||||
var _ net.Conn = &conn{}
|
||||
|
||||
// A conn is the net.Conn implementation for VM sockets.
|
||||
type conn struct {
|
||||
*os.File
|
||||
file *os.File
|
||||
localAddr *Addr
|
||||
remoteAddr *Addr
|
||||
}
|
||||
|
||||
// LocalAddr and RemoteAddr implement the net.Conn interface for conn.
|
||||
func (c *conn) LocalAddr() net.Addr { return c.localAddr }
|
||||
func (c *conn) RemoteAddr() net.Addr { return c.remoteAddr }
|
||||
// Implement net.Conn for type conn.
|
||||
func (c *conn) LocalAddr() net.Addr { return c.localAddr }
|
||||
func (c *conn) RemoteAddr() net.Addr { return c.remoteAddr }
|
||||
func (c *conn) SetDeadline(t time.Time) error { return c.file.SetDeadline(t) }
|
||||
func (c *conn) SetReadDeadline(t time.Time) error { return c.file.SetReadDeadline(t) }
|
||||
func (c *conn) SetWriteDeadline(t time.Time) error { return c.file.SetWriteDeadline(t) }
|
||||
func (c *conn) Read(b []byte) (n int, err error) { return c.file.Read(b) }
|
||||
func (c *conn) Write(b []byte) (n int, err error) { return c.file.Write(b) }
|
||||
func (c *conn) Close() error { return c.file.Close() }
|
||||
|
||||
// SetDeadline functions implement the net.Conn interface for conn.
|
||||
func (c *conn) SetDeadline(_ time.Time) error { return errDeadlinesNotImplemented }
|
||||
func (c *conn) SetReadDeadline(_ time.Time) error { return errDeadlinesNotImplemented }
|
||||
func (c *conn) SetWriteDeadline(_ time.Time) error { return errDeadlinesNotImplemented }
|
||||
// newConn creates a conn using an fd with the specified file name, local, and
|
||||
// remote addresses.
|
||||
func newConn(cfd fd, file string, local, remote *Addr) (*conn, error) {
|
||||
// Enable integration with runtime network poller for timeout support
|
||||
// in Go 1.11+.
|
||||
if err := cfd.SetNonblock(true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &conn{
|
||||
file: cfd.NewFile(file),
|
||||
localAddr: local,
|
||||
remoteAddr: remote,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// dialStream is the entry point for DialStream on Linux.
|
||||
func dialStream(cid, port uint32) (net.Conn, error) {
|
||||
@ -89,9 +97,6 @@ func dialStreamLinux(cfd fd, cid, port uint32) (net.Conn, error) {
|
||||
Port: port,
|
||||
}
|
||||
|
||||
return &conn{
|
||||
File: cfd.NewFile(remoteAddr.fileName()),
|
||||
localAddr: localAddr,
|
||||
remoteAddr: remoteAddr,
|
||||
}, nil
|
||||
// File name is the name of the local socket.
|
||||
return newConn(cfd, localAddr.fileName(), localAddr, remoteAddr)
|
||||
}
|
||||
|
6
vendor/github.com/mdlayher/vsock/fd_linux.go
generated
vendored
6
vendor/github.com/mdlayher/vsock/fd_linux.go
generated
vendored
@ -11,11 +11,12 @@ import (
|
||||
type fd interface {
|
||||
Accept4(flags int) (fd, unix.Sockaddr, error)
|
||||
Bind(sa unix.Sockaddr) error
|
||||
Connect(sa unix.Sockaddr) error
|
||||
Close() error
|
||||
Connect(sa unix.Sockaddr) error
|
||||
Getsockname() (unix.Sockaddr, error)
|
||||
Listen(n int) error
|
||||
NewFile(name string) *os.File
|
||||
SetNonblock(nonblocking bool) error
|
||||
}
|
||||
|
||||
var _ fd = &sysFD{}
|
||||
@ -38,6 +39,7 @@ func (fd *sysFD) Accept4(flags int) (fd, unix.Sockaddr, error) {
|
||||
func (fd *sysFD) Bind(sa unix.Sockaddr) error { return unix.Bind(fd.fd, sa) }
|
||||
func (fd *sysFD) Close() error { return unix.Close(fd.fd) }
|
||||
func (fd *sysFD) Connect(sa unix.Sockaddr) error { return unix.Connect(fd.fd, sa) }
|
||||
func (fd *sysFD) Getsockname() (unix.Sockaddr, error) { return unix.Getsockname(fd.fd) }
|
||||
func (fd *sysFD) Listen(n int) error { return unix.Listen(fd.fd, n) }
|
||||
func (fd *sysFD) NewFile(name string) *os.File { return os.NewFile(uintptr(fd.fd), name) }
|
||||
func (fd *sysFD) Getsockname() (unix.Sockaddr, error) { return unix.Getsockname(fd.fd) }
|
||||
func (fd *sysFD) SetNonblock(nonblocking bool) error { return unix.SetNonblock(fd.fd, nonblocking) }
|
||||
|
10
vendor/github.com/mdlayher/vsock/listener_linux.go
generated
vendored
10
vendor/github.com/mdlayher/vsock/listener_linux.go
generated
vendored
@ -35,11 +35,7 @@ func (l *listener) Accept() (net.Conn, error) {
|
||||
Port: savm.Port,
|
||||
}
|
||||
|
||||
return &conn{
|
||||
File: cfd.NewFile(l.addr.fileName()),
|
||||
localAddr: l.addr,
|
||||
remoteAddr: remoteAddr,
|
||||
}, nil
|
||||
return newConn(cfd, l.addr.fileName(), l.addr, remoteAddr)
|
||||
}
|
||||
|
||||
// listenStream is the entry point for ListenStream on Linux.
|
||||
@ -87,6 +83,10 @@ func listenStreamLinux(lfd fd, cid, port uint32) (net.Listener, error) {
|
||||
Port: port,
|
||||
}
|
||||
|
||||
if err := lfd.SetNonblock(true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := lfd.Bind(sa); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -91,19 +91,19 @@ func newAgent(agentType AgentType) agent {
|
||||
}
|
||||
|
||||
// newAgentConfig returns an agent config from a generic SandboxConfig interface.
|
||||
func newAgentConfig(agentType AgentType, agentConfig interface{}) interface{} {
|
||||
func newAgentConfig(agentType AgentType, agentConfig interface{}) (interface{}, error) {
|
||||
switch agentType {
|
||||
case NoopAgentType:
|
||||
return nil
|
||||
return nil, nil
|
||||
case KataContainersAgent:
|
||||
var kataAgentConfig KataAgentConfig
|
||||
err := mapstructure.Decode(agentConfig, &kataAgentConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
return kataAgentConfig
|
||||
return kataAgentConfig, nil
|
||||
default:
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,7 +116,7 @@ type agent interface {
|
||||
// init().
|
||||
// After init() is called, agent implementations should be initialized and ready
|
||||
// to handle all other Agent interface methods.
|
||||
init(ctx context.Context, sandbox *Sandbox, config interface{}) error
|
||||
init(ctx context.Context, sandbox *Sandbox, config interface{}) (disableVMShutdown bool, err error)
|
||||
|
||||
// capabilities should return a structure that specifies the capabilities
|
||||
// supported by the agent.
|
||||
|
@ -86,7 +86,12 @@ func TestNewAgentFromUnknownAgentType(t *testing.T) {
|
||||
}
|
||||
|
||||
func testNewAgentConfig(t *testing.T, config SandboxConfig, expected interface{}) {
|
||||
agentConfig := newAgentConfig(config.AgentType, config.AgentConfig)
|
||||
agentConfig, err := newAgentConfig(config.AgentType, config.AgentConfig)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
}
|
||||
|
||||
if reflect.DeepEqual(agentConfig, expected) == false {
|
||||
t.Fatal()
|
||||
}
|
||||
|
@ -83,11 +83,25 @@ var (
|
||||
maxHostnameLen = 64
|
||||
)
|
||||
|
||||
const (
|
||||
agentTraceModeDynamic = "dynamic"
|
||||
agentTraceModeStatic = "static"
|
||||
agentTraceTypeIsolated = "isolated"
|
||||
agentTraceTypeCollated = "collated"
|
||||
|
||||
defaultAgentTraceMode = agentTraceModeDynamic
|
||||
defaultAgentTraceType = agentTraceTypeIsolated
|
||||
)
|
||||
|
||||
// KataAgentConfig is a structure storing information needed
|
||||
// to reach the Kata Containers agent.
|
||||
type KataAgentConfig struct {
|
||||
LongLiveConn bool
|
||||
UseVSock bool
|
||||
Debug bool
|
||||
Trace bool
|
||||
TraceMode string
|
||||
TraceType string
|
||||
}
|
||||
|
||||
type kataVSOCK struct {
|
||||
@ -115,10 +129,11 @@ type kataAgent struct {
|
||||
sync.Mutex
|
||||
client *kataclient.AgentClient
|
||||
|
||||
reqHandlers map[string]reqFunc
|
||||
state KataAgentState
|
||||
keepConn bool
|
||||
proxyBuiltIn bool
|
||||
reqHandlers map[string]reqFunc
|
||||
state KataAgentState
|
||||
keepConn bool
|
||||
proxyBuiltIn bool
|
||||
dynamicTracing bool
|
||||
|
||||
vmSocket interface{}
|
||||
ctx context.Context
|
||||
@ -175,7 +190,68 @@ func (k *kataAgent) generateVMSocket(id string, c KataAgentConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k *kataAgent) init(ctx context.Context, sandbox *Sandbox, config interface{}) (err error) {
|
||||
// KataAgentSetDefaultTraceConfigOptions validates agent trace options and
|
||||
// sets defaults.
|
||||
func KataAgentSetDefaultTraceConfigOptions(config *KataAgentConfig) error {
|
||||
if !config.Trace {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch config.TraceMode {
|
||||
case agentTraceModeDynamic:
|
||||
case agentTraceModeStatic:
|
||||
case "":
|
||||
config.TraceMode = defaultAgentTraceMode
|
||||
default:
|
||||
return fmt.Errorf("invalid kata agent trace mode: %q (need %q or %q)", config.TraceMode, agentTraceModeDynamic, agentTraceModeStatic)
|
||||
}
|
||||
|
||||
switch config.TraceType {
|
||||
case agentTraceTypeIsolated:
|
||||
case agentTraceTypeCollated:
|
||||
case "":
|
||||
config.TraceType = defaultAgentTraceType
|
||||
default:
|
||||
return fmt.Errorf("invalid kata agent trace type: %q (need %q or %q)", config.TraceType, agentTraceTypeIsolated, agentTraceTypeCollated)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// KataAgentKernelParams returns a list of Kata Agent specific kernel
|
||||
// parameters.
|
||||
func KataAgentKernelParams(config KataAgentConfig) []Param {
|
||||
var params []Param
|
||||
|
||||
if config.Debug {
|
||||
params = append(params, Param{Key: "agent.log", Value: "debug"})
|
||||
}
|
||||
|
||||
if config.Trace && config.TraceMode == agentTraceModeStatic {
|
||||
params = append(params, Param{Key: "agent.trace", Value: config.TraceType})
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
func (k *kataAgent) handleTraceSettings(config KataAgentConfig) bool {
|
||||
if !config.Trace {
|
||||
return false
|
||||
}
|
||||
|
||||
disableVMShutdown := false
|
||||
|
||||
switch config.TraceMode {
|
||||
case agentTraceModeStatic:
|
||||
disableVMShutdown = true
|
||||
case agentTraceModeDynamic:
|
||||
k.dynamicTracing = true
|
||||
}
|
||||
|
||||
return disableVMShutdown
|
||||
}
|
||||
|
||||
func (k *kataAgent) init(ctx context.Context, sandbox *Sandbox, config interface{}) (disableVMShutdown bool, err error) {
|
||||
// save
|
||||
k.ctx = sandbox.ctx
|
||||
|
||||
@ -185,21 +261,23 @@ func (k *kataAgent) init(ctx context.Context, sandbox *Sandbox, config interface
|
||||
switch c := config.(type) {
|
||||
case KataAgentConfig:
|
||||
if err := k.generateVMSocket(sandbox.id, c); err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
disableVMShutdown = k.handleTraceSettings(c)
|
||||
k.keepConn = c.LongLiveConn
|
||||
default:
|
||||
return fmt.Errorf("Invalid config type")
|
||||
return false, vcTypes.ErrInvalidConfigType
|
||||
}
|
||||
|
||||
k.proxy, err = newProxy(sandbox.config.ProxyType)
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
k.shim, err = newShim(sandbox.config.ShimType)
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
k.proxyBuiltIn = isProxyBuiltIn(sandbox.config.ProxyType)
|
||||
@ -209,7 +287,7 @@ func (k *kataAgent) init(ctx context.Context, sandbox *Sandbox, config interface
|
||||
k.Logger().Debug("Could not retrieve anything from storage")
|
||||
}
|
||||
|
||||
return nil
|
||||
return disableVMShutdown, nil
|
||||
}
|
||||
|
||||
func (k *kataAgent) agentURL() (string, error) {
|
||||
@ -241,7 +319,7 @@ func (k *kataAgent) internalConfigure(h hypervisor, id, sharePath string, builti
|
||||
}
|
||||
k.keepConn = c.LongLiveConn
|
||||
default:
|
||||
return fmt.Errorf("Invalid config type")
|
||||
return vcTypes.ErrInvalidConfigType
|
||||
}
|
||||
}
|
||||
|
||||
@ -275,7 +353,7 @@ func (k *kataAgent) configure(h hypervisor, id, sharePath string, builtin bool,
|
||||
}
|
||||
k.vmSocket = s
|
||||
default:
|
||||
return fmt.Errorf("Invalid config type")
|
||||
return vcTypes.ErrInvalidConfigType
|
||||
}
|
||||
|
||||
// Neither create shared directory nor add 9p device if hypervisor
|
||||
@ -702,7 +780,18 @@ func (k *kataAgent) startSandbox(sandbox *Sandbox) error {
|
||||
}
|
||||
|
||||
_, err = k.sendReq(req)
|
||||
return err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if k.dynamicTracing {
|
||||
_, err = k.sendReq(&grpc.StartTracingRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k *kataAgent) stopSandbox(sandbox *Sandbox) error {
|
||||
@ -719,6 +808,13 @@ func (k *kataAgent) stopSandbox(sandbox *Sandbox) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if k.dynamicTracing {
|
||||
_, err := k.sendReq(&grpc.StopTracingRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := k.proxy.stop(k.state.ProxyPid); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1632,6 +1728,12 @@ func (k *kataAgent) installReqFunc(c *kataclient.AgentClient) {
|
||||
k.reqHandlers["grpc.SetGuestDateTimeRequest"] = func(ctx context.Context, req interface{}, opts ...golangGrpc.CallOption) (interface{}, error) {
|
||||
return k.client.SetGuestDateTime(ctx, req.(*grpc.SetGuestDateTimeRequest), opts...)
|
||||
}
|
||||
k.reqHandlers["grpc.StartTracingRequest"] = func(ctx context.Context, req interface{}, opts ...golangGrpc.CallOption) (interface{}, error) {
|
||||
return k.client.StartTracing(ctx, req.(*grpc.StartTracingRequest), opts...)
|
||||
}
|
||||
k.reqHandlers["grpc.StopTracingRequest"] = func(ctx context.Context, req interface{}, opts ...golangGrpc.CallOption) (interface{}, error) {
|
||||
return k.client.StopTracing(ctx, req.(*grpc.StopTracingRequest), opts...)
|
||||
}
|
||||
}
|
||||
|
||||
func (k *kataAgent) sendReq(request interface{}) (interface{}, error) {
|
||||
|
@ -191,14 +191,6 @@ func (p *gRPCProxy) DestroySandbox(ctx context.Context, req *pb.DestroySandboxRe
|
||||
return emptyResp, nil
|
||||
}
|
||||
|
||||
func (p *gRPCProxy) AddInterface(ctx context.Context, req *pb.AddInterfaceRequest) (*aTypes.Interface, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (p *gRPCProxy) RemoveInterface(ctx context.Context, req *pb.RemoveInterfaceRequest) (*aTypes.Interface, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (p *gRPCProxy) UpdateInterface(ctx context.Context, req *pb.UpdateInterfaceRequest) (*aTypes.Interface, error) {
|
||||
return &aTypes.Interface{}, nil
|
||||
}
|
||||
@ -256,6 +248,14 @@ func (p *gRPCProxy) CopyFile(ctx context.Context, req *pb.CopyFileRequest) (*gpb
|
||||
return &gpb.Empty{}, nil
|
||||
}
|
||||
|
||||
func (p *gRPCProxy) StartTracing(ctx context.Context, req *pb.StartTracingRequest) (*gpb.Empty, error) {
|
||||
return &gpb.Empty{}, nil
|
||||
}
|
||||
|
||||
func (p *gRPCProxy) StopTracing(ctx context.Context, req *pb.StopTracingRequest) (*gpb.Empty, error) {
|
||||
return &gpb.Empty{}, nil
|
||||
}
|
||||
|
||||
func (p *gRPCProxy) MemHotplugByProbe(ctx context.Context, req *pb.MemHotplugByProbeRequest) (*gpb.Empty, error) {
|
||||
return &gpb.Empty{}, nil
|
||||
}
|
||||
@ -934,3 +934,199 @@ func TestKataCleanupSandbox(t *testing.T) {
|
||||
t.Fatalf("%s still exists\n", dir)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKataAgentKernelParams(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
type testData struct {
|
||||
debug bool
|
||||
trace bool
|
||||
traceMode string
|
||||
traceType string
|
||||
expectedParams []Param
|
||||
}
|
||||
|
||||
debugParam := Param{Key: "agent.log", Value: "debug"}
|
||||
|
||||
traceIsolatedParam := Param{Key: "agent.trace", Value: "isolated"}
|
||||
traceCollatedParam := Param{Key: "agent.trace", Value: "collated"}
|
||||
|
||||
traceFooParam := Param{Key: "agent.trace", Value: "foo"}
|
||||
|
||||
data := []testData{
|
||||
{false, false, "", "", []Param{}},
|
||||
{true, false, "", "", []Param{debugParam}},
|
||||
|
||||
{false, false, "foo", "", []Param{}},
|
||||
{false, false, "foo", "", []Param{}},
|
||||
{false, false, "", "foo", []Param{}},
|
||||
{false, false, "", "foo", []Param{}},
|
||||
{false, false, "foo", "foo", []Param{}},
|
||||
{false, true, "foo", "foo", []Param{}},
|
||||
|
||||
{false, false, agentTraceModeDynamic, "", []Param{}},
|
||||
{false, false, agentTraceModeStatic, "", []Param{}},
|
||||
{false, false, "", agentTraceTypeIsolated, []Param{}},
|
||||
{false, false, "", agentTraceTypeCollated, []Param{}},
|
||||
{false, false, "foo", agentTraceTypeIsolated, []Param{}},
|
||||
{false, false, "foo", agentTraceTypeCollated, []Param{}},
|
||||
|
||||
{false, false, agentTraceModeDynamic, agentTraceTypeIsolated, []Param{}},
|
||||
{false, false, agentTraceModeDynamic, agentTraceTypeCollated, []Param{}},
|
||||
|
||||
{false, false, agentTraceModeStatic, agentTraceTypeCollated, []Param{}},
|
||||
{false, false, agentTraceModeStatic, agentTraceTypeCollated, []Param{}},
|
||||
|
||||
{false, true, agentTraceModeDynamic, agentTraceTypeIsolated, []Param{}},
|
||||
{false, true, agentTraceModeDynamic, agentTraceTypeCollated, []Param{}},
|
||||
{true, true, agentTraceModeDynamic, agentTraceTypeCollated, []Param{debugParam}},
|
||||
|
||||
{false, true, "", agentTraceTypeIsolated, []Param{}},
|
||||
{false, true, "", agentTraceTypeCollated, []Param{}},
|
||||
{true, true, "", agentTraceTypeIsolated, []Param{debugParam}},
|
||||
{true, true, "", agentTraceTypeCollated, []Param{debugParam}},
|
||||
{false, true, "foo", agentTraceTypeIsolated, []Param{}},
|
||||
{false, true, "foo", agentTraceTypeCollated, []Param{}},
|
||||
{true, true, "foo", agentTraceTypeIsolated, []Param{debugParam}},
|
||||
{true, true, "foo", agentTraceTypeCollated, []Param{debugParam}},
|
||||
|
||||
{false, true, agentTraceModeStatic, agentTraceTypeIsolated, []Param{traceIsolatedParam}},
|
||||
{false, true, agentTraceModeStatic, agentTraceTypeCollated, []Param{traceCollatedParam}},
|
||||
{true, true, agentTraceModeStatic, agentTraceTypeIsolated, []Param{traceIsolatedParam, debugParam}},
|
||||
{true, true, agentTraceModeStatic, agentTraceTypeCollated, []Param{traceCollatedParam, debugParam}},
|
||||
|
||||
{false, true, agentTraceModeStatic, "foo", []Param{traceFooParam}},
|
||||
{true, true, agentTraceModeStatic, "foo", []Param{debugParam, traceFooParam}},
|
||||
}
|
||||
|
||||
for i, d := range data {
|
||||
config := KataAgentConfig{
|
||||
Debug: d.debug,
|
||||
Trace: d.trace,
|
||||
TraceMode: d.traceMode,
|
||||
TraceType: d.traceType,
|
||||
}
|
||||
|
||||
count := len(d.expectedParams)
|
||||
|
||||
params := KataAgentKernelParams(config)
|
||||
|
||||
if count == 0 {
|
||||
assert.Emptyf(params, "test %d (%+v)", i, d)
|
||||
continue
|
||||
}
|
||||
|
||||
assert.Len(params, count)
|
||||
|
||||
for _, p := range d.expectedParams {
|
||||
assert.Containsf(params, p, "test %d (%+v)", i, d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestKataAgentHandleTraceSettings(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
type testData struct {
|
||||
traceMode string
|
||||
trace bool
|
||||
expectDisableVMShutdown bool
|
||||
expectDynamicTracing bool
|
||||
}
|
||||
|
||||
data := []testData{
|
||||
{"", false, false, false},
|
||||
{"", true, false, false},
|
||||
{agentTraceModeStatic, true, true, false},
|
||||
{agentTraceModeDynamic, true, false, true},
|
||||
}
|
||||
|
||||
for i, d := range data {
|
||||
k := &kataAgent{}
|
||||
|
||||
config := KataAgentConfig{
|
||||
Trace: d.trace,
|
||||
TraceMode: d.traceMode,
|
||||
}
|
||||
|
||||
disableVMShutdown := k.handleTraceSettings(config)
|
||||
|
||||
if d.expectDisableVMShutdown {
|
||||
assert.Truef(disableVMShutdown, "test %d (%+v)", i, d)
|
||||
} else {
|
||||
assert.Falsef(disableVMShutdown, "test %d (%+v)", i, d)
|
||||
}
|
||||
|
||||
if d.expectDynamicTracing {
|
||||
assert.Truef(k.dynamicTracing, "test %d (%+v)", i, d)
|
||||
} else {
|
||||
assert.Falsef(k.dynamicTracing, "test %d (%+v)", i, d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestKataAgentSetDefaultTraceConfigOptions(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
type testData struct {
|
||||
traceMode string
|
||||
traceType string
|
||||
trace bool
|
||||
expectDefaultTraceMode bool
|
||||
expectDefaultTraceType bool
|
||||
expectError bool
|
||||
}
|
||||
|
||||
data := []testData{
|
||||
{"", "", false, false, false, false},
|
||||
{agentTraceModeDynamic, agentTraceTypeCollated, false, false, false, false},
|
||||
{agentTraceModeDynamic, agentTraceTypeIsolated, false, false, false, false},
|
||||
{agentTraceModeStatic, agentTraceTypeCollated, false, false, false, false},
|
||||
{agentTraceModeStatic, agentTraceTypeIsolated, false, false, false, false},
|
||||
|
||||
{agentTraceModeDynamic, agentTraceTypeCollated, true, false, false, false},
|
||||
{agentTraceModeDynamic, agentTraceTypeIsolated, true, false, false, false},
|
||||
|
||||
{agentTraceModeStatic, agentTraceTypeCollated, true, false, false, false},
|
||||
{agentTraceModeStatic, agentTraceTypeIsolated, true, false, false, false},
|
||||
|
||||
{agentTraceModeDynamic, "", true, false, true, false},
|
||||
{agentTraceModeDynamic, "invalid", true, false, false, true},
|
||||
|
||||
{agentTraceModeStatic, "", true, false, true, false},
|
||||
{agentTraceModeStatic, "invalid", true, false, false, true},
|
||||
|
||||
{"", agentTraceTypeIsolated, true, true, false, false},
|
||||
{"invalid", agentTraceTypeIsolated, true, false, false, true},
|
||||
|
||||
{"", agentTraceTypeCollated, true, true, false, false},
|
||||
{"invalid", agentTraceTypeCollated, true, false, false, true},
|
||||
|
||||
{"", "", true, true, true, false},
|
||||
{"invalid", "invalid", true, false, false, true},
|
||||
}
|
||||
|
||||
for i, d := range data {
|
||||
config := &KataAgentConfig{
|
||||
Trace: d.trace,
|
||||
TraceMode: d.traceMode,
|
||||
TraceType: d.traceType,
|
||||
}
|
||||
|
||||
err := KataAgentSetDefaultTraceConfigOptions(config)
|
||||
if d.expectError {
|
||||
assert.Error(err, "test %d (%+v)", i, d)
|
||||
continue
|
||||
} else {
|
||||
assert.NoError(err, "test %d (%+v)", i, d)
|
||||
}
|
||||
|
||||
if d.expectDefaultTraceMode {
|
||||
assert.Equalf(config.TraceMode, defaultAgentTraceMode, "test %d (%+v)", i, d)
|
||||
}
|
||||
|
||||
if d.expectDefaultTraceType {
|
||||
assert.Equalf(config.TraceType, defaultAgentTraceType, "test %d (%+v)", i, d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,13 +11,6 @@ import (
|
||||
|
||||
type kataShim struct{}
|
||||
|
||||
// KataShimConfig is the structure providing specific configuration
|
||||
// for kataShim implementation.
|
||||
type KataShimConfig struct {
|
||||
Path string
|
||||
Debug bool
|
||||
}
|
||||
|
||||
// start is the ccShim start implementation.
|
||||
// It starts the cc-shim binary with URL and token flags provided by
|
||||
// the proxy.
|
||||
@ -28,7 +21,7 @@ func (s *kataShim) start(sandbox *Sandbox, params ShimParams) (int, error) {
|
||||
|
||||
config, ok := newShimConfig(*(sandbox.config)).(ShimConfig)
|
||||
if !ok {
|
||||
return -1, fmt.Errorf("Wrong shim config type, should be KataShimConfig type")
|
||||
return -1, fmt.Errorf("Wrong shim config type, should be ShimConfig type")
|
||||
}
|
||||
|
||||
if config.Path == "" {
|
||||
|
@ -27,8 +27,8 @@ func (n *noopAgent) startProxy(sandbox *Sandbox) error {
|
||||
}
|
||||
|
||||
// init initializes the Noop agent, i.e. it does nothing.
|
||||
func (n *noopAgent) init(ctx context.Context, sandbox *Sandbox, config interface{}) error {
|
||||
return nil
|
||||
func (n *noopAgent) init(ctx context.Context, sandbox *Sandbox, config interface{}) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// createSandbox is the Noop agent sandbox creation implementation. It does nothing.
|
||||
|
@ -40,10 +40,14 @@ func TestNoopAgentInit(t *testing.T) {
|
||||
n := &noopAgent{}
|
||||
sandbox := &Sandbox{}
|
||||
|
||||
err := n.init(context.Background(), sandbox, nil)
|
||||
disableVMShutdown, err := n.init(context.Background(), sandbox, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if disableVMShutdown != false {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoopAgentExec(t *testing.T) {
|
||||
|
@ -11,9 +11,10 @@ import (
|
||||
|
||||
// common error objects used for argument checking
|
||||
var (
|
||||
ErrNeedSandbox = errors.New("Sandbox must be specified")
|
||||
ErrNeedSandboxID = errors.New("Sandbox ID cannot be empty")
|
||||
ErrNeedContainerID = errors.New("Container ID cannot be empty")
|
||||
ErrNeedState = errors.New("State cannot be empty")
|
||||
ErrNoSuchContainer = errors.New("Container does not exist")
|
||||
ErrNeedSandbox = errors.New("Sandbox must be specified")
|
||||
ErrNeedSandboxID = errors.New("Sandbox ID cannot be empty")
|
||||
ErrNeedContainerID = errors.New("Container ID cannot be empty")
|
||||
ErrNeedState = errors.New("State cannot be empty")
|
||||
ErrNoSuchContainer = errors.New("Container does not exist")
|
||||
ErrInvalidConfigType = errors.New("Invalid config type")
|
||||
)
|
||||
|
@ -186,10 +186,11 @@ type Sandbox struct {
|
||||
|
||||
wg *sync.WaitGroup
|
||||
|
||||
shmSize uint64
|
||||
sharePidNs bool
|
||||
stateful bool
|
||||
seccompSupported bool
|
||||
shmSize uint64
|
||||
sharePidNs bool
|
||||
stateful bool
|
||||
seccompSupported bool
|
||||
disableVMShutdown bool
|
||||
|
||||
ctx context.Context
|
||||
}
|
||||
@ -583,8 +584,12 @@ func newSandbox(ctx context.Context, sandboxConfig SandboxConfig, factory Factor
|
||||
return nil, err
|
||||
}
|
||||
|
||||
agentConfig := newAgentConfig(sandboxConfig.AgentType, sandboxConfig.AgentConfig)
|
||||
if err = s.agent.init(ctx, s, agentConfig); err != nil {
|
||||
agentConfig, err := newAgentConfig(sandboxConfig.AgentType, sandboxConfig.AgentConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if s.disableVMShutdown, err = s.agent.init(ctx, s, agentConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -1030,6 +1035,13 @@ func (s *Sandbox) stopVM() error {
|
||||
s.Logger().WithError(err).WithField("sandboxid", s.id).Warning("Agent did not stop sandbox")
|
||||
}
|
||||
|
||||
if s.disableVMShutdown {
|
||||
// Do not kill the VM - allow the agent to shut it down
|
||||
// (only used to support static agent tracing).
|
||||
s.Logger().Info("Not stopping VM")
|
||||
return nil
|
||||
}
|
||||
|
||||
s.Logger().Info("Stopping VM")
|
||||
return s.hypervisor.stopSandbox()
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ func TestVMConfigGrpc(t *testing.T) {
|
||||
HypervisorType: QemuHypervisor,
|
||||
HypervisorConfig: newQemuConfig(),
|
||||
AgentType: KataContainersAgent,
|
||||
AgentConfig: KataAgentConfig{false, true},
|
||||
AgentConfig: KataAgentConfig{false, true, false, false, "", ""},
|
||||
ProxyType: NoopProxyType,
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user