Help us shape the future of Go! Take the 2026 Go Developer Survey

qga

package
v0.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 25, 2026 License: Apache-2.0 Imports: 29 Imported by: 0

Documentation

Overview

Package qga implements the server side of the approved QGA pod-exec pilot transport (`qga-pod-exec/v1`): a Kubernetes-authenticated pod exec into the current KubeVirt virt-launcher, driving the fixed installed runner through the QEMU guest agent. It is an explicit opt-in backend for bounded VM command-only pilot and is never a fallback from a failed mTLS management connection; the dedicated mTLS management transport remains the follow-up.

Trust shape: the API signs one short-lived, single-use Ed25519 grant bound to the fresh request bytes, actor/workspace/provisioning-generation identity and a digest of the server-resolved launcher target. Sensitive grant and request bytes travel only over pod-exec stdin through a fixed wrapper, never as pod-exec URL arguments. The guest independently verifies the grant, its own enrolled workspace UID and the request bounds before creating any process, and reports one bounded JSON result the API treats as authoritative; loss of that result is an unknown outcome, never success.

Index

Constants

View Source
const (

	// Pilot contract bounds, kept in step with kw-management's Rust constants.
	MaxDeadlineSeconds = 20
	MaxOutputBytes     = 16 * 1024
	MaxArgs            = 64
	MaxArgBytes        = 8 * 1024
	MaxExecutableBytes = 1024
	MaxCwdBytes        = 1024
	MaxEnvelopeBytes   = 96 * 1024
)

Fixed installed-guest paths. The runner is the installed kw-agent binary; staged files live in the agent data dir, which exists on every enrolled guest (the runner independently denies a missing enrolled identity).

View Source
const (
	EnvEnabled = "KW_EXECUTION_QGA_ENABLED"
	EnvKeyFile = "KW_MANAGEMENT_GRANT_KEY_FILE"
)

Environment configuration for the opt-in pilot transport.

Variables

View Source
var (
	ErrDenied      = errors.New("QGA target denied")
	ErrUnavailable = errors.New("QGA target unavailable")
)

Fail-closed resolver outcomes. ErrDenied means the named workspace is not an eligible running, controller-bound agent VM right now; ErrUnavailable means a required read could not be completed.

View Source
var ErrConfiguration = errors.New("QGA pilot transport configuration is invalid")

ErrConfiguration reports unusable opt-in pilot configuration. It is never logged with private material.

View Source
var ErrNotStarted = errors.New("runner could not be started")

ErrNotStarted reports a guest refusal before any runner process exists: the installed runner is missing or could not be spawned. Nothing ran, so the caller records a failed outcome rather than an uncertain transport loss.

View Source
var ErrRequestTooLarge = errors.New("QGA pilot request is too large")

ErrRequestTooLarge reports a framed request plus grant beyond the staged envelope bound; nothing was staged, so the caller records a failed pre-dispatch outcome, never an uncertain transport loss or a success.

View Source
var ErrTransport = errors.New("QGA transport failed")

ErrTransport reports a pod-exec/QGA protocol failure with no trustworthy runner result. The caller must record an unknown outcome, never success.

Functions

func LoadSigner

func LoadSigner(path string) (*grants.Signer, error)

LoadSigner reads exactly one unencrypted PKCS#8 Ed25519 private key, either PEM ("BEGIN PRIVATE KEY") or raw 64-byte DER, from a bounded regular file. No inline/environment key or automatic generation is available.

func RunBudget

func RunBudget(deadlineSeconds int) time.Duration

RunBudget is the wall-clock bound for one bounded guest command: staging, the guest deadline, the poll grace and margin for the reply. The API derives its execution context from this budget so a disconnected caller cannot abandon a command mid-flight.

func ScriptPath added in v0.11.0

func ScriptPath(target Target, executionID, name string) string

ScriptPath builds the script staging path for a target.

Types

type Bridge

type Bridge struct {
	// contains filtered or unexported fields
}

Bridge drives one launcher's QEMU guest agent through pod exec.

func NewBridge

func NewBridge(exec ExecFunc) (*Bridge, error)

NewBridge validates the injected exec transport.

func (*Bridge) Run

func (b *Bridge) Run(ctx context.Context, target Target, executionID string, envelope, keysJSON []byte, deadlineSeconds int) (*GuestResult, error)

Run stages the pinned keys and the signed envelope, invokes the fixed installed runner through the QEMU guest agent, polls for its bounded JSON result and best-effort clears the staged envelope. A guest refusal to spawn the runner returns ErrNotStarted: a deterministic "nothing ran" failure. Any other protocol failure without a parsed result returns ErrTransport: an unknown outcome.

func (*Bridge) RunWithExtras added in v0.11.0

func (b *Bridge) RunWithExtras(ctx context.Context, target Target, executionID string, envelope, keysJSON []byte, deadlineSeconds int, extras map[string][]byte) (*GuestResult, error)

RunWithExtras stages extras for tests/callers.

type Command

