OpenWrt на D-Link DNS-325: установка Transmission, настройка каталогов, скрипт
Предпосылка: 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. Ссылки
- OpenWrt PR #17924 (DNS-325)
- Transmission — Scripts.md (
TR_*для script-torrent-done)
Комментарии
Отправить комментарий