execution

package
v0.15.0 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package execution defines the versioned agent execution contract used by sshx run and shared by compatibility adapters for single-host paths.

Index

Constants

View Source
const (
	RequestSchemaVersion = "sshx.request.v1"
	ResultSchemaVersion  = "sshx.result.v1"
	EventSchemaVersion   = "sshx.event.v1"

	DefaultConcurrency = 4
	MaxConcurrency     = 32
	DefaultMaxOutput   = 10 << 20 // 10 MiB
	DefaultMaxPayload  = 10 << 20 // 10 MiB

	ActionCommand  = "command"
	ActionScript   = "script"
	ActionInspect  = "inspect"
	ActionSFTP     = "sftp"
	ActionTransfer = "transfer"
	ActionApply    = "apply"

	IntentRead    = "read"
	IntentChange  = "change"
	IntentUnknown = "unknown"

	FailureContinue = "continue"
	FailureFailFast = "fail_fast"

	StatusSucceeded = "succeeded"
	StatusFailed    = "failed"
	StatusSkipped   = "skipped"

	CompletionNotStarted           = "not_started"
	CompletionPartial              = "partial"
	CompletionCompleted            = "completed"
	CompletionCompletedUnconfirmed = "completed_unconfirmed"
	CompletionUnknown              = "unknown"

	PhaseResolve      = "resolve"
	PhaseAdmission    = "admission"
	PhaseConnect      = "connect"
	PhaseAuthenticate = "authenticate"
	PhaseExecute      = "execute"
	PhaseCollect      = "collect"
	PhasePersist      = "persist"
	PhaseComplete     = "complete"

	EventRunStarted     = "run_started"
	EventTargetStarted  = "target_started"
	EventTargetFinished = "target_finished"
	EventRunFinished    = "run_finished"

	RetrySafe        = "safe"
	RetryUnsafe      = "unsafe"
	RetryVerifyFirst = "verify_first"
	RetryUnknown     = "unknown"

	ErrorKindConnect      = "connect"
	ErrorKindAuth         = "auth"
	ErrorKindHostKey      = "host_key"
	ErrorKindBlocked      = "blocked"
	ErrorKindTimeout      = "timeout"
	ErrorKindCancelled    = "cancelled" //nolint:misspell // Preserve the machine-readable cancellation category.
	ErrorKindRemoteExit   = "remote_exit"
	ErrorKindExitMissing  = "exit_missing"
	ErrorKindProtocol     = "protocol"
	ErrorKindConfig       = "config"
	ErrorKindLocalIO      = "local_io"
	ErrorKindRemoteIO     = "remote_io"
	ErrorKindPrecondition = "precondition"
	ErrorKindUnknown      = "unknown"

	ScriptRunnerSH = "sh"
)
View Source
const MaxJumpHops = 4

MaxJumpHops is the maximum number of intermediate bastion hops, not counting the target. Longer chains are a config error and never touch the network.

View Source
const PlanSchemaVersion = "sshx.plan.v1"

Variables

View Source
var (
	// ErrConfig indicates a request/schema/selector configuration failure.
	ErrConfig = errors.New("execution config error")
	// ErrLocalIO indicates local file, stdin, or result-delivery failure.
	ErrLocalIO = errors.New("local io error")
	// ErrRemoteIO indicates a remote filesystem/protocol I/O failure.
	ErrRemoteIO = errors.New("remote io error")
	// ErrBlocked indicates the safety policy refused the action.
	ErrBlocked = errors.New("action blocked by safety policy")
	// ErrNoTargets indicates selector resolution matched zero hosts.
	ErrNoTargets = fmt.Errorf("%w: no targets matched", ErrConfig)
)

Functions

func Classify

func Classify(err error) string

Classify maps an error to a stable machine-readable kind. Typed/sentinel errors are preferred; free-form matching is only a fallback at external-library boundaries.

func ClassifyLocalRisk added in v0.15.0

func ClassifyLocalRisk(mode, action string) (Risk, Effects, bool)

ClassifyLocalRisk describes supported local management actions, not observed state changes. Remote host diagnostics and unknown actions are excluded.

func ClassifyRisk added in v0.15.0

