hub

package
v0.1.0-alpha.1 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: Apache-2.0 Imports: 41 Imported by: 0

Documentation

Overview

Package hub implements the Regulus hub: the HTTP server that serves the dashboard and, in later phases, the API and the agent connections.

Index

Constants

View Source
const (
	EventRolloutStarted  = "update_rollout_started"
	EventRolloutFinished = "update_rollout_finished"
	EventAgentUpdated    = "update_agent_updated"
	EventAgentFailed     = "update_agent_failed"
)

Audit events of the rollout.

View Source
const (
	AgentPending    = "pending"
	AgentOffered    = "offered"    // the update was sent; the server is fetching it
	AgentInstalling = "installing" // handed to the installer; waiting for it to come back
	AgentUpdated    = "updated"
	AgentFailed     = "failed"
	AgentSkipped    = "skipped" // an earlier failure stopped the rollout
)

Status of one server in a rollout.

View Source
const (
	RolloutIdle    = "idle"
	RolloutRunning = "running"
	RolloutDone    = "done"
	RolloutFailed  = "failed" // stopped by a failure
	RolloutStopped = "stopped"
)

State of a rollout.

View Source
const BuiltinAgentID = "local"

BuiltinAgentID is the id of the agent that runs inside the hub.

View Source
const ReleaseRepo = "CodexCircle/Regulus"

ReleaseRepo is the repository the hub reads releases from.

Variables

View Source
var (
	ErrAgentNotFound     = errors.New("agent is not connected")
	ErrAgentDisconnected = errors.New("agent disconnected before answering")
)

Errors returned by SendCommand.

View Source
var (
	ErrRolloutRunning = errors.New("an update of the servers is already running")
	ErrNothingToRoll  = errors.New("no connected server runs an older version than this hub")
	ErrNotRelease     = errors.New("this hub is not a release build, so it has no release to offer the servers")
)

Errors of the rollout.

View Source
var ErrAgentsOff = errors.New("remote agents are off: set agent_listen in the configuration")

ErrAgentsOff is returned when remote agents are not enabled.

Functions

func NewHandler

func NewHandler(d Deps) http.Handler

NewHandler returns the hub HTTP handler. The API (under /api/) requires a login, except for the endpoints of the auth package. The dashboard files and /healthz are public: they hold no data, and the page asks for a login before it shows anything.

Types

type AgentInfo

type AgentInfo struct {
	ID            string
	Version       string
	System        *agentv1.SystemInfo
	ConnectedAt   time.Time
	LastHeartbeat time.Time // zero until the first heartbeat
	LastMetrics   *agentv1.MetricsReport
	// ProtocolVersion is the version negotiated for the connection.
	ProtocolVersion uint32
	// Compat tells how the agent's release relates to the hub's.
	Compat update.Compat
}

AgentInfo is a snapshot of a connected agent.

type AgentSource

type AgentSource interface {
	Agents() []AgentInfo
	// StaleAfter is how long an agent may stay silent before it is reported as
	// stale.
	StaleAfter() time.Duration
	// Metrics returns the recent metrics of an agent, oldest first; known is
	// false for an agent the hub never saw.
	Metrics(agentID string) (samples []MetricsSample, known bool)
	// Subscribe returns a channel of JSON events (see events.go) and a function
	// that ends the subscription. The channel is closed if the subscriber falls
	// too far behind.
	Subscribe() (events <-chan []byte, cancel func())
}

AgentSource provides the agent data served by the HTTP API. *Hub implements it.

type Deps

type Deps struct {
	// UI holds the compiled dashboard.
	UI fs.FS
	// Agents, Layouts and Log may be nil in tests; the agent list is then empty
	// and the layout endpoints answer 404.
	Agents  AgentSource
	Layouts LayoutStore
	Log     *slog.Logger
	// Auth protects the API. A nil Auth leaves it open, which is only meant for
	// tests.
	Auth *auth.Service
	// Fleet enrolls and revokes remote agents. May be nil in tests; the
	// endpoints then answer 404.
	Fleet FleetControl
	// Updates reports and steers the updates of the hub. May be nil in tests;
	// the endpoints then answer 404.
	Updates UpdateControl
	// Rollout updates the managed servers to the version of the hub. May be nil
	// in tests; the endpoints then answer 404.
	Rollout RolloutControl
}

