ExecSync executes a command in the container, and returns the stdout output. If command exits with a non-zero exit code, an error is returned.
(ctx context.Context, r *runtime.ExecSyncRequest)
| 70 | // ExecSync executes a command in the container, and returns the stdout output. |
| 71 | // If command exits with a non-zero exit code, an error is returned. |
| 72 | func (c *criService) ExecSync(ctx context.Context, r *runtime.ExecSyncRequest) (*runtime.ExecSyncResponse, error) { |
| 73 | const maxStreamSize = 1024 * 1024 * 16 |
| 74 | |
| 75 | var stdout, stderr bytes.Buffer |
| 76 | |
| 77 | // cappedWriter truncates the output. In that case, the size of |
| 78 | // the ExecSyncResponse will hit the CRI plugin's gRPC response limit. |
| 79 | // Thus the callers outside of the containerd process (e.g. Kubelet) never see |
| 80 | // the truncated output. |
| 81 | cout := &cappedWriter{w: cioutil.NewNopWriteCloser(&stdout), remain: maxStreamSize} |
| 82 | cerr := &cappedWriter{w: cioutil.NewNopWriteCloser(&stderr), remain: maxStreamSize} |
| 83 | |
| 84 | exitCode, err := c.execInContainer(ctx, r.GetContainerId(), execOptions{ |
| 85 | cmd: r.GetCmd(), |
| 86 | stdout: cout, |
| 87 | stderr: cerr, |
| 88 | timeout: time.Duration(r.GetTimeout()) * time.Second, |
| 89 | }) |
| 90 | if err != nil { |
| 91 | return nil, fmt.Errorf("failed to exec in container: %w", err) |
| 92 | } |
| 93 | |
| 94 | return &runtime.ExecSyncResponse{ |
| 95 | Stdout: stdout.Bytes(), |
| 96 | Stderr: stderr.Bytes(), |
| 97 | ExitCode: int32(*exitCode), |
| 98 | }, nil |
| 99 | } |
| 100 | |
| 101 | // execOptions specifies how to execute command in container. |
| 102 | type execOptions struct { |
nothing calls this directly
no test coverage detected