func ClassifyRisk(action, command string, sudo bool) (Risk, Effects)

ClassifyRisk is deliberately narrower than shell validation: admission to the command guardrail does not establish that a command is read-only.

func CompletionFor

func CompletionFor(phase, kind string, remoteStarted bool, exitObserved bool) string

CompletionFor maps phase + error kind onto observed execution certainty.

func CompletionForAttempt added in v0.15.0

func CompletionForAttempt(phase, kind string, startAttempted, remoteStarted, exitObserved bool) string

CompletionForAttempt also accounts for an exec request whose acknowledgement was never received. This is not evidence that remote execution did not start.

func Digest added in v0.15.0

func Digest(data []byte) string

func IsRequestLevelError

func IsRequestLevelError(err error) bool

IsRequestLevelError reports whether err should become process exit 255.

func NewRunID

func NewRunID() string

NewRunID returns a random opaque run identifier.

func NormalizeRequest

func NormalizeRequest(req *Request) error

NormalizeRequest fills defaults and validates the internal request shape. It does not resolve hosts or read secrets.

func ProcessExitCode

func ProcessExitCode(counts RunCounts, requestErr error) int

ProcessExitCode maps a run outcome to the multi-target process exit code.

0   all selected targets completed successfully
1   run accepted but at least one selected target failed, was skipped, or is uncertain
255 request-level failure before a valid run could execute

func SafetyCheck

func SafetyCheck(req *Request, payload []byte) error

SafetyCheck evaluates command/script safety without connecting.

func SupportedScriptRunner added in v0.12.0

func SupportedScriptRunner(name string) bool

SupportedScriptRunner reports whether name can be used as a script runner.

func ValidatePlanHash added in v0.15.0

func ValidatePlanHash(value string) error

func WithScopedTimeout added in v0.15.0

func WithScopedTimeout(parent context.Context, timeout time.Duration, scope string) (context.Context, context.CancelFunc)

WithScopedTimeout keeps the scope of the earliest effective deadline.

Types

type ActionSpec

type ActionSpec struct {
	Kind            string `json:"kind"`
	Intent          string `json:"intent"`
	Command         string `json:"command,omitempty"`
	ScriptPath      string `json:"script_path,omitempty"`
	ScriptFromStdin bool   `json:"script_from_stdin,omitempty"`
	ScriptRunner    string `json:"script_runner,omitempty"`
	UseSudo         bool   `json:"use_sudo,omitempty"`
	PayloadSHA256   string `json:"payload_sha256,omitempty"`
	PayloadBytes    int    `json:"payload_bytes,omitempty"`
	SftpAction      string `json:"sftp_action,omitempty"`
	LocalPath       string `json:"local_path,omitempty"`
	RemotePath      string `json:"remote_path,omitempty"`
}

ActionSpec describes the single action admitted by one request.

type BoundaryError added in v0.15.0

type BoundaryError struct {
	Kind    string
	Message string
}

BoundaryError has a stable machine category independent of diagnostic text.

func (*BoundaryError) Error added in v0.15.0

func (e *BoundaryError) Error() string

func (*BoundaryError) ErrorKind added in v0.15.0

func (e *BoundaryError) ErrorKind() string

type Condition added in v0.15.0

type Condition struct {
	Kind     string `json:"kind"`
	Subject  string `json:"subject,omitempty"`
	Expected string `json:"expected,omitempty"`
	Observed string `json:"observed,omitempty"`
	Status   string `json:"status"`
}

type DefaultDialer

type DefaultDialer struct{}

DefaultDialer uses sshclient.NewSSHClient + Connect.

func (DefaultDialer) Connect

Connect implements Dialer.

type Dialer

type Dialer interface {
	Connect(cfg *sshclient.Config) (*sshclient.SSHClient, error)
}

Dialer creates and connects an SSH client for one target.

type DryRunPlan