Deps are what the HTTP handler serves.

type Enrollment

type Enrollment struct {
	Token         string
	Name          string
	ExpiresAt     time.Time
	CAFingerprint string
	AgentPort     int
}

Enrollment is what an admin needs to add a server: the token, valid once, and what the agent must trust.

type FleetControl

type FleetControl interface {
	CreateEnrollment(ctx context.Context, by, name string) (Enrollment, error)
	RevokeAgent(ctx context.Context, by, id string) error
	RenameAgent(ctx context.Context, by, id, name string) error
}

FleetControl is what the HTTP API needs to enroll and revoke remote agents. *Hub implements it.

type Hub

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

Hub is a running-capable hub instance: its configuration, database, UI and the agents connected to it.

func New

func New(ctx context.Context, cfg config.Config, log *slog.Logger, ui fs.FS, opts ...Option) (*Hub, error)

New opens the database (applying migrations) and returns a Hub that serves the dashboard from ui. Call Close when done.

func (*Hub) AgentAddr

func (h *Hub) AgentAddr() string

AgentAddr is where the listener for remote agents is bound, or "" while it is off.

func (*Hub) AgentConn

func (h *Hub) AgentConn() (*grpc.ClientConn, error)

AgentConn returns a client connection to the hub's agent service over the in-process transport. The built-in agent uses it. Close it when done.

func (*Hub) Agents

func (h *Hub) Agents() []AgentInfo

Agents returns a snapshot of the connected agents, ordered by id.

func (*Hub) Close

func (h *Hub) Close() error

Close releases the hub resources.

func (*Hub) CreateEnrollment

func (h *Hub) CreateEnrollment(ctx context.Context, by, name string) (Enrollment, error)

CreateEnrollment makes a one-time enrollment token.

func (*Hub) Layout

func (h *Hub) Layout(ctx context.Context, userID int64) (json.RawMessage, time.Time, bool, error)

Layout implements LayoutStore.

func (*Hub) Metrics

func (h *Hub) Metrics(agentID string) (samples []MetricsSample, known bool)

Metrics returns the recent metrics reported by an agent, oldest first. known is false when the hub has never seen the agent.

func (*Hub) Registry

func (h *Hub) Registry(ctx context.Context) ([]fleet.Agent, error)

Registry lists the enrolled agents, connected or not.

func (*Hub) Rejection

func (h *Hub) Rejection(id string) (Rejection, bool)

Rejection returns why an enrolled agent was last refused because of its version, if it has not connected since.

func (*Hub) RenameAgent

func (h *Hub) RenameAgent(ctx context.Context, by, id, name string) error

RenameAgent sets the name shown for an enrolled agent.

func (*Hub) RevokeAgent

func (h *Hub) RevokeAgent(ctx context.Context, by, id string) error

RevokeAgent stops an agent from connecting again and drops its connection.

func (*Hub) RolloutStatus

func (h *Hub) RolloutStatus(_ context.Context) (RolloutStatus, error)

RolloutStatus reports the servers that could be updated and what the last rollout did.

func (*Hub) SendCommand

func (h *Hub) SendCommand(ctx context.Context, agentID string, cmd *agentv1.Command) (*agentv1.CommandResult, error)

SendCommand sends a command to a connected agent and waits for its result. It returns ErrAgentNotFound if the agent is not connected and ErrAgentDisconnected if it goes away before answering.

func (*Hub) Serve

func (h *Hub) Serve(ctx context.Context, ln net.Listener) error

Serve serves HTTP on ln until ctx is cancelled, then shuts down gracefully.

func (*Hub) SetLayout

func (h *Hub) SetLayout(ctx context.Context, userID int64, layout json.RawMessage) error

SetLayout implements LayoutStore.

func (*Hub) StaleAfter

func (h *Hub) StaleAfter() time.Duration

StaleAfter is how long an agent may stay silent before it is reported as stale.

func (*Hub) StartRollout

func (h *Hub) StartRollout(ctx context.Context, by string, opts RolloutOptions) (RolloutStatus, error)

StartRollout updates the connected servers that run an older version to the version of this hub, a wave at a time, and stops at the first failure.

func (*Hub) StopRollout

