OpenWrt на D-Link DNS-325: установка Transmission, настройка каталогов, скрипт

OpenWrt на DNS-325: софт — каталоги, Transmission, watch

Предпосылка: OpenWrt уже стоит, диск смонтирован на /mnt/data, swap на HDD и при необходимости Samba для /mnt/data — как в основной заметке про прошивку и в гайде установки. Пакеты ставлю через apk (на старых сборках вместо него — opkg, имена пакетов проверь через поиск). Устройство: D-Link DNS-325, RAM порядка 256 MiB.


1. Перед началом

Выполни на NAS и убедись, что данные не на overlay, а на большом томе:

df -h /mnt/data

Ожидаемо: отдельный раздел (у меня /dev/sda1 на /mnt/data, размер порядка терабайт). Если /mnt/data не смонтирован — сначала доведи монтирование и swap по основному гайду.


2. Каталоги на /mnt/data

Зачем: заранее развести данные по папкам: корень для торрентов (/mnt/data/torrents), Syncthing, общие файлы и фото. Отдельный каталог /mnt/data/video здесь не создаём: готовое видео с торрентов по схеме ниже кладётся в /mnt/data/torrents/video (создаётся в п. 3.9 внутри download_dir, из‑за ujail так и нужно).

2.1. Каталоги одной командой:

mkdir -p /mnt/data/torrents /mnt/data/syncthing /mnt/data/files /mnt/data/photos

2.2. Права на все четыре каталога:

chmod 775 /mnt/data/torrents /mnt/data/syncthing /mnt/data/files /mnt/data/photos

2.3. Если гостевая Samba на весь диск идёт под nobody (как в базовом гайде), выровняй владельца под запись гостя:

chown -R nobody /mnt/data/torrents /mnt/data/syncthing /mnt/data/files /mnt/data/photos

2.4. Проверка после шага — выполни и сохрани вывод (пригодится для отладки):

date
uptime
free -m
df -h / /overlay /mnt/data
cat /proc/swaps

Диск ~1.8 T, свободно ~1.7 T; overlay ~81.6 M свободно из 106 M; swap-файл /mnt/data/.system/swapfile ~4 G, использование 0; load 0.00. Полный лог с консоли:

root@OpenWrt:~# df -h /mnt/data
Filesystem                Size      Used Available Use% Mounted on
/dev/sda1                 1.8T      4.0G      1.7T   0% /mnt/data

root@OpenWrt:~# mkdir -p /mnt/data/torrents /mnt/data/syncthing /mnt/data/files /mnt/data/photos

root@OpenWrt:~# chmod 775 /mnt/data/torrents /mnt/data/syncthing /mnt/data/files /mnt/data/photos

root@OpenWrt:~# chown -R nobody /mnt/data/torrents /mnt/data/syncthing /mnt/data/files /mnt/data/photos

root@OpenWrt:~# date
Sun Mar 22 06:41:09 GMT 2026

root@OpenWrt:~# uptime
 06:41:14 up  9:02,  load average: 0.00, 0.00, 0.00

root@OpenWrt:~# free -m
              total        used        free      shared  buff/cache   available
Mem:         249464       23656       21880        3656      203928      173864
Swap:       4194300           0     4194300

root@OpenWrt:~# df -h / /overlay /mnt/data
Filesystem                Size      Used Available Use% Mounted on
overlayfs:/overlay      106.0M     19.7M     81.6M  19% /
/dev/ubi0_2             106.0M     19.7M     81.6M  19% /overlay
/dev/sda1                 1.8T      4.0G      1.7T   0% /mnt/data

root@OpenWrt:~# cat /proc/swaps
Filename                                Type            Size            Used            Priority
/mnt/data/.system/swapfile              file            4194300         0               -2

Заметка: на BusyBox/OpenWrt колонки free -m могут вводить в заблуждение; при сомнениях смотри df и /proc/meminfo.


3.Transmission

3.1. Установка пакетов

apk update
apk add transmission-daemon transmission-web luci-app-transmission

Опционально русский LuCI: apk add luci-i18n-transmission-ru.

3.2. Каталог торрентов и владелец

mkdir -p /mnt/data/torrents
chown -R transmission:transmission /mnt/data/torrents
chmod 775 /mnt/data/torrents
/etc/init.d/transmission enable

3.3. Включение в UCI (по умолчанию enabled='0', без этого init не стартует демон):

/etc/init.d/transmission start

Если видишь: Transmission not enabled. Please enable in /etc/config/transmission — выполни:

uci set transmission.@transmission[0].enabled='1'
uci commit transmission
/etc/init.d/transmission start
/etc/init.d/transmission status