type DryRunPlan struct {
	Plan                *Plan          `json:"plan,omitempty"`
	PlanHash            string         `json:"plan_hash,omitempty"`
	Risk                Risk           `json:"risk,omitempty"`
	Effects             Effects        `json:"effects"`
	SchemaVersion       string         `json:"schema_version"`
	DryRun              bool           `json:"dry_run"`
	Valid               bool           `json:"valid"`
	RequestID           string         `json:"request_id,omitempty"`
	Action              ActionSpec     `json:"action"`
	Limits              Limits         `json:"limits"`
	Policy              PolicyPublic   `json:"policy"`
	Snapshot            TargetSnapshot `json:"snapshot"`
	WouldConnect        bool           `json:"would_connect"`
	WouldExecute        bool           `json:"would_execute"`
	WouldReadSecret     bool           `json:"would_read_secret"`
	WouldWriteLocal     bool           `json:"would_write_local_state"`
	WouldMutateRemote   bool           `json:"would_mutate_remote"`
	MayMutateKnownHosts bool           `json:"may_mutate_known_hosts"`
	SecretBackend       string         `json:"secret_backend,omitempty"`
	SecretUnlock        string         `json:"secret_unlock,omitempty"`
	Notes               []string       `json:"notes,omitempty"`
	Error               *ErrorInfo     `json:"error,omitempty"`
}

DryRunPlan is the validated local plan for sshx run --dry-run.

func BuildDryRunPlan

func BuildDryRunPlan(req *Request, hosts []HostRecord, defaults HostRecord, payload *Payload) DryRunPlan

BuildDryRunPlan resolves selectors and reports effects without secrets/network.

type Effects added in v0.15.0

type Effects struct {
	Unknown     bool `json:"unknown"`
	RemoteWrite bool `json:"remote_write"`
	LocalWrite  bool `json:"local_write"`
	Privileged  bool `json:"privileged"`
	Destructive bool `json:"destructive"`
}

Effects retain facts that cannot be represented by a single risk level.

func (Effects) Risk added in v0.15.0

func (e Effects) Risk() Risk

type ErrorInfo

type ErrorInfo struct {
	Kind        string `json:"kind"`
	Message     string `json:"message"`
	Retryable   bool   `json:"retryable"`
	RetrySafety string `json:"retry_safety"`
}

ErrorInfo is the structured failure surface for one target or run.

func BuildError

func BuildError(err error, kind, intent, completion string) *ErrorInfo

BuildError treats unknown intent as potentially mutating. Callers with a reviewed plan should pass its risk instead of trusting a declared read intent.

type Event

type Event struct {
	Metadata
	SchemaVersion  string          `json:"schema_version"`
	RunID          string          `json:"run_id"`
	RequestID      string          `json:"request_id,omitempty"`
	Sequence       int64           `json:"sequence"`
	Kind           string          `json:"kind"`
	Timestamp      string          `json:"timestamp"`
	Target         *ResolvedTarget `json:"target,omitempty"`
	Result         *TargetResult   `json:"result,omitempty"`
	Counts         *RunCounts      `json:"counts,omitempty"`
	SelectorDigest string          `json:"selector_digest,omitempty"`
	Concurrency    int             `json:"concurrency,omitempty"`
	FailureMode    string          `json:"failure_mode,omitempty"`
	MaxFailures    int             `json:"max_failures,omitempty"`
	Action         *ActionSpec     `json:"action,omitempty"`
	Error          *ErrorInfo      `json:"error,omitempty"`
}

Event is one JSONL stream record for multi-target runs.

type EventWriter

type EventWriter interface {
	WriteEvent(Event) error
}

EventWriter receives ordered JSONL events.

type HostRecord

type HostRecord struct {
	Name            string
	Address         string
	Port            string
	User            string
	KeyPath         string
	SSHPasswordKey  string
	SudoPasswordKey string
	Groups          []string
	Tags            map[string]string
	Bind            string
	BindSet         bool
	// Via is the named next hop toward the operator. Empty means direct TCP.
	Via string
}

HostRecord is the inventory shape required by selector resolution. The app package adapts settings HostConfig into this type.

type HumanWriter

type HumanWriter struct {
	W io.Writer
	// contains filtered or unexported fields
}

HumanWriter prints target-prefixed human output without interleaving lines.

func (*HumanWriter) WriteEvent

func (h *HumanWriter) WriteEvent(ev Event) error

