vole
Clone
Read only, no credentials:
https://rodent.software/vole.git
Write over SSH with a registered key:
git clone ssh://git@rodent.software:2222/vole.git
A free and open-source forge that lives in your Git repo.
|
3b39a84c
Keenan Nemetz
14d ago
|
1 | # Packages |
| 2 | ||
| 3 | A release can be installed with the system package manager instead of unpacking a | |
| 4 | tarball. 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 | |
| 8 | dpkg -i vole_0.2.0-1_amd64.deb # Debian, Ubuntu | |
| 9 | dnf install ./vole-0.2.0-1.x86_64.rpm # Fedora, RHEL, Rocky | |
| 10 | ``` | |
| 11 | ||
| 12 | There is no apt or dnf repository and no signature on these files yet. Each release | |
| 13 | page also carries `SHA256SUMS`; compare it before installing. | |
| 14 | ||
|
b8e7a567
Keenan Nemetz
3d ago
|
15 | To 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 | |
| 17 | is how a `.deb` from a release page is named: | |
|
b7396a11
Keenan Nemetz
6h ago
|
18 | `.../vole/releases/v0.2.0/artifacts/vole_0.2.0-1_amd64.deb`, or `arm64` for an |
|
b8e7a567
Keenan Nemetz
3d ago
|
19 | `arm64` machine. |
| 20 | ||
|
95425af7
Keenan Nemetz
10d ago
|
21 | Both packages depend on `git` and the system SQLite library: `libsqlite3-0` on |
| 22 | Debian and Ubuntu, `sqlite-libs` on Fedora, RHEL, and Rocky. Vole links SQLite | |
| 23 | dynamically, so the library must be present where the binary runs; the package | |
|
41dd571f
Keenan Nemetz
10d ago
|
24 | manager installs it with the package. The system library must include SQLite's |
| 25 | FTS5 module, which every distribution listed above enables in its build; the | |
|
1265ea55
Keenan Nemetz
9d ago
|
26 | command palette is what needs it, and the binary carries the tag that asks for it |
|
41dd571f
Keenan Nemetz
10d ago
|
27 | when the driver's bundled copy is used instead. |
|
95425af7
Keenan Nemetz
10d ago
|
28 | |
|
3b39a84c
Keenan Nemetz
14d ago
|
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 | | |
|
e21f6c5e
Keenan Nemetz
3d ago
|
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) | | |
|
9704d735
Keenan Nemetz
5h ago
|
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) | | |
|
3b39a84c
Keenan Nemetz
14d ago
|
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 | ||
| 43 | The package creates the `vole` service account and runs `vole admin init` against | |
|
ab326d3a
Keenan Nemetz
14d ago
|
44 | the shipped config. It does not create an instance admin and does not enable the |
|
3b39a84c
Keenan Nemetz
14d ago
|
45 | service: who may administer the instance is the operator's decision, not the |
| 46 | package's. | |
| 47 | ||
| 48 | The shipped config listens on `0.0.0.0:2222` for SSH and `127.0.0.1:8080` for the | |
|
642e5994
Keenan Nemetz
14d ago
|
49 | web. Open 2222 in the firewall, set `public_url` before anyone signs in with a |
| 50 | passkey, and either terminate TLS in a proxy in front of 8080 or use `https_addr` | |
|
ed181212
Keenan Nemetz
13d ago
|
51 | to let Vole obtain certificates itself. See |
|
642e5994
Keenan Nemetz
14d ago
|
52 | [Configuration § Automatic HTTPS with ACME](configuration.md#automatic-https-with-acme) |
| 53 | and [Configuration § Running behind a proxy](configuration.md#running-behind-a-proxy). | |
|
3b39a84c
Keenan Nemetz
14d ago
|
54 | |
|
ed181212
Keenan Nemetz
13d ago
|
55 | The unit is written for the packaged layout and is safe to use as shipped: it |
| 56 | drops all capabilities, sets `UMask=0027`, gives the service a private `/tmp` and | |
| 57 | device tree, hides other processes, and makes `/var/lib/vole` the only writable | |
| 58 | path. If you need to bind a port below 1024 — SSH on 2222 does not, HTTP on 80 and | |
| 59 | HTTPS on 443 do — add the one capability with a drop-in, which must widen the | |
| 60 | bounding set as well: | |
| 61 | ||
| 62 | ```ini | |
| 63 | # /etc/systemd/system/vole.service.d/bind.conf | |
| 64 | [Service] | |
| 65 | CapabilityBoundingSet=CAP_NET_BIND_SERVICE | |
| 66 | AmbientCapabilities=CAP_NET_BIND_SERVICE | |
| 67 | ``` | |
| 68 | ||
| 69 | `MemoryDenyWriteExecute=true` is safe for the forge because it runs no JIT. A CI | |
| 70 | runner executes repository code in containers and is a separate process with its | |
| 71 | own unit; do not relax this unit to accommodate it. | |
| 72 | ||
|
3b39a84c
Keenan Nemetz
14d ago
|
73 | ## First steps after install |
| 74 | ||
| 75 | ```sh | |
|
2e024cc9
Keenan Nemetz
14d ago
|
76 | vole admin --config /etc/vole/vole.toml account create you --key ~/.ssh/id_ed25519.pub |
|
3b39a84c
Keenan Nemetz
14d ago
|
77 | vole admin --config /etc/vole/vole.toml repo create demo --owner you |
|
2e024cc9
Keenan Nemetz
14d ago
|
78 | vole admin --config /etc/vole/vole.toml acl set-default-role demo read |
|
3b39a84c
Keenan Nemetz
14d ago
|
79 | systemctl enable --now vole |
| 80 | ``` | |
| 81 | ||
| 82 | Run admin commands as the `vole` user or with `--config /etc/vole/vole.toml`; the | |
| 83 | service account owns the files they write. A command that writes as the wrong user | |
| 84 | leaves state the service cannot open, so prefer: | |
| 85 | ||
| 86 | ```sh | |
|
2e024cc9
Keenan Nemetz
14d ago
|
87 | sudo -u vole vole admin --config /etc/vole/vole.toml account list |
|
3b39a84c
Keenan Nemetz
14d ago
|
88 | ``` |
| 89 | ||
| 90 | ## Upgrading | |
| 91 | ||
| 92 | `users.db` is migrated in place the first time a newer binary opens it, and the | |
| 93 | migration cannot be rolled back. Back up before upgrading: | |
| 94 | ||
| 95 | ```sh | |
|
2e024cc9
Keenan Nemetz
14d ago
|
96 | sudo -u vole vole admin --config /etc/vole/vole.toml account backup /var/lib/vole/users.db.bak |
|
3b39a84c
Keenan Nemetz
14d ago
|
97 | sudo cp /var/lib/vole/data/ssh_host_ed25519_key /var/lib/vole/ssh_host_ed25519_key.bak |
| 98 | ``` | |
| 99 | ||
| 100 | Then install the new package. See [Operations](operations.md) for what else is | |
| 101 | worth 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 | |
| 106 | the tests, it cross-compiles the binary for both architectures, and it packages | |
| 107 | each 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 | |
| 109 | release with `release: true`, so they appear on the release page like any other | |
| 110 | attached file. | |
| 111 | ||
| 112 | Two 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 | |
|
95425af7
Keenan Nemetz
10d ago
|
117 | installs `git`, the C toolchain, and both architectures' SQLite development |
| 118 | files (see `.vole/images/release.yaml`). | |
|
3b39a84c
Keenan Nemetz
14d ago
|
119 | - **Nothing else.** The binaries are cross-compiled, so any runner that can start a |
| 120 | Linux container produces the same four packages. | |
| 121 | ||
| 122 | Reproduce a release locally without a runner, from the tag: | |
| 123 | ||
| 124 | ```sh | |
| 125 | git switch --detach v0.2.0 | |
| 126 | go run ./cmd/vole workflow run release | |
| 127 | ``` | |
| 128 | ||
| 129 | That runs the steps in your working tree as a check of the commands. It does not | |
| 130 | publish 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 | ||
| 133 | The version comes from `git describe --tags --exact-match`, so a checkout with no | |
| 134 | tag stops before building anything. | |
| 135 | ||
| 136 | ## The package definition is checked on every push | |
| 137 | ||
|
91e6a33a
Keenan Nemetz
14d ago
|
138 | The CI workflow (`.vole/workflows/verify.yaml`) builds one architecture and packages |
|
3b39a84c
Keenan Nemetz
14d ago
|
139 | it with the same `packaging/nfpm.yaml` on every branch push. A broken definition, |
| 140 | install path, or unit file therefore fails the push that broke it, instead of the | |
| 141 | tag that cannot be rebuilt. |