Files
llmgw/internal/web/about.go
T
Ilker ManapandClaude Opus 5.5 fea5774fe5 The install guide shows every screen of a real install
/install takes a reader from three bare Ubuntu machines to a first answer:
what each machine needs and the commands that check it, the release fetched
and its checksum checked, the eight setup screens, the system's state and
the console, and a first request with a key from the account page. Every
screen is from an install of v0.14.9 on three fresh VMs, recorded with tmux
and kept as terminal frames: the page shows them as text, and plays a
session back when asked, fetching it compressed from /install/cast/. The
administrator's password and the API key were masked before the recording
was kept, and a test fails if either shape reaches the page.

/about gains what llmgw now does beyond routing, and its install steps are
today's: the setup screens and node add, not onboard-node.sh and a model
file, with a link into the guide.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 01:35:08 +02:00

95 lines
3.0 KiB
Go

package web
import (
"embed"
"html/template"
"io"
"net/http"
"regexp"
"strings"
)
// The page about llmgw itself: what it is, how to install it, where to get
// it. It is the project's website, carried by every gateway so an operator
// has it where they already are, and served without a key like the landing
// page — it says nothing about this installation, only about the software.
//
// The same template renders the published website (Site), which differs in
// three ways: fonts from Google rather than from this binary, no link back to
// a gateway, and features on main marked as coming in the next release.
// proxyConfigs are the reverse proxy configurations the page shows. They are
// copies of deploy/proxy, which the release attaches; embed cannot reach
// outside this package, and TestAboutProxyConfigsMatchDeploy keeps the two
// the same.
//
//go:embed proxy
var proxyConfigs embed.FS
// AboutData is what the page is rendered with.
type AboutData struct {
// Version is what this build calls itself; Release is the same when it is
// a released version, and empty for a development build, which has no
// files to download.
Version, Release string
// Download is where the release's files are, or for a development build
// the proxy configurations on main.
Download string
// Date is the release date, when it is known. A binary does not know it.
Date string
Caddy, Nginx string
Site bool
}
// InstallURL is the install guide: on a gateway its /install, on the website
// the page beside this one.
func (d AboutData) InstallURL() string {
if d.Site {
return "install.html"
}
return "/install"
}
// Still is a screen of the install guide's recording, for the steps here.
func (d AboutData) Still(name string) template.HTML {
return InstallData{Site: d.Site}.Still(name)
}
// releaseTag is a version the releases page has files for.
var releaseTag = regexp.MustCompile(`^v\d+\.\d+\.\d+$`)
const repoURL = "https://gitea.mynodes.xyz/ilker/llmgw"
// NewAboutData fills the page's data for a version.
func NewAboutData(version string) AboutData {
d := AboutData{Version: version, Download: repoURL + "/raw/branch/main/deploy/proxy"}
if releaseTag.MatchString(version) {
d.Release = version
d.Download = repoURL + "/releases/download/" + version
}
d.Caddy = proxyConfig("Caddyfile")
d.Nginx = proxyConfig("nginx.conf")
return d
}
func proxyConfig(name string) string {
b, err := proxyConfigs.ReadFile("proxy/" + name)
if err != nil {
panic("web: the proxy configuration " + name + " is missing from the binary: " + err.Error())
}
return strings.TrimRight(string(b), "\n")
}
// RenderAbout writes the page, for the website's build as much as for About.
func RenderAbout(w io.Writer, d AboutData) error {
return tmpl.ExecuteTemplate(w, "about", d)
}
// About serves the page at /about.
func About(version string) http.HandlerFunc {
d := NewAboutData(version)
return func(w http.ResponseWriter, r *http.Request) {
render(w, r, "about", d)
}
}