Skip to content

Add -airgap: embed Chart.js in dashboard.html for offline viewing - #59

Merged
CamiloSierraH merged 2 commits into
mainfrom
cami/airgap-dashboard
Oct 22, 2026
Merged

CamiloSierraH merged 2 commits into
mainfrom
cami/airgap-dashboard

Conversation

@CamiloSierraH

@CamiloSierraH CamiloSierraH commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Why

dashboard.html loads Chart.js from a public CDN. When the file is opened on a machine with no internet access (air-gapped networks, locked-down workstations, browsers that block CDNs), the script never loads and the page renders nothing: no charts, no tables and no alerts, not only the charts.

What

A new -airgap flag embeds Chart.js 4.4.3, which ships inside the binary, directly in dashboard.html, so the page opens with no network access. Without the flag nothing changes: the output is the same CDN page as today, and a test checks this.

  • airgap/README.md: how and when to use it, with examples (single node, cluster ... -- -airgap, and combined with other flags), how to verify it from the footer, and the size cost. The flag is documented only there. The main README's "Dashboard charts blank" entry now links to that folder.
  • internal/dashboard/assets/chart.umd.js: dist/chart.umd.js from the npm chart.js@4.4.3 tarball, unmodified. The tarball matches the registry's sha512 integrity hash, and the test pins the file's sha256. The MIT licence (LICENSE.chartjs.md) is embedded too, and its full text is inlined as a comment just ahead of the library, so every standalone dashboard.html carries the permission notice.
  • internal/dashboard/airgap.go: go:embed plus WithAirgap, which replaces the CDN <script> tag and the footer text.
  • Makefile: airgap added to DATA_DIRS, so release archives ship the README.
  • Gov mode produces no dashboard, so the flag has no effect there. schema_graph.html was already network-free.

Testing

  • make test passes and gofmt -l is clean.
  • New tests:
    • the checksum is pinned;
    • the CDN tag and the embedded banner name the same release;
    • the library and the licence contain no </script or */ that would end the script or the comment early;
    • the full MIT permission notice comes before the library;
    • the default output still uses the CDN;
    • the -airgap output has no remote <script>/<link>, and Chart.js comes before the dashboard script.
  • When the replacement was disabled on purpose, the air-gap test failed.
  • I ran the binary against a local lab cluster both ways and opened each dashboard in headless Chrome with all hosts unresolvable:
Build Network Charts Table rows
default online 22 177
default offline 0 (Chart undefined) 0
-airgap offline 22 177
  • dashboard.html grows from about 300 KB to about 510 KB with the flag (about 70 KB once gzipped in the bundle).
  • make release: every archive contains airgap/README.md.
  • cluster -- -airgap passes the flag through to every host's command.

🤖 Generated with Claude Code

By default the dashboard loads Chart.js from a CDN; opened without
internet the script fails and the page renders no charts, tables or
alerts. -airgap inlines Chart.js 4.4.3 (vendored from the npm tarball,
checksum pinned in a test, MIT licence alongside). Without the flag the
output is unchanged. Documented in airgap/README.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Distributed artifacts need the full MIT notice, and release archives need the linked offline usage guide.

2 open issues
What changed in this PR

Adds optional offline viewing for ClickHouse diagnostic dashboards while preserving default CDN loading.

Changes:

  • Adds -airgap and embeds Chart.js 4.4.3.
  • Tests asset integrity, rendering, and script order.
  • Documents offline usage and links troubleshooting guidance.
File Description
README.md Links offline dashboard instructions.
internal/​dashboard/​generator.go Selects offline or CDN rendering.
internal/​dashboard/​assets/​LICENSE.chartjs.md Adds Chart.js licence text.
internal/​dashboard/​assets/​chart.umd.js Vendors Chart.js 4.4.3.
internal/​dashboard/​airgap.go Embeds Chart.js and updates the footer.
internal/​dashboard/​airgap_test.go Tests asset integrity and rendering modes.
cmd/​main.go Registers and forwards -airgap.
airgap/​README.md Documents offline usage and limitations.

Review effort: Balanced

Comment thread internal/dashboard/airgap.go Outdated
Comment thread README.md
@CamiloSierraH
CamiloSierraH requested a review from ugosan October 19, 2026 18:25
A dashboard.html travels alone, so the banner's one-line MIT mention is
not enough: the full licence text is now embedded in a comment ahead of
the library. The release packaging copied cluster-collect/ but not
airgap/, leaving release users without the only usage guide.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ugosan

ugosan commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

The -airgap version of the same report adds about 300kb to the html with the embedded chart.js, which is reasonable.

We could consider of a "self-hosted" support diagnostics in the future, e.g. with a flag -serve that would spawn a local webserver (using golang's http.ListenAndServe() ) to serve the diagnostics. It would provide better separation between our code and libraries, and then the page could have an export function+api that would generate the airgapped dashboard if needed. Something to think about.

@ugosan ugosan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@CamiloSierraH
CamiloSierraH merged commit 29a5ac6 into main Oct 22, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants