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

5.1 KiB
Raw Blame History

date, type, tags
date type tags
2026-05-06 snippet
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

#!/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()
chmod +x /usr/local/bin/kb-pull-webhook.py

2. systemd unit /etc/systemd/system/kb-pull-webhook.service

[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
systemctl daemon-reload
systemctl enable --now kb-pull-webhook.service
systemctl status  kb-pull-webhook.service
ss -ltnp | grep 18790

Сгенерировать секрет:

openssl rand -hex 32

3. Webhook в Gitea UI

git.dttb.ru → репо oleg/knowledge-baseSettings → 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:

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

# на 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

Откат

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.