agent

package
v0.3.88 Latest Latest
Warning

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

Go to latest
Published: Oct 30, 2026 License: MIT Imports: 30 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AllowedCommands = map[string]CommandSpec{
	"node.start":             {Description: "Start a Klever node container", RequiresContainer: true},
	"node.stop":              {Description: "Stop a Klever node container", RequiresContainer: true},
	"node.restart":           {Description: "Restart a Klever node container", RequiresContainer: true},
	"node.status":            {Description: "Get status of a Klever node container", RequiresContainer: true},
	"node.create":            {Description: "Create a new Klever node container", RequiresContainer: false},
	"node.remove":            {Description: "Remove a Klever node container", RequiresContainer: true},
	"node.upgrade":           {Description: "Upgrade a Klever node to a new image tag", RequiresContainer: true},
	"node.pull":              {Description: "Pull a Docker image", RequiresContainer: false},
	"node.provision":         {Description: "Provision a new Klever node from scratch", RequiresContainer: false},
	"node.restore-db":        {Description: "Restore a node's chain DB from the official Klever backup", RequiresContainer: true},
	"node.reset-db":          {Description: "Delete a node's chain DB and re-bootstrap from the latest epoch", RequiresContainer: true},
	"node.discovery":         {Description: "Scan for existing Klever nodes", RequiresContainer: false},
	"docker.images.list":     {Description: "List local Klever Docker images", RequiresContainer: false},
	"docker.images.remove":   {Description: "Remove unused Klever Docker images", RequiresContainer: false},
	"config.list":            {Description: "List configuration files for a node", RequiresContainer: false},
	"config.read":            {Description: "Read a configuration file", RequiresContainer: false},
	"config.write":           {Description: "Write a configuration file (auto-backup)", RequiresContainer: false},
	"config.backup":          {Description: "Create a backup of a configuration file", RequiresContainer: false},
	"config.backups":         {Description: "List backups of a configuration file", RequiresContainer: false},
	"config.restore":         {Description: "Restore a configuration file from backup", RequiresContainer: false},
	"config.upgrade":         {Description: "Download and apply new Klever configs during upgrade", RequiresContainer: false},
	"config.preview":         {Description: "Compare current configs with the new Klever download (read-only)", RequiresContainer: false},
	"config.version-backups": {Description: "List version-labeled config backups", RequiresContainer: false},
	"config.version-restore": {Description: "Restore config from a version backup", RequiresContainer: false},
	"node.logs":              {Description: "Fetch historical logs from a container", RequiresContainer: true},
	"key.info":               {Description: "Get validator key info", RequiresContainer: false},
	"key.generate":           {Description: "Generate a new BLS key pair", RequiresContainer: false},
	"key.import":             {Description: "Import a validator key", RequiresContainer: false},
	"key.export":             {Description: "Export a validator key", RequiresContainer: false},
	"key.backup":             {Description: "Backup the validator key", RequiresContainer: false},
	"key.backups":            {Description: "List validator key backups", RequiresContainer: false},
	"agent.update":           {Description: "Update agent binary", RequiresContainer: false},
	"agent.restart":          {Description: "Restart the agent process", RequiresContainer: false},
	"server.benchmark":       {Description: "Run server hardware benchmark", RequiresContainer: false},
}

AllowedCommands defines the set of commands the agent will execute.

Functions

func BackupConfigFile

func BackupConfigFile(dataDir, fileName string) error

BackupConfigFile creates a timestamped backup of a configuration file.

func BackupKey

func BackupKey(dataDir string) error

BackupKey creates a timestamped backup of the validator key.

func BuildResultMessage

func BuildResultMessage(result *models.CommandResult) *models.Message

BuildResultMessage wraps a CommandResult in a Message envelope.

func DetectPublicIP

func DetectPublicIP(ctx context.Context) string

DetectPublicIP queries external services to determine the agent's public IP. Returns empty string on failure (graceful degradation).

func EnsureDataDirs

