109 lines
4.5 KiB
Markdown
109 lines
4.5 KiB
Markdown
# Gitea — so the VM sub-agent can publish what it built
|
|
|
|
Fifteen minutes. **Optional**: without it a session still runs, still keeps its files in
|
|
the project folder on the array, and simply returns no link.
|
|
|
|
You need a Gitea instance first — see
|
|
[../deployment/gitea.compose.yml](../deployment/gitea.compose.yml) if you do not have one.
|
|
|
|
## What it is for
|
|
|
|
When a session finishes, vmd commits the project folder and pushes it to a repository named
|
|
after the project, then cuts a release. The user gets one link. The agent never touches
|
|
git: the token stays on the host, the commit runs with hooks disabled under a non-root
|
|
user, and a scratch filter keeps test scripts out of what gets published.
|
|
|
|
## Steps
|
|
|
|
1. **Create an organisation** to hold the repositories. Signed in as an admin:
|
|
*+ → New Organisation*. Call it `vmlab` or whatever you like.
|
|
|
|
Set its visibility to **Limited** if you want the repositories visible to signed-in
|
|
users only. The repositories themselves are created public *within* that org, so the
|
|
org's visibility is what controls who can see them.
|
|
|
|
2. **Create a bot account.** *Site Administration → Identity & Access → Users → Create
|
|
User*. Name it `vmagent`. Give it a long random password you will not need again, and
|
|
untick "require password change".
|
|
|
|
3. **Add the bot to the organisation** as a member with **write** access to repositories.
|
|
|
|
4. **Generate a token as the bot.** Sign in as it, then *Settings → Applications →
|
|
Generate New Token*. It needs:
|
|
- `write:repository`
|
|
- `write:organization`
|
|
|
|
Copy it now; Gitea shows it once.
|
|
|
|
5. **Put it on the host**, in `/etc/owuivm/vmd.env`:
|
|
|
|
```
|
|
OWUITOOLS_GITEA_URL=http://192.168.1.10:7200
|
|
OWUITOOLS_GITEA_PUBLIC_URL=https://git.example.com
|
|
OWUITOOLS_GITEA_ORG=vmlab
|
|
OWUITOOLS_GITEA_BOT=vmagent
|
|
OWUITOOLS_GITEA_TOKEN=<the token>
|
|
```
|
|
|
|
`configs/vmd.env` is the template this file is created from; edit the live copy, since
|
|
`install.sh` never overwrites it once it exists.
|
|
|
|
6. **Let the daemon reach it.** `vm/host/owuivmd.service` runs with
|
|
`IPAddressDeny=any` and an allowlist. Gitea's address has to be on it:
|
|
|
|
```ini
|
|
IPAddressAllow=192.168.1.10/32
|
|
IPAddressAllow=172.28.0.0/16
|
|
```
|
|
|
|
**Both lines.** The first is the LAN address you push to. The second is the Docker
|
|
network Gitea's container is on, and it is not redundant: systemd's filter is a BPF
|
|
program on the cgroup's packets, and by the time it sees them Docker's DNAT has already
|
|
rewritten the destination to the container's own address. Measured — with only the
|
|
`/32`, the connection times out.
|
|
|
|
7. `sudo ./vm/host/install.sh && sudo systemctl restart owuivmd`
|
|
|
|
## Checking it
|
|
|
|
This asks Gitea, as the daemon, using the credentials it will actually use:
|
|
|
|
```sh
|
|
sudo -u owuivmd python3 - <<'PY'
|
|
import json, urllib.request
|
|
env = {}
|
|
for line in open("/etc/owuivm/vmd.env"):
|
|
line = line.strip()
|
|
if line and not line.startswith("#") and "=" in line:
|
|
key, value = line.split("=", 1)
|
|
env[key] = value
|
|
token = env.get("OWUITOOLS_GITEA_TOKEN", "")
|
|
if not token:
|
|
raise SystemExit("no OWUITOOLS_GITEA_TOKEN in /etc/owuivm/vmd.env")
|
|
url = env.get("OWUITOOLS_GITEA_URL", "").rstrip("/")
|
|
org = env.get("OWUITOOLS_GITEA_ORG", "")
|
|
request = urllib.request.Request(f"{url}/api/v1/orgs/{org}",
|
|
headers={"Authorization": f"token {token}"})
|
|
answer = json.load(urllib.request.urlopen(request, timeout=15))
|
|
print(f"OK: reached {url} and the token can see the '{answer['username']}' organisation")
|
|
PY
|
|
```
|
|
|
|
Running it as `owuivmd` is the point — it proves the daemon can read the file *and* that
|
|
the address filter in its unit permits the connection, which is the step most likely to be
|
|
wrong. A timeout here almost always means step 6 was missed or only half done.
|
|
|
|
Otherwise, run a session and see whether the result carries a link.
|
|
|
|
## Two things worth knowing
|
|
|
|
**The token is never given to the machine or to the agent container.** vmd does the clone,
|
|
commit and push on the host and supplies the credential at push time through `GIT_ASKPASS`.
|
|
A guest that reads its own project folder finds no credential in it.
|
|
|
|
**Only the release archive downloads.** On a Gitea release page, uploaded assets are served
|
|
`inline` — a browser opens them rather than saving them, even a `.zip`. Only the
|
|
auto-generated *Source code (zip)* is served as an attachment. So what a user actually
|
|
downloads is built from the commit, which is why the scratch filter operates on the commit
|
|
rather than on the asset list.
|