executor

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: May 12, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package executor provides the execution engine for mooncake configuration steps.

Package executor implements the core execution engine for mooncake configuration plans.

The executor is responsible for:

  • Loading and validating configuration plans
  • Expanding steps (loops, includes, presets)
  • Evaluating conditions (when, unless, creates)
  • Dispatching actions to handlers
  • Managing execution context and variables
  • Tracking results and statistics
  • Emitting events for observability
  • Handling dry-run mode
  • Supporting privilege escalation (sudo/become)

Architecture

The executor follows a pipeline architecture:

Plan Loading → Step Expansion → Condition Evaluation → Action Dispatch → Result Handling

Each step goes through:

  1. Pre-execution: Check when/unless/creates, apply tags filter
  2. Variable processing: Merge step vars into context
  3. Loop expansion: Expand with_items/with_filetree into multiple executions
  4. Action execution: Dispatch to handler or legacy implementation
  5. Post-execution: Evaluate changed_when/failed_when, register results
  6. Event emission: Publish lifecycle events

Execution Context

ExecutionContext carries all state needed during execution:

  • Variables: Step vars, global vars, facts, registered results
  • Template: Jinja2-like template renderer
  • Evaluator: Expression evaluator for conditions
  • Logger: Structured logging (TUI or text)
  • PathUtil: Path resolution and expansion
  • EventPublisher: Event emission for observability
  • Stats: Execution statistics (total, success, failed, changed, skipped)

Action Dispatch

Actions are dispatched through two paths:

  1. Handler-based (new): Look up handler in actions.Registry, call handler.Execute()
  2. Legacy: Direct executor methods (HandleShell, HandleFile, etc.)

The executor prefers handlers when available, falling back to legacy for non-migrated actions.

Idempotency

The executor enforces idempotency through:

  • creates: Skip if path exists
  • unless: Skip if command succeeds
  • changed_when: Custom change detection
  • Handler implementations: Built-in state checking

Dry-Run Mode

When DryRun is true:

  • No actual changes are made to the system
  • Handlers log what would happen
  • Template rendering still occurs (validates syntax)
  • File existence checks are performed (read-only)
  • Statistics track what would have changed

Error Handling

Errors are wrapped with context using custom error types:

  • RenderError: Template rendering failures (field + cause)
  • EvaluationError: Expression evaluation failures (expression + cause)
  • CommandError: Command execution failures (command + exit code)
  • FileOperationError: File operation failures (path + operation + cause)
  • StepValidationError: Configuration validation failures
  • SetupError: Infrastructure/environment setup failures

Use errors.Is() and errors.As() for programmatic error inspection.

Usage Example

// Load configuration
steps, err := config.ReadConfig("config.yml")
if err != nil {
    return err
}

// Create executor
log := logger.NewTextLogger()
exec := NewExecutor(log)

// Execute with options
result, err := exec.Execute(config.Plan{Steps: steps}, ExecuteOptions{
    DryRun: false,
    Tags: []string{"setup", "deploy"},
    Variables: map[string]interface{}{
        "environment": "production",
    },
})

// Check results
if !result.Success {
    log.Errorf("Execution failed: %d failed steps", result.FailedSteps)
}
log.Infof("Summary: %d changed, %d unchanged, %d failed",
    result.ChangedSteps, result.SuccessSteps-result.ChangedSteps, result.FailedSteps)

Index

Constants

View Source
const (
	ModeExecute = actions.ModeExecute
	ModePlan    = actions.ModePlan
)

Variables

This section is empty.

Functions

func AddGlobalVariables added in v0.5.0

func AddGlobalVariables(variables map[string]interface{})

AddGlobalVariables injects system facts into the variables map. This makes facts like ansible_os_family, ansible_distribution, etc. available during planning.

func CheckIdempotencyConditions added in v0.5.0

func CheckIdempotencyConditions(step config.Step, ec *ExecutionContext) (bool, string, error)

CheckIdempotencyConditions evaluates creates and unless conditions for shell steps. Returns (shouldSkip bool, reason string, error)

INTERNAL: This function is exported for testing purposes only and is not part of the public API. It may change or be removed in future versions without notice.

func CheckSkipConditions added in v0.5.0

func CheckSkipConditions(step config.Step, ec *ExecutionContext) (bool, string, error)

CheckSkipConditions evaluates whether a step should be skipped based on conditional expressions and tag filters.

It first checks if the step was marked as skipped during planning (via step.Skipped field). This happens when tag filtering is applied during the planning phase.

Next, it evaluates the step's "when" condition (if present), which is an expression that must evaluate to true for the step to execute. If the condition evaluates to false, the step is skipped with reason "when".

Returns:

  • shouldSkip: true if the step should be skipped
  • skipReason: "when" or "tags" indicating why the step was skipped (empty if not skipped)
  • error: any error encountered while evaluating conditions

INTERNAL: This function is exported for testing purposes only and is not part of the public API. It may change or be removed in future versions without notice.

func DispatchStepAction added in v0.5.0

func DispatchStepAction(step config.Step, ec *ExecutionContext) error

DispatchStepAction executes the appropriate handler based on step type. All actions are now handled through the actions registry.

INTERNAL: This function is exported for testing purposes only and is not part of the public API. It may change or be removed in future versions without notice.

func ExecutePlan added in v0.5.0

func ExecutePlan(p *plan.Plan, sudoPass string, mode actions.Mode, log logger.Logger, publisher events.Publisher) error

ExecutePlan executes a pre-compiled plan. Emits events through the provided publisher for all execution progress.

func ExecuteStep

func ExecuteStep(step config.Step, ec *ExecutionContext) error

ExecuteStep executes a single configuration step within the given execution context.

func ExecuteSteps

func ExecuteSteps(steps []config.Step, ec *ExecutionContext) error

ExecuteSteps executes a sequence of configuration steps within the given execution context.

func GetStepDisplayName added in v0.5.0

func GetStepDisplayName(step config.Step, ec *ExecutionContext) (string, bool)

GetStepDisplayName determines the display name to show for a step in logs and output.

The function follows a priority order to determine the name:

  1. If executing within a with_filetree loop, uses action + destination path
  2. If executing within a with_items loop, uses the string representation of the item
  3. Otherwise, uses the step's configured Name field

Returns:

  • displayName: the name to display for this step
  • hasName: true if a name was found, false if the step is anonymous

INTERNAL: This function is exported for testing purposes only and is not part of the public API. It may change or be removed in future versions without notice.

func HandleVars added in v0.5.0

func HandleVars(step config.Step, ec *ExecutionContext) error

HandleVars processes the vars field of a step, rendering templates and merging into the execution context.

INTERNAL: This function is exported for testing purposes only and is not part of the public API. It may change or be removed in future versions without notice.

func HandleWhenExpression added in v0.5.0

func HandleWhenExpression(step config.Step, ec *ExecutionContext) (bool, error)

HandleWhenExpression evaluates the when condition and returns whether the step should be skipped. Returns (shouldSkip bool, error).

INTERNAL: This function is exported for testing purposes only and is not part of the public API. It may change or be removed in future versions without notice.

func InspectPlan added in v0.5.0

func InspectPlan(p *plan.Plan, sudoPass string, log logger.Logger) ([]plan.StepInspection, error)

InspectPlan runs the plan in non-mutating ModePlan and returns per-step inspections. Each inspection reports whether applying the step would change state, the handler-supplied reason, and whether the step is checkable at all (shell steps return Checkable=false).

This is the primitive that powers `mooncake plan` after Spec 16: the plan command builds the static plan via planner.BuildPlan, then calls InspectPlan to fill in the per-step state predictions.

Implementation: subscribes a collector to a fresh SyncPublisher, dispatches the plan through the standard executor in check mode (which routes Runner handlers via dispatchRunner and legacy handlers via dispatchCheck — both emit EventStepChecked), then returns the collected results.

func MarkStepFailed added in v0.5.0

func MarkStepFailed(result *Result, step config.Step, ec *ExecutionContext)

MarkStepFailed marks a result as failed and registers it if needed. The caller is responsible for returning an appropriate error.

INTERNAL: This function is exported for testing purposes only and is not part of the public API. It may change or be removed in future versions without notice.

func ParseFileMode added in v0.5.0

func ParseFileMode(modeStr string, defaultMode os.FileMode) os.FileMode

ParseFileMode parses a mode string (e.g., "0644") into os.FileMode. Returns default mode if mode is empty or invalid.

INTERNAL: This function is exported for testing purposes only and is not part of the public API. It may change or be removed in future versions without notice.

