Documentation
¶
Overview ¶
Package passthrough hands control from obol to an external tool (kubectl, helm, helmfile, k9s, or `kubectl exec` into an agent pod) with the tool's native behaviour intact: argv, environment, TTY, signals and exit codes.
Two execution modes:
- Exec: on unix the obol process is replaced (syscall.Exec), so the tool owns the terminal, receives signals directly and its exit status (or signal death) is what the shell sees. On Windows it runs as a child (see Run) and obol exits with the child's code.
- Run: the tool runs as a child process with stdio wired through. Used when obol must do something after the tool exits (stop a port-forward, print a hint). SIGTERM/SIGHUP sent to obol are forwarded to the child; SIGINT/SIGQUIT are not, because terminal-generated signals already reach the whole foreground process group (forwarding would double-deliver Ctrl-C). A child killed by signal n maps to exit status 128+n.
Env policy (KubeEnv): `obol <tool>` always targets the stack kubeconfig, overriding an ambient KUBECONFIG; only an explicit --kubeconfig on the command line opts out. Plain tools can be pointed at the stack with `obol env`.
Index ¶
- Constants
- func DefaultEnv(env, args []string, key, value string, flags ...string) ([]string, bool)
- func Exec(path string, args, env []string) error
- func ExitStatus(ps *os.ProcessState) int
- func Handoff(path string, args, env []string, hint string) error
- func HasFlag(args []string, flags ...string) bool
- func KubeEnv(env, args []string, stackKubeconfig string) ([]string, bool)
- func LookupEnv(env []string, key string) (string, bool)
- func ResolveTool(binDir, name string, warn io.Writer) (string, error)
- func Run(path string, args, env []string) (int, error)
- func SetEnv(env []string, key, value string) []string
- func StackHint(usesStack bool, stackKubeconfig string) string
- func StripSeparator(args []string) []string
- type ExitError
Constants ¶
const StackDownHint = "hint: no stack kubeconfig found — is the stack up? run 'obol stack up'"
StackDownHint is printed to stderr when a tool that was pointed at the stack kubeconfig fails while that kubeconfig does not exist.
Variables ¶
This section is empty.
Functions ¶
func DefaultEnv ¶
DefaultEnv returns a copy of env with key=value appended unless the user already chose a value: key is set (non-empty) in env, or one of flags is present in args. The bool reports whether the default was applied. Any existing (empty) key entries are replaced (see SetEnv).
func Exec ¶
Exec replaces the obol process with path (argv[0] = path). The tool keeps obol's PID, terminal and stdio, so signals and exit status are native. It returns only when the exec itself fails.
func ExitStatus ¶
func ExitStatus(ps *os.ProcessState) int
ExitStatus maps a finished process to a shell-style exit status: the exit code, or 128+n when the process was killed by signal n.
func Handoff ¶
Handoff transfers control to the tool. With an empty hint it calls Exec (unix: the obol process is replaced; Handoff only returns if exec itself failed). With a hint, the tool runs as a child; on a non-zero exit the hint is printed to stderr and an *ExitError with the tool's code is returned.
func HasFlag ¶
HasFlag reports whether any of flags appears in args, either bare ("--kubeconfig") or with an inline value ("--kubeconfig=x"). Scanning stops at "--": what follows belongs to a nested command (e.g. `kubectl exec`).
func KubeEnv ¶
KubeEnv applies the kubeconfig policy for `obol <tool>`: the obol prefix means "target the stack", so KUBECONFIG=stackKubeconfig always replaces an ambient KUBECONFIG. Only an explicit --kubeconfig on the command line opts out (env left untouched; the flag wins in the tool). --context alone does not change this. The bool reports whether the stack kubeconfig is used.
The stack path is set even when the file does not exist yet: falling back to ~/.kube/config or an ambient KUBECONFIG would silently point `obol kubectl delete …` at some other cluster.
func LookupEnv ¶
LookupEnv returns the value of key in env (KEY=value entries; last one wins, matching exec semantics). Names are case-insensitive on Windows.
func ResolveTool ¶
ResolveTool resolves a host tool for passthrough use. It follows the same order as config.ToolPath (OBOL_<TOOL> → obol bin dir → compatible $PATH), with one relaxation: when no managed or compatible copy exists but $PATH has a version-incompatible one, a warning goes to warn and that binary is used — the user asked to run the tool, so a skewed version beats "not found". Stack lifecycle commands keep the strict resolver.
func Run ¶
Run executes path as a child process with obol's stdin/stdout/stderr, forwarding termination signals, and returns the child's exit status (128+n when killed by signal n). err is non-nil only if the child could not be started.
func SetEnv ¶
SetEnv returns a copy of env with every existing key entry removed and key=value appended (syscall.Exec passes env verbatim and getenv returns the first match, so duplicates must not survive).
func StackHint ¶
StackHint returns StackDownHint when the tool will use the stack kubeconfig and that file is missing, otherwise "".
func StripSeparator ¶
StripSeparator removes exactly one leading "--", so `obol kubectl -- get po` behaves like `obol kubectl get po`. Later "--" are the tool's business.
Types ¶
type ExitError ¶
type ExitError struct{ Code int }
ExitError carries a tool's exit status back to the CLI layer so obol can exit with the same code after its own deferred cleanup has run. It implements urfave/cli's ExitCoder; Error is empty so nothing extra is printed (the tool already reported its own failure).