mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-17 05:31:16 +08:00
* fix(exec): preserve output after stdin EOF and verify stream completion Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com> * test(exec): cover fair duplex progress and live SDK completion Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com> * test(sdk): compare large exec buffers with native equality Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com> * test(exec): use workspace-scoped sandbox name in EOF regression Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com> --------- Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>
71 lines
2.7 KiB
Go
71 lines
2.7 KiB
Go
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package v1
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/NVIDIA/OpenShell/sdk/go/openshell/v1/types"
|
|
)
|
|
|
|
// ExecResult holds the collected output of a completed command execution.
|
|
type ExecResult = types.ExecResult
|
|
|
|
// ExecChunk represents a single chunk of output from a streaming command execution.
|
|
type ExecChunk = types.ExecChunk
|
|
|
|
// ExecStream provides an iterator interface over streaming command output.
|
|
type ExecStream interface {
|
|
Next() (*ExecChunk, error)
|
|
ExitCode() (int, error)
|
|
Close() error
|
|
}
|
|
|
|
// InteractiveSession provides bidirectional I/O for interactive command execution.
|
|
type InteractiveSession interface {
|
|
Read(p []byte) (int, error)
|
|
Write(p []byte) (int, error)
|
|
Resize(cols, rows uint32) error
|
|
// ExitCode waits for final stream completion. An observed exit code is
|
|
// returned alongside any later transport error. Drain Read concurrently.
|
|
ExitCode() (int, error)
|
|
Close() error
|
|
}
|
|
|
|
// InteractiveSessionControl adds optional input closure and cancellation to
|
|
// InteractiveSession without requiring existing implementations to add methods.
|
|
// Sessions returned by this SDK implement both interfaces.
|
|
type InteractiveSessionControl interface {
|
|
InteractiveSession
|
|
// CloseWrite ends stdin and resize input without cancelling output.
|
|
CloseWrite() error
|
|
// Cancel aborts the RPC. Close retains the same full-close behavior.
|
|
Cancel() error
|
|
}
|
|
|
|
// CloseInteractiveInput ends input while preserving output when supported.
|
|
// Unsupported sessions return ErrorUnimplemented and are left open.
|
|
func CloseInteractiveInput(session InteractiveSession) error {
|
|
if closer, ok := session.(interface{ CloseWrite() error }); ok {
|
|
return closer.CloseWrite()
|
|
}
|
|
return &StatusError{Code: ErrorUnimplemented, Message: "interactive session does not support closing input independently"}
|
|
}
|
|
|
|
// CancelInteractive aborts a session, falling back to the original Close contract.
|
|
func CancelInteractive(session InteractiveSession) error {
|
|
if canceler, ok := session.(interface{ Cancel() error }); ok {
|
|
return canceler.Cancel()
|
|
}
|
|
return session.Close()
|
|
}
|
|
|
|
// ExecInterface defines command execution operations on sandboxes.
|
|
// Methods accept a sandbox name and resolve it to an ID internally.
|
|
type ExecInterface interface {
|
|
Run(ctx context.Context, workspace, sandboxName string, command []string, opts ...ExecOptions) (*ExecResult, error)
|
|
Stream(ctx context.Context, workspace, sandboxName string, command []string, opts ...ExecOptions) (ExecStream, error)
|
|
Interactive(ctx context.Context, workspace, sandboxName string, command []string, cols, rows uint32, opts ...ExecOptions) (InteractiveSession, error)
|
|
}
|