github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/utils/cri/cri_runtime_wrapper.go (about) 1 package cri 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 criruntimev1alpha2 "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" 9 ) 10 11 // NewCRIExtendedRuntimeServiceWrapper creates an ExtendedRuntimeService from a v1alpha2 runtime service client 12 // NOTE: the passed context is used for every subsequent call on the interface as the parent context with a timeout 13 // as passed through the argument. If the parent context gets canceled, this client becomes useless. 14 func NewCRIExtendedRuntimeServiceWrapper(ctx context.Context, timeout time.Duration, client criruntimev1alpha2.RuntimeServiceClient) (ExtendedRuntimeService, error) { 15 if client == nil { 16 return nil, fmt.Errorf("client cannot be nil") 17 } 18 if timeout == time.Duration(0) { 19 return nil, fmt.Errorf("timeout cannot be 0") 20 } 21 return &extendedServiceRuntimeWrapper{ 22 ctx: ctx, 23 timeout: timeout, 24 rs: client, 25 }, nil 26 } 27 28 type extendedServiceRuntimeWrapper struct { 29 // well, this is stupid: 30 // the criapi.RuntimeService should take a context as first argument everywhere 31 // as it doesn't, the only sensible way is to be able to pass it from here 32 // however, be careful with this: if that passed context gets canceled, nothing will work anymore 33 ctx context.Context 34 timeout time.Duration 35 rs criruntimev1alpha2.RuntimeServiceClient 36 } 37 38 // Version returns the runtime name, runtime version and runtime API version 39 func (w *extendedServiceRuntimeWrapper) Version(apiVersion string) (*criruntimev1alpha2.VersionResponse, error) { 40 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 41 defer cancel() 42 return w.rs.Version(ctx, &criruntimev1alpha2.VersionRequest{Version: apiVersion}) 43 } 44 45 // CreateContainer creates a new container in specified PodSandbox. 46 func (w *extendedServiceRuntimeWrapper) CreateContainer(podSandboxID string, config *criruntimev1alpha2.ContainerConfig, sandboxConfig *criruntimev1alpha2.PodSandboxConfig) (string, error) { 47 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 48 defer cancel() 49 resp, err := w.rs.CreateContainer(ctx, &criruntimev1alpha2.CreateContainerRequest{ 50 PodSandboxId: podSandboxID, 51 Config: config, 52 SandboxConfig: sandboxConfig, 53 }) 54 if err != nil { 55 return "", err 56 } 57 return resp.GetContainerId(), nil 58 } 59 60 // StartContainer starts the container. 61 func (w *extendedServiceRuntimeWrapper) StartContainer(containerID string) error { 62 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 63 defer cancel() 64 _, err := w.rs.StartContainer(ctx, &criruntimev1alpha2.StartContainerRequest{ 65 ContainerId: containerID, 66 }) 67 return err 68 } 69 70 // StopContainer stops a running container with a grace period (i.e., timeout). 71 func (w *extendedServiceRuntimeWrapper) StopContainer(containerID string, timeout int64) error { 72 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 73 defer cancel() 74 _, err := w.rs.StopContainer(ctx, &criruntimev1alpha2.StopContainerRequest{ 75 ContainerId: containerID, 76 Timeout: timeout, 77 }) 78 return err 79 } 80 81 // RemoveContainer removes the container. 82 func (w *extendedServiceRuntimeWrapper) RemoveContainer(containerID string) error { 83 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 84 defer cancel() 85 _, err := w.rs.RemoveContainer(ctx, &criruntimev1alpha2.RemoveContainerRequest{ 86 ContainerId: containerID, 87 }) 88 return err 89 } 90 91 // ListContainers lists all containers by filters. 92 func (w *extendedServiceRuntimeWrapper) ListContainers(filter *criruntimev1alpha2.ContainerFilter) ([]*criruntimev1alpha2.Container, error) { 93 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 94 defer cancel() 95 resp, err := w.rs.ListContainers(ctx, &criruntimev1alpha2.ListContainersRequest{ 96 Filter: filter, 97 }) 98 if err != nil { 99 return nil, err 100 } 101 return resp.GetContainers(), nil 102 } 103 104 // ContainerStatus returns the status of the container. 105 func (w *extendedServiceRuntimeWrapper) ContainerStatus(containerID string) (*criruntimev1alpha2.ContainerStatus, error) { 106 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 107 defer cancel() 108 resp, err := w.rs.ContainerStatus(ctx, &criruntimev1alpha2.ContainerStatusRequest{ 109 ContainerId: containerID, 110 Verbose: false, 111 }) 112 if err != nil { 113 return nil, err 114 } 115 return resp.GetStatus(), nil 116 } 117 118 // ContainerStatusVerbose returns the status of the container. 119 func (w *extendedServiceRuntimeWrapper) ContainerStatusVerbose(containerID string) (*criruntimev1alpha2.ContainerStatus, map[string]string, error) { 120 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 121 defer cancel() 122 resp, err := w.rs.ContainerStatus(ctx, &criruntimev1alpha2.ContainerStatusRequest{ 123 ContainerId: containerID, 124 Verbose: true, 125 }) 126 if err != nil { 127 return nil, nil, err 128 } 129 return resp.GetStatus(), resp.GetInfo(), nil 130 } 131 132 // UpdateContainerResources updates the cgroup resources for the container. 133 func (w *extendedServiceRuntimeWrapper) UpdateContainerResources(containerID string, resources *criruntimev1alpha2.LinuxContainerResources) error { 134 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 135 defer cancel() 136 _, err := w.rs.UpdateContainerResources(ctx, &criruntimev1alpha2.UpdateContainerResourcesRequest{ 137 ContainerId: containerID, 138 Linux: resources, 139 }) 140 return err 141 } 142 143 // ExecSync executes a command in the container, and returns the stdout output. 144 // If command exits with a non-zero exit code, an error is returned. 145 func (w *extendedServiceRuntimeWrapper) ExecSync(containerID string, cmd []string, timeout time.Duration) (stdout []byte, stderr []byte, err error) { 146 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 147 defer cancel() 148 resp, err := w.rs.ExecSync(ctx, &criruntimev1alpha2.ExecSyncRequest{ 149 ContainerId: containerID, 150 Cmd: cmd, 151 Timeout: int64(timeout.Seconds()), 152 }) 153 if err != nil { 154 return nil, nil, err 155 } 156 if resp.GetExitCode() != int32(0) { 157 return resp.GetStdout(), resp.GetStderr(), fmt.Errorf("exit code: %d", resp.GetExitCode()) 158 } 159 return resp.GetStdout(), resp.GetStderr(), nil 160 } 161 162 // Exec prepares a streaming endpoint to execute a command in the container, and returns the address. 163 func (w *extendedServiceRuntimeWrapper) Exec(req *criruntimev1alpha2.ExecRequest) (*criruntimev1alpha2.ExecResponse, error) { 164 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 165 defer cancel() 166 return w.rs.Exec(ctx, req) 167 } 168 169 // Attach prepares a streaming endpoint to attach to a running container, and returns the address. 170 func (w *extendedServiceRuntimeWrapper) Attach(req *criruntimev1alpha2.AttachRequest) (*criruntimev1alpha2.AttachResponse, error) { 171 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 172 defer cancel() 173 return w.rs.Attach(ctx, req) 174 } 175 176 // ReopenContainerLog asks runtime to reopen the stdout/stderr log file 177 // for the container. If it returns error, new container log file MUST NOT 178 // be created. 179 func (w *extendedServiceRuntimeWrapper) ReopenContainerLog(containerID string) error { 180 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 181 defer cancel() 182 _, err := w.rs.ReopenContainerLog(ctx, &criruntimev1alpha2.ReopenContainerLogRequest{ 183 ContainerId: containerID, 184 }) 185 return err 186 } 187 188 // RunPodSandbox creates and starts a pod-level sandbox. Runtimes should ensure 189 // the sandbox is in ready state. 190 func (w *extendedServiceRuntimeWrapper) RunPodSandbox(config *criruntimev1alpha2.PodSandboxConfig, runtimeHandler string) (string, error) { 191 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 192 defer cancel() 193 resp, err := w.rs.RunPodSandbox(ctx, &criruntimev1alpha2.RunPodSandboxRequest{ 194 Config: config, 195 RuntimeHandler: runtimeHandler, 196 }) 197 if err != nil { 198 return "", err 199 } 200 return resp.GetPodSandboxId(), nil 201 } 202 203 // StopPodSandbox stops the sandbox. If there are any running containers in the 204 // sandbox, they should be force terminated. 205 func (w *extendedServiceRuntimeWrapper) StopPodSandbox(podSandboxID string) error { 206 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 207 defer cancel() 208 _, err := w.rs.StopPodSandbox(ctx, &criruntimev1alpha2.StopPodSandboxRequest{ 209 PodSandboxId: podSandboxID, 210 }) 211 return err 212 } 213 214 // RemovePodSandbox removes the sandbox. If there are running containers in the 215 // sandbox, they should be forcibly removed. 216 func (w *extendedServiceRuntimeWrapper) RemovePodSandbox(podSandboxID string) error { 217 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 218 defer cancel() 219 _, err := w.rs.RemovePodSandbox(ctx, &criruntimev1alpha2.RemovePodSandboxRequest{ 220 PodSandboxId: podSandboxID, 221 }) 222 return err 223 } 224 225 // PodSandboxStatus returns the Status of the PodSandbox. 226 func (w *extendedServiceRuntimeWrapper) PodSandboxStatus(podSandboxID string) (*criruntimev1alpha2.PodSandboxStatus, error) { 227 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 228 defer cancel() 229 resp, err := w.rs.PodSandboxStatus(ctx, &criruntimev1alpha2.PodSandboxStatusRequest{ 230 PodSandboxId: podSandboxID, 231 Verbose: false, 232 }) 233 if err != nil { 234 return nil, err 235 } 236 return resp.GetStatus(), nil 237 } 238 239 // PodSandboxStatusVerbose returns the Status of the PodSandbox. 240 func (w *extendedServiceRuntimeWrapper) PodSandboxStatusVerbose(podSandboxID string) (*criruntimev1alpha2.PodSandboxStatus, map[string]string, error) { 241 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 242 defer cancel() 243 resp, err := w.rs.PodSandboxStatus(ctx, &criruntimev1alpha2.PodSandboxStatusRequest{ 244 PodSandboxId: podSandboxID, 245 Verbose: true, 246 }) 247 if err != nil { 248 return nil, nil, err 249 } 250 return resp.GetStatus(), resp.GetInfo(), nil 251 } 252 253 // ListPodSandbox returns a list of Sandbox. 254 func (w *extendedServiceRuntimeWrapper) ListPodSandbox(filter *criruntimev1alpha2.PodSandboxFilter) ([]*criruntimev1alpha2.PodSandbox, error) { 255 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 256 defer cancel() 257 resp, err := w.rs.ListPodSandbox(ctx, &criruntimev1alpha2.ListPodSandboxRequest{ 258 Filter: filter, 259 }) 260 if err != nil { 261 return nil, err 262 } 263 return resp.GetItems(), nil 264 } 265 266 // PortForward prepares a streaming endpoint to forward ports from a PodSandbox, and returns the address. 267 func (w *extendedServiceRuntimeWrapper) PortForward(req *criruntimev1alpha2.PortForwardRequest) (*criruntimev1alpha2.PortForwardResponse, error) { 268 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 269 defer cancel() 270 return w.rs.PortForward(ctx, req) 271 } 272 273 // ContainerStats returns stats of the container. If the container does not 274 // exist, the call returns an error. 275 func (w *extendedServiceRuntimeWrapper) ContainerStats(containerID string) (*criruntimev1alpha2.ContainerStats, error) { 276 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 277 defer cancel() 278 resp, err := w.rs.ContainerStats(ctx, &criruntimev1alpha2.ContainerStatsRequest{ 279 ContainerId: containerID, 280 }) 281 if err != nil { 282 return nil, err 283 } 284 return resp.GetStats(), nil 285 } 286 287 // ListContainerStats returns stats of all running containers. 288 func (w *extendedServiceRuntimeWrapper) ListContainerStats(filter *criruntimev1alpha2.ContainerStatsFilter) ([]*criruntimev1alpha2.ContainerStats, error) { 289 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 290 defer cancel() 291 resp, err := w.rs.ListContainerStats(ctx, &criruntimev1alpha2.ListContainerStatsRequest{ 292 Filter: filter, 293 }) 294 if err != nil { 295 return nil, err 296 } 297 return resp.GetStats(), nil 298 } 299 300 // UpdateRuntimeConfig updates runtime configuration if specified 301 func (w *extendedServiceRuntimeWrapper) UpdateRuntimeConfig(runtimeConfig *criruntimev1alpha2.RuntimeConfig) error { 302 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 303 defer cancel() 304 _, err := w.rs.UpdateRuntimeConfig(ctx, &criruntimev1alpha2.UpdateRuntimeConfigRequest{ 305 RuntimeConfig: runtimeConfig, 306 }) 307 return err 308 } 309 310 // Status returns the status of the runtime. 311 func (w *extendedServiceRuntimeWrapper) Status() (*criruntimev1alpha2.RuntimeStatus, error) { 312 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 313 defer cancel() 314 resp, err := w.rs.Status(ctx, &criruntimev1alpha2.StatusRequest{ 315 Verbose: false, 316 }) 317 if err != nil { 318 return nil, err 319 } 320 return resp.GetStatus(), nil 321 } 322 323 // Status returns the status of the runtime. 324 func (w *extendedServiceRuntimeWrapper) StatusVerbose() (*criruntimev1alpha2.RuntimeStatus, map[string]string, error) { 325 ctx, cancel := context.WithTimeout(w.ctx, w.timeout) 326 defer cancel() 327 resp, err := w.rs.Status(ctx, &criruntimev1alpha2.StatusRequest{ 328 Verbose: true, 329 }) 330 if err != nil { 331 return nil, nil, err 332 } 333 return resp.GetStatus(), resp.GetInfo(), nil 334 }