daemon

package
v0.24.0 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultDaemonConfigPath = "/opt/solo/weaver/config/daemon.yaml"

	// CurrentSchemaVersion is the schema version written by this build.
	// Increment this constant whenever a breaking structural change is made to
	// DaemonConfig so that LoadDaemonConfig can detect and migrate old files.
	CurrentSchemaVersion = 1

	// DefaultStatuszPollInterval is the steady-state cadence at which the
	// traffic-shaper monitor polls statusz when statusz.poll_interval is unset.
	// The design specifies a 5-second poll loop.
	DefaultStatuszPollInterval = 5 * time.Second
)

Variables

View Source
var (
	ErrNamespace = errorx.NewNamespace("daemon")

	// ErrConfig is the base type for daemon configuration errors.
	ErrConfig = ErrNamespace.NewType("config")

	// ErrConfigNotFound is returned when daemon.yaml does not exist at the expected path.
	ErrConfigNotFound = ErrConfig.NewSubtype("not_found", errorx.NotFound())

	// ErrConfigMalformed is returned when daemon.yaml exists but cannot be parsed or has missing required fields.
	ErrConfigMalformed = ErrConfig.NewSubtype("malformed")
)

Functions

func IsConfigMalformed

func IsConfigMalformed(err error) bool

IsConfigMalformed reports whether err is (or wraps) an ErrConfigMalformed error.

func IsConfigNotFound

func IsConfigNotFound(err error) bool

IsConfigNotFound reports whether err is (or wraps) an ErrConfigNotFound error.

func WriteDaemonConfig

func WriteDaemonConfig(path string, cfg DaemonConfig) error

WriteDaemonConfig serialises cfg to YAML and writes it to path, creating any missing parent directories. It stamps SchemaVersion = CurrentSchemaVersion before writing. Callers should call cfg.Validate() before writing.

Types

type BlockNodeComponentConfig

type BlockNodeComponentConfig struct {
	// Enabled controls whether this component and its monitors are started.
	Enabled bool `yaml:"enabled"`

	// Kubeconfig is the path to the scoped kubeconfig for this component's SA.
	// Written by solo-provisioner during daemon install.
	Kubeconfig string `yaml:"kubeconfig"`

	// Orbit is the Kubernetes namespace where block-node CRs are watched.
	Orbit string `yaml:"orbit"`

	Monitors BlockNodeMonitors `yaml:"monitors"`

	// Statusz is the optional local-fallback statusz source for the
	// traffic-shaper poll loop. When nil or with an empty BaseURL, the monitor
	// has no statusz source to poll (BN-pod statusz discovery is a future story)
	// and the poll loop idles. When set, the monitor polls that fixed REST
	// endpoint — a mock statusz server in dev/test, or a directly reachable BN
	// statusz.
	Statusz *StatuszConfig `yaml:"statusz,omitempty"`
}

BlockNodeComponentConfig is the configuration block for the block-node component. It carries its own kubeconfig so its RBAC is independent of the consensus-node.

func (BlockNodeComponentConfig) Validate

func (bn BlockNodeComponentConfig) Validate() error

Validate checks that all required fields within the block-node block are present.

type BlockNodeMonitors

type BlockNodeMonitors struct {
	TrafficShaper bool `yaml:"traffic_shaper"`
}

BlockNodeMonitors toggles individual monitors for the block-node component.

type ComponentStatus

type ComponentStatus struct {
	Monitors map[string]daemonkit.MonitorState `json:"monitors"`
}

ComponentStatus holds the per-monitor states for one component.

type ConsensusNodeComponentConfig

type ConsensusNodeComponentConfig struct {
	// Enabled controls whether this component and its monitors are started.
	Enabled bool `yaml:"enabled"`

	// Kubeconfig is the path to the scoped kubeconfig for this component's SA.
	// Written by solo-provisioner during daemon install (WriteConsensusNodeKubeconfigStep).
	Kubeconfig string `yaml:"kubeconfig"`

	// NodeID is the numeric node identifier (e.g. "0", "1", "2"). Used as nodeId in
	// all JSONL event log entries.
	NodeID string `yaml:"node_id"`

	// Orbit is the Kubernetes namespace where NetworkUpgradeExecute CRs are watched.
	Orbit string `yaml:"orbit"`

	// UpgradeDir is the path to the CN's upgrade staging directory.
	// Defaults to /opt/hgcapp/services-hedera/HapiApp2.0/data/upgrade/current.
	UpgradeDir string `yaml:"upgrade_dir,omitempty"`

	Monitors ConsensusNodeMonitors `yaml:"monitors"`
}