func EnsureDataDirs(dataDir string) error

EnsureDataDirs creates the required data directory structure.

func ExportKey

func ExportKey(dataDir string) (string, error)

ExportKey reads and returns the validator key PEM content.

func ExtractBLSPublicKey

func ExtractBLSPublicKey(configDir string) (string, error)

ExtractBLSPublicKey reads a validatorKey.pem from the config directory and extracts the BLS public key (hex-encoded).

The PEM file contains the private key in a custom format used by Klever. The public key is extracted from the last 96 bytes of the decoded key data (BLS12-381 public key = 96 bytes).

func FindAvailablePort

func FindAvailablePort(startPort int) int

FindAvailablePort finds the next available port starting from startPort.

func IsPortAvailable

func IsPortAvailable(port int) bool

IsPortAvailable checks if a TCP port is available on the host. "Available" here means nothing is currently accepting connections on it.

The bounded dial timeout matters: a firewalled black-hole port (SYN silently dropped, no RST) would block indefinitely without it, and provisioning's FindAvailablePort calls this in a 100-port loop.

func ReadConfigFile

func ReadConfigFile(dataDir, fileName string) (string, error)

ReadConfigFile reads a configuration file's contents.

func RemoveDataDirectory

func RemoveDataDirectory(dataDir string) error

RemoveDataDirectory removes the data directory for a node. Requires explicit confirmation to prevent accidental data loss.

func ResetDBFastBootstrap added in v0.3.85

func ResetDBFastBootstrap(ctx context.Context, docker *DockerClient, req *models.ResetDBRequest, onProgress DBResetProgressFunc) error

ResetDBFastBootstrap deletes a node's local chain DB and restarts it with --start-in-epoch so it re-bootstraps from the latest epoch. This is the deliberate opposite of RestoreDB (which downloads the full-history snapshot): here we throw the local DB away and let the node fetch a fresh, epoch-aligned state on its own. It is for operators who do NOT need archival history.

Only the db/ subtree is removed — config/, keys and validatorKey.pem are left untouched. The empty db/ is recreated with the container user's ownership (999:999) so the validator process can write into it; if the directory were left for Docker to create it would be owned by root and the node could not write to it.

func RestoreConfigBackup

func RestoreConfigBackup(dataDir, backupName string) error

RestoreConfigBackup restores a config file from a backup.

func RestoreConfigVersion

func RestoreConfigVersion(dataDir, backupName string) error

RestoreConfigVersion restores all config files from a version backup.

func RestoreDB added in v0.3.78

func RestoreDB(ctx context.Context, docker *DockerClient, req *models.RestoreDBRequest, onProgress DBRestoreProgressFunc) error

RestoreDB replaces a node's chain DB with the official Klever FullNode snapshot. Flow: preflight disk check -> stop node -> rotate old db aside (or delete if space is tight) -> stream-download + extract only the db/ entries -> fix permissions -> start node. On failure before the new DB is in place, the old DB is rolled back.

It streams the archive straight through gzip+tar (never staging the tens of GB on disk) and only extracts entries under db/, so a stray config/ in the archive can't clobber the node's existing configuration.

func RollbackBinary

func RollbackBinary(backupPath string) error

RollbackBinary restores the previous agent binary from backup.

func SHA256Hex

func SHA256Hex(data []byte) string

SHA256Hex computes the SHA-256 hex digest of data.

func ValidateCommand

func ValidateCommand(action string, containerName string) error

ValidateCommand checks if a command action is allowed and parameters are valid. Returns an error describing why the command was rejected, or nil if valid.

func WriteConfigFile

func WriteConfigFile(dataDir, fileName, content string) error

WriteConfigFile writes content to a configuration file, creating a backup first.

Types

type Agent

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

Agent is the main agent process.

func New

func New(configDir string) *Agent

New creates a new Agent with the given config directory.

func (*Agent) BuildAgentInfo

func (a *Agent) BuildAgentInfo(publicIP string) *models.AgentInfo