func ShouldSkipByTags added in v0.5.0

func ShouldSkipByTags(step config.Step, ec *ExecutionContext) bool

ShouldSkipByTags determines if a step should be skipped based on tag filtering. Returns true if the step should be skipped, false otherwise.

INTERNAL: This function is exported for testing purposes only and is not part of the public API. It may change or be removed in future versions without notice.

func Start

func Start(startConfig StartConfig, log logger.Logger, publisher events.Publisher) error

Start begins execution of a mooncake configuration with the given settings. Always goes through the planner to expand loops, includes, and variables. Emits events through the provided publisher for all execution progress.

Types

type AssertionError added in v0.5.0

type AssertionError struct {
	Type     string // "command", "file", "http"
	Expected string // What was expected
	Actual   string // What was found
	Details  string // Additional context (optional)
	Cause    error  // Underlying error (optional)
}

AssertionError represents an assertion verification failure. Unlike other errors, assertions are expected to fail when conditions aren't met.

func (*AssertionError) Error added in v0.5.0

func (e *AssertionError) Error() string

func (*AssertionError) Unwrap added in v0.5.0

func (e *AssertionError) Unwrap() error

type CommandError added in v0.5.0

type CommandError struct {
	ExitCode int
	Timeout  bool
	Duration string
	Cause    error // Optional underlying error (e.g., exec.ExitError, OS errors)
}

CommandError represents a command execution failure

func (*CommandError) Error added in v0.5.0

func (e *CommandError) Error() string

func (*CommandError) Unwrap added in v0.5.0

func (e *CommandError) Unwrap() error

type DryRunLogger added in v0.5.0

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

DryRunLogger provides consistent dry-run message formatting across all handlers.

INTERNAL: This type is exported for testing purposes only and is not part of the public API. It may change or be removed in future versions without notice.

func NewDryRunLogger added in v0.5.0

func NewDryRunLogger(log logger.Logger) *DryRunLogger

NewDryRunLogger creates a dry-run logger wrapper.

INTERNAL: This function is exported for testing purposes only and is not part of the public API. It may change or be removed in future versions without notice.

func (*DryRunLogger) LogArchiveExtraction added in v0.5.0

func (d *DryRunLogger) LogArchiveExtraction(src, dest, format string, stripComponents int)

LogArchiveExtraction logs a dry-run message for archive extraction.

func (*DryRunLogger) LogAssertCheck added in v0.5.0

func (d *DryRunLogger) LogAssertCheck(assertType, expected string)

LogAssertCheck logs a dry-run message for assertion verification.

func (*DryRunLogger) LogDirectoryCreate added in v0.5.0

func (d *DryRunLogger) LogDirectoryCreate(path string, mode os.FileMode)

LogDirectoryCreate logs a dry-run message for directory creation.

func (*DryRunLogger) LogDirectoryRemove added in v0.5.0

func (d *DryRunLogger) LogDirectoryRemove(path string)

LogDirectoryRemove logs a dry-run message for directory removal.

func (*DryRunLogger) LogFileCopy added in v0.5.0

func (d *DryRunLogger) LogFileCopy(src, dest string, mode os.FileMode, size int64)

LogFileCopy logs a dry-run message for file copy.

func (*DryRunLogger) LogFileCopyNoChange added in v0.5.0

func (d *DryRunLogger) LogFileCopyNoChange(src, dest string)

LogFileCopyNoChange logs a dry-run message when file copy is not needed.

func (*DryRunLogger) LogFileCreate added in v0.5.0

func (d *DryRunLogger) LogFileCreate(path string, mode os.FileMode, size int)

LogFileCreate logs a dry-run message for file creation.

func (*DryRunLogger) LogFileDownload added in v0.5.0

func (d *DryRunLogger) LogFileDownload(url, dest string, mode os.FileMode)

LogFileDownload logs a dry-run message for file download.

func (*DryRunLogger) LogFileDownloadNoChange added in v0.5.0

func (d *DryRunLogger) LogFileDownloadNoChange(_, dest string)

LogFileDownloadNoChange logs a dry-run message when file download is not needed.

func (*DryRunLogger) LogFileRemove added in v0.5.0

func (d *DryRunLogger) LogFileRemove(path string, size int64)

LogFileRemove logs a dry-run message for file removal.

