binary

package
v1.0.0-rc0 Latest Latest
Warning

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

Go to latest
Published: Jan 20, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewBinaryVersionDetector

func NewBinaryVersionDetector() ports.BinaryVersionDetector

NewBinaryVersionDetector creates a new version detector with a default timeout. The timeout prevents hanging if a binary doesn't respond or gets stuck.

func NewBinaryVersionDetectorWithTimeout

func NewBinaryVersionDetectorWithTimeout(timeout time.Duration) ports.BinaryVersionDetector

NewBinaryVersionDetectorWithTimeout creates a new version detector with a custom timeout. This is useful for testing or when dealing with slow binaries.

Types

type BinaryValidator

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

BinaryValidator validates cached binaries for usability. This implements the Validator component from the implementation plan.

Validation Checks:

  1. File exists and is a regular file (not directory)
  2. File has executable permissions (mode & 0111 != 0)
  3. Binary runs successfully with "version" command
  4. Version output can be parsed

Design Decision: Uses BinaryVersionDetector port to maintain Clean Architecture. The validator focuses on structural validation, delegating version detection to the adapter.

func NewBinaryValidator

func NewBinaryValidator(detector ports.BinaryVersionDetector) *BinaryValidator

NewBinaryValidator creates a new binary validator.

Parameters:

  • detector: Version detector implementation (e.g., VersionDetectorAdapter)

Example:

detector := NewVersionDetectorAdapter(
    executor.NewOSCommandExecutor(),
    5 * time.Second,
)
validator := NewBinaryValidator(detector)

func (*BinaryValidator) ValidateAndEnrichMetadata

func (v *BinaryValidator) ValidateAndEnrichMetadata(ctx context.Context, metadata *cache.CachedBinaryMetadata) (*cache.CachedBinaryMetadata, error)

ValidateAndEnrichMetadata validates a binary and enriches metadata with version info.

This is a convenience method that combines validation and version detection in a single call, updating the CachedBinaryMetadata struct in place.

Parameters:

  • ctx: Context for cancellation/timeout
  • metadata: Pointer to CachedBinaryMetadata to validate and enrich

Side Effects:

  • Sets metadata.IsValid = true if validation succeeds
  • Sets metadata.ValidationError if validation fails
  • Populates metadata.Version and metadata.CommitHash on success

Returns:

  • The enriched metadata with updated fields
  • Error if validation fails (also stored in metadata.ValidationError)

Usage:

enriched, err := validator.ValidateAndEnrichMetadata(ctx, &binary)
if err != nil {
    logger.Warn("Skipping binary %s: %v", binary.Path, err)
}

func (*BinaryValidator) ValidateBinary

func (v *BinaryValidator) ValidateBinary(ctx context.Context, binaryPath string) error

ValidateBinary checks if a binary is usable for deployment.

This performs all validation checks required by the spec:

  • FR-004: Binary must be executable and version-detectable
  • EC-007: Corrupted binaries must be skipped with warning
  • EC-009: Permission issues must produce actionable error messages

Parameters:

  • ctx: Context for cancellation/timeout
  • binaryPath: Absolute path to binary file

Returns:

  • nil if binary is valid and usable
  • Error with actionable message if validation fails

Error Messages (user-facing):

  • "binary not found: <path>"
  • "path is a directory, not a binary"
  • "binary is not executable (use chmod +x to fix)"
  • "version detection failed: <reason>"

type PassthroughExecutor

type PassthroughExecutor struct {
}

PassthroughExecutor implements ports.BinaryExecutor for executing plugin binaries. It provides both standard execution and interactive (TTY) execution modes.

This implementation:

  • Streams output in real-time to stdout/stderr
  • Supports context cancellation
  • Handles exit codes properly
  • Provides TTY support for interactive commands

Thread-safety: Each Execute call is independent and can be called concurrently.

func NewPassthroughExecutor

func NewPassthroughExecutor() *PassthroughExecutor

NewPassthroughExecutor creates a new PassthroughExecutor.

func (*PassthroughExecutor) Execute

Execute runs a binary command and waits for completion. Output is streamed to the configured writers (or os.Stdout/Stderr if not set).

Implementation details:

  • Creates exec.Cmd with the binary and arguments
  • Connects stdin/stdout/stderr
  • Starts the process
  • Waits for completion or context cancellation
  • Returns exit code

func (*PassthroughExecutor) ExecuteInteractive

func (e *PassthroughExecutor) ExecuteInteractive(ctx context.Context, cmd ports.BinaryPassthroughCommand) (int, error)

ExecuteInteractive runs a binary in interactive mode with TTY support. This is used for commands that require user interaction (prompts, editors, etc.).

