remove experimental web UI

The web UI shipped as "experimental" and was never finished — no nav
off the dashboard, no live updates, no settled design, never a
supported surface. It was opt-in by default already; leaving the code
in the tree for v0.1.0 only invited "does this work?" questions and
kept HostSummary/BangerSummary/SudoStatus types on the public RPC
surface that nothing else uses.

Removed:

  internal/webui/                         (all Go + templates + assets)
  internal/daemon/web.go                  (server start / Layout / Config / ListVMs / ListImages)
  internal/daemon/dashboard.go            (DashboardSummary aggregator)

Simplified:

  internal/api/types.go                   drop WebURL on PingResult, drop
                                          HostSummary / SudoStatus / BangerSummary /
                                          DashboardSummary / DashboardSummaryResult
  internal/model/types.go                 drop DaemonConfig.WebListenAddr
  internal/config/config.go               drop web_listen_addr from fileConfig + Load
  internal/daemon/daemon.go               drop webListener / webServer / webURL fields +
                                          startWebServer() call + ping WebURL population
  internal/cli/banger.go                  `daemon status` output no longer branches on web
  internal/daemon/{doc.go,ARCHITECTURE.md} drop web UI sections
  README.md                               drop web_listen_addr config bullet + security paragraph

Tests updated to reflect the new shape. Coverage 57.3 -> 58.9% (the
webui package was largely untested; its removal lifts the ratio
without moving the numerator). `banger daemon status` output and
--help are web-free. Lint + full suite green.
This commit is contained in:
Thales Maciel 2026-04-19 14:28:08 -03:00
parent 687fcf0b59
commit d1b9a8c102
No known key found for this signature in database
GPG key ID: 33112E6833C34679
24 changed files with 9 additions and 2752 deletions

View file

@ -21,7 +21,6 @@ import (
type fileConfig struct {
LogLevel string `toml:"log_level"`
WebListenAddr *string `toml:"web_listen_addr"`
FirecrackerBin string `toml:"firecracker_bin"`
SSHKeyPath string `toml:"ssh_key_path"`
DefaultImageName string `toml:"default_image_name"`
@ -55,10 +54,7 @@ type vmDefaultsFile struct {
func Load(layout paths.Layout) (model.DaemonConfig, error) {
cfg := model.DaemonConfig{
LogLevel: "info",
// Experimental web UI is opt-in: users set web_listen_addr in
// config.toml (e.g. "127.0.0.1:7777") to enable it.
WebListenAddr: "",
LogLevel: "info",
AutoStopStaleAfter: 0,
StatsPollInterval: model.DefaultStatsPollInterval,
MetricsPollInterval: model.DefaultMetricsPollInterval,
@ -87,9 +83,6 @@ func Load(layout paths.Layout) (model.DaemonConfig, error) {
if value := strings.TrimSpace(file.LogLevel); value != "" {
cfg.LogLevel = value
}
if file.WebListenAddr != nil {
cfg.WebListenAddr = strings.TrimSpace(*file.WebListenAddr)
}
if value := strings.TrimSpace(file.FirecrackerBin); value != "" {
cfg.FirecrackerBin = value
} else if path, err := system.LookupExecutable("firecracker"); err == nil {

View file

@ -39,16 +39,12 @@ func TestLoadDefaultsResolveFirecrackerAndGenerateSSHKey(t *testing.T) {
if cfg.DefaultImageName != "debian-bookworm" {
t.Fatalf("DefaultImageName = %q, want debian-bookworm", cfg.DefaultImageName)
}
if cfg.WebListenAddr != "" {
t.Fatalf("WebListenAddr default = %q, want empty (experimental web UI is opt-in)", cfg.WebListenAddr)
}
}
func TestLoadAppliesConfigOverrides(t *testing.T) {
configDir := t.TempDir()
data := []byte(`
log_level = "debug"
web_listen_addr = "127.0.0.1:8080"
firecracker_bin = "/opt/firecracker"
ssh_key_path = "/tmp/custom-key"
default_image_name = "void"
@ -73,9 +69,6 @@ default_dns = "9.9.9.9"
if cfg.LogLevel != "debug" {
t.Fatalf("LogLevel = %q", cfg.LogLevel)
}
if cfg.WebListenAddr != "127.0.0.1:8080" {
t.Fatalf("WebListenAddr = %q, want 127.0.0.1:8080", cfg.WebListenAddr)
}
if cfg.FirecrackerBin != "/opt/firecracker" {
t.Fatalf("FirecrackerBin = %q", cfg.FirecrackerBin)
}