Итак, мы имеем настроенный и функционирующий серверный узел первичного распространения "торрент"-файлов и файлов содержимого как такового. Теперь отработаем методику создания вспомогательных узлов раздачи контента в сегментах нашей сети.
Пусть распространяемые файлы будут располагаться в директории "/mnt/storage/share/files/", а "торрент"-файлы в директории "/var/lib/share/torrents/":
# mkdir -p /mnt/storage/share/files
# mkdir -p /var/lib/share/torrents
# mkdir -p /var/lib/share/torrents
Создаём группу для пользователей сервисов:
# groupadd share-users
В качестве приложения раздачи данных применим заслуженный "rtorrent" запускаемый с помощью "sudo" в сессии "screen", а загрузку (скорее "зеркалирование" с каталогом хранения) "торрент"-файлов с центрального узла будем осуществлять с помощью утилиты "rsync".
Инсталлируем необходимые утилиты:
# aptitude install rtorrent rsync screen sudo
Создаём для rtorrent "домик", где он будет жить:
# mkdir -p /var/lib/rtorrent
Создаем учётную запись пользователя для запуска rtorrent:
# useradd --shell /bin/false --home-dir /var/lib/rtorrent rtorrent
Создаём директорию для хранения файлов и сессий загрузок:
# mkdir -p /var/lib/rtorrent/session
Создаём конфигурационный файл для "rtorrent":
# touch /var/lib/rtorrent/.rtorrent.rc
# Директория сохранения файлов
directory = /mnt/storage/share/files
# Директория хранения файлов сессий загрузок
session = /var/lib/rtorrent/session
# Указываем сохранять состояние сессий
session_save = yes
# Отключаем проверку файла блокировки в директории сессий (лучше проверить факт запуска скриптом, нежели заблокировать rtorrent после аварийного завершения системы)
session_lock = no
# Запускаем планировщик rtorrent для периодической проверки новых "торрент"-файлов
schedule = watch_directory,5,5,load_start=/var/lib/share/torrents/*.torrent
# Диапазон портов для входящих соединений
port_range = 6998-6999
# Проверка контрольной суммы для завершённых закачек
check_hash = yes
# Указываем принимать зашифрованные входящие соединения, при установке исходящих соединений переключатся между режимом с шифрованием и без шифрования в случае ошибок, предпочитать передачу данных простым текстом после установления зашифрованного соединения
encryption = allow_incoming,enable_retry,prefer_plaintext
# Запрещаем использование UDP протокола
use_udp_trackers = no
# Принудительно устанавливаем кодировку для имён файлов, если она не была определена
encoding_list = UTF-8
directory = /mnt/storage/share/files
# Директория хранения файлов сессий загрузок
session = /var/lib/rtorrent/session
# Указываем сохранять состояние сессий
session_save = yes
# Отключаем проверку файла блокировки в директории сессий (лучше проверить факт запуска скриптом, нежели заблокировать rtorrent после аварийного завершения системы)
session_lock = no
# Запускаем планировщик rtorrent для периодической проверки новых "торрент"-файлов
schedule = watch_directory,5,5,load_start=/var/lib/share/torrents/*.torrent
# Диапазон портов для входящих соединений
port_range = 6998-6999
# Проверка контрольной суммы для завершённых закачек
check_hash = yes
# Указываем принимать зашифрованные входящие соединения, при установке исходящих соединений переключатся между режимом с шифрованием и без шифрования в случае ошибок, предпочитать передачу данных простым текстом после установления зашифрованного соединения
encryption = allow_incoming,enable_retry,prefer_plaintext
# Запрещаем использование UDP протокола
use_udp_trackers = no
# Принудительно устанавливаем кодировку для имён файлов, если она не была определена
encoding_list = UTF-8
Наводим порядок с правами доступа:
# chown -R rtorrent:share-users /mnt/storage/share/files /var/lib/rtorrent
# chmod -R ug+rw /mnt/storage/share/files /var/lib/rtorrent
# chmod -R ug+rw /mnt/storage/share/files /var/lib/rtorrent
Запускаем rtorrent:
# screen -S screen.rtorrent sudo -H -u rtorrent rtorrent
Проверяем, слушает ли rtorrent порты для входящих соединений:
# netstat -apn | grep rtorrent
tcp 0 0 0.0.0.0:6999 0.0.0.0:* LISTEN 10920/rtorrent
Подключится к уже существующей сессии screen с запущенным в ней rtorrent можно следующим образом:
# screen -r screen.rtorrent
Для автоматизации запуска rtorrent напишем следующий скрипт:
# touch /etc/init.d/rtorrent
# chmod ugo+x /etc/init.d/rtorrent
# chmod ugo+x /etc/init.d/rtorrent
#!/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
### BEGIN INIT INFO
# Provides: rtorrent
# Required-Start: $local_fs $network
# Required-Stop: $local_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Script management of rtorrent
# Description: Script management of rtorrent
### END INIT INFO
USER="rtorrent"
GROUP="share-users"
case "$1" in
start)
STATE=`ps wax | grep -v grep | grep -i screen | grep -c -i rtorrent`
if [ ${STATE} -eq 0 ]
then
# Предварительно удаляем файлы блокировки сессии (они часто остаются при грубом завершении работы программы)
rm --force /var/lib/rtorrent/session/*.lock
# Запускаем rtorrent внутри фоновой сессии screen
screen -dmS screen.rtorrent sudo -H -u ${USER} rtorrent
fi
;;
stop)
killall rtorrent
;;
restart|force-reload)
$0 stop
sleep 60
$0 start
;;
*)
echo "Usage: /etc/init.d/rtorrent {start|stop|restart}"
exit 1
;;
esac
exit 0
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
### BEGIN INIT INFO
# Provides: rtorrent
# Required-Start: $local_fs $network
# Required-Stop: $local_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Script management of rtorrent
# Description: Script management of rtorrent
### END INIT INFO
USER="rtorrent"
GROUP="share-users"
case "$1" in
start)
STATE=`ps wax | grep -v grep | grep -i screen | grep -c -i rtorrent`
if [ ${STATE} -eq 0 ]
then
# Предварительно удаляем файлы блокировки сессии (они часто остаются при грубом завершении работы программы)
rm --force /var/lib/rtorrent/session/*.lock
# Запускаем rtorrent внутри фоновой сессии screen
screen -dmS screen.rtorrent sudo -H -u ${USER} rtorrent
fi
;;
stop)
killall rtorrent
;;
restart|force-reload)
$0 stop
sleep 60
$0 start
;;
*)
echo "Usage: /etc/init.d/rtorrent {start|stop|restart}"
exit 1
;;
esac
exit 0
Создаем в директориях "runlevels" символические ссылки на скрипт авто-запуска. Прописываем наш скрипт для нужных уровней исполнения в системе:
# update-rc.d rtorrent start 10 2 3 4 5 . stop 10 0 1 6 .
"Rsync" у нас уже установлен, автоматический запуск заблокирован в файле "/etc/default/rsync" директивой "RSYNC_ENABLE=false".
Воспользуемся утилитой, чтобы просмотреть список поддерживаемых сервисом файловых модулей:
# rsync --port=8730 share.storage.local::
В команде выше два двоеточия "::" после адреса сервера указывает на то, что подключение клиента к сервису должно осуществлено напрямую, без посредника, вроде SSH2 или RSH (если нужно осуществить подключение поверх транспортной прослойки - нужно указывать одно двоеточие ":"). Как более академический вариант можно использовать следующий стиль написания запроса прямого соединения: "rsync://[user@]ip.primary.server[:port][/object]".
Вывод для запроса без точного указания объекта обращения даст нам список поддерживаемых сервисом "модулей" (тех, что мы описали в конфигурационном файле сервиса rsyncd) - что то вроде следующего:
torrents
Более точный запрос с указанием объекта даст содержимое описанное запрашиваемым модулем (мы помним, что из всей директории "/etc" доступ разрешён только к четырём файлам реквизитов пользователей):
# rsync --port=8730 share.storage.local::torrents
drwxrwxr-x 4096 2010/08/05 09:55:30 .
-rwxrwxr-- 240 2010/08/06 12:01:01 file0.torrent
-rwxrwxr-- 1778 2010/08/06 12:01:01 file1.torrent
-rwxrwxr-- 2116 2010/08/06 12:01:02 file2.torrent
....
-rwxrwxr-- 240 2010/08/06 12:01:01 file0.torrent
-rwxrwxr-- 1778 2010/08/06 12:01:01 file1.torrent
-rwxrwxr-- 2116 2010/08/06 12:01:02 file2.torrent
....
Запрос (в "читабельном" виде) доставит нам в директорию "/tmp/test" содержимое директории "/var/lib/share/torrents" сервера "share.storage.local":
# rsync --checksum --recursive --delete rsync://share.storage.local:8730/torrents/ /tmp/test
Где:
"--checksum" - применяем сверку по контрольным суммам файлов, а не по времени изменения и размеру (дольше но точнее);
"--delete" - указываем удалять файлы, которых нет на стороне сервера;
"--recursive" - указываем осуществлять рекурсивный обход директорий.
"--delete" - указываем удалять файлы, которых нет на стороне сервера;
"--recursive" - указываем осуществлять рекурсивный обход директорий.
Применение "/" после имени директории в описании объекта "зеркалирования" в клиентском запросе указывает rsync оперировать только содержимым директории, а отсутствие этого символа делает директорию, как и её содержимое, объектом проводимой операции; иначе говоря, в отсутствии "/" копируется, как сама директория, так и её содержимое, а в присутствии "/" - только содержимое.
Вывод содержимого директории "/tmp/test":
# ls -l /tmp/test
-rwxr-xr-- 1 root root 240 2010-08-06 14:07 file0.torrent
-rwxr-xr-- 1 root root 1778 2010-08-06 14:07 file1.torrent
-rwxr-xr-- 1 root root 2116 2010-08-06 14:07 file2.torrent
....
-rwxr-xr-- 1 root root 1778 2010-08-06 14:07 file1.torrent
-rwxr-xr-- 1 root root 2116 2010-08-06 14:07 file2.torrent
....
Зеркалирование инкрементальное и замещающее с удалением отсутствующих файлов.
Пишем скриптик, запускающий доставку "торрент"-файлов:
# mkdir -p /usr/local/etc/torrent
# touch /usr/local/etc/torrent/rsync.sh
# chmod ugo+x /usr/local/etc/torrent/rsync.sh
# touch /usr/local/etc/torrent/rsync.sh
# chmod ugo+x /usr/local/etc/torrent/rsync.sh
#!/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
USER="rtorrent"
GROUP="share-users"
rsync --checksum --recursive --delete rsync://share.storage.local:8730/torrents/ /var/lib/share/torrents
chown -R ${USER}:${GROUP} /var/lib/share/torrents
exit 0
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
USER="rtorrent"
GROUP="share-users"
rsync --checksum --recursive --delete rsync://share.storage.local:8730/torrents/ /var/lib/share/torrents
chown -R ${USER}:${GROUP} /var/lib/share/torrents
exit 0
Внесем в таблицу "/etc/crontab" указание на запуск скрипта "зеркалирования" с определённой периодичностью. Можно и раз в день, а можно и раз в три часа. Учитывая то, что утилита rsync копирует только изменённые данные, нагрузка в процессе эксплуатации на оборудование не будет настолько великой, чтобы переносить время процедуры на ночное время:
# cat /etc/crontab
....
1 */3 * * * root /usr/local/etc/torrent/rsync.sh &
....
1 */3 * * * root /usr/local/etc/torrent/rsync.sh &
....
Теперь "rsync" каждые три часа будет доставлять обновления "торрент"-файлов с центрального узла и удалять ненужные файлы, а "rtorrent" закачивать из себе в хранилище для последующего предоставления клиентам.