On Unix systems, this properly sets up the TTY to allow interactive features:

  • Terminal raw mode
  • Signal handling (Ctrl+C, etc.)
  • Terminal size

On Windows, this falls back to standard execution.

func (*PassthroughExecutor) ExecuteWithOutput

func (e *PassthroughExecutor) ExecuteWithOutput(ctx context.Context, cmd ports.BinaryPassthroughCommand) (stdout, stderr string, exitCode int, err error)

ExecuteWithOutput is a convenience method that captures stdout and stderr. This is useful for commands where we need to parse the output.

type PluginBinaryResolver

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

PluginBinaryResolver implements ports.BinaryResolver using the plugin system. It resolves plugin names to binary paths by:

  1. Loading the plugin to get its Module interface
  2. Querying the binary name from Module.BinaryName()
  3. Checking the BinaryCache for the active binary

This adapter follows the Adapter pattern to bridge the plugin system with the binary passthrough use cases.

Thread-safety: This implementation is thread-safe for concurrent use.

func NewPluginBinaryResolver

func NewPluginBinaryResolver(loader *plugin.Loader, cache ports.BinaryCache) *PluginBinaryResolver

NewPluginBinaryResolver creates a new PluginBinaryResolver.

Parameters:

  • loader: Plugin loader for discovering and loading plugins
  • cache: Binary cache for resolving cached binary paths

Returns:

  • *PluginBinaryResolver: Configured resolver instance

func (*PluginBinaryResolver) GetActiveBinary

func (r *PluginBinaryResolver) GetActiveBinary(ctx context.Context) (string, string, error)

GetActiveBinary returns the currently active binary path and plugin name. This queries the BinaryCache for the active symlink and resolves it.

func (*PluginBinaryResolver) GetBinaryName

func (r *PluginBinaryResolver) GetBinaryName(ctx context.Context, pluginName string) (string, error)

GetBinaryName returns the binary name for a plugin. This loads the plugin and queries its Module.BinaryName() method.

func (*PluginBinaryResolver) ListAvailablePlugins

func (r *PluginBinaryResolver) ListAvailablePlugins(ctx context.Context) ([]string, error)

ListAvailablePlugins returns all available plugin names. This uses the plugin loader's Discover() method.

func (*PluginBinaryResolver) ResolveBinary

func (r *PluginBinaryResolver) ResolveBinary(ctx context.Context, pluginName string) (string, error)

ResolveBinary resolves a plugin name to its binary path. This implementation:

  1. Loads the plugin (or retrieves from cache)
  2. Gets the binary name from the Module interface
  3. Checks for custom binary in devnet metadata (future enhancement)
  4. Falls back to active binary from cache

Thread-safe: Uses RWMutex for concurrent access to plugin cache.

type VersionDetectorAdapter

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

VersionDetectorAdapter implements ports.BinaryVersionDetector using command execution. This adapter follows Clean Architecture by implementing an application port with infrastructure-level concerns (command execution).

Design Decision: Uses CommandExecutor abstraction for testability. The detector can work with any binary following Cosmos SDK version output format.

func NewVersionDetectorAdapter

func NewVersionDetectorAdapter(exec executor.CommandExecutor, timeout time.Duration) *VersionDetectorAdapter

NewVersionDetectorAdapter creates a new version detector with the given executor and timeout.

Parameters:

  • executor: Command executor (use executor.NewOSCommandExecutor() for production)
  • timeout: Maximum time to wait for version command (recommended: 5 seconds per spec)

Example:

detector := NewVersionDetectorAdapter(
    executor.NewOSCommandExecutor(),
    5 * time.Second,
)

func (*VersionDetectorAdapter) DetectVersion

func (d *VersionDetectorAdapter) DetectVersion(ctx context.Context, binaryPath string) (*ports.BinaryVersionInfo, error)

DetectVersion executes the binary with "version" command and parses output.

Expected Binary Output Format (Cosmos SDK standard):

version: v1.0.0
commit: 80ad31b1234567890abcdef1234567890abcdef

Or alternate format:

v1.0.0
80ad31b1234567890abcdef1234567890abcdef

Parameters:

  • ctx: Context for cancellation/timeout
  • binaryPath: Absolute path to binary executable

Returns:

  • BinaryVersionInfo with parsed version and commit hash
  • Error if execution fails, times out, or output cannot be parsed

Error Handling:

  • Command not found: "binary not executable or not found"
  • Timeout: "version detection timed out after 5s"
  • Parse failure: "failed to parse version output"
  • Exit code != 0: "version command failed: <output>"

Jump to

Keyboard shortcuts

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