type Command struct {
	ActorUID        string
	ExecutionID     string
	RecordingID     string
	Executable      string
	Args            []string
	Cwd             *string
	DeadlineSeconds int
	Script          *Script
}

Command is one bounded elevated command or script. ExecutionID/RecordingID/ActorUID are server-minted or authenticated values, never raw client input.

type Config

type Config struct {
	Enabled bool
	KeyFile string
}

Config is the validated opt-in pilot configuration.

func ConfigFromEnv

func ConfigFromEnv() (Config, error)

ConfigFromEnv reads the explicit opt-in flag and signing-key location. The transport is disabled unless explicitly enabled, and enabling without a key file is a startup error rather than a silent downgrade.

type ExecFunc

type ExecFunc func(ctx context.Context, namespace, pod, container string, command []string, stdin []byte) (stdout, stderr []byte, err error)

ExecFunc runs one Kubernetes pod exec carrying the QGA JSON on stdin and returns bounded stdout/stderr. The injectable seam keeps the bridge unit-testable without a cluster.

func KubernetesExecFunc

func KubernetesExecFunc(config *rest.Config, client kubernetes.Interface) (ExecFunc, error)

KubernetesExecFunc builds the production SPDY pod-exec transport. Grant and request bytes travel only on exec stdin through a fixed wrapper, so Kubernetes audit logs never carry them as command arguments.

type GuestResult

type GuestResult struct {
	Outcome    string
	ExitCode   *int
	Stdout     []byte
	Stderr     []byte
	Truncated  bool
	DurationMS uint64
	Denial     string
}

GuestResult is one parsed runner JSON result. It is the authoritative guest outcome; the API must never invent success when it is absent.

type PolicyReader

type PolicyReader interface {
	GetVMExecutionPolicy(context.Context) (platform.VMExecutionPolicy, error)
}

PolicyReader supplies the fresh controller-owned VM execution policy.

type Resolver

type Resolver struct {
	// contains filtered or unexported fields
}

Resolver performs uncached, bounded reads through the Kubernetes API and fail-closes on every ownership, lifecycle, profile, launcher and policy check, including a final snapshot re-verification before returning.

func NewResolver

func NewResolver(client dynamic.Interface, policy PolicyReader) (*Resolver, error)

NewResolver builds a resolver over the shared dynamic client.

func (*Resolver) Resolve

func (r *Resolver) Resolve(ctx context.Context, namespace, name string) (Target, error)

Resolve returns the current launcher target only after a complete fresh snapshot re-verifies identically and policy still admits elevation.

type Runtime

type Runtime struct {
	// contains filtered or unexported fields
}

Runtime is the opt-in QGA pilot executor behind the API's start endpoint.

func NewRuntime

func NewRuntime(cfg Config, dyn dynamic.Interface, policy PolicyReader, restConfig *rest.Config, client kubernetes.Interface) (*Runtime, error)

NewRuntime wires the production pilot stack: the configured signing key, an uncached dynamic-client resolver and the SPDY pod-exec bridge. Every dependency must be present; enabling the pilot never degrades silently.

func NewRuntimeWithExec

func NewRuntimeWithExec(signer *grants.Signer, resolver TargetResolver, exec ExecFunc) (*Runtime, error)

NewRuntimeWithExec wires a runtime over an injected exec transport for tests; the guest-side contract is exercised end to end through fakes.

func (*Runtime) Execute

func (r *Runtime) Execute(ctx context.Context, target Target, command Command) (*GuestResult, error)

Execute issues one single-use QGA grant bound to the resolved target and the exact request bytes, stages both through the bridge and returns the runner's authoritative result. Resolver errors pass through (ErrDenied and ErrUnavailable are pre-dispatch states, not losses); framing failures are ErrTransport (unknown outcome); oversized framing is ErrRequestTooLarge, which is deterministic and staged nothing. A GuestResult is returned only from a parsed runner reply, never invented.

func (*Runtime) Resolve

func (r *Runtime) Resolve(ctx context.Context, namespace, name string) (Target, error)

Resolve delegates to the fail-closed launcher resolver.

type Script added in v0.11.0

type Script struct {
	Body string
	Name string
}

Script describes an inline script to be written to a temp file and executed via shebang.

type Target

type Target struct {
	Namespace     string
	WorkspaceName string
	WorkspaceUID  string
	// VMUID is the controller-owned VirtualMachine UID: the management
	// provisioning generation (reset/recreation changes it; VMI reboot does not).
	VMUID           string
	PodName         string
	PodUID          string
	Domain          string
	RevocationEpoch uint64
	// Linux is set only for controller-bound Linux agent workspaces. The zero
	// value retains the original Windows target contract.
	Linux bool
}

Target is the server-resolved, re-verified launcher identity for one execution. Callers must never build it from client-supplied values.

func (Target) OSIdentity added in v0.11.0

func (t Target) OSIdentity() string

type TargetResolver

type TargetResolver interface {
	Resolve(ctx context.Context, namespace, name string) (Target, error)
}

TargetResolver resolves the fresh launcher target for one workspace.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL