Loggerhead
Loggerhead is a web viewer for Bazaar / Breezy branches. It can be used to navigate a branch's history, annotate files, view patches, download tarballs, and search commit messages.
Loggerhead is distantly based on bazaar-webserve, which was itself loosely based on hgweb for Mercurial.
This branch of Loggerhead is written in Rust and uses breezyshim to talk to Breezy.
Getting started
Building
Loggerhead is a Rust crate. You need a recent stable Rust toolchain and a working Python environment (Breezy is invoked through PyO3 via breezyshim).
cargo build --release
The resulting binary is target/release/loggerhead-serve.
Running
Point loggerhead-serve at a branch or a directory of branches:
./target/release/loggerhead-serve ~/path/to/branch
By default the server listens on port 8080, so browse to http://localhost:8080/ to see the branch.
If you pass a directory that contains several branches, Loggerhead
presents a simple directory listing at /, with each branch mounted
under /<name>/.
Loggerhead re-reads the branch data on every request, so you can update your branches while the server is running and see the changes the next time you reload.
See loggerhead-serve for every command-line
option.
Hiding branches
To hide a branch from Loggerhead, add the following to
~/.config/breezy/locations.conf under the branch's section:
[/path/to/branch]
http_serve = False
loggerhead-serve
loggerhead-serve runs a standalone Loggerhead HTTP server in the
foreground.
Usage
loggerhead-serve [OPTIONS] <PATH_OR_URL>
<PATH_OR_URL> is either a single branch or a directory of branches
(see --user-dirs for the Launchpad-style layout).
Options
--port <PORT>
Port to listen on. Defaults to 8080.
--host <HOST>
Host address to bind to. Defaults to 0.0.0.0 (all interfaces).
--prefix <PREFIX>
URL prefix, for use when Loggerhead is mounted under a sub-path behind
a reverse proxy. For example, if the proxy forwards
https://example.com/bzr/ to Loggerhead, pass --prefix=/bzr.
--cache-dir <DIR> (alias: --cachepath)
Directory to place the on-disk revision-info cache (SQLite). The cache is optional — if it's not configured, Loggerhead recomputes history from the branch on every cold request.
--export-tarballs
Allow tarball downloads of revisions. Enabled by default. Pass
--export-tarballs=false to disable.
--log-folder <DIR>
Directory to write log files to. Accepted for CLI compatibility with the Python implementation; currently logs are still emitted to stderr.
--log-level <LEVEL>
Log level. One of trace, debug, info, warn, error. You can
also set RUST_LOG in the environment.
--static-dir <DIR>
Directory of static CSS/JS/image assets to serve under /static.
Defaults to the static/ directory shipped with the source checkout;
Debian-packaged installs typically point this at
/usr/share/loggerhead/static.
--user-dirs
Serve the root as a directory of user branches. Each
<root>/<user>/<branch> is exposed at /~<user>/<branch>/. Requires
--trunk-dir.
--trunk-dir <DIR>
When --user-dirs is set, the subdirectory under <root> whose
branches are served under / without the ~user prefix.
-h, --help
Print help and exit.
--version
Print the software version and exit.
Running behind a reverse proxy
Loggerhead's preferred deployment is as a long-running HTTP server
behind a reverse proxy such as nginx, Apache (with mod_proxy), or
Caddy. The proxy handles TLS, logging, access control, and any other
shared concerns for your site.
nginx
location /bzr/ {
proxy_pass http://127.0.0.1:8080/bzr/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
And run Loggerhead with a matching --prefix:
loggerhead-serve --prefix=/bzr /srv/bzr
Apache
<Location "/bzr/">
ProxyPass http://127.0.0.1:8080/bzr/
ProxyPassReverse http://127.0.0.1:8080/bzr/
</Location>
Again, match --prefix=/bzr on the Loggerhead side.
systemd
A minimal unit:
[Unit]
Description=Loggerhead
After=network.target
[Service]
ExecStart=/usr/bin/loggerhead-serve --cache-dir=/var/cache/loggerhead /srv/bzr
User=loggerhead
Group=loggerhead
Restart=on-failure
[Install]
WantedBy=multi-user.target
Searching
Loggerhead's /search page is backed by the bzr-search Breezy
plugin. You need to have the plugin installed in the Python environment
that Loggerhead is calling into, and each branch must be indexed before
its contents become searchable.
Indexing a branch is a Breezy-side operation:
brz index /path/to/branch
If the plugin isn't available or the branch hasn't been indexed, the
/search page renders a "search unavailable" notice rather than
erroring out.