BuildAgentInfo creates the agent.info payload.

func (*Agent) BuildDiscoveryMessage

func (a *Agent) BuildDiscoveryMessage(report *models.DiscoveryReport) *models.Message

BuildDiscoveryMessage creates a discovery report message.

func (*Agent) BuildInfoMessage

func (a *Agent) BuildInfoMessage(publicIP string) *models.Message

BuildInfoMessage creates a complete agent.info message.

func (*Agent) Config

func (a *Agent) Config() *Config

Config returns the agent's current configuration.

func (*Agent) IsRegistered

func (a *Agent) IsRegistered() bool

IsRegistered returns true if the agent has a stored certificate.

func (*Agent) LoadConfig

func (a *Agent) LoadConfig() error

LoadConfig loads the agent configuration from disk.

func (*Agent) Register

func (a *Agent) Register(dashboardURL, token string) error

Register performs initial registration with the dashboard.

func (*Agent) RunDiscovery

func (a *Agent) RunDiscovery(dockerSocket string) *models.DiscoveryReport

RunDiscovery scans the server for Klever nodes and returns a discovery report.

func (*Agent) SaveConfig

func (a *Agent) SaveConfig() error

SaveConfig saves the agent configuration to disk.

func (*Agent) TLSConfig

func (a *Agent) TLSConfig() (*tls.Config, error)

TLSConfig builds a tls.Config using the agent's mTLS credentials. The returned config trusts the dashboard CA and presents the agent's client certificate, AND verifies the dashboard's server certificate against the CA the agent stored at registration time.

The CA we already load was previously ignored: InsecureSkipVerify was set to true on the assumption that mTLS alone was sufficient. It is not — mTLS only ensures the dashboard authenticates the agent, not the reverse. Without verifying the dashboard's cert against the stored CA, an attacker who has stolen any client cert can intercept the connection.

ServerName is pinned to "localhost" because crypto.DashboardTLSConfig issues the dashboard's server certificate with DNSNames: ["localhost"] regardless of the host/IP the agent dials. The cert is still signed by the trusted CA, so verifying against that SAN proves authenticity.

type BenchmarkProgress added in v0.3.54

type BenchmarkProgress func(step, total int, status string)

BenchmarkProgress is called during benchmark execution to report progress.

type BenchmarkResult added in v0.3.49

type BenchmarkResult struct {
	Timestamp int64              `json:"timestamp"`
	Score     int                `json:"score"`     // 0-1000
	MaxScore  int                `json:"max_score"` // 1000
	Grade     string             `json:"grade"`     // "A", "B", "C", etc.
	Verdict   string             `json:"verdict"`   // "Excellent — production-ready..."
	Sections  []BenchmarkSection `json:"sections"`
	RawOutput string             `json:"raw_output"`
}

BenchmarkResult holds the parsed results of a server hardware benchmark.

type BenchmarkSection added in v0.3.51

type BenchmarkSection struct {
	Name     string  `json:"name"`      // "GOROUTINE SCALABILITY", "DISK I/O", etc.
	Status   string  `json:"status"`    // "PASS", "WARN", "FAIL"
	Score    int     `json:"score"`     // section score
	MaxScore int     `json:"max_score"` // section max
	Percent  float64 `json:"percent"`   // score percentage
}

BenchmarkSection is one category in the benchmark report.

type CommandSpec

type CommandSpec struct {
	Description       string
	RequiresContainer bool
}

CommandSpec defines constraints for a whitelisted command.

type Config

type Config struct {
	ServerID     string `json:"server_id"`
	DashboardURL string `json:"dashboard_url"`
	CertPEM      string `json:"cert_pem"`
	KeyPEM       string `json:"key_pem"`
	CACertPEM    string `json:"ca_cert_pem"`
	AgentPort    int    `json:"agent_port,omitempty"`
}

Config holds the agent's persistent configuration.

type ConfigDiffItem added in v0.3.88

type ConfigDiffItem struct {
	ID   string `json:"id"` // "<file>::<key>", stable between preview and upgrade
	File string `json:"file"`
	Key  string `json:"key"`
	Kind string `json:"kind"`
	Mine string `json:"mine"`
	New  string `json:"new"`
}

ConfigDiffItem is one difference between the node's current config and the freshly downloaded one that the operator can decide on.

type ConfigFile

type ConfigFile struct {
	Name     string `json:"name"`
	Path     string `json:"path"`
	Size     int64  `json:"size"`
	Modified int64  `json:"modified"` // Unix timestamp
}

ConfigFile represents a configuration file's metadata.

func ListConfigBackups

func ListConfigBackups(dataDir, fileName string) ([]ConfigFile, error)

ListConfigBackups lists backup files for a specific config file.

func ListConfigFiles

func ListConfigFiles(dataDir string) ([]ConfigFile, error)

ListConfigFiles lists configuration files in a node's config directory.

func ListKeyBackups

func ListKeyBackups(dataDir string) ([]ConfigFile, error)

ListKeyBackups lists backup key files.

type ConfigPreview added in v0.3.88

type ConfigPreview struct {
	Items          []ConfigDiffItem `json:"items"`
	AddedByFile    map[string]int   `json:"added_by_file,omitempty"`
	DownloadSource string           `json:"download_source"`
}

ConfigPreview is the result of comparing current configs with the new download.

func PreviewConfigUpgrade added in v0.3.88

func PreviewConfigUpgrade(ctx context.Context, dataDir, network string) (*ConfigPreview, error)

PreviewConfigUpgrade downloads the new configs and compares them with the node's current ones without touching anything, so the operator can decide which local values to keep before UpgradeConfigs runs.

type ConfigUpgradeResult

type ConfigUpgradeResult struct {
	BackupDir      string   `json:"backup_dir"`
	BackupVersion  string   `json:"backup_version"`
	ReplacedFiles  []string `json:"replaced_files"`
	MergedFiles    []string `json:"merged_files"`
	SkippedFiles   []string `json:"skipped_files,omitempty"`
	DownloadSource string   `json:"download_source"` // "primary" or "fallback"
	// KeptValues lists the operator's local values written back over the new
	// defaults; UnappliedKeeps lists requested ones that no longer matched.
	KeptValues     []string `json:"kept_values,omitempty"`
	UnappliedKeeps []string `json:"unapplied_keeps,omitempty"`
}

ConfigUpgradeResult describes what happened during a config upgrade.

func UpgradeConfigs

func UpgradeConfigs(ctx context.Context, dataDir, network, versionLabel string, keep []string) (*ConfigUpgradeResult, error)

UpgradeConfigs downloads new config files and replaces system configs while preserving user-specific values in config.toml.

Steps:

  1. Backup all current configs into a version-labeled directory
  2. Download new configs (primary: Klever backup server, fallback: GitHub)
  3. Replace system configs (yaml, json) with the download, writing back the local values the operator chose to keep (ids from PreviewConfigUpgrade)
  4. Merge config.toml: new defaults + preserved user values

type ConfigVersionBackup

type ConfigVersionBackup struct {
	Name      string `json:"name"`
	CreatedAt int64  `json:"created_at"`
	FileCount int    `json:"file_count"`
}

ConfigVersionBackup represents a version-labeled config backup directory.

func ListConfigVersionBackups

func ListConfigVersionBackups(dataDir string) ([]ConfigVersionBackup, error)

ListConfigVersionBackups lists all version-labeled config backups.

type ContainerConfig

type ContainerConfig struct {
	Name            string `json:"name"`             // Container name, e.g. "klever-node1"
	ImageTag        string `json:"image_tag"`        // e.g. "v0.60.0" or "latest"
	DataDir         string `json:"data_dir"`         // Host data directory
	RestAPIPort     int    `json:"rest_api_port"`    // REST API port
	DisplayName     string `json:"display_name"`     // Node display name
	RedundancyLevel int    `json:"redundancy_level"` // 0 = active, 1 = fallback
	StartInEpoch    bool   `json:"start_in_epoch"`   // add --start-in-epoch (fast bootstrap)
}

