暂无描述

clanker 13235ce122 Ignore compile_commands.json (generated by meson, copied out by spry dev) 1 周之前
src a9e0c34357 usm-web: USM repository browser + serving frontend (Statum + Spry) 1 周之前
usm-scripts a9e0c34357 usm-web: USM repository browser + serving frontend (Statum + Spry) 1 周之前
.gitignore 13235ce122 Ignore compile_commands.json (generated by meson, copied out by spry dev) 1 周之前
.usmignore 13235ce122 Ignore compile_commands.json (generated by meson, copied out by spry dev) 1 周之前
MANIFEST.usm a9e0c34357 usm-web: USM repository browser + serving frontend (Statum + Spry) 1 周之前
README.md a9e0c34357 usm-web: USM repository browser + serving frontend (Statum + Spry) 1 周之前
meson.build a9e0c34357 usm-web: USM repository browser + serving frontend (Statum + Spry) 1 周之前

README.md

usm-web

A Statum + Spry application that browses and serves a USM repository: human-facing pages for exploring packages, plus the exact HTTP endpoints a real USM client (usm repository list / verify / install) expects to fetch from a repository host.

What it serves

Endpoint Purpose
GET / Repo overview: name/summary, signing-key fingerprint, package count and total size, add-repository + install-USM instructions, package table with server-side search
GET /package/{file} Package detail: manifest fields read out of the .usmc (licences, flags, provides/depends tables), sha512, on-disk size/mtime, download button
GET /PACKAGES.usml The repository listing streamed verbatim (application/json)
GET /repo.usmr A rewritten copy of the .usmr with its embedded url replaced by the derived base
GET /<file>.usmc Package archives streamed from <repo>/public/ (application/octet-stream, exact content-length)
GET /install-usm.sh The configured installer script (installer.path mode only)

The derived base is base_url from the config when set, else X-Forwarded-Proto/X-Forwarded-Host, else the request's own scheme/host — so clients behind a reverse proxy resolve against the public name.

Configuration

web-config.json (in the app's working directory, or ASTRALIS_CONFIG_PATH) carries the static Statum keys plus an optional "usm-web" section:

{
  "statum": { "…": "static keys from spry keys / statum-genkeys" },
  "usm-web": {
    "installer": { "path": "install-usm.sh" },
    "base_url": "https://repo.example.com/",
    "name": "My repository"
  }
}
Key Meaning
installer.url External installer location; the homepage links out and shows curl -fsSL <url> \| sh
installer.path Installer script this app serves at /install-usm.sh; relative paths resolve against the config file's directory
base_url Optional override of the request-derived repository base (normalised to a trailing slash)
name Optional display-name override for the .usmr name

installer takes exactly one of url/path; providing both (or neither, when the block should appear) is a configuration error. Omit the section entirely to hide the install-USM card.

The repository root is selected by (in order) the --repo <dir> argument, the USM_WEB_REPO_DIR environment variable, or the /repo default, and is expected to look like a published repository:

/repo
├── web-stack.usmr
├── keys/            (not used by usm-web; signing is upstream)
└── public/
    ├── PACKAGES.usml
    └── <name>-<version>.usmc

Both the .usmr and PACKAGES.usml are re-read when their mtimes change, so a rebuilt repository is picked up without a restart. There is no database and no authentication; all Statum state is stateless PAGE slots.

Development

spry dev

Builds, runs the app on port 8080 (--port N to change) and watches src/, meson.build and web-config.json: saving a file rebuilds incrementally — page HTML and resources recompile via the meson codegen targets — and restarts the app when the build succeeds.

The environment below is required for the underlying meson builds (the spry dev child processes set it for you; export it in shells where you build or run manually):

export WS_PREFIX="$HOME/.local"
export PKG_CONFIG_PATH="$WS_PREFIX/lib64/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
export XDG_DATA_DIRS="$WS_PREFIX/share${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}"
export LD_LIBRARY_PATH="$WS_PREFIX/lib64${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"

meson setup builddir
ninja -C builddir
./builddir/usm-web 8080 --repo ../web-stack-repo

Repo parsing uses libusm (Usm.Repository, Usm.RepositoryListing, Usm.Manifest.from_package) — no hand-rolled usml/usmr mappers.

Layout

Path Purpose
src/main.vala application wiring: modules, config, pages, action, endpoints
src/UsmWebConfig.vala the "usm-web" config section (installer url|path, base_url, name)
src/RepositoryService.vala libusm-backed read side with mtime-based reload
src/DerivedBase.vala base-URI derivation from config/forwarded headers
src/PackagesState.vala shared packages slot-state builder + size/fingerprint formatting
src/entrypoints/ HomeEntrypoint (/) and PackageDetailEntrypoint (/package/{file})
src/actions/ SearchPackagesAction — server-side table filtering
src/endpoints/ the USM-facing endpoints listed above
src/pages/*.html Statum pages, compiled by statum-mkpstm at build time
src/Static/main.css stylesheet embedded by statum-mkres
MANIFEST.usm USM package manifest: provides bin:usm-web, build/runtime/manage deps
usm-scripts/ USM build + install scripts (meson staging)
web-config.json static keys and the usm-web section (gitignored, 0600)

Registrations live between // spry:*-begin/end markers in src/main.vala, # spry:*-begin/end markers in meson.build and <!-- spry:nav-begin/end --> markers in src/pages/main.html; the spry add commands edit only those blocks and are idempotent.

Deployment (USM)

spry deploy --verbose \
  --repository ../web-stack-repo/web-stack.usmr \
  --installer-url file:///tmp/kilo/usm-shim/install-usm-full.sh

This packages the application and builds a single-stage container image through USM (usm manifest deploy): the MANIFEST.usm + usm-scripts/ drive the in-container build and install, the Web-Stack resolves from the given repository (including the usm package that provides the libusm pc:/vapi: refs this app builds against), and the system package manager provides the platform libraries. The result is usm-web-<version>.image.tar.xz, loadable with podman load -i.

web-config.json is never packaged (.usmignore), so keys are never baked into the image. Bind-mount the repository read-only at /repo and, when you want stable keys or an installer section, mount a config:

podman load -i usm-web-0.1.image.tar.xz
podman run -d -p 8080:8080 \
    -v /path/to/web-stack-repo:/repo:ro,Z \
    -v $PWD/web-config.json:/run/web-config.json:ro \
    -e ASTRALIS_CONFIG_PATH=/run/web-config.json \
    localhost/usm-web:0.1