func (*DryRunLogger) LogFileTouch added in v0.5.0

func (d *DryRunLogger) LogFileTouch(path string)

LogFileTouch logs a dry-run message for updating file timestamps.

func (*DryRunLogger) LogFileUpdate added in v0.5.0

func (d *DryRunLogger) LogFileUpdate(path string, mode os.FileMode, oldSize, newSize int)

LogFileUpdate logs a dry-run message for file update.

func (*DryRunLogger) LogHardlinkCreate added in v0.5.0

func (d *DryRunLogger) LogHardlinkCreate(src, dest string, force bool)

LogHardlinkCreate logs a dry-run message for hardlink creation.

func (*DryRunLogger) LogHardlinkNoChange added in v0.5.0

func (d *DryRunLogger) LogHardlinkNoChange(src, dest string)

LogHardlinkNoChange logs a dry-run message when hardlink already exists correctly.

func (*DryRunLogger) LogPermissionsChange added in v0.5.0

func (d *DryRunLogger) LogPermissionsChange(path, mode, owner, group string, recurse bool)

LogPermissionsChange logs a dry-run message for permission changes.

func (*DryRunLogger) LogPermissionsNoChange added in v0.5.0

func (d *DryRunLogger) LogPermissionsNoChange(path string)

LogPermissionsNoChange logs a dry-run message when permissions are already correct.

func (*DryRunLogger) LogPresetOperation added in v0.5.0

func (d *DryRunLogger) LogPresetOperation(invocation *config.PresetInvocation, paramsCount int)

LogPresetOperation logs a preset expansion operation in dry-run mode.

func (*DryRunLogger) LogPrintMessage added in v0.5.0

func (d *DryRunLogger) LogPrintMessage(message string)

LogPrintMessage logs a print message in dry-run mode.

func (*DryRunLogger) LogRegister added in v0.5.0

func (d *DryRunLogger) LogRegister(step config.Step)

LogRegister logs a dry-run message for registering results.

func (*DryRunLogger) LogServiceOperation added in v0.5.0

func (d *DryRunLogger) LogServiceOperation(serviceName string, serviceAction *config.ServiceAction, withSudo bool)

LogServiceOperation logs a dry-run message for service management.

func (*DryRunLogger) LogShellExecution added in v0.5.0

func (d *DryRunLogger) LogShellExecution(command string, withSudo bool)

LogShellExecution logs a dry-run message for shell command execution.

func (*DryRunLogger) LogSymlinkCreate added in v0.5.0

func (d *DryRunLogger) LogSymlinkCreate(src, dest string, force bool)

LogSymlinkCreate logs a dry-run message for symlink creation.

func (*DryRunLogger) LogSymlinkNoChange added in v0.5.0

func (d *DryRunLogger) LogSymlinkNoChange(src, dest string)

LogSymlinkNoChange logs a dry-run message when symlink already exists correctly.

func (*DryRunLogger) LogTemplateCreate added in v0.5.0

func (d *DryRunLogger) LogTemplateCreate(src, dest string, mode os.FileMode, size int)

LogTemplateCreate logs a dry-run message for template creation.

func (*DryRunLogger) LogTemplateNoChange added in v0.5.0

func (d *DryRunLogger) LogTemplateNoChange(src, dest string)

LogTemplateNoChange logs a dry-run message when template produces no changes.

func (*DryRunLogger) LogTemplateRender added in v0.5.0

func (d *DryRunLogger) LogTemplateRender(src, dest string, mode os.FileMode)

LogTemplateRender logs a dry-run message for template rendering.

func (*DryRunLogger) LogTemplateUpdate added in v0.5.0

func (d *DryRunLogger) LogTemplateUpdate(src, dest string, mode os.FileMode, oldSize, newSize int)

LogTemplateUpdate logs a dry-run message for template update.

func (*DryRunLogger) LogVariableLoad added in v0.5.0

func (d *DryRunLogger) LogVariableLoad(count int, source string)

LogVariableLoad logs a dry-run message for loading variables.

func (*DryRunLogger) LogVariableSet added in v0.5.0

func (d *DryRunLogger) LogVariableSet(count int)

LogVariableSet logs a dry-run message for setting variables.

type EvaluationError added in v0.5.0

type EvaluationError struct {
	Expression string
	Cause      error
}

EvaluationError represents an expression evaluation failure