WriteEvent implements EventWriter for human mode (subset of events).

type JSONLWriter

type JSONLWriter struct {
	W io.Writer
	// contains filtered or unexported fields
}

JSONLWriter writes one JSON object per line to w.

func (*JSONLWriter) WriteEvent

func (j *JSONLWriter) WriteEvent(ev Event) error

WriteEvent implements EventWriter.

type Limits

type Limits struct {
	Concurrency             int           `json:"concurrency"`
	Timeout                 time.Duration `json:"timeout,omitempty"`
	HostTimeout             time.Duration `json:"host_timeout,omitempty"`
	GlobalTimeout           time.Duration `json:"global_timeout,omitempty"`
	MaxOutputBytesPerTarget int           `json:"max_output_bytes_per_target"`
	MaxPayloadBytes         int           `json:"max_payload_bytes,omitempty"`
}

Limits bounds one process run.

type Metadata added in v0.15.0

type Metadata struct {
	PlanHash             string         `json:"plan_hash,omitempty"`
	Risk                 Risk           `json:"risk,omitempty"`
	Effects              Effects        `json:"effects"`
	ExecutionID          string         `json:"execution_id,omitempty"`
	ParentExecutionID    string         `json:"parent_execution_id,omitempty"`
	ExecutionFingerprint string         `json:"execution_fingerprint,omitempty"`
	TargetFingerprints   []string       `json:"target_fingerprints,omitempty"`
	Peers                []PeerIdentity `json:"peers,omitempty"`
	CancellationCause    string         `json:"cancellation_cause,omitempty"`
	DeadlineScope        string         `json:"deadline_scope,omitempty"`
	StartedAt            string         `json:"started_at,omitempty"`
	FinishedAt           string         `json:"finished_at,omitempty"`
	ChangeState          string         `json:"change_state"`
	Executed             *bool          `json:"executed"`
	Verified             bool           `json:"verified"`
	Verification         string         `json:"verification"`
	Preconditions        []Condition    `json:"preconditions,omitempty"`
	Postconditions       []Condition    `json:"postconditions,omitempty"`
}

func NewMetadata added in v0.15.0

func NewMetadata(plan *Plan, id string) Metadata

func (*Metadata) Finish added in v0.15.0

func (m *Metadata) Finish(status, phase, completion string, exitCode int, errorKind string)

Finish hashes redacted outcome facts, never stdout, stderr or raw errors.

func (*Metadata) ObserveContext added in v0.15.0

func (m *Metadata) ObserveContext(ctx context.Context)

type Payload

type Payload struct {
	Bytes  []byte
	SHA256 string
	Size   int
	// Shebang is the interpreter basename declared by a leading `#!` line,
	// empty when the payload declares none.
	Shebang string
}

Payload holds a byte-preserving script body and its digest metadata.

func LoadScriptFile

func LoadScriptFile(path string, maxBytes int) (Payload, error)

LoadScriptFile reads one local regular file as a script payload.

func LoadScriptStdin

func LoadScriptStdin(r io.Reader, maxBytes int) (Payload, error)

LoadScriptStdin reads process stdin as a script payload.

type PeerIdentity added in v0.15.0

type PeerIdentity struct {
	Role               string `json:"role"`
	Address            string `json:"address,omitempty"`
	HostKeyFingerprint string `json:"host_key_fingerprint,omitempty"`
	AuthMethod         string `json:"auth_method,omitempty"`
	User               string `json:"user,omitempty"`
	SSHPasswordKey     string `json:"ssh_password_key,omitempty"`
	SudoPasswordKey    string `json:"sudo_password_key,omitempty"`
}

type Plan added in v0.15.0

type Plan struct {
	SchemaVersion string            `json:"schema_version"`
	Semantics     string            `json:"semantics"`
	Action        string            `json:"action"`
	Targets       []PlanTarget      `json:"targets"`
	Inputs        map[string]string `json:"inputs"`
	Risk          Risk              `json:"risk"`
	Effects       Effects           `json:"effects"`
	Bindable      bool              `json:"bindable"`
	Unresolved    []string          `json:"unresolved,omitempty"`
	PlanHash      string            `json:"plan_hash"`
}