ContainerConfig defines parameters for creating a Klever node container.

type DBResetProgressFunc added in v0.3.85

type DBResetProgressFunc func(*models.DBResetProgress)

DBResetProgressFunc receives status updates during a fast-reset.

type DBRestoreProgressFunc added in v0.3.78

type DBRestoreProgressFunc func(p *models.DBRestoreProgress)

DBRestoreProgressFunc receives progress updates during a restore.

type DiscoveredNode

type DiscoveredNode struct {
	ContainerID     string  `json:"container_id"`
	ContainerName   string  `json:"container_name"`
	Status          string  `json:"status"` // "running" or "stopped"
	RestAPIPort     int     `json:"rest_api_port"`
	DisplayName     string  `json:"display_name,omitempty"`
	RedundancyLevel int     `json:"redundancy_level"`
	DockerImageTag  string  `json:"docker_image_tag,omitempty"`
	DataDirectory   string  `json:"data_directory,omitempty"`
	ConfigDirectory string  `json:"config_directory,omitempty"`
	BLSPublicKey    string  `json:"bls_public_key,omitempty"`
	CPUPercent      float64 `json:"cpu_percent"`
	MemUsed         uint64  `json:"mem_used"`
	MemLimit        uint64  `json:"mem_limit"`
	MemPercent      float64 `json:"mem_percent"`
}

DiscoveredNode holds the information extracted from a running Klever container.

type DockerClient

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

DockerClient talks to the Docker Engine API via Unix socket.

func NewDockerClient

func NewDockerClient(socketPath string) *DockerClient

NewDockerClient creates a client connected to the Docker socket.

func (*DockerClient) CreateContainer

func (d *DockerClient) CreateContainer(ctx context.Context, cfg *ContainerConfig) (string, error)

CreateContainer creates a new Klever node container.

func (*DockerClient) DiscoverNodes

func (d *DockerClient) DiscoverNodes(ctx context.Context) ([]DiscoveredNode, error)

DiscoverNodes scans Docker for all Klever containers and extracts their configuration.

func (*DockerClient) FetchLogs

func (d *DockerClient) FetchLogs(ctx context.Context, containerName string, tail int, since int64) ([]LogLine, error)

FetchLogs retrieves historical logs from a container.

func (*DockerClient) GenerateKey

func (d *DockerClient) GenerateKey(ctx context.Context, dataDir, imageTag string) (*KeyInfo, error)

GenerateKey runs the klever-go keygenerator to create a new BLS key pair.

func (*DockerClient) GetContainerStatus

func (d *DockerClient) GetContainerStatus(ctx context.Context, containerName string) (string, error)

GetContainerStatus returns the current status of a container ("running", "exited", etc.).

func (*DockerClient) InspectContainer

func (d *DockerClient) InspectContainer(ctx context.Context, containerID string) (*containerJSON, error)

InspectContainer returns detailed information about a container.

func (*DockerClient) ListKleverContainers

func (d *DockerClient) ListKleverContainers(ctx context.Context) ([]string, error)

ListKleverContainers returns IDs of all containers using the klever-go image. We list ALL containers and filter by image name ourselves, because Docker's "ancestor" filter matches by image ID which can miss containers created from a different pull/digest of the same image name. When Docker returns a sha256 digest instead of the image name (happens when the original tag is removed after pulling a newer version), we fall back to inspecting the container to read Config.Image which always preserves the original name.

func (*DockerClient) ListKleverImages added in v0.3.79

func (d *DockerClient) ListKleverImages(ctx context.Context) ([]ImageInfo, error)

ListKleverImages returns detailed info for every local kleverapp/klever-go image, flagging which ones are still referenced by a container so the dashboard can block their deletion.

func (*DockerClient) ListLocalImages

