github.com/kata-containers/runtime@v0.0.0-20210505125100-04f29832a923/virtcontainers/agent.go (about)

     1  // Copyright (c) 2016 Intel Corporation
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  //
     5  
     6  package virtcontainers
     7  
     8  import (
     9  	"fmt"
    10  	"syscall"
    11  	"time"
    12  
    13  	"github.com/kata-containers/agent/protocols/grpc"
    14  	persistapi "github.com/kata-containers/runtime/virtcontainers/persist/api"
    15  	vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types"
    16  	"github.com/kata-containers/runtime/virtcontainers/types"
    17  	"github.com/mitchellh/mapstructure"
    18  	specs "github.com/opencontainers/runtime-spec/specs-go"
    19  	"golang.org/x/net/context"
    20  )
    21  
    22  // AgentType describes the type of guest agent a Sandbox should run.
    23  type AgentType string
    24  
    25  // ProcessListOptions contains the options used to list running
    26  // processes inside the container
    27  type ProcessListOptions struct {
    28  	// Format describes the output format to list the running processes.
    29  	// Formats are unrelated to ps(1) formats, only two formats can be specified:
    30  	// "json" and "table"
    31  	Format string
    32  
    33  	// Args contains the list of arguments to run ps(1) command.
    34  	// If Args is empty the agent will use "-ef" as options to ps(1).
    35  	Args []string
    36  }
    37  
    38  // ProcessList represents the list of running processes inside the container
    39  type ProcessList []byte
    40  
    41  const (
    42  	// NoopAgentType is the No-Op agent.
    43  	NoopAgentType AgentType = "noop"
    44  
    45  	// KataContainersAgent is the Kata Containers agent.
    46  	KataContainersAgent AgentType = "kata"
    47  
    48  	// SocketTypeVSOCK is a VSOCK socket type for talking to an agent.
    49  	SocketTypeVSOCK = "vsock"
    50  
    51  	// SocketTypeUNIX is a UNIX socket type for talking to an agent.
    52  	// It typically means the agent is living behind a host proxy.
    53  	SocketTypeUNIX = "unix"
    54  )
    55  
    56  // Set sets an agent type based on the input string.
    57  func (agentType *AgentType) Set(value string) error {
    58  	switch value {
    59  	case "noop":
    60  		*agentType = NoopAgentType
    61  		return nil
    62  	case "kata":
    63  		*agentType = KataContainersAgent
    64  		return nil
    65  	default:
    66  		return fmt.Errorf("Unknown agent type %s", value)
    67  	}
    68  }
    69  
    70  // String converts an agent type to a string.
    71  func (agentType *AgentType) String() string {
    72  	switch *agentType {
    73  	case NoopAgentType:
    74  		return string(NoopAgentType)
    75  	case KataContainersAgent:
    76  		return string(KataContainersAgent)
    77  	default:
    78  		return ""
    79  	}
    80  }
    81  
    82  // newAgent returns an agent from an agent type.
    83  func newAgent(agentType AgentType) agent {
    84  	switch agentType {
    85  	case NoopAgentType:
    86  		return &noopAgent{}
    87  	case KataContainersAgent:
    88  		return &kataAgent{}
    89  	default:
    90  		return &noopAgent{}
    91  	}
    92  }
    93  
    94  // newAgentConfig returns an agent config from a generic SandboxConfig interface.
    95  func newAgentConfig(agentType AgentType, agentConfig interface{}) (interface{}, error) {
    96  	switch agentType {
    97  	case NoopAgentType:
    98  		return nil, nil
    99  	case KataContainersAgent:
   100  		var kataAgentConfig KataAgentConfig
   101  		err := mapstructure.Decode(agentConfig, &kataAgentConfig)
   102  		if err != nil {
   103  			return nil, err
   104  		}
   105  		return kataAgentConfig, nil
   106  	default:
   107  		return nil, nil
   108  	}
   109  }
   110  
   111  // agent is the virtcontainers agent interface.
   112  // Agents are running in the guest VM and handling
   113  // communications between the host and guest.
   114  type agent interface {
   115  	// init is used to pass agent specific configuration to the agent implementation.
   116  	// agent implementations also will typically start listening for agent events from
   117  	// init().
   118  	// After init() is called, agent implementations should be initialized and ready
   119  	// to handle all other Agent interface methods.
   120  	init(ctx context.Context, sandbox *Sandbox, config interface{}) (disableVMShutdown bool, err error)
   121  
   122  	// capabilities should return a structure that specifies the capabilities
   123  	// supported by the agent.
   124  	capabilities() types.Capabilities
   125  
   126  	// check will check the agent liveness
   127  	check() error
   128  
   129  	// tell whether the agent is long  live connected or not
   130  	longLiveConn() bool
   131  
   132  	// disconnect will disconnect the connection to the agent
   133  	disconnect() error
   134  
   135  	// start the proxy
   136  	startProxy(sandbox *Sandbox) error
   137  
   138  	// set to use an existing proxy
   139  	setProxy(sandbox *Sandbox, proxy proxy, pid int, url string) error
   140  
   141  	// set to use an existing proxy from Grpc
   142  	setProxyFromGrpc(proxy proxy, pid int, url string)
   143  
   144  	// get agent url
   145  	getAgentURL() (string, error)
   146  
   147  	// update the agent using some elements from another agent
   148  	reuseAgent(agent agent) error
   149  
   150  	// createSandbox will tell the agent to perform necessary setup for a Sandbox.
   151  	createSandbox(sandbox *Sandbox) error
   152  
   153  	// exec will tell the agent to run a command in an already running container.
   154  	exec(sandbox *Sandbox, c Container, cmd types.Cmd) (*Process, error)
   155  
   156  	// startSandbox will tell the agent to start all containers related to the Sandbox.
   157  	startSandbox(sandbox *Sandbox) error
   158  
   159  	// stopSandbox will tell the agent to stop all containers related to the Sandbox.
   160  	stopSandbox(sandbox *Sandbox) error
   161  
   162  	// createContainer will tell the agent to create a container related to a Sandbox.
   163  	createContainer(sandbox *Sandbox, c *Container) (*Process, error)
   164  
   165  	// startContainer will tell the agent to start a container related to a Sandbox.
   166  	startContainer(sandbox *Sandbox, c *Container) error
   167  
   168  	// stopContainer will tell the agent to stop a container related to a Sandbox.
   169  	stopContainer(sandbox *Sandbox, c Container) error
   170  
   171  	// signalProcess will tell the agent to send a signal to a
   172  	// container or a process related to a Sandbox. If all is true, all processes in
   173  	// the container will be sent the signal.
   174  	signalProcess(c *Container, processID string, signal syscall.Signal, all bool) error
   175  
   176  	// winsizeProcess will tell the agent to set a process' tty size
   177  	winsizeProcess(c *Container, processID string, height, width uint32) error
   178  
   179  	// writeProcessStdin will tell the agent to write a process stdin
   180  	writeProcessStdin(c *Container, ProcessID string, data []byte) (int, error)
   181  
   182  	// closeProcessStdin will tell the agent to close a process stdin
   183  	closeProcessStdin(c *Container, ProcessID string) error
   184  
   185  	// readProcessStdout will tell the agent to read a process stdout
   186  	readProcessStdout(c *Container, processID string, data []byte) (int, error)
   187  
   188  	// readProcessStderr will tell the agent to read a process stderr
   189  	readProcessStderr(c *Container, processID string, data []byte) (int, error)
   190  
   191  	// processListContainer will list the processes running inside the container
   192  	processListContainer(sandbox *Sandbox, c Container, options ProcessListOptions) (ProcessList, error)
   193  
   194  	// updateContainer will update the resources of a running container
   195  	updateContainer(sandbox *Sandbox, c Container, resources specs.LinuxResources) error
   196  
   197  	// waitProcess will wait for the exit code of a process
   198  	waitProcess(c *Container, processID string) (int32, error)
   199  
   200  	// onlineCPUMem will online CPUs and Memory inside the Sandbox.
   201  	// This function should be called after hot adding vCPUs or Memory.
   202  	// cpus specifies the number of CPUs that were added and the agent should online
   203  	// cpuOnly specifies that we should online cpu or online memory or both
   204  	onlineCPUMem(cpus uint32, cpuOnly bool) error
   205  
   206  	// memHotplugByProbe will notify the guest kernel about memory hotplug event through
   207  	// probe interface.
   208  	// This function should be called after hot adding Memory and before online memory.
   209  	// addr specifies the address of the recently hotplugged or unhotplugged memory device.
   210  	memHotplugByProbe(addr uint64, sizeMB uint32, memorySectionSizeMB uint32) error
   211  
   212  	// statsContainer will tell the agent to get stats from a container related to a Sandbox
   213  	statsContainer(sandbox *Sandbox, c Container) (*ContainerStats, error)
   214  
   215  	// pauseContainer will pause a container
   216  	pauseContainer(sandbox *Sandbox, c Container) error
   217  
   218  	// resumeContainer will resume a paused container
   219  	resumeContainer(sandbox *Sandbox, c Container) error
   220  
   221  	// configure will update agent settings based on provided arguments
   222  	configure(h hypervisor, id, sharePath string, builtin bool, config interface{}) error
   223  
   224  	// configureFromGrpc will update agent settings based on provided arguments which from Grpc
   225  	configureFromGrpc(h hypervisor, id string, builtin bool, config interface{}) error
   226  
   227  	// reseedRNG will reseed the guest random number generator
   228  	reseedRNG(data []byte) error
   229  
   230  	// updateInterface will tell the agent to update a nic for an existed Sandbox.
   231  	updateInterface(inf *vcTypes.Interface) (*vcTypes.Interface, error)
   232  
   233  	// listInterfaces will tell the agent to list interfaces of an existed Sandbox
   234  	listInterfaces() ([]*vcTypes.Interface, error)
   235  
   236  	// updateRoutes will tell the agent to update route table for an existed Sandbox.
   237  	updateRoutes(routes []*vcTypes.Route) ([]*vcTypes.Route, error)
   238  
   239  	// listRoutes will tell the agent to list routes of an existed Sandbox
   240  	listRoutes() ([]*vcTypes.Route, error)
   241  
   242  	// getGuestDetails will tell the agent to get some information of guest
   243  	getGuestDetails(*grpc.GuestDetailsRequest) (*grpc.GuestDetailsResponse, error)
   244  
   245  	// setGuestDateTime asks the agent to set guest time to the provided one
   246  	setGuestDateTime(time.Time) error
   247  
   248  	// copyFile copies file from host to container's rootfs
   249  	copyFile(src, dst string) error
   250  
   251  	// markDead tell agent that the guest is dead
   252  	markDead()
   253  
   254  	// cleanup removes all on disk information generated by the agent
   255  	cleanup(s *Sandbox)
   256  
   257  	// return data for saving
   258  	save() persistapi.AgentState
   259  
   260  	// load data from disk
   261  	load(persistapi.AgentState)
   262  
   263  	// getOOMEvent will wait on OOM events that occur in the sandbox.
   264  	// Will return the ID of the container where the event occurred.
   265  	getOOMEvent() (string, error)
   266  }