Documentation
¶
Index ¶
- func NewBinaryVersionDetector() ports.BinaryVersionDetector
- func NewBinaryVersionDetectorWithTimeout(timeout time.Duration) ports.BinaryVersionDetector
- type BinaryValidator
- type PassthroughExecutor
- func (e *PassthroughExecutor) Execute(ctx context.Context, cmd ports.BinaryPassthroughCommand) (int, error)
- func (e *PassthroughExecutor) ExecuteInteractive(ctx context.Context, cmd ports.BinaryPassthroughCommand) (int, error)
- func (e *PassthroughExecutor) ExecuteWithOutput(ctx context.Context, cmd ports.BinaryPassthroughCommand) (stdout, stderr string, exitCode int, err error)
- type PluginBinaryResolver
- func (r *PluginBinaryResolver) GetActiveBinary(ctx context.Context) (string, string, error)
- func (r *PluginBinaryResolver) GetBinaryName(ctx context.Context, pluginName string) (string, error)
- func (r *PluginBinaryResolver) ListAvailablePlugins(ctx context.Context) ([]string, error)
- func (r *PluginBinaryResolver) ResolveBinary(ctx context.Context, pluginName string) (string, error)
- type VersionDetectorAdapter
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:
- File exists and is a regular file (not directory)
- File has executable permissions (mode & 0111 != 0)
- Binary runs successfully with "version" command
- 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 ¶
func (e *PassthroughExecutor) Execute(ctx context.Context, cmd ports.BinaryPassthroughCommand) (int, error)
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:
- Loading the plugin to get its Module interface
- Querying the binary name from Module.BinaryName()
- 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 ¶
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:
- Loads the plugin (or retrieves from cache)
- Gets the binary name from the Module interface
- Checks for custom binary in devnet metadata (future enhancement)
- 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>"