From 8573c8d5c17bc292ba6b676bd199767ec147f886 Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Tue, 26 Mar 2019 14:44:32 +0000 Subject: [PATCH] agent: Support Kata agent tracing Add configuration options to support the various Kata agent tracing modes and types. See the comments in the configuration files for details: - `cli/config/configuration-fc.toml` - `cli/config/configuration-qemu.toml` Fixes #1369. Signed-off-by: James O. D. Hunt --- cli/config/configuration-fc.toml.in | 21 +++ cli/config/configuration-qemu.toml.in | 21 +++ cli/kata-env.go | 12 +- cli/kata-env_test.go | 18 +++ pkg/katautils/config.go | 29 +++- pkg/katautils/config_test.go | 10 ++ virtcontainers/agent.go | 2 +- virtcontainers/hyperstart_agent.go | 10 +- virtcontainers/kata_agent.go | 108 ++++++++++++-- virtcontainers/kata_agent_test.go | 195 ++++++++++++++++++++++++-- virtcontainers/noop_agent.go | 4 +- virtcontainers/sandbox.go | 18 ++- virtcontainers/vm_test.go | 2 +- 13 files changed, 410 insertions(+), 40 deletions(-) diff --git a/cli/config/configuration-fc.toml.in b/cli/config/configuration-fc.toml.in index 7cc052b728..d90c79e2d1 100644 --- a/cli/config/configuration-fc.toml.in +++ b/cli/config/configuration-fc.toml.in @@ -226,6 +226,27 @@ path = "@SHIMPATH@" # (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 # sandbox is created. This allows for the detection of some additional diff --git a/cli/config/configuration-qemu.toml.in b/cli/config/configuration-qemu.toml.in index 63e67f544f..aeaa1a5d20 100644 --- a/cli/config/configuration-qemu.toml.in +++ b/cli/config/configuration-qemu.toml.in @@ -273,6 +273,27 @@ path = "@SHIMPATH@" # (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 # sandbox is created. This allows for the detection of some additional diff --git a/cli/kata-env.go b/cli/kata-env.go index 0d6883bb75..af8c9a7513 100644 --- a/cli/kata-env.go +++ b/cli/kata-env.go @@ -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.22" +const formatVersion = "1.0.23" // MetaInfo stores information on the format of the output itself type MetaInfo struct { @@ -112,8 +112,11 @@ type ShimInfo struct { // AgentInfo stores agent details type AgentInfo struct { - Type string - Debug bool + Type string + Debug bool + Trace bool + TraceMode string + TraceType string } // DistroInfo stores host operating system distribution details. @@ -321,6 +324,9 @@ func getAgentInfo(config oci.RuntimeConfig) (AgentInfo, error) { 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 } diff --git a/cli/kata-env_test.go b/cli/kata-env_test.go index 73bfaeae2a..a2c5c6de59 100644 --- a/cli/kata-env_test.go +++ b/cli/kata-env_test.go @@ -43,6 +43,7 @@ var ( shimDebug = false netmonDebug = false agentDebug = false + agentTrace = false ) // makeVersionBinary creates a shell script with the specified file @@ -155,6 +156,7 @@ func makeRuntimeConfig(prefixDir string) (configFile string, config oci.RuntimeC ShimDebug: shimDebug, NetmonDebug: netmonDebug, AgentDebug: agentDebug, + AgentTrace: agentTrace, } runtimeConfig := katatestutils.MakeRuntimeConfigFileData(configFileOptions) @@ -217,6 +219,11 @@ func getExpectedAgentDetails(config oci.RuntimeConfig) (AgentInfo, error) { return AgentInfo{ Type: string(config.AgentType), Debug: agentConfig.Debug, + Trace: agentConfig.Trace, + + // No trace mode/type set by default + TraceMode: "", + TraceType: "", }, nil } @@ -496,6 +503,7 @@ func TestEnvGetEnvInfo(t *testing.T) { runtimeTrace = toggle shimDebug = toggle agentDebug = toggle + agentTrace = toggle configFile, config, err := makeRuntimeConfig(tmpdir) assert.NoError(t, err) @@ -823,6 +831,16 @@ func TestEnvGetAgentInfo(t *testing.T) { 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) diff --git a/pkg/katautils/config.go b/pkg/katautils/config.go index 748a1dc921..71d990369a 100644 --- a/pkg/katautils/config.go +++ b/pkg/katautils/config.go @@ -138,7 +138,10 @@ type shim struct { } type agent struct { - Debug bool `toml:"enable_debug"` + Debug bool `toml:"enable_debug"` + Tracing bool `toml:"enable_tracing"` + TraceMode string `toml:"trace_mode"` + TraceType string `toml:"trace_type"` } type netmon struct { @@ -395,6 +398,18 @@ 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 } @@ -655,8 +670,11 @@ func updateRuntimeConfigAgent(configPath string, tomlConf tomlConfig, config *oc case kataAgentTableType: config.AgentType = vc.KataContainersAgent config.AgentConfig = vc.KataAgentConfig{ - UseVSock: config.HypervisorConfig.UseVSock, - Debug: agent.debug(), + UseVSock: config.HypervisorConfig.UseVSock, + Debug: agent.debug(), + Trace: agent.trace(), + TraceMode: agent.traceMode(), + TraceType: agent.traceType(), } } } @@ -717,6 +735,11 @@ 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 { diff --git a/pkg/katautils/config_test.go b/pkg/katautils/config_test.go index 9d521ee402..1293253dbc 100644 --- a/pkg/katautils/config_test.go +++ b/pkg/katautils/config_test.go @@ -34,6 +34,7 @@ var ( shimDebug = false netmonDebug = false agentDebug = false + agentTrace = false ) type testRuntimeConfig struct { @@ -111,6 +112,7 @@ func createAllRuntimeConfigFiles(dir, hypervisor string) (config testRuntimeConf ShimDebug: shimDebug, NetmonDebug: netmonDebug, AgentDebug: agentDebug, + AgentTrace: agentTrace, } runtimeConfigFileData := katatestutils.MakeRuntimeConfigFileData(configFileOptions) @@ -1206,6 +1208,14 @@ func TestAgentDefaults(t *testing.T) { 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) { diff --git a/virtcontainers/agent.go b/virtcontainers/agent.go index 9f98fb27b9..97e9037b09 100644 --- a/virtcontainers/agent.go +++ b/virtcontainers/agent.go @@ -133,7 +133,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. diff --git a/virtcontainers/hyperstart_agent.go b/virtcontainers/hyperstart_agent.go index a8c6e9624c..5876327221 100644 --- a/virtcontainers/hyperstart_agent.go +++ b/virtcontainers/hyperstart_agent.go @@ -264,7 +264,7 @@ func fsMapFromDevices(c *Container) ([]*hyperstart.FsmapDescriptor, error) { } // init is the agent initialization implementation for hyperstart. -func (h *hyper) init(ctx context.Context, sandbox *Sandbox, config interface{}) (err error) { +func (h *hyper) init(ctx context.Context, sandbox *Sandbox, config interface{}) (disableVMShutdown bool, err error) { // save h.ctx = ctx @@ -276,17 +276,17 @@ func (h *hyper) init(ctx context.Context, sandbox *Sandbox, config interface{}) h.sandbox = sandbox default: - return errInvalidConfigType + return false, errInvalidConfigType } h.proxy, err = newProxy(sandbox.config.ProxyType) if err != nil { - return err + return false, err } h.shim, err = newShim(sandbox.config.ShimType) if err != nil { - return err + return false, err } // Fetch agent runtime info. @@ -294,7 +294,7 @@ func (h *hyper) init(ctx context.Context, sandbox *Sandbox, config interface{}) h.Logger().Debug("Could not retrieve anything from storage") } - return nil + return false, nil } func (h *hyper) getVMPath(id string) string { diff --git a/virtcontainers/kata_agent.go b/virtcontainers/kata_agent.go index dc5747f992..e4fafc4dbb 100644 --- a/virtcontainers/kata_agent.go +++ b/virtcontainers/kata_agent.go @@ -72,12 +72,25 @@ var ( grpcMaxDataSize = int64(1024 * 1024) ) +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 { @@ -112,6 +125,8 @@ type kataAgent struct { vmSocket interface{} ctx context.Context + + dynamicTracing bool } func (k *kataAgent) trace(name string) (opentracing.Span, context.Context) { @@ -165,6 +180,34 @@ func (k *kataAgent) generateVMSocket(id string, c KataAgentConfig) error { return nil } +// 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 { @@ -174,10 +217,31 @@ func KataAgentKernelParams(config KataAgentConfig) []Param { 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) init(ctx context.Context, sandbox *Sandbox, config interface{}) (err error) { +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 @@ -186,32 +250,34 @@ 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 + if err = k.generateVMSocket(sandbox.id, c); err != nil { + return false, err } + + disableVMShutdown = k.handleTraceSettings(c) k.keepConn = c.LongLiveConn default: - return errInvalidConfigType + return false, 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) // Fetch agent runtime info. - if err := sandbox.store.Load(store.Agent, &k.state); err != nil { + if err = sandbox.store.Load(store.Agent, &k.state); err != nil { k.Logger().Debug("Could not retrieve anything from storage") } - return nil + return disableVMShutdown, nil } func (k *kataAgent) agentURL() (string, error) { @@ -704,7 +770,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 { @@ -721,6 +798,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 } @@ -1593,6 +1677,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) { diff --git a/virtcontainers/kata_agent_test.go b/virtcontainers/kata_agent_test.go index 68a970e179..dce1ae86a5 100644 --- a/virtcontainers/kata_agent_test.go +++ b/virtcontainers/kata_agent_test.go @@ -941,22 +941,195 @@ func TestKataCleanupSandbox(t *testing.T) { func TestKataAgentKernelParams(t *testing.T) { assert := assert.New(t) - config := KataAgentConfig{} + 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) - assert.Empty(params) + params := KataAgentKernelParams(config) - config.Debug = true + if count == 0 { + assert.Emptyf(params, "test %d (%+v)", i, d) + continue + } + + assert.Len(params, count) - params = KataAgentKernelParams(config) - assert.NotEmpty(params) + for _, p := range d.expectedParams { + assert.Containsf(params, p, "test %d (%+v)", i, d) + } + } +} - assert.Len(params, 1) +func TestKataAgentHandleTraceSettings(t *testing.T) { + assert := assert.New(t) - expected := Param{ - Key: "agent.log", - Value: "debug", + type testData struct { + trace bool + traceMode string + expectDisableVMShutdown bool + expectDynamicTracing bool } - assert.Equal(params[0], expected) + data := []testData{ + {false, "", false, false}, + {true, "", false, false}, + {true, agentTraceModeStatic, true, false}, + {true, agentTraceModeDynamic, 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 { + trace bool + traceMode string + traceType string + expectDefaultTraceMode bool + expectDefaultTraceType bool + expectError bool + } + + data := []testData{ + {false, "", "", 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}, + + {true, agentTraceModeDynamic, agentTraceTypeCollated, false, false, false}, + {true, agentTraceModeDynamic, agentTraceTypeIsolated, false, false, false}, + + {true, agentTraceModeStatic, agentTraceTypeCollated, false, false, false}, + {true, agentTraceModeStatic, agentTraceTypeIsolated, false, false, false}, + + {true, agentTraceModeDynamic, "", false, true, false}, + {true, agentTraceModeDynamic, "invalid", false, false, true}, + + {true, agentTraceModeStatic, "", false, true, false}, + {true, agentTraceModeStatic, "invalid", false, false, true}, + + {true, "", agentTraceTypeIsolated, true, false, false}, + {true, "invalid", agentTraceTypeIsolated, false, false, true}, + + {true, "", agentTraceTypeCollated, true, false, false}, + {true, "invalid", agentTraceTypeCollated, false, false, true}, + + {true, "", "", true, true, false}, + {true, "invalid", "invalid", 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) + } + } } diff --git a/virtcontainers/noop_agent.go b/virtcontainers/noop_agent.go index db9a3dcbdf..34f2ed60d1 100644 --- a/virtcontainers/noop_agent.go +++ b/virtcontainers/noop_agent.go @@ -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. diff --git a/virtcontainers/sandbox.go b/virtcontainers/sandbox.go index 536f663ce4..fd4e022356 100644 --- a/virtcontainers/sandbox.go +++ b/virtcontainers/sandbox.go @@ -181,10 +181,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 } @@ -555,7 +556,7 @@ func newSandbox(ctx context.Context, sandboxConfig SandboxConfig, factory Factor return nil, err } - if err = s.agent.init(ctx, s, agentConfig); err != nil { + if s.disableVMShutdown, err = s.agent.init(ctx, s, agentConfig); err != nil { return nil, err } @@ -988,6 +989,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() } diff --git a/virtcontainers/vm_test.go b/virtcontainers/vm_test.go index 7b3583b4bb..bc36bcf522 100644 --- a/virtcontainers/vm_test.go +++ b/virtcontainers/vm_test.go @@ -118,7 +118,7 @@ func TestVMConfigGrpc(t *testing.T) { HypervisorType: QemuHypervisor, HypervisorConfig: newQemuConfig(), AgentType: KataContainersAgent, - AgentConfig: KataAgentConfig{false, true, false}, + AgentConfig: KataAgentConfig{false, true, false, false, "", ""}, ProxyType: NoopProxyType, }