func (*EvaluationError) Error added in v0.5.0

func (e *EvaluationError) Error() string

func (*EvaluationError) Unwrap added in v0.5.0

func (e *EvaluationError) Unwrap() error

type ExecutionContext

type ExecutionContext struct {
	// Variables contains template variables available to steps.
	// Copied on context copy so nested contexts can have their own variables (e.g., loop items).
	Variables map[string]interface{}

	// CurrentDir is the directory containing the current config file.
	// Used for resolving relative paths in include, template src, etc.
	CurrentDir string

	// PresetBaseDir is the root directory of the currently executing preset.
	// When set, template paths are resolved relative to this directory instead of CurrentDir.
	// This ensures templates in presets work correctly even when included from task subdirectories.
	PresetBaseDir string

	// CurrentFile is the absolute path to the current config file being executed.
	// Used for error messages and debugging.
	CurrentFile string

	// Level tracks nesting depth for display indentation.
	// 0 = root config, increments by 1 for each include or loop level.
	Level int

	// CurrentIndex is the 0-based index of the current step within the current scope.
	// Resets to 0 when entering includes or loops.
	CurrentIndex int

	// TotalSteps is the number of steps in the current execution scope.
	// Updated when entering includes or loops to reflect the new scope size.
	TotalSteps int

	// Logger handles all output, configured with padding based on Level.
	Logger logger.Logger

	// SudoPass is the password used for steps with become: true.
	// Empty string if not provided via --sudo-pass flag.
	SudoPass string

	// Tags filters which steps execute (empty = all steps execute).
	// Steps without matching tags are skipped when this is non-empty.
	Tags []string

	// CurrentMode is the dispatch mode for this context. ModeExecute
	// performs side effects; ModePlan inspects state and returns
	// predictions without mutating. Read via ec.Mode().
	CurrentMode actions.Mode

	// Stats holds shared execution statistics counters.
	// SHARED via pointer - all contexts update the same counters.
	Stats *ExecutionStats

	// Template renders template strings with variable substitution.
	// SHARED across all contexts - same instance used everywhere.
	Template template.Renderer

	// Evaluator evaluates when condition expressions.
	// SHARED across all contexts - same instance used everywhere.
	Evaluator expression.Evaluator

	// PathUtil expands paths with tilde and variable substitution.
	// SHARED across all contexts - same instance used everywhere.
	PathUtil *pathutil.PathExpander

	// FileTree walks directory trees for with_filetree.
	// SHARED across all contexts - same instance used everywhere.
	FileTree *filetree.Walker

	// Redactor redacts sensitive values (passwords) from log output.
	// SHARED across all contexts - same instance used everywhere.
	Redactor *security.Redactor

	// EventPublisher publishes execution events to subscribers.
	// SHARED across all contexts - same instance used everywhere.
	EventPublisher events.Publisher

	// CurrentStepID is the unique identifier for the currently executing step.
	// Used for correlating events from the same step execution.
	CurrentStepID string

	// CurrentResult holds the result of the currently executing step.
	// Handlers should set this to provide result data to event emission.
	CurrentResult *Result
}

ExecutionContext holds all state needed to execute a step or sequence of steps.

The context is designed to be copied when entering nested execution scopes (includes, loops). Most fields are copied by value, but certain fields use pointers to maintain shared state across the entire execution tree.

Field categories:

  • Configuration: Variables, CurrentDir, CurrentFile (copied on nested contexts)
  • Display state: Level, CurrentIndex, TotalSteps (modified for each scope)
  • Execution settings: Logger, SudoPass, Tags, DryRun (shared across contexts)
  • Global counters: Pointers that accumulate across all contexts
  • Dependencies: Shared service instances

func (*ExecutionContext) Clone added in v0.5.0

func (ec *ExecutionContext) Clone() ExecutionContext

Clone creates a new ExecutionContext for a nested execution scope (include or loop). Variables map is shallow copied, display fields are copied by value, and pointer fields remain shared across all contexts.

func (*ExecutionContext) Effects added in v0.5.0

func (ec *ExecutionContext) Effects() actions.Performer

Effects returns a Performer that routes filesystem and command primitives by the current Mode. Handlers should call this instead of calling os.* directly so that ModePlan vs ModeExecute is decided in one place. The returned Performer is cheap to construct.