ConsensusNodeComponentConfig is the configuration block for the consensus-node component. It carries its own kubeconfig so its RBAC is independent of any future block-node or host-only component.

func (ConsensusNodeComponentConfig) EffectiveUpgradeDir

func (cn ConsensusNodeComponentConfig) EffectiveUpgradeDir() string

EffectiveUpgradeDir returns UpgradeDir if set, otherwise the CN default path.

func (ConsensusNodeComponentConfig) Validate

func (cn ConsensusNodeComponentConfig) Validate() error

Validate checks that all required fields within the consensus-node block are present.

type ConsensusNodeMonitors

type ConsensusNodeMonitors struct {
	Upgrade   bool `yaml:"upgrade"`
	Migration bool `yaml:"migration"`
}

ConsensusNodeMonitors toggles individual monitors for the consensus-node component.

type Daemon

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

Daemon is the controller for solo-provisioner-daemon. It composes the sub-systems and owns their lifecycle via Run.

Goroutine map:

  • Socket server — always on; HTTP control plane on daemon.sock
  • componentSupervisor — one supervised goroutine per enabled monitor; crashes are absorbed per-monitor with exponential back-off (#662/#663)
  • runComponentProbes — background loop; retries disk probes until all prerequisites are satisfied; results visible via GET /status

func New

func New(paths models.WeaverPaths) (*Daemon, error)

New constructs a Daemon from WeaverPaths. It reads daemon.yaml from paths.DaemonConfigPath and fails fast if the config is missing or invalid.

func NewFromConfig

func NewFromConfig(paths models.WeaverPaths, cfg DaemonConfig) (*Daemon, error)

NewFromConfig constructs a Daemon from a pre-resolved DaemonConfig. Components are skipped when their Enabled flag is false. Individual monitors within a component are skipped when their toggle is false.

func (*Daemon) Run

func (d *Daemon) Run(ctx context.Context) error

Run starts all sub-systems and blocks until ctx is cancelled or a critical sub-system exits with an error.

type DaemonComponents

type DaemonComponents struct {
	ConsensusNode *ConsensusNodeComponentConfig `yaml:"consensus_node,omitempty"`
	BlockNode     *BlockNodeComponentConfig     `yaml:"block_node,omitempty"`
}

DaemonComponents holds the per-component configuration blocks.

type DaemonConfig

type DaemonConfig struct {
	// SchemaVersion identifies the config file format. Always written as
	// CurrentSchemaVersion by WriteDaemonConfig. A value of 0 means the file
	// predates schema versioning and is treated as version 1 for compatibility.
	SchemaVersion int `yaml:"schemaVersion"`

	Components DaemonComponents `yaml:"components"`
}

DaemonConfig is parsed from daemon.yaml at startup.

Example daemon.yaml:

schemaVersion: 1
components:
  consensus_node:
    enabled: true
    kubeconfig: /opt/solo/weaver/config/daemon-cn.kubeconfig
    node_id: 0
    orbit: hedera-network
    upgrade_dir: /opt/hgcapp/services-hedera/HapiApp2.0/data/upgrade/current
    monitors:
      upgrade: true
      migration: true
  block_node:
    enabled: true
    kubeconfig: /opt/solo/weaver/config/daemon-bn.kubeconfig
    orbit: hedera-block-node
    monitors:
      traffic_shaper: true
    statusz:                     # optional local-fallback statusz source
      base_url: http://127.0.0.1:8080
      poll_interval: 5s

func LoadDaemonConfig

func LoadDaemonConfig(path string) (DaemonConfig, error)

LoadDaemonConfig reads and parses the daemon config file at path. Returns an error if the file is missing or malformed — the daemon must not start without a valid config. CLI flag overrides are applied after this call in cmd/daemon/main.go; call Validate() again after overrides are applied.

Loading uses a two-phase approach:

  1. Probe: unmarshal only schemaVersion to determine the on-disk format.
  2. Parse + migrate: unmarshal into the versioned struct for that version, then walk the migration chain (vN.migrateToLatest()) to produce the current DaemonConfig. Each step in the chain is a pure field transform that knows only about one version transition.

Version rules:

  • 0 (absent): pre-versioning file; treated as version 1.
  • 1..CurrentSchemaVersion: accepted; migrated to current if needed.
  • > CurrentSchemaVersion: rejected — written by a newer binary.

func ParseDaemonConfig added in v0.24.0

func ParseDaemonConfig(data []byte, source string) (DaemonConfig, error)

ParseDaemonConfig parses daemon config bytes that have already been read from source (a path, used only in error messages). It is the file-read-free core of LoadDaemonConfig: callers that have already captured the raw bytes — e.g. an install step that snapshots daemon.yaml for rollback — parse from those exact bytes so the parsed config and the snapshot can never diverge across a second read. It applies the same two-phase probe + migration + Validate as LoadDaemonConfig (see that function's doc for version rules).

func (DaemonConfig) Validate

func (c DaemonConfig) Validate() error

Validate checks that the config is structurally valid. Called by LoadDaemonConfig and by cmd/daemon/main.go after applying CLI flag overrides. At least one component (consensus_node or block_node) must be present.

type ErrorResponse

type ErrorResponse struct {
	Error string `json:"error"`
}

ErrorResponse is the standard JSON error envelope returned on 4xx/5xx.

type HealthResponse

type HealthResponse struct {
	Status string `json:"status"`
}

HealthResponse is returned by GET /health.

type StatusResponse

type StatusResponse struct {
	Components map[string]ComponentStatus `json:"components"`
	// ProbeErrors maps component name → rich error descriptor for any component
	// whose disk prerequisites are not yet satisfied. Empty when all probes pass.
	// Each entry includes a Reason code, the error Message, an operator-actionable
	// Resolution hint, and the Since timestamp of when the failure was first seen.
	ProbeErrors map[string]daemonkit.StatusError `json:"probe_errors,omitempty"`
}

StatusResponse is returned by GET /status. It reports the runtime state of every enabled component and their individual monitors, plus any unmet startup prerequisites detected by the background probe loop.

type StatuszConfig added in v0.24.0

type StatuszConfig struct {
	// BaseURL is the root the statusz REST endpoints resolve against, e.g.
	// http://127.0.0.1:8080. Empty means "no local-fallback source configured";
	// the poll loop then idles rather than polling.
	BaseURL string `yaml:"base_url,omitempty"`

	// PollInterval is the poll cadence in Go duration form (e.g. "5s"). Empty
	// defaults to DefaultStatuszPollInterval.
	PollInterval string `yaml:"poll_interval,omitempty"`
}

StatuszConfig is the local-fallback statusz source polled by the block-node traffic-shaper monitor. The monitor reads `statusz/inbound-clients` and `statusz/outbound-clients` relative to BaseURL and reconciles the returned roster into the live nft set membership.

func (StatuszConfig) EffectivePollInterval added in v0.24.0

func (s StatuszConfig) EffectivePollInterval() time.Duration

EffectivePollInterval returns the configured poll interval, or the 5-second default when unset. It assumes the value has already passed Validate, and falls back to the default for any residual parse failure rather than erroring.

func (StatuszConfig) Validate added in v0.24.0

func (s StatuszConfig) Validate() error

Validate checks the statusz block's fields: BaseURL, when set, must be an http(s) URL with a host, and PollInterval, when set, must be a positive Go duration.

Directories

Path Synopsis
statuszmock
Package statuszmock provides a minimal mock of a Block Node's statusz REST endpoints for daemon development and tests.
Package statuszmock provides a minimal mock of a Block Node's statusz REST endpoints for daemon development and tests.
statuszmock/cmd command
Command statuszmock runs the mock Block Node statusz REST server for daemon development and the UTM-VM traffic-shaper demo.
Command statuszmock runs the mock Block Node statusz REST server for daemon development and the UTM-VM traffic-shaper demo.
Package privexec is the daemon's privileged-exec delegation seam.
Package privexec is the daemon's privileged-exec delegation seam.
Package probes holds the Kubernetes-specific leaf probe(s) that cannot live in the lightweight pkg/daemonkit because they pull in k8s.io/client-go.
Package probes holds the Kubernetes-specific leaf probe(s) that cannot live in the lightweight pkg/daemonkit because they pull in k8s.io/client-go.

Jump to

Keyboard shortcuts

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