Documentation
¶
Index ¶
- Constants
- func CacheLicense(key string, valid bool, cacheDir string) error
- func DisablePlugin(name, pluginDir string) error
- func EnablePlugin(name, pluginDir string) error
- func Install(ctx context.Context, cfg *config.Config, name string, pluginDir string) error
- func IsDisabled(name, pluginDir string) bool
- func LicenseCacheDir() string
- func NeedsRevalidation(key string, cacheDir string) bool
- func ProxyCommand(cmdName string, args []string) error
- func Remove(ctx context.Context, cfg *config.Config, name string, pluginDir string, ...) error
- func Start(ctx context.Context, pluginDir string, name string) error
- func Stop(ctx context.Context, name string) error
- func Update(ctx context.Context, cfg *config.Config, name string, pluginDir string) error
- func ValidateLicenseRemote(ctx context.Context, key string, pingURL string) (bool, error)
- func ValidateNetworkAccess(ctx context.Context, registryURL string) error
- type CLICommand
- type EnvVar
- type ExitCodeError
- type InstalledPluginInfo
- type LicenseClient
- type MultiApp
- type PluginInfo
- type PluginManifest
- type PluginStatus
- type Registry
- type RegistryClient
- type SystemDependencies
- type SystemDependency
Constants ¶
const ( // DefaultRegistryURL is the primary registry endpoint (Cloudflare Worker). DefaultRegistryURL = "https://plugins.nself.org/registry.json" // FallbackRegistryURL is the GitHub raw fallback when the primary is down. FallbackRegistryURL = "https://raw.githubusercontent.com/nself-org/plugins/main/registry.json" // DefaultCacheTTL is the registry cache lifetime in seconds. DefaultCacheTTL = 300 )
Variables ¶
This section is empty.
Functions ¶
func CacheLicense ¶
CacheLicense writes the validation result for a license key to a cache file inside cacheDir. The cache format is: {data}|{hmac_hex} where data is {key_prefix}|{status}|{timestamp} and hmac_hex is the HMAC-SHA256 of data keyed by machineID().
Before writing, it prunes any cache entries older than 30 days.
func DisablePlugin ¶ added in v1.0.2
DisablePlugin creates a .disabled marker file in the plugin's directory, causing it to be excluded from compose files on the next build.
func EnablePlugin ¶ added in v1.0.2
EnablePlugin removes the .disabled marker file from the plugin's directory, allowing it to be included in compose files on the next build.
func Install ¶
Install downloads, extracts, and configures a plugin. For paid plugins it checks the license first. Dependencies are resolved and recursively installed before the target plugin. If any step after extraction fails, the extracted directory and database schema are rolled back.
A file lock on {pluginDir}/.install.lock is held for the duration of the operation to prevent concurrent installs from corrupting plugin state.
func IsDisabled ¶ added in v1.0.2
IsDisabled returns true if the named plugin has a .disabled marker file.
func LicenseCacheDir ¶
func LicenseCacheDir() string
LicenseCacheDir returns the directory used for license validation caching. This is ~/.nself/license/ (or /tmp/.nself/license/ if the home directory cannot be determined).
func NeedsRevalidation ¶
NeedsRevalidation returns true if the license cache in cacheDir is missing, tampered with, or if the most recent validation timestamp is older than revalidationInterval (7 days). This is used during nself start to trigger a periodic heartbeat check against the license server. Owner keys never need revalidation.
func ProxyCommand ¶
ProxyCommand checks if a plugin binary exists and executes it. If not, it instructs the user to install it.
For security, the binary is looked up ONLY in the plugin bin directory, never via the full system PATH. This prevents PATH hijacking attacks.
func Remove ¶
func Remove(ctx context.Context, cfg *config.Config, name string, pluginDir string, keepData bool, force bool) error
Remove stops a plugin (if running), optionally drops its database schema, and removes its directory from disk. When force is false and other installed plugins depend on the target, Remove returns an error listing them.
A file lock on {pluginDir}/.install.lock is held for the duration of the operation so that concurrent install and remove calls serialize correctly.
func Start ¶
Start launches a plugin process in the background. It locates the plugin's entry point inside pluginDir, starts it, writes the PID to ~/.nself/runtime/pids/{name}.pid, and records the state in ~/.nself/runtime/states/{name}.state.
func Stop ¶
Stop gracefully shuts down a running plugin. It sends SIGTERM first, waits up to 5 seconds for the process to exit, then sends SIGKILL if it is still alive. PID and state files are cleaned up.
func Update ¶
Update backs up the current installation, then reinstalls from the registry. If the new install fails, the previous version is restored automatically.
func ValidateLicenseRemote ¶
ValidateLicenseRemote performs a remote license check by POSTing to the given pingURL. It returns (true, nil) on HTTP 200, (false, nil) on 401/403/404, and (false, error) on network or unexpected failures.
func ValidateNetworkAccess ¶
ValidateNetworkAccess does a HEAD request to the registry URL. Returns an error with a clear message if the registry is unreachable. Call before any operation that requires network access to the plugin registry.
Types ¶
type CLICommand ¶
CLICommand describes a CLI command provided by a plugin.
type EnvVar ¶
type EnvVar struct {
Name string `json:"name"`
Required bool `json:"required"`
Description string `json:"description"`
Default string `json:"default,omitempty"`
}
EnvVar describes an environment variable required or used by a plugin.
type ExitCodeError ¶ added in v1.0.2
type ExitCodeError struct {
Code int
}
ExitCodeError is returned when a plugin process exits with a non-zero code. The caller (main) should call os.Exit with Code.
func (*ExitCodeError) Error ¶ added in v1.0.2
func (e *ExitCodeError) Error() string
type InstalledPluginInfo ¶
type InstalledPluginInfo struct {
Name string
Version string
Tier string
Status string
Description string
}
InstalledPluginInfo is a richer view of an installed plugin used by the inventory subcommand. It includes Description and Tier from the manifest.
func ListInstalled ¶
func ListInstalled(pluginDir string) ([]InstalledPluginInfo, error)
ListInstalled scans pluginDir and returns detailed information for every installed plugin. Each entry's Status is "running", "installed", or "unknown" depending on the plugin's current runtime state.
type LicenseClient ¶
LicenseClient abstracts license validation for testability.
type MultiApp ¶
type MultiApp struct {
Supported bool `json:"supported"`
IsolationColumn string `json:"isolationColumn,omitempty"`
PKStrategy string `json:"pkStrategy,omitempty"`
DefaultValue string `json:"defaultValue,omitempty"`
}
MultiApp describes multi-tenancy configuration for a plugin.
type PluginInfo ¶
PluginInfo describes a plugin's identity and current state.
type PluginManifest ¶
type PluginManifest struct {
// Required fields
Name string `json:"name"`
Version string `json:"version"`
Description string `json:"description"`
Category string `json:"category"`
License string `json:"license"`
// Optional metadata
Author string `json:"author,omitempty"`
Homepage string `json:"homepage,omitempty"`
Repository string `json:"repository,omitempty"`
Tags []string `json:"tags,omitempty"`
IsCommercial bool `json:"isCommercial,omitempty"`
LicenseType string `json:"licenseType,omitempty"`
RequiredEntitlements []string `json:"requiredEntitlements,omitempty"`
RequiresLicense bool `json:"requires_license,omitempty"`
MinNselfVersion string `json:"minNselfVersion,omitempty"`
MinNodeVersion string `json:"minNodeVersion,omitempty"`
ArchSupport []string `json:"arch_support,omitempty"`
// Implementation
Language string `json:"language,omitempty"`
Runtime string `json:"runtime,omitempty"`
Port int `json:"port,omitempty"`
EntryPoint string `json:"entryPoint,omitempty"`
CLI string `json:"cli,omitempty"`
HealthEndpoint string `json:"health_endpoint,omitempty"`
PackageManager string `json:"packageManager,omitempty"`
Framework string `json:"framework,omitempty"`
// Database
Tables []string `json:"tables,omitempty"`
Views []string `json:"views,omitempty"`
// API
APIEndpoints []string `json:"apiEndpoints,omitempty"`
Webhooks []string `json:"webhooks,omitempty"`
CLICommands []CLICommand `json:"cliCommands,omitempty"`
// Environment
EnvVars []EnvVar `json:"envVars,omitempty"`
// Dependencies
Dependencies []string `json:"dependencies,omitempty"`
OptionalDependencies []string `json:"optionalDependencies,omitempty"`
SystemDependencies SystemDependencies `json:"systemDependencies,omitempty"`
// Multi-tenancy
MultiApp MultiApp `json:"multiApp,omitempty"`
// Permissions
Permissions []string `json:"permissions,omitempty"`
// Registry-specific fields (not in plugin.json, populated by registry)
Tier string `json:"tier,omitempty"`
Checksum string `json:"checksum,omitempty"`
}
PluginManifest describes a single plugin, parsed from plugin.json.
type PluginStatus ¶
type PluginStatus struct {
Name string
State string // starting, running, stopping, stopped, failed
PID int
}
PluginStatus describes the current state of a plugin process.
func Status ¶
func Status(name string) (*PluginStatus, error)
Status returns the current status of a plugin by reading its PID and state files. If the PID file indicates a process that is no longer running, the state is corrected to "stopped".
type Registry ¶
type Registry struct {
Plugins []PluginManifest
}
Registry represents the full plugin registry response.
func FetchRegistry ¶
FetchRegistry is the standalone entry point for fetching a registry. It creates an ephemeral client and delegates to Fetch.
Fallback chain:
- registryURL (default: https://plugins.nself.org/registry.json)
- GitHub raw fallback
- Stale cache at cacheDir/registry.json
func (Registry) MarshalJSON ¶
MarshalJSON implements json.Marshaler for Registry so the cache round-trips through the array format consistently.
type RegistryClient ¶
type RegistryClient interface {
Fetch(ctx context.Context) (*Registry, error)
GetPlugin(ctx context.Context, name string) (*PluginManifest, error)
}
RegistryClient abstracts plugin registry HTTP operations for testability.
type SystemDependencies ¶
type SystemDependencies struct {
Required []SystemDependency `json:"required,omitempty"`
Recommended []SystemDependency `json:"recommended,omitempty"`
}
SystemDependencies groups required and recommended system deps.
type SystemDependency ¶
type SystemDependency struct {
Name string `json:"name"`
Verify string `json:"verify"`
MinVersion string `json:"minVersion,omitempty"`
Apt string `json:"apt,omitempty"`
Brew string `json:"brew,omitempty"`
CustomInstall string `json:"custom_install,omitempty"`
}
SystemDependency describes a system-level dependency for a plugin.