func (*ExecutionContext) EmitEvent added in v0.5.0

func (ec *ExecutionContext) EmitEvent(eventType events.EventType, data interface{})

EmitEvent publishes an event to all subscribers

func (*ExecutionContext) GetCurrentStepID added in v0.5.0

func (ec *ExecutionContext) GetCurrentStepID() string

GetCurrentStepID returns the current step ID.

func (*ExecutionContext) GetEvaluator added in v0.5.0

func (ec *ExecutionContext) GetEvaluator() expression.Evaluator

GetEvaluator returns the expression evaluator.

func (*ExecutionContext) GetEventPublisher added in v0.5.0

func (ec *ExecutionContext) GetEventPublisher() events.Publisher

GetEventPublisher returns the event publisher.

func (*ExecutionContext) GetLogger added in v0.5.0

func (ec *ExecutionContext) GetLogger() logger.Logger

GetLogger returns the logger.

func (*ExecutionContext) GetTemplate added in v0.5.0

func (ec *ExecutionContext) GetTemplate() template.Renderer

GetTemplate returns the template renderer.

func (*ExecutionContext) GetVariables added in v0.5.0

func (ec *ExecutionContext) GetVariables() map[string]interface{}

GetVariables returns the execution variables.

func (*ExecutionContext) Mode added in v0.5.0

func (ec *ExecutionContext) Mode() Mode

Mode returns the current dispatch mode (ModeExecute or ModePlan).

type ExecutionStats added in v0.5.0

type ExecutionStats struct {
	// Global tracks total non-skipped steps across the entire execution tree
	Global *int
	// Executed counts successfully completed steps
	Executed *int
	// Skipped counts steps skipped due to when conditions or tag filtering
	Skipped *int
	// Failed counts steps that failed with errors
	Failed *int
	// Changed counts steps that resulted in a system change
	Changed *int
}

ExecutionStats holds shared statistics counters for execution tracking. All fields are pointers to enable shared state across nested execution contexts.

func NewExecutionStats added in v0.5.0

func NewExecutionStats() *ExecutionStats

NewExecutionStats creates a new ExecutionStats with all counters initialized to zero

type FileOperationError added in v0.5.0

type FileOperationError struct {
	Operation string // "create", "read", "write", "delete", "chmod", "chown", "link"
	Path      string
	Cause     error
}

FileOperationError represents a file operation failure

func (*FileOperationError) Error added in v0.5.0

func (e *FileOperationError) Error() string

func (*FileOperationError) Unwrap added in v0.5.0

func (e *FileOperationError) Unwrap() error

type Mode added in v0.5.0

type Mode = actions.Mode

Mode and its constants live in the actions package; re-exported here for backward source compatibility during the Spec 16 migration.

type RenderError added in v0.5.0

type RenderError struct {
	Field string
	Cause error
}

RenderError represents a template rendering failure

func (*RenderError) Error added in v0.5.0

func (e *RenderError) Error() string

func (*RenderError) Unwrap added in v0.5.0

func (e *RenderError) Unwrap() error

type Result added in v0.5.0

type Result struct {
	// Stdout contains the standard output from shell commands.
	// Only populated by shell steps.
	Stdout string `json:"stdout"`

	// Stderr contains the standard error from shell commands.
	// Only populated by shell steps.
	Stderr string `json:"stderr"`

	// Rc is the return/exit code.
	// For shell steps: the command's exit code (0 = success).
	// For file/template steps: 0 for success, 1 for failure.
	Rc int `json:"rc"`

	// Failed indicates whether the step execution failed.
	// Set to true when shell commands exit non-zero or when file/template operations error.
	Failed bool `json:"failed"`

	// Changed indicates whether the step made modifications to the system.
	// Shell steps: always true (commands assumed to make changes).
	// File steps: true if file/directory was created or modified.
	// Template steps: true if output file was created or content changed.
	Changed bool `json:"changed"`

	// WouldChange indicates that a plan-mode (non-mutating) inspection
	// predicts the step would change the system if executed.
	// Set by handlers running in ModePlan (Spec 16). Mirrors today's
	// CheckResult.WouldChange and is the eventual replacement.
	WouldChange bool `json:"would_change,omitempty"`

	// Reason is a short human-readable description of the result, e.g.
	// "would create directory", "already matches", "content differs".
	// Populated alongside WouldChange and Changed.
	Reason string `json:"reason,omitempty"`

	// Checkable indicates whether the action supports plan-mode inspection.
	// False for actions like shell where no prediction is possible (the
	// command must run to know its effect). Set by handlers in ModePlan.
	Checkable bool `json:"checkable,omitempty"`

	// Skipped is reserved for future use to indicate skipped steps.
	// Currently not set by any step type.
	Skipped bool `json:"skipped"`

	// Data holds custom result data set by actions via SetData.
	// This allows actions to provide additional structured information
	// that can be accessed in templates and registered results.
	Data map[string]interface{} `json:"data,omitempty"`

	// Timing information
	StartTime time.Time     `json:"start_time,omitempty"`
	EndTime   time.Time     `json:"end_time,omitempty"`
	Duration  time.Duration `json:"duration_ms,omitempty"` // Duration in time.Duration format
}

