Descoperit la prima sincronizare reala din Drive: `maria-sync.timer` a pornit peste rularea manuala si doua procese faceau embeddings in paralel pe acelasi Ollama, ambele urmand sa scrie acelasi rag_index.json. Embedding-ul a incetinit de la ~7s la ~20s din concurenta, iar ultimul care termina ar fi suprascris munca celuilalt. - config.exclusive(): lacat `flock` intre procese, luat la intrarea in sync.py si indexer.py. Nu asteapta — a doua rulare iese curat cu "o reindexare e deja in curs", fiindca ar reface exact acelasi lucru. Verificat pe procese reale. - indexer scrie indexul atomic (tmp + os.replace): consumer-ul reciteste fisierul la 30s si putea prinde un JSON pe jumatate scris. - build() intoarce `warnings` pentru XML-urile care nu se pot parsa, iar rularea din linia de comanda le scrie in stderr. Pana acum, un XML invalid se indexa tacut ca text simplu, cu o singura linie pierduta in log. Context de performanta, masurat pe LXC 171 fara alta incarcare: un embedding `nomic-embed-text` ia ~7,3s, deci o reindexare completa a celor 173 de chunk-uri dureaza ~21 de minute — mai mult decat intervalul timer-ului. Nu e o problema practica (amprenta reindexeaza doar la schimbare, iar lacatul opreste suprapunerea), dar explica de ce prima rulare pare blocata. docs/rclone-google-drive-headless.md: procedura de conectare a unui container headless la Drive prin `rclone authorize`, cu transcriptul rularii reale de pe Windows, capcanele (sync e distructiv pe destinatie, connection string in loc de cale pe nume, unde stau secretele) si de ce nu contul de serviciu. Indexata in CLAUDE.md. 6 teste noi (lacat, eliberare la exceptie, scriere atomica, avertismente). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4uzvgm7AyJch5WH8QHRhY
5.3 KiB
rclone + Google Drive pe un container headless (fără cont de serviciu)
Procedura de conectare a unui container Linux fără browser la Google Drive.
Folosită prima dată pentru depozitul de documente al Mariei (LXC 171,
maria-whatsapp-bridge), dar e generală — se aplică oricărui container din cluster.
Ideea: autorizarea OAuth are nevoie de un browser, containerul nu are. Deci autorizezi pe o mașină care are browser (stația Windows), iar rclone îți dă un token pe care îl muți pe container. Nu e nevoie de cont de serviciu și nu se atinge deloc consola Google Cloud.
De ce nu contul de serviciu
Prima variantă documentată era un service account în Google Cloud Console, cu dosarul
din Drive partajat către adresa lui. Funcționează, dar cere: proiect în Google Cloud,
activare Drive API, creare cont, descărcare JSON, partajare manuală a dosarului. Șapte
pași în două interfețe. rclone authorize face același lucru în doi pași, dintr-o
fereastră de browser deja autentificată.
Contul de serviciu rămâne varianta mai bună doar dacă ai nevoie de acces care nu depinde de niciun cont de om (ex. un serviciu care trebuie să meargă și după ce omul respectiv pleacă din firmă).
Pasul 1 — autorizezi pe Windows
Descarcă arhiva portabilă de la https://rclone.org/downloads/ (rclone-vX-windows-amd64.zip),
dezarhiveaz-o oriunde — nu cere instalare. În acel dosar:
rclone.exe authorize "drive" --drive-scope=drive.readonly
drive.readonly fiindcă sincronizarea doar citește. Dacă ai nevoie și de scriere,
folosește drive, dar atunci un rclone sync greșit poate șterge în Drive.
Se deschide browserul. Dacă nu se deschide, rclone scrie linkul în consolă. Cum arată o rulare reușită:
C:\Users\mmari\Downloads\rclone-v1.75.0-windows-amd64>rclone.exe authorize "drive" --drive-scope=drive.readonly
NOTICE: Config file "C:\\Users\\mmari\\AppData\\Roaming\\rclone\\rclone.conf" not found - using defaults
NOTICE: Make sure your Redirect URL is set to "http://127.0.0.1:53682/" in your custom config.
NOTICE: If your browser doesn't open automatically go to the following link: http://127.0.0.1:53682/auth?state=...
NOTICE: Log in and authorize rclone for access
NOTICE: Waiting for code...
NOTICE: Got code
Paste the following into your remote machine --->
{"access_token":"ya29...","token_type":"Bearer","refresh_token":"1//03...","expiry":"...","expires_in":3599}
<---End paste
Cele două mesaje despre „Config file not found" și „Redirect URL" nu sunt erori —
authorize nu scrie niciun config pe Windows, doar obține tokenul. Dosarul rclone de
pe Windows poate fi șters după.
Copiază tot JSON-ul dintre ---> și <---, inclusiv acoladele.
Pasul 2 — creezi remote-ul pe container
rclone config create gdrive drive \
scope=drive.readonly \
token='<TOKEN_JSON>' \
--non-interactive
Ghilimelele simple sunt obligatorii — JSON-ul conține ghilimele duble.
Pentru Maria există un script care face pasul ăsta plus verificarea, scrierea în env și
prima sincronizare: maria-whatsapp-bridge/ops/setup-drive.sh '<TOKEN_JSON>'.
Pasul 3 — fixezi dosarul după ID, nu după nume
rclone lsf 'gdrive,root_folder_id=<FOLDER_ID>:'
<FOLDER_ID> e din URL-ul dosarului în Drive
(https://drive.google.com/drive/folders/<FOLDER_ID>).
Sintaxa remote,parametru=valoare: e „connection string"-ul rclone. Folosește-o în loc
de căi pe nume (gdrive:romfast/document_store): calea pe nume se rupe dacă dosarul e
mutat sau redenumit în Drive, iar rclone sync nu dă eroare — pur și simplu nu găsește
nimic și, dacă e sincronizare bidirecțională, poate goli destinația.
Unde stau secretele
Tokenul ajunge în ~/.config/rclone/rclone.conf pe container. Fișierul conține
refresh_token, adică acces continuu la Drive-ul contului — nu ajunge niciodată în
git și nu se copiază între containere.
access_token expiră într-o oră; refresh_token îl reînnoiește singur, la nesfârșit,
cât timp aplicația rămâne autorizată în contul Google. Se poate revoca oricând din
https://myaccount.google.com/permissions.
Dacă tokenul e revocat sau expiră, sincronizarea începe să eșueze — se reiau pașii 1-2.
Capcane
rclone synce distructiv pe destinație. Șterge local ce nu mai există în sursă. Depozitul devine o oglindă a dosarului din Drive, nu o colecție care crește: un fișier pus manual acolo dispare la prima sincronizare. Dacă vrei doar adăugare, erclone copy.- Filtrează ce aduci.
--include '*.md' --include '*.xml'etc. Un dosar de Drive strânge în timp tot felul de lucruri (.json,.ps1,.docx) care n-au ce căuta în depozit. rclone authorizenu merge pe container, nici prin Tailscale: pornește un server local pe127.0.0.1:53682la care redirectează Google, deci browserul trebuie să fie pe aceeași mașină.- Versiunea de pe container poate fi mai veche decât cea de pe Windows (aici: 1.60.1 vs 1.75.0). Nu contează pentru token — formatul e stabil de mult.
Vezi și
proxmox/lxc171-claude-agent/maria-whatsapp-bridge/README.md, secțiunea „Sincronizare cu Google Drive" — configurarea concretă pentru Maria.proxmox/lxc171-claude-agent/maria-whatsapp-bridge/ops/setup-drive.sh— scriptul care face pașii 2-3 plus prima sincronizare.