func (d *DockerClient) ListLocalImages(ctx context.Context) ([]string, error)

ListLocalImages returns images matching the klever-go image.

func (*DockerClient) PullImage

func (d *DockerClient) PullImage(ctx context.Context, image string) error

PullImage pulls a Docker image from the registry.

func (*DockerClient) PullImageWithProgress

func (d *DockerClient) PullImageWithProgress(ctx context.Context, image string, onProgress func(status string)) error

PullImageWithProgress pulls a Docker image and streams progress updates.

func (*DockerClient) RecreateWithStartInEpoch added in v0.3.85

func (d *DockerClient) RecreateWithStartInEpoch(ctx context.Context, containerName string) error

RecreateWithStartInEpoch recreates a container with the same config but with --start-in-epoch added. Used by the fast-reset flow: after the local chain DB is deleted, the node must fast-bootstrap from the latest epoch rather than try to resume from an empty DB. Docker only applies command args at create time, so a plain restart would keep whatever flag the container was created with — hence the recreate.

func (*DockerClient) RecreateWithoutStartInEpoch added in v0.3.79

func (d *DockerClient) RecreateWithoutStartInEpoch(ctx context.Context, containerName string) error

RecreateWithoutStartInEpoch recreates a container with the same config but with --start-in-epoch removed. Used after a full-DB restore: the node must resume from the restored DB's height and sync forward block-by-block, NOT fast-bootstrap to the latest epoch (which leaves a gap between the snapshot and now). Docker only applies command args at create time, so a plain restart would keep the original --start-in-epoch flag — hence the recreate.

func (*DockerClient) RemoveContainer

func (d *DockerClient) RemoveContainer(ctx context.Context, containerName string, force bool) error

RemoveContainer stops and removes a container.

func (*DockerClient) RemoveImage added in v0.3.79

func (d *DockerClient) RemoveImage(ctx context.Context, imageID string) error

RemoveImage deletes a single image by ID. noprune is left at Docker's default (false) so untagged parent layers freed by the delete are also reclaimed.

func (*DockerClient) RestartContainer

func (d *DockerClient) RestartContainer(ctx context.Context, containerName string, timeoutSec int) error

RestartContainer restarts a container with a graceful timeout.

func (*DockerClient) RunBenchmark added in v0.3.49

func (d *DockerClient) RunBenchmark(ctx context.Context, onProgress BenchmarkProgress) (*BenchmarkResult, error)

RunBenchmark runs the klever-go benchmark tool in a one-shot Docker container.

func (*DockerClient) StartContainer

func (d *DockerClient) StartContainer(ctx context.Context, containerName string) error

StartContainer starts a stopped container.

func (*DockerClient) StopContainer

func (d *DockerClient) StopContainer(ctx context.Context, containerName string, timeoutSec int) error

StopContainer stops a running container with a graceful timeout.

func (*DockerClient) StreamLogs

func (d *DockerClient) StreamLogs(ctx context.Context, containerName string, since int64, onLine func(LogLine)) error

StreamLogs streams live logs from a container, calling onLine for each new line. It blocks until the context is cancelled or the stream ends.

func (*DockerClient) UpgradeContainer

func (d *DockerClient) UpgradeContainer(ctx context.Context, containerName, newTag string) (string, error)

UpgradeContainer upgrades a container to a new image tag. 1. Inspect current container for config 2. Pull new image 3. Stop and remove old container 4. Create new container with same config + new tag 5. Start new container

func (*DockerClient) UpgradeContainerWithRollback

func (d *DockerClient) UpgradeContainerWithRollback(ctx context.Context, containerName, newTag string, onProgress ...UpgradeProgress) (string, error)

UpgradeContainerWithRollback upgrades a container and rolls back on failure. It verifies the new container is running after startup, and if not, recreates the container with the original image tag. The optional onProgress callback reports each step.

type Executor

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

Executor handles incoming commands from the dashboard.

func NewExecutor

