[2026-09-26] eagle: personal/plans/tagwriter-container.md personal/tech/music-tags-repair-truenas.md personal/tech/skill-truenas-administration.md
This commit is contained in:
1 parent
59d2ad1737
commit
b885cd8426
3 files changed
+77
-2
No files matched your search
@@ -139,7 +139,7 @@ docker compose --profile tools run --rm tagwriter --readback # проверк
|
||||
|
||||
## Питфоллы
|
||||
|
||||
- 🔴 `/mnt/RED_2TB/docker/` — **root-owned**, uid 950 не пишет (это и есть блокер).
|
||||
- 🔴 `/mnt/RED_2TB/docker/` — **root-owned**, uid 950 не пишет. Создавать каталоги **из контейнера** (`docker run -u 0 -v /mnt/RED_2TB/docker:/docker alpine mkdir` + `chown 950:950`).
|
||||
- 🔴 `sudo` без пароля **недоступен**.
|
||||
- 🔴 Имена файлов на диске **не в UTF-8** (mojibake в `ls`) → только python-скрипт, NFC.
|
||||
- 🔴 Пути в CSV контейнерные (`/storage/Music/…`) → мапить в `/music/…`.
|
||||
|
||||
@@ -76,7 +76,8 @@ related:
|
||||
> Бэкапы: `bak-wave38-p2p3`, `-p4`, `-nashestvie`, `-chast`, `-chast2`, `-gorigori`.
|
||||
>
|
||||
> ⏭ **Дальше:** применение тегов через контейнер `tagwriter` — [[personal/plans/tagwriter-container]].
|
||||
> Блокер: `/mnt/RED_2TB/docker/` root-owned, uid 950 не пишет, sudo требует пароль.
|
||||
> ✅ Контейнер собран, **dry-run прошёл (MISSING 0, к обработке 7041)**. Осталось: `--backup` → `--apply`.
|
||||
> Блокер прав на `/mnt/RED_2TB/docker/` решён: каталог создан **из контейнера** (`docker run -u 0 -v /mnt/RED_2TB/docker:/docker alpine mkdir` + `chown 950:950`).
|
||||
>
|
||||
> ### 🔴 ПИТФОЛЛ: sentinel-группа собирается по КОРНЮ сборника, НЕ по ближайшей папке
|
||||
>
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
---
|
||||
title: skill — truenas-administration
|
||||
namespace: personal
|
||||
type: tech
|
||||
created: '2026-09-26'
|
||||
updated: '2026-09-26'
|
||||
tags:
|
||||
- truenas
|
||||
- skill
|
||||
- docker
|
||||
- acl
|
||||
- nfc
|
||||
related:
|
||||
- '[[personal/plans/tagwriter-container]]'
|
||||
- '[[personal/tech/music-tags-repair-truenas]]'
|
||||
---
|
||||
|
||||
# Зеркало навыка `truenas-administration`
|
||||
|
||||
Навык: `~/.hermes/hermes-whale/skills/devops/truenas-administration/SKILL.md`
|
||||
(umbrella: ACL/PUID, ZFS panic recovery, tree comparison, named-volumes→bind-mount).
|
||||
|
||||
Ниже — дельта, добавленная **2026-09-26** (сессия music-tags волна 38 + сборка `tagwriter`).
|
||||
|
||||
## 1. Создание НОВОГО каталога под `/mnt/<POOL>/docker/` — из контейнера
|
||||
|
||||
`/mnt/RED_2TB/docker/` = `root:root`. `truenas_admin` (uid 950) **не пишет** туда;
|
||||
`sudo` требует пароль (`sudo -n` → password required). Но `docker` доступен (юзер в группе `docker`).
|
||||
|
||||
```bash
|
||||
docker run --rm -u 0 -v /mnt/RED_2TB/docker:/docker alpine:latest sh -c \
|
||||
'mkdir -p /docker/tagwriter/data && chown -R 950:950 /docker/tagwriter && chmod 755 /docker/tagwriter'
|
||||
```
|
||||
|
||||
Затем `scp` проекта обычным путём (владелец 950).
|
||||
**Правило: любой новый каталог под `docker/` создавать ИЗ КОНТЕЙНЕРА (`-u 0`), не через ssh под 950.**
|
||||
|
||||
## 2. 🔴 Права файлов при `scp` → `COPY` в Dockerfile
|
||||
|
||||
`scp` кладёт файлы как `-rw-------` (600). `COPY` **сохраняет режим** → внутри образа
|
||||
`/app/<script>.py` = root:root 600 → пользователь образа (uid 950) получает
|
||||
`python3: can't open file '/app/x.py': [Errno 13] Permission denied`, хотя на хосте права 644.
|
||||
|
||||
**Фикс:** в Dockerfile `RUN chmod 755 /app/<script>.py && chmod 755 /app` + `chmod 644` файлов проекта на хосте.
|
||||
**Проверка:** `docker run --rm --entrypoint sh -u 950:950 <img> -c 'id; ls -la /app'`.
|
||||
|
||||
## 3. 🔴🔴 NFD на диске vs NFC в данных — путь молча НЕ находится
|
||||
|
||||
Батч-задача сверяла манифест (CSV) с реальными файлами → **47 «отсутствующих» файлов**, которые
|
||||
лежат на диске. Причина: имена на диске в **NFD** (разложенная форма: `й` = `и` + combining breve
|
||||
`U+0306`, то же для `ё`), манифест — в **NFC**. `os.path.exists()` → `False`; `ls` ничего не показывает;
|
||||
выглядит как «файл удалён».
|
||||
|
||||
Поражённые: `Али-Баба и сорок разбойников`, `Принц и нищий (Диск 2)`, `Пеппи Длинный Чулок`,
|
||||
`Летучий корабль`, `Голубой щенок` — **любое имя с `й`/`ё`**.
|
||||
|
||||
```python
|
||||
# ✅ индекс диска: NFC(путь) -> реальный путь
|
||||
idx = {}
|
||||
for root, dirs, files in os.walk(BASE):
|
||||
for n in files:
|
||||
real = os.path.join(root, n)
|
||||
idx[unicodedata.normalize("NFC", real)] = real
|
||||
real = idx.get(unicodedata.normalize("NFC", wanted)) # None ⇒ действительно нет
|
||||
```
|
||||
|
||||
**Правило: не звать `os.path.exists()` на не-ASCII путь из манифеста — строить NFC-индекс и искать по нему.**
|
||||
Тот же класс, что кейс `combining breve` для `Принц и нищий (Диск 2)`; применимо к **любой**
|
||||
батч-задаче с кириллическими путями, не только к музыке. Приёмка: MISSING `47 → 0`.
|
||||
|
||||
## Применение
|
||||
|
||||
Оба питфолла воспроизвелись при сборке контейнера [[personal/plans/tagwriter-container]]
|
||||
(применение тегов MP3, 7041 файл). Оттуда же — команды `docker compose --profile tools run …`.
|
||||
Reference in new issue
Block a user