Files
obsidian-vault/family/documents/vault-sync/2026-09-26-syncthing-clone-root-objects-acl-confusion.md
T

12 KiB
Executable File
Raw Blame History

title, type, namespace, tags, date, status
title type namespace tags date status
obsidian-syncthing — root-owned objects + битый remote + путаница ACL/chown log family
vault
sync
syncthing
git
permissions
acl
nfsv4
root
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. В NFSv4 group@ — это 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 repo
  • family/documents/vault-sync/2026-09-26-mode-flip-644-755.md — шум прав от Syncthing
  • personal/tech/truenas-administration (skill) — NFSv4 ACL через midclt