server

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 13, 2026 License: MIT Imports: 28 Imported by: 0

Documentation

Overview

Package server wires the control plane together: store, transport, Connect handlers, the scheduler and the log fan-out, behind one HTTP server.

Index

Constants

View Source
const (
	// TransportLocal is the shared bearer-token transport: one machine, no Tailscale.
	TransportLocal = "local"
	// TransportTailnet embeds a Tailscale device (tsnet) and serves HTTPS on its MagicDNS name.
	TransportTailnet = "tailnet"
	// TransportHost uses the machine's existing tailscaled instead of embedding a device.
	TransportHost = "host"
)

The transports PODIUM_TRANSPORT accepts.

View Source
const ReadHeaderTimeout = 10 * time.Second

ReadHeaderTimeout bounds how long a connection may take to send its request headers, so a client that opens a socket and says nothing cannot hold a goroutine forever.

It is exported because it is not only an HTTP/1 concern. Go 1.26 armed this deadline on the raw connection and left it armed when the connection turned out to be cleartext HTTP/2, which severed every node stream after exactly this long; see the note on the go directive in go.mod. A test asserts that a stream outlives it, and derives the wait from this constant rather than repeating the number.

View Source
const ShutdownTimeout = 10 * time.Second

ShutdownTimeout is how long Run gives in-flight work to finish after a signal.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// DatabaseURL is PODIUM_DATABASE_URL. Required.
	DatabaseURL string
	// Transport is PODIUM_TRANSPORT: dev (default), tailnet or host.
	Transport string
	// LocalListen is PODIUM_LOCAL_LISTEN, default 127.0.0.1:8080. It must be loopback.
	LocalListen string
	// LocalToken is PODIUM_LOCAL_TOKEN, the shared bearer token of the local transport.
	LocalToken string
	// LocalAllowUnsafeListen is PODIUM_LOCAL_ALLOW_UNSAFE_LISTEN: let LocalListen bind an address
	// that is not loopback. A container deployment needs it — loopback inside a container is
	// the container's own, so nothing could reach the server — and the published port is the
	// boundary there. On a host it publishes the whole API to anything that can route to the
	// address, guarded by one static token, so the server warns loudly when it is on.
	LocalAllowUnsafeListen bool

	// MasterKeyFile is PODIUM_MASTER_KEY_FILE: the file holding the 32-byte AES-256 key
	// every stored secret is encrypted under. The file must not be readable by other
	// accounts on the machine or the server refuses to start. Empty disables secrets.
	MasterKeyFile string
	// MasterKey is PODIUM_MASTER_KEY, the same key inline. It is a development
	// convenience — an environment variable is visible in /proc and in `docker inspect` —
	// and the server warns loudly when it is used. MasterKeyFile wins if both are set.
	// SENSITIVE: never log it.
	MasterKey string

	// TSHostname is PODIUM_TS_HOSTNAME: the Tailscale device name, and therefore the first
	// label of the MagicDNS name the server is reached at.
	TSHostname string
	// TSStateDir is PODIUM_TS_STATE_DIR: where tsnet keeps the device's node key. It must
	// persist across restarts or the server registers a new device every time.
	TSStateDir string
	// TSAuthKey is TS_AUTHKEY, read on the first run only. This is the *Tailscale* auth key —
	// reusable, pre-approved, tagged tag:podium-server — not a Podium enrollment token.
	// SENSITIVE: never log it.
	TSAuthKey string
	// TSRequiredNodeTag is PODIUM_TS_REQUIRED_NODE_TAG: the ACL tag a device must carry to be
	// treated as a worker.
	TSRequiredNodeTag string
	// TSAllowUntaggedNodes is PODIUM_TS_ALLOW_UNTAGGED_NODES: let an untagged tailnet device
	// enroll as a node. It removes the network-level proof that a caller is an authorised
	// worker and exists only for a tailnet that has no ACL tags yet.
	TSAllowUntaggedNodes bool

	// AgentURL is PODIUM_AGENT_URL: where podium-agent, the conductor, listens. Setting it
	// makes the server reverse-proxy /podium.agent.v1.AgentService/ to that address behind
	// its own identity middleware, which is the only way a browser reaches the conductor.
	// Empty means this control plane has no conductor and nothing is mounted.
	AgentURL string
	// AgentToken is PODIUM_AGENT_TOKEN: the bearer the proxy presents to the conductor. It
	// is also the conductor's proof that a proxied request came through this server, which
	// is what makes the X-Podium-Login header trustworthy at the other end.
	// SENSITIVE: never log it.
	AgentToken string

	// S3 is the PODIUM_S3_* object store: where artifacts and rolled-up logs live. An
	// empty endpoint disables artifacts entirely, which is a supported configuration —
	// a task does not need artifacts to run.
	S3 artifacts.Config
	// Rollup is the log roll-up schedule.
	Rollup logs.RollupConfig
}