func NewExecutor(dockerSocket string) *Executor

NewExecutor creates a new command executor.

func NewExecutorWithClient

func NewExecutorWithClient(client *DockerClient) *Executor

NewExecutorWithClient creates an executor with a specific Docker client (for testing).

func (*Executor) Execute

func (e *Executor) Execute(msg *models.Message, onProgress ProgressFunc) *models.CommandResult

Execute processes a command message and returns a result.

onProgress is per-call rather than an Executor field so that concurrent command goroutines don't race when assigning a new callback — each execution carries its own.

func (*Executor) SetUpdateSource added in v0.3.87

func (e *Executor) SetUpdateSource(dashboardURL string, tlsConfig *tls.Config)

SetUpdateSource configures where and how the agent fetches its update binary over HTTP, used when the dashboard sends a download_path instead of inline base64 data. tlsConfig is the same client config used for the WebSocket, so the HTTP download trusts the dashboard exactly the same way. If this is never called (e.g. in tests), the agent falls back to the base64 payload.

type ImageInfo added in v0.3.79

type ImageInfo struct {
	ID       string   `json:"id"`        // full image ID (e.g. "sha256:abc...")
	RepoTags []string `json:"repo_tags"` // e.g. ["kleverapp/klever-go:v1.2.3"]
	Created  int64    `json:"created"`   // creation time, unix seconds
	Size     int64    `json:"size"`      // size on disk, bytes
	InUse    bool     `json:"in_use"`    // referenced by an existing container
	UsedBy   []string `json:"used_by,omitempty"`
}

ImageInfo describes a local Docker image for the cleanup view.

type KeyInfo

type KeyInfo struct {
	BLSPublicKey string `json:"bls_public_key"`
	KeyFile      string `json:"key_file"`
	FileSize     int64  `json:"file_size"`
	Modified     int64  `json:"modified"`
	HasBackup    bool   `json:"has_backup"`
}

KeyInfo represents information about a validator key.

func GetKeyInfo

func GetKeyInfo(dataDir string) (*KeyInfo, error)

GetKeyInfo returns information about the validator key for a node.

func ImportKey

func ImportKey(dataDir, pemContent string) (*KeyInfo, error)

ImportKey imports a validator key from PEM content, backing up any existing key.

type LogLine

type LogLine struct {
	Timestamp string `json:"timestamp,omitempty"`
	Stream    string `json:"stream"` // "stdout" or "stderr"
	Message   string `json:"message"`
}

LogLine represents a single log line from a container.

type LogStreamManager

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

LogStreamManager manages active log streams for containers.

The streams map is touched from at least three goroutines (the caller of StartStream/StopStream, the per-stream worker that removes itself when the stream ends, and any caller of StopAll/ActiveStreams). All access goes through mu — concurrent map writes panic at runtime, so the lock is correctness, not optimization.

func NewLogStreamManager

func NewLogStreamManager(docker *DockerClient) *LogStreamManager

NewLogStreamManager creates a new log stream manager.

func (*LogStreamManager) ActiveStreams

func (m *LogStreamManager) ActiveStreams() int

ActiveStreams returns the number of active streams.

func (*LogStreamManager) StartStream

func (m *LogStreamManager) StartStream(containerName string, onLine func(LogLine)) error

StartStream starts streaming logs for a container. Only one stream per container is allowed.

func (*LogStreamManager) StopAll

func (m *LogStreamManager) StopAll()

StopAll stops all active log streams.

func (*LogStreamManager) StopStream

func (m *LogStreamManager) StopStream(containerName string)

StopStream stops streaming logs for a container.

type MetricsCollector

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

MetricsCollector collects system-level metrics from the host.

func NewMetricsCollector

func NewMetricsCollector(diskPaths []string) *MetricsCollector

NewMetricsCollector creates a new metrics collector. diskPaths specifies which filesystem paths to monitor for disk usage.

func (*MetricsCollector) Collect

func (mc *MetricsCollector) Collect() *models.SystemMetrics