Result represents the outcome of executing a step and can be registered to variables for use in subsequent steps via the "register" field.

Field usage varies by step type:

Shell steps:

  • Stdout: captured standard output from the command
  • Stderr: captured standard error from the command
  • Rc: exit code (0 for success, non-zero for failure)
  • Failed: true if Rc != 0
  • Changed: always true (commands are assumed to make changes)

File steps (file with state: file or directory):

  • Rc: 0 for success, 1 for failure
  • Failed: true if file/directory operation failed
  • Changed: true if file/directory was created or content modified

Template steps:

  • Rc: 0 for success, 1 for failure
  • Failed: true if template rendering or file write failed
  • Changed: true if output file was created or content changed

Variable steps (vars, include_vars):

  • All fields remain at default values (not currently used)

The Skipped field is reserved for future use but not currently set by any step type.

func NewResult added in v0.5.0

func NewResult() *Result

NewResult creates a new Result with default values.

func (*Result) RegisterTo added in v0.5.0

func (r *Result) RegisterTo(variables map[string]interface{}, name string)

RegisterTo registers this result to the variables map under the given name. The result can be accessed using nested field syntax (e.g., "result.stdout", "result.rc") in templates and when conditions.

func (*Result) SetChanged added in v0.5.0

func (r *Result) SetChanged(changed bool)

SetChanged marks whether the action made changes.

func (*Result) SetData added in v0.5.0

func (r *Result) SetData(data map[string]interface{})

SetData sets custom result data. This merges the provided data into the result's ToMap output, allowing actions to provide additional structured information.

func (*Result) SetFailed added in v0.5.0

func (r *Result) SetFailed(failed bool)

SetFailed marks the result as failed.

func (*Result) SetStderr added in v0.5.0

func (r *Result) SetStderr(stderr string)

SetStderr sets the stderr output.

func (*Result) SetStdout added in v0.5.0

func (r *Result) SetStdout(stdout string)

SetStdout sets the stdout output.

func (*Result) Status added in v0.5.0

func (r *Result) Status() string

Status returns a string representation of the result status.

func (*Result) ToMap added in v0.5.0

func (r *Result) ToMap() map[string]interface{}

ToMap converts Result to a map for use in template variables.

type SetupError added in v0.5.0

type SetupError struct {
	Component string // "become", "timeout", "sudo", "user", "group"
	Issue     string // What went wrong
	Cause     error  // Underlying error (optional)
}

SetupError represents infrastructure or configuration setup failures

func (*SetupError) Error added in v0.5.0

func (e *SetupError) Error() string

func (*SetupError) Unwrap added in v0.5.0

func (e *SetupError) Unwrap() error

type StartConfig

type StartConfig struct {
	ConfigFilePath   string
	VarsFilePath     string
	SudoPass         string // Sudo password provided directly (use SudoPassFile for better security)
	SudoPassFile     string
	AskBecomePass    bool
	InsecureSudoPass bool
	Tags             []string

	// Artifact configuration
	ArtifactsDir      string
	CaptureFullOutput bool
	MaxOutputBytes    int
	MaxOutputLines    int
}

StartConfig contains configuration for starting a mooncake execution.

type StepValidationError added in v0.5.0

type StepValidationError struct {
	Field   string
	Message string
}

StepValidationError represents step parameter validation failure during execution

func (*StepValidationError) Error added in v0.5.0

func (e *StepValidationError) Error() string

Jump to

Keyboard shortcuts

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