Plan contains public semantic inputs only. Payloads and credentials are held separately by the caller and must not be reconstructed from this view.

func (Plan) CanonicalBytes added in v0.15.0

func (p Plan) CanonicalBytes() ([]byte, error)

CanonicalBytes excludes display metadata and the digest itself. Go's JSON encoder sorts string map keys; target order is normalized by Seal.

func (Plan) CheckExpected added in v0.15.0

func (p Plan) CheckExpected(expected string) error

func (*Plan) Seal added in v0.15.0

func (p *Plan) Seal() error

type PlanTarget added in v0.15.0

type PlanTarget struct {
	Role           string `json:"role"`
	Alias          string `json:"alias,omitempty"`
	Address        string `json:"address"`
	Port           string `json:"port"`
	User           string `json:"user"`
	Bind           string `json:"bind,omitempty"`
	KeyFingerprint string `json:"key_fingerprint,omitempty"`
	TrustSHA256    string `json:"trust_sha256,omitempty"`
	SSHPasswordKey string `json:"ssh_password_key,omitempty"`
	SudoKey        string `json:"sudo_key,omitempty"`
}

type Policy

type Policy struct {
	FailureMode          string `json:"failure_mode"`
	MaxFailures          int    `json:"max_failures,omitempty"`
	SafetyCheckEnabled   bool   `json:"safety_check_enabled"`
	SafetyBypass         bool   `json:"safety_bypass"`
	BypassReason         string `json:"bypass_reason,omitempty"`
	AcceptUnknownHost    bool   `json:"accept_unknown_host"`
	AllowInsecureHostKey bool   `json:"allow_insecure_host_key"`
	KnownHostsPath       string `json:"known_hosts_path,omitempty"`
	UseKeyAuth           bool   `json:"use_key_auth"`
	KeyPath              string `json:"key_path,omitempty"`
	// SSHPasswordKey is a typed keyring reference for SSH login only.
	SSHPasswordKey string `json:"ssh_password_key,omitempty"`
	// SudoPasswordKey is a typed keyring reference for sudo auto-fill only.
	SudoPasswordKey string `json:"sudo_password_key,omitempty"`
	// SSHPassword is an already-resolved login password (for example SSH_PASSWORD).
	// It is never serialized into dry-run or audit payloads.
	SSHPassword string `json:"-"`
	// Bind is a local source address (literal IP or interface name).
	Bind string `json:"bind,omitempty"`
	// BindSet is true when the request explicitly set bind, including empty.
	BindSet bool `json:"-"`
}

Policy captures high-risk decisions that must be explicit per request.

type PolicyPublic

type PolicyPublic struct {
	FailureMode          string `json:"failure_mode"`
	MaxFailures          int    `json:"max_failures,omitempty"`
	SafetyCheckEnabled   bool   `json:"safety_check_enabled"`
	SafetyBypass         bool   `json:"safety_bypass"`
	BypassReason         string `json:"bypass_reason,omitempty"`
	AcceptUnknownHost    bool   `json:"accept_unknown_host"`
	AllowInsecureHostKey bool   `json:"allow_insecure_host_key"`
	KnownHostsPath       string `json:"known_hosts_path,omitempty"`
	UseKeyAuth           bool   `json:"use_key_auth"`
	KeyPath              string `json:"key_path,omitempty"`
	SSHPasswordKey       string `json:"ssh_password_key,omitempty"`
	SudoPasswordKey      string `json:"sudo_password_key,omitempty"`
	SSHPasswordProvided  bool   `json:"ssh_password_provided"`
	Bind                 string `json:"bind,omitempty"`
	BindSet              bool   `json:"bind_set,omitempty"`
}

PolicyPublic is the audit/dry-run view of Policy without secret values.

func PublicPolicy

func PublicPolicy(p Policy) PolicyPublic

PublicPolicy projects Policy without secret material.

type Request

