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  }