Files
knowledge-base/snippets/openclaw-kb-webhook.md
dttb 80fd8ca7bf Липки: карточка объекта (клиент Антон, Cudy TR3000 100.70.35.234, белый WAN 5.101.135.71) + рецепт Gitea→openclaw kb-pull webhook
Закрывает причину #1 путаницы Максимки на запросах вида "OpenWRT Липки": слово "Липки" во всём vault встречалось только одной строкой в netbird-inventory, FTS вытаскивал НИИКН по статистике слова "OpenWRT".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:03:36 +03:00

149 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
date: 2026-05-06
type: snippet
tags: [openclaw, gitea, webhook, kb-sync]
---
# Webhook Gitea → kb-pull на LXC 137 (Максимка)
Сократить лаг Mac → openclaw FTS с **до 15 мин** (cron `*/15`) до **<5 секунд** через push-webhook от Gitea.
Cron оставляем как safety net — он почти ничего не стоит и спасает, если listener умер.
## Архитектура
```
Mac git push ──► Gitea (LXC 136, 10.0.0.189)
│ HTTP POST (push event)
LXC 137 :18790 kb-pull-webhook (systemd)
└─► /usr/local/bin/kb-pull.sh (тот же что в cron)
```
## 1. Listener `/usr/local/bin/kb-pull-webhook.py`
```python
#!/usr/bin/env python3
"""Слушает Gitea webhook, дёргает kb-pull.sh."""
import hmac, hashlib, http.server, os, subprocess
SECRET = os.environ.get('GITEA_WEBHOOK_SECRET', '').encode()
PULL = '/usr/local/bin/kb-pull.sh'
class H(http.server.BaseHTTPRequestHandler):
def do_POST(self):
n = int(self.headers.get('Content-Length', 0) or 0)
body = self.rfile.read(n)
if SECRET:
sig = self.headers.get('X-Gitea-Signature', '')
mac = hmac.new(SECRET, body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(sig, mac):
self.send_error(401); return
subprocess.Popen([PULL],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
self.send_response(202); self.end_headers()
self.wfile.write(b'queued\n')
def do_GET(self): # health-check
self.send_response(200); self.end_headers()
self.wfile.write(b'ok\n')
def log_message(self, fmt, *a): # без спама в journal
pass
if __name__ == '__main__':
port = int(os.environ.get('PORT', '18790'))
http.server.HTTPServer(('0.0.0.0', port), H).serve_forever()
```
```bash
chmod +x /usr/local/bin/kb-pull-webhook.py
```
## 2. systemd unit `/etc/systemd/system/kb-pull-webhook.service`
```ini
[Unit]
Description=KB pull webhook listener (Gitea -> kb-pull.sh)
After=network-online.target
[Service]
Type=simple
Environment=GITEA_WEBHOOK_SECRET=CHANGE_ME_LONG_RANDOM
Environment=PORT=18790
ExecStart=/usr/bin/python3 /usr/local/bin/kb-pull-webhook.py
Restart=on-failure
RestartSec=5
# Минимальные права — listener не пишет в /root, только запускает kb-pull.sh
NoNewPrivileges=yes
PrivateTmp=yes
[Install]
WantedBy=multi-user.target
```
```bash
systemctl daemon-reload
systemctl enable --now kb-pull-webhook.service
systemctl status kb-pull-webhook.service
ss -ltnp | grep 18790
```
Сгенерировать секрет:
```bash
openssl rand -hex 32
```
## 3. Webhook в Gitea UI
`git.dttb.ru` → репо `oleg/knowledge-base`**Settings → Webhooks → Add Webhook → Gitea**
| Поле | Значение |
|---|---|
| Target URL | `http://10.0.0.239:18790/` |
| HTTP Method | POST |
| Content Type | `application/json` |
| Secret | тот же, что в systemd unit |
| Trigger On | Push Events |
| Branch filter | `main` |
| Active | ✓ |
Жмём **Test Delivery** — должно прилететь `202 queued`.
## 4. Опционально: ограничить порт по источнику
Listener слушает на `0.0.0.0`. Если хочется — закрыть всё кроме Gitea LXC 136:
```bash
iptables -A INPUT -p tcp --dport 18790 -s 10.0.0.189 -j ACCEPT
iptables -A INPUT -p tcp --dport 18790 -j DROP
# или через nftables / netbird ACL — на вкус
```
## 5. Проверка end-to-end
```bash
# на Mac
cd ~/knowledge-base
date >> /tmp/test && git add -A && git commit -m "webhook test" && git push
# на LXC 137 — должна появиться свежая строка
pct exec 137 -- tail -3 /var/log/kb-pull.log
```
## Откат
```bash
systemctl disable --now kb-pull-webhook.service
rm /etc/systemd/system/kb-pull-webhook.service
rm /usr/local/bin/kb-pull-webhook.py
# в Gitea — деактивировать webhook
```
Cron `*/15` остаётся живым — KB продолжит синкаться по таймеру.
## Замечания
- **`openclaw memory` не переиндексируется автоматически** после `kb-pull`. Бот видит markdown сразу (он читает из FS), но FTS-индекс в `~/.openclaw/memory/main.sqlite` обновляется при следующем reindex-цикле. Если нужно ускорить — после pull можно дёргать `openclaw memory rebuild --incremental` (проверить наличие команды в текущей версии). Это уже отдельный шаг — добавить в `kb-pull.sh` после успешного `git pull`.
- На LXC 137 `kb-pull.sh` — простой ff-only с авто-reset при divergence. Webhook на нём ничего не ломает: тот же скрипт, та же блокировка `/tmp/kb-pull.lock`.