type Request struct {
	Plan          *Plan          `json:"-"`
	ExecutionID   string         `json:"-"`
	SchemaVersion string         `json:"schema_version"`
	RequestID     string         `json:"request_id,omitempty"`
	Targets       TargetSelector `json:"targets"`
	Action        ActionSpec     `json:"action"`
	Limits        Limits         `json:"limits"`
	Policy        Policy         `json:"policy"`
	JSONOutput    bool           `json:"json_output,omitempty"`
	JSONLOutput   bool           `json:"jsonl_output,omitempty"`
	DryRun        bool           `json:"dry_run,omitempty"`
	AuditEnabled  bool           `json:"audit_enabled,omitempty"`
	AuditOutput   string         `json:"audit_output,omitempty"`
}

Request is the versioned internal execution unit.

type ResolvedTarget

type ResolvedTarget struct {
	Index                  int               `json:"index"`
	Alias                  string            `json:"alias,omitempty"`
	Address                string            `json:"address"`
	Port                   string            `json:"port"`
	User                   string            `json:"user"`
	KeyPath                string            `json:"key_path,omitempty"`
	SSHPasswordKey         string            `json:"ssh_password_key,omitempty"`
	SudoPasswordKey        string            `json:"sudo_password_key,omitempty"`
	Groups                 []string          `json:"groups,omitempty"`
	Tags                   map[string]string `json:"tags,omitempty"`
	HostKeyFingerprint     string            `json:"host_key_fingerprint,omitempty"`
	KnownHostsData         []byte            `json:"-"`
	ExpectedKeyFingerprint string            `json:"-"`
	Literal                bool              `json:"literal,omitempty"`
	Bind                   string            `json:"bind,omitempty"`
	// Via is the named next hop from inventory or --via=. Empty means direct.
	Via string `json:"via,omitempty"`
	// Jumps is the resolved bastion chain, outermost first. Nested Jumps are empty.
	Jumps []ResolvedTarget `json:"jumps,omitempty"`
}

ResolvedTarget is one frozen host from selector resolution.

func ResolveJumps added in v0.15.0

func ResolveJumps(hosts []HostRecord, target ResolvedTarget, viaOverride *string) (ResolvedTarget, error)

ResolveJumps walks named-host via pointers from target to the outermost bastion. viaOverride, when non-nil, replaces the target's inventory via (including an empty value that forces a direct connection).

Returned Jumps are outermost-first. Each hop must be a configured alias; literal addresses are rejected so secrets and host-key decisions stay named.

type Result

type Result struct {
	Metadata
	SchemaVersion string         `json:"schema_version"`
	RunID         string         `json:"run_id"`
	RequestID     string         `json:"request_id,omitempty"`
	Target        ResolvedTarget `json:"target"`
	Action        ActionSpec     `json:"action"`
	Status        string         `json:"status"`
	Phase         string         `json:"phase"`
	Completion    string         `json:"completion"`
	ExitCode      int            `json:"exit_code"`
	Success       bool           `json:"success"`
	Error         *ErrorInfo     `json:"error,omitempty"`
	// Compatibility fields retained for current major version agents.
	Host            string `json:"host"`
	Port            string `json:"port"`
	User            string `json:"user"`
	Command         string `json:"command,omitempty"`
	Stdout          string `json:"stdout,omitempty"`
	Stderr          string `json:"stderr,omitempty"`
	StdoutTruncated bool   `json:"stdout_truncated,omitempty"`
	StderrTruncated bool   `json:"stderr_truncated,omitempty"`
	DurationMs      int64  `json:"duration_ms"`
	AuthMethod      string `json:"auth_method,omitempty"`
	PeerAddress     string `json:"peer_address,omitempty"`
	// ErrorKind is a compatibility projection of Error.Kind for agents that
	// still branch on the flat field from single-command JSON.
	ErrorKind string `json:"error_kind,omitempty"`
}

Result is the single-target versioned document (and compatibility envelope).

func ToResult

func ToResult(runID, requestID string, tr TargetResult) *Result

ToResult projects a TargetResult into the versioned single-target document with compatibility fields.

type Risk added in v0.15.0

type Risk string
const (
	RiskRead        Risk = "read"
	RiskMutation    Risk = "mutation"
	RiskPrivileged  Risk = "privileged"
	RiskDestructive Risk = "destructive"
)

type RunCounts

