12 KiB
Executable File
title, type, namespace, tags, date, status
| title | type | namespace | tags | date | status | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| obsidian-syncthing — root-owned objects + битый remote + путаница ACL/chown | log | family |
|
2026-09-26 | resolved |
obsidian-syncthing: 4031 root-объект, битый remote, ACL/chown не стоит
Когда: 2026-09-26, разбор по запросу Alex «почему документ не доехал до телефона».
Статус: ✅ РЕШЕНО — ACL с nas_users + INHERIT применён, синк работает (см. «РЕШЕНИЕ» ниже).
Симптом
Нота personal/plans/music-tags-review/1-needs-decision.md закоммичена и запушена с Mac
(66d4d62..f2501dc main -> main), но в клон /obsidian-syncthing на TrueNAS не попала.
git pull в клоне падает, а sync-vault.sh глушит ошибку (2>/dev/null) — синк выглядит
успешным.
Две независимые поломки
1. Битый remote в клоне (починено в этой сессии)
было: origin /vault.git ← потерян префикс пути
стало: origin /mnt/RED_2TB/storage/git/obsidian-vault.git
git fetch при этом падал с fatal: '/vault.git' does not appear to be a git repository.
Remote переписан через git remote set-url. Это не связано с правами — отдельный дефект.
2. Права: новые объекты пишет root (НЕ починено)
объекты от root: 4051 ← свежие, 2026-09-26 02:42
объекты от truenas_admin: 4 ← только старые pack с 2026-07-06
git fetch падает на записи:
error: insufficient permission for adding an object to repository database .git/objects
fatal: failed to write object
fatal: unpack-objects failed
Причина: контейнер hermes-taiga работает от root (docker inspect → Config.User
пусто, docker exec ... id → uid=0(root)). Именно он делает git pull в
/obsidian-syncthing — значит каждый новый loose-объект рождается root:root, а git под
truenas_admin (uid 950) писать в них не может.
ACL на obsidian-syncthing НЕ СТОИТ — trivial_acl: true
nfs4xdr_getfacl /mnt/RED_2TB/storage/obsidian-syncthing
# owner: 950 # group: 950 # mode: 0o40770
# trivial_acl: true ← расширенного ACL нет
owner@:rwxpD-aARWcCos:-------:allow
group@:rwxpD-a-R-c--s:-------:allow
everyone@:------a-R-c--s:-------:allow
Только дефолтный набор TrueNAS (owner@ / group@ / everyone@), ни одной именованной
записи. POSIX-вид (getfacl) показывает user::rwx group::rwx other::--- и скрывает
отсутствие расширенного ACL — поэтому диагностировать надо nfs4xdr_getfacl, а не getfacl.
🔴 Путаница: ACL ставился на Edu, не на obsidian-syncthing
Alex помнил, что фикс ACL уже делался («ты вроде ставил рекурсивный acl а не chown»).
Проверка по базе Hermes (state.db, таблица messages) нашла сессию
20260923_124118_9e70782e (2026-09-23) — там рекурсивный ACL действительно ставился,
но на /mnt/RED_2TB/Edu, по прямой просьбе Alex: «ты можешь просто группу под acl
сделать с inherit чтобы весь edu был доступен группе включающей truenas_admin?»
Что тогда было сделано (и сработало — на Edu):
# 1. бэкап ACL
midclt call filesystem.getacl /mnt/RED_2TB/Edu > .../acl-edu-before-YYYYmmdd-HHMMSS.json
# 2. setacl recursive: gid -> 3000 (nas_users) + INHERIT на всех ACE → job SUCCESS
# 3. chgrp -R nas_users → FAILED (Operation not permitted)
# 4. повтор через midclt setacl с uid/gid=3000 → job 15393 SUCCESS
Результат на Edu: drwxrwxr-x root:nas_users, gid=3000, все ACE INHERITED: True,
touch → WRITE_OK. Группа nas_users (gid 3000) — рабочая: в ней truenas_admin,
mallexxx, nas, root, transmission.
⚠️ Урок: «ACL уже ставили» ≠ «ACL стоит на этой папке». Правка была на
Edu. Наobsidian-syncthingрасширенного ACL не было никогда (trivial_acl: trueдоказывает). Прежде чем повторять «известный фикс» — проверить, что он на той самой папке.
🔴
chgrpотtruenas_adminдаётOperation not permitted. В NFSv4group@— это POSIX-gid файла, а не ACE. Без смены gid группа не получает ничего. Менять gid надо черезmidclt filesystem.setacl(root-контекст), а неchgrp/chownиз шелла.
✅ РЕШЕНИЕ (2026-09-26, после требования Alex «Да, ставь acl inherit»)
Alex отверг предложенные варианты и дал прямую команду: «Да, ставь acl inherit».
Выбран вариант A — ACL + INHERIT, применён на /mnt/RED_2TB/storage/obsidian-syncthing.
Что сделано (по порядку):
# 1. бэкап ACL
midclt call filesystem.getacl /mnt/RED_2TB/storage/obsidian-syncthing \
> /home/truenas_admin/variantA_bk/acl-obsidian-syncthing-before-20260926-154827.json
# 2. скрипт read-modify-write (файлом, не инлайном) → scp на NAS → python3
# payload: gid=3000 (nas_users), uid=950, recursive=true,
# все ACE → FILE_INHERIT+DIRECTORY_INHERIT, stripacl=false
# → job 25046 SUCCESS
# 3. remote клона
git remote set-url origin /mnt/RED_2TB/storage/git/obsidian-vault.git
Результат (проверено ФАКТОМ):
| До | После | |
|---|---|---|
nfs4xdr_getfacl |
trivial_acl: true |
trivial_acl: false |
group |
950 | 3000 (nas_users) |
| флаги ACE | ------- (NOINHERIT) |
fd----- (FILE+DIRECTORY_INHERIT) |
| объекты от root | 4051 | 0 (все 4073 = truenas_admin) |
git fetch |
падал | Already up to date |
новый файл touch |
— | truenas_admin:nas_users ✅ |
Наследование подтверждено: touch .inherit_test и mkdir .inherit_dir_test внутри папки
получили truenas_admin:nas_users (тестовые артефакты удалены после проверки).
Нота доехала: коммит с Mac f2501dc (1-needs-decision.md, разбор 28 файлов) найден в
истории клона, поверх уже лежал 8efe5c8 от Taiga.
🔴 ГЛАВНЫЙ ПИТФОЛЛ: midclt getacl = КЭШ
Сразу после setacl скрипт делал верификацию через midclt filesystem.getacl — и получал
старые значения (trivial: True, gid: 950, NOINHERIT), печатая ложный «VERIFY FAILED».
Правка на диске при этом была уже применена.
Реальное состояние проверять только:
nfs4xdr_getfacl <path>(trivial_acl: false, флагиfd-----) +stat -c '%A %U:%G %n'+ фактическийtouchнового файла. Не откатывать и не повторятьsetaclпо показаниямgetacl.
Альтернативный вариант B (не использован, для истории)
user: "950:950" в taiga service — устранил бы корень (контейнер не от root), но риск:
образ может требовать root для /opt/data. Оставлен как возможное усиление;
текущий ACL-INHERIT закрывает последствия.
ℹ️ Почему однократный chown не лечил (историческая справка)
Прошлый разовый chown объектов на truenas_admin чинил только уже существующие объекты.
Следующий git pull от root снова рождал root-owned объекты — и chown приходилось повторять.
Это лечение симптома. Перманентный фикс — либо ACL + INHERIT (новые объекты наследуют
права группы), либо запуск синка не от root (user: "950:950" в taiga service).
Что предлагается (решение за Alex)
| Вариант | Как | Плюс / минус |
|---|---|---|
| A. ACL + INHERIT | setfacl/midclt setacl с g:truenas_admin:rwx + d: (default) + chmod g+s |
root и uid 950 пишут одновременно; нужен контроль, что TrueNAS не сбросит ACL при операциях датасета |
| B. Контейнер не от root | user: "950:950" в taiga service /mnt/RED_2TB/docker/hermes/docker-compose.yml |
устраняет корень; риск — образ может требовать root для /opt/data |
C. Повторный chown |
перед каждым pull | НЕ рекомендуется — лечит симптом |
Сопутствующий дефект: скрипт глушит ошибки
sync-vault.sh / sync-vault-lib.sh вызывают git fetch и git merge с 2>/dev/null.
При падении синк рапортует «Pushed ✓» / exit 0, хотя pull не прошёл. Это и скрывало
поломку. Предложение — убрать 2>/dev/null с fetch/merge, чтобы падение было видно в логе
(та же логика, что уже описана для launchd: exit code 0 ≠ «синк прошёл»).
Диагностика (воспроизвести)
# владельцы объектов в клоне
ssh truenas_admin@mallexxx.duckdns.org \
"cd /mnt/RED_2TB/storage/obsidian-syncthing && find .git/objects -type f -printf '%u\n' | sort | uniq -c"
# реальный ACL (NFSv4, не POSIX!)
nfs4xdr_getfacl /mnt/RED_2TB/storage/obsidian-syncthing # trivial_acl: true?
# под кем реально работает контейнер
docker inspect hermes-taiga --format '{{.Config.User}}' # пусто => root
docker exec hermes-taiga id # uid=0(root)
# remote клона
cd /mnt/RED_2TB/storage/obsidian-syncthing && git remote -v
Связанные документы
family/how-to/vault-git-sync.md— архитектура и питфоллы синкаfamily/documents/vault-sync/2026-09-21-bare-repo-push-permission-denied.md— тот же root-инстанс Hermes, но на bare repofamily/documents/vault-sync/2026-09-26-mode-flip-644-755.md— шум прав от Syncthingpersonal/tech/truenas-administration(skill) — NFSv4 ACL черезmidclt