Ожидаемо: running. Проверка процесса:

ps w | grep -E '[t]ransmission-daemon'

У меня демон шёл через ujail, строка вида /usr/bin/transmission-daemon -f -g /tmp/transmission.

3.4. Перенос загрузок с /tmp на диск (иначе большие файлы забивают RAM/tmp):

mkdir -p /mnt/data/torrents/incomplete
chown -R transmission:transmission /mnt/data/torrents
uci set transmission.@transmission[0].download_dir='/mnt/data/torrents'
uci set transmission.@transmission[0].incomplete_dir='/mnt/data/torrents/incomplete'
uci set transmission.@transmission[0].incomplete_dir_enabled='1'
uci commit transmission
/etc/init.d/transmission restart
uci show transmission | grep -E 'download_dir|incomplete'
/etc/init.d/transmission status

Ожидаемо: в выводе uci show пути на /mnt/data/torrents и incomplete, статус running. Лог с моей консоли:

root@OpenWrt:~# /etc/init.d/transmission start
Transmission not enabled. Please enable in /etc/config/transmission

root@OpenWrt:~# uci set transmission.@transmission[0].enabled='1'
root@OpenWrt:~# uci commit transmission
root@OpenWrt:~# /etc/init.d/transmission start
root@OpenWrt:~# /etc/init.d/transmission status
running
root@OpenWrt:~# ps w | grep -E '[t]ransmission-daemon'
 4394 root      2172 SN   {transmission} /sbin/ujail -t 5 -n transmission -S /etc/seccomp/transmission-daemon.json -U transmission
 4419 transmis  8088 SN   /usr/bin/transmission-daemon -f -g /tmp/transmission

root@OpenWrt:~# mkdir -p /mnt/data/torrents/incomplete
root@OpenWrt:~# chown -R transmission:transmission /mnt/data/torrents
root@OpenWrt:~# uci set transmission.@transmission[0].download_dir='/mnt/data/torrents'
root@OpenWrt:~# uci set transmission.@transmission[0].incomplete_dir='/mnt/data/torrents/incomplete'
root@OpenWrt:~# uci set transmission.@transmission[0].incomplete_dir_enabled='1'
root@OpenWrt:~# uci commit transmission
root@OpenWrt:~# /etc/init.d/transmission restart
root@OpenWrt:~# uci show transmission | grep -E 'download_dir|incomplete'
transmission.@transmission[0].download_dir='/mnt/data/torrents'
transmission.@transmission[0].incomplete_dir='/mnt/data/torrents/incomplete'
transmission.@transmission[0].incomplete_dir_enabled='1'
root@OpenWrt:~# /etc/init.d/transmission status
running

3.5. Watch-каталог (подкинул .torrent — пошла закачка):

mkdir -p /mnt/data/torrents/watch
chown -R transmission:transmission /mnt/data/torrents
chmod 775 /mnt/data/torrents/watch
uci set transmission.@transmission[0].watch_dir='/mnt/data/torrents/watch'
uci set transmission.@transmission[0].watch_dir_enabled='1'
uci commit transmission
/etc/init.d/transmission restart

3.6. Samba: шара на watch (у меня отдельная шара torr_download/mnt/data/torrents/watch, шара nas на /mnt/data осталась как была).

  • Чтобы файлы в watch писались от системного пользователя transmission, задай ему пароль Samba и пускай на эту шару только его:
smbpasswd -a transmission
/etc/init.d/samba4 restart
  • В настройках шары watch: Allowed users = transmission, Allow guests = выкл. С Windows подключайся как OPENWRT\transmission или transmission с этим паролем.

3.7. Проверка watch: положи тестовый .torrent в /mnt/data/torrents/watch (или скинь по SMB в torr_download) — задание должно появиться в веб-морде Transmission. Веб обычно: http://IP_NAS:9091/transmission/web/ (порт уточни: uci show transmission).

3.8. Полный текст скрипта transmission-done-move-video.sh

Сохрани на NAS в файл /mnt/data/torrents/transmission-done-move-video.sh:

