[2026-09-02] eagle: family/documents/vault-sync/2026-09-02-restore-privilege-scope.md family/how-to/arr-stack-taiga.md family/how-to/vault-git-sync.md

This commit is contained in:
Alexey Martemyanov
2026-09-02 12:25:39 +06:00
parent 189a359651
commit 2b6c1817d1
3 changed files with 61 additions and 11 deletions
@@ -2,7 +2,7 @@
tags: [truenas, restore, incident, git, media, arr, permission]
created: 2026-09-02
updated: 2026-09-02
status: in-progress (Этап 0-3 done — transmission пересоздан под PUID=950 штатно, медиа-права рекурсивно исправлены; ОСТАЛОСЬ: git/nas/второй root-заход на добивку, запуск arr-стека, первый sync-vault на маке)
status: in-progress (Этап 0-3 + 2-й root-проход DONE — storage все 950, git-sync fetch ОК; ОСТАЛОСЬ основной блокер: NFS4 ACL DENY READ_DATA на ~1946 git-объектах → push на маке падает)
---
# Incident 2026-09-02: Поломка прав uid 921/0000 после restore — масштаб и влияния
@@ -169,11 +169,60 @@ ssh truenas_admin@mallexxx.duckdns.org 'bash /tmp/fix-storage-nfs4-acl.sh'
- ✅ **Этап 3 — рекурсивный фикс прав вглубь ВЫПОЛНЕН Alex (root) + проверен.** Результат верификации 2026-09-02:
- Медиа-папки → `950:950 drwxrwx---`: Cartoons, Downloads, Movies, Music, art, books, cartoons-series, documentaries(-series), series, shared, work. ✅
- Вглубь Movies: файлы → `950:950`, права разблокированы (`rw-r-----`/`rwxrwx---`). ✅
- **ЕЩЁ НЕ ДОБИТО (остаточек):** `git/` bare repo dir → `d--------- 950:950` (0000) → **git-sync на маке всё ещё стоит** `fatal: not a git repository`; `nas` (921/0000, не попал в chown/chmod), `ada3s1`, `photo_dedup_test`, `seafile`, `singularity` (0000/700); скрытые mac-файлы корня `.DS_Store/.bash*/.profile/.com.apple*` (921); сам корень `storage` → `921:921 drwxrwx---`.
- ✅ **Второй root-проход ВЫПОЛНЕН Alex (вторая команда ниже) — добиты `git`, `nas`, `ada3s1`, `photo_dedup_test`, `seafile`, `singularity`, `radarr`, `sonarr`:** все теперь `950:950 drwxrwx---`. Проверено:
- Все топ-папки storage теперь `950:950 drwxrwx---` (сплошняком, кроме скрытых файлов корня и самого корня). ✅
- `storage/git/obsidian-vault.git` теперь **открывается** — `git log` показывает коммиты (HEAD `a2c72793` [2026-08-17]...).
- `git/nas` уже не «matching вне-списка» — chown/chmod догнаны вторым проходом.
### ⬜ Остаточный root-шаг (второй проход, готов для Alex) — добить git + nas + прочее
### ⬜ Найден БЛОКЕР PUSH: NFS4 ACL `DENY READ_DATA` на тировых объектах git-репозитория
Команда подготовлена в сессии, Alex ещё не запускал:
**Симптом (после починки прав):** на маке git-sync теперь:
```
git fetch nas main → OK (bare repo доступен, fetch exit=0)
git push nas main → FAIL:
remote: fatal: loose object acd1b45542e82aa40f345da3b8ac9f721633b138 ... is corrupt
remote unpack failed: index-pack abnormal exit
```
`sync-vault.sh` — `Committed` потом `Push failed`. Ahead вырос 55 → 62 (коммиты локально копятся, не пушатся).
**Диагностика — это НЕ повреждение данных, а NFS4 ACL-блокировка чтения:**
| Проверка | Результат |
|---|---|
| `git fsck --full` через **root** (контейнер gitea, монтирует `/git-repos`) | ЧИСТО: только `dangling commit/tree`, **ни одного corrupt/missing/bad** |
| `git cat-file -t acd1b45...` под root (gitea) | `tree` — объект читается, цел |
| NFS4 ACL самого файла `objects/ac/d1b...` (через `filesystem.getacl`) | **`owner@ DENY READ_DATA=True`** поверх `ALLOW` → перекрывает |
**Суть:** у ~**1946 из 3373** loose git-объектов в `obsidian-vault.git/objects/` стоит битый NFS4 ACL `owner@ type=DENY READ_DATA=True`. DENY-запись в NFSv4 **перекрывает ALLOW**, поэтому владелец (uid 950 = truenas_admin) **не может mmap/прочитать эти объекты** при push. Git на приеме (`git-receive-pack`/`index-pack`) трактует нечитаемость как «loose object corrupt» → push rejected. Root игнорирует ACL → поэтому fsck под gitea чист, а push от 950 падает. **Данные целы.**
POSIX-признак битых файлов: **mode `40` (`r--------`)**; нормальные объекты — mode `750`. (count: 3373 объектов, ~1946 с mode 4xx.)
**Фикс (root/root-midclt) — ГОТОВ, Alex ещё не запускал (ждёт отдельного подтверждения, т.к. влияет на ACL объектов):**
```bash
# снять битые NFS4 ACL (DENY) на весь git-репозиторий, вернуть стандарт из uid/gid
midclt call filesystem.setacl /mnt/RED_2TB/storage/git/obsidian-vault.git \
'{"uid":950,"gid":950,"dacl":[],"options":{"recursive":true,"traverse":true,"stripacl":true}}'
# проверить, что проблемный объект читается владельцем:
git --git-dir=/mnt/RED_2TB/storage/git/obsidian-vault.git cat-file -t acd1b45542e82aa40f345da3b8ac9f721633b138
# затем с мака:
cd ~/obsidian && git push nas main
```
> ⚠️ `chmod`/`chown` НЕ снимает NFS4 `DENY` ACE — нужен именно `stripacl:true` (или `setfacl -Rb` на хосте, если доступен). TrueNAS SCALE: `setacl` с `stripacl:true` + пустым `dacl` переведёт на POSIX-default из owner@/group@.
> ⚠️ Перед применением снять бэкап ACL `git/` (read-only): `midclt call filesystem.getacl /mnt/RED_2TB/storage/git > ~/variantA_bk/git_after.acl`.
> ⚠️ Стоп-правило Alex: nothing destructive без явного подтверждения — не делался, ждёт команды.
**Куда попадают DENY-ACL:** артефакт restore — часть loose-объектов при переносе данных получили инверсивный NFS4 ACL (`owner@ DENY read`). Это НЕ родние git-права (git-репо хранит объекты как read-only `r--r--r--` в обычном случае); на полке после поломки.
### Диагностические insights (для будущих сессий)
- `docker exec transmission ...` даёт root вглубь `/mnt/storage` (transmission монтирует `storage`); `gitea` контейнер монтирует `/mnt/RED_2TB/storage/git → /git-repos` и имеет `git` — удобен для `git fsck`-честных проверок (root-контекст). `hermes-taiga` монтирует `/vault.git` = `storage/git/obsidian-vault.git` и тоже имеет git.
- NFS4 `owner@ DENY` перекрывает `ALLOW` — клинический кейс «ls показывает доступно, а процесс не читает».
- POSIX-бит файла (mode 40/750) коррелирует с NFS4 ACL; «corrupt» от `index-pack` при целых данных = почти всегда ACL/права на приеме, не реальное повреждение.
### ✅ Остаточный root-шаг (второй проход) — ВЫПОЛНЕН Alex; команда для справки (историческая)
> Уже пройдено — итоговое состояние `950:950 drwxrwx---` на всех топ-папках см. в Этапе 3 выше. Команда зафиксирована как рецепт для будущего:
```bash
S=/mnt/RED_2TB/storage
@@ -190,9 +239,9 @@ git --git-dir="$S/git/obsidian-vault.git" log --oneline -2 2>&1 | head # пр
> ⚠️ `rm -f` скрытых файлов корня — mac-мусор/остатки старого владельца 921, безопасно. Если `.profile`/`.bashrc` рабочие — убрать их из rm по решению.
### После остаточного фикса
- **На маке**: `bash ~/scripts/sync-vault.sh` → 55 коммитов уедут в bare repo (launchd возобновит); проверить `git log nas/main..main` = 0.
- **Arr-стек**: `cd /mnt/RED_2TB/docker/arr && docker compose up -d` → проверить `docker compose ps` + что jellyfin видит библиотеки (пути `/storage/*`).
### ⚠️ Текущий статус после второго прохода (актуально)
- **Push на маке БЛОКИРОВАН** NFS4 ACL `DENY READ_DATA` на ~1946 loose git-объектах — см. секцию «Найден БЛОКЕР PUSH» выше. Фикс `filesystem.setacl ... stripacl:true` ГОТОВ, Alex должен подтвердить.
- **Arr-стек**: после снятия DENY-блокера на git и починки прав медиа — `cd /mnt/RED_2TB/docker/arr && docker compose up -d` → проверить `docker compose ps` + что jellyfin видит библиотеки (пути `/storage/*`). PUID/PGID=950 уже прописаны во всех 4 сервисах докер-стека.
### Точное содержание transmission compose (оригинал, важно для пересоздания)
```yaml