Refactor media storage and management functionalities: enhance IMediaStorage interface with manual inbox handling, update FileSystemMediaStorage to support manual file imports, and improve MediaPathResolver for better path management. Extend MediaEndpoints to include new manual inbox features and update frontend components for improved media management experience.
This commit is contained in:
+208
-200
@@ -1,200 +1,208 @@
|
||||
# Подготовка диска под медиахранилище (tvvm)
|
||||
|
||||
Runbook: разметка, форматирование и монтирование диска `sdb` (700G) под хранилище TeleWave.
|
||||
Выполняется **один раз** на сервере `tvvm` перед запуском фичи медиа. Все команды — от root
|
||||
(`sudo -i` или с `sudo` перед каждой).
|
||||
|
||||
> ⚠️ Команды разметки **уничтожают данные** на целевом диске. Диск `sdb` сейчас пустой (нет
|
||||
> разделов), но каждый шаг ниже содержит проверку — не пропускайте их.
|
||||
|
||||
Итог: раздел `sdb1` (ext4) смонтирован в `/srv/telewave/media`, внутри созданы рабочие каталоги,
|
||||
запись из контейнера (сейчас работает под root) возможна.
|
||||
|
||||
---
|
||||
|
||||
## 0. Проверить, что это тот самый диск
|
||||
|
||||
```bash
|
||||
lsblk -o NAME,SIZE,TYPE,MOUNTPOINTS,FSTYPE /dev/sdb
|
||||
```
|
||||
|
||||
Ожидается: `sdb` размером `700G`, тип `disk`, **без разделов и без точек монтирования**. Убедитесь
|
||||
дополнительно, что на диске нет файловой системы и подписей:
|
||||
|
||||
```bash
|
||||
sudo wipefs -n /dev/sdb # -n = «сухой прогон», ничего не меняет
|
||||
```
|
||||
|
||||
Если вывод пустой — диск чист, продолжаем. Если что-то нашлось (следы старой ФС/RAID) —
|
||||
**остановитесь** и разберитесь, что это, прежде чем идти дальше.
|
||||
|
||||
---
|
||||
|
||||
## 1. Создать таблицу разделов и один раздел
|
||||
|
||||
GPT + один раздел на весь диск:
|
||||
|
||||
```bash
|
||||
sudo parted -s /dev/sdb mklabel gpt
|
||||
sudo parted -s -a optimal /dev/sdb mkpart primary ext4 0% 100%
|
||||
sudo partprobe /dev/sdb
|
||||
lsblk /dev/sdb
|
||||
```
|
||||
|
||||
Должен появиться `sdb1` размером ~700G.
|
||||
|
||||
---
|
||||
|
||||
## 2. Отформатировать в ext4
|
||||
|
||||
`-m 1` уменьшает резерв под root с 5% до 1% (на диске данных резерв в 35 ГБ не нужен), `-L` даёт
|
||||
метку тома:
|
||||
|
||||
```bash
|
||||
sudo mkfs.ext4 -m 1 -L telewave-media /dev/sdb1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Создать точку монтирования
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /srv/telewave/media
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Прописать в /etc/fstab (монтирование по UUID)
|
||||
|
||||
Монтируем по UUID, а не по имени `sdb1` — имя может измениться при добавлении дисков. Узнать UUID:
|
||||
|
||||
```bash
|
||||
sudo blkid /dev/sdb1
|
||||
```
|
||||
|
||||
Скопируйте значение `UUID="..."` и добавьте строку в `/etc/fstab` (подставьте свой UUID):
|
||||
|
||||
```
|
||||
UUID=ВАШ-UUID /srv/telewave/media ext4 defaults,noatime,nofail,x-systemd.device-timeout=10 0 2
|
||||
```
|
||||
|
||||
Пояснения к опциям:
|
||||
- `noatime` — не обновлять время доступа при чтении сегментов; заметно снижает лишние записи при
|
||||
раздаче видео.
|
||||
- `nofail` — если диск не подключился, система всё равно загрузится (приложение просто не сможет
|
||||
писать, а не «висит» на загрузке).
|
||||
- `x-systemd.device-timeout=10` — не ждать диск дольше 10с при старте.
|
||||
|
||||
Проверить, что fstab корректен, и смонтировать:
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo mount -a
|
||||
findmnt /srv/telewave/media
|
||||
```
|
||||
|
||||
`findmnt` должен показать смонтированный `ext4` на `/dev/sdb1`. **Ошибка на этом шаге лучше, чем
|
||||
на следующей перезагрузке** — если `mount -a` ругается, чините fstab сейчас.
|
||||
|
||||
---
|
||||
|
||||
## 5. Рабочие каталоги и права
|
||||
|
||||
Создать структуру, ожидаемую приложением:
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /srv/telewave/media/{inbox,uploads,originals,assets}
|
||||
```
|
||||
|
||||
**Владелец.** Контейнер сейчас работает под `root` (в Dockerfile нет `USER`), а bind-mount
|
||||
пробрасывает права хоста внутрь как есть. Поэтому достаточно оставить владельцем root:
|
||||
|
||||
```bash
|
||||
sudo chown -R root:root /srv/telewave/media
|
||||
sudo chmod -R 755 /srv/telewave/media
|
||||
```
|
||||
|
||||
Чтобы вы могли класть файлы в `inbox/` вручную (SFTP/rsync) под своим пользователем, откройте на
|
||||
запись именно этот каталог вашей группе:
|
||||
|
||||
```bash
|
||||
sudo chown root:$(id -gn) /srv/telewave/media/inbox
|
||||
sudo chmod 775 /srv/telewave/media/inbox
|
||||
```
|
||||
|
||||
> При переходе контейнера на non-root пользователя (если позже добавим `USER` в Dockerfile —
|
||||
> в aspnet-образе это обычно uid `1654`), сменить владельца на этот uid:
|
||||
> `sudo chown -R 1654:1654 /srv/telewave/media` (кроме `inbox`, оставленного вам).
|
||||
|
||||
---
|
||||
|
||||
## 6. Проброс в контейнер (bind mount)
|
||||
|
||||
В `docker-compose.yml`, в сервис `app`, добавить том (этого пока **нет** в репозитории — появится
|
||||
вместе с реализацией фичи, здесь для справки):
|
||||
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
# ... существующая конфигурация ...
|
||||
volumes:
|
||||
- /srv/telewave/media:/media
|
||||
mem_limit: 3g
|
||||
```
|
||||
|
||||
И переменные окружения в `.env` (см. `docs/media-storage-and-streaming.md`):
|
||||
|
||||
```
|
||||
Storage__RootPath=/media
|
||||
```
|
||||
|
||||
Выбран **bind mount**: диск смонтирован в ОС через fstab (шаги 1–5) и виден всегда, независимо от
|
||||
Docker — это важно, потому что файлы в `inbox/` кладутся вручную по SFTP/rsync, в том числе когда
|
||||
контейнер остановлен.
|
||||
|
||||
> **Альтернатива — named volume, монтируемый самим Docker** (не используем, для справки). Позволяет
|
||||
> пропустить шаги 3–5, но диск тогда доступен только при запущенном контейнере, а подкаталоги всё
|
||||
> равно надо создавать заранее. Пример:
|
||||
>
|
||||
> ```yaml
|
||||
> services:
|
||||
> app:
|
||||
> volumes:
|
||||
> - media:/media
|
||||
> mem_limit: 3g
|
||||
> volumes:
|
||||
> media:
|
||||
> driver: local
|
||||
> driver_opts:
|
||||
> type: ext4
|
||||
> device: /dev/disk/by-uuid/ВАШ-UUID
|
||||
> o: noatime
|
||||
> ```
|
||||
>
|
||||
> Разметка и `mkfs.ext4` (шаги 1–2) обязательны в любом случае.
|
||||
|
||||
---
|
||||
|
||||
## 7. Проверка записи из контейнера
|
||||
|
||||
После добавления тома и пересборки образа убедиться, что контейнер пишет на диск:
|
||||
|
||||
```bash
|
||||
docker compose exec app sh -c 'touch /media/.wtest && ls -l /media/.wtest && rm /media/.wtest'
|
||||
```
|
||||
|
||||
Команда должна отработать без ошибок доступа. На этом подготовка хоста завершена — дальнейшее
|
||||
(создание `MediaAsset`, нарезка ffmpeg) делает уже само приложение.
|
||||
|
||||
---
|
||||
|
||||
## Приложение: если диск нужно расширить в будущем
|
||||
|
||||
Если VM отдаст диску больше места (например `sdb` вырастет с 700G), после увеличения на стороне
|
||||
гипервизора:
|
||||
|
||||
```bash
|
||||
sudo growpart /dev/sdb 1 # расширить раздел на весь диск
|
||||
sudo resize2fs /dev/sdb1 # расширить ext4 (можно на смонтированном)
|
||||
df -h /srv/telewave/media
|
||||
```
|
||||
# Подготовка диска под медиахранилище (tvvm)
|
||||
|
||||
Runbook: разметка, форматирование и монтирование диска `sdb` (700G) под хранилище TeleWave.
|
||||
Выполняется **один раз** на сервере `tvvm` перед запуском фичи медиа. Все команды — от root
|
||||
(`sudo -i` или с `sudo` перед каждой).
|
||||
|
||||
> ⚠️ Команды разметки **уничтожают данные** на целевом диске. Диск `sdb` сейчас пустой (нет
|
||||
> разделов), но каждый шаг ниже содержит проверку — не пропускайте их.
|
||||
|
||||
Итог: раздел `sdb1` (ext4) смонтирован в `/srv/telewave/media`, внутри созданы рабочие каталоги,
|
||||
запись из контейнера (сейчас работает под root) возможна.
|
||||
|
||||
---
|
||||
|
||||
## 0. Проверить, что это тот самый диск
|
||||
|
||||
```bash
|
||||
lsblk -o NAME,SIZE,TYPE,MOUNTPOINTS,FSTYPE /dev/sdb
|
||||
```
|
||||
|
||||
Ожидается: `sdb` размером `700G`, тип `disk`, **без разделов и без точек монтирования**. Убедитесь
|
||||
дополнительно, что на диске нет файловой системы и подписей:
|
||||
|
||||
```bash
|
||||
sudo wipefs -n /dev/sdb # -n = «сухой прогон», ничего не меняет
|
||||
```
|
||||
|
||||
Если вывод пустой — диск чист, продолжаем. Если что-то нашлось (следы старой ФС/RAID) —
|
||||
**остановитесь** и разберитесь, что это, прежде чем идти дальше.
|
||||
|
||||
---
|
||||
|
||||
## 1. Создать таблицу разделов и один раздел
|
||||
|
||||
GPT + один раздел на весь диск:
|
||||
|
||||
```bash
|
||||
sudo parted -s /dev/sdb mklabel gpt
|
||||
sudo parted -s -a optimal /dev/sdb mkpart primary ext4 0% 100%
|
||||
sudo partprobe /dev/sdb
|
||||
lsblk /dev/sdb
|
||||
```
|
||||
|
||||
Должен появиться `sdb1` размером ~700G.
|
||||
|
||||
---
|
||||
|
||||
## 2. Отформатировать в ext4
|
||||
|
||||
`-m 1` уменьшает резерв под root с 5% до 1% (на диске данных резерв в 35 ГБ не нужен), `-L` даёт
|
||||
метку тома:
|
||||
|
||||
```bash
|
||||
sudo mkfs.ext4 -m 1 -L telewave-media /dev/sdb1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Создать точку монтирования
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /srv/telewave/media
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Прописать в /etc/fstab (монтирование по UUID)
|
||||
|
||||
Монтируем по UUID, а не по имени `sdb1` — имя может измениться при добавлении дисков. Узнать UUID:
|
||||
|
||||
```bash
|
||||
sudo blkid /dev/sdb1
|
||||
```
|
||||
|
||||
Скопируйте значение `UUID="..."` и добавьте строку в `/etc/fstab` (подставьте свой UUID):
|
||||
|
||||
```
|
||||
UUID=ВАШ-UUID /srv/telewave/media ext4 defaults,noatime,nofail,x-systemd.device-timeout=10 0 2
|
||||
```
|
||||
|
||||
Пояснения к опциям:
|
||||
- `noatime` — не обновлять время доступа при чтении сегментов; заметно снижает лишние записи при
|
||||
раздаче видео.
|
||||
- `nofail` — если диск не подключился, система всё равно загрузится (приложение просто не сможет
|
||||
писать, а не «висит» на загрузке).
|
||||
- `x-systemd.device-timeout=10` — не ждать диск дольше 10с при старте.
|
||||
|
||||
Проверить, что fstab корректен, и смонтировать:
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo mount -a
|
||||
findmnt /srv/telewave/media
|
||||
```
|
||||
|
||||
`findmnt` должен показать смонтированный `ext4` на `/dev/sdb1`. **Ошибка на этом шаге лучше, чем
|
||||
на следующей перезагрузке** — если `mount -a` ругается, чините fstab сейчас.
|
||||
|
||||
---
|
||||
|
||||
## 5. Рабочие каталоги и права
|
||||
|
||||
Создать структуру, ожидаемую приложением:
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /srv/telewave/media/{inbox,manual,uploads,originals,assets}
|
||||
```
|
||||
|
||||
**Владелец.** Контейнер сейчас работает под `root` (в Dockerfile нет `USER`), а bind-mount
|
||||
пробрасывает права хоста внутрь как есть. Поэтому достаточно оставить владельцем root:
|
||||
|
||||
```bash
|
||||
sudo chown -R root:root /srv/telewave/media
|
||||
sudo chmod -R 755 /srv/telewave/media
|
||||
```
|
||||
|
||||
Два каталога наполняете вы, а не приложение:
|
||||
|
||||
- `inbox/` — разбирается сканером автоматически: файл с допустимым расширением и стабильным
|
||||
размером регистрируется сам и уходит в обработку;
|
||||
- `manual/` — **ручной разбор**: сканер сюда не заглядывает. Файлы видны в админке
|
||||
(Медиа → «Из папки manual»), выбираются галочками и сразу привязываются к шоу. Импортированные
|
||||
файлы уходят из каталога так же, как из `inbox/`.
|
||||
|
||||
Чтобы класть в них файлы вручную (SFTP/rsync) под своим пользователем, откройте на запись именно
|
||||
эти каталоги вашей группе:
|
||||
|
||||
```bash
|
||||
sudo chown root:$(id -gn) /srv/telewave/media/inbox /srv/telewave/media/manual
|
||||
sudo chmod 775 /srv/telewave/media/inbox /srv/telewave/media/manual
|
||||
```
|
||||
|
||||
> При переходе контейнера на non-root пользователя (если позже добавим `USER` в Dockerfile —
|
||||
> в aspnet-образе это обычно uid `1654`), сменить владельца на этот uid:
|
||||
> `sudo chown -R 1654:1654 /srv/telewave/media` (кроме `inbox` и `manual`, оставленных вам).
|
||||
|
||||
---
|
||||
|
||||
## 6. Проброс в контейнер (bind mount)
|
||||
|
||||
В `docker-compose.yml`, в сервис `app`, добавить том (этого пока **нет** в репозитории — появится
|
||||
вместе с реализацией фичи, здесь для справки):
|
||||
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
# ... существующая конфигурация ...
|
||||
volumes:
|
||||
- /srv/telewave/media:/media
|
||||
mem_limit: 3g
|
||||
```
|
||||
|
||||
И переменные окружения в `.env` (см. `docs/media-storage-and-streaming.md`):
|
||||
|
||||
```
|
||||
Storage__RootPath=/media
|
||||
```
|
||||
|
||||
Выбран **bind mount**: диск смонтирован в ОС через fstab (шаги 1–5) и виден всегда, независимо от
|
||||
Docker — это важно, потому что файлы в `inbox/` кладутся вручную по SFTP/rsync, в том числе когда
|
||||
контейнер остановлен.
|
||||
|
||||
> **Альтернатива — named volume, монтируемый самим Docker** (не используем, для справки). Позволяет
|
||||
> пропустить шаги 3–5, но диск тогда доступен только при запущенном контейнере, а подкаталоги всё
|
||||
> равно надо создавать заранее. Пример:
|
||||
>
|
||||
> ```yaml
|
||||
> services:
|
||||
> app:
|
||||
> volumes:
|
||||
> - media:/media
|
||||
> mem_limit: 3g
|
||||
> volumes:
|
||||
> media:
|
||||
> driver: local
|
||||
> driver_opts:
|
||||
> type: ext4
|
||||
> device: /dev/disk/by-uuid/ВАШ-UUID
|
||||
> o: noatime
|
||||
> ```
|
||||
>
|
||||
> Разметка и `mkfs.ext4` (шаги 1–2) обязательны в любом случае.
|
||||
|
||||
---
|
||||
|
||||
## 7. Проверка записи из контейнера
|
||||
|
||||
После добавления тома и пересборки образа убедиться, что контейнер пишет на диск:
|
||||
|
||||
```bash
|
||||
docker compose exec app sh -c 'touch /media/.wtest && ls -l /media/.wtest && rm /media/.wtest'
|
||||
```
|
||||
|
||||
Команда должна отработать без ошибок доступа. На этом подготовка хоста завершена — дальнейшее
|
||||
(создание `MediaAsset`, нарезка ffmpeg) делает уже само приложение.
|
||||
|
||||
---
|
||||
|
||||
## Приложение: если диск нужно расширить в будущем
|
||||
|
||||
Если VM отдаст диску больше места (например `sdb` вырастет с 700G), после увеличения на стороне
|
||||
гипервизора:
|
||||
|
||||
```bash
|
||||
sudo growpart /dev/sdb 1 # расширить раздел на весь диск
|
||||
sudo resize2fs /dev/sdb1 # расширить ext4 (можно на смонтированном)
|
||||
df -h /srv/telewave/media
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user