#!/bin/sh
# transmission-done-move-video.sh — скрипт для Transmission «по завершении торрента» (script-torrent-done).
# Переносит данные торрента в каталог с видео ТОЛЬКО если среди файлов есть «видео-расширения».
# Перенос через transmission-remote --move (не через mv!), чтобы не ломать пути и сидирование.
#
# Официальные переменные окружения (см. transmission/docs/Scripts.md):
#   TR_APP_VERSION
#   TR_TIME_LOCALTIME
#   TR_TORRENT_BYTES_DOWNLOADED
#   TR_TORRENT_DIR       — каталог загрузок (родитель для данных торрента)
#   TR_TORRENT_HASH
#   TR_TORRENT_ID        — ID для transmission-remote -t
#   TR_TORRENT_LABELS    — метки через запятую
#   TR_TORRENT_NAME      — имя торрента (папка или имя файла внутри TR_TORRENT_DIR)
#   TR_TORRENT_PRIORITY
#   TR_TORRENT_TRACKERS
#
# Зависимости на NAS: transmission-daemon; отдельно пакет transmission-remote (в OpenWrt apk пакет transmission-cli его НЕ содержит).
#
# Установка на OpenWrt (пример):
#   — Положи скрипт ВНУТРИ download_dir (например /mnt/data/torrents/…), иначе ujail не даст его выполнить.
#   — UCI: script_torrent_done_filename и script_torrent_done_enabled (НЕ опция script_torrent_done).
#   cp transmission-done-move-video.sh /mnt/data/torrents/transmission-done-move-video.sh
#   chmod 750 /mnt/data/torrents/transmission-done-move-video.sh
#   chown transmission:transmission /mnt/data/torrents/transmission-done-move-video.sh
#   uci set transmission.@transmission[0].script_torrent_done_filename='/mnt/data/torrents/transmission-done-move-video.sh'
#   uci set transmission.@transmission[0].script_torrent_done_enabled='1'
#   uci commit transmission && /etc/init.d/transmission restart
#   grep script-torrent-done /tmp/transmission/settings.json
#
# При RPC с паролем задай ниже RPC_USER / RPC_PASS или включи чтение из UCI (блок ниже).

# ============ настройки ============
# Куда переносить «видео-торренты» (каталог должен существовать и быть доступен пользователю transmission).
# По умолчанию — ВНУТРИ download_dir (/mnt/data/torrents/...): иначе на OpenWrt ujail не монтирует /mnt/data/video,
# и transmission-remote --move в «соседнюю» папку не сработает (Permission denied / файл не переезжает).
DEST_VIDEO="${DEST_VIDEO:-/mnt/data/torrents/video}"

# Лог на диске (не путать с UCI: /etc/config/transmission). Нужны права у пользователя transmission; внутри download_dir надёжнее для ujail.
LOG_FILE="${LOG_FILE:-/mnt/data/torrents/transmission-done.log}"

# transmission-remote: адрес демона (на том же NAS — localhost).
RPC_HOST="${RPC_HOST:-127.0.0.1}"
RPC_PORT="${RPC_PORT:-9091}"

# Если в LuCI включена аутентификация RPC — задайте (или раскомментируйте автозагрузку из UCI ниже).
RPC_USER="${RPC_USER:-}"
RPC_PASS="${RPC_PASS:-}"

# Раскомментируй, чтобы подставить порт/логин из UCI (если есть uci в PATH при вызове скрипта):
# RPC_PORT="$(uci -q get transmission.@transmission[0].rpc_port 2>/dev/null)" || RPC_PORT=9091
# if [ "$(uci -q get transmission.@transmission[0].rpc_authentication_required 2>/dev/null)" = "1" ]; then
#   RPC_USER="$(uci -q get transmission.@transmission[0].rpc_username)"
#   RPC_PASS="$(uci -q get transmission.@transmission[0].rpc_password)"
# fi

# ============ конец настроек ============

log_msg() {
  _ts="$(date '+%Y-%m-%d %H:%M:%S' 2>/dev/null || date)"
  _line="$_ts $*"
  logger -t transmission-done "$_line"
  [ -n "$LOG_FILE" ] && echo "$_line" >>"$LOG_FILE" 2>/dev/null
}

TR_BIN="transmission-remote"
[ -x /usr/bin/transmission-remote ] && TR_BIN="/usr/bin/transmission-remote"

TR_REMOTE_CMD() {
  if [ -n "$RPC_USER" ] && [ -n "$RPC_PASS" ]; then
    "$TR_BIN" "$RPC_HOST:$RPC_PORT" -n "$RPC_USER:$RPC_PASS" "$@"
  else
    "$TR_BIN" "$RPC_HOST:$RPC_PORT" "$@"
  fi
}

# Проверка наличия transmission-remote (обязателен для --move). В ujail может быть пустой PATH — смотрим /usr/bin.
if ! command -v transmission-remote >/dev/null 2>&1 && [ ! -x /usr/bin/transmission-remote ]; then
  log_msg "ERROR: transmission-remote not found. Install: apk add transmission-remote. Skipping."
  exit 0
fi

