mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-09-02 01:16:27 +00:00
api: add sandbox release API
It disconnects the agent connection and removes the sandbox from global sandbox list. A new option `LongLiveConn` is also added to kata agent's configuration. When set, the API caller is expected to call sandbox.Release() to drop the agent connection explicitly. `proxyBuiltIn` is moved out of agent state because we can always retrieve it from sandbox config instead. Fixes: #217 Signed-off-by: Peng Tao <bergwolf@gmail.com>
This commit is contained in:
@@ -133,6 +133,9 @@ type agent interface {
|
|||||||
// supported by the agent.
|
// supported by the agent.
|
||||||
capabilities() capabilities
|
capabilities() capabilities
|
||||||
|
|
||||||
|
// disconnect will disconnect the connection to the agent
|
||||||
|
disconnect() error
|
||||||
|
|
||||||
// createSandbox will tell the agent to perform necessary setup for a Sandbox.
|
// createSandbox will tell the agent to perform necessary setup for a Sandbox.
|
||||||
createSandbox(sandbox *Sandbox) error
|
createSandbox(sandbox *Sandbox) error
|
||||||
|
|
||||||
|
@@ -2273,3 +2273,16 @@ func TestFetchNonExistingSandbox(t *testing.T) {
|
|||||||
_, err := FetchSandbox("some-non-existing-sandbox-name")
|
_, err := FetchSandbox("some-non-existing-sandbox-name")
|
||||||
assert.NotNil(t, err, "fetch non-existing sandbox should fail")
|
assert.NotNil(t, err, "fetch non-existing sandbox should fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReleaseSandbox(t *testing.T) {
|
||||||
|
cleanUp()
|
||||||
|
|
||||||
|
config := newTestSandboxConfigNoop()
|
||||||
|
|
||||||
|
s, err := CreateSandbox(config)
|
||||||
|
if s == nil || err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
err = s.Release()
|
||||||
|
assert.Nil(t, err, "sandbox release failed: %v", err)
|
||||||
|
}
|
||||||
|
@@ -715,13 +715,13 @@ func (h *hyper) connect() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *hyper) disconnect() {
|
func (h *hyper) disconnect() error {
|
||||||
if h.client == nil {
|
if h.client != nil {
|
||||||
return
|
h.client.Close()
|
||||||
|
h.client = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
h.client.Close()
|
return nil
|
||||||
h.client = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *hyper) register() error {
|
func (h *hyper) register() error {
|
||||||
|
@@ -45,6 +45,8 @@ type VCSandbox interface {
|
|||||||
GetContainer(containerID string) VCContainer
|
GetContainer(containerID string) VCContainer
|
||||||
ID() string
|
ID() string
|
||||||
SetAnnotations(annotations map[string]string) error
|
SetAnnotations(annotations map[string]string) error
|
||||||
|
|
||||||
|
Release() error
|
||||||
}
|
}
|
||||||
|
|
||||||
// VCContainer is the Container interface
|
// VCContainer is the Container interface
|
||||||
|
@@ -21,8 +21,10 @@ import (
|
|||||||
vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
|
vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
|
||||||
ns "github.com/kata-containers/runtime/virtcontainers/pkg/nsenter"
|
ns "github.com/kata-containers/runtime/virtcontainers/pkg/nsenter"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/pkg/uuid"
|
"github.com/kata-containers/runtime/virtcontainers/pkg/uuid"
|
||||||
|
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
golangGrpc "google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -47,7 +49,8 @@ var (
|
|||||||
// KataAgentConfig is a structure storing information needed
|
// KataAgentConfig is a structure storing information needed
|
||||||
// to reach the Kata Containers agent.
|
// to reach the Kata Containers agent.
|
||||||
type KataAgentConfig struct {
|
type KataAgentConfig struct {
|
||||||
GRPCSocket string
|
GRPCSocket string
|
||||||
|
LongLiveConn bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type kataVSOCK struct {
|
type kataVSOCK struct {
|
||||||
@@ -62,16 +65,17 @@ func (s *kataVSOCK) String() string {
|
|||||||
// KataAgentState is the structure describing the data stored from this
|
// KataAgentState is the structure describing the data stored from this
|
||||||
// agent implementation.
|
// agent implementation.
|
||||||
type KataAgentState struct {
|
type KataAgentState struct {
|
||||||
ProxyPid int
|
ProxyPid int
|
||||||
ProxyBuiltIn bool
|
URL string
|
||||||
URL string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type kataAgent struct {
|
type kataAgent struct {
|
||||||
shim shim
|
shim shim
|
||||||
proxy proxy
|
proxy proxy
|
||||||
client *kataclient.AgentClient
|
client *kataclient.AgentClient
|
||||||
state KataAgentState
|
state KataAgentState
|
||||||
|
keepConn bool
|
||||||
|
proxyBuiltIn bool
|
||||||
|
|
||||||
vmSocket interface{}
|
vmSocket interface{}
|
||||||
}
|
}
|
||||||
@@ -128,6 +132,7 @@ func (k *kataAgent) init(sandbox *Sandbox, config interface{}) (err error) {
|
|||||||
if err := k.generateVMSocket(*sandbox, c); err != nil {
|
if err := k.generateVMSocket(*sandbox, c); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
k.keepConn = c.LongLiveConn
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Invalid config type")
|
return fmt.Errorf("Invalid config type")
|
||||||
}
|
}
|
||||||
@@ -142,6 +147,8 @@ func (k *kataAgent) init(sandbox *Sandbox, config interface{}) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
k.proxyBuiltIn = isProxyBuiltIn(sandbox.config.ProxyType)
|
||||||
|
|
||||||
// Fetch agent runtime info.
|
// Fetch agent runtime info.
|
||||||
if err := sandbox.storage.fetchAgentState(sandbox.id, &k.state); err != nil {
|
if err := sandbox.storage.fetchAgentState(sandbox.id, &k.state); err != nil {
|
||||||
k.Logger().Debug("Could not retrieve anything from storage")
|
k.Logger().Debug("Could not retrieve anything from storage")
|
||||||
@@ -418,7 +425,6 @@ func (k *kataAgent) startSandbox(sandbox Sandbox) error {
|
|||||||
|
|
||||||
// Fill agent state with proxy information, and store them.
|
// Fill agent state with proxy information, and store them.
|
||||||
k.state.ProxyPid = pid
|
k.state.ProxyPid = pid
|
||||||
k.state.ProxyBuiltIn = isProxyBuiltIn(sandbox.config.ProxyType)
|
|
||||||
k.state.URL = uri
|
k.state.URL = uri
|
||||||
if err := sandbox.storage.storeAgentState(sandbox.id, k.state); err != nil {
|
if err := sandbox.storage.storeAgentState(sandbox.id, k.state); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -905,7 +911,7 @@ func (k *kataAgent) connect() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := kataclient.NewAgentClient(k.state.URL, k.state.ProxyBuiltIn)
|
client, err := kataclient.NewAgentClient(k.state.URL, k.proxyBuiltIn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -920,10 +926,9 @@ func (k *kataAgent) disconnect() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := k.client.Close(); err != nil {
|
if err := k.client.Close(); err != nil && err != golangGrpc.ErrClientConnClosing {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
k.client = nil
|
k.client = nil
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -933,7 +938,9 @@ func (k *kataAgent) sendReq(request interface{}) (interface{}, error) {
|
|||||||
if err := k.connect(); err != nil {
|
if err := k.connect(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer k.disconnect()
|
if !k.keepConn {
|
||||||
|
defer k.disconnect()
|
||||||
|
}
|
||||||
|
|
||||||
switch req := request.(type) {
|
switch req := request.(type) {
|
||||||
case *grpc.ExecProcessRequest:
|
case *grpc.ExecProcessRequest:
|
||||||
|
@@ -29,6 +29,11 @@ func (n *noopAgent) capabilities() capabilities {
|
|||||||
return capabilities{}
|
return capabilities{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// disconnect is the Noop agent connection closer. It does nothing.
|
||||||
|
func (n *noopAgent) disconnect() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// exec is the Noop agent command execution implementation. It does nothing.
|
// exec is the Noop agent command execution implementation. It does nothing.
|
||||||
func (n *noopAgent) exec(sandbox *Sandbox, c Container, cmd Cmd) (*Process, error) {
|
func (n *noopAgent) exec(sandbox *Sandbox, c Container, cmd Cmd) (*Process, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@@ -49,3 +49,8 @@ func (p *Sandbox) GetContainer(containerID string) vc.VCContainer {
|
|||||||
}
|
}
|
||||||
return &Container{}
|
return &Container{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Release implements the VCSandbox function of the same name.
|
||||||
|
func (p *Sandbox) Release() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@@ -529,6 +529,12 @@ func (s *Sandbox) GetContainer(containerID string) VCContainer {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Release closes the agent connection and removes sandbox from internal list.
|
||||||
|
func (s *Sandbox) Release() error {
|
||||||
|
globalSandboxList.removeSandbox(s.id)
|
||||||
|
return s.agent.disconnect()
|
||||||
|
}
|
||||||
|
|
||||||
func createAssets(sandboxConfig *SandboxConfig) error {
|
func createAssets(sandboxConfig *SandboxConfig) error {
|
||||||
kernel, err := newAsset(sandboxConfig, kernelAsset)
|
kernel, err := newAsset(sandboxConfig, kernelAsset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Reference in New Issue
Block a user