Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Code

392 commit(s) on main

Merge change request 01M70WES5ZZDJ6RP226WB11BBZ: Let people rename and remove their own passkeys keenan · 17m ago 4b8c9e1d
source preview history blame raw 7.0 KiB
1# Packages
2
3A release can be installed with the system package manager instead of unpacking a
4tarball. Pushing an annotated tag builds the `.deb` and the `.rpm` for `amd64` and
5`arm64` and attaches them to the release page; nothing is published anywhere else.
6
7```sh
8dpkg -i vole_0.2.0-1_amd64.deb # Debian, Ubuntu
9dnf install ./vole-0.2.0-1.x86_64.rpm # Fedora, RHEL, Rocky
10```
11
12There is no apt or dnf repository and no signature on these files yet. Each release
13page also carries `SHA256SUMS`; compare it before installing.
14
15To have a fresh cloud machine install and configure the package for you, use the
16[deployment guides](deploy/README.md). They need the URL of the file above, which
17is how a `.deb` from a release page is named:
18`.../vole/releases/v0.2.0/artifacts/vole_0.2.0-1_amd64.deb`, or `arm64` for an
19`arm64` machine.
20
21Both packages depend on `git` and the system SQLite library: `libsqlite3-0` on
22Debian and Ubuntu, `sqlite-libs` on Fedora, RHEL, and Rocky. Vole links SQLite
23dynamically, so the library must be present where the binary runs; the package
24manager installs it with the package. The system library must include SQLite's
25FTS5 module, which every distribution listed above enables in its build; the
26command palette is what needs it, and the binary carries the tag that asks for it
27when the driver's bundled copy is used instead.
28
29## What the package installs
30
31| Path | What it is |
32|---|---|
33| `/usr/bin/vole` | The binary, built from the tag with `vole version` set to it |
34| `/usr/lib/systemd/system/vole.service` | The unit, with hardening and a `/var/lib/vole` state directory |
35| `/usr/lib/systemd/system/vole-runner.service` | The CI runner's unit. Not enabled, and inert until `/etc/vole/runner.env` names an instance |
36| `/etc/vole/runner.env` | Arguments for that unit, as a conffile. See [Deploying § CI runners](deploy/runner.md) |
37| `/etc/containers/registries.conf.d/50-vole-runner.conf` | Where a short image name is looked up, as a conffile. Debian and Ubuntu ship no unqualified search registries, so a digest-pinned base written as a short name cannot resolve without it. See [Deploying § CI runners](deploy/runner.md#what-the-package-configures-in-the-container-runtime) |
38| `/etc/containers/containers.conf.d/50-vole-runner.conf` | `cgroup_manager = "cgroupfs"` for the runner's rootless runtime, as a conffile. A system service has no systemd user manager for podman to ask for a cgroup scope. See [Deploying § CI runners](deploy/runner.md#what-the-package-configures-in-the-container-runtime) |
39| `/etc/vole/vole.toml` | Configuration, marked as a conffile so your edits survive upgrades |
40| `/usr/share/doc/vole/` | `LICENSE` and `NOTICE` |
41| `/var/lib/vole/data` | The instance: repositories, databases, stores, host key, audit log |
42
43The package creates the `vole` service account and runs `vole admin init` against
44the shipped config. It does not create an instance admin and does not enable the
45service: who may administer the instance is the operator's decision, not the
46package's.
47
48The shipped config listens on `0.0.0.0:2222` for SSH and `127.0.0.1:8080` for the
49web. Open 2222 in the firewall, set `public_url` before anyone signs in with a
50passkey, and either terminate TLS in a proxy in front of 8080 or use `https_addr`
51to let Vole obtain certificates itself. See
52[Configuration § Automatic HTTPS with ACME](configuration.md#automatic-https-with-acme)
53and [Configuration § Running behind a proxy](configuration.md#running-behind-a-proxy).
54
55The unit is written for the packaged layout and is safe to use as shipped: it
56drops all capabilities, sets `UMask=0027`, gives the service a private `/tmp` and
57device tree, hides other processes, and makes `/var/lib/vole` the only writable
58path. If you need to bind a port below 1024 — SSH on 2222 does not, HTTP on 80 and
59HTTPS on 443 do — add the one capability with a drop-in, which must widen the
60bounding set as well:
61
62```ini
63# /etc/systemd/system/vole.service.d/bind.conf
64[Service]
65CapabilityBoundingSet=CAP_NET_BIND_SERVICE
66AmbientCapabilities=CAP_NET_BIND_SERVICE
67```
68
69`MemoryDenyWriteExecute=true` is safe for the forge because it runs no JIT. A CI
70runner executes repository code in containers and is a separate process with its
71own unit; do not relax this unit to accommodate it.
72
73## First steps after install
74
75```sh
76vole admin --config /etc/vole/vole.toml account create you --key ~/.ssh/id_ed25519.pub
77vole admin --config /etc/vole/vole.toml repo create demo --owner you
78vole admin --config /etc/vole/vole.toml acl set-default-role demo read
79systemctl enable --now vole
80```
81
82Run admin commands as the `vole` user or with `--config /etc/vole/vole.toml`; the
83service account owns the files they write. A command that writes as the wrong user
84leaves state the service cannot open, so prefer:
85
86```sh
87sudo -u vole vole admin --config /etc/vole/vole.toml account list
88```
89
90## Upgrading
91
92`users.db` is migrated in place the first time a newer binary opens it, and the
93migration cannot be rolled back. Back up before upgrading:
94
95```sh
96sudo -u vole vole admin --config /etc/vole/vole.toml account backup /var/lib/vole/users.db.bak
97sudo cp /var/lib/vole/data/ssh_host_ed25519_key /var/lib/vole/ssh_host_ed25519_key.bak
98```
99
100Then install the new package. See [Operations](operations.md) for what else is
101worth copying.
102
103## How the release is built
104
105`.vole/workflows/release.yaml` runs on a `v*` tag and does three things: it runs
106the tests, it cross-compiles the binary for both architectures, and it packages
107each one with [nfpm](https://nfpm.goreleaser.com) from `packaging/nfpm.yaml`. The
108`.deb`, the `.rpm`, the plain binaries, and `SHA256SUMS` are attached to the tag's
109release with `release: true`, so they appear on the release page like any other
110attached file.
111
112Two requirements on the runner:
113
114- **Network.** `go build` fetches modules, and the packaging step fetches a pinned
115 `nfpm`, and a job container has none unless the runner was started with
116 `--container-network bridge`. The image build already needs the network; it
117 installs `git`, the C toolchain, and both architectures' SQLite development
118 files (see `.vole/images/release.yaml`).
119- **Nothing else.** The binaries are cross-compiled, so any runner that can start a
120 Linux container produces the same four packages.
121
122Reproduce a release locally without a runner, from the tag:
123
124```sh
125git switch --detach v0.2.0
126go run ./cmd/vole workflow run release
127```
128
129That runs the steps in your working tree as a check of the commands. It does not
130publish the artifacts. The packaging step fetches nfpm itself with a pinned
131`go run`, so there is no tool to install first — only Go and the network.
132
133The version comes from `git describe --tags --exact-match`, so a checkout with no
134tag stops before building anything.
135
136## The package definition is checked on every push
137
138The CI workflow (`.vole/workflows/verify.yaml`) builds one architecture and packages
139it with the same `packaging/nfpm.yaml` on every branch push. A broken definition,
140install path, or unit file therefore fails the push that broke it, instead of the
141tag that cannot be rebuilt.
142