if [ -z "$TR_TORRENT_ID" ] || [ -z "$TR_TORRENT_DIR" ] || [ -z "$TR_TORRENT_NAME" ]; then
  log_msg "ERROR: missing TR_TORRENT_ID / TR_TORRENT_DIR / TR_TORRENT_NAME. TR_TORRENT_ID=${TR_TORRENT_ID:-?} DIR=${TR_TORRENT_DIR:-?} NAME=${TR_TORRENT_NAME:-?}"
  exit 0
fi

TARGET="${TR_TORRENT_DIR}/${TR_TORRENT_NAME}"

# Уже внутри каталога с видео — не трогаем (защита от зацикливания при странных путях).
case "$TARGET" in
  "$DEST_VIDEO"|"$DEST_VIDEO"/*) log_msg "SKIP: already under $DEST_VIDEO (id=$TR_TORRENT_ID name=$TR_TORRENT_NAME)"; exit 0 ;;
esac

if [ ! -e "$TARGET" ]; then
  log_msg "ERROR: path does not exist: $TARGET (id=$TR_TORRENT_ID)"
  exit 0
fi

if [ ! -d "$DEST_VIDEO" ]; then
  log_msg "ERROR: DEST_VIDEO is not a directory: $DEST_VIDEO"
  exit 0
fi

# Расширения видеоконтейнеров и типичных трансляций (при необходимости дополни список).
# Используем find с -iname (регистронезависимо).
has_video=$(find "$TARGET" -type f \( \
  -iname '*.mkv' -o -iname '*.mp4' -o -iname '*.m4v' -o -iname '*.avi' -o -iname '*.mov' \
  -o -iname '*.wmv' -o -iname '*.mpeg' -o -iname '*.mpg' -o -iname '*.m2ts' -o -iname '*.ts' \
  -o -iname '*.webm' -o -iname '*.flv' -o -iname '*.vob' -o -iname '*.asf' -o -iname '*.3gp' \
  -o -iname '*.ogv' -o -iname '*.divx' -o -iname '*.xvid' \
\) 2>/dev/null | head -n 1)

if [ -z "$has_video" ]; then
  log_msg "SKIP: no video-like files in torrent id=$TR_TORRENT_ID name=$TR_TORRENT_NAME path=$TARGET"
  exit 0
fi

log_msg "MOVE: video detected, id=$TR_TORRENT_ID name=$TR_TORRENT_NAME -> $DEST_VIDEO"

if TR_REMOTE_CMD -t "$TR_TORRENT_ID" --move "$DEST_VIDEO"; then
  log_msg "OK: transmission-remote --move id=$TR_TORRENT_ID -> $DEST_VIDEO"
else
  log_msg "ERROR: transmission-remote --move failed id=$TR_TORRENT_ID (check RPC auth, ujail, paths)"
fi

exit 0

3.9. Пакет transmission-remote, каталог видео и подключение скрипта в Transmission

Пакет transmission-cli не содержит transmission-remote — нужен отдельный пакет:

apk search transmission
apk add transmission-remote

Создай каталог назначения внутри download_dir (из-за ujail перенос в /mnt/data/video у меня не сработал — ошибка прав / не переезжало; рабочая цель — /mnt/data/torrents/video):

mkdir -p /mnt/data/torrents/video
chown -R transmission:transmission /mnt/data/torrents/video

Создай файл скрипта на NAS по содержимому из п. 3.8 (например через vim /mnt/data/torrents/transmission-done-move-video.sh и вставку из браузера). Файл должен лежать внутри /mnt/data/torrents/ — иначе демон из песочницы не сможет его выполнить. Права:

chmod 750 /mnt/data/torrents/transmission-done-move-video.sh
chown transmission:transmission /mnt/data/torrents/transmission-done-move-video.sh

В OpenWrt опция пути к скрипту — script_torrent_done_filename:

uci set transmission.@transmission[0].script_torrent_done_filename='/mnt/data/torrents/transmission-done-move-video.sh'
uci set transmission.@transmission[0].script_torrent_done_enabled='1'
uci delete transmission.@transmission[0].script_torrent_done 2>/dev/null
uci commit transmission
/etc/init.d/transmission restart
grep -E 'script-torrent-done' /tmp/transmission/settings.json

Если RPC без пароля (rpc_authentication_required='false'), в скрипте ничего для RPC_USER / RPC_PASS не задавал. Ручная проверка переноса (подставь свой ID торрента вместо 1):

transmission-remote -t 1 --stop
transmission-remote -t 1 --move /mnt/data/torrents/video
transmission-remote -t 1 --start

У меня перенос сработал, события скрипта — в logread.


4. Контроль ресурсов

date
uptime
free -m
df -h / /overlay /mnt/data
cat /proc/swaps

5. Ссылки

Комментарии

Популярные сообщения