Collect gathers current system metrics.

type NodeMetricsCollector

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

NodeMetricsCollector polls /node/status for each discovered Klever node.

func NewNodeMetricsCollector

func NewNodeMetricsCollector(opts ...NodeMetricsCollectorOption) *NodeMetricsCollector

NewNodeMetricsCollector creates a new collector for Klever node metrics.

func (*NodeMetricsCollector) CollectAll

CollectAll polls all registered nodes and returns metrics events plus any stall alerts. Polling is parallel — a single unreachable node would otherwise block the whole cycle for defaultNodePollTimeout. With N nodes down, the previous serial loop took N * 5 s before the writer could send any of the partial results.

func (*NodeMetricsCollector) CollectOne

func (c *NodeMetricsCollector) CollectOne(nodeID, serverID string) (*models.NodeMetricsEvent, error)

CollectOne polls a single node and returns its metrics event.

func (*NodeMetricsCollector) PollInterval

func (c *NodeMetricsCollector) PollInterval() time.Duration

PollInterval returns the configured polling interval.

func (*NodeMetricsCollector) RunPoller

func (c *NodeMetricsCollector) RunPoller(ctx context.Context, serverID string, metricsCh chan<- *models.Message, stallCh chan<- *models.Message)

RunPoller starts a background goroutine that polls all nodes at the configured interval. It sends metrics and stall events to the provided channels. The goroutine stops when ctx is canceled.

func (*NodeMetricsCollector) UpdateNodes

func (c *NodeMetricsCollector) UpdateNodes(report *models.DiscoveryReport)

UpdateNodes updates the set of nodes to poll from a discovery report.

type NodeMetricsCollectorOption

type NodeMetricsCollectorOption func(*NodeMetricsCollector)

NodeMetricsCollectorOption configures the NodeMetricsCollector.

func WithHTTPClient

func WithHTTPClient(client *http.Client) NodeMetricsCollectorOption

WithHTTPClient sets a custom HTTP client (useful for testing).

func WithPollInterval

func WithPollInterval(d time.Duration) NodeMetricsCollectorOption

WithPollInterval sets the polling interval.

func WithStallTimeout

func WithStallTimeout(d time.Duration) NodeMetricsCollectorOption

WithStallTimeout sets the nonce stall detection timeout.

type ProgressFunc added in v0.3.54

type ProgressFunc func(action string, payload map[string]any)

ProgressFunc is called to send progress events during long-running commands.

type ProvisionStep

type ProvisionStep struct {
	Name string
	Fn   func(p *Provisioner, ctx context.Context) error
}

ProvisionStep represents a single provisioning step.

type Provisioner

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

Provisioner handles the multi-step node provisioning workflow.

func NewProvisioner

func NewProvisioner(docker *DockerClient, req *models.ProvisionRequest, jobID string, progressFn func(*models.ProvisionProgress)) *Provisioner

NewProvisioner creates a new provisioner for a given request.

func (*Provisioner) Run

func (p *Provisioner) Run(ctx context.Context) error

Run executes all provisioning steps in sequence. On failure, it attempts cleanup and reports which step failed.

type UpdateResult

type UpdateResult struct {
	OldVersion   string `json:"old_version"`
	NewVersion   string `json:"new_version"`
	BackupPath   string `json:"backup_path"`
	NeedsRestart bool   `json:"needs_restart"`
}

UpdateResult holds the result of an agent binary update.

func VerifyAndReplaceBinary

func VerifyAndReplaceBinary(binaryData []byte, expectedChecksum string, agentConfigDir string) (*UpdateResult, error)

VerifyAndReplaceBinary verifies the checksum of new binary data and replaces the current agent binary. Keeps a backup of the previous version for rollback.

type UpgradeProgress

type UpgradeProgress func(step int, totalSteps int, stepName string, status string)

UpgradeProgress is a callback for reporting upgrade step progress.

Jump to

Keyboard shortcuts

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