diff options
author | Stonewall Jackson <stonewall@sacredheartsc.com> | 2023-02-04 01:23:43 -0500 |
---|---|---|
committer | Stonewall Jackson <stonewall@sacredheartsc.com> | 2023-02-04 01:52:13 -0500 |
commit | 0261e875679f1bf63c8d689da7fc7e014597885d (patch) | |
tree | 3f19cd74a0c1070944f75437f30b098d6ef2ffcb /roles/jellyfin | |
download | selfhosted-0261e875679f1bf63c8d689da7fc7e014597885d.tar.gz selfhosted-0261e875679f1bf63c8d689da7fc7e014597885d.zip |
initial commit
Diffstat (limited to 'roles/jellyfin')
-rw-r--r-- | roles/jellyfin/defaults/main.yml | 11 | ||||
-rw-r--r-- | roles/jellyfin/handlers/main.yml | 4 | ||||
-rw-r--r-- | roles/jellyfin/meta/main.yml | 10 | ||||
-rw-r--r-- | roles/jellyfin/tasks/freeipa.yml | 67 | ||||
-rw-r--r-- | roles/jellyfin/tasks/main.yml | 94 | ||||
-rw-r--r-- | roles/jellyfin/templates/etc/jellyfin/network.xml.j2 | 36 | ||||
-rw-r--r-- | roles/jellyfin/templates/etc/sysconfig/jellyfin.j2 | 22 | ||||
-rw-r--r-- | roles/jellyfin/templates/etc/systemd/system/jellyfin.service.j2 | 51 | ||||
-rw-r--r-- | roles/jellyfin/templates/var/lib/jellyfin/plugins/configurations/LDAP-Auth.xml.j2 | 23 | ||||
-rw-r--r-- | roles/jellyfin/vars/main.yml | 34 |
10 files changed, 352 insertions, 0 deletions
diff --git a/roles/jellyfin/defaults/main.yml b/roles/jellyfin/defaults/main.yml new file mode 100644 index 0000000..2c3fadb --- /dev/null +++ b/roles/jellyfin/defaults/main.yml @@ -0,0 +1,11 @@ +jellyfin_version: 10.8.9 +jellyfin_port: 8096 +jellyfin_user: s-jellyfin + +jellyfin_sysaccount_username: jellyfin + +jellyfin_media_access_group: role-media-access +jellyfin_access_group: role-media-access +jellyfin_admin_group: role-media-admin + +jellyfin_ldap_server: '{{ freeipa_hosts[0] }}' diff --git a/roles/jellyfin/handlers/main.yml b/roles/jellyfin/handlers/main.yml new file mode 100644 index 0000000..d6dee75 --- /dev/null +++ b/roles/jellyfin/handlers/main.yml @@ -0,0 +1,4 @@ +- name: restart jellyfin + systemd: + name: jellyfin + state: restarted diff --git a/roles/jellyfin/meta/main.yml b/roles/jellyfin/meta/main.yml new file mode 100644 index 0000000..f93843f --- /dev/null +++ b/roles/jellyfin/meta/main.yml @@ -0,0 +1,10 @@ +dependencies: + - role: yum + yum_repositories: + - epel + - rpmfusion-free + tags: yum + + - role: freeipa_system_account + system_account_username: '{{ jellyfin_sysaccount_username }}' + system_account_password: '{{ jellyfin_sysaccount_password }}' diff --git a/roles/jellyfin/tasks/freeipa.yml b/roles/jellyfin/tasks/freeipa.yml new file mode 100644 index 0000000..06cfd25 --- /dev/null +++ b/roles/jellyfin/tasks/freeipa.yml @@ -0,0 +1,67 @@ +- name: create user + ipauser: + ipaadmin_principal: '{{ ipa_user }}' + ipaadmin_password: '{{ ipa_pass }}' + name: '{{ jellyfin_user }}' + loginshell: /sbin/nologin + homedir: '{{ jellyfin_home }}' + givenname: Jellyfin + sn: Service Account + state: present + run_once: True + +- name: retrieve user keytab + include_role: + name: freeipa_keytab + vars: + keytab_principal: '{{ jellyfin_user }}' + keytab_path: '{{ jellyfin_keytab }}' + keytab_owner: '{{ jellyfin_user }}' + +- name: create media access group + ipagroup: + ipaadmin_principal: '{{ ipa_user }}' + ipaadmin_password: '{{ ipa_pass }}' + name: '{{ jellyfin_media_access_group }}' + nonposix: no + action: group + state: present + run_once: True + +- name: add user to media access group + ipagroup: + ipaadmin_principal: '{{ ipa_user }}' + ipaadmin_password: '{{ ipa_pass }}' + name: '{{ jellyfin_media_access_group }}' + user: '{{ jellyfin_user }}' + action: member + state: present + run_once: True + +- name: create access group + ipagroup: + ipaadmin_principal: '{{ ipa_user }}' + ipaadmin_password: '{{ ipa_pass }}' + name: '{{ jellyfin_access_group }}' + action: group + state: present + run_once: True + +- name: create admin group + ipagroup: + ipaadmin_principal: '{{ ipa_user }}' + ipaadmin_password: '{{ ipa_pass }}' + name: '{{ jellyfin_admin_group }}' + state: present + run_once: True + +- name: configure gssproxy for kerberized NFS + include_role: + name: gssproxy_client + vars: + gssproxy_name: jellyfin + gssproxy_section: service/jellyfin + gssproxy_keytab: /etc/krb5.keytab + gssproxy_client_keytab: '{{ jellyfin_keytab }}' + gssproxy_cred_usage: initiate + gssproxy_euid: '{{ jellyfin_user }}' diff --git a/roles/jellyfin/tasks/main.yml b/roles/jellyfin/tasks/main.yml new file mode 100644 index 0000000..0bb8b91 --- /dev/null +++ b/roles/jellyfin/tasks/main.yml @@ -0,0 +1,94 @@ +- name: install packages + dnf: + name: '{{ jellyfin_packages }}' + state: present + +- name: create installation directory + file: + path: '{{ jellyfin_install_dir }}' + state: directory + +- name: extract tarball + unarchive: + src: '{{ jellyfin_url }}' + remote_src: yes + dest: '{{ jellyfin_install_dir }}' + extra_opts: + - '--strip-components=2' + notify: restart jellyfin + +- name: generate systemd unit + template: + src: etc/systemd/system/jellyfin.service.j2 + dest: /etc/systemd/system/jellyfin.service + notify: restart jellyfin + register: jellyfin_unit + +- name: reload systemd units + systemd: + daemon_reload: yes + when: jellyfin_unit.changed + +- name: generate sysconfig file + template: + src: etc/sysconfig/jellyfin.j2 + dest: /etc/sysconfig/jellyfin + notify: restart jellyfin + +- name: create runtime directories + file: + path: '{{ item.path }}' + owner: '{{ jellyfin_user }}' + group: '{{ jellyfin_user }}' + mode: '{{ item.mode }}' + state: directory + loop: + - { path: '{{ jellyfin_home }}', mode: '0750' } + - { path: '{{ jellyfin_home }}/plugins', mode: '0750' } + - { path: '{{ jellyfin_home }}/plugins/configurations', mode: '0750' } + - { path: /var/cache/jellyfin, mode: '0750' } + - { path: /var/log/jellyfin, mode: '0755' } + - { path: '{{ jellyfin_conf_dir }}', mode: '0755' } + +- name: generate jellyfin network configuration + template: + src: '{{ jellyfin_conf_dir[1:] }}/network.xml.j2' + dest: '{{ jellyfin_conf_dir }}/network.xml' + owner: '{{ jellyfin_user }}' + group: '{{ jellyfin_user }}' + mode: 0644 + notify: restart jellyfin + +- name: generate jellyfin LDAP configuration + template: + src: '{{ jellyfin_home[1:] }}/plugins/configurations/LDAP-Auth.xml.j2' + dest: '{{ jellyfin_home }}/plugins/configurations/LDAP-Auth.xml' + owner: '{{ jellyfin_user }}' + group: '{{ jellyfin_user }}' + mode: 0640 + notify: restart jellyfin + +- import_tasks: freeipa.yml + +- name: enable jellyfin + systemd: + name: jellyfin + state: started + enabled: yes + +- name: allow apache to connect to jellyfin port + seport: + ports: '{{ jellyfin_port }}' + proto: tcp + setype: http_port_t + state: present + tags: selinux + +- name: open firewall ports + firewalld: + port: '{{ item }}' + permanent: yes + immediate: yes + state: enabled + loop: '{{ jellyfin_discovery_ports }}' + tags: firewalld diff --git a/roles/jellyfin/templates/etc/jellyfin/network.xml.j2 b/roles/jellyfin/templates/etc/jellyfin/network.xml.j2 new file mode 100644 index 0000000..9b73f6b --- /dev/null +++ b/roles/jellyfin/templates/etc/jellyfin/network.xml.j2 @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<NetworkConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <RequireHttps>false</RequireHttps> + <BaseUrl /> + <PublicHttpsPort>0</PublicHttpsPort> + <HttpServerPortNumber>{{ jellyfin_port }}</HttpServerPortNumber> + <HttpsPortNumber>0</HttpsPortNumber> + <EnableHttps>false</EnableHttps> + <PublicPort>{{ jellyfin_port }}</PublicPort> + <UPnPCreateHttpPortMap>false</UPnPCreateHttpPortMap> + <UDPPortRange /> + <EnableIPV6>false</EnableIPV6> + <EnableIPV4>true</EnableIPV4> + <EnableSSDPTracing>false</EnableSSDPTracing> + <SSDPTracingFilter /> + <UDPSendCount>2</UDPSendCount> + <UDPSendDelay>100</UDPSendDelay> + <IgnoreVirtualInterfaces>true</IgnoreVirtualInterfaces> + <VirtualInterfaceNames>vEthernet*</VirtualInterfaceNames> + <GatewayMonitorPeriod>60</GatewayMonitorPeriod> + <TrustAllIP6Interfaces>false</TrustAllIP6Interfaces> + <HDHomerunPortRange /> + <PublishedServerUriBySubnet /> + <AutoDiscoveryTracing>false</AutoDiscoveryTracing> + <AutoDiscovery>true</AutoDiscovery> + <RemoteIPFilter /> + <IsRemoteIPFilterBlacklist>false</IsRemoteIPFilterBlacklist> + <EnableUPnP>false</EnableUPnP> + <EnableRemoteAccess>true</EnableRemoteAccess> + <LocalNetworkSubnets /> + <LocalNetworkAddresses> + <string>127.0.0.1</string> + </LocalNetworkAddresses> + <KnownProxies /> + <EnablePublishedServerUriByRequest>false</EnablePublishedServerUriByRequest> +</NetworkConfiguration> diff --git a/roles/jellyfin/templates/etc/sysconfig/jellyfin.j2 b/roles/jellyfin/templates/etc/sysconfig/jellyfin.j2 new file mode 100644 index 0000000..75f56ff --- /dev/null +++ b/roles/jellyfin/templates/etc/sysconfig/jellyfin.j2 @@ -0,0 +1,22 @@ +# Program directories +JELLYFIN_DATA_DIR="/var/lib/jellyfin" +JELLYFIN_CONFIG_DIR="/etc/jellyfin" +JELLYFIN_LOG_DIR="/var/log/jellyfin" +JELLYFIN_CACHE_DIR="/var/cache/jellyfin" + +# web client path, installed by the jellyfin-web package +JELLYFIN_WEB_OPT="--webdir={{ jellyfin_install_dir }}/jellyfin-web" + +# [OPTIONAL] ffmpeg binary paths, overriding the UI-configured values +#JELLYFIN_FFMPEG_OPT="--ffmpeg=/usr/bin/ffmpeg" + +# [OPTIONAL] run Jellyfin as a headless service +JELLYFIN_SERVICE_OPT="--service" + +# [OPTIONAL] run Jellyfin without the web app +#JELLYFIN_NOWEBAPP_OPT="--noautorunwebapp" + +# [OPTIONAL] run Jellyfin with ASP.NET Server Garbage Collection (uses more RAM and less CPU than Workstation GC) +# 0 = Workstation +# 1 = Server +COMPlus_gcServer=1 diff --git a/roles/jellyfin/templates/etc/systemd/system/jellyfin.service.j2 b/roles/jellyfin/templates/etc/systemd/system/jellyfin.service.j2 new file mode 100644 index 0000000..2b809bb --- /dev/null +++ b/roles/jellyfin/templates/etc/systemd/system/jellyfin.service.j2 @@ -0,0 +1,51 @@ +[Unit] +Description = Jellyfin Media Server +After=autofs.service network-online.target nss-user-lookup.target + +[Service] +Type = simple +EnvironmentFile = /etc/sysconfig/jellyfin +User = {{ jellyfin_user }} +Group = {{ jellyfin_user }} +WorkingDirectory = /var/lib/jellyfin +ExecStart = {{ jellyfin_install_dir }}/jellyfin ${JELLYFIN_WEB_OPT} ${JELLYFIN_RESTART_OPT} ${JELLYFIN_FFMPEG_OPT} ${JELLYFIN_SERVICE_OPT} ${JELLYFIN_NOWEBAPP_OPT} ${JELLYFIN_ADDITIONAL_OPTS} +Restart = on-failure +TimeoutSec = 15 +SuccessExitStatus=0 143 + +NoNewPrivileges=true +SystemCallArchitectures=native +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK +RestrictNamespaces=false +RestrictRealtime=true +RestrictSUIDSGID=true +ProtectClock=true +ProtectControlGroups=false +ProtectHostname=true +ProtectKernelLogs=false +ProtectKernelModules=false +ProtectKernelTunables=false +LockPersonality=true +PrivateTmp=false +PrivateDevices=false +PrivateUsers=true +RemoveIPC=true +SystemCallFilter=~@clock +SystemCallFilter=~@aio +SystemCallFilter=~@chown +SystemCallFilter=~@cpu-emulation +SystemCallFilter=~@debug +SystemCallFilter=~@keyring +SystemCallFilter=~@memlock +SystemCallFilter=~@module +SystemCallFilter=~@mount +SystemCallFilter=~@obsolete +SystemCallFilter=~@privileged +SystemCallFilter=~@raw-io +SystemCallFilter=~@reboot +SystemCallFilter=~@setuid +SystemCallFilter=~@swap +SystemCallErrorNumber=EPERM + +[Install] +WantedBy = multi-user.target diff --git a/roles/jellyfin/templates/var/lib/jellyfin/plugins/configurations/LDAP-Auth.xml.j2 b/roles/jellyfin/templates/var/lib/jellyfin/plugins/configurations/LDAP-Auth.xml.j2 new file mode 100644 index 0000000..5326ff2 --- /dev/null +++ b/roles/jellyfin/templates/var/lib/jellyfin/plugins/configurations/LDAP-Auth.xml.j2 @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<PluginConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <LdapServer>{{ jellyfin_ldap_server }}</LdapServer> + <LdapPort>636</LdapPort> + <UseSsl>true</UseSsl> + <UseStartTls>false</UseStartTls> + <SkipSslVerify>false</SkipSslVerify> + <LdapBindUser>uid={{ jellyfin_sysaccount_username }},{{ freeipa_sysaccount_basedn }}</LdapBindUser> + <LdapBindPassword>{{ jellyfin_sysaccount_password }}</LdapBindPassword> + <LdapBaseDn>{{ freeipa_user_basedn }}</LdapBaseDn> + <LdapSearchFilter>(memberOf=cn={{ jellyfin_access_group }},{{ freeipa_group_basedn }})</LdapSearchFilter> + <LdapAdminBaseDn /> + <LdapAdminFilter>(memberOf=cn={{ jellyfin_admin_group }},{{ freeipa_group_basedn }})</LdapAdminFilter> + <LdapSearchAttributes>uid</LdapSearchAttributes> + <EnableCaseInsensitiveUsername>false</EnableCaseInsensitiveUsername> + <CreateUsersFromLdap>true</CreateUsersFromLdap> + <AllowPassChange>false</AllowPassChange> + <LdapUsernameAttribute>uid</LdapUsernameAttribute> + <LdapPasswordAttribute>userPassword</LdapPasswordAttribute> + <EnableAllFolders>true</EnableAllFolders> + <EnabledFolders /> + <PasswordResetUrl /> +</PluginConfiguration> diff --git a/roles/jellyfin/vars/main.yml b/roles/jellyfin/vars/main.yml new file mode 100644 index 0000000..00b4251 --- /dev/null +++ b/roles/jellyfin/vars/main.yml @@ -0,0 +1,34 @@ +jellyfin_url: https://repo.jellyfin.org/releases/server/linux/stable/combined/jellyfin_{{ jellyfin_version }}_amd64.tar.gz + +jellyfin_packages: + - ffmpeg + +jellyfin_home: /var/lib/jellyfin +jellyfin_conf_dir: /etc/jellyfin +jellyfin_install_dir: /opt/jellyfin +jellyfin_keytab: /var/lib/gssproxy/clients/{{ jellyfin_user }}.keytab + +jellyfin_discovery_ports: + - 1900/udp + - 7359/udp + +jellyfin_apache_config: | + {{ apache_proxy_config }} + ProxyPass / http://127.0.0.1:{{ jellyfin_port }}/ + ProxyPassReverse / http://127.0.0.1:{{ jellyfin_port }}/ + + <Location /socket> + ProxyPass http://127.0.0.1:{{ jellyfin_port }}/socket/ + ProxyPassReverse http://127.0.0.1:{{ jellyfin_port }}/socket/ + + RewriteEngine on + RewriteCond %{HTTP:Upgrade} websocket [NC] + RewriteCond %{HTTP:Connection} upgrade [NC] + RewriteRule ^/?(.*) "ws://127.0.0.1:{{ jellyfin_port }}/socket/$1" [P,L] + </Location> + +jellyfin_archive_shell: >- + TIMESTAMP=$(date +%Y%m%d%H%M%S); + tar czf "jellyfin-${TIMESTAMP}.tar.gz" + {{ jellyfin_home | quote }}/{data,metadata,plugins,root} + {{ jellyfin_conf_dir | quote }} |