Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion cmd/server_foreground.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"encoding/json"
"fmt"
"io"
"io/fs"
"log"
"log/slog"
"os"
Expand Down Expand Up @@ -330,7 +331,14 @@ func runServerStart(cmd *cobra.Command, args []string) error {
}

if !web.AssetsEmbedded && webAssetsDir == "" {
slog.Warn("This binary was built without web assets. The web UI will not be available. Run 'make web' and rebuild to include the web frontend, or use --web-assets-dir.")
slog.Warn("This binary was built without web assets. The web UI will not be available. Run 'make all' (or 'make web && make build') to rebuild with web assets included, or use --web-assets-dir.")
} else if web.AssetsEmbedded && webAssetsDir == "" {
sub, err := fs.Sub(web.ClientAssets, "dist/client")
if err != nil {
slog.Error("Failed to create sub-filesystem from embedded assets. The web UI will not be available. Run 'make web && make build' to rebuild with web assets included, or use --web-assets-dir.", "error", err)
} else if _, err := fs.Stat(sub, "assets/main.js"); err != nil {
slog.Warn("Embedded web assets are incomplete (main.js missing). The web UI will not be available. Run 'make all' (or 'make web && make build') to rebuild with web assets included, or use --web-assets-dir.")
}
}
Comment on lines 333 to 342

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This block introduces redundant file system checks and duplicate warning logs.

When enableWeb is true, initWebServer is called on line 326, which instantiates the web server via NewWebServer. Inside NewWebServer (in pkg/hub/web.go), the exact same checks (fs.Sub and fs.Stat for assets/main.js) are already performed, and appropriate warnings/errors are logged.

Therefore, executing these checks and logging another warning here is redundant and leads to duplicate warning messages in the console at startup. We can safely remove this entire block.

Note: Removing this block will make the "io/fs" import unused, so it should be removed from the import block as well.

log.Printf("Starting Web Frontend on %s:%d", cfg.Hub.Host, webPort)
wg.Add(1)
Expand Down
12 changes: 8 additions & 4 deletions pkg/hub/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,11 +381,11 @@ var noAssetsPage = `<!DOCTYPE html>
<body>
<div class="container">
<h1>Web UI Not Available</h1>
<p>This Scion binary was not built from source with web assets included.
<p>This hub binary was built without embedded web assets.
The Hub API is still fully operational.</p>
<div class="hint">
<p>To use the web UI, either:</p>
<p>1. Build from source: <code>make build</code></p>
<p>1. Rebuild with assets: <code>make all</code> (or <code>make web &amp;&amp; make build</code>)</p>
<p>2. Point to pre-built assets: <code>--web-assets-dir /path/to/dist/client</code></p>
</div>
</div>
Expand Down Expand Up @@ -475,11 +475,15 @@ func NewWebServer(cfg WebServerConfig) *WebServer {
} else if web.AssetsEmbedded {
sub, err := fs.Sub(web.ClientAssets, "dist/client")
if err != nil {
slog.Error("Failed to create sub-filesystem from embedded assets", "error", err)
slog.Error("Failed to create sub-filesystem from embedded assets. Run 'make web && make build' to rebuild with web assets included, or use --web-assets-dir.", "error", err)
} else if _, err := fs.Stat(sub, "assets/main.js"); err != nil {
slog.Warn("Embedded web assets directory exists but main.js is missing. Run 'make all' (or 'make web && make build') to rebuild with web assets included, or use --web-assets-dir.")
} else {
ws.assets = sub
}
slog.Info("Web server using embedded assets")
if ws.assets != nil {
slog.Info("Web server using embedded assets")
}
} else {
slog.Warn("No web assets available: build with embedded assets or use --web-assets-dir")
}
Expand Down
19 changes: 16 additions & 3 deletions pkg/hub/web_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"path/filepath"
"strings"
"testing"
"testing/fstest"
"time"

"github.com/GoogleCloudPlatform/scion/pkg/store"
Expand All @@ -39,7 +40,13 @@ type mockWebStore struct {

func newTestWebServer(t *testing.T, cfg WebServerConfig) *WebServer {
t.Helper()
return NewWebServer(cfg)
ws := NewWebServer(cfg)
if ws.assets == nil && ws.assetsDisk == "" && cfg.AssetsDir == "" {
ws.assets = fstest.MapFS{
"assets/main.js": &fstest.MapFile{Data: []byte("// test stub")},
}
}
return ws
}

// newDevAuthWebServer creates a web server with dev-auth enabled for testing
Expand All @@ -52,7 +59,13 @@ func newDevAuthWebServer(t *testing.T, overrides ...func(*WebServerConfig)) *Web
for _, fn := range overrides {
fn(&cfg)
}
return NewWebServer(cfg)
ws := NewWebServer(cfg)
if ws.assets == nil && ws.assetsDisk == "" {
ws.assets = fstest.MapFS{
"assets/main.js": &fstest.MapFile{Data: []byte("// test stub")},
}
}
return ws
}

func TestSPAShellHandler(t *testing.T) {
Expand Down Expand Up @@ -231,7 +244,7 @@ func TestSPAHandler_NoAssets_ServesErrorPage(t *testing.T) {
assert.Equal(t, http.StatusOK, resp.StatusCode)
assert.Contains(t, resp.Header.Get("Content-Type"), "text/html")
assert.Contains(t, html, "Web UI Not Available")
assert.Contains(t, html, "not built from source")
assert.Contains(t, html, "built without embedded web assets")
assert.Contains(t, html, "Hub API")
assert.NotContains(t, html, "scion-app",
"should not render SPA shell when no assets are available")
Expand Down
Loading