env

package
v1.0.4 Latest Latest
Warning

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

Go to latest
Published: Jun 25, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package env owns the daemon's environment-variable handling: port allocation (with refcounting), value synthesis (HOST / URL for allocated ports), cross-service propagation, and operator un-prefix —.

The package exposes two surfaces:

Allocator — picks free host ports, tracks refcounts, frees on release.
Builder   — assembles the full env block for one service, including
            constants from compose, allocated values, derived values,
            and cross-service references resolved against other
            services' allocations.

The runner calls Builder.ForTarget at process spawn time and Allocator.ReleaseForTarget when the process terminates. Server's GetEnv RPC calls Builder.ForService for read-only inspection.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ServicePrefix

func ServicePrefix(serviceName string) string

ServicePrefix is the uppercase, underscore-separated form of a service name used in cross-service env references. The convention turns `service-json-keys` into `SERVICE_JSON_KEYS`; the resulting prefix is what other services prepend when consuming this service's vars: `${SERVICE_JSON_KEYS_GRPC_PORT}`.

Types

type Allocation

type Allocation struct {
	Owner    string
	LocalVar string
	Port     int
	Refs     []string
}

Allocation is one snapshot row.

type Allocator

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

Allocator picks free host ports for `*_PORT` env variables and tracks refcounts so an allocation is freed only when its last consumer terminates. Local-dev convention: ephemeral range, kernel-assigned, no fixed pool.

The (ownerService, localVar) tuple is the unique key. Cross-service references resolve by looking up the owner's allocation; the consumer is added to the refs list without taking a separate slot.

func NewAllocator

func NewAllocator() *Allocator

NewAllocator returns an empty allocator. Call SetServices to register the cross-service prefix vocabulary before any allocation.

func (*Allocator) Acquire

func (a *Allocator) Acquire(owner, localVar, consumer string) (int, error)

Acquire returns the host port for (owner, localVar), allocating a fresh one if no slot exists. `consumer` is the target ID claiming this slot; repeated calls with the same consumer are idempotent. Spec §6.2.

func (*Allocator) Lookup

func (a *Allocator) Lookup(owner, localVar string) (int, bool)

Lookup returns the current port for (owner, localVar) WITHOUT allocating. Returns (0, false) if no slot exists. Used by the Builder for the read-only ForService path (`a-novel run env`).

func (*Allocator) Release

func (a *Allocator) Release(consumer string)

Release decrements every slot the given consumer was holding. A slot whose refcount hits zero is removed (its port returned to the ephemeral pool simply by virtue of nobody binding it). Idempotent.

func (*Allocator) Reserve

func (a *Allocator) Reserve(owner, localVar string, port int, consumer string) int

Reserve records (owner, localVar) → port WITHOUT consulting the kernel. Used by adoption: when the daemon restarts and finds an already-running infra container with port mapping host:N → container:5432, it calls Reserve to re-seed the slot so subsequent Acquire calls (e.g., for the one-shot migrations target) return the same host port the running container is bound to. Idempotent for matching (owner, localVar, port); refuses to overwrite a conflicting port already recorded (returns the existing port instead).

func (*Allocator) Services

func (a *Allocator) Services() []string

Services returns a snapshot of the registered service names. Read-only helper for callers that need to resolve owners without grabbing the internal lock.

func (*Allocator) SetServices

func (a *Allocator) SetServices(names []string)

SetServices registers the universe of service names the allocator should recognize as cross-service prefixes. Sorts longest-first so shadowing (e.g., `service-template-extra` vs `service-template`) resolves to the longer name.

func (*Allocator) Snapshot

func (a *Allocator) Snapshot() []Allocation

Snapshot returns every current allocation. Stable order keyed by (owner, localVar) so output is deterministic.

type Builder

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

Builder assembles env blocks for services / targets. It reads compose values from the discovery snapshot and resolves references against the shared Allocator.

func NewBuilder

func NewBuilder(alloc *Allocator) *Builder

NewBuilder wraps an Allocator. The Allocator must have SetServices called before the first ForTarget invocation.

func (*Builder) ForService

func (b *Builder) ForService(svc *discovery.Service, allServices []string) ([]Entry, error)

ForService is the read-only variant. Used by the GetEnv RPC so users can inspect the env without side-effecting the allocator. Vars whose allocations haven't been acquired yet appear with empty string values.

func (*Builder) ForServiceUp

func (b *Builder) ForServiceUp(svc *discovery.Service, allServices []string, consumer string) ([]Entry, error)

ForServiceUp is the allocate-on-demand variant of ForService — used when bringing infra up so the daemon claims `${*_PORT}` slots referenced by infra services (e.g., postgres-X's `${POSTGRES_PORT}`). Consumer is the service-level synthetic ID ("<stack>/<service>-infra") so KillInfra can Release the slots cleanly.

func (*Builder) ForTarget

func (b *Builder) ForTarget(t *discovery.Target, allServices []string) ([]Entry, []string, error)

ForTarget builds the env block to pass to a spawned process for the given target. Allocations are CREATED here — the target is recorded as the consumer for every `*_PORT` it references (directly or via cross-service), and Allocator.Release(targetID) frees them.

It returns the resolved env entries plus any missing-secret warning lines (value-free) the caller should write to the target's log so the operator sees what to set. Callers that only inspect env (not start a process) discard the warnings.

type Entry

type Entry struct {
	Key   string
	Value string
}

Entry is one resolved env variable.

Jump to

Keyboard shortcuts

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