├── .gitignore
├── README.md
├── ansible.cfg
├── assets
├── reverse_proxy
│ ├── .gitignore
│ ├── certs
│ │ └── .gitignore
│ └── img
│ │ ├── .gitignore
│ │ ├── unifi_bg_example.png
│ │ └── unifi_fg_example.png
├── rtorrent
│ └── .gitignore
└── stats
│ └── .gitignore
├── group_vars
├── .gitignore
├── jails.yaml.template
└── media.yaml.template
├── host_vars
├── .gitignore
├── dnscrypt-proxy.yaml.template
├── freenas.yaml.template
├── reverse-proxy.yaml.template
├── rtorrent.yaml.template
└── stats.yaml.template
├── inventories
└── hosts.yaml
├── roles
├── dnscrypt-proxy
│ ├── defaults
│ │ └── main.yaml
│ ├── handlers
│ │ └── main.yaml
│ ├── tasks
│ │ └── main.yaml
│ └── templates
│ │ └── unbound.conf
├── flood
│ ├── defaults
│ │ └── main.yaml
│ ├── handlers
│ │ └── main.yaml
│ ├── meta
│ │ └── main.yaml
│ ├── tasks
│ │ └── main.yaml
│ └── templates
│ │ ├── config.js
│ │ ├── flood.sh
│ │ └── nginx-vhost.conf
├── jails_setup
│ ├── files
│ │ └── sudoers_ansible
│ └── tasks
│ │ ├── main.yaml
│ │ └── setup.yaml
├── mdns
│ ├── handlers
│ │ └── main.yaml
│ └── tasks
│ │ └── main.yaml
├── media_group
│ └── tasks
│ │ └── main.yaml
├── nginx
│ ├── defaults
│ │ └── main.yaml
│ ├── handlers
│ │ └── main.yaml
│ ├── tasks
│ │ └── main.yaml
│ └── templates
│ │ ├── nginx.conf
│ │ └── ssl_session_cache.conf
├── php
│ ├── handlers
│ │ └── main.yaml
│ ├── tasks
│ │ └── main.yaml
│ └── templates
│ │ └── php.ini
├── plex
│ ├── handlers
│ │ └── main.yaml
│ └── tasks
│ │ ├── hello_hue.yaml
│ │ ├── main.yaml
│ │ ├── trakt_tv.yaml
│ │ └── twitch_mod.yaml
├── pre_setup
│ └── tasks
│ │ └── main.yaml
├── radarr
│ ├── handlers
│ │ └── main.yaml
│ └── tasks
│ │ └── main.yaml
├── reverse_proxy
│ ├── defaults
│ │ └── main.yaml
│ ├── files
│ │ ├── 50x.html
│ │ └── access.lua
│ ├── handlers
│ │ └── main.yaml
│ ├── meta
│ │ └── main.yaml
│ ├── tasks
│ │ ├── alt-domains.yaml
│ │ ├── google-oauth.yaml
│ │ ├── letsencrypt.yaml
│ │ ├── main.yaml
│ │ ├── public.yaml
│ │ ├── secure.yaml
│ │ └── subdirs.yaml
│ └── templates
│ │ ├── alt-domains-location.conf
│ │ ├── alt-domains-vhost.conf
│ │ ├── google-oauth.conf
│ │ ├── index.html
│ │ ├── letsencrypt.conf
│ │ ├── proxy_params
│ │ ├── public-vhost.conf
│ │ ├── secure-vhost.conf
│ │ ├── subdirs-location.conf
│ │ └── subdirs-upstream.conf
├── rtorrent
│ ├── handlers
│ │ └── main.yaml
│ ├── meta
│ │ └── main.yaml
│ ├── tasks
│ │ ├── main.yaml
│ │ └── nzbtomedia.yaml
│ └── templates
│ │ ├── autoProcessMedia.cfg
│ │ ├── rtorrent.rc
│ │ ├── rtorrent.sh
│ │ └── set_home.sh
├── rutorrent
│ ├── files
│ │ └── labels
│ │ │ ├── couchpotato.png
│ │ │ ├── movies.png
│ │ │ └── sonarr.png
│ ├── meta
│ │ └── main.yaml
│ ├── tasks
│ │ └── main.yaml
│ └── templates
│ │ ├── config.php
│ │ ├── config.php.orig
│ │ ├── nginx-vhost.conf
│ │ └── php-pool.conf
├── sabnzbd
│ ├── handlers
│ │ └── main.yaml
│ ├── meta
│ │ └── main.yaml
│ ├── tasks
│ │ ├── main.yaml
│ │ └── nzbtomedia.yaml
│ └── templates
│ │ ├── autoProcessMedia.cfg
│ │ └── nginx-vhost.conf
├── sonarr
│ ├── handlers
│ │ └── main.yaml
│ └── tasks
│ │ └── main.yaml
├── stats
│ ├── HDD stats.json
│ ├── System Load.json
│ ├── defaults
│ │ └── main.yaml
│ ├── handlers
│ │ └── main.yaml
│ ├── tasks
│ │ └── main.yaml
│ └── templates
│ │ ├── grafana.conf
│ │ ├── influxd.conf
│ │ └── telegraf.conf
└── user_customization
│ ├── defaults
│ └── main.yaml
│ └── tasks
│ └── main.yaml
├── scripts
├── backup_freenas_db.sh
└── backup_jails.sh
└── site.yaml
/.gitignore:
--------------------------------------------------------------------------------
1 | site.retry
2 | *.pyc
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Jails configuration for FreeNAS
2 |
3 | Configure your FreeNAS jails with ansible.
4 | All software and their dependencies are automatically
5 | installed. Most of the configuration is taken care of as well, with the exception of settings only configurable through a web front-end (such as credentials for Usenet in SABnzbd).
6 | All jails have mDNS set-up, so you can access them on the internal network with `[[jailname]].local`.
7 |
8 | The jails are:
9 |
10 | * Reverse proxy
11 | * Acts as a internet facing frontend for all jail webinterfaces
12 | * Has a nice landing page where you can add links and parallax images for navigation
13 | * Automatically sets up letsencrypt
14 | * Authenticates you via your Google account
15 | * [DNSCrypt Proxy](https://github.com/jedisct1/dnscrypt-proxy)
16 | * All jails can be configured to use this one for name resolution
17 | * You can set your DHCP server to tell the rest of the network to use this jail for name resolution
18 | * [Unifi](https://unifi-sdn.ubnt.com/) server
19 | * Easy access to your Unifi AP configuration interface
20 | * Run your Unifi management software as a daemon so it can collect stats
21 | * [SABnzbd](https://sabnzbd.org/)
22 | * [rTorrent](https://github.com/rakshasa/rtorrent) + [ruTorrent](https://github.com/Novik/ruTorrent)
23 | * Contains some extra labels for ruTorrent
24 | * [Jackett](https://github.com/Jackett/Jackett)
25 | * [Sonarr](https://sonarr.tv/)
26 | * [Radarr](https://radarr.video/)
27 | * [Plex media server](https://www.plex.tv/)
28 | * Comes with [HelloHue](https://github.com/ledge74/HelloHue.bundle), [Trakt.tv](https://github.com/trakt/Plex-Trakt-Scrobbler), [TwitchMod](https://github.com/coryo/TwitchMod.bundle), [WebTools](https://github.com/ukdtom/WebTools.bundle/wiki), [YouTubeTV](https://github.com/kolsys/YouTubeTV.bundle) plugins
29 | * [Grafana](https://grafana.com/) + [Telegraf](https://github.com/influxdata/telegraf) + [InfluxDB](https://www.influxdata.com/) statistics
30 | * Supports fetching data through IPMI from your server
31 | * Can get your overall network usage through SNMP from your router (only tested with Linksys LRT214)
32 | * Can pull data from FreeNAS' own collectd service (see `host_vars/stats@freenas.local.yaml.template`, pre-made Grafana dashboard at `roles/stats/`)
33 | * Pulls all S.M.A.R.T. data from your HDDs & SSDs (also has a pre-made Grafana dashboard)
34 | * [Elasticsearch](https://www.elastic.co/products/elasticsearch) + [Kibana](https://www.elastic.co/products/kibana) [Logstash](https://www.elastic.co/products/logstash) + [Filebeat](https://www.elastic.co/products/beats/filebeat) for log aggregation
35 | * Most other jails are set up with filebeat to forward their logs to this jail (some parsing of logs and setup is still missing to see all logs in all jails)
36 | * Normalizes data from different loggers so that fields containing the same data have the same name
37 | * Can act as a rsyslog server for FreeNAS, Unifi, your router, and other devices on your network
38 |
39 | # Setup
40 |
41 | Start by creating the jails you want to create in FreeNAS.
42 | The names must match the ones used in this project, check out `inventories/hosts.yaml`
43 | for a list. Comment out any jail you are not interested in.
44 | Read the `*.template` files in `host_vars/` for instructions for the different jails
45 | and copy them to the same directory but omit `.template` part to enable them.
46 |
47 | # Backup
48 |
49 | `scripts/` contains two scripts that you can use for creating versioned backups of
50 | both your FreeNAS configuration database and the userdata of the software running in your jails.
51 | The jail backup script uses rsync with hardlinks two preserve diskspace.
52 |
--------------------------------------------------------------------------------
/ansible.cfg:
--------------------------------------------------------------------------------
1 | # config file for ansible -- http://ansible.com/
2 | # ==============================================
3 |
4 | # nearly all parameters can be overridden in ansible-playbook
5 | # or with command line flags. ansible will read ANSIBLE_CONFIG,
6 | # ansible.cfg in the current working directory, .ansible.cfg in
7 | # the home directory or /etc/ansible/ansible.cfg, whichever it
8 | # finds first
9 |
10 | [defaults]
11 | inventory = inventories/hosts.yaml
12 | remote_user = ansible
13 |
14 | [privilege_escalation]
15 | become = True
16 |
17 | [ssh_connection]
18 | # ssh arguments to use
19 | # Leaving off ControlPersist will result in poor performance, so use
20 | # paramiko on older platforms rather than removing it
21 | #
22 | ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s -o ForwardAgent=yes
23 |
24 | # Enabling pipelining reduces the number of SSH operations required to
25 | # execute a module on the remote server. This can result in a significant
26 | # performance improvement when enabled, however when using "sudo:" you must
27 | # first disable 'requiretty' in /etc/sudoers
28 | #
29 | # By default, this option is disabled to preserve compatibility with
30 | # sudoers configurations that have requiretty (the default on many distros).
31 | #
32 | pipelining = True
33 |
--------------------------------------------------------------------------------
/assets/reverse_proxy/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !/.gitignore
3 |
--------------------------------------------------------------------------------
/assets/reverse_proxy/certs/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !/.gitignore
3 |
--------------------------------------------------------------------------------
/assets/reverse_proxy/img/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !/.gitignore
3 | !/unifi_bg_example.png
4 | !/unifi_fg_example.png
5 |
--------------------------------------------------------------------------------
/assets/reverse_proxy/img/unifi_bg_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/andsens/freenas-jailconfig/60d09a7a4921ee6c132051b1f3568cee756a8a7d/assets/reverse_proxy/img/unifi_bg_example.png
--------------------------------------------------------------------------------
/assets/reverse_proxy/img/unifi_fg_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/andsens/freenas-jailconfig/60d09a7a4921ee6c132051b1f3568cee756a8a7d/assets/reverse_proxy/img/unifi_fg_example.png
--------------------------------------------------------------------------------
/assets/rtorrent/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !/.gitignore
3 |
--------------------------------------------------------------------------------
/assets/stats/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !/.gitignore
3 |
--------------------------------------------------------------------------------
/group_vars/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 | !*.yaml.template
4 |
--------------------------------------------------------------------------------
/group_vars/jails.yaml.template:
--------------------------------------------------------------------------------
1 | ---
2 | # Jails-wide configuration to customize your shell as root during `iocage console`
3 |
4 | root_shell: /usr/local/bin/zsh
5 |
6 | # Packages to install
7 | user_packages:
8 | - git
9 | - bash
10 | - zsh
11 |
12 | # Repos to clone.
13 | # Use "private: yes" to only create the repo and its remote, you can pull it later
14 | git_repos:
15 | - remote: https://github.com/andsens/homeshick.git
16 | path: /root/.homesick/repos/homeshick
17 | - remote: https://github.com/sorin-ionescu/prezto.git
18 | path: /root/.homesick/repos/prezto
19 | - remote: git@github.com:andsens/dotfiles
20 | path: /root/.homesick/repos/dotfiles
21 | private: yes
22 |
--------------------------------------------------------------------------------
/group_vars/media.yaml.template:
--------------------------------------------------------------------------------
1 | sabnzbd_api_key: 0123456789abcdef0123456789abcdef
2 | sonarr_api_key: 0123456789abcdef0123456789abcdef
3 | radarr_api_key: 0123456789abcdef0123456789abcdef
4 |
--------------------------------------------------------------------------------
/host_vars/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 | !*.yaml.template
4 |
--------------------------------------------------------------------------------
/host_vars/dnscrypt-proxy.yaml.template:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | dnscrypt_resolvers:
4 | - dnscrypt.eu-dk
5 | - dnscrypt-de-blahdns-ipv4
6 | - dnscrypt.nl-ns0
7 | - dnscrypt.me
8 | - dnscrypt.uk-ipv4
9 |
--------------------------------------------------------------------------------
/host_vars/freenas.yaml.template:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # Unless passwordless sudo is enabled for the freenas user, provision this host with:
4 | # ANSIBLE_BECOME_ASK_PASS=true ANSIBLE_REMOTE_USER=USER ansible-playbook --limit freenas site.yml
5 |
6 | jails_path: /mnt/jails/iocage/jails
7 | jails_auth_keys:
8 | - "{{ lookup('file', '/home/USERNAME/.ssh/id_rsa.pub') }}"
9 |
--------------------------------------------------------------------------------
/host_vars/reverse-proxy.yaml.template:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # Consider https://github.com/GUI/nginx-upstream-dynamic-servers
4 |
5 | # In order to run nginx with the lua & ndk modules you need to compile nginx yourself
6 | # Do this by entering the jail with `sudo iocage console reverse-proxy sh`
7 | # and then running:
8 | # portsnap fetch; portsnap extract; cd /usr/ports/www/nginx; make config
9 | # Select DEVEL KIT, LUA & SET MISC in the modules prompt and answer yes to all subsequent prompts
10 | # After that run: `make install`
11 |
12 | # See https://github.com/cloudflare/nginx-google-oauth#configuring-oauth-access
13 | # for instructions on how to create a client ID and secret.
14 | # Make sure to allow all reverse_proxy_alt_domains subdomains as redirect URIs
15 |
16 | reverse_proxy_google_oauth:
17 | client_id: "CLIENTID.apps.googleusercontent.com"
18 | client_secret: "CLIENTSECRET"
19 | token_secret: "{{ lookup('password', playbook_dir ~ '/assets/reverse_proxy_google_oauth length=32 chars=ascii_letters') }}"
20 | whitelist:
21 | - example@gmail.com
22 | # nginx requires its own resolvers to be specified, set them here
23 | resolvers:
24 | - "10.134.102.1"
25 | - "8.8.8.8"
26 | - "8.8.4.4"
27 | reverse_proxy_domain: example.com
28 | reverse_proxy_alt_domains:
29 | - name: unifi
30 | domain: unifi.example.com
31 | address: 10.134.102.3:8443
32 | trust_ssl: '{{ playbook_dir }}/assets/reverse_proxy/certs/unifi.pem'
33 | # Fetch the PEM cert with
34 | # echo | openssl s_client -showcerts -servername 10.134.102.3 -connect 10.134.102.3:8443 2>/dev/null | openssl x509 -inform pem -outform pem -out assets/reverse_proxy/certs/unifi.pem
35 | - name: plex
36 | domain: plex.example.com
37 | address: 10.134.102.10:32400
38 | require_authentication: no
39 | reverse_proxy_subdirs:
40 | - name: sabnzbd
41 | address: 10.134.102.11:80
42 | forward_subdir_name: yes # determines whether the forwarded request should contain the subdir
43 | inline_config: |
44 | # Don't authenticate API access, let sabnzbd do that
45 | location /sabnzbd/api {
46 | set $ngo_enabled "false";
47 | proxy_pass http://sabnzbd;
48 | }
49 | client_max_body_size 10M;
50 | # - name: rutorrent
51 | # address: 10.134.102.14:80
52 | - name: flood
53 | address: 10.134.102.14:80
54 | - name: jackett
55 | address: 10.134.102.16:9117
56 | - name: radarr
57 | address: 10.134.102.15:7878
58 | forward_subdir_name: yes
59 | - name: sonarr
60 | address: 10.134.102.12:8989
61 | forward_subdir_name: yes
62 | - name: stats
63 | address: 10.134.102.25:3000
64 | forward_subdir_name: no # default is no, but especially important for grafana
65 | - name: logs
66 | address: 10.134.102.26:5601
67 | forward_subdir_name: no
68 | reverse_proxy_links:
69 | - name: Unifi
70 | link: unifi/
71 | background: '{{ playbook_dir }}/assets/reverse_proxy/img/unifi_example_bg.png'
72 | foreground: '{{ playbook_dir }}/assets/reverse_proxy/img/unifi_example_fg.png'
73 |
--------------------------------------------------------------------------------
/host_vars/rtorrent.yaml.template:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # Can be flood or rutorrent
4 | rtorrent_frontend: flood
5 | flood_jwt_secret: "{{ lookup('password', playbook_dir ~ '/assets/rtorrent/flood_jwt_secret length=32 chars=ascii_letters') }}"
6 |
--------------------------------------------------------------------------------
/host_vars/stats.yaml.template:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # To send FreeNAS stats to InfluxDB copy the typesdb from FreeNAS to the jail:
4 | # sudo cp /usr/local/share/collectd/types.db /mnt/jails/stats/usr/local/share/collectd/types.db
5 | # Then add the following "Post Init" command in the FreeNAS console:
6 | # printf '\n Server "10.134.102.25" "25826"\n\n' >> /usr/local/etc/collectd.conf && service collectd restart
7 | # In Grafana import "roles/stats/System Load.json" to get an overview of that data
8 |
9 | grafana_root_url: https://example.com/stats
10 | grafana_secret_key: "{{ lookup('password', playbook_dir ~ '/assets/stats/grafana_secret_key length=32 chars=ascii_letters') }}"
11 | grafana_plugins:
12 | - briangann-gauge-panel
13 | telegraf_snmp:
14 | agents: ["10.134.102.1"]
15 | fields: |
16 | name = "router"
17 | [[inputs.snmp.field]]
18 | name = "hostname"
19 | oid = "SNMPv2-MIB::sysName.0"
20 | is_tag = true
21 | [[inputs.snmp.field]]
22 | name = "if7_in_octects"
23 | oid = "IF-MIB::ifInOctets.7"
24 | [[inputs.snmp.field]]
25 | name = "if7_out_octects"
26 | oid = "IF-MIB::ifOutOctets.7"
27 | [[inputs.snmp.field]]
28 | name = "if8_in_octects"
29 | oid = "IF-MIB::ifInOctets.8"
30 | [[inputs.snmp.field]]
31 | name = "if8_out_octects"
32 | oid = "IF-MIB::ifOutOctets.8"
33 |
--------------------------------------------------------------------------------
/inventories/hosts.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | all:
3 | hosts:
4 | freenas:
5 | ansible_ssh_host: freenas.local
6 | ansible_python_interpreter: /usr/local/bin/python3
7 | children:
8 | jails:
9 | hosts:
10 | reverse-proxy:
11 | ansible_ssh_host: reverse-proxy.local
12 | ansible_python_interpreter: /usr/local/bin/python3
13 | rtorrent:
14 | ansible_ssh_host: rtorrent.local
15 | ansible_python_interpreter: /usr/local/bin/python3
16 | sabnzbd:
17 | ansible_ssh_host: sabnzbd.local
18 | ansible_python_interpreter: /usr/local/bin/python3
19 | plex:
20 | ansible_ssh_host: plex.local
21 | ansible_python_interpreter: /usr/local/bin/python3
22 | sonarr:
23 | ansible_ssh_host: sonarr.local
24 | ansible_python_interpreter: /usr/local/bin/python3
25 | radarr:
26 | ansible_ssh_host: radarr.local
27 | ansible_python_interpreter: /usr/local/bin/python3
28 | dnscrypt-proxy:
29 | ansible_ssh_host: dnscrypt-proxy.local
30 | ansible_python_interpreter: /usr/local/bin/python3
31 | stats:
32 | ansible_ssh_host: stats.local
33 | ansible_python_interpreter: /usr/local/bin/python3
34 | media:
35 | hosts:
36 | rtorrent:
37 | sabnzbd:
38 | plex:
39 | sonarr:
40 | radarr:
41 |
--------------------------------------------------------------------------------
/roles/dnscrypt-proxy/defaults/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | dnscrypt_resolvers: []
4 |
--------------------------------------------------------------------------------
/roles/dnscrypt-proxy/handlers/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: start dnscrypt-proxy
4 | service:
5 | name: dnscrypt-proxy
6 | state: started
7 |
8 | - name: restart dnscrypt-proxy
9 | service:
10 | name: dnscrypt-proxy
11 | state: restarted
12 |
13 | - name: start unbound
14 | service:
15 | name: local_unbound
16 | state: started
17 |
18 | - name: restart unbound
19 | service:
20 | name: local_unbound
21 | state: restarted
22 |
--------------------------------------------------------------------------------
/roles/dnscrypt-proxy/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: install dnscrypt-proxy2
4 | pkgng:
5 | name: dnscrypt-proxy2
6 | state: present
7 |
8 | - name: install unbound
9 | pkgng:
10 | name: unbound
11 | state: present
12 | notify: restart unbound
13 |
14 | - name: configure dnscrypt-proxy resolver list
15 | lineinfile:
16 | dest: /usr/local/etc/dnscrypt-proxy/dnscrypt-proxy.toml
17 | line: server_names = {{ dnscrypt_resolvers | to_json }}
18 | regexp: ^server_names
19 | notify: restart dnscrypt-proxy
20 | tags: [config]
21 |
22 | - name: configure dnscrypt-proxy listening port
23 | lineinfile:
24 | dest: /usr/local/etc/dnscrypt-proxy/dnscrypt-proxy.toml
25 | line: listen_addresses = ['127.0.0.1:5300']
26 | regexp: ^listen_addresses
27 | notify: restart dnscrypt-proxy
28 | tags: [config]
29 |
30 | - name: configure unbound
31 | template:
32 | src: unbound.conf
33 | dest: /var/unbound/unbound.conf
34 | owner: root
35 | group: wheel
36 | mode: 0644
37 | notify: restart unbound
38 | tags: [config]
39 |
40 | - name: enable dnscrypt-proxy
41 | service:
42 | name: dnscrypt-proxy
43 | enabled: yes
44 | notify: start dnscrypt-proxy
45 |
46 | - name: enable unbound
47 | service:
48 | name: local_unbound
49 | enabled: yes
50 | notify: start unbound
51 |
--------------------------------------------------------------------------------
/roles/dnscrypt-proxy/templates/unbound.conf:
--------------------------------------------------------------------------------
1 | server:
2 | # base setup
3 | username: unbound
4 | directory: /var/unbound
5 | chroot: /var/unbound
6 | pidfile: /var/run/local_unbound.pid
7 | # DNSSEC
8 | auto-trust-anchor-file: /var/unbound/root.key
9 | # Verbose logging
10 | verbosity: 1
11 |
12 | # Listen on all interfaces and allow external lookups (i.e. LAN)
13 | interface: 0.0.0.0
14 | interface: ::0
15 | access-control: 0.0.0.0/0 allow_snoop
16 |
17 | # DNSCrypt specific setting
18 | do-not-query-localhost: no
19 |
20 | # Unblock reverse lookups for LAN addresses
21 | unblock-lan-zones: yes
22 | insecure-lan-zones: yes
23 | # Forward all queries to DNSCrypt
24 | forward-zone:
25 | name: "."
26 | forward-addr: 127.0.0.1@5300
27 | # Disable remote control
28 | remote-control:
29 | control-enable: no
30 | # Include additional files from conf.d
31 | include: /var/unbound/conf.d/*.conf
32 |
--------------------------------------------------------------------------------
/roles/flood/defaults/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | flood_jwt_secret: null
4 |
--------------------------------------------------------------------------------
/roles/flood/handlers/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: yarn install flood
4 | yarn:
5 | path: /usr/local/www/flood
6 |
7 | - name: yarn build flood
8 | command: yarn run build
9 | args:
10 | chdir: /usr/local/www/flood
11 |
12 | - name: start flood
13 | service:
14 | name: flood
15 | state: started
16 |
17 | - name: restart flood
18 | service:
19 | name: flood
20 | state: restarted
21 |
--------------------------------------------------------------------------------
/roles/flood/meta/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | dependencies:
4 | - role: nginx
5 |
--------------------------------------------------------------------------------
/roles/flood/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: install flood dependencies
4 | pkgng:
5 | name:
6 | - node
7 | - yarn
8 | state: present
9 |
10 | - name: create flood user
11 | user:
12 | name: flood
13 | groups:
14 | - media
15 | - rtorrent
16 | state: present
17 | home: /usr/local/www/flood
18 | createhome: no
19 |
20 | - name: add the flood user to the rtorrent group
21 | user:
22 | name: flood
23 | groups: rtorrent
24 | append: yes
25 | notify: restart flood
26 |
27 | - name: add the www user to the rtorrent group
28 | user:
29 | name: www
30 | groups: rtorrent
31 | append: yes
32 | notify: restart nginx
33 |
34 | - name: create flood webdir
35 | file:
36 | path: /usr/local/www/flood
37 | state: directory
38 | owner: root
39 | group: wheel
40 | mode: 0755
41 |
42 | - name: clone flood
43 | git:
44 | repo: https://github.com/jfurrow/flood.git
45 | dest: /usr/local/www/flood
46 | version: 61b63e9b549b4ae92796b5595f583e4cff388a13
47 | update: yes
48 | force: yes
49 | notify:
50 | - yarn install flood
51 | - yarn build flood
52 |
53 | - name: set owner of server/db/ to flood
54 | file:
55 | path: /usr/local/www/flood/server/db
56 | state: directory
57 | recurse: yes
58 | owner: flood
59 | group: wheel
60 | mode: 'u=rwX,go=rX'
61 |
62 | - name: configure flood
63 | template:
64 | src: config.js
65 | dest: /usr/local/www/flood/config.js
66 | owner: root
67 | group: wheel
68 | mode: 0644
69 | notify:
70 | - yarn build flood
71 | tags: [config]
72 |
73 | - name: create flood init script
74 | template:
75 | src: flood.sh
76 | dest: /usr/local/etc/rc.d/flood
77 | owner: root
78 | group: wheel
79 | mode: 0755
80 | notify: restart flood
81 |
82 | - name: enable flood
83 | service:
84 | name: flood
85 | enabled: yes
86 | notify: start flood
87 |
88 | - name: create the nginx vhost
89 | template:
90 | src: nginx-vhost.conf
91 | dest: /usr/local/etc/nginx/sites-available/flood
92 | owner: root
93 | group: wheel
94 | mode: 0644
95 | notify: reload nginx
96 | tags: [config]
97 |
98 | - name: disable rutorrent vhost
99 | file:
100 | path: /usr/local/etc/nginx/sites-enabled/rutorrent
101 | state: absent
102 | notify: reload nginx
103 |
104 | - name: enable the vhost
105 | file:
106 | src: /usr/local/etc/nginx/sites-available/flood
107 | dest: /usr/local/etc/nginx/sites-enabled/flood
108 | state: link
109 | notify: reload nginx
110 |
--------------------------------------------------------------------------------
/roles/flood/templates/config.js:
--------------------------------------------------------------------------------
1 | // This is the configuration file for Flood, a React-based frontend for the
2 | // rtorrent BitTorrent client.
3 | // Copy this file to ./config.js and make changes below.
4 | // config.js must exist before running `npm run build`.
5 |
6 | const CONFIG = {
7 | // This URI will prefix all of Flood's HTTP requests. You _must_ have a web
8 | // server, like nginx, configured to forward these requests to the Flood
9 | // web server.
10 | // For example, if you intend to serve from http://example.com/flood, set this to
11 | // '/flood' and configure your web server to pass _all_ requests from `/flood` to
12 | // the root of Flood's web server.
13 | // Recompiling assets with `npm run build` is needed after each `baseURI` change.
14 | // See https://github.com/jfurrow/flood/wiki/Using-Flood-behind-a-reverse-proxy
15 | baseURI: '/flood',
16 | // Flood uses a local nedb database to keep track of users, torrents,
17 | // and activity. The database is regularly purged to remove outdated data.
18 | // This value dictates how old data is, in milliseconds, before being purged.
19 | dbCleanInterval: 1000 * 60 * 60,
20 | // Where to store the local nedb database.
21 | dbPath: './server/db/',
22 | // The host that Flood should listen for web connections on.
23 | // If you want to connect to Flood from hosts other that the one it is running
24 | // on, you should change this value.
25 | // To listen on all interfaces, change to `floodServerHost: '0.0.0.0'`..
26 | floodServerHost: '127.0.0.1',
27 | // The port that Flood should listen for web connections on.
28 | floodServerPort: 3000,
29 | // Used for development. See the "Local Development" section of README.md
30 | // for detail.
31 | floodServerProxy: 'http://127.0.0.1:3000',
32 | // Flood keeps a history of torrent download and upload speeds.
33 | // This value dictates the number of individual records per period to keep.
34 | maxHistoryStates: 30,
35 | // How often (in milliseconds) Flood will request the torrent list from.
36 | torrentClientPollInterval: 1000 * 2,
37 | // A unique secret for signing messages with JWT (see https://jwt.io). Change
38 | // this to something unique and hard to guess.
39 | secret: '{{ flood_jwt_secret }}',
40 | // Configuration for SSL, if using SSL with the Flood service directly.
41 | ssl: false,
42 | sslKey: '/absolute/path/to/key/',
43 | sslCert: '/absolute/path/to/certificate/'
44 | };
45 | // Do not remove the below line.
46 | module.exports = CONFIG;
47 |
--------------------------------------------------------------------------------
/roles/flood/templates/flood.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # PROVIDE: flood
4 | # REQUIRE: DAEMON cleanvar
5 | # KEYWORD: shutdown
6 |
7 | . /etc/rc.subr
8 |
9 | flood_home=/usr/local/www/flood
10 | flood_bin=/usr/local/www/flood/server/bin/start.js
11 |
12 | name=flood
13 | rcvar=flood_enable
14 | pidfile="/var/run/${name}.pid"
15 | logfile="/var/log/${name}.log"
16 | command="/usr/sbin/daemon"
17 | command_args="-o ${logfile} -P ${pidfile} -t ${name} -u flood /usr/local/bin/node ${flood_bin}"
18 | flood_chdir=${flood_home}
19 | argument_precmd=
20 |
21 | load_rc_config $name
22 | export PATH="$PATH:/usr/local/bin"
23 | run_rc_command "$@"
24 |
--------------------------------------------------------------------------------
/roles/flood/templates/nginx-vhost.conf:
--------------------------------------------------------------------------------
1 | upstream flood {
2 | server localhost:3000;
3 | }
4 | upstream rtorrent {
5 | server unix:/usr/local/libdata/rtorrent/rpc.socket;
6 | }
7 | server {
8 | listen 80;
9 | location /RPC2 {
10 | include scgi_params;
11 | scgi_param SCRIPT_NAME /RPC2;
12 | scgi_pass rtorrent;
13 | }
14 | location /flood/ {
15 | proxy_pass http://flood/;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/roles/jails_setup/files/sudoers_ansible:
--------------------------------------------------------------------------------
1 | Defaults:ansible !requiretty
2 | ansible ALL=(ALL) NOPASSWD: ALL
3 |
--------------------------------------------------------------------------------
/roles/jails_setup/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - include_tasks: setup.yaml
4 | loop_control:
5 | label: "{{ jail_name }}"
6 | loop_var: jail_name
7 | loop: "{{ groups['jails'] }}"
8 |
--------------------------------------------------------------------------------
/roles/jails_setup/tasks/setup.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: initialize pkg
4 | command: iocage exec {{ jail_name }} env ASSUME_ALWAYS_YES=true pkg update
5 |
6 | - name: enable sshd
7 | lineinfile:
8 | dest: "{{ jails_path }}/{{ jail_name }}/root/etc/defaults/rc.conf"
9 | line: sshd_enable="YES"
10 | regexp: ^sshd_enable
11 | register: sshd_conf_result
12 | tags: [config]
13 | become: yes
14 |
15 | - name: start sshd
16 | command: iocage exec {{ jail_name }} service sshd start
17 | become: yes
18 | when: sshd_conf_result is changed
19 |
20 | - name: create the ansible user
21 | command: iocage exec {{ jail_name }} pw useradd ansible
22 | args:
23 | creates: "{{ jails_path }}/{{ jail_name }}/root/home/ansible"
24 | become: yes
25 |
26 | - name: create ssh dir for ansible user
27 | file:
28 | path: "{{ jails_path }}/{{ jail_name }}/root/home/ansible/.ssh"
29 | state: directory
30 | mode: 0755
31 | become: yes
32 |
33 | - name: chown home dir to ansible user
34 | command: iocage exec {{ jail_name }} chown -R ansible:ansible "/home/ansible"
35 | become: yes
36 |
37 | # The authorized_key module expects the user to exist, which it does,
38 | # but only in the jail. So we use lineinfile as a low-lelvel solution instead.
39 | - name: setup authorized_keys for ansible user
40 | lineinfile:
41 | dest: "{{ jails_path }}/{{ jail_name }}/root/home/ansible/.ssh/authorized_keys"
42 | line: "{{ key }}"
43 | create: yes
44 | loop: "{{ jails_auth_keys }}"
45 | loop_control:
46 | loop_var: key
47 | label: "{{ key.split()[-1] }}"
48 |
49 | - name: chown authorized_keys to ansible user
50 | command: iocage exec {{ jail_name }} chown ansible:ansible "/home/ansible/.ssh/authorized_keys"
51 | become: yes
52 |
53 | - name: install sudo
54 | command: iocage exec {{ jail_name }} pkg install -y sudo
55 | become: yes
56 |
57 | - name: allow ansible to do passwordless sudo
58 | copy:
59 | src: sudoers_ansible
60 | dest: "{{ jails_path }}/{{ jail_name }}/root/usr/local/etc/sudoers.d/50_ansible"
61 | mode: 0440
62 | owner: root
63 | group: wheel
64 | become: yes
65 |
66 | - name: install python3
67 | command: iocage exec {{ jail_name }} pkg install -y python3
68 | become: yes
69 |
--------------------------------------------------------------------------------
/roles/mdns/handlers/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: start avahi
4 | service:
5 | name: avahi-daemon
6 | state: started
7 | pattern: avahi-daemon
8 |
9 | - name: restart avahi
10 | service:
11 | name: avahi-daemon
12 | state: restarted
13 | pattern: avahi-daemon
14 |
15 | - name: start dbus
16 | service:
17 | name: dbus
18 | state: started
19 |
20 | - name: restart dbus
21 | service:
22 | name: dbus
23 | state: restarted
24 |
--------------------------------------------------------------------------------
/roles/mdns/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: install mdns-daemon
4 | pkgng:
5 | name: dns/mdnsd
6 | state: present
7 |
8 | - name: install nss_mdns
9 | pkgng:
10 | name: dns/nss_mdns
11 | state: present
12 |
13 | - name: enable mdns resolution
14 | lineinfile:
15 | dest: /etc/nsswitch.conf
16 | regexp: "^hosts:"
17 | line: "hosts: files dns mdns"
18 | tags: [config]
19 |
20 | - name: enable dbus
21 | service:
22 | name: dbus
23 | enabled: yes
24 | notify: start dbus
25 |
26 | - name: flush handlers to ensure dbus is started before avahi-daemon
27 | meta: flush_handlers
28 |
29 | - name: enable avahi-daemon
30 | service:
31 | name: avahi-daemon
32 | enabled: yes
33 | pattern: avahi-daemon
34 | notify: start avahi
35 |
--------------------------------------------------------------------------------
/roles/media_group/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: create the media group
4 | group:
5 | name: media
6 | gid: 8675309
7 | state: present
8 |
--------------------------------------------------------------------------------
/roles/nginx/defaults/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | nginx_ssl: no
4 |
--------------------------------------------------------------------------------
/roles/nginx/handlers/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: start nginx
4 | service:
5 | name: nginx
6 | state: started
7 |
8 | - name: restart nginx
9 | service:
10 | name: nginx
11 | state: restarted
12 |
13 | - name: reload nginx
14 | service:
15 | name: nginx
16 | state: reloaded
17 |
--------------------------------------------------------------------------------
/roles/nginx/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: install nginx
4 | pkgng:
5 | name: nginx
6 | state: present
7 | become: yes
8 |
9 | - name: clear out nginx default www files
10 | file:
11 | path: /usr/local/www/{{ item }}
12 | state: absent
13 | loop:
14 | - nginx
15 | - nginx-dist
16 | become: yes
17 |
18 | - name: create nginx config folders
19 | file:
20 | path: /usr/local/etc/nginx/{{ item }}
21 | state: directory
22 | owner: root
23 | group: wheel
24 | mode: 0755
25 | loop:
26 | - conf.d
27 | - sites-available
28 | - sites-enabled
29 | - mods-available
30 | - mods-enabled
31 | become: yes
32 |
33 | - name: configure nginx
34 | template:
35 | src: nginx.conf
36 | dest: /usr/local/etc/nginx/nginx.conf
37 | owner: root
38 | group: wheel
39 | mode: 0644
40 | notify: reload nginx
41 | tags: [config]
42 | become: yes
43 |
44 | - name: configure nginx ssl session cache
45 | template:
46 | src: ssl_session_cache.conf
47 | dest: /usr/local/etc/nginx/conf.d/ssl_session_cache.conf
48 | owner: root
49 | group: wheel
50 | mode: 0644
51 | notify: reload nginx
52 | when: nginx_ssl
53 | tags: [config]
54 | become: yes
55 |
56 | - name: generate diffie-hellman group
57 | command: openssl dhparam -out /usr/local/etc/nginx/dhparams.pem 2048
58 | args:
59 | creates: /usr/local/etc/nginx/dhparams.pem
60 | notify: reload nginx
61 | when: nginx_ssl
62 | become: yes
63 |
64 | - name: enable nginx
65 | service:
66 | name: nginx
67 | enabled: yes
68 | notify: start nginx
69 | become: yes
70 |
--------------------------------------------------------------------------------
/roles/nginx/templates/nginx.conf:
--------------------------------------------------------------------------------
1 | include mods-enabled/*.load;
2 |
3 | user www;
4 | worker_processes 1;
5 | pid /var/run/nginx.pid;
6 |
7 | events {
8 | worker_connections 1024;
9 | multi_accept on;
10 | }
11 |
12 | http {
13 | sendfile on;
14 | tcp_nopush on;
15 | tcp_nodelay on;
16 | keepalive_timeout 65;
17 | types_hash_max_size 2048;
18 | server_tokens off;
19 |
20 | include mime.types;
21 | default_type application/octet-stream;
22 |
23 | access_log /var/log/nginx-access.log;
24 | error_log /var/log/nginx-error.log;
25 |
26 | include conf.d/*.conf;
27 | include sites-enabled/*;
28 | }
29 |
--------------------------------------------------------------------------------
/roles/nginx/templates/ssl_session_cache.conf:
--------------------------------------------------------------------------------
1 | # Enable SSL session caching for improved performance
2 | # http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_cache
3 | ssl_session_cache shared:ssl_session_cache:10m;
4 |
--------------------------------------------------------------------------------
/roles/php/handlers/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: start php-fpm
4 | service:
5 | name: php-fpm
6 | state: started
7 |
8 | - name: restart php-fpm
9 | service:
10 | name: php-fpm
11 | state: restarted
12 |
--------------------------------------------------------------------------------
/roles/php/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: install php
4 | pkgng:
5 | name: php56
6 | state: present
7 |
8 | - name: install php extensions
9 | pkgng:
10 | name: php56-extensions
11 | state: present
12 | notify: restart php-fpm
13 |
14 | - name: configure php
15 | template:
16 | src: php.ini
17 | dest: /usr/local/etc/php.ini
18 | owner: root
19 | group: wheel
20 | mode: 0644
21 | notify: restart php-fpm
22 | tags: [config]
23 |
24 | - name: enable php-fpm
25 | service:
26 | name: php-fpm
27 | enabled: yes
28 | notify: start php-fpm
29 |
--------------------------------------------------------------------------------
/roles/plex/handlers/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: start plex
4 | service:
5 | name: plexmediaserver
6 | state: started
7 |
8 | - name: restart plex
9 | service:
10 | name: plexmediaserver
11 | state: restarted
12 |
--------------------------------------------------------------------------------
/roles/plex/tasks/hello_hue.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: download hello hue
4 | get_url:
5 | url: https://github.com/ledge74/HelloHue.bundle/archive/37ea90faf2fdf8d3badddfb5466173329e8e6122.tar.gz
6 | dest: /usr/local/libdata/ansible/downloads/hello-hue-37ea90fa.tar.gz
7 | sha256sum: 00ec7aa1d5da3657419a57b36282273081fed044319d2ac16c2d9ce8b21222b3
8 | register: hello_hue_downloaded
9 |
10 | - name: create hello hue bundle dir
11 | file:
12 | path: "/usr/local/plexdata/Plex Media Server/Plug-ins/HelloHue.bundle"
13 | state: directory
14 |
15 | - name: install hello hue
16 | command: tar -xvzf /usr/local/libdata/ansible/downloads/hello-hue-37ea90fa.tar.gz
17 | -C "/usr/local/plexdata/Plex Media Server/Plug-ins/HelloHue.bundle"
18 | --strip-components 1
19 | HelloHue.bundle-37ea90faf2fdf8d3badddfb5466173329e8e6122
20 | # args:
21 | # creates: "/usr/local/plexdata/Plex Media Server/Plug-ins/HelloHue.bundle/README.md"
22 | when: hello_hue_downloaded|changed
23 | notify: restart plex
24 |
25 | - name: change owner of the hello hue plugin code to plex
26 | file:
27 | path: '/usr/local/plexdata/Plex Media Server/Plug-ins/HelloHue.bundle'
28 | state: directory
29 | recurse: yes
30 | owner: plex
31 | group: plex
32 | mode: 'u=rwX,go=rX'
33 |
--------------------------------------------------------------------------------
/roles/plex/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: install plex
4 | pkgng:
5 | name: plexmediaserver
6 | state: present
7 |
8 | - name: flush handlers to start plex (plexdata dir needed in other tasks)
9 | meta: flush_handlers
10 |
11 | - name: install trakt tv plugin
12 | include: trakt_tv.yaml
13 |
14 | - name: install hello hue plugin
15 | include: hello_hue.yaml
16 |
17 | - name: install twitch mod plugin
18 | include: twitch_mod.yaml
19 |
20 | - name: enable plex
21 | service:
22 | name: plexmediaserver
23 | enabled: yes
24 | notify: start plex
25 |
--------------------------------------------------------------------------------
/roles/plex/tasks/trakt_tv.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: download trakt tv
4 | get_url:
5 | url: https://github.com/trakt/Plex-Trakt-Scrobbler/archive/f9dc5ec3cf7fab07e6a5128f082d82d96dd170ad.tar.gz
6 | dest: /usr/local/libdata/ansible/downloads/trakt-tv-a6ab5f41.tar.gz
7 | sha256sum: bb3a37db7ac5c5f21306ce36e7491908a1e8ce48b02fb65f64ea14d54ce09f66
8 | register: trakt_tv_downloaded
9 |
10 | - name: create trakt tv bundle dir
11 | file:
12 | path: "/usr/local/plexdata/Plex Media Server/Plug-ins/Trakttv.bundle"
13 | state: directory
14 |
15 | - name: install trakt tv
16 | command: tar -xvzf /usr/local/libdata/ansible/downloads/trakt-tv-a6ab5f41.tar.gz
17 | -C "/usr/local/plexdata/Plex Media Server/Plug-ins/Trakttv.bundle"
18 | --strip-components 2
19 | Plex-Trakt-Scrobbler-f9dc5ec3cf7fab07e6a5128f082d82d96dd170ad/Trakttv.bundle
20 | # args:
21 | # creates: "/usr/local/plexdata/Plex Media Server/Plug-ins/Trakttv.bundle/CREDITS.md"
22 | when: trakt_tv_downloaded|changed
23 | notify: restart plex
24 |
25 | - name: change owner of the trakt tv plugin code to plex
26 | file:
27 | path: '/usr/local/plexdata/Plex Media Server/Plug-ins/Trakttv.bundle'
28 | state: directory
29 | recurse: yes
30 | owner: plex
31 | group: plex
32 | mode: 'u=rwX,go=rX'
33 |
--------------------------------------------------------------------------------
/roles/plex/tasks/twitch_mod.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: download twitch mod
4 | get_url:
5 | url: https://github.com/coryo/TwitchMod.bundle/archive/6aecc72bfde03c94225901daaa5834a4b867a1ad.tar.gz
6 | dest: /usr/local/libdata/ansible/downloads/twitch-mod-6aecc72b.tar.gz
7 | sha256sum: f05762b43c4c557af44c7dfd7d6f91cd82d8c5efb1f87f3f40cd664f7b922213
8 | register: twitch_mod_downloaded
9 |
10 | - name: create twitch mod bundle dir
11 | file:
12 | path: "/usr/local/plexdata/Plex Media Server/Plug-ins/TwitchMod.bundle"
13 | state: directory
14 |
15 | - name: install twitch mod
16 | command: tar -xvzf /usr/local/libdata/ansible/downloads/twitch-mod-6aecc72b.tar.gz
17 | -C "/usr/local/plexdata/Plex Media Server/Plug-ins/TwitchMod.bundle"
18 | --strip-components 1
19 | TwitchMod.bundle-6aecc72bfde03c94225901daaa5834a4b867a1ad
20 | # args:
21 | # creates: "/usr/local/plexdata/Plex Media Server/Plug-ins/TwitchMod.bundle/README.md"
22 | when: twitch_mod_downloaded|changed
23 | notify: restart plex
24 |
25 | - name: change owner of the twitch mod plugin code to plex
26 | file:
27 | path: '/usr/local/plexdata/Plex Media Server/Plug-ins/TwitchMod.bundle'
28 | state: directory
29 | recurse: yes
30 | owner: plex
31 | group: plex
32 | mode: 'u=rwX,go=rX'
33 |
--------------------------------------------------------------------------------
/roles/pre_setup/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: create ansible dirs
4 | file:
5 | path: /usr/local/libdata/{{ item }}
6 | state: directory
7 | mode: 0755
8 | owner: root
9 | group: wheel
10 | loop:
11 | - ansible
12 | - ansible/downloads
13 | - ansible/archives
14 | become: yes
15 |
--------------------------------------------------------------------------------
/roles/radarr/handlers/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: start radarr
4 | service:
5 | name: radarr
6 | state: started
7 |
8 | - name: restart radarr
9 | service:
10 | name: radarr
11 | state: restarted
12 |
--------------------------------------------------------------------------------
/roles/radarr/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: install radarr
4 | pkgng:
5 | name: radarr
6 | state: present
7 |
8 | - name: add the radarr user to the media group
9 | user:
10 | name: radarr
11 | groups: media
12 | append: yes
13 | notify: restart radarr
14 |
15 | - name: allow radarr to auto-update
16 | file:
17 | path: /usr/local/share/radarr
18 | state: directory
19 | recurse: yes
20 | owner: radarr
21 | group: wheel
22 | mode: 'u=rwX,go=rX'
23 |
24 | - name: enable radarr
25 | service:
26 | name: radarr
27 | enabled: yes
28 | notify: start radarr
29 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/defaults/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | reverse_proxy_domain: null
4 | reverse_proxy_alt_domains: []
5 | reverse_proxy_subdirs: []
6 | reverse_proxy_links: []
7 | reverse_proxy_google_oauth:
8 | client_id: null
9 | client_secret: null
10 | token_secret: null
11 | whitelist: null
12 | resolvers: null
13 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/files/50x.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Error
5 |
12 |
13 |
14 | An error occurred.
15 | Sorry, the page you are looking for is currently unavailable.
16 | Please try again later.
17 | If you are the system administrator of this resource then you should check
18 | the error log for details.
19 | Faithfully yours, nginx.
20 |
21 |
22 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/files/access.lua:
--------------------------------------------------------------------------------
1 | -- From: https://github.com/cloudflare/nginx-google-oauth (modified to support ngo_enabled)
2 | -- Copyright 2015-2016 CloudFlare
3 | -- Copyright 2014-2015 Aaron Westendorf
4 |
5 | local json = require("cjson")
6 | local http = require("resty.http")
7 |
8 | local uri = ngx.var.uri
9 | local uri_args = ngx.req.get_uri_args()
10 | local scheme = ngx.var.scheme
11 |
12 | local enabled = ngx.var.ngo_enabled ~= "false" or false
13 | local client_id = ngx.var.ngo_client_id
14 | local client_secret = ngx.var.ngo_client_secret
15 | local token_secret = ngx.var.ngo_token_secret
16 | local domain = ngx.var.ngo_domain
17 | local cb_scheme = ngx.var.ngo_callback_scheme or scheme
18 | local cb_server_name = ngx.var.ngo_callback_host
19 | local cb_uri = ngx.var.ngo_callback_uri or "/_oauth"
20 | local cb_url = cb_scheme .. "://" .. cb_server_name .. cb_uri
21 | local redirect_url = cb_scheme .. "://" .. cb_server_name .. ngx.var.request_uri
22 | local signout_uri = ngx.var.ngo_signout_uri or "/_signout"
23 | local extra_validity = tonumber(ngx.var.ngo_extra_validity or "0")
24 | local whitelist = ngx.var.ngo_whitelist or ""
25 | local blacklist = ngx.var.ngo_blacklist or ""
26 | local secure_cookies = ngx.var.ngo_secure_cookies == "true" or false
27 | local set_user = ngx.var.ngo_user or false
28 | local email_as_user = ngx.var.ngo_email_as_user == "true" or false
29 |
30 | if whitelist:len() == 0 then
31 | whitelist = nil
32 | end
33 |
34 | if blacklist:len() == 0 then
35 | blacklist = nil
36 | end
37 |
38 | local function handle_token_uris(email, token, expires)
39 | if uri == "/_token.json" then
40 | ngx.header["Content-type"] = "application/json"
41 | ngx.say(json.encode({
42 | email = email,
43 | token = token,
44 | expires = expires,
45 | }))
46 | ngx.exit(ngx.OK)
47 | end
48 |
49 | if uri == "/_token.txt" then
50 | ngx.header["Content-type"] = "text/plain"
51 | ngx.say("email: " .. email .. "\n" .. "token: " .. token .. "\n" .. "expires: " .. expires .. "\n")
52 | ngx.exit(ngx.OK)
53 | end
54 |
55 | if uri == "/_token.curl" then
56 | ngx.header["Content-type"] = "text/plain"
57 | ngx.say("-H \"OauthEmail: " .. email .. "\" -H \"OauthAccessToken: " .. token .. "\" -H \"OauthExpires: " .. expires .. "\"\n")
58 | ngx.exit(ngx.OK)
59 | end
60 | end
61 |
62 |
63 | local function on_auth(email, token, expires)
64 | local oauth_domain = email:match("[^@]+@(.+)")
65 |
66 | if not (whitelist or blacklist) then
67 | if domain:len() ~= 0 then
68 | if oauth_domain ~= domain then
69 | ngx.log(ngx.ERR, email .. " is not on " .. domain)
70 | return ngx.exit(ngx.HTTP_FORBIDDEN)
71 | end
72 | end
73 | end
74 |
75 | if whitelist then
76 | if not string.find(" " .. whitelist .. " ", " " .. email .. " ") then
77 | ngx.log(ngx.ERR, email .. " is not in whitelist")
78 | return ngx.exit(ngx.HTTP_FORBIDDEN)
79 | end
80 | end
81 |
82 | if blacklist then
83 | if string.find(" " .. blacklist .. " ", " " .. email .. " ") then
84 | ngx.log(ngx.ERR, email .. " is in blacklist")
85 | return ngx.exit(ngx.HTTP_FORBIDDEN)
86 | end
87 | end
88 |
89 | if set_user then
90 | if email_as_user then
91 | ngx.var.ngo_user = email
92 | else
93 | ngx.var.ngo_user = email:match("([^@]+)@.+")
94 | end
95 | end
96 |
97 | handle_token_uris(email, token, expires)
98 | end
99 |
100 | local function request_access_token(code)
101 | local request = http.new()
102 |
103 | request:set_timeout(7000)
104 |
105 | local res, err = request:request_uri("https://accounts.google.com/o/oauth2/token", {
106 | method = "POST",
107 | body = ngx.encode_args({
108 | code = code,
109 | client_id = client_id,
110 | client_secret = client_secret,
111 | redirect_uri = cb_url,
112 | grant_type = "authorization_code",
113 | }),
114 | headers = {
115 | ["Content-type"] = "application/x-www-form-urlencoded"
116 | },
117 | ssl_verify = true,
118 | })
119 | if not res then
120 | return nil, (err or "auth token request failed: " .. (err or "unknown reason"))
121 | end
122 |
123 | if res.status ~= 200 then
124 | return nil, "received " .. res.status .. " from https://accounts.google.com/o/oauth2/token: " .. res.body
125 | end
126 |
127 | return json.decode(res.body)
128 | end
129 |
130 | local function request_profile(token)
131 | local request = http.new()
132 |
133 | request:set_timeout(7000)
134 |
135 | local res, err = request:request_uri("https://www.googleapis.com/oauth2/v2/userinfo", {
136 | headers = {
137 | ["Authorization"] = "Bearer " .. token,
138 | },
139 | ssl_verify = true,
140 | })
141 | if not res then
142 | return nil, "auth info request failed: " .. (err or "unknown reason")
143 | end
144 |
145 | if res.status ~= 200 then
146 | return nil, "received " .. res.status .. " from https://www.googleapis.com/oauth2/v2/userinfo"
147 | end
148 |
149 | return json.decode(res.body)
150 | end
151 |
152 | local function is_authorized()
153 | local headers = ngx.req.get_headers()
154 |
155 | local expires = tonumber(ngx.var.cookie_OauthExpires) or 0
156 | local email = ngx.unescape_uri(ngx.var.cookie_OauthEmail or "")
157 | local token = ngx.unescape_uri(ngx.var.cookie_OauthAccessToken or "")
158 |
159 | if expires == 0 and headers["oauthexpires"] then
160 | expires = tonumber(headers["oauthexpires"])
161 | end
162 |
163 | if email:len() == 0 and headers["oauthemail"] then
164 | email = headers["oauthemail"]
165 | end
166 |
167 | if token:len() == 0 and headers["oauthaccesstoken"] then
168 | token = headers["oauthaccesstoken"]
169 | end
170 |
171 | local expected_token = ngx.encode_base64(ngx.hmac_sha1(token_secret, cb_server_name .. email .. expires))
172 |
173 | if token == expected_token and expires and expires > ngx.time() - extra_validity then
174 | on_auth(email, expected_token, expires)
175 | return true
176 | else
177 | return false
178 | end
179 | end
180 |
181 | local function redirect_to_auth()
182 | return ngx.redirect("https://accounts.google.com/o/oauth2/auth?" .. ngx.encode_args({
183 | client_id = client_id,
184 | scope = "email",
185 | response_type = "code",
186 | redirect_uri = cb_url,
187 | state = redirect_url,
188 | login_hint = domain,
189 | }))
190 | end
191 |
192 | local function authorize()
193 | if uri ~= cb_uri then
194 | return redirect_to_auth()
195 | end
196 |
197 | if uri_args["error"] then
198 | ngx.log(ngx.ERR, "received " .. uri_args["error"] .. " from https://accounts.google.com/o/oauth2/auth")
199 | return ngx.exit(ngx.HTTP_FORBIDDEN)
200 | end
201 |
202 | local token, token_err = request_access_token(uri_args["code"])
203 | if not token then
204 | ngx.log(ngx.ERR, "got error during access token request: " .. token_err)
205 | return ngx.exit(ngx.HTTP_FORBIDDEN)
206 | end
207 |
208 | local profile, profile_err = request_profile(token["access_token"])
209 | if not profile then
210 | ngx.log(ngx.ERR, "got error during profile request: " .. profile_err)
211 | return ngx.exit(ngx.HTTP_FORBIDDEN)
212 | end
213 |
214 | local expires = ngx.time() + token["expires_in"]
215 | local cookie_tail = ";version=1;path=/;Max-Age=" .. expires
216 | if secure_cookies then
217 | cookie_tail = cookie_tail .. ";secure"
218 | end
219 |
220 | local email = profile["email"]
221 | local user_token = ngx.encode_base64(ngx.hmac_sha1(token_secret, cb_server_name .. email .. expires))
222 |
223 | on_auth(email, user_token, expires)
224 |
225 | ngx.header["Set-Cookie"] = {
226 | "OauthEmail=" .. ngx.escape_uri(email) .. cookie_tail,
227 | "OauthAccessToken=" .. ngx.escape_uri(user_token) .. cookie_tail,
228 | "OauthExpires=" .. expires .. cookie_tail,
229 | }
230 |
231 | return ngx.redirect(uri_args["state"])
232 | end
233 |
234 | local function handle_signout()
235 | if uri == signout_uri then
236 | ngx.header["Set-Cookie"] = "OauthAccessToken==deleted; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"
237 | return ngx.redirect("/")
238 | end
239 | end
240 |
241 | handle_signout()
242 |
243 | if enabled and not is_authorized() then
244 | authorize()
245 | end
246 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/handlers/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: request letsencrypt certificate
4 | command: >
5 | /usr/local/bin/acme-client -N -n -e
6 | -C /usr/local/www/public/.well-known/acme-challenge
7 | {{ reverse_proxy_domain }}
8 | {{ reverse_proxy_alt_domains|map(attribute='domain')|join(' ') }}
9 | notify: reload nginx
10 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/meta/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | dependencies:
4 | - role: nginx
5 | nginx_ssl: yes
6 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/tasks/alt-domains.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: copy trusted certificates
4 | copy:
5 | src: "{{ item.trust_ssl }}"
6 | dest: /usr/local/etc/ssl/nginx_trusted/{{ item.trust_ssl|basename }}
7 | when: item.trust_ssl is defined
8 | notify: reload nginx
9 | loop: "{{ reverse_proxy_alt_domains }}"
10 |
11 | - name: create alternative domain vhosts
12 | template:
13 | src: alt-domains-vhost.conf
14 | dest: /usr/local/etc/nginx/sites-available/{{ item.name }}
15 | owner: root
16 | group: wheel
17 | mode: 0644
18 | notify: reload nginx
19 | loop: "{{ reverse_proxy_alt_domains }}"
20 | tags: [config]
21 |
22 | - name: enable alternative domain vhosts
23 | file:
24 | src: ../sites-available/{{ item.name }}
25 | dest: /usr/local/etc/nginx/sites-enabled/{{ item.name }}
26 | state: link
27 | notify: reload nginx
28 | loop: "{{ reverse_proxy_alt_domains }}"
29 |
30 | - name: configure alternative domain redirect locations on subdirs domain
31 | template:
32 | src: alt-domains-location.conf
33 | dest: /usr/local/etc/nginx/reverse-proxy/locations/{{ item.name }}
34 | owner: root
35 | group: wheel
36 | mode: 0644
37 | notify: reload nginx
38 | loop: "{{ reverse_proxy_alt_domains }}"
39 | tags: [config]
40 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/tasks/google-oauth.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # From: https://github.com/cloudflare/nginx-google-oauth
4 |
5 | - name: check if NDK module exists
6 | stat:
7 | path: /usr/local/libexec/nginx/ndk_http_module.so
8 | register: ndk_module
9 |
10 | - name: fail when NDK module doesn't exist
11 | fail:
12 | msg: >
13 | The google oauth module requires some modules to be installed
14 | that are not part of the default nginx package distribution.
15 | You need to compile nginx yourself using ports, please refer to
16 | the reverse-proxy host_vars file for instructions (they are fairly simple)
17 | when:
18 | - not ndk_module.stat.exists
19 |
20 | - name: create module loading configurations
21 | copy:
22 | content: load_module "{{ item.path }}";
23 | dest: /usr/local/etc/nginx/mods-available/{{ item.name }}.load
24 | owner: root
25 | group: wheel
26 | mode: 0644
27 | notify: reload nginx
28 | tags: [config]
29 | loop:
30 | - name: ndk-module
31 | path: /usr/local/libexec/nginx/ndk_http_module.so
32 | - name: set-misc-module
33 | path: /usr/local/libexec/nginx/ngx_http_set_misc_module.so
34 | - name: lua-module
35 | path: /usr/local/libexec/nginx/ngx_http_lua_module.so
36 |
37 | - name: enable required nginx modules
38 | file:
39 | src: /usr/local/etc/nginx/mods-available/{{ item.name }}.load
40 | dest: /usr/local/etc/nginx/mods-enabled/{{ item.order }}-{{ item.name }}.load
41 | state: link
42 | notify: reload nginx
43 | loop:
44 | - name: ndk-module
45 | order: 10
46 | - name: set-misc-module
47 | order: 40
48 | - name: lua-module
49 | order: 60
50 |
51 | - name: install cjson lua lib
52 | pkgng:
53 | name: lua51-cjson-2.1.0
54 | state: present
55 |
56 | - name: download resty.http
57 | get_url:
58 | url: https://github.com/pintsized/lua-resty-http/archive/v0.10.tar.gz
59 | dest: /usr/local/libdata/ansible/downloads/lua-resty.http-0.10.tar.gz
60 | sha256sum: 6917ab4fd0dcd99df076e238f591aeaa9e2d7e0bca4904ebeb3c1bd418e7c1b9
61 |
62 | - name: extract resty.http
63 | command: tar -xvzf /usr/local/libdata/ansible/downloads/lua-resty.http-0.10.tar.gz
64 | -C /usr/local/libdata/ansible/downloads/
65 | args:
66 | creates: /usr/local/libdata/ansible/downloads/lua-resty-http-0.10
67 |
68 | # *.lua files are expected to be in /usr/local/share while *.so files are expected to be in /usr/local/lib
69 | # The resty.http Makefile is a bit weird and installs its *.lua files to ../lib,
70 | # so we fix that with LUA_LIB_DIR=...
71 | - name: install resty.http
72 | command: make install LUA_INCLUDE_DIR=/usr/local/include/luajit-2.0/ LUA_LIB_DIR=/usr/local/share/luajit-2.0.5/
73 | args:
74 | chdir: /usr/local/libdata/ansible/downloads/lua-resty-http-0.10
75 | creates: /usr/local/share/luajit-2.0.5/resty/http.lua
76 |
77 | - name: copy google-oauth lua module to nginx
78 | copy:
79 | src: access.lua
80 | dest: /usr/local/etc/nginx/reverse-proxy/google-oauth.lua
81 | owner: root
82 | group: wheel
83 | mode: 0644
84 |
85 | - name: create google-oauth module configuration
86 | template:
87 | src: google-oauth.conf
88 | dest: /usr/local/etc/nginx/reverse-proxy/google-oauth.conf
89 | owner: root
90 | group: wheel
91 | mode: 0644
92 | notify: reload nginx
93 | tags: [config]
94 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/tasks/letsencrypt.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: install acme-client
4 | pkgng:
5 | name: acme-client
6 | state: present
7 |
8 | - name: remove the default acme challenge dir
9 | file:
10 | path: /usr/local/www/acme
11 | state: absent
12 |
13 | - name: create .well-known dir
14 | file:
15 | path: public
16 | dest: /usr/local/www/public/{{ item }}
17 | state: directory
18 | owner: root
19 | group: wheel
20 | mode: 0755
21 | loop:
22 | - .well-known
23 | - .well-known/acme-challenge
24 |
25 | - name: configure acme-client to run weekly
26 | template:
27 | src: letsencrypt.conf
28 | dest: /etc/periodic.conf
29 | owner: root
30 | group: wheel
31 | mode: 0755
32 | # config file changes might not impact the certificate
33 | # but there's no harm in running a request.
34 | # acme-client will know what's up.
35 | notify: request letsencrypt certificate
36 | tags: [config]
37 |
38 | - name: request letsencrypt certificate for the first time
39 | command: >
40 | /usr/local/bin/acme-client -N -n -e
41 | -C /usr/local/www/public/.well-known/acme-challenge
42 | {{ reverse_proxy_domain }}
43 | {{ reverse_proxy_alt_domains|map(attribute='domain')|join(' ') }}
44 | args:
45 | creates: /usr/local/etc/ssl/acme/fullchain.pem
46 | notify: reload nginx
47 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: check if reverse_proxy_domain is defined
4 | fail:
5 | msg: "reverse_proxy_domain is undefined. Set it in host_vars/reverse-proxy@freenas.local.yaml"
6 | when: reverse_proxy_domain is not defined
7 |
8 | - name: create reverse-proxy config folder
9 | file:
10 | path: /usr/local/etc/nginx/reverse-proxy
11 | state: directory
12 | owner: root
13 | group: wheel
14 | mode: 0755
15 |
16 | - name: configure public site
17 | include: public.yaml
18 |
19 | - name: flush handlers to reload nginx config
20 | meta: flush_handlers
21 |
22 | - name: configure letsencrypt
23 | include: letsencrypt.yaml
24 |
25 | - name: install nginx-google-oauth
26 | include: google-oauth.yaml
27 |
28 | - name: configure nginx proxy params
29 | template:
30 | src: proxy_params
31 | dest: /usr/local/etc/nginx/proxy_params
32 | owner: root
33 | group: wheel
34 | mode: 0644
35 | notify: reload nginx
36 | tags: [config]
37 |
38 | - name: create nginx ssl cert trust dir
39 | file:
40 | path: /usr/local/etc/ssl/nginx_trusted
41 | state: directory
42 | owner: root
43 | group: wheel
44 | mode: 0755
45 |
46 | - name: configure secure site
47 | include: secure.yaml
48 |
49 | - name: configure subdirs
50 | include: subdirs.yaml
51 |
52 | - name: configure altdomains
53 | include: alt-domains.yaml
54 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/tasks/public.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: create public dir
4 | file:
5 | path: /usr/local/www/public
6 | state: directory
7 | owner: root
8 | group: wheel
9 | mode: 0755
10 |
11 | - name: create 50x.html
12 | copy:
13 | src: 50x.html
14 | dest: /usr/local/www/public/50x.html
15 | owner: root
16 | group: wheel
17 | mode: 0644
18 |
19 | - name: create public vhost
20 | template:
21 | src: public-vhost.conf
22 | dest: /usr/local/etc/nginx/sites-available/public
23 | owner: root
24 | group: wheel
25 | mode: 0644
26 | notify: reload nginx
27 | tags: [config]
28 |
29 | - name: enable public vhost
30 | file:
31 | src: ../sites-available/public
32 | dest: /usr/local/etc/nginx/sites-enabled/public
33 | state: link
34 | notify: reload nginx
35 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/tasks/secure.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: create secure dir
4 | file:
5 | path: /usr/local/www/secure
6 | state: directory
7 | owner: root
8 | group: wheel
9 | mode: 0755
10 |
11 | - name: create 50x.html
12 | copy:
13 | src: 50x.html
14 | dest: /usr/local/www/secure/50x.html
15 | owner: root
16 | group: wheel
17 | mode: 0644
18 |
19 | - name: create index.html
20 | template:
21 | src: index.html
22 | dest: /usr/local/www/secure/index.html
23 | owner: root
24 | group: wheel
25 | mode: 0644
26 |
27 | - name: create index images dir
28 | file:
29 | path: /usr/local/www/secure/img
30 | state: directory
31 | owner: root
32 | group: wheel
33 | mode: 0755
34 |
35 | - name: copy index.html background images
36 | copy:
37 | src: "{{ item.background }}"
38 | dest: /usr/local/www/secure/img/
39 | owner: root
40 | group: wheel
41 | mode: 0644
42 | loop: '{{ reverse_proxy_links }}'
43 |
44 | - name: copy index.html foreground images
45 | copy:
46 | src: "{{ item.foreground }}"
47 | dest: /usr/local/www/secure/img/
48 | owner: root
49 | group: wheel
50 | mode: 0644
51 | loop: '{{ reverse_proxy_links }}'
52 |
53 | - name: create secure vhost
54 | template:
55 | src: secure-vhost.conf
56 | dest: /usr/local/etc/nginx/sites-available/secure
57 | owner: root
58 | group: wheel
59 | mode: 0644
60 | notify: reload nginx
61 | tags: [config]
62 |
63 | - name: enable secure vhost
64 | file:
65 | src: ../sites-available/secure
66 | dest: /usr/local/etc/nginx/sites-enabled/secure
67 | state: link
68 | notify: reload nginx
69 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/tasks/subdirs.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: create reverse-proxy subdirs config structure
4 | file:
5 | path: /usr/local/etc/nginx/{{ item }}
6 | state: directory
7 | owner: root
8 | group: wheel
9 | mode: 0755
10 | loop:
11 | - reverse-proxy/locations
12 | - reverse-proxy/upstreams
13 |
14 | - name: copy trusted certificates
15 | copy:
16 | src: "{{ item.trust_ssl }}"
17 | dest: /usr/local/etc/ssl/nginx_trusted/{{ item.trust_ssl|basename }}
18 | when: item.trust_ssl is defined
19 | notify: reload nginx
20 | loop: "{{ reverse_proxy_subdirs }}"
21 |
22 | - name: configure locations
23 | template:
24 | src: "{{ item.location_template | default('subdirs-location.conf') }}"
25 | dest: /usr/local/etc/nginx/reverse-proxy/locations/{{ item.name }}
26 | owner: root
27 | group: wheel
28 | mode: 0644
29 | notify: reload nginx
30 | loop: "{{ reverse_proxy_subdirs }}"
31 | tags: [config]
32 |
33 | - name: configure upstreams
34 | template:
35 | src: subdirs-upstream.conf
36 | dest: /usr/local/etc/nginx/reverse-proxy/upstreams/{{ item.name }}
37 | owner: root
38 | group: wheel
39 | mode: 0644
40 | notify: reload nginx
41 | loop: "{{ reverse_proxy_subdirs }}"
42 | tags: [config]
43 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/templates/alt-domains-location.conf:
--------------------------------------------------------------------------------
1 | location /{{ item.name }} {
2 | return 301 https://{{ item.domain }}/;
3 | }
4 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/templates/alt-domains-vhost.conf:
--------------------------------------------------------------------------------
1 | upstream {{ item.name }} {
2 | server {{ item.address }};
3 | }
4 | server {
5 | listen 443 ssl;
6 | server_name {{ item.domain }};
7 | ssl_dhparam /usr/local/etc/nginx/dhparams.pem;
8 | ssl_certificate /usr/local/etc/ssl/acme/fullchain.pem;
9 | ssl_certificate_key /usr/local/etc/ssl/acme/private/privkey.pem;
10 |
11 | ssl_protocols TLSv1.2 TLSv1.3;
12 | ssl_prefer_server_ciphers on;
13 | ssl_ciphers "EECDH+AESGCM:EDH+AESGCM";
14 | ssl_session_timeout 10m;
15 | add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;" always;
16 | keepalive_timeout 70;
17 |
18 | error_page 500 502 503 504 /50x.html;
19 | location / {
20 | {% if item.require_authentication|default(True) -%}
21 | # Require authentication
22 | set $ngo_callback_host "{{ item.domain }}";
23 | include reverse-proxy/google-oauth.conf;
24 | {%- endif %}
25 |
26 | # Don't use the upstream port when redirecting
27 | port_in_redirect off;
28 |
29 | # Enable websockets, set some headers etc.
30 | include proxy_params;
31 |
32 | {% if item.trust_ssl is defined -%}
33 | proxy_ssl_trusted_certificate /usr/local/etc/ssl/nginx_trusted/{{ item.trust_ssl|basename }};
34 | proxy_ssl_verify off;
35 | proxy_pass https://{{ item.name }};
36 | {%- else -%}
37 | proxy_pass http://{{ item.name }};
38 | {%- endif %}
39 |
40 | {% if item.inline_config is defined -%}
41 | {{ item.inline_config|indent(4) }}
42 | {%- endif %}
43 |
44 | access_log /var/log/nginx/{{ item.name }}-access.log;
45 | error_log /var/log/nginx/{{ item.name }}-error.log;
46 | }
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/templates/google-oauth.conf:
--------------------------------------------------------------------------------
1 | # See https://github.com/cloudflare/nginx-google-oauth/blob/master/README.md for a list of possible values
2 | set $ngo_client_id "{{ reverse_proxy_google_oauth.client_id }}";
3 | set $ngo_client_secret "{{ reverse_proxy_google_oauth.client_secret }}";
4 | set $ngo_token_secret "{{ reverse_proxy_google_oauth.token_secret }}";
5 | set $ngo_secure_cookies "true";
6 | set $ngo_whitelist "{{ reverse_proxy_google_oauth.whitelist|join(" ") }}";
7 | set $ngo_extra_validity "432000";
8 | set $ngo_secure_cookies "true";
9 |
10 | # Define a resolver so that we can resolve accounts.google.com in the access script
11 | resolver {{ reverse_proxy_google_oauth.resolvers|join(" ") }} ipv6=off;
12 |
13 | # Define the CA certs location so that we can verify accounts.google.com in the access script.
14 | lua_ssl_trusted_certificate /usr/local/share/certs/ca-root-nss.crt;
15 |
16 | # Fix the default verify depth of 1, because in OpenResty world
17 | # everybody apparently signs certificates with root certs.
18 | lua_ssl_verify_depth 2;
19 |
20 | access_by_lua_file "reverse-proxy/google-oauth.lua";
21 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Reverse Proxy
5 |
8 |
77 |
78 |
79 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/templates/letsencrypt.conf:
--------------------------------------------------------------------------------
1 | weekly_acme_client_enable="YES"
2 | weekly_acme_client_domains="{{ reverse_proxy_domain }} {{ reverse_proxy_alt_domains|map(attribute='domain')|join(' ') }}"
3 | weekly_acme_client_challengedir="/usr/local/www/public/.well-known/acme-challenge"
4 | weekly_acme_client_args="-e"
5 | weekly_acme_client_deployscript="/usr/sbin/service nginx reload"
6 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/templates/proxy_params:
--------------------------------------------------------------------------------
1 | proxy_http_version 1.1;
2 | proxy_set_header Host $http_host;
3 | proxy_set_header X-Real-IP $remote_addr;
4 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
5 | proxy_set_header X-Forwarded-Proto $scheme;
6 | proxy_set_header Upgrade $http_upgrade;
7 | proxy_set_header Connection "upgrade";
8 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/templates/public-vhost.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | root /usr/local/www/public/;
4 | error_page 500 502 503 504 /50x.html;
5 | # Redirect to https unless it is for letsencrypt
6 | if ($request_uri !~ "^/.well-known(/|/.*)$") {
7 | return 301 https://{{ reverse_proxy_domain }}$request_uri;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/templates/secure-vhost.conf:
--------------------------------------------------------------------------------
1 | include reverse-proxy/upstreams/*;
2 | server {
3 | listen 443 ssl;
4 | server_name {{ reverse_proxy_domain }};
5 | ssl_dhparam /usr/local/etc/nginx/dhparams.pem;
6 | ssl_certificate /usr/local/etc/ssl/acme/fullchain.pem;
7 | ssl_certificate_key /usr/local/etc/ssl/acme/private/privkey.pem;
8 |
9 | ssl_protocols TLSv1.2 TLSv1.3;
10 | ssl_prefer_server_ciphers on;
11 | ssl_ciphers "EECDH+AESGCM:EDH+AESGCM";
12 | ssl_session_timeout 10m;
13 | add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;" always;
14 | keepalive_timeout 70;
15 |
16 | error_page 500 502 503 504 /50x.html;
17 | location / {
18 | # Require authentication
19 | set $ngo_callback_host "{{ reverse_proxy_domain }}";
20 | include reverse-proxy/google-oauth.conf;
21 |
22 | # Don't use the upstream port when redirecting
23 | port_in_redirect off;
24 |
25 | # Enable websockets, set some headers etc.
26 | include proxy_params;
27 |
28 | root /usr/local/www/secure/;
29 | include reverse-proxy/locations/*;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/templates/subdirs-location.conf:
--------------------------------------------------------------------------------
1 | location /{{ item.name }}/ {
2 | # Require authentication
3 | set $ngo_callback_host "{{ reverse_proxy_domain }}";
4 | include reverse-proxy/google-oauth.conf;
5 |
6 | {% if item.trust_ssl is defined -%}
7 | proxy_ssl_trusted_certificate /usr/local/etc/ssl/nginx_trusted/{{ item.trust_ssl|basename }};
8 | proxy_ssl_verify off;
9 | {% if item.forward_subdir_name|default(False) -%}
10 | proxy_pass https://{{ item.name }};
11 | {%- else -%}
12 | proxy_pass https://{{ item.name }}/;
13 | {%- endif -%}
14 | {%- else -%}
15 | {% if item.forward_subdir_name|default(False) -%}
16 | proxy_pass http://{{ item.name }};
17 | {%- else -%}
18 | proxy_pass http://{{ item.name }}/;
19 | {%- endif -%}
20 | {%- endif %}
21 |
22 | {% if item.inline_config is defined -%}
23 | {{ item.inline_config|indent(4) }}
24 | {%- endif %}
25 |
26 | access_log /var/log/nginx/{{ item.name }}-access.log;
27 | error_log /var/log/nginx/{{ item.name }}-error.log;
28 | }
29 | location /{{ item.name }} {
30 | # Redirect, URL was accessed without a trailing slash
31 | rewrite ^/{{ item.name }}$ /{{ item.name }}/ permanent;
32 | }
33 |
--------------------------------------------------------------------------------
/roles/reverse_proxy/templates/subdirs-upstream.conf:
--------------------------------------------------------------------------------
1 | upstream {{ item.name }} {
2 | server {{ item.address }};
3 | }
4 |
--------------------------------------------------------------------------------
/roles/rtorrent/handlers/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: start rtorrent
4 | service:
5 | name: rtorrent
6 | state: started
7 |
8 | - name: restart rtorrent
9 | service:
10 | name: rtorrent
11 | state: restarted
12 |
--------------------------------------------------------------------------------
/roles/rtorrent/meta/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | dependencies:
4 | - role: rutorrent
5 | when: rtorrent_frontend == 'rutorrent'
6 | - role: flood
7 | when: rtorrent_frontend == 'flood'
8 |
--------------------------------------------------------------------------------
/roles/rtorrent/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: install rtorrent
4 | pkgng:
5 | name: rtorrent
6 | state: present
7 |
8 | - name: install dtach for running rtorrent
9 | pkgng:
10 | name: dtach
11 | state: present
12 |
13 | - name: create rtorrent user
14 | user:
15 | name: rtorrent
16 | groups: media
17 | state: present
18 | home: /usr/local/libdata/rtorrent
19 | createhome: no
20 |
21 | - name: create rtorrent user home dir
22 | file:
23 | path: /usr/local/libdata/rtorrent
24 | state: directory
25 | owner: rtorrent
26 | group: rtorrent
27 | mode: 0755
28 |
29 | - name: create rtorrent session dir
30 | file:
31 | path: /usr/local/libdata/rtorrent/.rtorrent.session
32 | state: directory
33 | owner: rtorrent
34 | group: rtorrent
35 | mode: 0755
36 |
37 | - name: configure rtorrent
38 | template:
39 | src: rtorrent.rc
40 | dest: /usr/local/libdata/rtorrent/.rtorrent.rc
41 | owner: rtorrent
42 | group: rtorrent
43 | mode: 0644
44 | notify: restart rtorrent
45 | tags: [config]
46 |
47 | - name: copy set_home script
48 | template:
49 | src: set_home.sh
50 | dest: /usr/local/libdata/rtorrent/set_home.sh
51 | owner: rtorrent
52 | group: rtorrent
53 | mode: 0755
54 |
55 | - name: configure nzbtomedia
56 | include: nzbtomedia.yaml
57 |
58 | - name: create rtorrent init script
59 | template:
60 | src: rtorrent.sh
61 | dest: /usr/local/etc/rc.d/rtorrent
62 | owner: root
63 | group: wheel
64 | mode: 0755
65 | notify: restart rtorrent
66 |
67 | - name: enable rtorrent
68 | service:
69 | name: rtorrent
70 | enabled: yes
71 | notify: start rtorrent
72 |
--------------------------------------------------------------------------------
/roles/rtorrent/tasks/nzbtomedia.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: alias python 2.7 to python
4 | file:
5 | src: python2.7
6 | dest: /usr/local/bin/python
7 | state: link
8 |
9 | - name: install nzbtomedia dependencies
10 | pkgng:
11 | name:
12 | - py27-sqlite3
13 | - ffmpeg
14 | - unrar
15 | - unzip
16 | - p7zip
17 | state: present
18 |
19 | - name: clone nzbtomedia
20 | git:
21 | repo: https://github.com/clinton-hall/nzbToMedia.git
22 | dest: /usr/local/libdata/rtorrent/nzbtomedia
23 | version: 12.0.0
24 | update: no
25 | register: clone_nzbtomedia
26 |
27 | - name: set permissions on nzbtomedia files
28 | file:
29 | path: /usr/local/libdata/rtorrent/nzbtomedia
30 | state: directory
31 | recurse: yes
32 | owner: rtorrent
33 | group: rtorrent
34 | mode: 'u=rwX,go=rX'
35 | when: clone_nzbtomedia is changed
36 |
37 | - name: configure nzbtomedia
38 | template:
39 | src: autoProcessMedia.cfg
40 | dest: /usr/local/libdata/rtorrent/nzbtomedia/autoProcessMedia.cfg
41 | owner: rtorrent
42 | group: rtorrent
43 | mode: 0644
44 | tags: [config]
45 |
--------------------------------------------------------------------------------
/roles/rtorrent/templates/autoProcessMedia.cfg:
--------------------------------------------------------------------------------
1 | # nzbToMedia Configuration
2 | # For more information, visit https://github.com/clinton-hall/nzbToMedia/wiki
3 |
4 | [General]
5 | # Enable/Disable update notifications
6 | version_notify = 1
7 | # Enable/Disable automatic updates
8 | auto_update = 1
9 | # Set to the full path to the git executable
10 | git_path = /usr/local/bin/git
11 | # GitHUB user for repo
12 | git_user =
13 | # GitHUB branch for repo
14 | git_branch =
15 | # Enable/Disable forceful cleaning of leftover files following postprocess
16 | force_clean = 0
17 | # Enable/Disable logging debug messages to nzbtomedia.log
18 | log_debug = 0
19 | # Enable/Disable logging database messages to nzbtomedia.log
20 | log_db = 0
21 | # Enable/Disable logging environment variables to debug nzbtomedia.log (helpful to track down errors calling external tools.)
22 | log_env = 0
23 | # Enable/Disable logging git output to debug nzbtomedia.log (helpful to track down update failures.)
24 | log_git = 0
25 | # Set to the directory where your ffmpeg/ffprobe executables are located
26 | ffmpeg_path = /usr/local/bin
27 | # Enable/Disable media file checking using ffprobe.
28 | check_media = 1
29 | # Enable/Disable a safety check to ensure we don't process all downloads in the default_downloadDirectories by mistake.
30 | safe_mode = 1
31 | # Turn this on to disable additional extraction attempts for failed downloads. Default = 0 will attempt to extract and verify if media is present.
32 | no_extract_failed = 0
33 |
34 | [Posix]
35 | ### Process priority setting for External commands (Extractor and Transcoder) on Posix (Unix/Linux/OSX) systems.
36 | # Set the Niceness value for the nice command. These range from -20 (most favorable to the process) to 19 (least favorable to the process).
37 | niceness = 0
38 | # Set the ionice scheduling class. 0 for none, 1 for real time, 2 for best-effort, 3 for idle.
39 | ionice_class = 0
40 | # Set the ionice scheduling class data. This defines the class data, if the class accepts an argument. For real time and best-effort, 0-7 is valid data.
41 | ionice_classdata = 0
42 |
43 | [Windows]
44 | ### Set specific settings for Windows systems
45 | # Set this to 1 to allow extraction (7zip) windows to be lunched visble (for debugging) otherwise 0 to have this run in background.
46 | show_extraction = 0
47 |
48 | [CouchPotato]
49 | #### autoProcessing for Movies
50 | #### movie - category that gets called for post-processing with CPS
51 | [[movie]]
52 | enabled = 0
53 | apikey =
54 | host = localhost
55 | port = 5050
56 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
57 | ssl = 0
58 | web_root =
59 | # api key for www.omdbapi.com (used as alternative to imdb)
60 | omdbapikey =
61 | # Enable/Disable linking for Torrents
62 | Torrent_NoLink = 0
63 | keep_archive = 1
64 | method = renamer
65 | delete_failed = 0
66 | wait_for = 2
67 | extract = 1
68 | # Set this to minimum required size to consider a media file valid (in MB)
69 | minSize = 0
70 | # Enable/Disable deleting ignored files (samples and invalid media files)
71 | delete_ignored = 0
72 | ##### Enable if Couchpotato is on a remote server for this category
73 | remote_path = 0
74 | ##### Set to path where download client places completed downloads locally for this category
75 | watch_dir =
76 | ##### Set the recursive directory permissions to the following (0 to disable)
77 | chmodDirectory = 0
78 |
79 | [Radarr]
80 | #### autoProcessing for Movies
81 | #### raCategory - category that gets called for post-processing with Radarr
82 | [[movie]]
83 | enabled = 0
84 | apikey =
85 | host = localhost
86 | port = 7878
87 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
88 | web_root =
89 | ssl = 0
90 | # api key for www.omdbapi.com (used as alternative to imdb)
91 | omdbapikey =
92 | delete_failed = 0
93 | # Enable/Disable linking for Torrents
94 | Torrent_NoLink = 0
95 | keep_archive = 1
96 | extract = 1
97 | nzbExtractionBy = Downloader
98 | wait_for = 6
99 | # Set this to minimum required size to consider a media file valid (in MB)
100 | minSize = 0
101 | # Enable/Disable deleting ignored files (samples and invalid media files)
102 | delete_ignored = 0
103 | ##### Enable if NzbDrone is on a remote server for this category
104 | remote_path = 0
105 | ##### Set to path where download client places completed downloads locally for this category
106 | watch_dir =
107 | ##### Set to define import behavior Move or Copy
108 | importMode = Copy
109 |
110 | [SickBeard]
111 | #### autoProcessing for TV Series
112 | #### tv - category that gets called for post-processing with SB
113 | [[tv]]
114 | enabled = 0
115 | host = localhost
116 | port = 8081
117 | apikey =
118 | username =
119 | password =
120 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
121 | web_root =
122 | ssl = 0
123 | fork = auto
124 | delete_failed = 0
125 | # Enable/Disable linking for Torrents
126 | Torrent_NoLink = 0
127 | keep_archive = 1
128 | process_method =
129 | # force processing of already processed content when running a manual scan.
130 | force = 0
131 | # tell SickRage/Medusa to delete all source files after processing.
132 | delete_on = 0
133 | # tell Medusa to ignore check for associated subtitle check when postponing release
134 | ignore_subs = 0
135 | extract = 1
136 | nzbExtractionBy = Downloader
137 | # Set this to minimum required size to consider a media file valid (in MB)
138 | minSize = 0
139 | # Enable/Disable deleting ignored files (samples and invalid media files)
140 | delete_ignored = 0
141 | ##### Enable if SickBeard is on a remote server for this category
142 | remote_path = 0
143 | ##### Set to path where download client places completed downloads locally for this category
144 | watch_dir =
145 | ##### Set the recursive directory permissions to the following (0 to disable)
146 | chmodDirectory = 0
147 |
148 | [NzbDrone]
149 | #### Formerly known as NzbDrone this is now Sonarr
150 | #### autoProcessing for TV Series
151 | #### ndCategory - category that gets called for post-processing with NzbDrone/Sonarr
152 | [[sonarr]]
153 | enabled = 1
154 | apikey = {{ sonarr_api_key }}
155 | host = sonarr.local
156 | port = 8989
157 | username =
158 | password =
159 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
160 | web_root = /sonarr
161 | ssl = 0
162 | delete_failed = 0
163 | # Enable/Disable linking for Torrents
164 | Torrent_NoLink = 0
165 | keep_archive = 1
166 | extract = 1
167 | nzbExtractionBy = Downloader
168 | wait_for = 6
169 | # Set this to minimum required size to consider a media file valid (in MB)
170 | minSize = 0
171 | # Enable/Disable deleting ignored files (samples and invalid media files)
172 | delete_ignored = 0
173 | ##### Enable if NzbDrone is on a remote server for this category
174 | remote_path = 0
175 | ##### Set to path where download client places completed downloads locally for this category
176 | watch_dir = /mnt/downloads/bittorrent/sonarr
177 | ##### Set to define import behavior Move or Copy
178 | importMode = Copy
179 | [[radarr]]
180 | enabled = 1
181 | apikey = {{ radarr_api_key }}
182 | host = radarr.local
183 | port = 8989
184 | username =
185 | password =
186 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
187 | web_root = /radarr
188 | ssl = 0
189 | delete_failed = 0
190 | # Enable/Disable linking for Torrents
191 | Torrent_NoLink = 0
192 | keep_archive = 1
193 | extract = 1
194 | nzbExtractionBy = Downloader
195 | wait_for = 6
196 | # Set this to minimum required size to consider a media file valid (in MB)
197 | minSize = 0
198 | # Enable/Disable deleting ignored files (samples and invalid media files)
199 | delete_ignored = 0
200 | ##### Enable if NzbDrone is on a remote server for this category
201 | remote_path = 0
202 | ##### Set to path where download client places completed downloads locally for this category
203 | watch_dir = /mnt/downloads/bittorrent/radarr
204 | ##### Set to define import behavior Move or Copy
205 | importMode = Copy
206 |
207 | [HeadPhones]
208 | #### autoProcessing for Music
209 | #### music - category that gets called for post-processing with HP
210 | [[music]]
211 | enabled = 0
212 | apikey =
213 | host = localhost
214 | port = 8181
215 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
216 | ssl = 0
217 | web_root =
218 | delete_failed = 0
219 | wait_for = 2
220 | # Enable/Disable linking for Torrents
221 | Torrent_NoLink = 0
222 | keep_archive = 1
223 | extract = 1
224 | # Set this to minimum required size to consider a media file valid (in MB)
225 | minSize = 0
226 | # Enable/Disable deleting ignored files (samples and invalid media files)
227 | delete_ignored = 0
228 | ##### Enable if HeadPhones is on a remote server for this category
229 | remote_path = 0
230 | ##### Set to path where download client places completed downloads locally for this category
231 | watch_dir =
232 |
233 | [Lidarr]
234 | #### autoProcessing for Music
235 | #### LiCategory - category that gets called for post-processing with Lidarr
236 | [[music]]
237 | enabled = 0
238 | apikey =
239 | host = localhost
240 | port = 8686
241 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
242 | web_root =
243 | ssl = 0
244 | delete_failed = 0
245 | # Enable/Disable linking for Torrents
246 | Torrent_NoLink = 0
247 | keep_archive = 1
248 | extract = 1
249 | nzbExtractionBy = Downloader
250 | wait_for = 6
251 | # Set this to minimum required size to consider a media file valid (in MB)
252 | minSize = 0
253 | # Enable/Disable deleting ignored files (samples and invalid media files)
254 | delete_ignored = 0
255 | ##### Enable if NzbDrone is on a remote server for this category
256 | remote_path = 0
257 | ##### Set to path where download client places completed downloads locally for this category
258 | watch_dir =
259 |
260 | [Mylar]
261 | #### autoProcessing for Comics
262 | #### comics - category that gets called for post-processing with Mylar
263 | [[comics]]
264 | enabled = 0
265 | host = localhost
266 | port= 8090
267 | apikey=
268 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
269 | web_root=
270 | ssl=0
271 | # Enable/Disable linking for Torrents
272 | Torrent_NoLink = 0
273 | keep_archive = 1
274 | extract = 1
275 | # Set this to minimum required size to consider a media file valid (in MB)
276 | minSize = 0
277 | # Enable/Disable deleting ignored files (samples and invalid media files)
278 | delete_ignored = 0
279 | ##### Enable if Mylar is on a remote server for this category
280 | remote_path = 0
281 | ##### Set to path where download client places completed downloads locally for this category
282 | watch_dir =
283 |
284 | [Gamez]
285 | #### autoProcessing for Games
286 | #### games - category that gets called for post-processing with Gamez
287 | [[games]]
288 | enabled = 0
289 | apikey =
290 | host = localhost
291 | port = 8085
292 | ######
293 | library = Set to path where you want the processed games to be moved to.
294 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
295 | ssl = 0
296 | web_root =
297 | # Enable/Disable linking for Torrents
298 | Torrent_NoLink = 0
299 | keep_archive = 1
300 | extract = 1
301 | # Set this to minimum required size to consider a media file valid (in MB)
302 | minSize = 0
303 | # Enable/Disable deleting ignored files (samples and invalid media files)
304 | delete_ignored = 0
305 | ##### Enable if Gamez is on a remote server for this category
306 | remote_path = 0
307 | ##### Set to path where download client places completed downloads locally for this category
308 | watch_dir =
309 |
310 | [Network]
311 | # Enter Mount points as LocalPath,RemotePath and separate each pair with '|'
312 | # e.g. MountPoints = /volume1/Public/,E:\|/volume2/share/,\\NAS\
313 | mount_points =
314 |
315 | [Nzb]
316 | ###### clientAgent - Supported clients: sabnzbd, nzbget
317 | clientAgent = sabnzbd
318 | ###### SabNZBD (You must edit this if you're using nzbToMedia.py with SabNZBD)
319 | sabnzbd_host = http://localhost
320 | sabnzbd_port = 8080
321 | sabnzbd_apikey =
322 | ###### Enter the default path to your default download directory (non-category downloads). this directory is protected by safe_mode.
323 | default_downloadDirectory =
324 |
325 | [Torrent]
326 | ###### clientAgent - Supported clients: utorrent, transmission, deluge, rtorrent, vuze, qbittorrent, other
327 | clientAgent = rtorrent
328 | ###### useLink - Set to hard for physical links, sym for symbolic links, move to move, move-sym to move and link back, and no to not use links (copy)
329 | useLink = no
330 | ###### outputDirectory - Default output directory (categories will be appended as sub directory to outputDirectory)
331 | outputDirectory = /mnt/downloads/bittorrent
332 | ###### Enter the default path to your default download directory (non-category downloads). this directory is protected by safe_mode.
333 | default_downloadDirectory =
334 | ###### Other categories/labels defined for your downloader. Does not include CouchPotato, SickBeard, HeadPhones, Mylar categories.
335 | categories = sonarr
336 | ###### A list of categories that you don't want to be flattened (i.e preserve the directory structure when copying/linking.
337 | noFlatten = pictures,manual
338 | ###### uTorrent Hardlink solution (You must edit this if you're using TorrentToMedia.py with uTorrent)
339 | uTorrentWEBui = http://localhost:8090/gui/
340 | uTorrentUSR = your username
341 | uTorrentPWD = your password
342 | ###### Transmission (You must edit this if you're using TorrentToMedia.py with Transmission)
343 | TransmissionHost = localhost
344 | TransmissionPort = 9091
345 | TransmissionUSR = your username
346 | TransmissionPWD = your password
347 | #### Deluge (You must edit this if you're using TorrentToMedia.py with deluge. Note that the host/port is for the deluge daemon, not the webui)
348 | DelugeHost = localhost
349 | DelugePort = 58846
350 | DelugeUSR = your username
351 | DelugePWD = your password
352 | ###### qBittorrent (You must edit this if you're using TorrentToMedia.py with qBittorrent)
353 | qBittorrenHost = localhost
354 | qBittorrentPort = 8080
355 | qBittorrentUSR = your username
356 | qBittorrentPWD = your password
357 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
358 | deleteOriginal = 0
359 | chmodDirectory = 0
360 | resume = 1
361 | resumeOnFailure = 1
362 |
363 | [Extensions]
364 | compressedExtensions = .zip,.rar,.7z,.gz,.bz,.tar,.arj,.1,.01,.001
365 | mediaExtensions = .mkv,.avi,.divx,.xvid,.mov,.wmv,.mp4,.mpg,.mpeg,.vob,.iso,.m4v,.ts
366 | audioExtensions = .mp3, .aac, .ogg, .ape, .m4a, .asf, .wma, .flac
367 | metaExtensions = .nfo,.sub,.srt,.jpg,.gif
368 |
369 | [Plex]
370 | # Only enter these details if you want to update plex library after processing.
371 | # Do not enter these details if you send the plex notifications from Sickbeard/CouchPotato.
372 | plex_host = localhost
373 | plex_port = 32400
374 | plex_token =
375 | plex_ssl = 0
376 | # Enter Plex category to section mapping as Category,section and separate each pair with '|'
377 | # e.g. plex_sections = movie,3|tv,4
378 | plex_sections =
379 |
380 | [Transcoder]
381 | # getsubs. enable to download subtitles.
382 | getSubs = 0
383 | # subLanguages. create a list of languages in the order you want them in your subtitles.
384 | subLanguages = eng,spa,fra
385 | # transcode. enable to use transcoder
386 | transcode = 0
387 | ###### duplicate =1 will create a new file. =0 will replace the original
388 | duplicate = 1
389 | # concat. joins cd1 cd2 etc into a single video.
390 | concat = 1
391 | # IgnoreExtensions is a comma-separated list of extensions that will not be transcoded.
392 | ignoreExtensions = .avi,.mkv,.mp4
393 | # outputFastStart. 1 will use -movflags + faststart. 0 will disable this from being used.
394 | outputFastStart = 0
395 | # outputQualityPercent. used as -q:a value. 0 will disable this from being used.
396 | outputQualityPercent = 0
397 | # outputVideoPath. Set path you want transcoded videos moved to. Leave blank to disable.
398 | outputVideoPath =
399 | # processOutput. 1 will send the outputVideoPath to SickBeard/CouchPotato. 0 will send original files.
400 | processOutput = 0
401 | # audioLanguage. set the 3 letter language code you want as your primary audio track.
402 | audioLanguage = eng
403 | # allAudioLanguages. 1 will keep all audio tracks (uses AudioCodec3) where available.
404 | allAudioLanguages = 0
405 | # allSubLanguages. 1 will keep all existing sub languages. 0 will discard those not in your list above.
406 | allSubLanguages = 0
407 | # embedSubs. 1 will embed external sub/srt subs into your video if this is supported.
408 | embedSubs = 1
409 | # burnInSubtitle. burns the default sub language into your video (needed for players that don't support subs)
410 | burnInSubtitle = 0
411 | # extractSubs. 1 will extract subs from the video file and save these as external srt files.
412 | extractSubs = 0
413 | # externalSubDir. set the directory where subs should be saved (if not the same directory as the video)
414 | externalSubDir =
415 | # hwAccel. 1 will set ffmpeg to enable hardware acceleration (this requires a recent ffmpeg)
416 | hwAccel = 0
417 | # generalOptions. Enter your additional ffmpeg options here with commas to separate each option/value (i.e replace spaces with commas).
418 | generalOptions =
419 | # outputDefault. Loads default configs for the selected device. The remaining options below are ignored.
420 | # If you want to use your own profile, leave this blank and set the remaining options below.
421 | # outputDefault profiles allowed: iPad, iPad-1080p, iPad-720p, Apple-TV2, iPod, iPhone, PS3, xbox, Roku-1080p, Roku-720p, Roku-480p, mkv, mp4-scene-release
422 | outputDefault =
423 | #### Define custom settings below.
424 | outputVideoExtension = .mp4
425 | outputVideoCodec = libx264
426 | VideoCodecAllow =
427 | outputVideoPreset = medium
428 | outputVideoResolution = 1920:1080
429 | outputVideoFramerate = 24
430 | outputVideoBitrate = 800000
431 | outputVideoCRF = 19
432 | outputVideoLevel = 3.1
433 | outputAudioCodec = ac3
434 | AudioCodecAllow =
435 | outputAudioChannels = 6
436 | outputAudioBitrate = 640k
437 | outputAudioTrack2Codec = libfaac
438 | AudioCodec2Allow =
439 | outputAudioTrack2Channels = 2
440 | outputAudioTrack2Bitrate = 128000
441 | outputAudioOtherCodec = libmp3lame
442 | AudioOtherCodecAllow =
443 | outputAudioOtherChannels =
444 | outputAudioOtherBitrate = 128000
445 | outputSubtitleCodec =
446 |
447 | [WakeOnLan]
448 | ###### set wake = 1 to send WOL broadcast to the mac and test the server (e.g. xbmc) the host and port specified.
449 | wake = 0
450 | host = 192.168.1.37
451 | port = 80
452 | mac = 00:01:2e:2D:64:e1
453 |
454 | [UserScript]
455 | #Use user_script for uncategorized downloads
456 | #Set the categories to use external script.
457 | #Use "UNCAT" to process non-category downloads, and "ALL" for all defined categories.
458 | [[UNCAT]]
459 | #Enable/Disable this subsection category
460 | enabled = 0
461 | Torrent_NoLink = 0
462 | keep_archive = 1
463 | extract = 1
464 | #Enable if you are sending commands to a remote server for this category
465 | remote_path = 0
466 | #What extension do you want to process? Specify all the extension, or use "ALL" to process all files.
467 | user_script_mediaExtensions = .mkv,.avi,.divx,.xvid,.mov,.wmv,.mp4,.mpg,.mpeg
468 | #Specify the path to your custom script. Use "None" if you wish to link this category, but NOT run any external script.
469 | user_script_path = /nzbToMedia/userscripts/script.sh
470 | #Specify the argument(s) passed to script, comma separated in order.
471 | #for example FP,FN,DN, TN, TL for file path (absolute file name with path), file name, absolute directory name (with path), Torrent Name, Torrent Label/Category.
472 | #So the result is /media/test/script/script.sh FP FN DN TN TL. Add other arguments as needed eg -f, -r
473 | user_script_param = FN
474 | #Set user_script_runOnce = 0 to run for each file, or 1 to only run once (presumably on the entire directory).
475 | user_script_runOnce = 0
476 | #Specify the successcodes returned by the user script as a comma separated list. Linux default is 0
477 | user_script_successCodes = 0
478 | #Clean after? Note that delay function is used to prevent possible mistake :) Delay is intended as seconds
479 | user_script_clean = 1
480 | delay = 120
481 | #Unique path (directory) created for every download. set 0 to disable.
482 | unique_path = 1
483 | ##### Set to path where download client places completed downloads locally for this category
484 | watch_dir =
485 |
486 | [ASCII]
487 | #Set convert =1 if you want to convert any "foreign" characters to ASCII (UTF8) before passing to SB/CP etc. Default is disabled (0).
488 | convert = 0
489 |
490 | [Passwords]
491 | # enter the full path to a text file containing passwords to be used for extraction attempts.
492 | # In the passwords file, every password should be on a new line
493 | PassWordFile =
494 |
495 | [Custom]
496 | # enter a list (comma separated) of Group Tags you want removed from filenames to help with subtitle matching.
497 | # e.g remove_group = [rarbag],-NZBgeek
498 | # be careful if your "group" is a common "real" word. Please report if you have any group replacements that would fall in this category.
499 | remove_group =
500 |
--------------------------------------------------------------------------------
/roles/rtorrent/templates/rtorrent.rc:
--------------------------------------------------------------------------------
1 | scgi_local = ~/rpc.socket
2 | schedule = scgi_permission,0,0,"execute.nothrow=chmod,\"g+w,o=\",~/rpc.socket"
3 | session = ~/.rtorrent.session
4 | directory = /mnt/downloads/bittorrent/incomplete
5 | encryption = require,allow_incoming,require_RC4
6 | method.set_key = event.download.finished,TorrentToMedia,"execute=/usr/local/bin/python2,~/nzbtomedia/TorrentToMedia.py,$d.base_path=,$d.name=,$d.custom1=,$d.hash="
7 |
--------------------------------------------------------------------------------
/roles/rtorrent/templates/rtorrent.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # PROVIDE: rtorrent
4 | # REQUIRE: DAEMON cleanvar
5 | # KEYWORD: shutdown
6 |
7 | . /etc/rc.subr
8 |
9 | rtorrent_home=/usr/local/libdata/rtorrent
10 | rtorrent_bin=/usr/local/bin/rtorrent
11 |
12 | name=rtorrent
13 | rcvar=rtorrent_enable
14 | procname=${rtorrent_bin}
15 | command=/usr/local/bin/dtach
16 | dtach_dir="/var/run/rtorrent"
17 | command_args="-n ${dtach_dir}/rtorrent.dtach ${rtorrent_home}/set_home.sh ${rtorrent_bin}"
18 | rtorrent_chdir=${rtorrent_home}
19 | rtorrent_user=rtorrent
20 | argument_precmd=
21 |
22 | [ -d $dtach_dir ] || mkdir $dtach_dir
23 | chown $rtorrent_user $dtach_dir
24 | load_rc_config $name
25 | export PATH="$PATH:/usr/local/bin"
26 | run_rc_command "$@"
27 |
--------------------------------------------------------------------------------
/roles/rtorrent/templates/set_home.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh -x
2 | export HOME=$(eval printf ~"$(whoami)")
3 | exec "$@"
4 |
--------------------------------------------------------------------------------
/roles/rutorrent/files/labels/couchpotato.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/andsens/freenas-jailconfig/60d09a7a4921ee6c132051b1f3568cee756a8a7d/roles/rutorrent/files/labels/couchpotato.png
--------------------------------------------------------------------------------
/roles/rutorrent/files/labels/movies.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/andsens/freenas-jailconfig/60d09a7a4921ee6c132051b1f3568cee756a8a7d/roles/rutorrent/files/labels/movies.png
--------------------------------------------------------------------------------
/roles/rutorrent/files/labels/sonarr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/andsens/freenas-jailconfig/60d09a7a4921ee6c132051b1f3568cee756a8a7d/roles/rutorrent/files/labels/sonarr.png
--------------------------------------------------------------------------------
/roles/rutorrent/meta/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | dependencies:
4 | - role: nginx
5 | - role: php
6 |
--------------------------------------------------------------------------------
/roles/rutorrent/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: install rutorrent dependencies
4 | pkgng:
5 | name:
6 | - ffmpeg
7 | - mediainfo
8 | - unrar
9 | - sox
10 | state: present
11 |
12 | - name: create rutorrent user
13 | user:
14 | name: rutorrent
15 | groups:
16 | - media
17 | - rtorrent
18 | state: present
19 | home: /usr/local/www/rutorrent
20 | createhome: no
21 |
22 | - name: add the www user to the rtorrent group
23 | user:
24 | name: www
25 | groups: rtorrent
26 | append: yes
27 | notify: restart nginx
28 |
29 | - name: create rutorrent webdir
30 | file:
31 | path: /usr/local/www/rutorrent
32 | state: directory
33 | owner: root
34 | group: wheel
35 | mode: 0755
36 |
37 | - name: clone rutorrent
38 | git:
39 | repo: https://github.com/Novik/ruTorrent.git
40 | dest: /usr/local/www/rutorrent
41 | version: 8ee59f7fc1b0a77b7048fc1f210d5539449d19f2
42 | update: yes
43 | force: yes
44 | register: rutorrent_cloned
45 | notify: restart php-fpm
46 |
47 | - name: clone rutorrent mobile plugin
48 | git:
49 | repo: https://github.com/xombiemp/rutorrentMobile.git
50 | dest: /usr/local/www/rutorrent/plugins/mobile
51 | version: 068099105acc7aca6fae94db34deecd9ce08122b
52 | update: yes
53 | register: rutorrent_mobile_cloned
54 | notify: restart php-fpm
55 |
56 | - name: set base permissions on rutorrent files
57 | file:
58 | path: /usr/local/www/rutorrent
59 | state: directory
60 | recurse: yes
61 | owner: root
62 | group: wheel
63 | mode: 'u=rwX,go=rX'
64 | when: rutorrent_cloned is changed or rutorrent_mobile_cloned is changed
65 |
66 | - name: change owner of share/ to rutorrent
67 | file:
68 | path: /usr/local/www/rutorrent/share
69 | state: directory
70 | recurse: yes
71 | owner: rutorrent
72 | group: wheel
73 | mode: 'u=rwX,go=rX'
74 |
75 | - name: copy labels to rutorrent tracklabels plugin
76 | copy:
77 | src: labels/
78 | dest: /usr/local/www/rutorrent/plugins/tracklabels/labels
79 | owner: root
80 | group: wheel
81 | mode: 0644
82 | loop:
83 | - couchpotato.png
84 | - sonarr.png
85 |
86 | - name: configure rutorrent
87 | template:
88 | src: config.php
89 | dest: /usr/local/www/rutorrent/conf/config.php
90 | owner: root
91 | group: wheel
92 | mode: 0644
93 | tags: [config]
94 |
95 | - name: create php-fpm pool folder
96 | file:
97 | path: /usr/local/etc/fpm-pool.d
98 | state: directory
99 | owner: root
100 | group: wheel
101 | mode: 0755
102 |
103 | - name: enable php-fpm pool configs
104 | lineinfile:
105 | dest: /usr/local/etc/php-fpm.conf
106 | line: include=etc/fpm-pool.d/*.conf
107 | notify: restart php-fpm
108 |
109 | - name: create rutorrent php pool
110 | template:
111 | src: php-pool.conf
112 | dest: /usr/local/etc/fpm-pool.d/rutorrent.conf
113 | owner: root
114 | group: wheel
115 | mode: 0644
116 | notify: restart php-fpm
117 | tags: [config]
118 |
119 | - name: create the nginx vhost
120 | template:
121 | src: nginx-vhost.conf
122 | dest: /usr/local/etc/nginx/sites-available/rutorrent
123 | owner: root
124 | group: wheel
125 | mode: 0644
126 | notify: reload nginx
127 | tags: [config]
128 |
129 | - name: disable flood vhost
130 | file:
131 | path: /usr/local/etc/nginx/sites-enabled/flood
132 | state: absent
133 | notify: reload nginx
134 |
135 | - name: enable the vhost
136 | file:
137 | src: /usr/local/etc/nginx/sites-available/rutorrent
138 | dest: /usr/local/etc/nginx/sites-enabled/rutorrent
139 | state: link
140 | notify: reload nginx
141 |
--------------------------------------------------------------------------------
/roles/rutorrent/templates/config.php:
--------------------------------------------------------------------------------
1 | rtorrent link through unix domain socket
34 | // (scgi_local in rtorrent conf file), change variables
35 | // above to something like this:
36 | //
37 | $scgi_port = 0;
38 | $scgi_host = "unix:///usr/local/libdata/rtorrent/rpc.socket";
39 |
40 | $XMLRPCMountPoint = "/RPC2"; // DO NOT DELETE THIS LINE!!! DO NOT COMMENT THIS LINE!!!
41 |
42 | $pathToExternals = array(
43 | "php" => '/usr/local/bin/php', // Something like /usr/bin/php. If empty, will be found in PATH.
44 | "curl" => '/usr/local/bin/curl', // Something like /usr/bin/curl. If empty, will be found in PATH.
45 | "gzip" => '/usr/bin/gzip', // Something like /usr/bin/gzip. If empty, will be found in PATH.
46 | "id" => '/usr/bin/id', // Something like /usr/bin/id. If empty, will be found in PATH.
47 | "stat" => '/usr/bin/stat', // Something like /usr/bin/stat. If empty, will be found in PATH.
48 | 'mediainfo' => '/usr/local/bin/mediainfo',
49 | 'ffmpeg' => '/usr/local/bin/ffmpeg',
50 | 'unrar' => '/usr/local/bin/unrar',
51 | );
52 |
53 | $localhosts = array( // list of local interfaces
54 | "127.0.0.1",
55 | "localhost",
56 | );
57 |
58 | $profilePath = '../share'; // Path to user profiles
59 | $profileMask = 0777; // Mask for files and directory creation in user profiles.
60 | // Both Webserver and rtorrent users must have read-write access to it.
61 | // For example, if Webserver and rtorrent users are in the same group then the value may be 0770.
62 |
63 | $tempDirectory = null; // Temp directory. Absolute path with trail slash. If null, then autodetect will be used.
64 |
65 | $canUseXSendFile = true; // If true then use X-Sendfile feature if it exist
66 |
67 | $locale = "UTF8";
68 |
--------------------------------------------------------------------------------
/roles/rutorrent/templates/config.php.orig:
--------------------------------------------------------------------------------
1 | rtorrent link through unix domain socket
34 | // (scgi_local in rtorrent conf file), change variables
35 | // above to something like this:
36 | //
37 | // $scgi_port = 0;
38 | // $scgi_host = "unix:///tmp/rpc.socket";
39 |
40 | $XMLRPCMountPoint = "/RPC2"; // DO NOT DELETE THIS LINE!!! DO NOT COMMENT THIS LINE!!!
41 |
42 | $pathToExternals = array(
43 | "php" => '', // Something like /usr/bin/php. If empty, will be found in PATH.
44 | "curl" => '', // Something like /usr/bin/curl. If empty, will be found in PATH.
45 | "gzip" => '', // Something like /usr/bin/gzip. If empty, will be found in PATH.
46 | "id" => '', // Something like /usr/bin/id. If empty, will be found in PATH.
47 | "stat" => '', // Something like /usr/bin/stat. If empty, will be found in PATH.
48 | );
49 |
50 | $localhosts = array( // list of local interfaces
51 | "127.0.0.1",
52 | "localhost",
53 | );
54 |
55 | $profilePath = '../share'; // Path to user profiles
56 | $profileMask = 0777; // Mask for files and directory creation in user profiles.
57 | // Both Webserver and rtorrent users must have read-write access to it.
58 | // For example, if Webserver and rtorrent users are in the same group then the value may be 0770.
59 |
60 | $tempDirectory = null; // Temp directory. Absolute path with trail slash. If null, then autodetect will be used.
61 |
62 | $canUseXSendFile = false; // If true then use X-Sendfile feature if it exist
63 |
64 | $locale = "UTF8";
65 |
--------------------------------------------------------------------------------
/roles/rutorrent/templates/nginx-vhost.conf:
--------------------------------------------------------------------------------
1 | upstream php5-fpm {
2 | server unix:/var/run/php-fpm.rutorrent.sock;
3 | }
4 | upstream rtorrent {
5 | server unix:/usr/local/libdata/rtorrent/rpc.socket;
6 | }
7 | server {
8 | listen 80;
9 | root /usr/local/www/rutorrent;
10 | location /rutorrent {
11 | rewrite ^/rutorrent(/.*)$ $1 last;
12 | }
13 | location /RPC2 {
14 | include scgi_params;
15 | scgi_param SCRIPT_NAME /RPC2;
16 | scgi_pass rtorrent;
17 | }
18 | location ~ ^(/php|/plugins).+\.php$ {
19 | include fastcgi_params;
20 | fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
21 | fastcgi_pass php5-fpm;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/roles/rutorrent/templates/php-pool.conf:
--------------------------------------------------------------------------------
1 | [rutorrent]
2 |
3 | user = rutorrent
4 | group = rutorrent
5 | listen = /var/run/php-fpm.rutorrent.sock
6 | listen.owner = www
7 | listen.group = www
8 | listen.mode = 0660
9 | pm = dynamic
10 | pm.max_children = 5
11 | pm.start_servers = 1
12 | pm.min_spare_servers = 1
13 | pm.max_spare_servers = 2
14 | php_admin_value[error_log] = /var/log/php-fpm.rutorrent.log
15 | env[PATH] = /bin:/usr/bin:/usr/local/bin
16 |
--------------------------------------------------------------------------------
/roles/sabnzbd/handlers/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: start sabnzbd
4 | service:
5 | name: sabnzbd
6 | state: started
7 |
8 | - name: restart sabnzbd
9 | service:
10 | name: sabnzbd
11 | state: restarted
12 |
--------------------------------------------------------------------------------
/roles/sabnzbd/meta/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | dependencies:
4 | - role: nginx
5 |
--------------------------------------------------------------------------------
/roles/sabnzbd/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: install sabnzbd
4 | pkgng:
5 | name: sabnzbdplus
6 | state: present
7 |
8 | - name: add the sabnzbd user to the media group
9 | user:
10 | name: _sabnzbd
11 | groups: media
12 | append: yes
13 | notify: restart nginx
14 |
15 | - name: add the www user to the sabnzbd group
16 | user:
17 | name: www
18 | groups: _sabnzbd
19 | append: yes
20 | notify: restart nginx
21 |
22 | - name: create sabnzbd script dir in home
23 | file:
24 | path: /usr/local/sabnzbd/scripts
25 | state: directory
26 | owner: _sabnzbd
27 | group: media
28 | mode: 0755
29 |
30 | - name: configure nzbtomedia
31 | include: nzbtomedia.yaml
32 |
33 | - name: create the nginx vhost
34 | template:
35 | src: nginx-vhost.conf
36 | dest: /usr/local/etc/nginx/sites-available/sabnzbd
37 | owner: root
38 | group: wheel
39 | mode: 0644
40 | notify: reload nginx
41 | tags: [config]
42 |
43 | - name: enable the vhost
44 | file:
45 | src: /usr/local/etc/nginx/sites-available/sabnzbd
46 | dest: /usr/local/etc/nginx/sites-enabled/sabnzbd
47 | state: link
48 | notify: reload nginx
49 |
50 | - name: enable sabnzbd
51 | service:
52 | name: sabnzbd
53 | enabled: yes
54 | notify: start sabnzbd
55 |
--------------------------------------------------------------------------------
/roles/sabnzbd/tasks/nzbtomedia.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: alias python 2.7 to python
4 | file:
5 | src: python2.7
6 | dest: /usr/local/bin/python
7 | state: link
8 |
9 | - name: install nzbtomedia dependencies
10 | pkgng:
11 | name:
12 | - py27-sqlite3
13 | - ffmpeg
14 | - unrar
15 | - unzip
16 | - p7zip
17 | state: present
18 |
19 | - name: clone nzbtomedia
20 | git:
21 | repo: https://github.com/clinton-hall/nzbToMedia.git
22 | dest: /usr/local/sabnzbd/scripts/nzbtomedia
23 | version: 12.0.0
24 | update: no
25 | register: clone_nzbtomedia
26 |
27 | - name: set permissions on nzbtomedia files
28 | file:
29 | path: /usr/local/sabnzbd/scripts/nzbtomedia
30 | state: directory
31 | recurse: yes
32 | owner: _sabnzbd
33 | group: _sabnzbd
34 | mode: 'u=rwX,go=rX'
35 | when: clone_nzbtomedia is changed
36 |
37 | - name: configure nzbtomedia
38 | template:
39 | src: autoProcessMedia.cfg
40 | dest: /usr/local/sabnzbd/scripts/nzbtomedia/autoProcessMedia.cfg
41 | owner: _sabnzbd
42 | group: _sabnzbd
43 | mode: 0644
44 | tags: [config]
45 |
--------------------------------------------------------------------------------
/roles/sabnzbd/templates/autoProcessMedia.cfg:
--------------------------------------------------------------------------------
1 | # nzbToMedia Configuration
2 | # For more information, visit https://github.com/clinton-hall/nzbToMedia/wiki
3 |
4 | [General]
5 | # Enable/Disable update notifications
6 | version_notify = 1
7 | # Enable/Disable automatic updates
8 | auto_update = 1
9 | # Set to the full path to the git executable
10 | git_path = /usr/local/bin/git
11 | # GitHUB user for repo
12 | git_user =
13 | # GitHUB branch for repo
14 | git_branch =
15 | # Enable/Disable forceful cleaning of leftover files following postprocess
16 | force_clean = 0
17 | # Enable/Disable logging debug messages to nzbtomedia.log
18 | log_debug = 0
19 | # Enable/Disable logging database messages to nzbtomedia.log
20 | log_db = 0
21 | # Enable/Disable logging environment variables to debug nzbtomedia.log (helpful to track down errors calling external tools.)
22 | log_env = 0
23 | # Enable/Disable logging git output to debug nzbtomedia.log (helpful to track down update failures.)
24 | log_git = 0
25 | # Set to the directory where your ffmpeg/ffprobe executables are located
26 | ffmpeg_path = /usr/local/bin
27 | # Enable/Disable media file checking using ffprobe.
28 | check_media = 1
29 | # Enable/Disable a safety check to ensure we don't process all downloads in the default_downloadDirectories by mistake.
30 | safe_mode = 1
31 | # Turn this on to disable additional extraction attempts for failed downloads. Default = 0 will attempt to extract and verify if media is present.
32 | no_extract_failed = 0
33 |
34 | [Posix]
35 | ### Process priority setting for External commands (Extractor and Transcoder) on Posix (Unix/Linux/OSX) systems.
36 | # Set the Niceness value for the nice command. These range from -20 (most favorable to the process) to 19 (least favorable to the process).
37 | niceness = 0
38 | # Set the ionice scheduling class. 0 for none, 1 for real time, 2 for best-effort, 3 for idle.
39 | ionice_class = 0
40 | # Set the ionice scheduling class data. This defines the class data, if the class accepts an argument. For real time and best-effort, 0-7 is valid data.
41 | ionice_classdata = 0
42 |
43 | [Windows]
44 | ### Set specific settings for Windows systems
45 | # Set this to 1 to allow extraction (7zip) windows to be lunched visble (for debugging) otherwise 0 to have this run in background.
46 | show_extraction = 0
47 |
48 | [CouchPotato]
49 | #### autoProcessing for Movies
50 | #### movie - category that gets called for post-processing with CPS
51 | [[movie]]
52 | enabled = 0
53 | apikey =
54 | host = localhost
55 | port = 5050
56 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
57 | ssl = 0
58 | web_root =
59 | # api key for www.omdbapi.com (used as alternative to imdb)
60 | omdbapikey =
61 | # Enable/Disable linking for Torrents
62 | Torrent_NoLink = 0
63 | keep_archive = 1
64 | method = renamer
65 | delete_failed = 0
66 | wait_for = 2
67 | extract = 1
68 | # Set this to minimum required size to consider a media file valid (in MB)
69 | minSize = 0
70 | # Enable/Disable deleting ignored files (samples and invalid media files)
71 | delete_ignored = 0
72 | ##### Enable if Couchpotato is on a remote server for this category
73 | remote_path = 0
74 | ##### Set to path where download client places completed downloads locally for this category
75 | watch_dir =
76 | ##### Set the recursive directory permissions to the following (0 to disable)
77 | chmodDirectory = 0
78 |
79 | [Radarr]
80 | #### autoProcessing for Movies
81 | #### raCategory - category that gets called for post-processing with Radarr
82 | [[movie]]
83 | enabled = 0
84 | apikey =
85 | host = localhost
86 | port = 7878
87 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
88 | web_root =
89 | ssl = 0
90 | # api key for www.omdbapi.com (used as alternative to imdb)
91 | omdbapikey =
92 | delete_failed = 0
93 | # Enable/Disable linking for Torrents
94 | Torrent_NoLink = 0
95 | keep_archive = 1
96 | extract = 1
97 | nzbExtractionBy = Downloader
98 | wait_for = 6
99 | # Set this to minimum required size to consider a media file valid (in MB)
100 | minSize = 0
101 | # Enable/Disable deleting ignored files (samples and invalid media files)
102 | delete_ignored = 0
103 | ##### Enable if NzbDrone is on a remote server for this category
104 | remote_path = 0
105 | ##### Set to path where download client places completed downloads locally for this category
106 | watch_dir =
107 | ##### Set to define import behavior Move or Copy
108 | importMode = Copy
109 |
110 | [SickBeard]
111 | #### autoProcessing for TV Series
112 | #### tv - category that gets called for post-processing with SB
113 | [[tv]]
114 | enabled = 0
115 | host = localhost
116 | port = 8081
117 | apikey =
118 | username =
119 | password =
120 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
121 | web_root =
122 | ssl = 0
123 | fork = auto
124 | delete_failed = 0
125 | # Enable/Disable linking for Torrents
126 | Torrent_NoLink = 0
127 | keep_archive = 1
128 | process_method =
129 | # force processing of already processed content when running a manual scan.
130 | force = 0
131 | # tell SickRage/Medusa to delete all source files after processing.
132 | delete_on = 0
133 | # tell Medusa to ignore check for associated subtitle check when postponing release
134 | ignore_subs = 0
135 | extract = 1
136 | nzbExtractionBy = Downloader
137 | # Set this to minimum required size to consider a media file valid (in MB)
138 | minSize = 0
139 | # Enable/Disable deleting ignored files (samples and invalid media files)
140 | delete_ignored = 0
141 | ##### Enable if SickBeard is on a remote server for this category
142 | remote_path = 0
143 | ##### Set to path where download client places completed downloads locally for this category
144 | watch_dir =
145 | ##### Set the recursive directory permissions to the following (0 to disable)
146 | chmodDirectory = 0
147 |
148 | [NzbDrone]
149 | #### Formerly known as NzbDrone this is now Sonarr
150 | #### autoProcessing for TV Series
151 | #### ndCategory - category that gets called for post-processing with NzbDrone/Sonarr
152 | [[tv]]
153 | enabled = 1
154 | apikey = 92346468b4c74bcf91ab1ff3bed84115
155 | host = sonarr.local
156 | port = 8989
157 | username =
158 | password =
159 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
160 | web_root = /sonarr
161 | ssl = 0
162 | delete_failed = 0
163 | # Enable/Disable linking for Torrents
164 | Torrent_NoLink = 0
165 | keep_archive = 1
166 | extract = 1
167 | nzbExtractionBy = Downloader
168 | wait_for = 6
169 | # Set this to minimum required size to consider a media file valid (in MB)
170 | minSize = 0
171 | # Enable/Disable deleting ignored files (samples and invalid media files)
172 | delete_ignored = 0
173 | ##### Enable if NzbDrone is on a remote server for this category
174 | remote_path = 0
175 | ##### Set to path where download client places completed downloads locally for this category
176 | watch_dir = /mnt/downloads/usenet/complete
177 |
178 | [HeadPhones]
179 | #### autoProcessing for Music
180 | #### music - category that gets called for post-processing with HP
181 | [[music]]
182 | enabled = 0
183 | apikey =
184 | host = localhost
185 | port = 8181
186 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
187 | ssl = 0
188 | web_root =
189 | delete_failed = 0
190 | wait_for = 2
191 | # Enable/Disable linking for Torrents
192 | Torrent_NoLink = 0
193 | keep_archive = 1
194 | extract = 1
195 | # Set this to minimum required size to consider a media file valid (in MB)
196 | minSize = 0
197 | # Enable/Disable deleting ignored files (samples and invalid media files)
198 | delete_ignored = 0
199 | ##### Enable if HeadPhones is on a remote server for this category
200 | remote_path = 0
201 | ##### Set to path where download client places completed downloads locally for this category
202 | watch_dir =
203 |
204 | [Lidarr]
205 | #### autoProcessing for Music
206 | #### LiCategory - category that gets called for post-processing with Lidarr
207 | [[music]]
208 | enabled = 0
209 | apikey =
210 | host = localhost
211 | port = 8686
212 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
213 | web_root =
214 | ssl = 0
215 | delete_failed = 0
216 | # Enable/Disable linking for Torrents
217 | Torrent_NoLink = 0
218 | keep_archive = 1
219 | extract = 1
220 | nzbExtractionBy = Downloader
221 | wait_for = 6
222 | # Set this to minimum required size to consider a media file valid (in MB)
223 | minSize = 0
224 | # Enable/Disable deleting ignored files (samples and invalid media files)
225 | delete_ignored = 0
226 | ##### Enable if NzbDrone is on a remote server for this category
227 | remote_path = 0
228 | ##### Set to path where download client places completed downloads locally for this category
229 | watch_dir =
230 |
231 | [Mylar]
232 | #### autoProcessing for Comics
233 | #### comics - category that gets called for post-processing with Mylar
234 | [[comics]]
235 | enabled = 0
236 | host = localhost
237 | port= 8090
238 | apikey=
239 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
240 | web_root=
241 | ssl=0
242 | # Enable/Disable linking for Torrents
243 | Torrent_NoLink = 0
244 | keep_archive = 1
245 | extract = 1
246 | # Set this to minimum required size to consider a media file valid (in MB)
247 | minSize = 0
248 | # Enable/Disable deleting ignored files (samples and invalid media files)
249 | delete_ignored = 0
250 | ##### Enable if Mylar is on a remote server for this category
251 | remote_path = 0
252 | ##### Set to path where download client places completed downloads locally for this category
253 | watch_dir =
254 |
255 | [Gamez]
256 | #### autoProcessing for Games
257 | #### games - category that gets called for post-processing with Gamez
258 | [[games]]
259 | enabled = 0
260 | apikey =
261 | host = localhost
262 | port = 8085
263 | ######
264 | library = Set to path where you want the processed games to be moved to.
265 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
266 | ssl = 0
267 | web_root =
268 | # Enable/Disable linking for Torrents
269 | Torrent_NoLink = 0
270 | keep_archive = 1
271 | extract = 1
272 | # Set this to minimum required size to consider a media file valid (in MB)
273 | minSize = 0
274 | # Enable/Disable deleting ignored files (samples and invalid media files)
275 | delete_ignored = 0
276 | ##### Enable if Gamez is on a remote server for this category
277 | remote_path = 0
278 | ##### Set to path where download client places completed downloads locally for this category
279 | watch_dir =
280 |
281 | [Network]
282 | # Enter Mount points as LocalPath,RemotePath and separate each pair with '|'
283 | # e.g. MountPoints = /volume1/Public/,E:\|/volume2/share/,\\NAS\
284 | mount_points =
285 |
286 | [Nzb]
287 | ###### clientAgent - Supported clients: sabnzbd, nzbget
288 | clientAgent = sabnzbd
289 | ###### SabNZBD (You must edit this if you're using nzbToMedia.py with SabNZBD)
290 | sabnzbd_host = http://localhost
291 | sabnzbd_port = 80
292 | sabnzbd_apikey = "8f9d92d2ccb8f51a08fe8910d54d5d53"
293 | ###### Enter the default path to your default download directory (non-category downloads). this directory is protected by safe_mode.
294 | default_downloadDirectory =
295 |
296 | [Torrent]
297 | ###### clientAgent - Supported clients: utorrent, transmission, deluge, rtorrent, vuze, qbittorrent, other
298 | clientAgent = other
299 | ###### useLink - Set to hard for physical links, sym for symbolic links, move to move, move-sym to move and link back, and no to not use links (copy)
300 | useLink = hard
301 | ###### outputDirectory - Default output directory (categories will be appended as sub directory to outputDirectory)
302 | outputDirectory = /abs/path/to/complete/
303 | ###### Enter the default path to your default download directory (non-category downloads). this directory is protected by safe_mode.
304 | default_downloadDirectory =
305 | ###### Other categories/labels defined for your downloader. Does not include CouchPotato, SickBeard, HeadPhones, Mylar categories.
306 | categories = music_videos,pictures,software,manual
307 | ###### A list of categories that you don't want to be flattened (i.e preserve the directory structure when copying/linking.
308 | noFlatten = pictures,manual
309 | ###### uTorrent Hardlink solution (You must edit this if you're using TorrentToMedia.py with uTorrent)
310 | uTorrentWEBui = http://localhost:8090/gui/
311 | uTorrentUSR = your username
312 | uTorrentPWD = your password
313 | ###### Transmission (You must edit this if you're using TorrentToMedia.py with Transmission)
314 | TransmissionHost = localhost
315 | TransmissionPort = 9091
316 | TransmissionUSR = your username
317 | TransmissionPWD = your password
318 | #### Deluge (You must edit this if you're using TorrentToMedia.py with deluge. Note that the host/port is for the deluge daemon, not the webui)
319 | DelugeHost = localhost
320 | DelugePort = 58846
321 | DelugeUSR = your username
322 | DelugePWD = your password
323 | ###### qBittorrent (You must edit this if you're using TorrentToMedia.py with qBittorrent)
324 | qBittorrenHost = localhost
325 | qBittorrentPort = 8080
326 | qBittorrentUSR = your username
327 | qBittorrentPWD = your password
328 | ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
329 | deleteOriginal = 0
330 | chmodDirectory = 0
331 | resume = 1
332 | resumeOnFailure = 1
333 |
334 | [Extensions]
335 | compressedExtensions = .zip,.rar,.7z,.gz,.bz,.tar,.arj,.1,.01,.001
336 | mediaExtensions = .mkv,.avi,.divx,.xvid,.mov,.wmv,.mp4,.mpg,.mpeg,.vob,.iso,.m4v,.ts
337 | audioExtensions = .mp3, .aac, .ogg, .ape, .m4a, .asf, .wma, .flac
338 | metaExtensions = .nfo,.sub,.srt,.jpg,.gif
339 |
340 | [Plex]
341 | # Only enter these details if you want to update plex library after processing.
342 | # Do not enter these details if you send the plex notifications from Sickbeard/CouchPotato.
343 | plex_host = localhost
344 | plex_port = 32400
345 | plex_token =
346 | plex_ssl = 0
347 | # Enter Plex category to section mapping as Category,section and separate each pair with '|'
348 | # e.g. plex_sections = movie,3|tv,4
349 | plex_sections =
350 |
351 | [Transcoder]
352 | # getsubs. enable to download subtitles.
353 | getSubs = 0
354 | # subLanguages. create a list of languages in the order you want them in your subtitles.
355 | subLanguages = eng,spa,fra
356 | # transcode. enable to use transcoder
357 | transcode = 0
358 | ###### duplicate =1 will create a new file. =0 will replace the original
359 | duplicate = 1
360 | # concat. joins cd1 cd2 etc into a single video.
361 | concat = 1
362 | # IgnoreExtensions is a comma-separated list of extensions that will not be transcoded.
363 | ignoreExtensions = .avi,.mkv,.mp4
364 | # outputFastStart. 1 will use -movflags + faststart. 0 will disable this from being used.
365 | outputFastStart = 0
366 | # outputQualityPercent. used as -q:a value. 0 will disable this from being used.
367 | outputQualityPercent = 0
368 | # outputVideoPath. Set path you want transcoded videos moved to. Leave blank to disable.
369 | outputVideoPath =
370 | # processOutput. 1 will send the outputVideoPath to SickBeard/CouchPotato. 0 will send original files.
371 | processOutput = 0
372 | # audioLanguage. set the 3 letter language code you want as your primary audio track.
373 | audioLanguage = eng
374 | # allAudioLanguages. 1 will keep all audio tracks (uses AudioCodec3) where available.
375 | allAudioLanguages = 0
376 | # allSubLanguages. 1 will keep all existing sub languages. 0 will discard those not in your list above.
377 | allSubLanguages = 0
378 | # embedSubs. 1 will embed external sub/srt subs into your video if this is supported.
379 | embedSubs = 1
380 | # burnInSubtitle. burns the default sub language into your video (needed for players that don't support subs)
381 | burnInSubtitle = 0
382 | # extractSubs. 1 will extract subs from the video file and save these as external srt files.
383 | extractSubs = 0
384 | # externalSubDir. set the directory where subs should be saved (if not the same directory as the video)
385 | externalSubDir =
386 | # hwAccel. 1 will set ffmpeg to enable hardware acceleration (this requires a recent ffmpeg)
387 | hwAccel = 0
388 | # generalOptions. Enter your additional ffmpeg options here with commas to separate each option/value (i.e replace spaces with commas).
389 | generalOptions =
390 | # outputDefault. Loads default configs for the selected device. The remaining options below are ignored.
391 | # If you want to use your own profile, leave this blank and set the remaining options below.
392 | # outputDefault profiles allowed: iPad, iPad-1080p, iPad-720p, Apple-TV2, iPod, iPhone, PS3, xbox, Roku-1080p, Roku-720p, Roku-480p, mkv, mp4-scene-release
393 | outputDefault =
394 | #### Define custom settings below.
395 | outputVideoExtension = .mp4
396 | outputVideoCodec = libx264
397 | VideoCodecAllow =
398 | outputVideoPreset = medium
399 | outputVideoResolution = 1920:1080
400 | outputVideoFramerate = 24
401 | outputVideoBitrate = 800000
402 | outputVideoCRF = 19
403 | outputVideoLevel = 3.1
404 | outputAudioCodec = ac3
405 | AudioCodecAllow =
406 | outputAudioChannels = 6
407 | outputAudioBitrate = 640k
408 | outputAudioTrack2Codec = libfaac
409 | AudioCodec2Allow =
410 | outputAudioTrack2Channels = 2
411 | outputAudioTrack2Bitrate = 128000
412 | outputAudioOtherCodec = libmp3lame
413 | AudioOtherCodecAllow =
414 | outputAudioOtherChannels =
415 | outputAudioOtherBitrate = 128000
416 | outputSubtitleCodec =
417 |
418 | [WakeOnLan]
419 | ###### set wake = 1 to send WOL broadcast to the mac and test the server (e.g. xbmc) the host and port specified.
420 | wake = 0
421 | host = 192.168.1.37
422 | port = 80
423 | mac = 00:01:2e:2D:64:e1
424 |
425 | [UserScript]
426 | #Use user_script for uncategorized downloads
427 | #Set the categories to use external script.
428 | #Use "UNCAT" to process non-category downloads, and "ALL" for all defined categories.
429 | [[UNCAT]]
430 | #Enable/Disable this subsection category
431 | enabled = 0
432 | Torrent_NoLink = 0
433 | keep_archive = 1
434 | extract = 1
435 | #Enable if you are sending commands to a remote server for this category
436 | remote_path = 0
437 | #What extension do you want to process? Specify all the extension, or use "ALL" to process all files.
438 | user_script_mediaExtensions = .mkv,.avi,.divx,.xvid,.mov,.wmv,.mp4,.mpg,.mpeg
439 | #Specify the path to your custom script. Use "None" if you wish to link this category, but NOT run any external script.
440 | user_script_path = /nzbToMedia/userscripts/script.sh
441 | #Specify the argument(s) passed to script, comma separated in order.
442 | #for example FP,FN,DN, TN, TL for file path (absolute file name with path), file name, absolute directory name (with path), Torrent Name, Torrent Label/Category.
443 | #So the result is /media/test/script/script.sh FP FN DN TN TL. Add other arguments as needed eg -f, -r
444 | user_script_param = FN
445 | #Set user_script_runOnce = 0 to run for each file, or 1 to only run once (presumably on the entire directory).
446 | user_script_runOnce = 0
447 | #Specify the successcodes returned by the user script as a comma separated list. Linux default is 0
448 | user_script_successCodes = 0
449 | #Clean after? Note that delay function is used to prevent possible mistake :) Delay is intended as seconds
450 | user_script_clean = 1
451 | delay = 120
452 | #Unique path (directory) created for every download. set 0 to disable.
453 | unique_path = 1
454 | ##### Set to path where download client places completed downloads locally for this category
455 | watch_dir =
456 |
457 | [ASCII]
458 | #Set convert =1 if you want to convert any "foreign" characters to ASCII (UTF8) before passing to SB/CP etc. Default is disabled (0).
459 | convert = 0
460 |
461 | [Passwords]
462 | # enter the full path to a text file containing passwords to be used for extraction attempts.
463 | # In the passwords file, every password should be on a new line
464 | PassWordFile =
465 |
466 | [Custom]
467 | # enter a list (comma separated) of Group Tags you want removed from filenames to help with subtitle matching.
468 | # e.g remove_group = [rarbag],-NZBgeek
469 | # be careful if your "group" is a common "real" word. Please report if you have any group replacements that would fall in this category.
470 | remove_group =
471 |
--------------------------------------------------------------------------------
/roles/sabnzbd/templates/nginx-vhost.conf:
--------------------------------------------------------------------------------
1 | upstream sabnzbd {
2 | server localhost:8080;
3 | }
4 | server {
5 | listen 80;
6 | location / {
7 | client_max_body_size 10m;
8 |
9 | proxy_set_header Host $host;
10 | proxy_set_header X-Real-IP $remote_addr;
11 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
12 | proxy_http_version 1.1;
13 | proxy_set_header Connection "";
14 |
15 | proxy_pass http://sabnzbd;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/roles/sonarr/handlers/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: start sonarr
4 | service:
5 | name: sonarr
6 | state: started
7 |
8 | - name: restart sonarr
9 | service:
10 | name: sonarr
11 | state: restarted
12 |
--------------------------------------------------------------------------------
/roles/sonarr/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: install sonarr
4 | pkgng:
5 | name: sonarr
6 | state: present
7 |
8 | - name: add the sonarr user to the media group
9 | user:
10 | name: sonarr
11 | groups: media
12 | append: yes
13 | notify: restart sonarr
14 |
15 | - name: allow sonarr to auto-update
16 | file:
17 | path: /usr/local/share/sonarr
18 | state: directory
19 | recurse: yes
20 | owner: sonarr
21 | group: wheel
22 | mode: 'u=rwX,go=rX'
23 |
24 | - name: enable sonarr
25 | service:
26 | name: sonarr
27 | enabled: yes
28 | notify: start sonarr
29 |
--------------------------------------------------------------------------------
/roles/stats/HDD stats.json:
--------------------------------------------------------------------------------
1 | {
2 | "__inputs": [
3 | {
4 | "name": "DS_TELEGRAF",
5 | "label": "telegraf",
6 | "description": "",
7 | "type": "datasource",
8 | "pluginId": "influxdb",
9 | "pluginName": "InfluxDB"
10 | }
11 | ],
12 | "__requires": [
13 | {
14 | "type": "grafana",
15 | "id": "grafana",
16 | "name": "Grafana",
17 | "version": "4.6.2"
18 | },
19 | {
20 | "type": "panel",
21 | "id": "graph",
22 | "name": "Graph",
23 | "version": ""
24 | },
25 | {
26 | "type": "datasource",
27 | "id": "influxdb",
28 | "name": "InfluxDB",
29 | "version": "1.0.0"
30 | },
31 | {
32 | "type": "panel",
33 | "id": "table",
34 | "name": "Table",
35 | "version": ""
36 | }
37 | ],
38 | "annotations": {
39 | "list": [
40 | {
41 | "builtIn": 1,
42 | "datasource": "-- Grafana --",
43 | "enable": true,
44 | "hide": true,
45 | "iconColor": "rgba(0, 211, 255, 1)",
46 | "name": "Annotations & Alerts",
47 | "type": "dashboard"
48 | }
49 | ]
50 | },
51 | "editable": true,
52 | "gnetId": null,
53 | "graphTooltip": 0,
54 | "hideControls": false,
55 | "id": null,
56 | "links": [],
57 | "rows": [
58 | {
59 | "collapse": false,
60 | "height": "250px",
61 | "panels": [
62 | {
63 | "aliasColors": {},
64 | "bars": false,
65 | "dashLength": 10,
66 | "dashes": false,
67 | "datasource": "${DS_TELEGRAF}",
68 | "fill": 0,
69 | "id": 1,
70 | "legend": {
71 | "avg": false,
72 | "current": false,
73 | "max": false,
74 | "min": false,
75 | "show": true,
76 | "total": false,
77 | "values": false
78 | },
79 | "lines": true,
80 | "linewidth": 1,
81 | "links": [],
82 | "nullPointMode": "null",
83 | "percentage": false,
84 | "pointradius": 5,
85 | "points": false,
86 | "renderer": "flot",
87 | "seriesOverrides": [],
88 | "spaceLength": 10,
89 | "span": 6,
90 | "stack": false,
91 | "steppedLine": false,
92 | "targets": [
93 | {
94 | "alias": "$tag_device",
95 | "dsType": "influxdb",
96 | "groupBy": [
97 | {
98 | "params": [
99 | "$__interval"
100 | ],
101 | "type": "time"
102 | },
103 | {
104 | "params": [
105 | "device"
106 | ],
107 | "type": "tag"
108 | },
109 | {
110 | "params": [
111 | "null"
112 | ],
113 | "type": "fill"
114 | }
115 | ],
116 | "measurement": "smart_attribute",
117 | "orderByTime": "ASC",
118 | "policy": "default",
119 | "refId": "A",
120 | "resultFormat": "time_series",
121 | "select": [
122 | [
123 | {
124 | "params": [
125 | "raw_value"
126 | ],
127 | "type": "field"
128 | },
129 | {
130 | "params": [],
131 | "type": "mean"
132 | }
133 | ]
134 | ],
135 | "tags": [
136 | {
137 | "key": "name",
138 | "operator": "=",
139 | "value": "Temperature_Celsius"
140 | }
141 | ]
142 | }
143 | ],
144 | "thresholds": [],
145 | "timeFrom": null,
146 | "timeShift": null,
147 | "title": "Temperatures",
148 | "tooltip": {
149 | "shared": true,
150 | "sort": 0,
151 | "value_type": "individual"
152 | },
153 | "type": "graph",
154 | "xaxis": {
155 | "buckets": null,
156 | "mode": "time",
157 | "name": null,
158 | "show": true,
159 | "values": []
160 | },
161 | "yaxes": [
162 | {
163 | "format": "celsius",
164 | "label": null,
165 | "logBase": 1,
166 | "max": null,
167 | "min": null,
168 | "show": true
169 | },
170 | {
171 | "format": "short",
172 | "label": null,
173 | "logBase": 1,
174 | "max": null,
175 | "min": null,
176 | "show": true
177 | }
178 | ]
179 | },
180 | {
181 | "aliasColors": {},
182 | "bars": false,
183 | "dashLength": 10,
184 | "dashes": false,
185 | "datasource": "${DS_TELEGRAF}",
186 | "fill": 1,
187 | "id": 6,
188 | "legend": {
189 | "alignAsTable": true,
190 | "avg": false,
191 | "current": false,
192 | "max": false,
193 | "min": false,
194 | "rightSide": true,
195 | "show": true,
196 | "total": false,
197 | "values": false
198 | },
199 | "lines": true,
200 | "linewidth": 1,
201 | "links": [],
202 | "nullPointMode": "null",
203 | "percentage": false,
204 | "pointradius": 5,
205 | "points": false,
206 | "renderer": "flot",
207 | "seriesOverrides": [],
208 | "spaceLength": 10,
209 | "span": 6,
210 | "stack": false,
211 | "steppedLine": false,
212 | "targets": [
213 | {
214 | "alias": "$tag_device $tag_name",
215 | "dsType": "influxdb",
216 | "groupBy": [
217 | {
218 | "params": [
219 | "$__interval"
220 | ],
221 | "type": "time"
222 | },
223 | {
224 | "params": [
225 | "device"
226 | ],
227 | "type": "tag"
228 | },
229 | {
230 | "params": [
231 | "name"
232 | ],
233 | "type": "tag"
234 | },
235 | {
236 | "params": [
237 | "null"
238 | ],
239 | "type": "fill"
240 | }
241 | ],
242 | "measurement": "smart_attribute",
243 | "orderByTime": "ASC",
244 | "policy": "default",
245 | "refId": "A",
246 | "resultFormat": "time_series",
247 | "select": [
248 | [
249 | {
250 | "params": [
251 | "raw_value"
252 | ],
253 | "type": "field"
254 | },
255 | {
256 | "params": [],
257 | "type": "mean"
258 | }
259 | ]
260 | ],
261 | "tags": [
262 | {
263 | "key": "device",
264 | "operator": "!=",
265 | "value": "ada0"
266 | },
267 | {
268 | "condition": "AND",
269 | "key": "name",
270 | "operator": "!=",
271 | "value": "Load_Cycle_Count"
272 | },
273 | {
274 | "condition": "AND",
275 | "key": "name",
276 | "operator": "!=",
277 | "value": "Power_On_Hours"
278 | },
279 | {
280 | "condition": "AND",
281 | "key": "name",
282 | "operator": "!=",
283 | "value": "Spin_Up_Time"
284 | },
285 | {
286 | "condition": "AND",
287 | "key": "name",
288 | "operator": "!=",
289 | "value": "Temperature_Celsius"
290 | },
291 | {
292 | "condition": "AND",
293 | "key": "name",
294 | "operator": "!=",
295 | "value": "Throughput_Performance"
296 | },
297 | {
298 | "condition": "AND",
299 | "key": "name",
300 | "operator": "!=",
301 | "value": "Power-Off_Retract_Count"
302 | },
303 | {
304 | "condition": "AND",
305 | "key": "name",
306 | "operator": "!=",
307 | "value": "Power_Cycle_Count"
308 | },
309 | {
310 | "condition": "AND",
311 | "key": "name",
312 | "operator": "!=",
313 | "value": "Seek_Time_Performance"
314 | },
315 | {
316 | "condition": "AND",
317 | "key": "name",
318 | "operator": "!=",
319 | "value": "Start_Stop_Count"
320 | },
321 | {
322 | "condition": "AND",
323 | "key": "name",
324 | "operator": "!=",
325 | "value": "Perc_Avail_Resrvd_Space"
326 | }
327 | ]
328 | }
329 | ],
330 | "thresholds": [],
331 | "timeFrom": null,
332 | "timeShift": null,
333 | "title": "Everything else",
334 | "tooltip": {
335 | "shared": true,
336 | "sort": 0,
337 | "value_type": "individual"
338 | },
339 | "type": "graph",
340 | "xaxis": {
341 | "buckets": null,
342 | "mode": "time",
343 | "name": null,
344 | "show": true,
345 | "values": []
346 | },
347 | "yaxes": [
348 | {
349 | "format": "short",
350 | "label": null,
351 | "logBase": 1,
352 | "max": null,
353 | "min": null,
354 | "show": true
355 | },
356 | {
357 | "format": "short",
358 | "label": null,
359 | "logBase": 1,
360 | "max": null,
361 | "min": null,
362 | "show": true
363 | }
364 | ]
365 | },
366 | {
367 | "aliasColors": {},
368 | "bars": false,
369 | "dashLength": 10,
370 | "dashes": false,
371 | "datasource": "${DS_TELEGRAF}",
372 | "fill": 0,
373 | "id": 5,
374 | "legend": {
375 | "avg": false,
376 | "current": false,
377 | "max": false,
378 | "min": false,
379 | "show": true,
380 | "total": false,
381 | "values": false
382 | },
383 | "lines": true,
384 | "linewidth": 1,
385 | "links": [],
386 | "nullPointMode": "null",
387 | "percentage": false,
388 | "pointradius": 5,
389 | "points": false,
390 | "renderer": "flot",
391 | "seriesOverrides": [],
392 | "spaceLength": 10,
393 | "span": 4,
394 | "stack": false,
395 | "steppedLine": false,
396 | "targets": [
397 | {
398 | "alias": "$tag_device",
399 | "dsType": "influxdb",
400 | "groupBy": [
401 | {
402 | "params": [
403 | "$__interval"
404 | ],
405 | "type": "time"
406 | },
407 | {
408 | "params": [
409 | "device"
410 | ],
411 | "type": "tag"
412 | },
413 | {
414 | "params": [
415 | "null"
416 | ],
417 | "type": "fill"
418 | }
419 | ],
420 | "measurement": "smart_attribute",
421 | "orderByTime": "ASC",
422 | "policy": "default",
423 | "refId": "A",
424 | "resultFormat": "time_series",
425 | "select": [
426 | [
427 | {
428 | "params": [
429 | "raw_value"
430 | ],
431 | "type": "field"
432 | },
433 | {
434 | "params": [],
435 | "type": "mean"
436 | }
437 | ]
438 | ],
439 | "tags": [
440 | {
441 | "key": "name",
442 | "operator": "=",
443 | "value": "Spin_Up_Time"
444 | }
445 | ]
446 | }
447 | ],
448 | "thresholds": [],
449 | "timeFrom": null,
450 | "timeShift": null,
451 | "title": "Spin-up time",
452 | "tooltip": {
453 | "shared": true,
454 | "sort": 0,
455 | "value_type": "individual"
456 | },
457 | "type": "graph",
458 | "xaxis": {
459 | "buckets": null,
460 | "mode": "time",
461 | "name": null,
462 | "show": true,
463 | "values": []
464 | },
465 | "yaxes": [
466 | {
467 | "format": "ms",
468 | "label": null,
469 | "logBase": 1,
470 | "max": null,
471 | "min": "0",
472 | "show": true
473 | },
474 | {
475 | "format": "short",
476 | "label": null,
477 | "logBase": 1,
478 | "max": null,
479 | "min": null,
480 | "show": true
481 | }
482 | ]
483 | },
484 | {
485 | "aliasColors": {},
486 | "bars": false,
487 | "dashLength": 10,
488 | "dashes": false,
489 | "datasource": "${DS_TELEGRAF}",
490 | "fill": 0,
491 | "id": 7,
492 | "legend": {
493 | "avg": false,
494 | "current": false,
495 | "max": false,
496 | "min": false,
497 | "show": true,
498 | "total": false,
499 | "values": false
500 | },
501 | "lines": true,
502 | "linewidth": 1,
503 | "links": [],
504 | "nullPointMode": "null",
505 | "percentage": false,
506 | "pointradius": 5,
507 | "points": false,
508 | "renderer": "flot",
509 | "seriesOverrides": [],
510 | "spaceLength": 10,
511 | "span": 4,
512 | "stack": false,
513 | "steppedLine": false,
514 | "targets": [
515 | {
516 | "alias": "$tag_device",
517 | "dsType": "influxdb",
518 | "groupBy": [
519 | {
520 | "params": [
521 | "$__interval"
522 | ],
523 | "type": "time"
524 | },
525 | {
526 | "params": [
527 | "device"
528 | ],
529 | "type": "tag"
530 | },
531 | {
532 | "params": [
533 | "null"
534 | ],
535 | "type": "fill"
536 | }
537 | ],
538 | "measurement": "smart_attribute",
539 | "orderByTime": "ASC",
540 | "policy": "default",
541 | "refId": "A",
542 | "resultFormat": "time_series",
543 | "select": [
544 | [
545 | {
546 | "params": [
547 | "raw_value"
548 | ],
549 | "type": "field"
550 | },
551 | {
552 | "params": [],
553 | "type": "mean"
554 | }
555 | ]
556 | ],
557 | "tags": [
558 | {
559 | "key": "name",
560 | "operator": "=",
561 | "value": "Throughput_Performance"
562 | }
563 | ]
564 | }
565 | ],
566 | "thresholds": [],
567 | "timeFrom": null,
568 | "timeShift": null,
569 | "title": "Throughput performance",
570 | "tooltip": {
571 | "shared": true,
572 | "sort": 0,
573 | "value_type": "individual"
574 | },
575 | "type": "graph",
576 | "xaxis": {
577 | "buckets": null,
578 | "mode": "time",
579 | "name": null,
580 | "show": true,
581 | "values": []
582 | },
583 | "yaxes": [
584 | {
585 | "format": "short",
586 | "label": null,
587 | "logBase": 1,
588 | "max": null,
589 | "min": "0",
590 | "show": true
591 | },
592 | {
593 | "format": "short",
594 | "label": null,
595 | "logBase": 1,
596 | "max": null,
597 | "min": null,
598 | "show": true
599 | }
600 | ]
601 | },
602 | {
603 | "aliasColors": {},
604 | "bars": false,
605 | "dashLength": 10,
606 | "dashes": false,
607 | "datasource": "${DS_TELEGRAF}",
608 | "fill": 0,
609 | "id": 9,
610 | "legend": {
611 | "avg": false,
612 | "current": false,
613 | "max": false,
614 | "min": false,
615 | "show": true,
616 | "total": false,
617 | "values": false
618 | },
619 | "lines": true,
620 | "linewidth": 1,
621 | "links": [],
622 | "nullPointMode": "null",
623 | "percentage": false,
624 | "pointradius": 5,
625 | "points": false,
626 | "renderer": "flot",
627 | "seriesOverrides": [],
628 | "spaceLength": 10,
629 | "span": 4,
630 | "stack": false,
631 | "steppedLine": false,
632 | "targets": [
633 | {
634 | "alias": "$tag_device",
635 | "dsType": "influxdb",
636 | "groupBy": [
637 | {
638 | "params": [
639 | "$__interval"
640 | ],
641 | "type": "time"
642 | },
643 | {
644 | "params": [
645 | "device"
646 | ],
647 | "type": "tag"
648 | },
649 | {
650 | "params": [
651 | "null"
652 | ],
653 | "type": "fill"
654 | }
655 | ],
656 | "measurement": "smart_attribute",
657 | "orderByTime": "ASC",
658 | "policy": "default",
659 | "refId": "A",
660 | "resultFormat": "time_series",
661 | "select": [
662 | [
663 | {
664 | "params": [
665 | "raw_value"
666 | ],
667 | "type": "field"
668 | },
669 | {
670 | "params": [],
671 | "type": "mean"
672 | }
673 | ]
674 | ],
675 | "tags": [
676 | {
677 | "key": "name",
678 | "operator": "=",
679 | "value": "Seek_Time_Performance"
680 | }
681 | ]
682 | }
683 | ],
684 | "thresholds": [],
685 | "timeFrom": null,
686 | "timeShift": null,
687 | "title": "Seek time performance",
688 | "tooltip": {
689 | "shared": true,
690 | "sort": 0,
691 | "value_type": "individual"
692 | },
693 | "type": "graph",
694 | "xaxis": {
695 | "buckets": null,
696 | "mode": "time",
697 | "name": null,
698 | "show": true,
699 | "values": []
700 | },
701 | "yaxes": [
702 | {
703 | "format": "ms",
704 | "label": null,
705 | "logBase": 1,
706 | "max": null,
707 | "min": "0",
708 | "show": true
709 | },
710 | {
711 | "format": "short",
712 | "label": null,
713 | "logBase": 1,
714 | "max": null,
715 | "min": null,
716 | "show": true
717 | }
718 | ]
719 | },
720 | {
721 | "columns": [
722 | {
723 | "text": "Avg",
724 | "value": "avg"
725 | }
726 | ],
727 | "datasource": "${DS_TELEGRAF}",
728 | "fontSize": "100%",
729 | "id": 12,
730 | "links": [],
731 | "pageSize": 5,
732 | "scroll": false,
733 | "showHeader": true,
734 | "sort": {
735 | "col": 0,
736 | "desc": false
737 | },
738 | "span": 2,
739 | "styles": [
740 | {
741 | "alias": "Time",
742 | "dateFormat": "YYYY-MM-DD HH:mm:ss",
743 | "pattern": "Time",
744 | "type": "date"
745 | },
746 | {
747 | "alias": "",
748 | "colorMode": null,
749 | "colors": [
750 | "rgba(245, 54, 54, 0.9)",
751 | "rgba(237, 129, 40, 0.89)",
752 | "rgba(50, 172, 45, 0.97)"
753 | ],
754 | "decimals": 2,
755 | "pattern": "/.*/",
756 | "thresholds": [],
757 | "type": "number",
758 | "unit": "h"
759 | }
760 | ],
761 | "targets": [
762 | {
763 | "alias": "$tag_device",
764 | "dsType": "influxdb",
765 | "groupBy": [
766 | {
767 | "params": [
768 | "$__interval"
769 | ],
770 | "type": "time"
771 | },
772 | {
773 | "params": [
774 | "device"
775 | ],
776 | "type": "tag"
777 | },
778 | {
779 | "params": [
780 | "null"
781 | ],
782 | "type": "fill"
783 | }
784 | ],
785 | "limit": "",
786 | "measurement": "smart_attribute",
787 | "orderByTime": "ASC",
788 | "policy": "default",
789 | "refId": "A",
790 | "resultFormat": "time_series",
791 | "select": [
792 | [
793 | {
794 | "params": [
795 | "raw_value"
796 | ],
797 | "type": "field"
798 | },
799 | {
800 | "params": [],
801 | "type": "last"
802 | }
803 | ]
804 | ],
805 | "slimit": "",
806 | "tags": [
807 | {
808 | "key": "name",
809 | "operator": "=",
810 | "value": "Power_On_Hours"
811 | }
812 | ]
813 | }
814 | ],
815 | "title": "Time spent powered on",
816 | "transform": "timeseries_aggregations",
817 | "type": "table"
818 | },
819 | {
820 | "columns": [
821 | {
822 | "text": "Avg",
823 | "value": "avg"
824 | }
825 | ],
826 | "datasource": "${DS_TELEGRAF}",
827 | "fontSize": "100%",
828 | "id": 15,
829 | "links": [],
830 | "pageSize": 5,
831 | "scroll": false,
832 | "showHeader": true,
833 | "sort": {
834 | "col": 0,
835 | "desc": false
836 | },
837 | "span": 2,
838 | "styles": [
839 | {
840 | "alias": "Time",
841 | "dateFormat": "YYYY-MM-DD HH:mm:ss",
842 | "pattern": "Time",
843 | "type": "date"
844 | },
845 | {
846 | "alias": "",
847 | "colorMode": null,
848 | "colors": [
849 | "rgba(245, 54, 54, 0.9)",
850 | "rgba(237, 129, 40, 0.89)",
851 | "rgba(50, 172, 45, 0.97)"
852 | ],
853 | "decimals": 0,
854 | "pattern": "/.*/",
855 | "thresholds": [],
856 | "type": "number",
857 | "unit": "short"
858 | }
859 | ],
860 | "targets": [
861 | {
862 | "alias": "$tag_device",
863 | "dsType": "influxdb",
864 | "groupBy": [
865 | {
866 | "params": [
867 | "$__interval"
868 | ],
869 | "type": "time"
870 | },
871 | {
872 | "params": [
873 | "device"
874 | ],
875 | "type": "tag"
876 | },
877 | {
878 | "params": [
879 | "null"
880 | ],
881 | "type": "fill"
882 | }
883 | ],
884 | "limit": "",
885 | "measurement": "smart_attribute",
886 | "orderByTime": "ASC",
887 | "policy": "default",
888 | "refId": "A",
889 | "resultFormat": "time_series",
890 | "select": [
891 | [
892 | {
893 | "params": [
894 | "raw_value"
895 | ],
896 | "type": "field"
897 | },
898 | {
899 | "params": [],
900 | "type": "last"
901 | }
902 | ]
903 | ],
904 | "slimit": "",
905 | "tags": [
906 | {
907 | "key": "name",
908 | "operator": "=",
909 | "value": "Power-Off_Retract_Count"
910 | }
911 | ]
912 | }
913 | ],
914 | "title": "Power off retract count",
915 | "transform": "timeseries_aggregations",
916 | "type": "table"
917 | },
918 | {
919 | "columns": [
920 | {
921 | "text": "Avg",
922 | "value": "avg"
923 | }
924 | ],
925 | "datasource": "${DS_TELEGRAF}",
926 | "fontSize": "100%",
927 | "id": 17,
928 | "links": [],
929 | "pageSize": 5,
930 | "scroll": false,
931 | "showHeader": true,
932 | "sort": {
933 | "col": 0,
934 | "desc": false
935 | },
936 | "span": 2,
937 | "styles": [
938 | {
939 | "alias": "Time",
940 | "dateFormat": "YYYY-MM-DD HH:mm:ss",
941 | "pattern": "Time",
942 | "type": "date"
943 | },
944 | {
945 | "alias": "",
946 | "colorMode": null,
947 | "colors": [
948 | "rgba(245, 54, 54, 0.9)",
949 | "rgba(237, 129, 40, 0.89)",
950 | "rgba(50, 172, 45, 0.97)"
951 | ],
952 | "decimals": 0,
953 | "pattern": "/.*/",
954 | "thresholds": [],
955 | "type": "number",
956 | "unit": "none"
957 | }
958 | ],
959 | "targets": [
960 | {
961 | "alias": "$tag_device",
962 | "dsType": "influxdb",
963 | "groupBy": [
964 | {
965 | "params": [
966 | "$__interval"
967 | ],
968 | "type": "time"
969 | },
970 | {
971 | "params": [
972 | "device"
973 | ],
974 | "type": "tag"
975 | },
976 | {
977 | "params": [
978 | "null"
979 | ],
980 | "type": "fill"
981 | }
982 | ],
983 | "limit": "",
984 | "measurement": "smart_attribute",
985 | "orderByTime": "ASC",
986 | "policy": "default",
987 | "refId": "A",
988 | "resultFormat": "time_series",
989 | "select": [
990 | [
991 | {
992 | "params": [
993 | "raw_value"
994 | ],
995 | "type": "field"
996 | },
997 | {
998 | "params": [],
999 | "type": "last"
1000 | }
1001 | ]
1002 | ],
1003 | "slimit": "",
1004 | "tags": [
1005 | {
1006 | "key": "name",
1007 | "operator": "=",
1008 | "value": "Load_Cycle_Count"
1009 | }
1010 | ]
1011 | }
1012 | ],
1013 | "title": "Load cycle count",
1014 | "transform": "timeseries_aggregations",
1015 | "type": "table"
1016 | },
1017 | {
1018 | "columns": [
1019 | {
1020 | "text": "Avg",
1021 | "value": "avg"
1022 | }
1023 | ],
1024 | "datasource": "${DS_TELEGRAF}",
1025 | "fontSize": "100%",
1026 | "id": 14,
1027 | "links": [],
1028 | "pageSize": 5,
1029 | "scroll": false,
1030 | "showHeader": true,
1031 | "sort": {
1032 | "col": 0,
1033 | "desc": false
1034 | },
1035 | "span": 2,
1036 | "styles": [
1037 | {
1038 | "alias": "Time",
1039 | "dateFormat": "YYYY-MM-DD HH:mm:ss",
1040 | "pattern": "Time",
1041 | "type": "date"
1042 | },
1043 | {
1044 | "alias": "",
1045 | "colorMode": null,
1046 | "colors": [
1047 | "rgba(245, 54, 54, 0.9)",
1048 | "rgba(237, 129, 40, 0.89)",
1049 | "rgba(50, 172, 45, 0.97)"
1050 | ],
1051 | "decimals": 0,
1052 | "pattern": "/.*/",
1053 | "thresholds": [],
1054 | "type": "number",
1055 | "unit": "short"
1056 | }
1057 | ],
1058 | "targets": [
1059 | {
1060 | "alias": "$tag_device",
1061 | "dsType": "influxdb",
1062 | "groupBy": [
1063 | {
1064 | "params": [
1065 | "$__interval"
1066 | ],
1067 | "type": "time"
1068 | },
1069 | {
1070 | "params": [
1071 | "device"
1072 | ],
1073 | "type": "tag"
1074 | },
1075 | {
1076 | "params": [
1077 | "null"
1078 | ],
1079 | "type": "fill"
1080 | }
1081 | ],
1082 | "limit": "",
1083 | "measurement": "smart_attribute",
1084 | "orderByTime": "ASC",
1085 | "policy": "default",
1086 | "refId": "A",
1087 | "resultFormat": "time_series",
1088 | "select": [
1089 | [
1090 | {
1091 | "params": [
1092 | "raw_value"
1093 | ],
1094 | "type": "field"
1095 | },
1096 | {
1097 | "params": [],
1098 | "type": "last"
1099 | }
1100 | ]
1101 | ],
1102 | "slimit": "",
1103 | "tags": [
1104 | {
1105 | "key": "name",
1106 | "operator": "=",
1107 | "value": "Power_Cycle_Count"
1108 | }
1109 | ]
1110 | }
1111 | ],
1112 | "title": "Power cycle count",
1113 | "transform": "timeseries_aggregations",
1114 | "type": "table"
1115 | },
1116 | {
1117 | "columns": [
1118 | {
1119 | "text": "Avg",
1120 | "value": "avg"
1121 | }
1122 | ],
1123 | "datasource": "${DS_TELEGRAF}",
1124 | "fontSize": "100%",
1125 | "id": 13,
1126 | "links": [],
1127 | "pageSize": 5,
1128 | "scroll": false,
1129 | "showHeader": true,
1130 | "sort": {
1131 | "col": 0,
1132 | "desc": false
1133 | },
1134 | "span": 2,
1135 | "styles": [
1136 | {
1137 | "alias": "Time",
1138 | "dateFormat": "YYYY-MM-DD HH:mm:ss",
1139 | "pattern": "Time",
1140 | "type": "date"
1141 | },
1142 | {
1143 | "alias": "",
1144 | "colorMode": null,
1145 | "colors": [
1146 | "rgba(245, 54, 54, 0.9)",
1147 | "rgba(237, 129, 40, 0.89)",
1148 | "rgba(50, 172, 45, 0.97)"
1149 | ],
1150 | "decimals": 0,
1151 | "pattern": "/.*/",
1152 | "thresholds": [],
1153 | "type": "number",
1154 | "unit": "short"
1155 | }
1156 | ],
1157 | "targets": [
1158 | {
1159 | "alias": "$tag_device",
1160 | "dsType": "influxdb",
1161 | "groupBy": [
1162 | {
1163 | "params": [
1164 | "$__interval"
1165 | ],
1166 | "type": "time"
1167 | },
1168 | {
1169 | "params": [
1170 | "device"
1171 | ],
1172 | "type": "tag"
1173 | },
1174 | {
1175 | "params": [
1176 | "null"
1177 | ],
1178 | "type": "fill"
1179 | }
1180 | ],
1181 | "limit": "",
1182 | "measurement": "smart_attribute",
1183 | "orderByTime": "ASC",
1184 | "policy": "default",
1185 | "refId": "A",
1186 | "resultFormat": "time_series",
1187 | "select": [
1188 | [
1189 | {
1190 | "params": [
1191 | "raw_value"
1192 | ],
1193 | "type": "field"
1194 | },
1195 | {
1196 | "params": [],
1197 | "type": "last"
1198 | }
1199 | ]
1200 | ],
1201 | "slimit": "",
1202 | "tags": [
1203 | {
1204 | "key": "name",
1205 | "operator": "=",
1206 | "value": "Start_Stop_Count"
1207 | }
1208 | ]
1209 | }
1210 | ],
1211 | "title": "Start stop count",
1212 | "transform": "timeseries_aggregations",
1213 | "type": "table"
1214 | },
1215 | {
1216 | "columns": [
1217 | {
1218 | "text": "Avg",
1219 | "value": "avg"
1220 | }
1221 | ],
1222 | "datasource": "${DS_TELEGRAF}",
1223 | "fontSize": "100%",
1224 | "id": 16,
1225 | "links": [],
1226 | "pageSize": 5,
1227 | "scroll": false,
1228 | "showHeader": true,
1229 | "sort": {
1230 | "col": 0,
1231 | "desc": false
1232 | },
1233 | "span": 2,
1234 | "styles": [
1235 | {
1236 | "alias": "Time",
1237 | "dateFormat": "YYYY-MM-DD HH:mm:ss",
1238 | "pattern": "Time",
1239 | "type": "date"
1240 | },
1241 | {
1242 | "alias": "",
1243 | "colorMode": null,
1244 | "colors": [
1245 | "rgba(245, 54, 54, 0.9)",
1246 | "rgba(237, 129, 40, 0.89)",
1247 | "rgba(50, 172, 45, 0.97)"
1248 | ],
1249 | "decimals": 0,
1250 | "pattern": "/.*/",
1251 | "thresholds": [],
1252 | "type": "number",
1253 | "unit": "percent"
1254 | }
1255 | ],
1256 | "targets": [
1257 | {
1258 | "alias": "$tag_device",
1259 | "dsType": "influxdb",
1260 | "groupBy": [
1261 | {
1262 | "params": [
1263 | "$__interval"
1264 | ],
1265 | "type": "time"
1266 | },
1267 | {
1268 | "params": [
1269 | "device"
1270 | ],
1271 | "type": "tag"
1272 | },
1273 | {
1274 | "params": [
1275 | "null"
1276 | ],
1277 | "type": "fill"
1278 | }
1279 | ],
1280 | "limit": "",
1281 | "measurement": "smart_attribute",
1282 | "orderByTime": "ASC",
1283 | "policy": "default",
1284 | "refId": "A",
1285 | "resultFormat": "time_series",
1286 | "select": [
1287 | [
1288 | {
1289 | "params": [
1290 | "raw_value"
1291 | ],
1292 | "type": "field"
1293 | },
1294 | {
1295 | "params": [],
1296 | "type": "last"
1297 | }
1298 | ]
1299 | ],
1300 | "slimit": "",
1301 | "tags": [
1302 | {
1303 | "key": "name",
1304 | "operator": "=",
1305 | "value": "Perc_Avail_Resrvd_Space"
1306 | }
1307 | ]
1308 | }
1309 | ],
1310 | "title": "SSD available reserved space",
1311 | "transform": "timeseries_aggregations",
1312 | "type": "table"
1313 | }
1314 | ],
1315 | "repeat": null,
1316 | "repeatIteration": null,
1317 | "repeatRowId": null,
1318 | "showTitle": false,
1319 | "title": "Dashboard Row",
1320 | "titleSize": "h6"
1321 | }
1322 | ],
1323 | "schemaVersion": 14,
1324 | "style": "dark",
1325 | "tags": [],
1326 | "templating": {
1327 | "list": []
1328 | },
1329 | "time": {
1330 | "from": "now-6h",
1331 | "to": "now"
1332 | },
1333 | "timepicker": {
1334 | "refresh_intervals": [
1335 | "5s",
1336 | "10s",
1337 | "30s",
1338 | "1m",
1339 | "5m",
1340 | "15m",
1341 | "30m",
1342 | "1h",
1343 | "2h",
1344 | "1d"
1345 | ],
1346 | "time_options": [
1347 | "5m",
1348 | "15m",
1349 | "1h",
1350 | "6h",
1351 | "12h",
1352 | "24h",
1353 | "2d",
1354 | "7d",
1355 | "30d"
1356 | ]
1357 | },
1358 | "timezone": "",
1359 | "title": "HDD stats",
1360 | "version": 10
1361 | }
--------------------------------------------------------------------------------
/roles/stats/defaults/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | grafana_root_url: null
4 | grafana_secret_key: null
5 | grafana_plugins: []
6 | telegraf_snmp: null
7 |
--------------------------------------------------------------------------------
/roles/stats/handlers/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: start grafana
4 | service:
5 | name: grafana
6 | enabled: yes
7 | state: started
8 |
9 | - name: restart grafana
10 | service:
11 | name: grafana
12 | enabled: yes
13 | state: restarted
14 |
15 | - name: start influxdb
16 | service:
17 | name: influxd
18 | enabled: yes
19 | state: started
20 |
21 | - name: restart influxdb
22 | service:
23 | name: influxd
24 | enabled: yes
25 | state: restarted
26 |
27 | - name: start telegraf
28 | service:
29 | name: telegraf
30 | enabled: yes
31 | state: started
32 |
33 | - name: restart telegraf
34 | service:
35 | name: telegraf
36 | enabled: yes
37 | state: restarted
38 |
--------------------------------------------------------------------------------
/roles/stats/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: install grafana
4 | pkgng:
5 | name: grafana5
6 | state: present
7 |
8 | - name: install influxdb
9 | pkgng:
10 | name: influxdb
11 | state: present
12 |
13 | - name: install telegraf
14 | pkgng:
15 | name: telegraf
16 | state: present
17 |
18 | - name: install other dependencies
19 | pkgng:
20 | name:
21 | - collectd5
22 | - ipmitool
23 | - net-snmp
24 | - smartmontools
25 | state: present
26 |
27 | - name: link snmptranslate to /usr/bin so telegraf can use it
28 | file:
29 | src: /usr/local/bin/snmptranslate
30 | dest: /usr/bin/snmptranslate
31 | state: link
32 |
33 | - name: configure grafana
34 | template:
35 | src: grafana.conf
36 | dest: /usr/local/etc/grafana.conf
37 | owner: root
38 | group: wheel
39 | mode: 0644
40 | notify: restart grafana
41 | tags:
42 | - config
43 |
44 | - name: install grafana plugins
45 | command: grafana-cli plugins install {{ item }}
46 | loop: "{{ grafana_plugins }}"
47 |
48 | - name: configure influxdb
49 | template:
50 | src: influxd.conf
51 | dest: /usr/local/etc/influxd.conf
52 | owner: root
53 | group: wheel
54 | mode: 0644
55 | notify: restart influxdb
56 | tags:
57 | - config
58 |
59 | - name: configure telegraf
60 | template:
61 | src: telegraf.conf
62 | dest: /usr/local/etc/telegraf.conf
63 | owner: root
64 | group: wheel
65 | mode: 0644
66 | notify: restart telegraf
67 | tags:
68 | - config
69 |
70 | - name: enable influxdb
71 | service:
72 | name: influxd
73 | enabled: yes
74 | notify: start influxdb
75 |
76 | - name: enable telegraf
77 | service:
78 | name: telegraf
79 | enabled: yes
80 | notify: start telegraf
81 |
82 | - name: enable grafana
83 | service:
84 | name: grafana
85 | enabled: yes
86 | notify: start grafana
87 |
88 | - name: flush handlers to start influxdb before creating database
89 | meta: flush_handlers
90 |
91 | - name: create influxdb databases
92 | command: influx -execute 'CREATE DATABASE {{ item }}'
93 | loop:
94 | - collectd
95 | - telegraf
96 |
--------------------------------------------------------------------------------
/roles/stats/templates/grafana.conf:
--------------------------------------------------------------------------------
1 | ##################### Grafana Configuration Example #####################
2 | #
3 | # Everything has defaults so you only need to uncomment things you want to
4 | # change
5 |
6 | # possible values : production, development
7 | ; app_mode = production
8 |
9 | # instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
10 | ; instance_name = ${HOSTNAME}
11 |
12 | #################################### Paths ####################################
13 | [paths]
14 | # Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
15 | data = /var/db/grafana/
16 |
17 | # Directory where grafana can store logs
18 | logs = /var/log/grafana/
19 |
20 | # Directory where grafana will automatically scan and look for plugins
21 | plugins = /var/db/grafana/plugins
22 |
23 | # folder that contains provisioning config files that grafana will apply on startup and while running.
24 | provisioning = /var/db/grafana/provisioning
25 |
26 | #################################### Server ####################################
27 | [server]
28 | # Protocol (http, https, socket)
29 | ;protocol = http
30 |
31 | # The ip address to bind to, empty will bind to all interfaces
32 | ;http_addr =
33 |
34 | # The http port to use
35 | ;http_port = 3000
36 |
37 | # The public facing domain name used to access grafana from a browser
38 | ;domain = localhost
39 |
40 | # Redirect to correct domain if host header does not match domain
41 | # Prevents DNS rebinding attacks
42 | ;enforce_domain = false
43 |
44 | # The full public facing url you use in browser, used for redirects and emails
45 | # If you use reverse proxy and sub path specify full url (with sub path)
46 | root_url = {{ grafana_root_url }}
47 |
48 | # Log web requests
49 | ;router_logging = false
50 |
51 | # the path relative working path
52 | ;static_root_path = public
53 |
54 | # enable gzip
55 | ;enable_gzip = false
56 |
57 | # https certs & key file
58 | ;cert_file =
59 | ;cert_key =
60 |
61 | # Unix socket path
62 | ;socket =
63 |
64 | #################################### Database ####################################
65 | [database]
66 | # You can configure the database connection by specifying type, host, name, user and password
67 | # as seperate properties or as on string using the url propertie.
68 |
69 | # Either "mysql", "postgres" or "sqlite3", it's your choice
70 | ;type = sqlite3
71 | ;host = 127.0.0.1:3306
72 | ;name = grafana
73 | ;user = root
74 | # If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
75 | ;password =
76 |
77 | # Use either URL or the previous fields to configure the database
78 | # Example: mysql://user:secret@host:port/database
79 | ;url =
80 |
81 | # For "postgres" only, either "disable", "require" or "verify-full"
82 | ;ssl_mode = disable
83 |
84 | # For "sqlite3" only, path relative to data_path setting
85 | ;path = grafana.db
86 |
87 | # Max idle conn setting default is 2
88 | ;max_idle_conn = 2
89 |
90 | # Max conn setting default is 0 (mean not set)
91 | ;max_open_conn =
92 |
93 | # Set to true to log the sql calls and execution times.
94 | log_queries =
95 |
96 | #################################### Session ####################################
97 | [session]
98 | # Either "memory", "file", "redis", "mysql", "postgres", default is "file"
99 | ;provider = file
100 |
101 | # Provider config options
102 | # memory: not have any config yet
103 | # file: session dir path, is relative to grafana data_path
104 | # redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana`
105 | # mysql: go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1:3306)/database_name`
106 | # postgres: user=a password=b host=localhost port=5432 dbname=c sslmode=disable
107 | ;provider_config = sessions
108 |
109 | # Session cookie name
110 | ;cookie_name = grafana_sess
111 |
112 | # If you use session in https only, default is false
113 | ;cookie_secure = false
114 |
115 | # Session life time, default is 86400
116 | ;session_life_time = 86400
117 |
118 | #################################### Data proxy ###########################
119 | [dataproxy]
120 |
121 | # This enables data proxy logging, default is false
122 | ;logging = false
123 |
124 |
125 | #################################### Analytics ####################################
126 | [analytics]
127 | # Server reporting, sends usage counters to stats.grafana.org every 24 hours.
128 | # No ip addresses are being tracked, only simple counters to track
129 | # running instances, dashboard and error counts. It is very helpful to us.
130 | # Change this option to false to disable reporting.
131 | ;reporting_enabled = true
132 |
133 | # Set to false to disable all checks to https://grafana.net
134 | # for new vesions (grafana itself and plugins), check is used
135 | # in some UI views to notify that grafana or plugin update exists
136 | # This option does not cause any auto updates, nor send any information
137 | # only a GET request to http://grafana.com to get latest versions
138 | ;check_for_updates = true
139 |
140 | # Google Analytics universal tracking code, only enabled if you specify an id here
141 | ;google_analytics_ua_id =
142 |
143 | #################################### Security ####################################
144 | [security]
145 | # default admin user, created on startup
146 | ;admin_user = admin
147 |
148 | # default admin password, can be changed before first start of grafana, or in profile settings
149 | ;admin_password = admin
150 |
151 | # used for signing
152 | secret_key = {{ grafana_secret_key }}
153 |
154 | # Auto-login remember days
155 | ;login_remember_days = 7
156 | ;cookie_username = grafana_user
157 | ;cookie_remember_name = grafana_remember
158 |
159 | # disable gravatar profile images
160 | ;disable_gravatar = false
161 |
162 | # data source proxy whitelist (ip_or_domain:port separated by spaces)
163 | ;data_source_proxy_whitelist =
164 |
165 | # disable protection against brute force login attempts
166 | ;disable_brute_force_login_protection = false
167 |
168 | #################################### Snapshots ###########################
169 | [snapshots]
170 | # snapshot sharing options
171 | ;external_enabled = true
172 | ;external_snapshot_url = https://snapshots-origin.raintank.io
173 | ;external_snapshot_name = Publish to snapshot.raintank.io
174 |
175 | # remove expired snapshot
176 | ;snapshot_remove_expired = true
177 |
178 | #################################### Dashboards History ##################
179 | [dashboards]
180 | # Number dashboard versions to keep (per dashboard). Default: 20, Minimum: 1
181 | ;versions_to_keep = 20
182 |
183 | #################################### Users ###############################
184 | [users]
185 | # disable user signup / registration
186 | ;allow_sign_up = true
187 |
188 | # Allow non admin users to create organizations
189 | ;allow_org_create = true
190 |
191 | # Set to true to automatically assign new users to the default organization (id 1)
192 | ;auto_assign_org = true
193 |
194 | # Default role new users will be automatically assigned (if disabled above is set to true)
195 | ;auto_assign_org_role = Viewer
196 |
197 | # Background text for the user field on the login page
198 | ;login_hint = email or username
199 |
200 | # Default UI theme ("dark" or "light")
201 | ;default_theme = dark
202 |
203 | # External user management, these options affect the organization users view
204 | ;external_manage_link_url =
205 | ;external_manage_link_name =
206 | ;external_manage_info =
207 |
208 | # Viewers can edit/inspect dashboard settings in the browser. But not save the dashboard.
209 | ;viewers_can_edit = false
210 |
211 | [auth]
212 | # Set to true to disable (hide) the login form, useful if you use OAuth, defaults to false
213 | ;disable_login_form = false
214 |
215 | # Set to true to disable the signout link in the side menu. useful if you use auth.proxy, defaults to false
216 | ;disable_signout_menu = false
217 |
218 | #################################### Anonymous Auth ##########################
219 | [auth.anonymous]
220 | # enable anonymous access
221 | enabled = true
222 |
223 | # specify organization name that should be used for unauthenticated users
224 | ;org_name = Main Org.
225 |
226 | # specify role for unauthenticated users
227 | org_role = Admin
228 |
229 | #################################### Github Auth ##########################
230 | [auth.github]
231 | ;enabled = false
232 | ;allow_sign_up = true
233 | ;client_id = some_id
234 | ;client_secret = some_secret
235 | ;scopes = user:email,read:org
236 | ;auth_url = https://github.com/login/oauth/authorize
237 | ;token_url = https://github.com/login/oauth/access_token
238 | ;api_url = https://api.github.com/user
239 | ;team_ids =
240 | ;allowed_organizations =
241 |
242 | #################################### Google Auth ##########################
243 | [auth.google]
244 | ;enabled = false
245 | ;allow_sign_up = true
246 | ;client_id = some_client_id
247 | ;client_secret = some_client_secret
248 | ;scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
249 | ;auth_url = https://accounts.google.com/o/oauth2/auth
250 | ;token_url = https://accounts.google.com/o/oauth2/token
251 | ;api_url = https://www.googleapis.com/oauth2/v1/userinfo
252 | ;allowed_domains =
253 |
254 | #################################### Generic OAuth ##########################
255 | [auth.generic_oauth]
256 | ;enabled = false
257 | ;name = OAuth
258 | ;allow_sign_up = true
259 | ;client_id = some_id
260 | ;client_secret = some_secret
261 | ;scopes = user:email,read:org
262 | ;auth_url = https://foo.bar/login/oauth/authorize
263 | ;token_url = https://foo.bar/login/oauth/access_token
264 | ;api_url = https://foo.bar/user
265 | ;team_ids =
266 | ;allowed_organizations =
267 |
268 | #################################### Grafana.com Auth ####################
269 | [auth.grafana_com]
270 | ;enabled = false
271 | ;allow_sign_up = true
272 | ;client_id = some_id
273 | ;client_secret = some_secret
274 | ;scopes = user:email
275 | ;allowed_organizations =
276 |
277 | #################################### Auth Proxy ##########################
278 | [auth.proxy]
279 | ;enabled = false
280 | ;header_name = X-WEBAUTH-USER
281 | ;header_property = username
282 | ;auto_sign_up = true
283 | ;ldap_sync_ttl = 60
284 | ;whitelist = 192.168.1.1, 192.168.2.1
285 |
286 | #################################### Basic Auth ##########################
287 | [auth.basic]
288 | ;enabled = true
289 |
290 | #################################### Auth LDAP ##########################
291 | [auth.ldap]
292 | ;enabled = false
293 | ;config_file = /etc/grafana/ldap.toml
294 | ;allow_sign_up = true
295 |
296 | #################################### SMTP / Emailing ##########################
297 | [smtp]
298 | ;enabled = false
299 | ;host = localhost:25
300 | ;user =
301 | # If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;"""
302 | ;password =
303 | ;cert_file =
304 | ;key_file =
305 | ;skip_verify = false
306 | ;from_address = admin@grafana.localhost
307 | ;from_name = Grafana
308 | # EHLO identity in SMTP dialog (defaults to instance_name)
309 | ;ehlo_identity = dashboard.example.com
310 |
311 | [emails]
312 | ;welcome_email_on_sign_up = false
313 |
314 | #################################### Logging ##########################
315 | [log]
316 | # Either "console", "file", "syslog". Default is console and file
317 | # Use space to separate multiple modes, e.g. "console file"
318 | ;mode = console file
319 |
320 | # Either "debug", "info", "warn", "error", "critical", default is "info"
321 | ;level = info
322 |
323 | # optional settings to set different levels for specific loggers. Ex filters = sqlstore:debug
324 | ;filters =
325 |
326 |
327 | # For "console" mode only
328 | [log.console]
329 | ;level =
330 |
331 | # log line format, valid options are text, console and json
332 | ;format = console
333 |
334 | # For "file" mode only
335 | [log.file]
336 | ;level =
337 |
338 | # log line format, valid options are text, console and json
339 | ;format = text
340 |
341 | # This enables automated log rotate(switch of following options), default is true
342 | ;log_rotate = true
343 |
344 | # Max line number of single file, default is 1000000
345 | ;max_lines = 1000000
346 |
347 | # Max size shift of single file, default is 28 means 1 << 28, 256MB
348 | ;max_size_shift = 28
349 |
350 | # Segment log daily, default is true
351 | ;daily_rotate = true
352 |
353 | # Expired days of log file(delete after max days), default is 7
354 | ;max_days = 7
355 |
356 | [log.syslog]
357 | ;level =
358 |
359 | # log line format, valid options are text, console and json
360 | ;format = text
361 |
362 | # Syslog network type and address. This can be udp, tcp, or unix. If left blank, the default unix endpoints will be used.
363 | ;network =
364 | ;address =
365 |
366 | # Syslog facility. user, daemon and local0 through local7 are valid.
367 | ;facility =
368 |
369 | # Syslog tag. By default, the process' argv[0] is used.
370 | ;tag =
371 |
372 |
373 | #################################### Alerting ############################
374 | [alerting]
375 | # Disable alerting engine & UI features
376 | ;enabled = true
377 | # Makes it possible to turn off alert rule execution but alerting UI is visible
378 | ;execute_alerts = true
379 |
380 | #################################### Internal Grafana Metrics ##########################
381 | # Metrics available at HTTP API Url /metrics
382 | [metrics]
383 | # Disable / Enable internal metrics
384 | ;enabled = true
385 |
386 | # Publish interval
387 | ;interval_seconds = 10
388 |
389 | # Send internal metrics to Graphite
390 | [metrics.graphite]
391 | # Enable by setting the address setting (ex localhost:2003)
392 | ;address =
393 | ;prefix = prod.grafana.%(instance_name)s.
394 |
395 | #################################### Distributed tracing ############
396 | [tracing.jaeger]
397 | # Enable by setting the address sending traces to jaeger (ex localhost:6831)
398 | ;address = localhost:6831
399 | # Tag that will always be included in when creating new spans. ex (tag1:value1,tag2:value2)
400 | ;always_included_tag = tag1:value1
401 | # Type specifies the type of the sampler: const, probabilistic, rateLimiting, or remote
402 | ;sampler_type = const
403 | # jaeger samplerconfig param
404 | # for "const" sampler, 0 or 1 for always false/true respectively
405 | # for "probabilistic" sampler, a probability between 0 and 1
406 | # for "rateLimiting" sampler, the number of spans per second
407 | # for "remote" sampler, param is the same as for "probabilistic"
408 | # and indicates the initial sampling rate before the actual one
409 | # is received from the mothership
410 | ;sampler_param = 1
411 |
412 | #################################### Grafana.com integration ##########################
413 | # Url used to to import dashboards directly from Grafana.com
414 | [grafana_com]
415 | ;url = https://grafana.com
416 |
417 | #################################### External image storage ##########################
418 | [external_image_storage]
419 | # Used for uploading images to public servers so they can be included in slack/email messages.
420 | # you can choose between (s3, webdav, gcs, azure_blob, local)
421 | ;provider =
422 |
423 | [external_image_storage.s3]
424 | ;bucket =
425 | ;region =
426 | ;path =
427 | ;access_key =
428 | ;secret_key =
429 |
430 | [external_image_storage.webdav]
431 | ;url =
432 | ;public_url =
433 | ;username =
434 | ;password =
435 |
436 | [external_image_storage.gcs]
437 | ;key_file =
438 | ;bucket =
439 | ;path =
440 |
441 | [external_image_storage.azure_blob]
442 | ;account_name =
443 | ;account_key =
444 | ;container_name =
445 |
446 | [external_image_storage.local]
447 | # does not require any configuration
448 |
--------------------------------------------------------------------------------
/roles/stats/templates/influxd.conf:
--------------------------------------------------------------------------------
1 | ### Welcome to the InfluxDB configuration file.
2 |
3 | # The values in this file override the default values used by the system if
4 | # a config option is not specified. The commented out lines are the configuration
5 | # field and the default value used. Uncommenting a line and changing the value
6 | # will change the value used at runtime when the process is restarted.
7 |
8 | # Once every 24 hours InfluxDB will report usage data to usage.influxdata.com
9 | # The data includes a random ID, os, arch, version, the number of series and other
10 | # usage data. No data from user databases is ever transmitted.
11 | # Change this option to true to disable reporting.
12 | # reporting-disabled = false
13 |
14 | # Bind address to use for the RPC service for backup and restore.
15 | # bind-address = "127.0.0.1:8088"
16 |
17 | ###
18 | ### [meta]
19 | ###
20 | ### Controls the parameters for the Raft consensus group that stores metadata
21 | ### about the InfluxDB cluster.
22 | ###
23 |
24 | [meta]
25 | # Where the metadata/raft database is stored
26 | dir = "/var/db/influxdb/meta"
27 |
28 | # Automatically create a default retention policy when creating a database.
29 | # retention-autocreate = true
30 |
31 | # If log messages are printed for the meta service
32 | # logging-enabled = true
33 |
34 | ###
35 | ### [data]
36 | ###
37 | ### Controls where the actual shard data for InfluxDB lives and how it is
38 | ### flushed from the WAL. "dir" may need to be changed to a suitable place
39 | ### for your system, but the WAL settings are an advanced configuration. The
40 | ### defaults should work for most systems.
41 | ###
42 |
43 | [data]
44 | # The directory where the TSM storage engine stores TSM files.
45 | dir = "/var/db/influxdb/data"
46 |
47 | # The directory where the TSM storage engine stores WAL files.
48 | wal-dir = "/var/db/influxdb/wal"
49 |
50 | # The amount of time that a write will wait before fsyncing. A duration
51 | # greater than 0 can be used to batch up multiple fsync calls. This is useful for slower
52 | # disks or when WAL write contention is seen. A value of 0s fsyncs every write to the WAL.
53 | # Values in the range of 0-100ms are recommended for non-SSD disks.
54 | # wal-fsync-delay = "0s"
55 |
56 |
57 | # The type of shard index to use for new shards. The default is an in-memory index that is
58 | # recreated at startup. A value of "tsi1" will use a disk based index that supports higher
59 | # cardinality datasets.
60 | # index-version = "inmem"
61 |
62 | # Trace logging provides more verbose output around the tsm engine. Turning
63 | # this on can provide more useful output for debugging tsm engine issues.
64 | # trace-logging-enabled = false
65 |
66 | # Whether queries should be logged before execution. Very useful for troubleshooting, but will
67 | # log any sensitive data contained within a query.
68 | # query-log-enabled = true
69 |
70 | # Settings for the TSM engine
71 |
72 | # CacheMaxMemorySize is the maximum size a shard's cache can
73 | # reach before it starts rejecting writes.
74 | # Valid size suffixes are k, m, or g (case insensitive, 1024 = 1k).
75 | # Values without a size suffix are in bytes.
76 | # cache-max-memory-size = "1g"
77 |
78 | # CacheSnapshotMemorySize is the size at which the engine will
79 | # snapshot the cache and write it to a TSM file, freeing up memory
80 | # Valid size suffixes are k, m, or g (case insensitive, 1024 = 1k).
81 | # Values without a size suffix are in bytes.
82 | # cache-snapshot-memory-size = "25m"
83 |
84 | # CacheSnapshotWriteColdDuration is the length of time at
85 | # which the engine will snapshot the cache and write it to
86 | # a new TSM file if the shard hasn't received writes or deletes
87 | # cache-snapshot-write-cold-duration = "10m"
88 |
89 | # CompactFullWriteColdDuration is the duration at which the engine
90 | # will compact all TSM files in a shard if it hasn't received a
91 | # write or delete
92 | # compact-full-write-cold-duration = "4h"
93 |
94 | # The maximum number of concurrent full and level compactions that can run at one time. A
95 | # value of 0 results in 50% of runtime.GOMAXPROCS(0) used at runtime. Any number greater
96 | # than 0 limits compactions to that value. This setting does not apply
97 | # to cache snapshotting.
98 | # max-concurrent-compactions = 0
99 |
100 | # The threshold, in bytes, when an index write-ahead log file will compact
101 | # into an index file. Lower sizes will cause log files to be compacted more
102 | # quickly and result in lower heap usage at the expense of write throughput.
103 | # Higher sizes will be compacted less frequently, store more series in-memory,
104 | # and provide higher write throughput.
105 | # Valid size suffixes are k, m, or g (case insensitive, 1024 = 1k).
106 | # Values without a size suffix are in bytes.
107 | # max-index-log-file-size = "1m"
108 |
109 | # The maximum series allowed per database before writes are dropped. This limit can prevent
110 | # high cardinality issues at the database level. This limit can be disabled by setting it to
111 | # 0.
112 | # max-series-per-database = 1000000
113 |
114 | # The maximum number of tag values per tag that are allowed before writes are dropped. This limit
115 | # can prevent high cardinality tag values from being written to a measurement. This limit can be
116 | # disabled by setting it to 0.
117 | # max-values-per-tag = 100000
118 |
119 | # If true, then the mmap advise value MADV_WILLNEED will be provided to the kernel with respect to
120 | # TSM files. This setting has been found to be problematic on some kernels, and defaults to off.
121 | # It might help users who have slow disks in some cases.
122 | # tsm-use-madv-willneed = false
123 |
124 | ###
125 | ### [coordinator]
126 | ###
127 | ### Controls the clustering service configuration.
128 | ###
129 |
130 | [coordinator]
131 | # The default time a write request will wait until a "timeout" error is returned to the caller.
132 | # write-timeout = "10s"
133 |
134 | # The maximum number of concurrent queries allowed to be executing at one time. If a query is
135 | # executed and exceeds this limit, an error is returned to the caller. This limit can be disabled
136 | # by setting it to 0.
137 | # max-concurrent-queries = 0
138 |
139 | # The maximum time a query will is allowed to execute before being killed by the system. This limit
140 | # can help prevent run away queries. Setting the value to 0 disables the limit.
141 | # query-timeout = "0s"
142 |
143 | # The time threshold when a query will be logged as a slow query. This limit can be set to help
144 | # discover slow or resource intensive queries. Setting the value to 0 disables the slow query logging.
145 | # log-queries-after = "0s"
146 |
147 | # The maximum number of points a SELECT can process. A value of 0 will make
148 | # the maximum point count unlimited. This will only be checked every second so queries will not
149 | # be aborted immediately when hitting the limit.
150 | # max-select-point = 0
151 |
152 | # The maximum number of series a SELECT can run. A value of 0 will make the maximum series
153 | # count unlimited.
154 | # max-select-series = 0
155 |
156 | # The maxium number of group by time bucket a SELECT can create. A value of zero will max the maximum
157 | # number of buckets unlimited.
158 | # max-select-buckets = 0
159 |
160 | ###
161 | ### [retention]
162 | ###
163 | ### Controls the enforcement of retention policies for evicting old data.
164 | ###
165 |
166 | [retention]
167 | # Determines whether retention policy enforcement enabled.
168 | # enabled = true
169 |
170 | # The interval of time when retention policy enforcement checks run.
171 | # check-interval = "30m"
172 |
173 | ###
174 | ### [shard-precreation]
175 | ###
176 | ### Controls the precreation of shards, so they are available before data arrives.
177 | ### Only shards that, after creation, will have both a start- and end-time in the
178 | ### future, will ever be created. Shards are never precreated that would be wholly
179 | ### or partially in the past.
180 |
181 | [shard-precreation]
182 | # Determines whether shard pre-creation service is enabled.
183 | # enabled = true
184 |
185 | # The interval of time when the check to pre-create new shards runs.
186 | # check-interval = "10m"
187 |
188 | # The default period ahead of the endtime of a shard group that its successor
189 | # group is created.
190 | # advance-period = "30m"
191 |
192 | ###
193 | ### Controls the system self-monitoring, statistics and diagnostics.
194 | ###
195 | ### The internal database for monitoring data is created automatically if
196 | ### if it does not already exist. The target retention within this database
197 | ### is called 'monitor' and is also created with a retention period of 7 days
198 | ### and a replication factor of 1, if it does not exist. In all cases the
199 | ### this retention policy is configured as the default for the database.
200 |
201 | [monitor]
202 | # Whether to record statistics internally.
203 | # store-enabled = true
204 |
205 | # The destination database for recorded statistics
206 | # store-database = "_internal"
207 |
208 | # The interval at which to record statistics
209 | # store-interval = "10s"
210 |
211 | ###
212 | ### [http]
213 | ###
214 | ### Controls how the HTTP endpoints are configured. These are the primary
215 | ### mechanism for getting data into and out of InfluxDB.
216 | ###
217 |
218 | [http]
219 | # Determines whether HTTP endpoint is enabled.
220 | # enabled = true
221 |
222 | # The bind address used by the HTTP service.
223 | # bind-address = ":8086"
224 |
225 | # Determines whether user authentication is enabled over HTTP/HTTPS.
226 | # auth-enabled = false
227 |
228 | # The default realm sent back when issuing a basic auth challenge.
229 | # realm = "InfluxDB"
230 |
231 | # Determines whether HTTP request logging is enabled.
232 | # log-enabled = true
233 |
234 | # Determines whether the HTTP write request logs should be suppressed when the log is enabled.
235 | # suppress-write-log = false
236 |
237 | # When HTTP request logging is enabled, this option specifies the path where
238 | # log entries should be written. If unspecified, the default is to write to stderr, which
239 | # intermingles HTTP logs with internal InfluxDB logging.
240 | #
241 | # If influxd is unable to access the specified path, it will log an error and fall back to writing
242 | # the request log to stderr.
243 | # access-log-path = ""
244 |
245 | # Determines whether detailed write logging is enabled.
246 | # write-tracing = false
247 |
248 | # Determines whether the pprof endpoint is enabled. This endpoint is used for
249 | # troubleshooting and monitoring.
250 | # pprof-enabled = true
251 |
252 | # Enables a pprof endpoint that binds to localhost:6060 immediately on startup.
253 | # This is only needed to debug startup issues.
254 | # debug-pprof-enabled = false
255 |
256 | # Determines whether HTTPS is enabled.
257 | # https-enabled = false
258 |
259 | # The SSL certificate to use when HTTPS is enabled.
260 | # https-certificate = "/etc/ssl/influxdb.pem"
261 |
262 | # Use a separate private key location.
263 | # https-private-key = ""
264 |
265 | # The JWT auth shared secret to validate requests using JSON web tokens.
266 | # shared-secret = ""
267 |
268 | # The default chunk size for result sets that should be chunked.
269 | # max-row-limit = 0
270 |
271 | # The maximum number of HTTP connections that may be open at once. New connections that
272 | # would exceed this limit are dropped. Setting this value to 0 disables the limit.
273 | # max-connection-limit = 0
274 |
275 | # Enable http service over unix domain socket
276 | # unix-socket-enabled = false
277 |
278 | # The path of the unix domain socket.
279 | # bind-socket = "/var/run/influxdb.sock"
280 |
281 | # The maximum size of a client request body, in bytes. Setting this value to 0 disables the limit.
282 | # max-body-size = 25000000
283 |
284 | # The maximum number of writes processed concurrently.
285 | # Setting this to 0 disables the limit.
286 | # max-concurrent-write-limit = 0
287 |
288 | # The maximum number of writes queued for processing.
289 | # Setting this to 0 disables the limit.
290 | # max-enqueued-write-limit = 0
291 |
292 | # The maximum duration for a write to wait in the queue to be processed.
293 | # Setting this to 0 or setting max-concurrent-write-limit to 0 disables the limit.
294 | # enqueued-write-timeout = 0
295 |
296 |
297 | ###
298 | ### [ifql]
299 | ###
300 | ### Configures the ifql RPC API.
301 | ###
302 |
303 | [ifql]
304 | # Determines whether the RPC service is enabled.
305 | # enabled = true
306 |
307 | # Determines whether additional logging is enabled.
308 | # log-enabled = true
309 |
310 | # The bind address used by the ifql RPC service.
311 | # bind-address = ":8082"
312 |
313 |
314 | ###
315 | ### [logging]
316 | ###
317 | ### Controls how the logger emits logs to the output.
318 | ###
319 |
320 | [logging]
321 | # Determines which log encoder to use for logs. Available options
322 | # are auto, logfmt, and json. auto will use a more a more user-friendly
323 | # output format if the output terminal is a TTY, but the format is not as
324 | # easily machine-readable. When the output is a non-TTY, auto will use
325 | # logfmt.
326 | # format = "auto"
327 |
328 | # Determines which level of logs will be emitted. The available levels
329 | # are error, warn, info, and debug. Logs that are equal to or above the
330 | # specified level will be emitted.
331 | # level = "info"
332 |
333 | # Suppresses the logo output that is printed when the program is started.
334 | # The logo is always suppressed if STDOUT is not a TTY.
335 | # suppress-logo = false
336 |
337 | ###
338 | ### [subscriber]
339 | ###
340 | ### Controls the subscriptions, which can be used to fork a copy of all data
341 | ### received by the InfluxDB host.
342 | ###
343 |
344 | [subscriber]
345 | # Determines whether the subscriber service is enabled.
346 | # enabled = true
347 |
348 | # The default timeout for HTTP writes to subscribers.
349 | # http-timeout = "30s"
350 |
351 | # Allows insecure HTTPS connections to subscribers. This is useful when testing with self-
352 | # signed certificates.
353 | # insecure-skip-verify = false
354 |
355 | # The path to the PEM encoded CA certs file. If the empty string, the default system certs will be used
356 | # ca-certs = ""
357 |
358 | # The number of writer goroutines processing the write channel.
359 | # write-concurrency = 40
360 |
361 | # The number of in-flight writes buffered in the write channel.
362 | # write-buffer-size = 1000
363 |
364 |
365 | ###
366 | ### [[graphite]]
367 | ###
368 | ### Controls one or many listeners for Graphite data.
369 | ###
370 |
371 | [[graphite]]
372 | # Determines whether the graphite endpoint is enabled.
373 | # enabled = false
374 | # database = "graphite"
375 | # retention-policy = ""
376 | # bind-address = ":2003"
377 | # protocol = "tcp"
378 | # consistency-level = "one"
379 |
380 | # These next lines control how batching works. You should have this enabled
381 | # otherwise you could get dropped metrics or poor performance. Batching
382 | # will buffer points in memory if you have many coming in.
383 |
384 | # Flush if this many points get buffered
385 | # batch-size = 5000
386 |
387 | # number of batches that may be pending in memory
388 | # batch-pending = 10
389 |
390 | # Flush at least this often even if we haven't hit buffer limit
391 | # batch-timeout = "1s"
392 |
393 | # UDP Read buffer size, 0 means OS default. UDP listener will fail if set above OS max.
394 | # udp-read-buffer = 0
395 |
396 | ### This string joins multiple matching 'measurement' values providing more control over the final measurement name.
397 | # separator = "."
398 |
399 | ### Default tags that will be added to all metrics. These can be overridden at the template level
400 | ### or by tags extracted from metric
401 | # tags = ["region=us-east", "zone=1c"]
402 |
403 | ### Each template line requires a template pattern. It can have an optional
404 | ### filter before the template and separated by spaces. It can also have optional extra
405 | ### tags following the template. Multiple tags should be separated by commas and no spaces
406 | ### similar to the line protocol format. There can be only one default template.
407 | # templates = [
408 | # "*.app env.service.resource.measurement",
409 | # # Default template
410 | # "server.*",
411 | # ]
412 |
413 | ###
414 | ### [collectd]
415 | ###
416 | ### Controls one or many listeners for collectd data.
417 | ###
418 |
419 | [[collectd]]
420 | enabled = true
421 | # bind-address = ":25826"
422 | # database = "collectd"
423 | # retention-policy = ""
424 | #
425 | # The collectd service supports either scanning a directory for multiple types
426 | # db files, or specifying a single db file.
427 | typesdb = "/usr/local/share/collectd"
428 | #
429 | # security-level = "none"
430 | # auth-file = "/etc/collectd/auth_file"
431 |
432 | # These next lines control how batching works. You should have this enabled
433 | # otherwise you could get dropped metrics or poor performance. Batching
434 | # will buffer points in memory if you have many coming in.
435 |
436 | # Flush if this many points get buffered
437 | # batch-size = 5000
438 |
439 | # Number of batches that may be pending in memory
440 | # batch-pending = 10
441 |
442 | # Flush at least this often even if we haven't hit buffer limit
443 | # batch-timeout = "10s"
444 |
445 | # UDP Read buffer size, 0 means OS default. UDP listener will fail if set above OS max.
446 | # read-buffer = 0
447 |
448 | # Multi-value plugins can be handled two ways.
449 | # "split" will parse and store the multi-value plugin data into separate measurements
450 | # "join" will parse and store the multi-value plugin as a single multi-value measurement.
451 | # "split" is the default behavior for backward compatability with previous versions of influxdb.
452 | # parse-multivalue-plugin = "split"
453 | ###
454 | ### [opentsdb]
455 | ###
456 | ### Controls one or many listeners for OpenTSDB data.
457 | ###
458 |
459 | [[opentsdb]]
460 | # enabled = false
461 | # bind-address = ":4242"
462 | # database = "opentsdb"
463 | # retention-policy = ""
464 | # consistency-level = "one"
465 | # tls-enabled = false
466 | # certificate= "/etc/ssl/influxdb.pem"
467 |
468 | # Log an error for every malformed point.
469 | # log-point-errors = true
470 |
471 | # These next lines control how batching works. You should have this enabled
472 | # otherwise you could get dropped metrics or poor performance. Only points
473 | # metrics received over the telnet protocol undergo batching.
474 |
475 | # Flush if this many points get buffered
476 | # batch-size = 1000
477 |
478 | # Number of batches that may be pending in memory
479 | # batch-pending = 5
480 |
481 | # Flush at least this often even if we haven't hit buffer limit
482 | # batch-timeout = "1s"
483 |
484 | ###
485 | ### [[udp]]
486 | ###
487 | ### Controls the listeners for InfluxDB line protocol data via UDP.
488 | ###
489 |
490 | [[udp]]
491 | # enabled = false
492 | # bind-address = ":8089"
493 | # database = "udp"
494 | # retention-policy = ""
495 |
496 | # InfluxDB precision for timestamps on received points ("" or "n", "u", "ms", "s", "m", "h")
497 | # precision = ""
498 |
499 | # These next lines control how batching works. You should have this enabled
500 | # otherwise you could get dropped metrics or poor performance. Batching
501 | # will buffer points in memory if you have many coming in.
502 |
503 | # Flush if this many points get buffered
504 | # batch-size = 5000
505 |
506 | # Number of batches that may be pending in memory
507 | # batch-pending = 10
508 |
509 | # Will flush at least this often even if we haven't hit buffer limit
510 | # batch-timeout = "1s"
511 |
512 | # UDP Read buffer size, 0 means OS default. UDP listener will fail if set above OS max.
513 | # read-buffer = 0
514 |
515 | ###
516 | ### [continuous_queries]
517 | ###
518 | ### Controls how continuous queries are run within InfluxDB.
519 | ###
520 |
521 | [continuous_queries]
522 | # Determines whether the continuous query service is enabled.
523 | # enabled = true
524 |
525 | # Controls whether queries are logged when executed by the CQ service.
526 | # log-enabled = true
527 |
528 | # Controls whether queries are logged to the self-monitoring data store.
529 | # query-stats-enabled = false
530 |
531 | # interval for how often continuous queries will be checked if they need to run
532 | # run-interval = "1s"
533 |
534 | ###
535 | ### [tls]
536 | ###
537 | ### Global configuration settings for TLS in InfluxDB.
538 | ###
539 |
540 | [tls]
541 | # Determines the available set of cipher suites. See https://golang.org/pkg/crypto/tls/#pkg-constants
542 | # for a list of available ciphers, which depends on the version of Go (use the query
543 | # SHOW DIAGNOSTICS to see the version of Go used to build InfluxDB). If not specified, uses
544 | # the default settings from Go's crypto/tls package.
545 | # ciphers = [
546 | # "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
547 | # "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
548 | # ]
549 |
550 | # Minimum version of the tls protocol that will be negotiated. If not specified, uses the
551 | # default settings from Go's crypto/tls package.
552 | # min-version = "tls1.2"
553 |
554 | # Maximum version of the tls protocol that will be negotiated. If not specified, uses the
555 | # default settings from Go's crypto/tls package.
556 | # max-version = "tls1.2"
557 |
--------------------------------------------------------------------------------
/roles/user_customization/defaults/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | root_shell: /bin/sh
4 | user_packages: []
5 | git_repos: []
6 |
--------------------------------------------------------------------------------
/roles/user_customization/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: install user packages
4 | pkgng:
5 | name: "{{ item }}"
6 | state: present
7 | loop: "{{ user_packages }}"
8 |
9 | - name: set the user shell
10 | user:
11 | name: root
12 | state: present
13 | shell: "{{ root_shell }}"
14 |
15 | - name: install git repos
16 | git:
17 | repo: "{{ item.remote }}"
18 | dest: "{{ item.path }}"
19 | version: master
20 | accept_hostkey: yes
21 | force: no
22 | update: no
23 | loop: "{{ git_repos }}"
24 | when: item.private is not defined or not item.private
25 |
26 | - name: create private homeshick repos
27 | shell: git init {{ item.path }} && \
28 | (cd {{ item.path }} &&
29 | git remote add origin {{ item.remote }} &&
30 | printf '[branch "master"]\n remote = origin\n merge = refs/heads/master' >> .git/config)
31 | args:
32 | creates: "{{ item.path }}"
33 | loop: "{{ git_repos }}"
34 | when: item.private is defined and item.private
35 |
--------------------------------------------------------------------------------
/scripts/backup_freenas_db.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | function backup {
4 | local date
5 | local version
6 | local hostname
7 | date=$(date +%Y%m%d%H%M%S)
8 | version=$(cat /etc/version)
9 | hostname=$(hostname -s)
10 | cp \
11 | /data/freenas-v1.db \
12 | "/mnt/media/backup/FreeNAS/$hostname-$version-$date.db"
13 | }
14 |
15 | backup
16 |
--------------------------------------------------------------------------------
/scripts/backup_jails.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | date=$(date +%Y%m%d%H%M%S)
4 | jails=/mnt/jails/iocage/jails
5 | backup=/mnt/media/backup/jails
6 |
7 | function cleanup {
8 | local jail=$1
9 | local destination=$2
10 | printf "Failed backing up %s\n" "$jail" >&2
11 | if [[ -n $destination ]]; then
12 | rm -rf "$destination"
13 | fi
14 | return 1
15 | }
16 |
17 | function backup {
18 | local jail=$1
19 | shift
20 | local destination=$backup/$jail
21 | local jail_root=$jails/$jail/root
22 | local start
23 | local end
24 | start=$(date +%s)
25 | # shellcheck disable=SC2064
26 | trap "cleanup $jail" EXIT
27 | if [[ ! -e $destination ]]; then
28 | mkdir "$destination"
29 | mkdir "$destination/current"
30 | fi
31 | mkdir "$destination/$date"
32 | # shellcheck disable=SC2064
33 | trap "cleanup $jail $destination/$date" EXIT
34 | (
35 | cd "$jail_root"
36 | rsync \
37 | --archive \
38 | --link-dest="$destination/current" \
39 | --log-file="$destination/$date/rsync.log" \
40 | "$@" \
41 | "$destination/$date"
42 | )
43 | rm -r "$destination/current"
44 | ln -s "$date" "$destination/current"
45 | trap EXIT
46 | printf "Successfully backed up %s\n" "$jail"
47 | end=$(date +%s)
48 | printf "Backup took %d seconds\n" "$((end-start))" >> "$destination/$date/rsync.log"
49 | }
50 |
51 | (set -e; backup rtorrent usr/local/libdata/rtorrent/.rtorrent.session usr/local/www/rutorrent/share)
52 | (set -e; backup sabnzbd usr/local/sabnzbd/sabnzbd.ini)
53 | (set -e; backup sonarr usr/local/sonarr/{nzbdrone.db,nzbdrone.db-shm,nzbdrone.db-wal,config.xml})
54 | (set -e; backup radarr usr/local/radarr/{nzbdrone.db,nzbdrone.db-shm,nzbdrone.db-wal,config.xml})
55 | (set -e; backup plex "usr/local/plexdata/Plex Media Server/Preferences.xml" "usr/local/plexdata/Plex Media Server/Plug-in Support/Databases")
56 | (set -e; backup stats var/db/grafana/grafana.db var/db/influxdb)
57 |
--------------------------------------------------------------------------------
/site.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - hosts: freenas
4 | roles:
5 | - jails_setup
6 |
7 | - hosts: jails
8 | roles:
9 | - pre_setup
10 | - mdns
11 | - user_customization
12 | tags: [all]
13 |
14 | - hosts: media
15 | roles: [media_group]
16 | tags: [media]
17 |
18 | - hosts: reverse-proxy
19 | roles: [reverse_proxy]
20 | tags: [app]
21 |
22 | - hosts: rtorrent
23 | roles: [rtorrent]
24 | tags: [app]
25 |
26 | - hosts: sabnzbd
27 | roles: [sabnzbd]
28 | tags: [app]
29 |
30 | - hosts: plex
31 | roles: [plex]
32 | tags: [app]
33 |
34 | - hosts: sonarr
35 | roles: [sonarr]
36 | tags: [app]
37 |
38 | - hosts: radarr
39 | roles: [radarr]
40 | tags: [app]
41 |
42 | - hosts: dnscrypt-proxy
43 | roles: [dnscrypt-proxy]
44 | tags: [app]
45 |
46 | - hosts: stats
47 | roles: [stats]
48 | tags: [app]
49 |
--------------------------------------------------------------------------------