Config is the whole of podium-server's configuration. The names are the canonical ones.

func ConfigFromEnv

func ConfigFromEnv() Config

ConfigFromEnv reads the canonical environment variables and applies the defaults.

func (Config) AgentEnabled

func (c Config) AgentEnabled() bool

AgentEnabled reports whether this control plane proxies the conductor's API.

func (Config) Validate

func (c Config) Validate() error

Validate reports the first thing that would stop the server from starting.

type Server

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

Server is a configured, not-yet-listening control plane.

func New

func New(ctx context.Context, cfg Config, logger *slog.Logger) (*Server, error)

New opens the store, migrates it, and builds every handler. It does not bind a socket; call Start or Run for that.

func (*Server) Addr

func (s *Server) Addr() string

Addr is the bound address, valid once Start has returned.

func (*Server) Close

func (s *Server) Close()

Close releases the store and leaves the tailnet. Call it after Shutdown.

func (*Server) Run

func (s *Server) Run(ctx context.Context) error

Run serves until ctx is cancelled, then shuts down within ShutdownTimeout.

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

Shutdown stops accepting, closes every node stream so the nodes reconnect elsewhere, and waits for in-flight requests until ctx expires. Streams still open at the deadline are cut.

func (*Server) Start

func (s *Server) Start(ctx context.Context) error

Start binds the socket and starts serving, the scheduler and the log fan-out. It returns as soon as the listener is up.

func (*Server) URL

func (s *Server) URL() string

URL is the base URL a Connect client should dial. Under the tailnet transports that is the MagicDNS name the certificate is issued for, not the address the socket is bound to.

Directories

Path Synopsis
Package api holds the operator-facing Connect handlers: tasks and node administration.
Package api holds the operator-facing Connect handlers: tasks and node administration.
Package artifacts is the control plane's half of the object store: the S3 client, the key layout, presigned URLs, and the service that records what has been stored.
Package artifacts is the control plane's half of the object store: the S3 client, the key layout, presigned URLs, and the service that records what has been stored.
fakes3
Package fakes3 is an in-process S3-compatible endpoint for Podium's own tests.
Package fakes3 is an in-process S3-compatible endpoint for Podium's own tests.
Package logs owns the write side of a task's event history: it turns a node's event batch into rows, applies the status transitions those events imply, and fans the result out to live subscribers.
Package logs owns the write side of a task's event history: it turns a node's event batch into rows, applies the status transitions those events imply, and fans the result out to live subscribers.
Package nodes owns node identity and the node stream: enrollment, the in-memory session registry, heartbeat bookkeeping and the event batches nodes push back.
Package nodes owns node identity and the node stream: enrollment, the in-memory session registry, heartbeat bookkeeping and the event batches nodes push back.
Package scheduler decides which node runs which task, and keeps the promises that decision makes: a lease per assignment, a deadline for accepting one, the spec's own timeout, and the node-health policy that turns a machine going away into either a new attempt or an honest `lost`.
Package scheduler decides which node runs which task, and keeps the promises that decision makes: a lease per assignment, a deadline for accepting one, the spec's own timeout, and the node-health policy that turns a machine going away into either a new attempt or an honest `lost`.
Package secrets is the control plane's encrypted secret store: the master key, the AES-256-GCM envelope around every stored value, and the resolution step that turns a task's SecretRefs into the plaintext an Assign carries to a node.
Package secrets is the control plane's encrypted secret store: the master key, the AES-256-GCM envelope around every stored value, and the resolution step that turns a task's SecretRefs into the plaintext an Assign carries to a node.
Package store is the only place SQL lives.
Package store is the only place SQL lives.
db

Jump to

Keyboard shortcuts

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