type RunCounts struct {
	Selected  int `json:"selected"`
	Started   int `json:"started"`
	Succeeded int `json:"succeeded"`
	Failed    int `json:"failed"`
	Skipped   int `json:"skipped"`
	Uncertain int `json:"uncertain"`
}

RunCounts summarizes a finished multi-target run.

type RunOptions

type RunOptions struct {
	Request  *Request
	Snapshot TargetSnapshot
	Payload  *Payload
	Secrets  SecretResolver
	Dialer   Dialer
	Events   EventWriter
	// ActiveSessions is optional instrumentation for tests.
	ActiveSessions *atomic.Int64
	// MaxObserved is optional peak concurrent sessions counter.
	MaxObserved *atomic.Int64
}

RunOptions configures one executor invocation.

type RunOutcome

type RunOutcome struct {
	Metadata
	RunID   string
	Counts  RunCounts
	Results []TargetResult
	// Single is set when exactly one target finished and JSON mode is requested.
	Single *Result
}

RunOutcome is the process-level summary for one accepted run.

func Execute

func Execute(ctx context.Context, opts RunOptions) (RunOutcome, error)

Execute runs the validated request against the frozen snapshot.

type SecretResolver

type SecretResolver interface {
	// GetSSHPassword returns an SSH login password for the given keyring key.
	GetSSHPassword(key string) (string, error)
	// GetSudoPassword returns a sudo password for the given keyring key.
	GetSudoPassword(key string) (string, error)
}

SecretResolver reads typed keyring references. Implementations must not be called during dry-run or selector-only operations.

type SkippedTarget

type SkippedTarget struct {
	Alias  string `json:"alias,omitempty"`
	Reason string `json:"reason"`
}

SkippedTarget records a selector candidate that was not admitted.

type TargetResult

type TargetResult struct {
	Metadata
	Target          ResolvedTarget `json:"target"`
	Action          ActionSpec     `json:"action"`
	Status          string         `json:"status"`
	Phase           string         `json:"phase"`
	Completion      string         `json:"completion"`
	ExitCode        int            `json:"exit_code"`
	Error           *ErrorInfo     `json:"error,omitempty"`
	Stdout          string         `json:"stdout,omitempty"`
	Stderr          string         `json:"stderr,omitempty"`
	StdoutTruncated bool           `json:"stdout_truncated,omitempty"`
	StderrTruncated bool           `json:"stderr_truncated,omitempty"`
	DurationMs      int64          `json:"duration_ms"`
	AuthMethod      string         `json:"auth_method,omitempty"`
	PeerAddress     string         `json:"peer_address,omitempty"`
}

TargetResult is the finished-target document embedded in events and single-target results.

type TargetSelector

type TargetSelector struct {
	Names    []string          `json:"names,omitempty"`
	Groups   []string          `json:"groups,omitempty"`
	Tags     map[string]string `json:"tags,omitempty"`
	AllHosts bool              `json:"all_hosts,omitempty"`
	// Address is an explicit single-target literal address path. It may not
	// combine with multi-host selectors.
	Address string `json:"address,omitempty"`
	Port    string `json:"port,omitempty"`
	User    string `json:"user,omitempty"`
}

TargetSelector describes how hosts are chosen for one execution request.

type TargetSnapshot

type TargetSnapshot struct {
	Targets        []ResolvedTarget `json:"targets"`
	Skipped        []SkippedTarget  `json:"skipped,omitempty"`
	Count          int              `json:"count"`
	SelectorDigest string           `json:"selector_digest"`
}

TargetSnapshot is the frozen, deterministic target set for one run.

func ResolveTargets

func ResolveTargets(hosts []HostRecord, sel TargetSelector, defaults HostRecord) (TargetSnapshot, error)

ResolveTargets freezes a deterministic target snapshot from configured hosts.

Semantics:

  • names and groups form a candidate union
  • every tag predicate is an AND filter
  • if only tags are provided, all configured hosts are the candidate set
  • --all-hosts selects the full inventory before tag filters
  • multi-host selectors never accept literal addresses
  • zero matches is a request-level failure (returned as error)

Jump to

Keyboard shortcuts

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