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 }