Initial Commit
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user