diff --git a/README.md b/README.md index 32fefde59..8e118b100 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,7 @@ If you have a spare domain name you can configure applications to be accessible * [Romm](https://github.com/zurdi15/romm) - A game library manager focused on retro gaming * [Route53 DDNS](https://crazymax.dev/ddns-route53/) - Automatically update AWS Route53 with your IP address * [RSS-Bridge](https://rss-bridge.github.io/rss-bridge/) - The RSS feed for websites missing it +* [ruTorrent](https://github.com/crazy-max/docker-rtorrent-rutorrent/) - BitTorrent client + WebUI * [Sabnzbd](https://sabnzbd.org/) - A powerful usenet downloader that FreeNAS provides * [Sickchill](https://sickchill.github.io/) - for managing TV episodes * [Silverbullet](https://silverbullet.md) - Note-taking application optimized for people with a hacker mindset diff --git a/roles/rtorrent/defaults/main.yml b/roles/rtorrent/defaults/main.yml index 5cf1c763d..50de78a59 100644 --- a/roles/rtorrent/defaults/main.yml +++ b/roles/rtorrent/defaults/main.yml @@ -22,4 +22,25 @@ rtorrent_passwd: "admin" # docker rtorrent_container_name: "rtorrent" rtorrent_image_name: "crazymax/rtorrent-rutorrent" -rtorrent_image_version: "latest" \ No newline at end of file +rtorrent_image_version: "latest" +rtorrent_install_plugins: false +rtorrent_install_themes: false + + +# plugins +rtorrent_plugins_repos: + - repo: "https://github.com/autodl-community/autodl-rutorrent.git" + dest: "autodl" + - repo: "https://github.com/Ac3sRwild/ruTorrent-plugins.git" + dest: "ruTorrent-plugins" + subfolder: true + +rtorrent_plugins_destination_path: "{{ rtorrent_data_directory }}/rutorrent/plugins" + +# themes +rtorrent_themes_repos: + - repo: "https://github.com/norjms/3rd-Party-rutorrent-themes" + dest: "rutorrent-themes" + subfolder: true + +rtorrent_themes_destination_path: "{{ rtorrent_data_directory }}/rutorrent/themes" \ No newline at end of file diff --git a/roles/rtorrent/tasks/main.yml b/roles/rtorrent/tasks/main.yml index f1fc94186..2f6db0a48 100644 --- a/roles/rtorrent/tasks/main.yml +++ b/roles/rtorrent/tasks/main.yml @@ -15,6 +15,188 @@ httpd:2.4-alpine htpasswd -Bb -c /passwd/rutorrent.htpasswd {{ rtorrent_user }} {{ rtorrent_passwd }} + - name: "Populate ruTorrent plugins folder" + tags: rtorrent_plugins + block: + + - name: "Populate ruTorrent plugins folder: Validate dest field in rtorrent_plugins_repos" + assert: + that: + - item.dest is defined + - item.dest != "" + loop: "{{ rtorrent_plugins_repos }}" + failed_when: not item.dest + no_log: true + + - name: "Populate ruTorrent plugins folder: Check if repository directory exists" + stat: + path: "{{ rtorrent_plugins_destination_path }}/{{ item.dest }}" + register: update_repo_list + loop: "{{ rtorrent_plugins_repos }}" + loop_control: + loop_var: item + + - name: "Populate ruTorrent plugins folder: Update repository if directory exists and no subfolder is defined" + git: + repo: "{{ item.item.repo }}" + dest: "{{ rtorrent_plugins_destination_path }}/{{ item.item.dest }}" + update: yes + recursive: yes + when: + - item.stat.exists + - not (item.item.subfolder | default(false)) + loop: "{{ update_repo_list.results }}" + loop_control: + loop_var: item + no_log: true + + - name: "Populate ruTorrent plugins folder: Clone new rTorrent plugins repositories" + git: + repo: "{{ item.item.repo }}" + dest: "{{ rtorrent_plugins_destination_path }}/{{ item.item.dest }}" + update: yes + recursive: yes + when: + - not item.stat.exists + - not (item.item.subfolder | default(false)) + loop: "{{ update_repo_list.results }}" + loop_control: + loop_var: item + no_log: true + + - name: "Populate ruTorrent plugins folder: Clone new rTorrent multi plugins repositories" + git: + repo: "{{ item.item.repo }}" + dest: "{{ rtorrent_plugins_destination_path }}/{{ item.item.dest }}_tmp" + update: yes + recursive: yes + when: + - not item.stat.exists + - (item.item.subfolder | default(false)) + loop: "{{ update_repo_list.results }}" + loop_control: + loop_var: item + no_log: true + + - name: "Populate ruTorrent plugins folder: Move subfolder content if 'subfolder' is true" + command: > + find "{{ rtorrent_plugins_destination_path }}/{{ item.item.dest }}_tmp" + -mindepth 1 -maxdepth 1 + ! -name '.git' + ! -name '.gitattributes' + ! -name 'src' + ! -name 'LICENSE' + ! -name 'README.md' + -exec mv -f -t "{{ rtorrent_plugins_destination_path }}" {} + + when: (item.item.subfolder | default(false)) + loop: "{{ update_repo_list.results }}" + loop_control: + loop_var: item + no_log: true + + - name: "Populate ruTorrent plugins folder: Clean up temporary directories" + file: + path: "{{ rtorrent_plugins_destination_path }}/{{ item.item.dest }}_tmp" + state: absent + when: (item.item.subfolder | default(false)) + loop: "{{ update_repo_list.results }}" + loop_control: + loop_var: item + no_log: true + + when: rtorrent_install_plugins is true + + - name: "Populate ruTorrent themes folder" + tags: rtorrent_themes + block: + + - name: "Populate ruTorrent themes folder: Validate dest field in rtorrent_themes_repos" + assert: + that: + - item.dest is defined + - item.dest != "" + loop: "{{ rtorrent_themes_repos }}" + failed_when: not item.dest + no_log: true + + - name: "Populate ruTorrent themes folder: Check if theme directory exists" + stat: + path: "{{ rtorrent_themes_destination_path }}/{{ item.dest }}" + register: update_theme_list + loop: "{{ rtorrent_themes_repos }}" + loop_control: + loop_var: item + + - name: "Populate ruTorrent themes folder: Update theme repository if directory exists and no subfolder is defined" + git: + repo: "{{ item.item.repo }}" + dest: "{{ rtorrent_themes_destination_path }}/{{ item.item.dest }}" + update: yes + recursive: yes + when: + - item.stat.exists + - not (item.item.subfolder | default(false)) + loop: "{{ update_theme_list.results }}" + loop_control: + loop_var: item + no_log: true + + - name: "Populate ruTorrent themes folder: Clone new rTorrent themes repositories" + git: + repo: "{{ item.item.repo }}" + dest: "{{ rtorrent_themes_destination_path }}/{{ item.item.dest }}" + update: yes + recursive: yes + when: + - not item.stat.exists + - not (item.item.subfolder | default(false)) + loop: "{{ update_theme_list.results }}" + loop_control: + loop_var: item + no_log: true + + - name: "Populate ruTorrent themes folder: Clone new rTorrent multi themes repositories" + git: + repo: "{{ item.item.repo }}" + dest: "{{ rtorrent_themes_destination_path }}/{{ item.item.dest }}_tmp" + update: yes + recursive: yes + when: + - not item.stat.exists + - (item.item.subfolder | default(false)) + loop: "{{ update_theme_list.results }}" + loop_control: + loop_var: item + no_log: true + + - name: "Populate ruTorrent themes folder: Move subfolder content if 'subfolder' is true" + command: > + find "{{ rtorrent_themes_destination_path }}/{{ item.item.dest }}_tmp" + -mindepth 1 -maxdepth 1 + ! -name '.git' + ! -name '.gitattributes' + ! -name 'src' + ! -name 'LICENSE' + ! -name 'README.md' + -exec mv -f -t "{{ rtorrent_themes_destination_path }}" {} + + when: (item.item.subfolder | default(false)) + loop: "{{ update_theme_list.results }}" + loop_control: + loop_var: item + #no_log: true + + - name: "Populate ruTorrent themes folder: Clean up temporary directories" + file: + path: "{{ rtorrent_themes_destination_path }}/{{ item.item.dest }}_tmp" + state: absent + when: (item.item.subfolder | default(false)) + loop: "{{ update_theme_list.results }}" + loop_control: + loop_var: item + no_log: true + + when: rtorrent_install_themes is true + - name: rtorrent Docker Container community.docker.docker_container: name: "{{ rtorrent_container_name }}" @@ -24,23 +206,53 @@ - "{{ rtorrent_data_directory }}:/data:rw" - "{{ rtorrent_passwd_directory }}:/passwd" - "{{ rtorrent_root }}:/downloads:rw" + - "{{ rtorrent_home }}/scripts:/scripts:rw" ports: - "{{ rtorrent_port }}:8080" + - "6881:6881/udp" - "50000:50000" + env: + TZ: "{{ ansible_nas_timezone }}" restart_policy: unless-stopped memory: "{{ rtorrent_memory }}" labels: traefik.enable: "{{ rtorrent_available_externally | string }}" - traefik.http.routers.hello_world.rule: "Host(`{{ rtorrent_hostname }}.{{ ansible_nas_domain }}`)" - traefik.http.routers.hello_world.tls.certresolver: "letsencrypt" - traefik.http.routers.hello_world.tls.domains[0].main: "{{ ansible_nas_domain }}" - traefik.http.routers.hello_world.tls.domains[0].sans: "*.{{ ansible_nas_domain }}" - traefik.http.services.hello_world.loadbalancer.server.port: "8000" + traefik.http.routers.rtorrent.rule: "Host(`{{ rtorrent_hostname }}.{{ ansible_nas_domain }}`)" + traefik.http.routers.rtorrent.tls.certresolver: "letsencrypt" + traefik.http.routers.rtorrent.tls.domains[0].main: "{{ ansible_nas_domain }}" + traefik.http.routers.rtorrent.tls.domains[0].sans: "*.{{ ansible_nas_domain }}" + traefik.http.services.rtorrent.loadbalancer.server.port: "8080" homepage.group: Download Tools homepage.name: ruTorrent homepage.icon: rutorrent.png homepage.href: "http://{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}:{{ rtorrent_port }}" homepage.description: ruTorrent client + + - name: "Install necessary packages for ruTorrent plugins" + community.docker.docker_container_exec: + container: "{{ rtorrent_container_name }}" + command: | + apk update + apk add --no-cache \ + p7zip \ + unzip \ + zip \ + cksfv + no_log: true + when: rtorrent_install_plugins is true + + - name: "Install rar packages for ruTorrent plugins" + community.docker.docker_container_exec: + container: "{{ rtorrent_container_name }}" + command: | + curl -LO https://www.rarlab.com/rar/rarlinux-x64-701.tar.gz + tar -xzf rarlinux-x64-701.tar.gz + cp rar/rar /usr/local/bin/ + cp rar/unrar /usr/local/bin/ + rm -rf rar rarlinux-x64-701.tar.gz + no_log: true + when: rtorrent_install_plugins is true + when: rtorrent_enabled is true - name: Stop rtorrent