Documentation
¶
Overview ¶
Package web implements the HTTP control plane: the fail-closed request pipeline (plan §5), the auth/session handlers, and the admin UI shell. It binds loopback only (plan §3); the managed edge fronts the public ports.
Index ¶
- func CSRFToken(ctx context.Context) string
- func ClientIP(ctx context.Context) netip.Addr
- func SessionFrom(ctx context.Context) *session.Session
- func TokenID(ctx context.Context) string
- type Deps
- type Server
- func (s *Server) Handler() http.Handler
- func (s *Server) Reload(ctx context.Context) error
- func (s *Server) Remediate(ctx context.Context, app monitor.App, service string, rung selfheal.Rung) error
- func (s *Server) Run(ctx context.Context) error
- func (s *Server) RunGitPoller(ctx context.Context, interval time.Duration)
- func (s *Server) Scale(ctx context.Context, appProject, service string, replicas int) error
- func (s *Server) SetCircuitClearer(c func(project, service string))
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ClientIP ¶
ClientIP returns the resolved client IP (the real peer, or the single overwritten XFF value when the peer is a trusted proxy). Zero value if unset.
func SessionFrom ¶
SessionFrom returns the loaded session, or nil if unauthenticated.
Types ¶
type Deps ¶
type Deps struct {
DB *store.DB
ConfigPath string // for SIGHUP allowlist+auth reload
Log *slog.Logger
Monitor *monitor.Monitor
OpsStore *ops.ConfigStore
Prober *ops.Prober
Runner *dockerexec.Runner
Docker *docker.Client
EnvStore *envstore.Store
CfgStore *cfgstore.Store
GitStore *gitstore.Store
ProvStore *provstore.Store
SetupStore *setupstore.Store
AlertStore *alertstore.Store
EdgeRoutes *edge.RouteStore
EdgeRecon *edge.Reconciler // nil when the edge isn't owned (external/unavailable)
EdgeReason string // why the edge isn't owned (banner), "" when owned
L4Routes *l4.RouteStore // managed L4 (TCP/UDP) routes (nil when L4 LB disabled)
L4Reconcile func(context.Context) error // push the L4 route set to the nginx-stream LB (nil when disabled)
SelfHeal *selfheal.Store // supervisor FSM + expected_down leases (may be nil)
Scaling *scale.Store // auto-scaling policies + state (may be nil)
DockerSem *dockerexec.Semaphore // global one-docker-child semaphore (shared with Runner)
APITokens *apitoken.Store // scoped read/deploy API tokens (M19; may be nil → /api/v1 disabled)
Backups *backupstore.Store // encrypted Helmsman-state backups (may be nil)
}
Deps are the (mostly optional) collaborators a Server uses. Anything nil degrades gracefully (e.g. nil mon → "collecting…"; nil runner → write plane shown disabled).
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server holds everything the request pipeline needs. Construct with New.
func (*Server) Reload ¶
Reload re-reads the config file and hot-swaps the allowlist + auth (plan §5.1). On any validation error the current state is kept (fail-closed: a bad edit never widens or breaks the running policy).
func (*Server) Remediate ¶
func (s *Server) Remediate(ctx context.Context, app monitor.App, service string, rung selfheal.Rung) error
Remediate makes *Server the supervisor's Actioner: it runs the rung through the SAME write path the operator uses (env render, §5.6 validation + config-file materialization for recreate/redeploy), but via RunHeld — the supervisor's safety gate already holds the one-docker-child semaphore, so re-acquiring would deadlock. Authority never widens what may run: a protected project is refused here too.
func (*Server) RunGitPoller ¶
RunGitPoller is the "just connect the repo and it works" loop: it FETCHES every connected repo so change-detection needs NO webhook setup. It is READ-PLANE ONLY — it never deploys; it surfaces an "update available" the operator deploys with a click (push-to-deploy stays an explicit opt-in via the webhook + auto_deploy, never this loop). A fetch never mutates a running app, and the loop is serialized through the same single-flight gate as deploys, so it can never pile up docker/git children.
Because Helmsman never auto-deploys, fetching when nobody is looking is wasted work — so the loop only fetches while a focused dashboard is open (the heartbeat above). When the operator opens/returns to the dashboard, the next tick fetches.
interval <= 0 disables polling. Blocks until ctx is cancelled.
func (*Server) Scale ¶
Scale makes *Server the auto-scaler's Scaler: it changes a service's replica count with a static-argv `docker compose up -d --no-deps --no-recreate --scale <svc>=<n>` through the gated write path (env render + §5.6 validation), via RunHeld — the scaler's safety gate already holds the one-docker-child semaphore. A protected project is refused (authority never widens what may run).
func (*Server) SetCircuitClearer ¶
SetCircuitClearer wires the supervisor's clear-circuit entry point (set by cmd_serve after both the server and the watcher exist — avoids an import cycle).
Source Files
¶
- alerts.go
- api.go
- apitokens_web.go
- apps_list.go
- assets.go
- auth.go
- backups_web.go
- configfiles.go
- context.go
- csrf.go
- edge.go
- env.go
- github_oauth.go
- gitops.go
- gitops_build.go
- gitpoll.go
- handlers.go
- incidents.go
- lifecycle.go
- lockout.go
- metrics_history.go
- middleware.go
- nofollow_unix.go
- ops_handlers.go
- pathsafe.go
- provision.go
- ratelimit.go
- routes_apply.go
- scale.go
- selfheal.go
- server.go
- settings.go
- setup.go
- theme.go