vibed-infra 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/github/__pycache__/notify-vps-pull.cpython-312.pyc +0 -0
- package/lib/__pycache__/generate.cpython-312.pyc +0 -0
- package/lib/__pycache__/github_oidc.cpython-312.pyc +0 -0
- package/lib/__pycache__/load_config.cpython-312.pyc +0 -0
- package/lib/__pycache__/product_config.cpython-312.pyc +0 -0
- package/lib/__pycache__/webhook.cpython-312.pyc +0 -0
- package/lib/persistlog/__pycache__/__init__.cpython-312.pyc +0 -0
- package/lib/product_config.py +10 -1
- package/package.json +1 -1
- package/skills/agent-vps-prep/SKILL.md +119 -0
- package/skills/system-gateway/SKILL.md +4 -1
- package/templates/host-gateway/setup-tls.sh +27 -7
- package/templates/update-agent/__pycache__/webhook_server.cpython-312.pyc +0 -0
package/README.md
CHANGED
|
@@ -19,6 +19,8 @@ git add dist && git commit && git push
|
|
|
19
19
|
|
|
20
20
|
## Operator flow (VPS)
|
|
21
21
|
|
|
22
|
+
Non-root agent prep (SSH, Docker group, uid 1000 data dirs): [`skills/agent-vps-prep/SKILL.md`](skills/agent-vps-prep/SKILL.md).
|
|
23
|
+
|
|
22
24
|
```bash
|
|
23
25
|
# 1) DNS — paste dist/DNS-SKILL.md into AU browser agent
|
|
24
26
|
# 2) App roles
|
|
@@ -62,7 +64,7 @@ See [`skills/infra-update-agent/SKILL.md`](skills/infra-update-agent/SKILL.md).
|
|
|
62
64
|
| `templates/update-agent/` | Queue agent + webhook |
|
|
63
65
|
| `templates/persist-logs/` | Shipper install |
|
|
64
66
|
| `lib/persistlog/` | Python append / seal / replay |
|
|
65
|
-
| `skills/` | system-gateway, infra-update-agent, infra-cicd, infra-packager, persist-logs, dns-configure |
|
|
67
|
+
| `skills/` | system-gateway, agent-vps-prep, infra-update-agent, infra-cicd, infra-packager, persist-logs, dns-configure |
|
|
66
68
|
|
|
67
69
|
## Environment
|
|
68
70
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lib/product_config.py
CHANGED
|
@@ -220,7 +220,16 @@ def dump_yaml(data: Any, indent: int = 0) -> str:
|
|
|
220
220
|
else:
|
|
221
221
|
lines.append(f"{sp}{pref}{k}: {v}")
|
|
222
222
|
else:
|
|
223
|
-
|
|
223
|
+
s = str(item)
|
|
224
|
+
if isinstance(item, bool):
|
|
225
|
+
s = "true" if item else "false"
|
|
226
|
+
elif item is None:
|
|
227
|
+
s = ""
|
|
228
|
+
elif any(c in s for c in ":{}[]#&*!|>'\"%@`") or s == "" or s.lower() in (
|
|
229
|
+
"null", "true", "false", "yes", "no", "on", "off",
|
|
230
|
+
):
|
|
231
|
+
s = json.dumps(s)
|
|
232
|
+
lines.append(f"{sp}- {s}")
|
|
224
233
|
return "\n".join(lines) + ("\n" if lines else "")
|
|
225
234
|
return f"{sp}{data}\n"
|
|
226
235
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-vps-prep
|
|
3
|
+
description: >-
|
|
4
|
+
Prepare a fresh VPS for vibed-infra installs run by an automation agent
|
|
5
|
+
(cloud_agent): SSH key, sudoers, Docker group, data-dir ownership, firewall.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Prepare a VPS for vibed-infra (agent operator)
|
|
9
|
+
|
|
10
|
+
## Who this is for
|
|
11
|
+
|
|
12
|
+
Non-root user (e.g. `cloud_agent`) that will run `wget …/dist/install-*.sh | bash`,
|
|
13
|
+
`setup-tls.sh` (docker certbot), and `start-*.sh` without interactive sudo.
|
|
14
|
+
|
|
15
|
+
## 1. Create the operator user
|
|
16
|
+
|
|
17
|
+
(as root)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
adduser --disabled-password --gecos "" cloud_agent
|
|
21
|
+
mkdir -p /home/cloud_agent/.ssh
|
|
22
|
+
chmod 700 /home/cloud_agent/.ssh
|
|
23
|
+
# paste agent public key:
|
|
24
|
+
echo 'ssh-ed25519 AAAA… cloud_agent' >> /home/cloud_agent/.ssh/authorized_keys
|
|
25
|
+
chmod 600 /home/cloud_agent/.ssh/authorized_keys
|
|
26
|
+
chown -R cloud_agent:cloud_agent /home/cloud_agent/.ssh
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 2. SSH from the agent machine
|
|
30
|
+
|
|
31
|
+
Generate a key if needed, then connect with `StrictHostKeyChecking=accept-new`:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
ssh-keygen -t ed25519 -f ~/.ssh/cloud_agent_vps -N ""
|
|
35
|
+
ssh -o StrictHostKeyChecking=accept-new -i ~/.ssh/cloud_agent_vps cloud_agent@VPS_IP
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 3. Install Docker + add user to docker group
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# as root — use distro docs or https://get.docker.com
|
|
42
|
+
usermod -aG docker cloud_agent
|
|
43
|
+
# cloud_agent must re-login for group to apply
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Verify as `cloud_agent`: `docker ps` (no sudo).
|
|
47
|
+
|
|
48
|
+
## 4. Home ownership
|
|
49
|
+
|
|
50
|
+
If home was created oddly (root-owned `$HOME`):
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
sudo chown -R cloud_agent:cloud_agent /home/cloud_agent
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
vibed-infra defaults: `~/services/gateway`, `~/services/vibed-infra`, product dirs under `~/services/<app>/`.
|
|
57
|
+
|
|
58
|
+
## 5. Container data directory ownership (uid 1000)
|
|
59
|
+
|
|
60
|
+
Product images often run as `node` (uid/gid **1000**). Bind-mounted `./data` and `./logs` created by `cloud_agent` (e.g. uid 1001) cause `SQLITE_CANTOPEN` / `EACCES`.
|
|
61
|
+
|
|
62
|
+
**One-shot after first install (or before first start), as root/sudo:**
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Trustless Commerce / typical vibed apps — adjust paths to your INSTALL_DIRs
|
|
66
|
+
sudo chown -R 1000:1000 \
|
|
67
|
+
/home/cloud_agent/services/*/api/data \
|
|
68
|
+
/home/cloud_agent/services/*/api/persist-logs \
|
|
69
|
+
/home/cloud_agent/services/*/nodes/logs
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Or per product:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
sudo chown -R 1000:1000 ~/services/tctest/api/data ~/services/tctest/api/persist-logs
|
|
76
|
+
sudo chown -R 1000:1000 ~/services/tcmain/api/data ~/services/tcmain/api/persist-logs
|
|
77
|
+
sudo chown -R 1000:1000 ~/services/tctest/nodes/logs ~/services/tcmain/nodes/logs
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Optional: allow passwordless chown for the agent (tight sudoers):
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# /etc/sudoers.d/cloud_agent-chown
|
|
84
|
+
cloud_agent ALL=(root) NOPASSWD: /usr/bin/chown -R 1000\:1000 /home/cloud_agent/services/*
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Prefer the explicit one-shot; sudoers is optional.
|
|
88
|
+
|
|
89
|
+
Note: start scripts may try `sudo chown` or a docker alpine chown — host sudo still helps for empty dirs created as the operator user.
|
|
90
|
+
|
|
91
|
+
## 6. Ports + DNS
|
|
92
|
+
|
|
93
|
+
- Free **80/443** for the host gateway (only vps-gateway binds them)
|
|
94
|
+
- Point DNS A records at `gateway.publicIp` before `setup-tls.sh` (Let’s Encrypt)
|
|
95
|
+
|
|
96
|
+
## 7. TLS (no host certbot required)
|
|
97
|
+
|
|
98
|
+
With Docker, `setup-tls.sh` uses `certbot/certbot` and writes PEMs under `~/services/gateway/certs/`. No sudo needed for LE when docker works. See [system-gateway](../system-gateway/SKILL.md).
|
|
99
|
+
|
|
100
|
+
## 8. First product install
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
export INSTALL_DIR=$HOME/services/myapp/api
|
|
104
|
+
mkdir -p "$INSTALL_DIR"
|
|
105
|
+
wget -qO- https://raw.githubusercontent.com/ORG/REPO/main/deploy/.../dist/install-api.sh | bash
|
|
106
|
+
# edit .env, then ./start-api.sh
|
|
107
|
+
# repeat ui, nodes, gateway
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Important:** `export INSTALL_DIR=...` before the pipe — `INSTALL_DIR=... wget | bash` does **not** pass the var into bash.
|
|
111
|
+
|
|
112
|
+
## 9. Checklist
|
|
113
|
+
|
|
114
|
+
- [ ] `ssh cloud_agent@VPS` works with key only
|
|
115
|
+
- [ ] `docker ps` works without sudo
|
|
116
|
+
- [ ] `$HOME` owned by `cloud_agent`
|
|
117
|
+
- [ ] uid 1000 chown on data/logs after first mkdir/install
|
|
118
|
+
- [ ] DNS → VPS IP
|
|
119
|
+
- [ ] install-gateway + setup-tls + start-gateway
|
|
@@ -7,6 +7,8 @@ description: >-
|
|
|
7
7
|
|
|
8
8
|
# System-wide host gateway (multi-app)
|
|
9
9
|
|
|
10
|
+
Fresh VPS as non-root agent: see [agent-vps-prep](../agent-vps-prep/SKILL.md).
|
|
11
|
+
|
|
10
12
|
## Model
|
|
11
13
|
|
|
12
14
|
```
|
|
@@ -55,7 +57,7 @@ cd ~/services/gateway
|
|
|
55
57
|
./setup-tls.sh --force # re-issue after host or IP change
|
|
56
58
|
```
|
|
57
59
|
|
|
58
|
-
- **Production:** `setup-tls.sh` issues Let’s Encrypt via docker `certbot/certbot` by default (config under `$GATEWAY_HOME/letsencrypt`, PEMs
|
|
60
|
+
- **Production:** `setup-tls.sh` issues Let’s Encrypt via docker `certbot/certbot` by default (config under `$GATEWAY_HOME/letsencrypt`, PEMs installed into `$GATEWAY_HOME/certs/` — direct `cp` when readable, else alpine container copy+chown for root-owned `live/`). No sudo required when Docker is available. Host certbot + sudo still preferred when present (same `--config-dir` under gateway home). Webroot if gateway is up, else standalone. On failure, fix DNS then re-run `setup-tls.sh`.
|
|
59
61
|
- **Lab/CI:** `TLS_MODE=lab` → multi-SAN self-signed under `./certs/`.
|
|
60
62
|
|
|
61
63
|
## Webhook path (immediate docker pull)
|
|
@@ -64,6 +66,7 @@ Host `00-default.conf` (HTTP) and each app `sites.conf` (HTTPS) proxy `/_vibed/h
|
|
|
64
66
|
|
|
65
67
|
## Pitfalls
|
|
66
68
|
|
|
69
|
+
- Operator user / Docker / uid 1000 data dirs: [agent-vps-prep](../agent-vps-prep/SKILL.md).
|
|
67
70
|
- Do not run a second standalone nginx on 80/443.
|
|
68
71
|
- Container names in `sites.conf` must match running API/UI names on `vps-edge`.
|
|
69
72
|
- After cert renewal or `setup-tls.sh`, reload happens automatically when the gateway container is already running.
|
|
@@ -254,13 +254,33 @@ EOF
|
|
|
254
254
|
return 0
|
|
255
255
|
fi
|
|
256
256
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
257
|
+
# Copy PEMs into CERT_DIR without sudo. Docker certbot leaves root-owned live/
|
|
258
|
+
# (mode 700); host path may be readable after sudo chown above.
|
|
259
|
+
install_pems_to_certs() {
|
|
260
|
+
local primary="$1"
|
|
261
|
+
local live="${LE_HOME}/live/${primary}"
|
|
262
|
+
mkdir -p "$CERT_DIR"
|
|
263
|
+
if [[ -r "${live}/fullchain.pem" && -r "${live}/privkey.pem" ]]; then
|
|
264
|
+
cp -L "${live}/fullchain.pem" "${CERT_DIR}/fullchain.pem"
|
|
265
|
+
cp -L "${live}/privkey.pem" "${CERT_DIR}/privkey.pem"
|
|
266
|
+
elif command -v docker >/dev/null 2>&1; then
|
|
267
|
+
# certbot container wrote root-owned live/; copy+chown via alpine
|
|
268
|
+
docker run --rm \
|
|
269
|
+
-v "${LE_HOME}:/etc/letsencrypt:ro" \
|
|
270
|
+
-v "${CERT_DIR}:/out" \
|
|
271
|
+
"${CERTBOT_HELPER_IMAGE:-alpine:3.20}" \
|
|
272
|
+
sh -c "cp -L /etc/letsencrypt/live/${primary}/fullchain.pem /out/fullchain.pem && cp -L /etc/letsencrypt/live/${primary}/privkey.pem /out/privkey.pem && chown $(id -u):$(id -g) /out/fullchain.pem /out/privkey.pem && chmod 644 /out/fullchain.pem && chmod 600 /out/privkey.pem"
|
|
273
|
+
else
|
|
274
|
+
echo "Cannot read ${live} PEMs (root-owned?) and docker unavailable to copy them" >&2
|
|
275
|
+
return 1
|
|
276
|
+
fi
|
|
277
|
+
if [[ ! -f "${CERT_DIR}/fullchain.pem" || ! -f "${CERT_DIR}/privkey.pem" ]]; then
|
|
278
|
+
echo "Failed to install PEMs into ${CERT_DIR}" >&2
|
|
279
|
+
return 1
|
|
280
|
+
fi
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
install_pems_to_certs "$primary"
|
|
264
284
|
chmod 644 "${CERT_DIR}/fullchain.pem"
|
|
265
285
|
chmod 600 "${CERT_DIR}/privkey.pem"
|
|
266
286
|
patch_env_key TLS_FULLCHAIN "${CERT_DIR}/fullchain.pem"
|
|
Binary file
|