func (h *Hub) StopRollout(ctx context.Context, by string) (RolloutStatus, error)

StopRollout lets the servers already handed an update finish and offers it to no other.

func (*Hub) Subscribe

func (h *Hub) Subscribe() (<-chan []byte, func())

Subscribe returns a channel of the JSON events pushed on GET /api/stream and a function that ends the subscription.

func (*Hub) Updates

func (h *Hub) Updates() *update.Manager

Updates returns the manager that looks for new releases.

type LayoutStore

type LayoutStore interface {
	// Layout returns the stored layout; found is false if the user has none.
	Layout(ctx context.Context, userID int64) (layout json.RawMessage, updatedAt time.Time, found bool, err error)
	SetLayout(ctx context.Context, userID int64, layout json.RawMessage) error
}

LayoutStore keeps the dashboard layout of each user. *Hub implements it.

type MetricsSample

type MetricsSample struct {
	At     time.Time
	Report *agentv1.MetricsReport
}

MetricsSample is one metrics report with the time the hub received it.

type Option

type Option func(*Hub)

Option customizes a Hub.

func WithAgentIntervals

func WithAgentIntervals(heartbeat, metrics time.Duration) Option

WithAgentIntervals sets the heartbeat and metrics intervals the hub asks agents to use. Mostly useful in tests.

func WithUpdateSource

func WithUpdateSource(src update.Source) Option

WithUpdateSource replaces the place the hub looks for new releases. Mostly useful in tests.

func WithUpdateVerifier

func WithUpdateVerifier(v update.Verifier) Option

WithUpdateVerifier replaces the check of the signature of downloaded releases. Only for tests: a hub without it never trusts an unsigned release.

func WithVersion

func WithVersion(version string) Option

WithVersion sets the release version of the hub, reported by the built-in agent.

type Rejection

type Rejection struct {
	At      time.Time
	Version string
	Message string
}

Rejection is the last time the hub refused an enrolled agent because its version cannot work with this hub. The dashboard shows it until the agent connects.

type RolloutAgent

type RolloutAgent struct {
	ID       string `json:"id"`
	Hostname string `json:"hostname,omitempty"`
	From     string `json:"from"`
	Status   string `json:"status"`
	Message  string `json:"message,omitempty"`
}

RolloutAgent is a server in a rollout, or one that could be in the next.

type RolloutControl

type RolloutControl interface {
	RolloutStatus(ctx context.Context) (RolloutStatus, error)
	StartRollout(ctx context.Context, by string, opts RolloutOptions) (RolloutStatus, error)
	StopRollout(ctx context.Context, by string) (RolloutStatus, error)
}

RolloutControl is what the HTTP API needs to update the servers. *Hub implements it.

type RolloutOptions

type RolloutOptions struct {
	// Agents limits the rollout to these servers; empty means every candidate.
	Agents []string `json:"agents"`
	// WaveSize is how many servers are updated at the same time (default 1).
	// The rollout stops at the first failure.
	WaveSize int `json:"wave_size"`
}

RolloutOptions say what a rollout does.

type RolloutStatus

type RolloutStatus struct {
	// Target is the version the servers are updated to: the one this hub runs.
	Target string `json:"target"`
	State  string `json:"state"`
	// Candidates are the connected servers that run an older version and would
	// be updated by a new rollout.
	Candidates []RolloutAgent `json:"candidates"`
	// Agents is what the last rollout did.
	Agents     []RolloutAgent `json:"agents"`
	WaveSize   int            `json:"wave_size,omitempty"`
	StartedBy  string         `json:"started_by,omitempty"`
	StartedAt  *time.Time     `json:"started_at"`
	FinishedAt *time.Time     `json:"finished_at"`
}

RolloutStatus is the state of updating the servers to the version of this hub.

type UpdateControl

type UpdateControl interface {
	Status(ctx context.Context) (update.Status, error)
	SetSettings(ctx context.Context, by string, s update.Settings) (update.Status, error)
	Check(ctx context.Context) (update.Status, error)
	Download(ctx context.Context, by string) (update.Status, error)
	Apply(ctx context.Context, by string) (update.Status, error)
}

UpdateControl is what the HTTP API needs to report and steer the updates of the hub. *update.Manager implements it.

Jump to

Keyboard shortcuts

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